Help us understand the problem. What is going on with this article?

Rails Tutorialの第4版をRSpecでテスト-6

Ruby on Rails チュートリアルの第4版を学習し、Everyday Rails - RSpecによるRailsテスト入門でRSpecを学習したので、Ruby on Rails チュートリアルをRSpecでテストしてみました。
今回は第12章のテストを書きます。

第3章~第11章のテストは以下。
- Railsチュートリアルの第4版をRSpecでテスト-1(第3章~第6章)
- Railsチュートリアルの第4版をRSpecでテスト-2(第7章~第8章)
- Railsチュートリアルの第4版をRSpecでテスト-3(第9章)
- Railsチュートリアルの第4版をRSpecでテスト-4(第10章)
- Railsチュートリアルの第4版をRSpecでテスト-5(第11章)

パスワードの再設定

Ruby on Rails チュートリアル 第12章のパスワードの再設定をテストしていきます。

送信メールのテスト

パスワードの再設定メールの送信とプレビューのテストをspec/mailers/user_mailer_spec.rbに追加します。

spec/mailers/user_mailer_spec.rb
require "rails_helper"

RSpec.describe UserMailer, type: :mailer do
  let(:user) { FactoryBot.create(:user) }

  describe "account_activation" do
    # アカウント有効化メールのテストは省略
  end

  describe "password_reset" do
    let(:mail) { UserMailer.password_reset(user) }

    # メール送信のテスト
    it "renders the headers" do
      user.reset_token = User.new_token                        # この行がないとエラーになった
      expect(mail.to).to eq ["tester3@example.com"]
      expect(mail.from).to eq ["noreply@example.com"]
      expect(mail.subject).to eq "Password reset"
    end

    # メールプレビューのテスト
    it "renders the body" do
      user.reset_token = User.new_token                        # この行がないとエラーになった
      expect(mail.body.encoded).to match user.reset_token
      expect(mail.body.encoded).to match CGI.escape(user.email)
    end
  end
end

基本的にはアカウント有効化のテストと同じですが,各テストの最初でuser.reset_tokenを定義しないとエラーになってしまいます。
実行しテストがパスするのを確認します。

パスワードの再設定をテストする

続いてパスワードの再設定のテストをリクエストスペックに書いていきます。
テストの手順は次の通りです。
最初に「forgot password」フォームを表示して無効なメールアドレスを送信し、次はそのフォームで有効なメールアドレスを送信します。
後者ではパスワード再設定用トークンが作成され、再設定用メールが送信されます。
続いて、GETリクエストでメールのリンクを開いて無効な情報を送信し、次にそのリンクから有効な情報を送信して、それぞれが期待どおりに動作することを確認します。

spec/requests/password_reset_spec.rb
require 'rails_helper'

RSpec.describe "User pages", type: :request do
  let(:user) { FactoryBot.create(:user) }

  include ActiveJob::TestHelper

  it "resets password" do
    perform_enqueued_jobs do
      # メールアドレスが無効
      post password_resets_path, params: { password_reset: { email: "" } }
      expect(response).to render_template(:new)
      # メールアドレスが有効
      post password_resets_path, params: { password_reset: { email: user.email }}
      expect(response).to redirect_to root_path

      # パスワード再設定フォームのテスト
      user = assigns(:user)
      # メールアドレスが無効
      get edit_password_reset_path(user.reset_token, email: "" )
      expect(response).to redirect_to root_path
      # メールアドレスが有効で、トークンが無効
      get edit_password_reset_path('wrong token', email: user.email )
      expect(response).to redirect_to root_path
      # メールアドレスもトークンも有効
      get edit_password_reset_path(user.reset_token, email: user.email )
      expect(response).to render_template(:edit)
      # 無効なパスワードとパスワード確認
      patch password_reset_path(user.reset_token), 
          params: { email: user.email,
                    user: { password: "foobaz",
                            password_confirmation: "barquux" } }
      expect(response).to render_template(:edit)
      # パスワードが空
      patch password_reset_path(user.reset_token), 
          params: { email: user.email,
                    user: { password: "",
                            password_confirmation: "" } }
      expect(response).to render_template(:edit)
      # 有効なパスワードとパスワード確認
      patch password_reset_path(user.reset_token), 
          params: { email: user.email,
                    user: { password: "foobaz",
                            password_confirmation: "foobaz" } }
      expect(session[:user_id]).to eq user.id
      expect(response).to redirect_to user_path(user)
    end
  end
end

実行しテストがパスするのを確認します。

以上でパスワード再設定のテストは終わりです。

nanamemo_net
◎社会人2年目(25) ◎機械設計エンジニア ◎製造装置メーカー勤務 ◎人見知り
https://nanamemo.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away