Rails Pundit Rspec 测试

Aus*_*tio 2 ruby-on-rails rspec-rails pundit

我在使用 Rspec 测试 Pundit 策略范围时遇到了障碍。基本上,我试图测试范围内的返回值是否严格限于用户。因此,我循环遍历为用户返回的所有问题,并确保 id 等于用户。

这是绿色的,但是当它是非公民角色时它会失败,因为 Scope 调用仅返回一个 Issue 对象。这不是什么大问题,因为每个角色都有一个 .where() 的范围,但这是一种代码味道,我可能做错了一些事情。

我有一个执行该操作的 IssueController

class IssuePolicy < ApplicationPolicy
  class Scope < Struct.new(:user, :scope)
    def resolve
      if user.role == 'citizen'
       scope.where(:user_id => user.id)
     else
       scope
     end
   end
end
Run Code Online (Sandbox Code Playgroud)

为了在 rspec 中测试这一点,我必须这样做

require 'spec_helper'

describe IssuePolicy do

  before(:each) do
    @user = FactoryGirl.create(:user)
    @issue = FactoryGirl.create(:issue)
    @last_issue = FactoryGirl.create(:issue, user_id: User.last.id + 1)
  end

  context "for a citizen" do
    before(:each) do
      @user.update(role: 'citizen')
    end
    it "should only return their posts on index action" do
     @p = IssuePolicy::Scope.new(@user, Issue).resolve
     @p.each do |issue|
       expect{issue.user_id}.to eql(@user.id)
     end
   end
  end
end
Run Code Online (Sandbox Code Playgroud)

Aus*_*tio 5

好吧,我做了一些挖掘,发现了如何通过文档来测试这个问题,然后如何通过研究来确定范围。

irb> IssuePolicy::Scope.new(@user, Issue.all).resolve.class 
Run Code Online (Sandbox Code Playgroud)

这将返回一个 ActiveRecord::QueryMethods::WhereChain

所以下一个问题实际上变成了我想测试它的结构或行为吗?我选择测试该行为是因为我真的只关心我的范围是否已正确应用。所以上面的范围测试对我来说很好。作为一个额外的帮助者,这是我如何测试只有员工角色可以访问而公民角色被拒绝的方法,希望它对某人有帮助。

需要“spec_helper”

describe IssuePolicy do
  subject { IssuePolicy }


  permissions :index?, :show?, :create?, :new?, :update?, :edit?, :destroy? do
    it "denies access to citizen" do
      expect(subject).not_to permit(FactoryGirl.create(:user, role: 'citizen'), Issue.create())
    end

    it "allows access to employee" do
      expect(subject).to permit(FactoryGirl.create(:user, role: 'employee'), Issue.create())
    end
  end


end
Run Code Online (Sandbox Code Playgroud)