I want to write an rails integration test (with ActionDispatch::IntegrationTest
). I am using devise for authentication and machinist for test models. I cannot successfully sign in.
Here is a simple example:
class UserFlowsTest < ActionDispatch::IntegrationTest
setup do
User.make
end
test "sign in to the site"
# sign in
post_via_redirect 'users/sign_in', :email => 'foo@bar.com', :password => 'qwerty'
p flash
p User.all
end
Here is the debug output:
Loaded suite test/integration/user_flows_test
Started
{:alert=>"Invalid email or password."}
[#<User id: 980190962, email: "", encrypted_password: "", password_salt: "", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2010-11-27 16:44:10", updated_at: "2010-11-27 16:44:10">, #<User id: 980190963, email: "foo@bar.com", encrypted_password: "$2a$10$vYSpjIfAd.Irl6eFvhJL0uAwp4qniv5gVl4O.Hnw/BUR...", password_salt: "$2a$10$vYSpjIfAd.Irl6eFvhJL0u", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2010-11-27 17:09:13", updated_at: "2010-11-27 17:09:13">]
"/unauthenticated"
F
Here is my blueprints.rb:
require 'machinist/active_record'
require 'sham'
User.blueprint do
email {"foo@bar.com"}
password {"qwerty"}
end
First of all, with devise, you may have to "confirm" the user.
you can do something like this:
Here is an example without Machinist (but you just have to replace the user creation code portion with the part above):
into test_integration_helper:
And into your integration_test:
The reason it doesn't work is devise creates form field names as
and post_via_redirect expects those names as arguments. So following statement would make a successful login.
I don't have a sample integration test in the book for Devise, but I think the code in the step definition in the Cucumber chapter will also work if you have Webrat/Capybara installed:
Since you are using
ActionDispatch::IntegrationTest
, you can include theDevise::Test::IntegrationHelpers
module and use thesign_in
method instead (which you can pass a user to):In case anyone else has a similar problem...
I was in a similar situation (migrating from Authlogic), and had this exact same problem. The issue was in the devise.rb initializer. By default it sets up your test environment to use only 1 stretch during the encryption/decryption of passwords. I honestly don't know what a stretch is, but for Devise to work with old Authlogic encrypted passwords, the stretches has to be 20. Since I was trying to sign in a user that originally had their password encrypted by Authlogic in my test, Devise needs to use 20 stretches in test also. I changed the config like below: