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