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
Était-ce utile?

La 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top