2014-04-05 257 views
0

我遇到了一个与Rspec一起测试Pundit策略范围的障碍。基本上,我试图测试范围上的返回值严格限制为一个用户。因此,我循环查看为用户返回的所有问题,并确保该ID与用户相同。Rails Pundit Rspec测试

这是绿色的,但由于Scope调用只返回一个Issue对象,所以它是非公民角色时失败。这并不是什么大问题,因为每个角色都会有.where()的作用域,但这是一种代码气味,我可能会做一些事情。

我有一个执行的操作

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 

回答

3

好吗所以做了一些挖掘,发现了如何测试过这个问题的IssueController文档以及如何通过研究来完成范围。

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