I am trying to stub out the @current_user that gets set in my concern for use in controllers. I am using a concern for authenticating a JWT and setting the @current_user in the concern. The JWTs get signed and verified from a third party so I am bypassing that step for testing purposes but need a way to setup @current_user. Below are my following files:
app/controllers/concerns/secured.rb
module Secured
extend ActiveSupport::Concern
def authorize
token = token_from_request
return if performed?
validation_response = client.verify_token_from_third_party # this is an external api call
@decoded_token = validation_response.decoded_token[0][0]
@current_user = User.find_by(id: @decoded_token["sub"])
return unless (error = validation_response.error)
render json: { message: error.message }, status: error.status
end
end
app/controllers/books_controller.rb
class BookssController < ApplicationController
before_action :set_book, only: %i[ show update destroy ]
before_action :authorize
# POST /books
def create
@books = Book.new(book_params.merge({user_id: @current_user.id}))
if @book.save
render json: @book, status: :created, location: @book
else
render json: @book.errors, status: :unprocessable_entity
end
end
end
spec/controllers/book_spec.rb
require 'rails_helper'
RSpec.describe BooksController do
let(:current_user) { User.create(username: "Joe") }
before :each do
allow(controller).to receive(:authorize).and_return(current_user)
end
context 'book creation' do
it 'authenticated user can create book' do #
post :create, :params => { :book => {:name => "Some Book"} }
expect(response).to have_http_status(:created)
end
end
end
The error:
1) BooksController book creation authenticated user can create book
Failure/Error: @book = Book.new(book_params.merge({user_id: @current_user.id}))
NoMethodError:
undefined method `id' for nil:NilClass
# ./app/controllers/books_controller.rb:23:in `create'
# ./spec/controllers/book_spec.rb:11:in `block (3 levels) in <top (required)>'
Finished in 0.10782 seconds (files took 1.13 seconds to load)
1 example, 1 failure
My goal is to be able to bypass the before_action :authorize in the specs and setup the @current_user myself
I have tried variations of .instance_variable_set, allows, etc. My inkling is I probably have to rework how the concern sets the @current_user but I haven't been able to figure it out