How to stub out current_user in JWT model for Rspec?

34 views Asked by At

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

0

There are 0 answers