Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a Rails 4 test for creating a session with the omniauth-google-oauth2 gem?

I'm attempting to write a test for the creation of a session with the omniauth-google-oauth2 gem. Do I need to pass the env["omniauth.auth"] variable with the post :create? Perhaps when I was attempting to do that I was doing it incorrectly. The error I'm getting is shown below...

Rake Test Error

  1) Error:
SessionsControllerTest#test_should_get_create:
NoMethodError: undefined method `provider' for nil:NilClass
    app/models/user.rb:6:in `from_omniauth'
    app/controllers/sessions_controller.rb:4:in `create'
    test/controllers/sessions_controller_test.rb:13:in `block in <class:SessionsControllerTest>'

The following is my attempt at writing the test...

SessionsControllerTest

require 'test_helper'

class SessionsControllerTest < ActionController::TestCase

  setup :prepare_omniauth

  test "should get create" do
    post :create
    redirect_to root_path, notice: "Signed in!"
  end

  test "should get destroy" do
    get :destroy
    assert session[:user_id].blank?, "user_id should no longer exist"
    assert_redirected_to root_path, notice: "Signed out!"
  end

  private

    def prepare_omniauth
      OmniAuth.config.test_mode = true
      OmniAuth.config.mock_auth[:google] = OmniAuth::AuthHash.new({
        :provider => 'google',
        :uid => '123545'
      })
      request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:google]
    end

end

Sessions Controller

class SessionsController < ApplicationController

  def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to root_path
  end

  def destroy
    session[:user_id] = nil unless session[:user_id].blank?
    redirect_to root_path
  end

end

User Model

class User < ActiveRecord::Base

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.oauth_token = auth.credentials.token
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save!
    end
  end

end
like image 714
daveomcd Avatar asked Jan 24 '15 20:01

daveomcd


1 Answers

I believe this blog has the answer to your question: http://natashatherobot.com/rails-test-omniauth-sessions-controller/

Basically you need to edit your rails_helper/spec_helper to set Omniauth's test mode to true and create an omniauth_hash to be used in your tests:

OmniAuth.config.test_mode = true
omniauth_hash = { 'provider' => 'github',
                  'uid' => '12345',
                  'info' => {
                      'name' => 'natasha',
                      'email' => '[email protected]',
                      'nickname' => 'NatashaTheRobot'
                  },
                  'extra' => {'raw_info' =>
                                  { 'location' => 'San Francisco',
                                    'gravatar_id' => '123456789'
                                  }
                  }
}

OmniAuth.config.add_mock(:github, omniauth_hash)

Then you require it before any tests:

before do
    request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:github]
end

Now you should be able to create users using Omniauth like in this example:

describe SessionsController do
    it "should successfully create a user" do
        expect {
            post :create, provider: :github
        }.to change{ User.count }.by(1)
    end
end

All credits to Natasha from http://natashatherobot.com for posting this answer in her blog.

like image 136
Lucas Moulin Avatar answered Oct 01 '22 08:10

Lucas Moulin