Railsチュートリアル12.3.3でパスワード再設定のテストを書いたのですが、通りませんでした。
原因を調べてみましたが手詰まりになったので質問させていただきます。
どうかよろしくお願いいたします。
エラーメッセージ
Running via Spring preloader in process 45795 Started with run options --seed 49439 FAIL["test_password_resets", Minitest::Result, 4.519563999958336] test_password_resets#Minitest::Result (4.52s) expecting <"password_resets/edit"> but rendering with <[]> test/integration/password_reset_test.rb:37:in `block in <class:PasswordResetTest>' 46/46: [=================] 100% Time: 00:00:04, Time: 00:00:04 Finished in 4.52010s 46 tests, 212 assertions, 1 failures, 0 errors, 0 skips
password_reset_test.rb
require 'test_helper' class PasswordResetTest < ActionDispatch::IntegrationTest def setup @user = users(:michael) ActionMailer::Base.deliveries.clear end test "password resets" do get new_password_reset_path assert_template 'password_resets/new' # メールアドレスが無効 post password_resets_path, params: { password_reset: { email: "" } } assert_not flash.empty? assert_template 'password_resets/new' # メールアドレスが有効 post password_resets_path, params: { password_reset: { email: @user.email } } assert_not_equal @user.reset_digest, @user.reload.reset_digest assert_equal 1, ActionMailer::Base.deliveries.size assert_not flash.empty? assert_redirected_to root_url # パスワード再設定フォーム user = assigns(:user) # メールアドレスが無効 get edit_password_reset_path(user.reset_token, email: '') assert_redirected_to root_url # 無効なユーザー user.toggle!(:activated) get edit_password_reset_path(user.reset_token, email: user.email) assert_redirected_to root_url user.toggle!(:activated) # メールアドレスが有効でトークンが無効 get edit_password_reset_path('wrong token', email: user.email) assert_redirected_to root_url # メールアドレスもトークンも有効 get edit_password_reset_path(user.reset_token, email: user.email) assert_template 'password_resets/edit' # ここでエラーが起きます assert_select "input[name=email][type=hidden][value=?]", user.email # パスワードと確認用パスワードが不一致 patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: 'foobaz', password_confirmation: 'barquux' } } assert_select 'div#error_explanation' # パスワードが空 patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: '', password_confirmation: '' } } assert_select 'div#error_explanation' # 有効なパスワードと確認用パスワード patch password_reset_path(user.reset_token), params: { email: user.email, user: {password: 'foobaz', password_confirmation: 'foobaz' } } assert is_logged_in? assert_not flash.empty? assert_redirected_to user end end
確認したこと
・getの前にdebuggerを入れてuser.reset_tokenを確認したところちゃんと生成されていました。user.emailも"michael@example.com"になっています。
・app/views/password_resets/edit.html.slimは存在します。
・12.3.2の演習まではできているので、開発環境における動作には問題がないと思われます。
ソースコード
routes.rb
Rails.application.routes.draw do root 'static_pages#home' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact' get '/signup', to: 'users#new' post '/signup', to: 'users#create' get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete 'logout', to: 'sessions#destroy' resources :users resources :account_activations, only: [:edit] resources :password_resets, only: %i[new create edit update] end
password_resets_controller.rb
class PasswordResetsController < ApplicationController before_action :get_user, only: [:edit, :update] before_action :valid_user, only: [:edit, :update] before_action :check_expiration, only: [:edit, :update] def new end def create @user = User.find_by(email: params[:password_reset][:email].downcase) if @user @user.create_reset_digest @user.send_password_reset_email flash[:info] = "Email sent with password reset instructions" redirect_to root_url else flash[:danger] = "Email address not found" render 'new' end end def edit end def update if params[:user][:password].empty? @user.errors.add(:password, :blank) render 'edit' elsif @user.update_attributes(user_params) log_in @user flash[:success] = "Password has been reset." redirect_to @user else render 'edit' end end private def user_params params.require(:user).permit(:password, :password_confirmation) end def get_user @user = User.find_by(email: params[:email]) end def valid_user unless (@user && @user.activated? && @user.authenticated?(:reset, params[:id])) redirect_to root_url end end def check_expiration unless @user.password_reset_expired? flash[:danger] = "Password reset has expired." redirect_to new_password_reset_url end end end
user_mailer_preview.rb
# Preview all emails at http://localhost:3000/rails/mailers/user_mailer class UserMailerPreview < ActionMailer::Preview # Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation def account_activation user = User.first user.activation_token = User.new_token UserMailer.account_activation(user) end # Preview this email at http://localhost:3000/rails/mailers/user_mailer/password_reset def password_reset user = User.first user.reset_token = User.new_token UserMailer.password_reset(user) end end
動作環境
Rails 5.2.3
ruby 2.5.3
Ruby on Railsチュートリアル 第4版
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/12 01:32