Я понимаю, что этот вопрос задавался до в различных формах .
Однако я изо всех силс чем-то, что, кажется, не решается в этих ответах.Мой вошедший в систему пользователь не сохраняется в спецификации.
Как вы должны реплицировать аутентификацию / авторизованных пользователей в спецификации запроса?
Вот что япопробовал, и что я делаю.Я использую Auth0 в качестве обработчика аутентификации.У меня есть метод входа, который вызывается в обратном вызове Auth0, поэтому я настроил конечную точку mock_auth для своих тестов, чтобы использовать объект ресурса.
Это моя текущая настройка и то, что я сделал дляпопробуйте скопировать поток входа.
#/spec/requests/api/v1/account_spec.rb
RSpec.describe "API V1 Accounts", type: :request do
# Factories.
...
describe "PATCH update" do
subject(:http_request) { patch endpoint, params: { account: account_params, format: :json } }
# set some defaults
let(:id) { account.id }
let(:endpoint) { "/api/v1/accounts/#{id}" }
let(:account_params) { {} }
# Configure subdomain contstraint
within_subdomain :api do
before do |example|
mock_login(resource) unless example.metadata[:skip_signin]
http_request
end
context "when no resource is logged in", :skip_signin do
# This spec passes fine, as it's skipping login.
it_behaves_like "an unauthenticated private api request"
end
context "when there is no record to be found" do
let(:id) { SecureRandom.uuid }
let(:resource) { create(:user) }
it "fails to access a record" do
expect(response).to have_http_status(:not_found)
end
end
xcontext "when the user has access permission" do
end
end
end
end
-
# config/routes.rb
post "/auth/mock/:id", to: "auth#mock", as: :mock_login if Rails.env.test?
-
# auth_controller.rb
def mock
return unless Rails.env.test?
@resource = User.find_by(params[:id]
signin(@resource)
end
def signin(resource)
reset_session
create_session(resource)
after_signin_redirect_for(resource)
end
, и я использую этот помощник, чтобы вызвать его из моей спецификации запроса
module Helpers
module Auth
def mock_login(resource)
post mock_login_path(resource.id)
end
end
end
RSpec.configure do |config|
config.include Helpers::Auth, type: :request
end
Так.Оббирая кучу отладчиков и binding.pry, я вижу, что мой mock_login (ресурс) вызывается успешно, и в конце метода signin
мой помощник signed_in?
равен true
.Успешно настроив сеанс.
Проблема, с которой я сталкиваюсь сейчас, заключается в том, что это не сохраняется в спецификации объектов при запуске в блоке before или в блоке it.
before do |example|
mock_login(resource) unless example.metadata[:skip_signin] # signed_in? == true!
http_request # signed_in? == nil
end
module API
module V1
class AccountsController < APIController
before_action :authenticate_resource!
# ^ This is where the spec is failing to recognise the signed in resource from the mock_login method.
before_action :set_account
# PATCH /api/v1/accounts/:id
def patch_update
# Cancancan Authorization
authorize! :update, @account
# handle patch
...
end
private
def set_account
binding.pry # We're never making it here.
@account = Account.find_by(id: params[:id])
end
...
end
end
end
def authenticate_resource!
return true if signed_in?
respond_to do |format|
format.json { head(:unauthorized) }
end
end
EDIT:Несколько изменений, чтобы было понятнее, о чем я спрашиваю.