How to test OmniAuth Params

Chris Oliver

January 14, 2023

OmniAuth provides some tooling for mocking OAuth requests in your test suite. This is handy because your tests don't have to redirect to a production OAuth provider like Twitter, authenticate with real credentials, and then handle the response.

Instead, you can set test mode in OmniAuth and then add a mock OAuth provider. This will allow your tests to skip the production OAuth process and simulate it in your test environment.

One problem is testing additional params you might pass to OmniAuth. For testing, you normally just request the callback URL for the mock request. If you test only with the callback url however, the params will not be present. This is because the params are stored in the session, so you need an additional request beforehand to set those params in the session.

To test OmniAuth params, we need to first POST to the OmniAuth URL with params. This will make a fake request that sets the session OmniAuth params and sets a few other things. You can see exactly what it does here: https://github.com/omniauth/omniauth/blob/v2.1.0/lib/omniauth/strategy.rb#L317

Here's the relevant bit:

def mock_request_call
  setup_phase

  session['omniauth.params'] = request.GET
  # ...

After making the mock OAuth request, we can make the mock OAuth callback request to process it. This will now have access to omniauth.params in the session and we now have a functional test!

You can see here in the mock callback call that it sets omniauth.params to the params from the session:

@env['omniauth.params'] = session.delete('omniauth.params') || {}

Here's an example of how to test OmniAuth params with a Rails integration test. You can use this same process to test OmniAuth params with Rspec.

require "test_helper"

class OmniauthCallbacksTest < ActionDispatch::IntegrationTest
  setup do
    OmniAuth.config.test_mode = true
    OmniAuth.config.add_mock(:developer, uid: "12345", info: {email: "twitter@example.com"}, credentials: {token: 1})
  end

  test "can connect a social account with another model" do
    # Sets omniauth.params to {"foo" => "bar"} and redirects to the OmniAuth callback URL
    post "/users/auth/developer?foo=bar"

    # Process the OAuth callback which has omniauth.params set
    follow_redirect!

    # Add your assertions here
  end
end

P.S. You might enjoy following me on Twitter.


Comments

Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

© 2024 GoRails, LLC. All rights reserved.