LoginSignup
23
23

RSpec, Capybara - OmniAuthのテスト

Last updated at Posted at 2015-08-10

#経緯

#やり方

##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

#資料

23
23
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
23
23