Railsチュートリアルの第４版をRSpecでテスト-3

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

第3章～第8章のテストは以下。
 - [Railsチュートリアルの第4版をRSpecでテスト-1][link-3]（第3章～第6章）
 - [Railsチュートリアルの第4版をRSpecでテスト-2][link-4]（第7章～第8章）

[link-1]:https://railstutorial.jp/
[link-2]:https://leanpub.com/everydayrailsrspec-jp
[link-3]:https://qiita.com/yano12/items/eba8693272c31d6af7f0
[link-4]:https://qiita.com/yano12/items/4ef93129a50249adcb8d
[link-5]:https://qiita.com/yano12/items/319615e6e5fdcd7d844a
[link-6]:https://qiita.com/yano12/items/99e3fd4213f61339bad4
[link-7]:https://railstutorial.jp/chapters/account_activation?version=5.1#sec-exercises_mailer_templates
[link-8]:https://qiita.com/yano12/items/f5167416f3c20e1896d4
[link-9]:https://railstutorial.jp/chapters/password_reset?version=5.1#cha-password_reset
[link-10]:https://qiita.com/IrieLuka/items/34b0edccecc036d24748

# 2つの目立たないバグのテスト
Remember me（ログイン時にログイン情報を記憶する）テストを書く前に、[Ruby on Rails チュートリアル(第4版)][link-1]の9.1.4 2つの目立たないバグ についてテストします。
まず、ログイン中の場合のみログアウトすることをテストするために、spec/requests/remember_me_spec.rbを作成し以下を追記します。

```spec/requests/remember_me_spec.rb
require 'rails_helper'

RSpec.describe "Remember me", type: :request do
  let(:user) { FactoryBot.create(:user) }
  
  # 2つのバグのテスト1
  context "with valid information" do
    # ログイン中のみログアウトすること
    it "logs in with valid information followed by logout" do
      sign_in_as(user)     # spec/support/utilities.rbに定義
      expect(response).to redirect_to user_path(user)
      
      # ログアウトする
      delete logout_path
      expect(response).to redirect_to root_path
      expect(session[:user_id]).to eq nil
      
      # 2番目のウィンドウでログアウトする
      delete logout_path
      expect(response).to redirect_to root_path
      expect(session[:user_id]).to eq nil
    end
  end
end
```

ここで、sign_in_asメソッドは[Railsチュートリアルの第4版をRSpecでテスト-2][link-4]で定義したものです。
テストを実行しパスするのを確認します。

続いて、ユーザーが複数のブラウザでログインしていた時のテストをspec/models/user.rbに追加します。

```spec/models/user.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  let(:user) { FactoryBot.create(:user) }
  
  # 途中のテストは省略

  # 2つのバグのテスト2
  describe "authenticated? should return false for a user with nil digest" do
    # ダイジェストが存在しない場合のauthenticated?のテスト
    it "is invalid without remember_digest" do
      expect(user.authenticated?(:remember, '')).to eq false
    end
  end
end

```

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

# [Remember me]のテスト
[Remember me]機能が正しく動作しているか確認するテストをspec/requests/remember_me_spec.rbに追加します。

```spec/remember_me_spec.rb
require 'rails_helper'

RSpec.describe "Remember me", type: :request do
  let(:user) { FactoryBot.create(:user) }
  
  # 途中のテストは省略
  
  # remember_meチェックボックスのテスト
  context "login with remembering" do
    it "remembers cookies" do
      post login_path, params: { session: { email: user.email,
                                      password: user.password,
                                      remember_me: '1'} }
      expect(response.cookies['remember_token']).to_not eq nil
    end
  end 
  
  context "login without remembering" do
    it "doesn't remember cookies"do
      # クッキーを保存してログイン
      post login_path, params: { session: { email: user.email,
                                      password: user.password,
                                      remember_me: '1'} }
      delete logout_path
      # クッキーを保存せずにログイン
      post login_path, params: { session: { email: user.email,
                                      password: user.password,
                                      remember_me: '0'} }
      expect(response.cookies['remember_token']).to eq nil
    end
  end
end

```

ここで、ログイン状態のシミュレートにはspec/support/utilities.rbに定義したsign_in_asメソッドを使いたかったのですが、キーワード引数を設定すると上手くいかなかったのでpost login_pathでログインを使いました。


今回は以上です。
10章以降は完成し次第書いていきます。

#追記
第10章以降のテストを書きました。
 - [Railsチュートリアルの第4版をRSpecでテスト-4][link-6]（第10章）
 - [Railsチュートリアルの第4版をRSpecでテスト-5][link-8]（第11章）
 - [Railsチュートリアルの第4版をRSpecでテスト-6][link-10]（第12章）