Controller specs and default_url_options

Hello,

I’m using Rails 3.1.3 with rspec-rails 2.8.1. I have a scope ‘:locale’
in routes.rb and I want to run controller and routing
specs. I’m aware of the problem with setting default_url_options in
application.rb controller so I apply the solution found in the last
comment on rspec issue #255 (


)

#./spec/support/default_locale.rb
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

#./spec/controllers/categories_controller_spec.rb
require “spec_helper”

describe CategoriesController do

describe “GET index” do
it “assigns all categories as @categories” do
category = Factory :category

  get :index
  assigns(:categories).to_a.should eq([category])
end

end
end

This test fails with routing error but if I use “get :index,
locale: :fr” instead of just “get :index” the test pass.
This test is a example of controller spec but I have failing tests for
routing and request. (I have no view specs but
I’m pretty sure they would also fail)

I can’t figure out where the problem come from and why the patch
doesn’t solve it. Is there another thing to do ? (I just put the code
in ./spec/support/default_locale.rb and verify that it loads
correctly).

Thanks in advance.

On Jan 16, 2012, at 5:17 PM, Titinux wrote:

class ActionView::TestCase::TestController

 assigns(:categories).to_a.should eq([category])

I can’t figure out where the problem come from and why the patch
doesn’t solve it. Is there another thing to do ? (I just put the code
in ./spec/support/default_locale.rb and verify that it loads
correctly).

Thanks in advance.

No guarantees here, but it’s possible that
ActionView::TestCase::TestController is not loaded yet, in which case
its own definition of default_url_options would clobber yours when it
does get loaded. Try this instead:

ActionView::TestCase::TestController.class_eval do
undef_method :default_url_options
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

ActionDispatch::Routing::RouteSet.class_eval do
undef_method :default_url_options
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

If those classes aren’t loaded yet, Rails will find and load them first
(via its autoload strategy) before invoking class_eval on them, thus
ensuring that you’re replacing the existing methods rather than writing
methods that will later be replaced.

HTH,
David

Hi,

I used your code but it does not work either.

To eliminate the possibility of a problem coming from my application I
made a new Rails 3.1.3 app from scratch and scaffold Category stuff.

And the result is that view specs start working with either issue #255
solution or yours but controller, routing and request specs fails
whatever I try.

I’ve set a “binding.pry” just before “get :index” in the controller
spec to have a better vision of what’s going on

ActionView::TestCase::TestController.new.default_url_options =>
{:locale=>:en}
ActionDispatch::Routing::RouteSet.new.default_url_options =>
{:locale=>:en}

So I think the patch does its job but “get :index” takes another path
and not use default_url_options from
ActionView::TestCase::TestController nor
ActionDispatch::Routing::RouteSet

Hi Jeremie,

I’m also using Rails 3.1.3 and rspec-rails 2.8.1 and I was in the same
situation as you: neither the rspec issue #255 or the proposed solutions
in this email thread solved my problems. But now I have something
working for me (and hopefully it will work for you too).

As I recently posted on Stackoverflow
(http://stackoverflow.com/questions/1987354/how-to-set-locale-default-url-options-for-functional-tests-rails/8920258#8920258
), here is the code I use to inject the locale in the controller’s
params (which makes all my controller specs pass without explicitly
specifying the locale in each controller spec):

class ActionController::TestCase
module Behavior
def process_with_default_locale(action, parameters = nil, session =
nil, flash = nil, http_method = ‘GET’)
parameters = { :locale => I18n.default_locale }.merge( parameters
|| {} )
process_without_default_locale(action, parameters, session, flash,
http_method)
end
alias_method_chain :process, :default_locale
end
end

And here is the “cheat” I use to inject the locale in Rails’s
assert_recognizes method (which makes all my routing specs pass without
explicitly specifying the locale in each routing spec):

module ActionDispatch::Assertions::RoutingAssertions
def assert_recognizes_with_default_locale(expected_options, path,
extras={}, message=nil)
expected_options = { :locale => I18n.default_locale.to_s
}.merge(expected_options || {} )
assert_recognizes_without_default_locale(expected_options, path,
extras, message)
end
alias_method_chain :assert_recognizes, :default_locale
end

Stucking those two code snippets in my spec helper class means that I do
not need to change all my previous controller/routing specs during the
implementation of supporting multiple locales for my app.

Hope this helps,

Martin

Thanks for these very useful informations.

I found the titinux’ first post to solve my problems with request specs,
and martin_c94’s post to solve my controller specs problems.

Still, in the console, the url helpers need the locale explicitly set,
it seems:

[1] pry(main)> app.user_path User.first
ActionController::RoutingError: No route matches {:action=>“show”,
:controller=>“users”, :locale=>#<User _id: 509fc01d77bb1…

Interestingly, when executing the following code block (which is also
used to fix the problem with the request specs) within the console, it
works!

[2] pry(main)> class ActionDispatch::Routing::RouteSet
[2] pry(main)* def default_url_options(options={})
[2] pry(main)* { :locale => I18n.default_locale }
[2] pry(main)* end
[2] pry(main)* end
=> nil
[3] pry(main)> app.user_path User.first
=> “/de/users/509fc01d77bb1e6a050000a0”

I’m not sure whether this would be a valid fix also for the console?? Do
you guys experience the same behavior??

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service