Search code examples
ruby-on-railsintegration-testingomniauthminitestomniauth-google-oauth2

Using MiniTest, when trying to test `omniauth-google-oauth2` gem I keep getting a 302 redirect to my sign_in path


I've setup omniauth-google-oauth2 gem with my rails application. And it works but while I try to write my test for it I keep getting a 302 redirect. Many of the website results I've seen reference how to test it in Rspec, but I'm trying to do it with MiniTest that comes with Rails. Since I'm new to it I'm struggling seeing where I'm messing things up.

routes.rb

Rails.application.routes.draw do

  devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }

  devise_scope :user do
      get 'sign_in', :to => 'devise/sessions#new', :as => :new_user_session
      get 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
    end

  root to: "home#index"

end

test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require 'mocha/minitest'

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  def setup_omniauth_mock(user)
    OmniAuth.config.test_mode = true
      OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
        provider: "google_oauth2",
        email: "#{user.email}",
        first_name: "#{user.first_name}",
        last_name: "#{user.last_name}"
      })
      Rails.application.env_config["devise.mapping"] = Devise.mappings[:user]
    Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
  end

  def login_with_user(user)
    setup_omniauth_mock(user)
    get user_google_oauth2_omniauth_authorize_path
  end

end

module ActionController
    class TestCase
        include Devise::Test::ControllerHelpers
    end
end

module ActionDispatch
    class IntegrationTest
        include Devise::Test::IntegrationHelpers
    end
end

test/integration/login_with_google_oauth2_test.rb

require 'test_helper'

class LoginWithGoogleOauth2Test < ActionDispatch::IntegrationTest
  setup do
    @user = users(:one)
  end

  test "allows a logged-in user to view the home page" do 
    login_with_user(@user)
    get root_path
    assert_redirected_to root_path
    assert_selector "h1", text: "#{user.full_name}"
  end

end

Error when running rails test

daveomcd@mcdonald-PC9020:~/rails_projects/haystack_scout$ rails test
Running via Spring preloader in process 24855
/home/daveomcd/.rvm/gems/ruby-2.5.1/gems/spring-2.0.2/lib/spring/application.rb:185: warning: Insecure world writable dir /home/daveomcd/.rvm/gems/ruby-2.5.1/bin in PATH, mode 040777
Run options: --seed 55919

# Running:

.....F

Failure:
LoginWithGoogleOauth2Test#test_allows_a_logged-in_user_to_view_the_home_page [/mnt/c/Users/mcdonaldd/Documents/Rails Projects/haystack_scout/test/integration/login_with_google_oauth2_test.rb:20]:
Expected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/sign_in>.
Expected "http://www.example.com/" to be === "http://www.example.com/sign_in".


bin/rails test test/integration/login_with_google_oauth2_test.rb:17



Finished in 0.238680s, 25.1383 runs/s, 50.2766 assertions/s.
6 runs, 12 assertions, 1 failures, 0 errors, 0 skips

Solution

  • So I've been able to figure out a means to testing omniauth-google-oauth2. I'll do my best to show it below. Thanks to anyone who took the time to look into my question.

    test\integration\authorization_integration_test.rb

    require 'test_helper'
    
    class AuthorizationIntegrationTest < ActionDispatch::IntegrationTest
      include Capybara::DSL
      include Capybara::Minitest::Assertions
      include Devise::Test::IntegrationHelpers
    
        setup do
            OmniAuth.config.test_mode = true
            Rails.application.env_config["devise.mapping"] = Devise.mappings[:user]
            Rails.application.env_config["omniauth.auth"]  = google_oauth2_mock
        end
    
        teardown do
            OmniAuth.config.test_mode = false
        end
    
        test "authorizes and sets user currently in database with Google OAuth" do
            visit root_path
            assert page.has_content? "Sign in with Google"  
            click_link "Sign in with Google"
            assert page.has_content? "Successfully authenticated from Google account."
        end
    
        private
    
            def google_oauth2_mock
                OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
                provider: "google_oauth2",
                uid: "12345678910",
                info: { 
                    email: "[email protected]",
                    first_name: "David",
                    last_name: "McDonald"
                },
                credentials: {
                    token: "abcdefgh12345",
                    refresh_token: "12345abcdefgh",
                    expires_at: DateTime.now
                }
              })
            end
    
    end