1

I'm new to RSpec, and trying to write a simple test that shows Devise is working. I've picked a random page and want to write a test that shows that a non logged-in user is re-redirected to /users/sign_in.

describe OrgsController do

  describe "GET index when not logged in" do
    it "redirects to new_user_session_path" do
      user = FactoryGirl.create(:user)
      user.confirm!
      sign_in user
      sign_out user
      get :index
      response.should redirect_to new_user_session_path
    end
  end

  before(:each) do
    user = FactoryGirl.create(:user)
    user.confirm!
    sign_in user
  end

  # remaining specs

end

I get "Expected response to be a redirect to <http://test.host/users/sign_in?locale=en> but was a redirect to <http://test.host/users/sign_in>."

I have implemented i18n, and have in my Application Controller:

before_filter :set_i18n_locale_from_params

What is the best way to get this working in terms of:

  • Getting the routes to match?
  • The hackishness of signing a user in and out again to get round the effects of the before(:each) block?
  • The overall approach?
Derek Hill
  • 5,965
  • 5
  • 55
  • 74

1 Answers1

3

The problem of getting controller tests/specs to properly set the locale is a longstanding one, see: How to set locale default_url_options for functional tests (Rails)

From what you've written, it looks like get :index is not setting the locale by default, because default_url_options will not work from controller tests/specs. Try one of the solutions mentioned in the link above to get the routes to match. See also this discussion on github: https://github.com/rspec/rspec-rails/issues/255

For what it's worth, this is the patch I currently use in specs/tests to get the locale to be automatically passed to routes from the current locale:

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

Regarding the hackishness of the before(:each) block setup you have, I'd really suggest separating the cases using context blocks, with one context without the before filter logging the user in, and another with the before block logging the user in. The setup you have right now is really confusing for someone trying to see what's going on.

Community
  • 1
  • 1
Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82
  • Shioyama - this worked perfectly! Many thanks. I put the patch in a new file in config/initializers (per http://stackoverflow.com/questions/3420680/monkey-patching-in-rails-3). Let me know if you would have applied it differently. – Derek Hill Sep 14 '12 at 06:03
  • Hi glad it worked out! I created a file for it in spec/support/ and then required that file from features/support/custom_env.rb so that it would apply to cucumber tests as well. But basically you can put it anywhere that will be loaded by rspec. The only thing about config/initializers is that those files will also be loaded in other modes, unless you wrap it in some conditional. I prefer to keep test-related stuff separate. – Chris Salzberg Sep 21 '12 at 11:35