Reputation: 7230
Now that Devise has removed the :confirmation_token from the database, how can I return the devise confirmation token in rspec?
I am trying to test the confirmable module by manually visiting the user_confirmation path with the confirmation token. How can I achieve this?
Upvotes: 5
Views: 4591
Reputation: 19102
A slight variation on the very helpful answer by Leonardo Pinto:
# Generate new raw/encrypted confirmation token pair and update database.
# This lets us visit the new "raw" path to confirm the user.
raw_confirmation_token, db_confirmation_token =
Devise.token_generator.generate(User, :confirmation_token)
User.last.update_attribute(:confirmation_token, db_confirmation_token)
visit user_confirmation_url(confirmation_token: raw_confirmation_token)
Background: As outlined in this Platformatec blog post under "Store digested tokens in the database," Devise 3.1+ sends the user a "raw" confirmation token, and saves an encrypted version in the database. When the user clicks on the raw link, the raw token is re-encrypted before searching in the database. See send_confirmation_instructions
and generate_confirmation_token
in this source code:
https://github.com/plataformatec/devise/blob/master/lib/devise/models/confirmable.rb
This code generates a new pair of raw and encrypted tokens, updates the last User in the database with the new encrypted version, then visit
s the raw version. The token should match and the account should be confirmed.
Although not in the original question, I also wanted to test for the correct link in the Devise confirmation mailer, but I don't think that's possible: when I create a user, the confirmation email is sent immediately, so the email's body contains the original raw token, not the new one generated here.
Upvotes: 10
Reputation: 129
The confirmation flow has changed. Now, the confirmation flow uses User.confirm_by_token. You can do something like this:
old_token = User.last.confirmation_token
new_token = Devise.token_generator.digest(User, :confirmation_token, old_token)
User.last.update_attribute(:confirmation_token, new_token)
visit user_confirmation_url(confirmation_token: old_token)
Upvotes: 5