Question

I am running into a snag with testing Pundit policy scopes with Rspec. Basically, i'm trying to test that the returned values on a scope are strictly limited to a user. So i cycle through all the issues returned for a user and make sure that the id is equal to the user.

This is green, however it fails when it is a non-citizen role due to the Scope call just returning an Issue object. This isn't a big deal as each role will have a scope with .where(), but it is a code smell that i may be doing something wront.

I have an IssueController that performs the action

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

To test this in rspec I had to do this

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
Was it helpful?

Solution

alright so did some digging and found out how to test this question through documentation and then how to do scopes through research.

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

This returns an ActiveRecord::QueryMethods::WhereChain

So the next question really becomes do i want to test the structure or the behavior of this. I chose to test the behavior because i really just care about whether my scope has been properly applied. So the scope testing above is fine for me. As an added helper, Here is how I tested that only role of employee can access and role of citizen is denied, hope that it helps someone.

require '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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top