How to do request spec for JWT authenticate app using RSpec

Metropolis picture Metropolis · Feb 19, 2017 · Viewed 7.2k times · Source

I have a Rails 5 API only app and using knock to do JWT authenticate.

After complete the model and model spec, I start to do the request spec.

But I have no idea how to complete the authentication inside the request spec in the right way,

My users controller,

module V1
  class UsersController < ApplicationController
    before_action :authenticate_user, except: [:create]
  end
end

Application controller,

class ApplicationController < ActionController::API
  include Knock::Authenticable
  include ActionController::Serialization
end

My stupidest solution (call the get token request to get the JWT before the rest request),

context 'when the request contains an authentication header' do
  it 'should return the user info' do
    user  = create(:user)
    post '/user_token', params: {"auth": {"email": user.email, "password": user.password }}
    body = response.body
    puts body # {"jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0ODgxMDgxMDYsInN1YiI6MX0.GDBHPzbivclJfwSTswXhDkV0TCFCybJFDrjBnLIfN3Q"}
    # use the retrieved JWT for future requests
  end
end

Any advice is appreciated.

Answer

Metropolis picture Metropolis · Feb 19, 2017
  def authenticated_header(user)
    token = Knock::AuthToken.new(payload: { sub: user.id }).token
    { 'Authorization': "Bearer #{token}" }
  end

  describe 'GET /users?me=true' do
    URL = '/v1/users?me=true'
    AUTH_URL = '/user_token'

    context 'when the request with NO authentication header' do
      it 'should return unauth for retrieve current user info before login' do
        get URL
        expect(response).to have_http_status(:unauthorized)
      end
    end

    context 'when the request contains an authentication header' do
      it 'should return the user info' do
        user  = create(:user)

        get URL, headers: authenticated_header(user)
        puts response.body
      end
    end
  end