0
0

More than 1 year has passed since last update.

【RSpec】Railsチュートリアル第6版 第9章

Last updated at Posted at 2021-11-03

はじめに

Railsチュートリアル第6版のテストをRSpecで書き直していく。

目次

Minitest

2番目のウィンドウでユーザーをログアウトするテスト

test/integration/users_login_test.rb
require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest
  .
  .
  .
  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
end

ダイジェストが存在しない場合のauthenticated?のテスト

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end
  .
  .
  .
  test "authenticated? should return false for a user with nil digest" do
    assert_not @user.authenticated?('')
  end
end

log_in_asヘルパーを追加する

test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
  fixtures :all

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

  # テストユーザーとしてログインする
  def log_in_as(user)
    session[:user_id] = user.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
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を削除してログイン
    log_in_as(@user, remember_me: '0')
    assert_empty cookies[:remember_token]
  end
end

永続的セッションのテスト

test/helpers/sessions_helper_test.rb
require 'test_helper'

class SessionsHelperTest < ActionView::TestCase

  def setup
    @user = users(:michael)
    remember(@user)
  end

  test "current_user returns right user when session is nil" do
    assert_equal @user, current_user
    assert is_logged_in?
  end

  test "current_user returns nil when remember digest is wrong" do
    @user.update_attribute(:remember_digest, User.digest(User.new_token))
    assert_nil current_user
  end
end

RSpec

2番目のウィンドウでユーザーをログアウトするテスト

spec/requests/users_sessions_spec.rb
require 'rails_helper'

RSpec.describe "session request", type: :request do

  let(:user) {FactoryBot.create(:user)}

  it "log in and log out" do
    post login_path, params: { session: {
      email: user.email,
      password: user.password,
    } }
    expect(response).to redirect_to user_path(user)
    expect(is_logged_in?).to be_truthy 
    delete logout_path
    expect(response).to redirect_to root_path
    expect(is_logged_in?).to be_falsey
    delete logout_path
    expect(response).to redirect_to root_path
    expect(is_logged_in?).to be_falsey
  end

end

is_logged_in?を使いたいので、request specに記述。

ダイジェストが存在しない場合のauthenticated?のテスト

spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do

  before do
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end
  .
  .
  .
  it "authenticated? should return false for a user with nil digest" do
    expect(@user.authenticated?("")).to be_falsy
  end

end

log_in_asヘルパーを追加する

spec/support/support.rb
module Support

  def is_logged_in?
      !session[:user_id].nil?
  end

  def log_in_as(user, remember_me: "1")
    post login_path, params: { session: {
      email: user.email,
      password: user.password,
      remember_me: remember_me,
    } }
  end

end

RSpec.configure do |config|
  config.include Support
end

[remember me]チェックボックスのテスト

spec/requests/users_sessions_spec.rb

require 'rails_helper'

RSpec.describe "UsersSessions", type: :request do

  let(:user) {FactoryBot.create(:user)}
  .
  .
  .
  it "login with remembering" do
    log_in_as(user, remember_me: "1")
    expect(cookies[:remember_token]).not_to eq ""
  end

  it "login without remembering" do
    log_in_as(user, remember_me: "1")
    expect(cookies[:remember_token]).not_to eq ""
    delete logout_path
    log_in_as(user, remember_me: "0")
    expect(cookies[:remember_token]).to eq ""
  end

end

永続的セッションのテスト

spec/helpers/sessions_helper_spec.rb

require 'rails_helper'

RSpec.describe SessionsHelper, type: :helper do

  let(:user) { FactoryBot.create(:user) }

  before do
    remember(user)
  end

  it "current_user returns right when session is nil" do
    expect(current_user).to eq user
    expect(is_logged_in?).to be_truthy
  end

  it "current_user returns nil when remember digest is wrong" do
    user.update_attribute(:remember_digest, User.digest(User.new_token))
    expect(current_user).to eq nil
  end

end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0