I'm having a small issue with testing in Rails 7 (API mode). I try to set the current user manually in my test, this way, when the server resolve the route/method and controller, it checks for authentication, which is skipped in testing environment, and then returns what its supposed to return. Unfortunaly, the User.current is reset somehow and I'm not sure why and where. I do not have other method that is called before reaching the controller.
require 'test_helper'
class ThingControllerTest < ActionDispatch::IntegrationTest
test "call method my_method" do
me = users(:me)
User.current = me
get("/api/users/#{me.id}/do-the-thing")
assert_response :success
end
end
class ApplicationController < ActionController::Base
before_action do |c|
authenticate_user
end
def authenticate_user
return User.current if Rails.env.test?
# lots of stuff going on otherwise
end
end
class ThingController < ApplicationController
# GET /users/:id/do-the-thing
def the_thing
user = User.find(params[:id])
if (User.current != user) # User.current is nil here
render json: {}, status: 500
return
end
render json: {}, status: 200
end
end
I tried setting manually the current user but it seems like when it lands in the authenticate_user, the User.current is already nil. Thanks !
Found a workaround, I made an AuthHelper module for my controller tests, this way my ApplicationController::authenticate_user has no longer the weird condition for the Rails environment.
# test/test_helpers/auth_helper.rb
module AuthHelper
def headers_jwt_auth(user)
iat = Time.now
exp = iat + 4.hours
payload = {iat: iat.to_i, exp: exp.to_i, some_other_stuff: nil}
secret = Rails.application.credentials.jwt_secret
return { Authorization: JWT.encode(payload, secret, 'HS256') }
end
end
and
# test/controllers/thing_controller_test.rb
require 'test_helper'
require "test_helpers/auth_helper"
class ThingControllerTest < ActionDispatch::IntegrationTest
include AuthHelper
test "call method my_method" do
me = users(:me)
User.current = me
get("/api/users/#{me.id}/do-the-thing", headers: headers_jwt_auth(User.current))
assert_response :success
end
end