1

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

这是绿色的,但是当它是一个非公民角色时它会失败,因为 Scope 调用只返回一个问题对象。这没什么大不了的,因为每个角色都有一个 .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

要在 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
4

1 回答 1

4

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

irb> IssuePolicy::Scope.new(@user, Issue.all).resolve.class 

这将返回一个 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
于 2014-05-05T01:39:58.293 回答