I'm writing rspecs for my ruby on rails application, and I'm using google for my authentication. I had my specs all setup fine before I added auth, but now I need some way to test an authenticated user. Here is what one of my specs looks like.
require 'rails_helper' RSpec.describe 'Test', type: :request do it 'should return 200' do get '/test' expect(response).to have_http_status(:ok) end end
This is failing with a 401 as it rightfully should be.
I need to add the authentication information into the session variable so the controller can recognize that the user is logged in, but there doesn't seem to be a way to modify the session variable from rspec. I guess I could make a test google account and setup some helpers that would log me into a real google account, but it seems like there should be a better way to write tests. I've seen a couple of examples online, but most seem to be for older versions of rails.
I'm on Rails 126.96.36.199 and ruby 3.2.2
Edit: It occurs to me that I should probably include my auth code.
class ApplicationController < ActionController::Base before_action :require_auth private def require_auth user_id = session[:user_id] if !user_id.present? head :unauthorized else @auth_user = User.find(user_id) if !@auth_user.present? head :unauthorized end end end end
As far as I know there is no way of easily modifying session variables in the test setup for RSpec request specs unless you add the
rack_session_access gem or a similar solution.
One approach is to just mock the
auth_user object in the tests that require a logged in user.
class ApplicationController < ActionController::Base before_action :require_auth private def auth_user @auth_user ||= User.find_by(id: session[:user_id]) end def require_auth head(:unauthorized) unless auth_user.present? end end # spec/support/test_macros.rb module TestMacros def log_in(user) allow_any_instance_of(ApplicationController).to receive(:auth_user).and_return(user) end end # spec/rails_helper.rb RSpec.configure do |config| config.include(TestMacros) end it 'should return 200' do user = # create or fabricate user log_in(user) get '/test' expect(response).to have_http_status(:ok) end