From 26e37067194af782caa639250c9b2e35984669b1 Mon Sep 17 00:00:00 2001 From: Tim Cooper Date: Mon, 12 Aug 2013 10:38:50 +1000 Subject: [PATCH] Allow policies and scopes to be injected into controllers. In controller specs instead of relying on Pundit to instantiate the correct policy object allow it to be injected into the controller. More often than not a double is used in controller specs which means the policy cannot be inferred. This also allows us to double the policy to ensure that on a unit level the rights methods are being called on callaborators. class PostsController < ApplicationController attr_writer :post helper_method :post def create authorize post post.save respond_with post end private def post @post ||= Post.new post_attributes end end describe PagesController do let(:policy) { double 'SomePolicy', create?: true } before do controller.policy = policy end it 'delegates authorization to policy' do expect(policy).to have_received(:create?) end end Add spec for injecting policy. Use `or` instead of ternary operator. Allow policy_scope to be injected for controller tests. --- lib/pundit.rb | 6 ++++-- spec/pundit_spec.rb | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/pundit.rb b/lib/pundit.rb index efb49e7..29e84dc 100644 --- a/lib/pundit.rb +++ b/lib/pundit.rb @@ -63,12 +63,14 @@ module Pundit def policy_scope(scope) @_policy_scoped = true - Pundit.policy_scope!(pundit_user, scope) + @policy_scope or Pundit.policy_scope!(pundit_user, scope) end + attr_writer :policy_scope def policy(record) - Pundit.policy!(pundit_user, record) + @policy or Pundit.policy!(pundit_user, record) end + attr_writer :policy def pundit_user current_user diff --git a/spec/pundit_spec.rb b/spec/pundit_spec.rb index 9dc7a89..3bcfe6a 100644 --- a/spec/pundit_spec.rb +++ b/spec/pundit_spec.rb @@ -242,6 +242,13 @@ describe Pundit do it "throws an exception if the given policy can't be found" do expect { controller.policy(article) }.to raise_error(Pundit::NotDefinedError) end + + it "allows policy to be injected" do + new_policy = OpenStruct.new + controller.policy = new_policy + + controller.policy(post).should == new_policy + end end describe ".policy_scope" do @@ -252,5 +259,12 @@ describe Pundit do it "throws an exception if the given policy can't be found" do expect { controller.policy_scope(Article) }.to raise_error(Pundit::NotDefinedError) end + + it "allows policy_scope to be injected" do + new_scope = OpenStruct.new + controller.policy_scope = new_scope + + controller.policy_scope(post).should == new_scope + end end end