I'm trying to go through Michael Hartl's RoR tutorial, but it's my third time through the thing and now I'm trying to implement Devise instead of the home rolled authentication in the tutorial. As you can imagine, this is a little bit painful, mainly due to the test driven development in the RoR tutorial not mixing well with Devise. My current hang up is that I can't seem to successfully test a successful login. I have the website up on localhost, so I know the login works, but my test is still failing for some reason. Here's the integration test snippet
def setup @user = users(:michael) end ... test "login with valid information" do get user_session_path assert_equal 200, status post user_session_path, 'user[email]' => @user.email, 'user[password]' => "password" follow_redirect! assert_equal 200, status assert_select "a[href=?]", user_session_path, count: 0 # THIS LINE FAILS assert_select "a[href=?]", destroy_user_session_path assert_select "a[href=?]", user_path(@user) end
The error I get is
FAIL["test_login_with_valid_information", UsersLoginTest, 2016-06-19 11:06:18 -0400] test_login_with_valid_information#UsersLoginTest (1466348778.61s) Expected exactly 0 elements matching "a[href="/users/sign_in"]", found 1.. Expected: 0 Actual: 1
The login bar up at the top switches from Sign in
to Account
, so it looks like the test isn't getting the user in the setup block successfully signed in. Another, possibly unrelated, issue is that in another test I have, I try the same exact login method with post user_session_path...
and then check that current_user
is not null with assert_not current_user.nil?
, but I get the error
NameError: undefined local variable or method 'current_user' for #<UsersLoginTest:0x00557f81155648>
I've looked around and made sure that I have the correct lines of devise_for :users
in my routes.rb file. I'm pretty sure It's not able to access current_user
because somehow I don't have my integration test able to access resources in Devise. Those are my two problems! Any help would be greatly appreciated.
Edit: I tried
post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password
instead of the previous method of testing the login, but I get the following errors
ERROR["test_login_with_valid_information", UsersLoginTest, 2016-06-28 20:40:59 -0400] test_login_with_valid_information#UsersLoginTest (1467160859.16s) RuntimeError: RuntimeError: not a redirect! 200 OK test/integration/users_login_test.rb:36:in `block in <class:UsersLoginTest>' test/integration/users_login_test.rb:36:in `block in <class:UsersLoginTest>' ERROR["test_login_with_valid_information_followed_by_logout", UsersLoginTest, 2016-06-28 20:40:59 -0400] test_login_with_valid_information_followed_by_logout#UsersLoginTest (1467160859.18s) NameError: NameError: undefined local variable or method `current_user' for #<UsersLoginTest:0x0055d0b9e0df50> test/integration/users_login_test.rb:49:in `block in <class:UsersLoginTest>' test/integration/users_login_test.rb:49:in `block in <class:UsersLoginTest>'
Edit 2:
I used Jemima's suggested fixture and reran the tests. Upon checking in the test log, I found
------------------------------------------------- UsersLoginTest: test_login_with_valid_information ------------------------------------------------- User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 762146111]] Started GET "/users/sign_in" for 127.0.0.1 at 2016-07-01 18:46:41 -0400 Processing by Devise::SessionsController#new as HTML Rendered devise/shared/_links.html.erb (0.4ms) Rendered devise/sessions/new.html.erb within layouts/application (1.6ms) Rendered layouts/_shim.html.erb (0.1ms) Rendered layouts/_header.html.erb (0.3ms) Rendered layouts/_footer.html.erb (0.1ms) Completed 200 OK in 4ms (Views: 3.4ms | ActiveRecord: 0.0ms) Started POST "/users/sign_in" for 127.0.0.1 at 2016-07-01 18:46:41 -0400 Processing by Devise::SessionsController#create as HTML Parameters: {"user"=>{"email"=>"michael@example.com", "password"=>"[FILTERED]"}} Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms) Processing by Devise::SessionsController#new as HTML Parameters: {"user"=>{"email"=>"michael@example.com", "password"=>"[FILTERED]"}} Rendered devise/shared/_links.html.erb (0.5ms) Rendered devise/sessions/new.html.erb within layouts/application (2.1ms) Rendered layouts/_shim.html.erb (0.1ms) Rendered layouts/_header.html.erb (0.3ms) Rendered layouts/_footer.html.erb (0.1ms) Completed 200 OK in 6ms (Views: 5.3ms | ActiveRecord: 0.0ms) (0.1ms) rollback transaction (0.1ms) begin transaction
So it looks like it's unauthorized? Also, I attempted to put include Devise::Test::IntegrationHelpers
at the top of my user login test, but it just throws the error NameError: uninitialized constant Devise::Test
.
2 Answers
Answers 1
Have you tried it with a post_via_redirect?
post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password
Answers 2
I'm having a similar issue that might help you to the answer. I believe my fixture isn't correct and therefore Devise is not authenticating.
My user fixture, in case it helps you:
user_no_club: email: noclub@example.com encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %> confirmed_at: 2016-01-02 08:31:23 confirmation_sent_at: 2016-01-02 08:30:59
And log/test.log shows the correct email is getting passed, but then:
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
EDIT:
On further investigation, I think Devise integration testing should be done with the Devise helper. I've not been able to get it working, but my understanding from the Google group is that the docs and gem might be temporarily out of sync.
0 comments:
Post a Comment