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

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

ただいまの
回答率

89.13%

Rails tutorialの8章においてテストスイートが上手くいかない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 569

yonamine

score 11

session_controller.rb

class SessionsController < ApplicationController
  def new

  end

  def create

    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      remember user
      redirect_to user
    else
      flash.now[:danger] = "Invalid email/password combination"
      render "new"
    end
  end

  def destroy

    log_out if logged_in?
    redirect_to root_url
  end


end

test_helpr.rb

ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
  fixtures :all

  # テストユーザーがログイン中の場合にtrueを返す
  def is_logged_in?
    !session[:user_id].nil?
  end



  # テストユーザーとしてログインする
  def log_in_as(user, options = {})
    password    = options[:password]    || 'password'
    remember_me = options[:remember_me] || '1'
    if integration_test?
      post login_path, params: {session: { email:       user.email,
                                  password:    password,
                                  remember_me: remember_me }}
    else
      session[:user_id] = user.id
    end
  end

  private

    # 統合テスト内ではtrueを返す
    def integration_test?
      defined?(post_via_redirect)
    end
end

users_login_test.rb

require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  test "login with invalid information" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: { session: { email: "", password: "" } }
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

  def setup
    @user = users(:michael)
  end

  test "login with valid information followed by logout" do
   get login_path
   post login_path, params: {session: { email: @user.email, password: 'password'}}
   assert is_logged_in?
   assert_redirected_to @user
   follow_redirect!
   assert_template 'users/show'
   assert_select "a[href=?]", login_path, count: 0
   assert_select "a[href=?]", logout_path
   assert_select "a[href=?]", user_path(@user)
   delete logout_path
   assert_not is_logged_in?
   assert_redirected_to root_url
   # 2番目のウィンドウでログアウトをクリックするユーザーをシミュレートする
   delete logout_path
   follow_redirect!
   assert_select "a[href=?]", login_path
   assert_select "a[href=?]", logout_path,     count: 0
   assert_select "a[href=?]", user_path(@user), count: 0
  end

  test "login with remembering" do
     log_in_as(@user, remember_me: '1')
     assert_not_nil cookies['remember_token']
   end

   test "login without remembering" do
     log_in_as(@user, remember_me: '0')
     assert_nil cookies["remember_token"]
   end

end


user.rb

class User < ApplicationRecord
  attr_accessor :remember_token
  before_save {self.email = email.downcase}
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: {case_sensitive: false }

  has_secure_password
  validates :password, presence: true, length: {minimum: 6}
  mount_uploader :image, ImageUploader

  # 与えられた文字列のハッシュ値を返す
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  def User.new_token
     SecureRandom.urlsafe_base64
  end

  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  def authenticated?(remember_token)
    return false if remember_digest.nil?
   BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end
   # ユーザーログインを破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end


end


Rails tutorialの8章でremember_me機能のテストを実行しているのですが以下の写真のように上手くいきません。
イメージ説明
これは上記に添付したusers_login_test.rbにおいてassert_nil cookies["remember_token"]の中の値がnilになることを求めているのですが、nilになっていません。
チュートリアルによると、ここまででテストは成功する事になっています。
なんどコードを確認してもRails tutorialに記載されているのと同じように見えます。
それとも自分が見落としていて、どこかおかしなコードがあるのでしょうか?
ストレスで夢の中でmacを破壊していました
どなたかご教授頂けたら非常に嬉しいです。
参考までにRails tutorial8章のリンクを以下に添付いたします。
リンク内容

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asm

    2019/01/22 00:28

    app/controllers/sessions_controller.rb
    はどうなっていますか?

    また、単なる興味ですが・・・
    Rails4.2版を用いているのには何か理由があるのでしょうか?

    キャンセル

  • yonamine

    2019/01/22 00:41

    コメントありがとうございます!
    sessions_controller.rbを追加いたしました。
    今ターミナルで確認したところ自分が使っているバージョンはRails 5.2.2と表記されました。

    キャンセル

回答 1

checkベストアンサー

0

      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      remember user

ここ
remember(user)をせっかく3項演算子で避けた後に
もう一度remember userしているので
forgetした意味がなくなっています。

remember userを消してください


別段理由がないなら最新版(Rails5.1対応)のRailsチュートリアルをオススメします

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/22 01:02 編集

    いや感動しました
    6時間ぐらい格闘しました。
    二回も回答して頂きありがとうございます。
    アドバイスもありがとうございます
    フォーロさせて頂きます。

    キャンセル

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

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる