質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

375閲覧

Railsチュートリアル12章のテストが通らない

yk097

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/04/11 11:15

前提・実現したいこと

Ruby on Rails チュートリアル12章の統合テストが通らずに困っています。
具体的には、password_resets/editというviewのレンダリングに失敗しているようです。
原因または解決策をご存知の方がいらっしゃれば、ぜひお知恵をお借りしたいです。

発生している問題・エラーメッセージ

Railsチュートリアル12章の統合テストを実行したところ、以下の箇所でテストが失敗します。

FAIL["test_password_resets", #<Minitest::Reporters::Suite:0x0000563ecdd1e6d0 @name="PasswordResetsTest">, 3.7588823639998736] test_password_resets#PasswordResetsTest (3.76s) expecting <"password_resets/edit"> but rendering with <[]> test/integration/password_resets_test.rb:41:in `block in <class:PasswordResetsTest>'

password_resets/editへのレンダリングが失敗しているようですが原因がつかめません。

該当のソースコード

失敗するテストコード

  • /test/integration/test_password_resets.rb

および関連がありそうな以下3ファイルのコードを貼付します

  • /app/views/password_resets/edit.html.erb
  • /app/models/users.rb
  • /app/controllers/password_resets_controller.rb

/test/integration/test_passsword_resets.rb

ruby

1require 'test_helper' 2class PasswordResetsTest < ActionDispatch::IntegrationTest 3 def setup 4 ActionMailer::Base.deliveries.clear 5 @user = users(:michael) 6 end 7 8 test "password resets" do 9 get new_password_reset_path 10 assert_template 'password_resets/new' 11 assert_select 'input[name=?]', 'password_reset[email]' 12 #メールアドレスが無効 13 post password_resets_path, params: {password_reset: {email: ""}} 14 assert_not flash.empty? 15 assert_template 'password_resets/new' 16 #メールアドレスが有効 17 post password_resets_path, 18 params: {password_reset: {email: @user.email}} 19 assert_not_equal @user.reset_digest, @user.reload.reset_digest 20 assert_equal 1, ActionMailer::Base.deliveries.size 21 assert_not flash.empty? 22 assert_redirected_to root_url 23 #パスワード再設定フォームのテスト 24 user = assigns(:user) 25 #メールアドレスが無効 26 get edit_password_reset_path(user.reset_token, email: "") 27 assert_redirected_to root_url 28 #無効なユーザー 29 user.toggle!(:activated) 30 get edit_password_reset_path(user.reset_token, email: "") 31 assert_redirected_to root_url 32 #メールアドレスが有効、トークンが無効 33 get edit_password_reset_path('wrong token', email: user.email) 34 assert_redirected_to root_url 35 #メールアドレスもトークンも有効 36 get edit_password_reset_path(user.reset_token, email: user.email) 37 assert_template 'password_resets/edit' 38 assert_select "input[name=email][type=hidden][value=?]", user.email 39 #無効なパスワードとパスワード確認 40 patch password_reset_path(user.reset_token), 41 params: {email: user.email, 42 user: {password: "foobaz", 43 password_confirmation: "barquux"}} 44 assert_select 'div#error_explanation' 45 #パスワードが空 46 patch password_reset_path(user.reset_token), 47 params: {email: user.email, 48 user: {password: "", 49 password_confirmation: ""}} 50 assert_select 'div#error_explanation' 51 #有効なパスワードとパスワード確認 52 patch password_reset_path(user.reset_token), 53 params: {email: user.email, 54 user: {password: "foobaz", 55 password_confirmation: "foobaz"}} 56 assert is_logged_in? 57 assert_not flash.empty? 58 assert_redirected_to user 59 end 60end

/app/views/password_resets/edit.html.erb

erb

1<% provide(:title, 'Reset password') %> 2<h1>Reset password</h1> 3 4<div class="row"> 5 <div class="col-md-6 col-md-offset-3"> 6 <%= form_with(model: @user, url: password_reset_path(params[:id]), 7 local: true) do |f| %> 8 <%= render 'shared/error_messages' %> 9 10 <%= hidden_field_tag :email, @user.email %> 11 12 <%= f.label :password %> 13 <%= f.password_field :password, class: 'form-control' %> 14 15 <%= f.label :password_confirmation, "Confirmation" %> 16 <%= f.password_field :password_confirmation, class: 'form-control' %> 17 18 <%= f.submit "Update password", class: "btn btn-primary" %> 19 <% end %> 20 </div> 21</div>

/app/models/user.rb

ruby

1class User < ApplicationRecord 2 attr_accessor :remember_token, :activation_token, :reset_token 3 before_save :downcase_email 4 before_create :create_activation_digest 5 validates :name, presence: true, length: {maximum: 50} 6 7 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i 8 validates :email, presence: true, length: {maximum: 255}, 9 format: {with: VALID_EMAIL_REGEX}, 10 uniqueness: true 11 has_secure_password 12 validates :password, presence: true, length: {minimum: 6}, allow_nil: true 13 14 #渡された文字列のハッシュ値を返す 15 def User.digest(string) 16 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 17 BCrypt::Engine.cost 18 BCrypt::Password.create(string, cost: cost) 19 end 20 21 #ランダムなトークンを返す 22 def User.new_token 23 SecureRandom.urlsafe_base64 24 end 25 26 #永続セッションのためにユーザーをデータベースに記憶する 27 def remember 28 self.remember_token = User.new_token 29 update_attribute(:remember_digest, User.digest(remember_token)) 30 end 31 32 #渡されたトークンがダイジェストと一致したらtrueを返す 33 def authenticated?(attribute, token) 34 digest = send("#{attribute}_digest") 35 return false if digest.nil? 36 BCrypt::Password.new(digest).is_password?(token) 37 end 38 39 #ユーザのログイン情報を破棄する 40 def forget 41 update_attribute(:remember_digest, nil) 42 end 43 44 #アカウントを有効にする 45 def activate 46 update_attribute(:activated, true) 47 update_attribute(:activated_at, Time.zone.now) 48 end 49 50 #有効化用のメールを送信する 51 def send_activation_email 52 UserMailer.account_activation(self).deliver_now 53 end 54 55 #パスワード再設定のメールを送信する 56 def create_reset_digest 57 self.reset_token = User.new_token 58 update_attribute(:reset_digest, User.digest(reset_token)) 59 update_attribute(:reset_sent_at, Time.zone.now) 60 end 61 62 #パスワード再設定用メールの送信 63 def send_password_reset_email 64 UserMailer.password_reset(self).deliver_now 65 end 66 67 #パスワード再設定の期限が切れている場合にtrueを返す 68 def password_reset_expired? 69 reset_sent_at < 2.hours.ago 70 end 71 72private 73 #メールアドレスをすべて小文字に 74 def downcase_email 75 self.email = email.downcase 76 end 77 78 #有効化トークンとダイジェストを作成・代入 79 def create_activation_digest 80 self.activation_token = User.new_token 81 self.activation_digest = User.digest(activation_token) 82 end 83end

/app/controllers/password_resets_controller.rb

ruby

1class PasswordResetsController < ApplicationController 2 before_action :get_user, only: [:edit, :update] 3 before_action :valid_user, only: [:edit, :update] 4 before_action :check_expiration, only: [:edit, :update] 5 6 7 def new 8 end 9 10 def create 11 @user = User.find_by(email: params[:password_reset][:email].downcase) 12 if @user 13 @user.create_reset_digest 14 @user.send_password_reset_email 15 flash[:info] = "Email sent with password reset instructions" 16 redirect_to root_url 17 else 18 flash.now[:danger] = "Email address not found" 19 render 'new' 20 end 21 end 22 23 24 def edit 25 end 26 27 def update 28 if params[:user][:password].empty? 29 @user.errors.add(:password, :blank) 30 render 'edit' 31 elsif @user.update(user_params) 32 log_in @user 33 flash[:success] = "Password has been reset." 34 redirect_to @user 35 else 36 render 'edit' 37 end 38 end 39 40 private 41 42 def user_params 43 params.require(:user).permit(:password, :password_confirmation) 44 end 45 46 def get_user 47 @user = User.find_by(email: params[:email]) 48 end 49 50 #正しいユーザかどうか確認する 51 def valid_user 52 unless (@user && @user.activated? && 53 @user.authenticated?(:reset, params[:id])) 54 redirect_to root_url 55 end 56 end 57 58 #トークンが期限切れかどうか確認する 59 def check_expiration 60 if @user.password_reset_expired? 61 flash[:danger] = "Password reset has expired." 62 redirect_to new_password_reset_url 63 end 64 end 65end

試したこと

同じ箇所で詰まっている方の質問を参照しました。
該当箇所を見直しましたが、自分のコードでは同じ問題が見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

Ruby on Rails 6.0です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

無効なユーザーのテストでactivated属性を反転させたままにしている
最後にtoggle!を使ってactivatedをtrueに戻す必要があった

#無効なユーザー user.toggle!(:activated) get edit_password_reset_path(user.reset_token, email: "") assert_redirected_to root_url user.toggle!(:activated)

投稿2021/05/11 01:15

yk097

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問