action_policy 0.6.2 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 491af624707f597ded52f7d1cacdfc07435937250370804c0ac374f436b494ce
4
- data.tar.gz: 33ac6abf6907738c6fce67193659e4fdb6615a2dd78a375dba4b57060c9d8f6e
3
+ metadata.gz: '095ceaf3dffeb28e23d1b89a20108ad23e6ddfb48e3fc317cf481151cdf82d66'
4
+ data.tar.gz: a1cac52b3641e0e3e9709a42a409324f348b13a037342cc004a4b51b99bc15ab
5
5
  SHA512:
6
- metadata.gz: 54e1dffffae9777c07d47f5718143cfbc546d6d100e873aadc3a51a1e8821f6495a7d869a477ac7d9d65be1ef92e1fef8bb9adde6c5177186c63eebb8dc88a94
7
- data.tar.gz: 2b866340538957aa93c5db05a9c8bc7181b9cc4b9b178a137b58a13ad0d7a5158904b911834ab5dd2cf5af4d29bca29d7003095144c7786583375ec8d273c0d5
6
+ metadata.gz: 3a4b4c4b40036ca59122dfa6c3623b542525b7e663ddfaacec4fe93fdadb0a85fc2c12d73f6a58c89cba8d0e647bf5ff8dbf094f6bc181db93a44a004fd07284
7
+ data.tar.gz: 28bbda81d9a149ad339558cc7f6b6d175f8385e3be2f0c8118df5491b8152e271382aed6d60235f3de73d73b92406d6442dcf25b24296e73af74d29054890af4
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.4 (2022-01-17)
6
+
7
+ - Fix loading of Rails scope matchers. ([@palkan][])
8
+
9
+ [Issue #225](https://github.com/palkan/action_policy/issues/225)
10
+
11
+ - Add support to assert context in test matchers ([@matsales28][])
12
+
13
+ ## 0.6.3 (2022-08-16)
14
+
15
+ - Fix regression for [#179](https://github.com/palkan/action_policy/issues/179). ([@palkan][])
16
+
5
17
  ## 0.6.2 (2022-08-12)
6
18
 
7
19
  - Allow omitting authorization record if `with` is provided. ([@palkan][])
@@ -468,3 +480,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
468
480
  [@pirj]: https://github.com/pirj
469
481
  [@skojin]: https://github.com/skojin
470
482
  [@tomdalling]: https://github.com/tomdalling
483
+ [@matsales28]: https://github.com/matsales28
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2021 Vladimir Dementyev
3
+ Copyright (c) 2018-2023 Vladimir Dementyev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -20,7 +20,7 @@ module ActionPolicy
20
20
  # end
21
21
  #
22
22
  class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
- attr_reader :rule, :target, :policy, :actual_calls
23
+ attr_reader :rule, :target, :policy, :actual_calls, :context
24
24
 
25
25
  def initialize(rule, target)
26
26
  @rule = rule
@@ -32,10 +32,16 @@ module ActionPolicy
32
32
  self
33
33
  end
34
34
 
35
+ def with_context(context)
36
+ @context = context
37
+ self
38
+ end
39
+
35
40
  def match(_expected, actual)
36
41
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
37
42
 
38
43
  @policy ||= ::ActionPolicy.lookup(target)
44
+ @context ||= nil
39
45
 
40
46
  begin
41
47
  ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
@@ -45,7 +51,7 @@ module ActionPolicy
45
51
 
46
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
47
53
 
48
- actual_calls.any? { |_1| _1.matches?(policy, rule, target) }
54
+ actual_calls.any? { |_1| _1.matches?(policy, rule, target, context) }
49
55
  end
50
56
 
51
57
  def does_not_match?(*)
@@ -57,6 +63,7 @@ module ActionPolicy
57
63
  def failure_message
58
64
  "expected #{formatted_record} " \
59
65
  "to be authorized with #{policy}##{rule}, " \
66
+ "#{context ? "and context #{context.inspect}, " : ""}" \
60
67
  "but #{actual_calls_message}"
61
68
  end
62
69
 
@@ -20,7 +20,7 @@ module ActionPolicy
20
20
  # end
21
21
  #
22
22
  class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
- attr_reader :rule, :target, :policy, :actual_calls
23
+ attr_reader :rule, :target, :policy, :actual_calls, :context
24
24
 
25
25
  def initialize(rule, target)
26
26
  @rule = rule
@@ -32,10 +32,16 @@ module ActionPolicy
32
32
  self
33
33
  end
34
34
 
35
+ def with_context(context)
36
+ @context = context
37
+ self
38
+ end
39
+
35
40
  def match(_expected, actual)
36
41
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
37
42
 
38
43
  @policy ||= ::ActionPolicy.lookup(target)
44
+ @context ||= nil
39
45
 
40
46
  begin
41
47
  ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
@@ -45,7 +51,7 @@ module ActionPolicy
45
51
 
46
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
47
53
 
48
- actual_calls.any? { _1.matches?(policy, rule, target) }
54
+ actual_calls.any? { _1.matches?(policy, rule, target, context) }
49
55
  end
50
56
 
51
57
  def does_not_match?(*)
@@ -57,6 +63,7 @@ module ActionPolicy
57
63
  def failure_message
58
64
  "expected #{formatted_record} " \
59
65
  "to be authorized with #{policy}##{rule}, " \
66
+ "#{context ? "and context #{context.inspect}, " : ""}" \
60
67
  "but #{actual_calls_message}"
61
68
  end
62
69
 
@@ -61,7 +61,7 @@ module ActionPolicy
61
61
  @_authorization_context ||= build_authorization_context
62
62
  end
63
63
 
64
- def build_authorization_context
64
+ private def build_authorization_context
65
65
  self.class.authorization_targets
66
66
  .each_with_object({}) do |(key, meth), obj|
67
67
  obj[key] = send(meth)
@@ -75,7 +75,7 @@ module ActionPolicy
75
75
  end
76
76
 
77
77
  def lookup_authorization_policy(record, with: nil, **options) # :nodoc:
78
- if record == :__undef__
78
+ if :__undef__ == record # rubocop:disable Style/YodaCondition
79
79
  record =
80
80
  if with
81
81
  implicit_authorization_target
@@ -100,7 +100,7 @@ module ActionPolicy
100
100
  # Enable namespace cache by default or
101
101
  # if RACK_ENV provided and equal to "production"
102
102
  self.namespace_cache_enabled =
103
- !ENV["RACK_ENV"].nil? ? ENV["RACK_ENV"] == "production" : true
103
+ (!ENV["RACK_ENV"].nil?) ? ENV["RACK_ENV"] == "production" : true
104
104
 
105
105
  # By self `policy_class` method
106
106
  INSTANCE_POLICY_CLASS = ->(record, **) {
@@ -4,6 +4,14 @@ module ActionPolicy # :nodoc:
4
4
  require "action_policy/rails/controller"
5
5
  require "action_policy/rails/channel"
6
6
 
7
+ if defined?(::ActionController)
8
+ require "action_policy/rails/scope_matchers/action_controller_params"
9
+ end
10
+
11
+ if defined?(::ActiveRecord)
12
+ require "action_policy/rails/scope_matchers/active_record"
13
+ end
14
+
7
15
  class Railtie < ::Rails::Railtie # :nodoc:
8
16
  # Provides Rails-specific configuration,
9
17
  # accessible through `Rails.application.config.action_policy`
@@ -81,8 +89,6 @@ module ActionPolicy # :nodoc:
81
89
  ::Rails.application.config.action_policy.namespace_cache_enabled
82
90
 
83
91
  ActiveSupport.on_load(:action_controller) do
84
- require "action_policy/rails/scope_matchers/action_controller_params"
85
-
86
92
  next unless ::Rails.application.config.action_policy.auto_inject_into_controller
87
93
 
88
94
  ActionController::Base.include ActionPolicy::Controller
@@ -104,7 +110,6 @@ module ActionPolicy # :nodoc:
104
110
 
105
111
  ActiveSupport.on_load(:active_record) do
106
112
  require "action_policy/rails/ext/active_record"
107
- require "action_policy/rails/scope_matchers/active_record"
108
113
  end
109
114
  end
110
115
  end
@@ -20,7 +20,7 @@ module ActionPolicy
20
20
  # end
21
21
  #
22
22
  class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
- attr_reader :rule, :target, :policy, :actual_calls
23
+ attr_reader :rule, :target, :policy, :actual_calls, :context
24
24
 
25
25
  def initialize(rule, target)
26
26
  @rule = rule
@@ -32,10 +32,16 @@ module ActionPolicy
32
32
  self
33
33
  end
34
34
 
35
+ def with_context(context)
36
+ @context = context
37
+ self
38
+ end
39
+
35
40
  def match(_expected, actual)
36
41
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
37
42
 
38
43
  @policy ||= ::ActionPolicy.lookup(target)
44
+ @context ||= nil
39
45
 
40
46
  begin
41
47
  ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
@@ -45,7 +51,7 @@ module ActionPolicy
45
51
 
46
52
  @actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
47
53
 
48
- actual_calls.any? { _1.matches?(policy, rule, target) }
54
+ actual_calls.any? { _1.matches?(policy, rule, target, context) }
49
55
  end
50
56
 
51
57
  def does_not_match?(*)
@@ -57,6 +63,7 @@ module ActionPolicy
57
63
  def failure_message
58
64
  "expected #{formatted_record} " \
59
65
  "to be authorized with #{policy}##{rule}, " \
66
+ "#{context ? "and context #{context.inspect}, " : ""}" \
60
67
  "but #{actual_calls_message}"
61
68
  end
62
69
 
@@ -36,7 +36,7 @@ module ActionPolicy
36
36
  # get :show, id: user.id
37
37
  # end
38
38
  #
39
- def assert_authorized_to(rule, target, with: nil)
39
+ def assert_authorized_to(rule, target, with: nil, context: {})
40
40
  raise ArgumentError, "Block is required" unless block_given?
41
41
 
42
42
  policy = with || ::ActionPolicy.lookup(target)
@@ -50,8 +50,9 @@ module ActionPolicy
50
50
  actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
51
51
 
52
52
  assert(
53
- actual_calls.any? { |call| call.matches?(policy, rule, target) },
53
+ actual_calls.any? { |call| call.matches?(policy, rule, target, context) },
54
54
  "Expected #{target.inspect} to be authorized with #{policy}##{rule}, " \
55
+ "#{context ? "and context #{context}, " : ""}" \
55
56
  "but no such authorization has been made.\n" \
56
57
  "Registered authorizations: " \
57
58
  "#{actual_calls.empty? ? "none" : actual_calls.map(&:inspect).join(",")}"
@@ -13,14 +13,23 @@ module ActionPolicy
13
13
  @rule = rule
14
14
  end
15
15
 
16
- def matches?(policy_class, actual_rule, target)
16
+ def matches?(policy_class, actual_rule, target, context)
17
17
  policy_class == policy.class &&
18
18
  (target.is_a?(Class) ? target == policy.record : target === policy.record) &&
19
- rule == actual_rule
19
+ rule == actual_rule && context_matches?(context, policy.authorization_context)
20
20
  end
21
21
 
22
22
  def inspect
23
- "#{policy.record.inspect} was authorized with #{policy.class}##{rule}"
23
+ "#{policy.record.inspect} was authorized with #{policy.class}##{rule} " \
24
+ "and context #{policy.authorization_context.inspect}"
25
+ end
26
+
27
+ private
28
+
29
+ def context_matches?(context, actual)
30
+ return true unless context
31
+
32
+ context === actual || actual >= context
24
33
  end
25
34
  end
26
35
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.6.2"
4
+ VERSION = "0.6.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-12 00:00:00.000000000 Z
11
+ date: 2023-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core