railsチュートリアル第9章 ［Remember me］のテスト

##［Remember me］のテスト
・チェックボックスのエラーを確認するため
・ユーザーを永続化するコードの中心部分が、実はまだまったくテストされていない
・チェックボックスが常にオンの状態になる。
####log_in_asヘルパーを追加する
test/test_helper.rb

```rb
.
.
.
  # テストユーザーとしてログインする
  def log_in_as(user)
    session[:user_id] = user.id
    # ユーザーidを代入させる
  end
end

class ActionDispatch::IntegrationTest

  # テストユーザーとしてログインする
  def log_in_as(user, password: 'password', remember_me: '1')
    post login_path, params: { session: { email: user.email,
                                          password: password,
                                          remember_me: remember_me } }
  end
end
```
####［remember me］チェックボックスのテスト
test/integration/users_login_test.rb

```rb
require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest
  
  def setup
    @user = users(:michael)
    # ハッシュで呼び出す。
    # なんでもハッシュで呼び出せるようになるのか？
  end
.
.
. 
  test "login with remembering" do
    log_in_as(@user, remember_me: '1')
    # テストユーザーをログイン オンの状態にする
    assert_not_empty cookies[:remember_token]
    # ログインするとクッキーが発生するのか？
    # 記憶トークンは空じゃないよね？
  end

  test "login without remembering" do
    # cookieを保存してログイン
    log_in_as(@user, remember_me: '1')
    delete logout_path
    # cookieを削除してログイン
    # ログアウトするとクッキーを削除しなければならないのか！？
    # remember_token
    log_in_as(@user, remember_me: '0')
    # オフの状態でログイン
    assert_empty cookies[:remember_token]
    # 空を確認
  end
end
```
#####テスト
```
ubuntu:~/environment/sample_app (advanced-login) $ rails t
Running via Spring preloader in process 11204
Started with run options --seed 9766

  27/27: [============================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.51641s
27 tests, 66 assertions, 0 failures, 0 errors, 0 skips
```

###演習
1.
リスト 9.25の統合テストでは、仮想のremember_token属性にアクセスできないと説明しましたが、実は、assignsという特殊なテストメソッドを使うとアクセスできるようになります。コントローラで定義したインスタンス変数にテストの内部からアクセスするには、テスト内部でassignsメソッドを使います。
このメソッドにはインスタンス変数に対応するシンボルを渡します。
例えばcreateアクションで@userというインスタンス変数が定義されていれば、テスト内部ではassigns(:user)と書くことでインスタンス変数にアクセスできます。

本チュートリアルのアプリケーションの場合、Sessionsコントローラのcreateアクションでは、userを（インスタンス変数ではない）通常のローカル変数として定義しましたが、

これをインスタンス変数に変えてしまえば、

cookiesにユーザーの記憶トークンが正しく含まれているかどうかをテストできるようになります。

このアイデアに従ってリスト 9.27とリスト 9.28の不足分を埋め（ヒントとして?や（コードを書き込む）を目印に置いてあります）、［remember me］チェックボックスのテストを改良してみてください。

```rb
def create
    @user = User.find_by(email: params[:session][:email].downcase)
    # 送信されたメアドを使ってデータベースから取り出す。
    #emailを小文字にする
    if @user &.authenticate(params[:session][:password])
    # user  取得したユーザーが有効かどうか？
    # その後にデータベース上にパスワードがあるか？
    # ユーザーログイン後にユーザー情報のページにリダイレクトする
    # &.は省略型
      log_in @user
      # ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      # ログイン中のremember_meハッシュをオン、オフにする
      # １がオン remember(user)を行う　
      # ０がオフ forget(user)を行う
      # remember(user) ダイジェストをデータベースに記憶させる
      redirect_to @user
      # 名前付きルート/userのビューを表示する
    else
      flash.now[:danger] = 'Invalid email/password combination'
      # flash.nowでリクエストが発生後メッセージを消滅する
      # エラーメッセージを作成する
        render 'new'
        # newアクションのビューを表示
    end
  end
```

```rb
 test "login with remembering" do
    log_in_as(@user, remember_me: '1')
    # テストユーザーをログイン オンの状態にする
    assert_equal cookies['remember_token'], assigns(:user).remember_token
    # インスタンス変数と仮想のremember_token属性にアクセスを比較する
  end
```
意味はわからん。