action_policy 0.6.8 → 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e78f24a8faa881e8cad62f6bb4fc58921668fb7d41ac933c7fb1934117acc7d
4
- data.tar.gz: 39f55de2e98b9a1d67519df40452349a2007e8d7168039438d2c8469cc7779e7
3
+ metadata.gz: ae3b29268276a0c189e7a2ce8d83e9a68f0de8a1da555de29549d6d7712bb6da
4
+ data.tar.gz: ff91808a4bf73e284ed2cc973de4e5d4eb76e9ffe18f4f987461e8fa531f9f5b
5
5
  SHA512:
6
- metadata.gz: 66b0de36683bc63ce349b0fba097585b7fcb4d7d65145da53c26cd5d6f0c798ef76c447d75a987c1f16110d3d4bb379153407ef79b531613cc6cfa8e55171570
7
- data.tar.gz: b7eadbbd0020e60addce888bf8287722c8bafd32a8b35ff2c66d8ea51eaa3b9c6f406e5214fdcddda4e7d4d527d12f08be3f86eac64d28db3b62b7976de28f17
6
+ metadata.gz: e914fd53642a316240ff3f4ef8e51076080bd98780fa5116678a1bc87d7ad135a34ba5ab8eff3e125d73b993044b026cb232605cf21b9ec4cb8dbbf5b2cc2f71
7
+ data.tar.gz: 4be9b544ab2a48d7e3a4a94896b417159c17b69745980a460e1927e2d8aef35b946e5a980c16fd78f83138c413afe290d510a3942f7f2deae5c10f132b8934f2
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.9 (2024-04-19)
6
+
7
+ - Add `.with_context` modifier to the `#have_authorized_scope` matcher. ([@killondark][])
8
+
5
9
  ## 0.6.8 (2024-01-17)
6
10
 
7
11
  - Do not preload Rails base classes, use load hooks everywhere. ([@palkan][])
@@ -509,3 +513,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
509
513
  [@skojin]: https://github.com/skojin
510
514
  [@tomdalling]: https://github.com/tomdalling
511
515
  [@matsales28]: https://github.com/matsales28
516
+ [@killondark]: https://github.com/killondark
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  #
22
22
  class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
23
  attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
- :target_expectations
24
+ :target_expectations, :context
25
25
 
26
26
  def initialize(type)
27
27
  @type = type
@@ -49,6 +49,11 @@ module ActionPolicy
49
49
  self
50
50
  end
51
51
 
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
52
57
  def match(_expected, actual)
53
58
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
54
59
 
@@ -56,7 +61,7 @@ module ActionPolicy
56
61
 
57
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
58
63
 
59
- matching_scopes = actual_scopes.select { |_1| _1.matches?(policy, type, name, scope_options) }
64
+ matching_scopes = actual_scopes.select { |_1| _1.matches?(policy, type, name, scope_options, context) }
60
65
 
61
66
  return false if matching_scopes.empty?
62
67
 
@@ -80,6 +85,7 @@ module ActionPolicy
80
85
  def failure_message
81
86
  "expected a scoping named :#{name} for type :#{type} " \
82
87
  "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
83
89
  "from #{policy} to have been applied, " \
84
90
  "but #{actual_scopes_message}"
85
91
  end
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  #
22
22
  class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
23
  attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
- :target_expectations
24
+ :target_expectations, :context
25
25
 
26
26
  def initialize(type)
27
27
  @type = type
@@ -49,6 +49,11 @@ module ActionPolicy
49
49
  self
50
50
  end
51
51
 
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
52
57
  def match(_expected, actual)
53
58
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
54
59
 
@@ -56,7 +61,7 @@ module ActionPolicy
56
61
 
57
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
58
63
 
59
- matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options) }
64
+ matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options, context) }
60
65
 
61
66
  return false if matching_scopes.empty?
62
67
 
@@ -80,6 +85,7 @@ module ActionPolicy
80
85
  def failure_message
81
86
  "expected a scoping named :#{name} for type :#{type} " \
82
87
  "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
83
89
  "from #{policy} to have been applied, " \
84
90
  "but #{actual_scopes_message}"
85
91
  end
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  #
22
22
  class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
23
  attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
- :target_expectations
24
+ :target_expectations, :context
25
25
 
26
26
  def initialize(type)
27
27
  @type = type
@@ -49,6 +49,11 @@ module ActionPolicy
49
49
  self
50
50
  end
51
51
 
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
52
57
  def match(_expected, actual)
53
58
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
54
59
 
@@ -56,7 +61,7 @@ module ActionPolicy
56
61
 
57
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
58
63
 
59
- matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options) }
64
+ matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options, context) }
60
65
 
61
66
  return false if matching_scopes.empty?
62
67
 
@@ -80,6 +85,7 @@ module ActionPolicy
80
85
  def failure_message
81
86
  "expected a scoping named :#{name} for type :#{type} " \
82
87
  "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
83
89
  "from #{policy} to have been applied, " \
84
90
  "but #{actual_scopes_message}"
85
91
  end
@@ -21,7 +21,7 @@ module ActionPolicy
21
21
  #
22
22
  class HaveAuthorizedScope < ::RSpec::Matchers::BuiltIn::BaseMatcher
