Рельсы 4 + разработать: Как написать тест для разработки сброс пароля без вас?
По причинам, не зависящим от меня, я не могу использовать RSpec для тестирования в моем текущем проекте. Я пытаюсь проверить, как сбросить пароль, и не могу придумать что-то, что работает.
Вот что у меня есть до сих пор:
require 'test_helper'
class ResetPasswordTest < ActionDispatch::IntegrationTest
setup do
@user = users(:example)
end
test "reset user's password" do
old_password = @user.encrypted_password
puts @user.inspect
# This assertion works
assert_difference('ActionMailer::Base.deliveries.count', 1) do
post user_password_path, user: {email: @user.email}
end
# puts @user.reset_password_token => nil
# Not sure why this doesn't assign a reset password token to @user
patch "/users/password", user: {
reset_password_token: @user.reset_password_token,
password: "new-password",
password_confirmation: "new-password",
}
# I get a success here, but I'm not sure why, since reset password token is nil.
assert_response :success
# This assertion doesn't work.
assert_not_equal(@user.encrypted_password, old_password)
end
end
Я добавил несколько комментариев выше, где вещи, кажется, не работают. Есть ли у кого-нибудь понимание или идея о том, как лучше это проверить?
3 ответа:
Devise тестирует
Как отмечалось в других ответах, вы должны получитьPasswordsController
внутренне. Я хотел протестировать мойPasswordsController
с дополнительной функциональностью и обратился к контроллерным тестам Device за помощью в построении тестов для функциональности Device по умолчанию, а затем добавил утверждения для моей новой функциональности в тестовый случай.reset_password_token
. Вместо разбора доставленного сообщения электронной почты, как в другом решении здесь, вы можете получить маркер тем же способом, что и Devise:setup do request.env["devise.mapping"] = Devise.mappings[:user] @user = users(:user_that_is_defined_in_fixture) @reset_password_token = @user.send_reset_password_instructions end
Проверьте Devise решение для
PasswordControllerTest
:Https://github.com/plataformatec/devise/blob/master/test/controllers/passwords_controller_test.rb.
Я понял, что вам нужно перезагрузить пользователя при отправке электронной почты сброса пароля и при
put
тинге маршрута/user/password
. Вам также необходимо получить маркер пароля из электронной почты, так как он отличается от того, который хранится в базе данных.require 'test_helper' class ResetPasswordTest < ActionDispatch::IntegrationTest setup do @user = users(:example) end test "reset user's password" do # store old encrypted password old_password = @user.encrypted_password # check to ensure mailer sends reset password email assert_difference('ActionMailer::Base.deliveries.count', 1) do post user_password_path, user: {email: @user.email} assert_redirected_to new_user_session_path end # Get the email, and get the reset password token from it message = ActionMailer::Base.deliveries[0].to_s rpt_index = message.index("reset_password_token")+"reset_password_token".length+1 reset_password_token = message[rpt_index...message.index("\"", rpt_index)] # reload the user and ensure user.reset_password_token is present # NOTE: user.reset_password_token and the token pulled from the email # are DIFFERENT @user.reload assert_not_nil @user.reset_password_token # Ensure that a bad token won't reset the password put "/users/password", user: { reset_password_token: "bad reset token", password: "new-password", password_confirmation: "new-password", } assert_match "error", response.body assert_equal @user.encrypted_password, old_password # Valid password update put "/users/password", user: { reset_password_token: reset_password_token, password: "new-password", password_confirmation: "new-password", } # After password update, signed in and redirected to root path assert_redirected_to root_path # Reload user and ensure that the password is updated. @user.reload assert_not_equal(@user.encrypted_password, old_password) end end
require 'rails_helper' feature 'User' do let(:user) { create(:user) } let(:new_password) { 'Passw0rd!' } it 'reset password' do visit '/' click_link 'Forgot password?' fill_in 'E-mail', with: user.email expect do click_button 'Send me reset password instructions' end.to change(ActionMailer::Base.deliveries, :count).by(1) expect(unread_emails_for(user.email)).to be_present open_email(user.email, with_subject: 'Reset password instructions') click_first_link_in_email fill_in 'New password', with: new_password fill_in 'Confirm new password', with: new_password click_button 'Change password' expect(page).to have_notice 'Your password has changed' click_link 'Logout' fill_in 'E-mail', with: user.email fill_in 'Password', with: new_password click_button 'Sign in' expect(page).to have_notice 'Wellcome!' end end
Этот код требует email_spec и FactoryGirl gems.