In my rails application i am using Devise
for user authentication.
When a user logs in to the application, Devise
authenticates that user and creates a session for that particular user.
I need to test that, when a user logs in, a session is created for that user. How do i do that?
In my acceptance test, If i do something like ,
feature 'User logs in' do
scenario 'with valid email and password' do
log_in_with '[email protected]', 'password'
expect(page).to have_content('Log out')
end
def log_in_with(email, password)
visit new_user_session_path
fill_in 'Email', with: email
fill_in 'Password', with: password
click_button 'Log in'
end
end
Still i am not checking that a new session was created for the logged in user. This does not fulfill my requirement as i am not checking if an actual user session was created.
Now, if i use warden
instead:
user = FactoryGirl.create(:user)
login_as(user, :scope => :user)
...
i am just saying that login as so and so user and go to next steps like maybe check for a Log Out link or an Edit Profile link, but no check on session creation for the user.
If i do this in controller specs, where i have access to sign_in
and sign_out
methods :
describe Devise::SessionsController do
it "user signed in successfully" do
logged_user = User.create(:email => "[email protected]", :password => "12345678")
sign_in logged_user
expect(controller.user_session).not_to be nil
end
end
Here, i have access to user_session
, current_user
, user_signed_in?
methods.
Out of these 3 choices, i opted for user_session
as it seems to be associated with current user session.
Is this the correct approach?
Or is there another alternative or direct method available to check that a session is active or was created for a user?
Is there a way to check this scenario in my acceptance test?
I'm pretty sure you can access all of your session data using the session hash in Controller specs. You could use it, let's say, to check if the user_id session key has been set after signing in:
expect(session[:user_id]).to_not be_nil
And, of course, you can use this to check any session that you might add throughout your application.
If you really want to see the session created by Devise, you can access the warden key generated in session:
expect(session["warden.user.user.key"][0].first).to eql logged_user.id
It's kind of unnecessary because this is the kind of thing that is already tested in Devise, so testing just if the user is logged in should be enough.
There's a great post about testing Omniauth controllers that is also a nice guide for testing SessionsController. It uses that old should syntax of RSpec, but it should be understandable =P