Random Developments And Random Toys

DRY up your API integration specs

Once we established that our API code is correctly wired to a component like Doorkeeper then there’s no point in repeating the fact that every request needs to include one or another kind of token header, for example:

  it '...' do
      get '/me', nil, { 'Authorization' => "Bearer #{token.token}" }
      # ... rest of the testcase
  end

For request/integration specs this could be easily replaced by:

  before(:each) { use_token_of(user) }

  it '...' do
      get '/me'
      # ... rest of the testcase
  end

In most of my projects I have the following helper:

module OAuthHelper
  def oauth_token_of(user)
    Doorkeeper::AccessToken
      .where(resource_owner_id: user.id).last.token
  end

  def use_token_of(user)
    @token = oauth_token_of(user)
  end

  def get(*args)
    args = with_auth_header(args)
    super(*args)
  end

  def post(*args)
    args = with_auth_header(args)
    super(*args)
  end

  def put(*args)
    args = with_auth_header(args)
    super(*args)
  end

  private

  def with_auth_header(args)
    if @token
      header = { 'Authorization' => 'Bearer ' + @token }
      header = args[2].merge(header) if args[2].is_a?(Hash)
      args[2] = header
    end

    args
  end
end

Make sure this gets loaded only for request specs by adding the following to spec/rails_helper.rb config block:

config.include OAuthHelper, type: :request

And finally get FactoryGirl create you authorised user instances:

FactoryGirl.define do
  factory :user do
    # ... skipped

    trait :authorized do
      after(:create) do |user|
        create(:access_token, resource_owner_id: user.id)
      end
    end
  end
end

Comments

Want to read / submit comments? Click the button below to enable. Do note that site is using Disqus comments.