Спецификация запроса с проверкой подлинности - PullRequest
0 голосов
/ 12 марта 2019

Я понимаю, что этот вопрос задавался до в различных формах .

Однако я изо всех силс чем-то, что, кажется, не решается в этих ответах.Мой вошедший в систему пользователь не сохраняется в спецификации.

Как вы должны реплицировать аутентификацию / авторизованных пользователей в спецификации запроса?

Вот что япопробовал, и что я делаю.Я использую 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:Несколько изменений, чтобы было понятнее, о чем я спрашиваю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...