PKul
PKul

Reputation: 1711

How can I test omniauth-facebook in rails 5 with minitest

I read previous possible questions that may have the answer but that not what I asked for.

First of all I am start to use test. However I already successful setup Omniauth-facebook for my App but still like to go back and test.

-sessions_controller.rb

class SessionsController < ApplicationController
  def new
    @title= 'Sign In'
  end

  def create
    auth = request.env["omniauth.auth"]
    user = User.from_omniauth(auth)
    session[:user_id] = user.id
    if params.permit[:remember_me]
      cookies.permanent[:auth_token] = user.auth_token
    else
      cookies[:auth_token] = user.auth_token
    end
    refresh_to root_path, :ma_notice => "Logged in"
  rescue
    redirect_to root_path, :alert=> "Authentication failed, please try again."
  end

  def destroy
    #session[:user_id] = nil
    cookies.delete(:auth_token)
    refresh_to root_path, :ma_notice => "Logged Out"
  end

  def failure
    ma_log "Authentication failed, please try again."
    redirect_to root_path, :alert=> "Authentication failed, please try again."
  end
end

-app/models/user.rb

class User

  ....
  ....

  def self.from_omniauth(auth)
    where(auth.slice(:uid, :provider, :email)).first_or_create do |user|
      case auth.provider 
        when 'identity'
          identity = Identity.find auth.uid
          user.code = identity.code
          user.email = identity.email
        else
          user.email = auth.info.email
          user.uid = auth.uid
          user.provider = auth.provider
          user.code = auth.info.name
          user.role = "M"
        end
      end
    end

  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
end

So what I did

  1. Test routes (Its seem simple but sometime I might forgot because I changing from dynamic route to fixed route as required in rails 5.2)

-test/integration/authen_test.rb

require 'test_helper'
class RoutesTest < ActionController::TestCase
  test 'facebook login' do
    assert_routing '/auth/facebook/callback', {controller: 'sessions', action: 'create',provider: 'facebook'}
  end

  test 'facebook login post' do
    assert_routing({path: '/auth/facebook/callback', method: 'post'},{controller: 'sessions', action: 'create' ,provider: 'facebook'})
  end
end
  1. I want to test if facebook accept login and return call back.

-test/models/user_test.rb

require 'test_helper'
class UserTest < ActiveSupport::TestCase
  test "Facebook  validation" do 
    auth = {provider: :facebook, FACEBOOK_API: "111111111111111", FACEBOOK_KEY: "11111111111111111111111111111111"}
    user = User.from_omniauth(auth)
    puts user
    assert_not nil
  end
end

Problem: It's always green even change FACEBOOK_API. I found the user from puts as well. It's seem like user.from _omniauth already gone to facebook and get info using FACEBOOK_API from .env not one I provided. Then how I can test if it really connected with facebook.

The same with this related test. It's always green in any FACEBOOI_API. That won't work as well.

  1. View Test. I like to test if no facebook login the system or not. The login would display accordingly. Still have no idea as stuck with Q.2 perhap someone could share how you do the test.

  2. To Setup Integration Testing-Omniauth as documented

You can turn on "test mode" for OmniAuth like so:

OmniAuth.config.test_mode = true Once you have enabled test mode, all requests to OmniAuth will be short circuited to use the mock authentication hash as described below. A request to /auth/provider will redirect immediately to /auth/provider/callback.

Then said

OmniAuth.config.add_mock(:twitter, {:uid => '12345'})

OK but where to put that code to turn on so I assumed the only one is -config/initializer/omniauth.rb

    Rails.application.config.middleware.use OmniAuth::Builder do
      provider :identity,
        :fields => [:code, :email],
        :on_failed_registration=> lambda { |env|
          IdentitiesController.action(:new).call(env)
      }
      provider :facebook, ENV['FACEBOOK_API'], ENV['FACEBOOK_KEY']
     OmniAuth.config.test_mode = true
     OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
    end

Here I used test from related question but used my method :create. It didn't do anything than green, even changed .test_mode = false

-test/integration/sessions_controller_test.rb

require 'test_helper'

class SessionsControllerTest < ActionController::TestCase

    test '#signup_success' do
        OmniAuth.config.test_mode = true
        OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
            'provider' => 'facebook',
            'uid' => '123451234512345',
            'info' => {'email' => 'testuser@testmail.com', 'name' => 'test', 'image' => ''}
        })
        request.env['omniauth.env'] = OmniAuth.config.mock_auth[:facebook]
        get :create
    end
end

Upvotes: 2

Views: 1295

Answers (2)

Aishwarya
Aishwarya

Reputation: 3

What i did and what worked for me was setting up mocks in my spec_helper file for various scenarios.

OmniAuth.config.test_mode = true
  omniauth_hash = { 'provider' => 'twitter',
                    'uid' => '12345',
                    'info' => {
                      'name' => 'test',
                      'email' => 'test@test.com',
                      'nickname' => 'testnick'
                    },
                    'extra' => {
                      'raw_info' =>
                                  { 
                                    'location' => 'Coralvilleo'
                                  }
                    }
  }

  omniauth_hash_fb = { 'provider' => 'facebook',
                       'uid' => '12345',
                       'info' => {
                         'name' => 'test',
                         'email' => 'test@testsomething.com'
                       },
                       'extra' => {'raw_info' =>
                                    { 'location' => 'Chicago'
                                    }
                    }
  }

  omniauth_hash_fail = { 'provider' => 'facebook',
                         'uid' => '12345',
                         'info' => {

                       },
                         'extra' => {'raw_info' =>
                                       { 'location' => 'Chicago'
                                       }
                       }
  }
  omniauth_hash_fail_2 = { 'provider' => 'facebook',
                           'uid' => '12345',
                           'info' => {

                         },
                           'extra' => {'raw_info' =>
                                         { 'location' => 'Chicago'
                                         }
                         }
  }
  omniauth_hash_fail_complete = { 'provider' => 'twitter'}
  OmniAuth.config.add_mock(:twitter, omniauth_hash)
  OmniAuth.config.add_mock(:facebook, omniauth_hash_fb)
  OmniAuth.config.add_mock(:facebook_fail, omniauth_hash_fail)
  OmniAuth.config.add_mock(:twitter_fail, omniauth_hash_fail_2)

Then using these methods in my rspec tests for controller like so.

 it 'should successfully create a user with twitter' do
        request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:twitter]
        expect {
          post :twitter, provider: :twitter
        }.to change{ User.count }.by(1)
      end

      it 'should redirect the user to the root url with twitter' do
        request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:twitter]
        post :twitter, provider: :twitter
        response.should redirect_to root_path
      end

name of the mocks to be specified and linked to what we specified in the helper.

OmniAuth.config.mock_auth[name of the mock you specified in spec helper].

Upvotes: 0

Rubyrider
Rubyrider

Reputation: 3587

You can use omniauth test helpers. Here is the link: https://github.com/omniauth/omniauth/wiki/Integration-Testing

Setup Mock Auth:

OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
  :provider => 'facebook',
  :uid => '123545'
  # etc.
})

Upvotes: 0

Related Questions