Rails check - check if a user has been signed with Devise

I am trying to verify that someone can log in to my site by doing a POST request to my SessionsController . I saw this method recommended in several places:

 it 'must be able to sign in a user' do user = create(:user) post :create, format: :js, user: {email: user.email, password: user.password, remember_me: 0} assert_response :success @controller.current_user.must_equal user end 

But this test is incorrect. The call to @controller.current_user will attempt to authenticate the user using the published parameters and will return user if the specified email address / password is correct. There is no guarantee that the create action actually calls sign_in or current_user .

Even if I rewrite the test to verify that these methods call, it is possible that other methods may be called, for example. sign_out .

Is there a more specific way to ultimately check if a user is registered, and if so, who is the user?

EDIT -

For example, the next test will pass

 it 'must sign in a user' do @controller.current_user.must_equal nil post :create, format: :js, user: {email: @user.email, password: @user.password, remember_me: 0} assert_response :success @controller.current_user.must_equal @user end 

when the action is SessionController # create:

 def create respond_to do |format| format.js { render nothing: true, status: 200 } end end 
+8
authentication ruby ruby-on-rails devise warden
source share
1 answer

A solution with minimal changes to the proposed code in question:

You need to initialize the system before starting the test. Try adding the following code before the code, I’m t 'must be able to sign in a user' do :

 before (:each) do user = FactoryGirl.create(:user) sign_out user end 

This should turn your test into a valid test for your post controller.

Explanation:

My assumption is that your test above always succeeds because the user is already signed up (other runs run before that). You can check this by using byebug in the line after it and run current_user in the bybug's console. If it is not nil , the user has already signed up, invalidating your test.

Please note that (other than what is discussed in the comments above), current_user does not change the status of the user; This is a read-only function.

Shorter / cleaner solution:

In my opinion, there is a cleaner way to perform such a test, for example:

 def sign_in_via_post(user) post :create, format: :js, user: {email: user.email, password: user.password, remember_me: 0} end ... before (:each) do user = FactoryGirl.create(:user) sign_out user end it 'must be able to sign in a user' do { sign_in_via_post user }.should change { current_user }.from(nil).to(user) end 

By using the should change from nil to user statement, you confirm that the user was logged out before the test and that the user was logged in after the test.

Please note that part

  { sign_in_via_post user }.should change { current_user }.from(nil).to(user) 

equivalent (maybe easier to understand) code

  { sign_in_via_post user }.should change { user_signed_in? }.from(false).to(true) 

as discussed here .

+2
source share

All Articles