Ruby
Rails
RSpec
Capybara
OmniAuth

RSpec, Capybara - OmniAuthのテスト

More than 3 years have passed since last update.


経緯


やり方


OmniAuthをテストモードにセット


/spec/rails_helper.rb

#...

OmniAuth.config.test_mode = true
#...


warden's built in stubbing actionsを利用するための設定


  • 簡単にログイン・ログアウトができるようにするため。

  • 本テストではlogout :userのみ使用した。

  • 通常の処理を飛ばして即ログイン・ログアウトが可能になる。


/spec/rails_helper.rb

#...

RSpec.configure do |config|
#...

include Warden::Test::Helpers
Warden.test_mode!

#...
end



ログイン用ユーティリティー


/spec/support/utilities.rb

# no_capybara: true\false

def log_in_as(user, options={})
# For controller specs
if options[:no_capybara]
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in user
# For feature specs
else
visit new_user_session_path
fill_in "Email", with: user.email.upcase
fill_in "Password", with: user.password
click_button "Log in"
end
user
end


認証データのmockを準備


  • 成功と失敗の2パターンを作った。

  • Twitterのみでテストする。


/spec/support/omniauth_utils.rb

def set_omniauth

OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
"provider" => "twitter",
"uid" => "mock_uid_1234",
"info" => {
"name" => "Mock User",
"image" => "http://mock_image_url.com"
},
"credentials" => {
"token" => "mock_credentials_token",
"secret" => "mock_credentials_secret"
},
"extra" => {
"raw_info" => {
"name" => "Mock User",
"id" => "mock_uid_1234"
}
}
})
end

def set_invalid_omniauth
OmniAuth.config.mock_auth[:twitter] = :invalid_credentials
end



フィーチャーテスト


/spec/features/omniauth_spec.rb

require 'rails_helper'

feature "OmniAuth interface" do

before { OmniAuth.config.mock_auth[:twitter] = nil }

describe "new user or non-logged-in user who is not registered with Twitter" do
let(:submit) { "Sign up / Log in with Twitter" }

describe "authentication error" do
before do
visit root_path
set_invalid_omniauth
click_link(submit)
end

it { expect(page).to have_content('Could not authenticate you from Twitter') }
end

describe "authentication success" do
before do
visit root_path
set_omniauth
click_link(submit)
end

it "asks user for email address" do
expect(page).to have_content("need your email address")
end

describe "filling out the form" do
let(:continue) { "Continue" }

describe "with temporary email" do
before do
find("#user_username").set "User Example"
find("#user_email").set "change@me.temporary.com"
click_button(continue)
end

it { expect(page).to have_content("error") }
end

describe "with valid information" do
before do
find("#user_username").set "User Example"
find("#user_email").set "user@example.com"
click_button(continue)
end

it { expect(page).to have_content("sent you a confirmation email") }
end
end
end
end

describe "non-logged-in user who is registered with Twitter" do
let(:submit) { "Sign up / Log in with Twitter" }
let!(:user) do
user = create(:user)
attrs = attributes_for(:social_profile)
attrs["uid"] = "mock_uid_1234"
user.social_profiles.create(attrs)
user.confirm!
user
end

before do
visit root_path
set_omniauth
click_link(submit)
end

it "can log in with Twitter" do
expect(current_path).to eq movings_path
expect(page).to have_content(user.username)
expect(page).to have_content(user.email)
end
end

describe "logged-in user who is an omniauth first-timer" do
let(:user) { create(:user) }

before do
log_in_as user
visit root_path
set_omniauth
end

it "not registered with Twitter" do
expect(page).to have_css(".twitter-connect")
expect(page).not_to have_css(".twitter-icon")
expect(user.social_profile(:twitter)).to be_nil
end

describe "clicking on Twitter button" do
before { find(".twitter-connect").click }

it "connects to Twitter" do
expect(page).to have_content("Successfully authenticated from Twitter account")
expect(page).to have_content("Disconnect")
expect(page).to have_css(".twitter-icon")
expect(user.social_profile(:twitter)).not_to be_nil
end

describe "logging out" do
let(:submit) { "Sign up / Log in with Twitter" }
before do
logout :user
visit root_path
set_omniauth
click_link(submit)
end

it "can log in with Twitter" do
expect(current_path).to eq movings_path
expect(page).to have_content(user.username)
expect(page).to have_content(user.email)
end

describe "clicking on Twitter button" do
before { find(".twitter-connect").click }

it "disconnects from Twitter" do
expect(page).to have_content("Disconnected")
expect(page).to have_content("Connect")
expect(page).not_to have_css(".twitter-icon")
expect(user.social_profile(:twitter)).to be_nil
end
end
end
end
end
end


Screenshot 2015-08-15 09.42.19.png


資料