23
23
  attr_reader :type, :name, :policy, :scope_options, :actual_scopes,
24
- :target_expectations
24
+ :target_expectations, :context
25
25
 
26
26
  def initialize(type)
27
27
  @type = type
@@ -49,6 +49,11 @@ module ActionPolicy
49
49
  self
50
50
  end
51
51
 
52
+ def with_context(context)
53
+ @context = context
54
+ self
55
+ end
56
+
52
57
  def match(_expected, actual)
53
58
  raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
54
59
 
@@ -56,7 +61,7 @@ module ActionPolicy
56
61
 
57
62
  @actual_scopes = ActionPolicy::Testing::AuthorizeTracker.scopings
58
63
 
59
- matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options) }
64
+ matching_scopes = actual_scopes.select { _1.matches?(policy, type, name, scope_options, context) }
60
65
 
61
66
  return false if matching_scopes.empty?
62
67
 
@@ -80,6 +85,7 @@ module ActionPolicy
80
85
  def failure_message
81
86
  "expected a scoping named :#{name} for type :#{type} " \
82
87
  "#{scope_options_message} " \
88
+ "#{context ? "and context #{context.inspect} " : ""}" \
83
89
  "from #{policy} to have been applied, " \
84
90
  "but #{actual_scopes_message}"
85
91
  end
@@ -82,7 +82,7 @@ module ActionPolicy
82
82
  # end
83
83
  # end
84
84
  #
85
- def assert_have_authorized_scope(type:, with:, as: :default, scope_options: nil)
85
+ def assert_have_authorized_scope(type:, with:, as: :default, scope_options: nil, context: {})
86
86
  raise ArgumentError, "Block is required" unless block_given?
87
87
 
88
88
  policy = with
@@ -97,10 +97,13 @@ module ActionPolicy
97
97
  "without scope options"
98
98
  end
99
99
 
100
+ context_message = context.empty? ? "without context" : "with context: #{context}"
101
+
100
102
  assert(
101
- actual_scopes.any? { |scope| scope.matches?(policy, type, as, scope_options) },
103
+ actual_scopes.any? { |scope| scope.matches?(policy, type, as, scope_options, context) },
102
104
  "Expected a scoping named :#{as} for :#{type} type " \
103
105
  "#{scope_options_message} " \
106
+ "and #{context_message} " \
104
107
  "from #{policy} to have been applied, " \
105
108
  "but no such scoping has been made.\n" \
106
109
  "Registered scopings: " \
@@ -5,7 +5,19 @@ module ActionPolicy
5
5
  module Testing
6
6
  # Collects all Authorizer calls
7
7
  module AuthorizeTracker
8
+ module Context
9
+ private
10
+
11
+ def context_matches?(context, actual)
12
+ return true unless context
13
+
14
+ context === actual || actual >= context
15
+ end
16
+ end
17
+
8
18
  class Call # :nodoc:
19
+ include Context
20
+
9
21
  attr_reader :policy, :rule
10
22
 
11
23
  def initialize(policy, rule)
@@ -23,17 +35,11 @@ module ActionPolicy
23
35
  "#{policy.record.inspect} was authorized with #{policy.class}##{rule} " \
24
36
  "and context #{policy.authorization_context.inspect}"
25
37
  end
26
-
27
- private
28
-
29
- def context_matches?(context, actual)
30
- return true unless context
31
-
32
- context === actual || actual >= context
33
- end
34
38
  end
35
39
 
36
40
  class Scoping # :nodoc:
41
+ include Context
42
+
37
43
  attr_reader :policy, :target, :type, :name, :scope_options
38
44
 
39
45
  def initialize(policy, target, type, name, scope_options)
@@ -44,11 +50,12 @@ module ActionPolicy
44
50
  @scope_options = scope_options
45
51
  end
46
52
 
47
- def matches?(policy_class, actual_type, actual_name, actual_scope_options)
53
+ def matches?(policy_class, actual_type, actual_name, actual_scope_options, actual_context)
48
54
  policy_class == policy.class &&
49
55
  type == actual_type &&
50
56
  name == actual_name &&
51
- actual_scope_options === scope_options
57
+ actual_scope_options === scope_options &&
58
+ context_matches?(actual_context, policy.authorization_context)
52
59
  end
53
60
 
54
61
  def inspect
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.6.8"
4
+ VERSION = "0.6.9"
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.8
4
+ version: 0.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-17 00:00:00.000000000 Z
11
+ date: 2024-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -234,7 +234,7 @@ metadata:
234
234
  documentation_uri: https://actionpolicy.evilmartians.io/
235
235
  homepage_uri: https://actionpolicy.evilmartians.io/
236
236
  source_code_uri: http://github.com/palkan/action_policy
237
- post_install_message:
237
+ post_install_message:
238
238
  rdoc_options: []
239
239
  require_paths:
240
240
  - lib
@@ -249,8 +249,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
249
  - !ruby/object:Gem::Version
250
250
  version: '0'
251
251
  requirements: []
252
- rubygems_version: 3.4.20
253
- signing_key:
252
+ rubygems_version: 3.4.19
253
+ signing_key:
254
254
  specification_version: 4
255
255
  summary: Authorization framework for Ruby/Rails application
256
256
  test_files: []