Skip to content

Commit

Permalink
fix PolicyFinder when given an array with policy class override
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanhertz committed Jul 22, 2017
1 parent ac2a25d commit 2803193
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
29 changes: 15 additions & 14 deletions lib/pundit/policy_finder.rb
Expand Up @@ -36,7 +36,7 @@ def scope
# policy.update? #=> false
#
def policy
klass = find
klass = find(object)
klass = klass.constantize if klass.is_a?(String)
klass
rescue NameError
Expand All @@ -48,15 +48,15 @@ def policy
#
def scope!
raise NotDefinedError, "unable to find policy scope of nil" if object.nil?
scope or raise NotDefinedError, "unable to find scope `#{find}::Scope` for `#{object.inspect}`"
scope or raise NotDefinedError, "unable to find scope `#{find(object)}::Scope` for `#{object.inspect}`"
end

# @return [Class] policy class with query methods
# @raise [NotDefinedError] if policy could not be determined
#
def policy!
raise NotDefinedError, "unable to find policy of nil" if object.nil?
policy or raise NotDefinedError, "unable to find policy `#{find}` for `#{object.inspect}`"
policy or raise NotDefinedError, "unable to find policy `#{find(object)}` for `#{object.inspect}`"
end

# @return [String] the name of the key this object would have in a params hash
Expand All @@ -73,19 +73,20 @@ def param_key

private

def find
if object.nil?
def find(subject)
if subject.nil?
nil
elsif object.respond_to?(:policy_class)
object.policy_class
elsif object.class.respond_to?(:policy_class)
object.class.policy_class
elsif subject.is_a?(Array)
modules = subject.dup
last = modules.pop
context = modules.map { |x| find_class_name(x) }.join("::")
[context, find(last)].join("::")
elsif subject.respond_to?(:policy_class)
subject.policy_class
elsif subject.class.respond_to?(:policy_class)
subject.class.policy_class
else
klass = if object.is_a?(Array)
object.map { |x| find_class_name(x) }.join("::")
else
find_class_name(object)
end
klass = find_class_name(subject)
"#{klass}#{SUFFIX}"
end
end
Expand Down
14 changes: 14 additions & 0 deletions spec/pundit_spec.rb
Expand Up @@ -134,6 +134,13 @@
expect(policy.post).to eq [:project, post]
end

it "returns an instantiated policy given an array of a symbol and a model instance with policy_class override" do
policy = Pundit.policy(user, [:project, customer_post])
expect(policy.class).to eq Project::PostPolicy
expect(policy.user).to eq user
expect(policy.post).to eq [:project, customer_post]
end

it "returns an instantiated policy given an array of a symbol and an active model instance" do
policy = Pundit.policy(user, [:project, comment])
expect(policy.class).to eq Project::CommentPolicy
Expand All @@ -155,6 +162,13 @@
expect(policy.post).to eq [:project, Comment]
end

it "returns an instantiated policy given an array of a symbol and a class with policy_class override" do
policy = Pundit.policy(user, [:project, Customer::Post])
expect(policy.class).to eq Project::PostPolicy
expect(policy.user).to eq user
expect(policy.post).to eq [:project, Customer::Post]
end

it "returns correct policy class for an array of a multi-word symbols" do
policy = Pundit.policy(user, [:project_one_two_three, :criteria_four_five_six])
expect(policy.class).to eq ProjectOneTwoThree::CriteriaFourFiveSixPolicy
Expand Down
6 changes: 5 additions & 1 deletion spec/spec_helper.rb
Expand Up @@ -77,9 +77,13 @@ def model_name
OpenStruct.new(param_key: "customer_post")
end

def policy_class
def self.policy_class
PostPolicy
end

def policy_class
self.class.policy_class
end
end
end

Expand Down

0 comments on commit 2803193

Please sign in to comment.