はじめに
- RSpec で devise + omniauth-google-oauth2 の構成で認証を利用している場合のリクエストテスト、システムテストを実施したい方を対象としております
- よって devise で Google 認証の実装が完了している前提です
環境など
開発環境一覧 |
---|
Windows11 Home 24H2 |
Ubuntsu |
Docker |
VScode |
Rails 7.2.1 |
参考コード
compose.yml
compose.yml
services:
db:
image: postgres
restart: always
environment:
TZ: Asia/Tokyo
POSTGRES_PASSWORD: password
volumes:
- postgresql_data:/var/lib/postgresql
ports:
- 5432:5432
healthcheck:
test: ["CMD-SHELL", "pg_isready -d myapp_development -U postgres"]
interval: 10s
timeout: 5s
retries: 5
web:
build:
context: .
dockerfile: Dockerfile.dev
command: bash -c "bundle install && bundle exec rails db:prepare && rm -f tmp/pids/server.pid && ./bin/dev"
tty: true
stdin_open: true
volumes:
- .:/myapp
- bundle_data:/usr/local/bundle:cached
- node_modules:/myapp/node_modules
environment:
TZ: Asia/Tokyo
SELENIUM_DRIVER_URL: http://selenium_chrome:4444/wd/hub
ports:
- "3000:3000"
user: "1000:1000"
depends_on:
db:
condition: service_healthy
selenium_chrome:
image: selenium/standalone-chrome
ports:
- "4444:4444"
logging:
driver: none
volumes:
bundle_data:
postgresql_data:
node_modules:
Gemfile
Gemfile
gem "rails", "~> 7.2.1"
gem "devise", "~> 4.9"
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "capybara"
gem "selenium-webdriver"
gem "webdrivers"
end
1. ユーザーの情報を管理するモデルクラスの確認
-
def self.from_omniauth(auth)
といったメソッドを定義して Google 認証時に"どんな情報を取得してきているか"など を定義しているかと思います- 人によっては Google アカウント名、プロフィール画像を合わせて取得してきていると思われるので事前に確認
- 人によっては Google アカウント名、プロフィール画像を合わせて取得してきていると思われるので事前に確認
- 以下、私の例になりますが Google 認証時に 'Google メールアドレス' を取得するように定義しております
- またメールアドレス認証を導入しているため、Google 認証利用時はメール認証をスキップするようにしております
app/models/user.rb
class User < ApplicationRecord
########## 【前略】##########
# https://github.com/heartcombo/devise/wiki/OmniAuth%3A-Overview
def self.from_omniauth(auth)
user = where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0, 20]
end
user.skip_confirmation! # メール認証のスキップ
user.save
user
end
########## 【後略】 ###########
end
2. RSpec テストで Devise 関連の設定を施す
spec/rails_helper.rb
RSpec.configure do |config|
########## 【中略】 ###########
# リクエストおよびシステムのテストを実施したため以下のような記述
config.include Devise::Test::IntegrationHelpers, type: :system
config.include Devise::Test::IntegrationHelpers, type: :request
config.include Warden::Test::Helpers
end
OmniAuth.configure do |c|
c.test_mode = true
c.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
provider: "google_oauth2",
uid: "12345abcde",
info: {
email: "john@example.com",
}
})
end
OmniAuth::AuthHash.new({
provider: "google_oauth2",
uid: "12345abcde",
info: {
email: "john@example.com",
}
})
-
info
にはemail
しか指定していませんが、これは前の手順の Google 認証時に"どんな情報を取得してきているか" で確認できた同じ項目を指定してください
-
モック
(Mock) … 「見せかけの、模型」- 疑似的に"Google 認証が成功した"と想定するテスト用の仮のオブジェクト
3. テスト内容の記述および実行
spec/factories/users.rb
FactoryBot.define do
##########【中略】##########
factory :google_user, class: User do
sequence(:email) { |n| "TEST#{n}@example.com" }
password { "testuser123" }
end
end
- 公式ドキュメントにもある通り以下の記述が必要となる
- Twitter ではないので
google_oauth2
に変更
- Twitter ではないので
before do
Rails.application.env_config["devise.mapping"] = Devise.mappings[:user] # If using Devise
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
end
spec/requests/signup_spec.rb
RSpec.describe "/XXXXX", type: :request do
describe 'GET /XXXXX' do
let(:google_user) { create(:google_user) }
before do
# https://github.com/omniauth/omniauth/wiki/Integration-Testing
Rails.application.env_config["devise.mapping"] = Devise.mappings[:user]
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
# メール認証のスキップ
google_user.confirm
# 認証のパス
get '/users/auth/google_oauth2/callback', params: { provider: "google_oauth2" }
end
it 'レスポンスでHTTPメッセージ302を返すこと' do
expect(response).to have_http_status(302)
end
end
end
spec/system/user_spec.rb
##########【前略】##########
it "Google認証が成功する" do
click_button('Continue with Google')
expect(page).to have_content('google アカウントによる認証に成功しました。')
end
end
##########【後略】##########
参考資料