Question

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 'valid@example.com', '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 => "valid@example.com", :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?

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top