action_policy 0.6.2 → 0.6.4

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: 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