Reputation: 53028
I am using Devise
for member authentication.
I need to test the log in scenario for a member. sign_in(member)
doesn't check authentication information - it just signs in the member thats why i am using authenticate_member!
method for authentication as suggested in Github Issue: How to authenticate the user with warden/devise in a customized way? .
BUT I get an exception saying ArgumentError: uncaught throw :warden
.
#spec/features/member.rb
FactoryGirl.define do
factory :member do
email "[email protected]"
password "12345678"
firstname "John"
lastname "Doe"
location "United States"
end
end
#spec/controllers/sessions_spec.rb
it "authenticate member" do
create(:member)
@request.env["devise.mapping"] = Devise.mappings[:member]
@request.env["warden"] = warden
controller.allow_params_authentication!
expect(controller.authenticate_member!(:scope => :member, :force => true)).not_to be nil
end
I also tried to set controller.resource = FactoryGirl.attributes_for(:member)
thinking that resource is not set but then i get exception as
NoMethodError: protected method 'resource=' called for #<Devise::SessionsController:0x007ffc4e5bab10>
How to resolve this issue?
Upvotes: 2
Views: 1859
Reputation: 53028
I posted a github issue on Devise regarding this question: Github Issue: RSpec with Devise : How to authenticate a user?
I was advised to use a post
to sessions#create
in order to simulate the POST request from the sign in form.
Here is the alternative solution:
#spec/controllers/sessions_spec.rb
it "authenticate member" do
create(:member)
@request.env["devise.mapping"] = Devise.mappings[:member]
@request.env["warden"] = warden
## Added post request to "create"
post :create, :member => FactoryGirl.attributes_for(:member)
## Added new expectations
expect(controller.member_signed_in?).to be true
expect(controller.current_member.email).to eq "[email protected]"
## "session["warden.user.member.key"][0].first" stores the "id" of logged in member
## Replace "member" in "session["warden.user.member.key"][0].first" with your
## devise model name. For example: If your devise model name is customer then you
## need to check "session["warden.user.customer.key"][0].first"
expect(session["warden.user.member.key"][0].first).to eq member.id
end
NOTE:
I would have liked to get an explanation of why my previous code as suggested in question and as provided by Devise team
in Github Issue: How to authenticate the user with warden/devise in a customized way? didn't work out which it should have. Feel free to post a new answer if anyone finds an explanation as to why my previous code for member authentication didn't work.
Upvotes: 2