已验证的请求规范

时间:2019-03-11 23:26:19

标签: ruby-on-rails rspec

我知道这个问题是asked before中的various forms

但是,我正在努力解决似乎无法在这些答案中解决的问题。我登录的用户不在规范内。

您应该如何在请求规范中复制身份验证/登录的用户?

这是我尝试过的事情,也是我正在做的事情。 我正在使用Auth0作为身份验证处理程序。我有一个在Auth0回调中调用的登录方法,因此我为自己的测试拼凑了一个模拟_认证端点,以利用资源对象。

这是我当前的设置,也是我尝试复制登录流程时所做的工作。

#/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,我可以看到我的嘲笑(resource)已成功调用,并且在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

编辑:进行了一些更改,以使我的要求更加清楚。

0 个答案:

没有答案