I'm attempting to write a request spec for a Rails app in API-only mode. In the UsersController, a before_action sets the @user using @uid (the primary key), which I'm attempting to assign in the spec.
User.uid is a custom primary key, User.find() works fine in development and production (as does everything else, I'm trying to learn how to test here). This is the error I receive in test:
Failure/Error @user = User.find(@uid)
ActiveRecord::RecordNotFound:
Couldn't find User without an ID
//controller
module Api
module V1
class UsersController < ApplicationController
before_action :set_user, only: %i[show update]
def show
render json: @user
end
private
def set_user
@user = User.find(@uid)
end
end
end
// request spec
require 'rails_helper'
require 'test_helper'
describe 'get user route' do
let!(:user) { FactoryBot.create(:user) }
before :each do
allow_any_instance_of(ApplicationController).to receive(:authorize).and_return(true)
@uid = user.uid
end
before { get '/api/v1/user' }
it 'returns status code 200' do
expect(response).to have_http_status(:success)
end
end
"authorize" is a before action on the ApplicationController that assigns @uid. I'm skipping it and trying to assign @uid to the created user's uid. There must be a better way to do this as well...
edit: I'm using Ruby 2.7.1 and the rspec-rails gem 4.0.1
The @uid is being set with a method in the ApplicationController which is used as a before_action. It's using a library to decode a firebase jwt and return an auth_user object which contains the uid.
class ApplicationController < ActionController::API
def authorize
auth_user = FirebaseIdToken::Signature.verify(params[:idToken])
@uid = auth_user ? auth_user['user_id'] : nil
render json: {}, status: 401 if @uid.nil?
end
end
I've read some posts that say that you lose the ability to set the instance variables by using a request spec (can't find this in the docs), because these types of specs are supposed to mimic a real scenario as much as possible. The controller instance variable is only available after the request so I'm not sure if it's possible at all to assign a controller's instance variable from a request spec.