18
votes

I am migrating my standart Rails unit tests to RSpec and i have problems with devise. All controller containing devise authentication are failing with RSpec.

I try to sign_in an admin in RSpec following the devise tutorial, without success :

https://github.com/plataformatec/devise/wiki/How-To:-Controllers-and-Views-tests-with-Rails-3-(and-rspec)

Here is what i tried :

/spec/controllers/ipad_tech_infos_controller_spec.rb

before :each do
    @request.env["devise.mapping"] = Devise.mappings[:admin]
    @admin = FactoryGirl.create :admin
    sign_in @admin
end

/spec/support/devise.rb

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

/spec/factories/admin.rb

FactoryGirl.define do
  factory :admin do
    email "[email protected]"
    password "foobar"
    password_confirmation {|u| u.password}
  end
end

My model is not confirmable, all my controller spec are failing.

If i remove before_filter :authenticate_admin! then all my tests pass.

Can anybody help ?

3
add config.include Devise::Test::ControllerHelpers, type: :controller to rails_helper.rb, it worked well with meAstm

3 Answers

21
votes

Likely culprit: Make sure you're not setting the session explicitly in your controller specs.

For instance, if you're using the default Rspec scaffold generator, the generated controller specs pass along session parameters.

get :index, {}, valid_session

These are overwriting the session variables that Devise's helpers set to sign in with Warden. The simplest solution is to remove them:

get :index, {}

Alternatively, you could set the Warden session information in them manually, instead of using Devise's helpers.

3
votes

You said "My model is not confirmable" so the following does not apply to you, but there is a subtlety here that others might miss, like I did (and wasted an hour).

Note in the RSpec/Devise How-To that vdaubry mentions above, it says if you do have the Devise "confirmable" module enabled in your model, then either you need to call @admin.confirm! right before sign_in @admin, or else make sure your factory sets a confirmed_at when it creates your @admin. If you don't do this, the sign_in call will silently fail and all the subsequent specs will act like you're not logged in.

1
votes

I don't know what was causing this, but for me the solution was to add the method:

def valid_session
  {"warden.user.user.key" => session["warden.user.user.key"]}
end

Found here: rail3/rspec/devise: rspec controller test fails unless I add a dummy=subject.current_user.inspect