New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rspec ignores default_url_options set in application_controller.rb #255
Comments
What kind of spec is this failing in? Controller w/ render_views? View spec? |
View specs are giving me troubles. I haven't tried it with render_views in controller specs. I'll give it a try. |
I'm pretty sure this is a rails issue, not RSpec. For view specs, RSpec wraps ActionView::TestCase. Can you please try one of the RSpec examples that's failing as an ActionView::TestCase and tell me if you get a different result? |
Sorry, I've tried to figure this out, but I don't know how to test a view without the controller by using ActionView::TestCase. I couldn't find much helpful documentation either. Any hints? |
|
Dave, it looks like your initial assessment was correct. The same test fails as an ActionView::TestCase. I'll figure out how to pass this to the rails team. Thanks. |
I'm going to go ahead and close this then. Please feel free to add comments here as you learn stuff. |
Was this reported as a bug to the Rails team? If yes, could somebody post the link? Can't find it... |
Yes, here is the link: It was recently marked invalid with a code sample of how testing should be done. I haven't had time to evaluate the response in conjunction with rspec. |
Thanks, I will try to implement it that way with RSpec. |
It worked for me by just monkeypatching the controller to be tested in a before(:all) filter:
|
If you want to change it everywhere, try dropping this into a file in spec/support
|
i needed to dig a little deeper to get all my spec up and running again with rails 3.1.3: # workaround, to set default locale for ALL spec
class ActionView::TestCase::TestController
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end
class ActionDispatch::Routing::RouteSet
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end |
I've been using @phoet's patch for the past year or so, but the other day when I updated rails from 3.2.3 to 3.2.6, suddenly the problem returned. After some digging I found that an upgrade to journey from 1.0.3 to 1.0.4 was part of the problem, but I still had issues in my integration tests. Specifically, this would fail: describe "default_url_options test" do
context 'test' do
before do
I18n.locale = 'en'
visit homepage_path
end
it "switches the locale to ja" do
I18n.locale = 'ja'
visit homepage_path
page.should have_content("サインイン")
end
end
end The locale would revert whatever it was initially set to, making it impossible to change midway through any particular spec. This used to work no problem. After digging some more, I found what I think is the source of the problem in this commit to rails, which prioritizes the locale passed in through the To get around this, I replaced both patches above with this one, which solves the problem everywhere: class ActionDispatch::Routing::RouteSet
def url_for_with_locale_fix(options)
url_for_without_locale_fix(options.merge(:locale => I18n.locale))
end
alias_method_chain :url_for, :locale_fix
end I'd be eager to hear if anyone had the same problem when upgrading rails, or if there is something specific to my environment that is triggering this behaviour. |
Thanks @shioyama , that was helpful. A remark, though : url_for_without_locale_fix(options.merge(:locale => I18n.locale)) using this, you do not actually set a default, but you override locale param after user pass it to route helper. This is not a problem in your case because you use To actually emulate class ActionDispatch::Routing::RouteSet
def url_for_with_locale_fix(options)
url_for_without_locale_fix({:locale => I18n.default_locale}.merge(options))
end
alias_method_chain :url_for, :locale_fix
end |
This has been very helpful! Thanks every one who contributed here. Is there anyway this can be made a default configuration option in rspec-rails so it doesn't feel like we're monkey patching or is this really a rails issue? |
FYI, controller spec patch still work, but the Here is my fix : class ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper
def call(t, args)
t.url_for(handle_positional_args(t, args, { locale: I18n.default_locale }.merge( @options ), @segment_keys))
end
end This overrides ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper#call with no possibility to use super or chain, so changes in this file should be observed for. Sorry @gaganawhad , I still can't answer your question. Even after half a day reading and playing with the code, I'm still unsure where default_url_options should be called for capybara. But please note a Hash is available in your rspec examples : before :each do
default_url_options[ :locale ] = 'fr'
end That's still a bit messy and hardly better than specifying locale in each route generation, though. I found no way to use that through rspec's |
@oelmekki Thanks for that last monkeypatch! It'd be nice to figure out where this issue belongs 😕 |
I finally gave up with monkeypatching and followed your last suggestion...
|
Thanks for feedback, @deivid-rodriguez . I'm curious : what problem did For reference, here is the exact code I use : # workaround, to set default locale for ALL spec
class ActionView::TestCase::TestController
def default_url_options(options={})
logged_in = options[ :controller ] =~ /admin/ ? 'members' : nil
{ locale: I18n.default_locale, logged_in: logged_in }
end
end
class ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper
def call(t, args)
logged_in = @options[ :controller ] =~ /admin/ ? 'members' : nil
t.url_for(handle_positional_args(t, args, { locale: I18n.default_locale, logged_in: logged_in }.merge( @options ), @segment_keys))
end
end I have two defaults : the locale and the "logged_in" part, which only |
Nono, your monkeypatch works just fine. I was having several issues related to this one when upgrading to rails4 (see rails/rails#12178), so at some point in my desperation I decided to remove all locale monkeypatching and use that |
I know that moment ;) Ok, thanks for feedback. |
…ault localisation parameters rspec/rspec-rails#255
Thanks for your comments, guys. I found @deivid-rodriguez' This seems a bit half-baked to me. What should happen with an issue like this? |
@jmuheim As was clarified when this was originally closed, it's a Rails issue, not an RSpec one. |
@oelmekki Does your fix work for anonymous controller specs, too? I have some functionality in application controller that I'd like to test, e.g.: describe ApplicationController do
controller(ApplicationController) do
def index
render text: 'Hello World'
end
end
context 'user not logged in (guest)' do
it 'creates a guest user for a first request' do
expect {
get :index
}.to change { User.guests.count }.from(0).to 1
expect(User.guests.last).to be_guest
end
end
end This results in errors like this:
|
@jmuheim : woops, apologies, I saw your message while I was off and Haven't ever used it that way. There is probably specific logic |
When unit testing views the controller is just a stub controller which inherits from ActionController::Base and not ApplicationController. You need to override this stub if you need special behaviour like default_url_options, e.g:
Hi! So at this point we know this is a Rails issue, but there's not any opened issue in Rails for this. Right? |
This code helped me .... just create spec/support/fix_locales.rb |
For me @igorkasyanchuk solution works the best. Don't forget to require |
Try add this in config/enviroment/test.rb
|
Try add this in config/enviroment/test.rb
|
Based on some previous solutions, the thing that currently works best for me in Rails 6 is [ApplicationController, ActionController::Base].each do |klass|
klass.class_eval do
def default_url_options(options = {})
{ locale: I18n.default_locale }.merge(options)
end
end
end in a |
Using Rails 3, I have a
:scope
in routes.rb:In application_controller.rb I set the default :locale
In my views, this works when I test in my browser, but fails with Rspec:
While running specs I see:
So, Rspec is not using the
default_url_options
set in application_controller.rb.Thanks
The text was updated successfully, but these errors were encountered: