How to test Rails devise login with token auth in a RESTful API with RSpec?

Viewed 3139

I built a RESTful API using Ruby on Rails and am now at the point of only letting authenticated users make requests. Therefore I implemented an ApiController:

class ApiController < ApplicationController
  include DeviseTokenAuth::Concerns::SetUserByToken
  before_action :authenticate_api_v1_user!
end

I use a React client that sends the required auth headers with every request. It all works well so far. Only that I have problems simulating the login in my request specs.

In theory, I would create a user and log them in. But how do I send the token along with the request?

describe 'Items API', type: :request do
  # initialize test data
  let!(:user) { create(:user) }
  let!(:items) { create_list(:item, 10) }

  # Test suite for GET /api/v1/items
  describe 'GET /api/v1/items' do
    # make HTTP get request before each example
    before { get '/api/v1/items' }

    it 'returns items' do
      expect(json).not_to be_empty
      expect(json.size).to eq(10)
    end

    it 'returns status code 200' do
      expect(response).to have_http_status(200)
    end
  end

  ...

end

The crucial part of the request is the request cookie:

authHeaders {
  "access-token":"sMKTl2Zx_8S5f12ydhSaPw",
  "token-type":"Bearer",
  "client":"rzarzdBXCv2SsS9XvYMLVA",
  "expiry":"1546427742",
  "uid":"104006675969015609263"
}

It is sent along with the request.

3 Answers

Not sure, but one work around could be to sign in user and then add auth token to the header params.

Module AuthSpecHelper
  def auth_spec_request(user)
    request.headers.merge!(user.create_new_auth_token) if sign_in(user)
  end
end

I found this on the Devise Wiki: How To: sign in and out a user in Request type specs (specs tagged with type: :request)

...but a simpler approach is to just:

spec/rails_helper.rb

RSpec.configure do |config|
  # ...
  config.include Devise::Test::IntegrationHelpers, type: :request
end

And just use sign_in in your request spec.

This is the equivalent of declaring include Devise::Test::IntegrationHelpers in an system/feature spec or Rails system/controller test.

Related