Search code examples
ruby-on-railstestingrspecoauthdoorkeeper

How do I write RSpec tests that require an OAuth2 access token?


I'm writing RSpec tests for a Rails API that is partially protected with OAuth2. I need to write tests such as

  • GET ResourcesController#index
    • when access_token is provided
      • shows a list of resources
    • when access_token is not provided
      • returns no content

and stuff like that. I thought I could use the oauth2 gem, but I soon realised that that works by issuing actual HTTP requests to the Rails app. I'm a little lost, can someone point me in the right direction?

EDIT Some further info

I'm using Doorkeeper to implement OAuth2. My question has to do with the fact that some methods of my controllers are hidden behind something like the following:

before_action :doorkeeper_authorize!, only: [:update, :destroy]

which verifies the presence, and validity, of an authentication token. Now, these tokens have to exist in the database. My question then is how do I, either

  • put these tokens in the database (aka, how do I simulate a correct login within a RSpec test), or
  • trick Doorkeeper (via stubbing?) to think that these tokens exist and are valid?

EDIT 2

Found this. Feel free to keep adding answers while I read this up.


Solution

  • You could still use oauth2 gem, it has many examples of stubbing acces tokens in its own test suite. Without a specifically pointed issue that you might be having it's hard to give more advice though.

    Alternatively, there is vcr gem which records http interactions and plays them out during testing. You could record your live API interactions and then use the playback to run your tests against.

    UPDATE

    After you mentioned the Doorkeeper and found its docs yourself, here is an example from the same source.

    describe Api::V1::ProfilesController do
      describe 'GET #index' do
        let(:token) { double :acceptable? => true }
    
        before do
          controller.stub(:doorkeeper_token) { token }
          # allow(controller).to receive(:doorkeeper_token) {token} # => RSpec 3
        end
    
        it 'responds with 200' do
          get :index, :format => :json
          response.status.should eq(200)
        end
      end
    end
    

    Stubbing :acceptable? => true will bypass the doorkeeper filter, since the token is valid. If you prefer to return false then the response status will be 401 unauthorized.