pundit-matchers 1.9.0 → 2.1.0

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: 836bd12c848b5a4d68608155884e87515ab4f73926d064e6da1881369e1abb27
4
- data.tar.gz: b8346711d3bbfdee77779c8607e0dde827f2dec9c34dc3e58491c4aaa659a9f8
3
+ metadata.gz: ca57a9d5fc96cbacd89c5af52106a126fa6cf01d72654c677fa5e1a7a957e139
4
+ data.tar.gz: 5dd3c52dcf6cc289a76ba40947ff1d46fad538e5b6bfcec5484ba1d87b2092b9
5
5
  SHA512:
6
- metadata.gz: 7069911c4cbd5886ca4ace96a2417b9c1a1afe45c410ac0f1a5bfbf24866478491b8f9c135e4f98b25e2f8eb6113dc72f7dc03abd63b25ebe98e38f3dff84859
7
- data.tar.gz: 9ad39f93ad83169107df878f85c71bc75bc4478ab3d6e59ced4338bfd05accbedb646476772f2c32868bbf5272edee0e833c9e30c4a29d2b9b740bc6b02ea936
6
+ metadata.gz: e965e471adca0f06d4ab84e1d03f426902d5ac79bb69644afc88be3b158defb27bcd36d9170c6f47fbb3cbf7d832884a9b8f1e65bc3e7e0587d4ede6d75f9de5
7
+ data.tar.gz: e8c47b1311ab7afc3d119714ee12d605d0063dc315f38a70e7fc0b5761e99432cd6f3fceb109a504e82b4c61621147197291dbd59f5d1dceb434e7f6ec346d80
@@ -14,7 +14,7 @@ module Pundit
14
14
  module ErrorMessageFormatter
15
15
  def message
16
16
  "#{policy_name} expected to have all actions #{expected_kind}, " \
17
- "but #{mismatches_are(missed_expected_actions)} #{opposite_kind}"
17
+ "but #{mismatches_are(missed_expected_actions)} #{opposite_kind}"
18
18
  end
19
19
 
20
20
  private
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pundit
4
+ module Matchers
5
+ module Utils
6
+ module OnlyActions
7
+ # Parent class for specific only_action matcher. Should not be used directly.
8
+ #
9
+ # Expects methods in child class:
10
+ # * actual_actions - list of actions which actually matches expected type.
11
+ class ActionsMatcher
12
+ attr_reader :policy_info, :expected_actions
13
+
14
+ def initialize(policy, expected_actions)
15
+ @policy_info = PolicyInfo.new(policy)
16
+ @expected_actions = expected_actions
17
+ end
18
+
19
+ def match?
20
+ missed_expected_actions.empty? &&
21
+ actual_actions.sort == expected_actions.sort
22
+ end
23
+
24
+ def unexpected_actions
25
+ @unexpected_actions ||= actual_actions - expected_actions
26
+ end
27
+
28
+ def missed_expected_actions
29
+ @missed_expected_actions ||= expected_actions - actual_actions
30
+ end
31
+
32
+ def policy
33
+ policy_info.policy
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pundit
4
+ module Matchers
5
+ module Utils
6
+ module OnlyActions
7
+ # Adds #message method which generates failed assertion message
8
+ # for *_only_actions matchers.
9
+ #
10
+ # Expects methods to be defined:
11
+ # * matcher - instance which has `OnlyActions::ActionsMatcher` as a parent class
12
+ # * expected_kind - string with expected actions type (can be "forbidden" or "permitted")
13
+ # * opposite_kind - string with oposite then expected actions type (can be "permitted" or "forbidden")
14
+ module ErrorMessageFormatter
15
+ def message
16
+ "#{policy_name} expected to have only actions #{matcher.expected_actions} #{expected_kind}, but " \
17
+ "#{unless missed_expected_actions.empty?
18
+ "#{mismatches_are(missed_expected_actions)} #{opposite_kind} and "
19
+ end}" \
20
+ "#{mismatches_are(unexpected_actions)} #{expected_kind} too"
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :matcher, :expected_kind, :opposite_kind
26
+
27
+ def policy
28
+ matcher.policy
29
+ end
30
+
31
+ def unexpected_actions
32
+ matcher.unexpected_actions
33
+ end
34
+
35
+ def missed_expected_actions
36
+ matcher.missed_expected_actions
37
+ end
38
+
39
+ def policy_name
40
+ policy.class.name
41
+ end
42
+
43
+ def mismatches_are(mismatches)
44
+ if mismatches.count == 1
45
+ "#{mismatches} is"
46
+ else
47
+ "#{mismatches} are"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error_message_formatter'
4
+
5
+ module Pundit
6
+ module Matchers
7
+ module Utils
8
+ module OnlyActions
9
+ # Error message formatter for `forbid_only_actions` matcher.
10
+ class ForbiddenActionsErrorFormatter
11
+ include OnlyActions::ErrorMessageFormatter
12
+
13
+ def initialize(matcher)
14
+ @expected_kind = 'forbidden'
15
+ @opposite_kind = 'permitted'
16
+ @matcher = matcher
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :matcher, :expected_kind, :opposite_kind
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'actions_matcher'
4
+
5
+ module Pundit
6
+ module Matchers
7
+ module Utils
8
+ module OnlyActions
9
+ # Handles all the checks in `forbid_only_actions` matcher.
10
+ class ForbiddenActionsMatcher < OnlyActions::ActionsMatcher
11
+ private
12
+
13
+ def actual_actions
14
+ policy_info.forbidden_actions
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'error_message_formatter'
4
+
5
+ module Pundit
6
+ module Matchers
7
+ module Utils
8
+ module OnlyActions
9
+ # Error message formatter for `permit_only_actions` matcher.
10
+ class PermittedActionsErrorFormatter
11
+ include OnlyActions::ErrorMessageFormatter
12
+
13
+ def initialize(matcher)
14
+ @expected_kind = 'permitted'
15
+ @opposite_kind = 'forbidden'
16
+ @matcher = matcher
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :matcher, :expected_kind, :opposite_kind
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'actions_matcher'
4
+
5
+ module Pundit
6
+ module Matchers
7
+ module Utils
8
+ module OnlyActions
9
+ # Handles all the checks in `permit_only_actions` matcher.
10
+ class PermittedActionsMatcher < OnlyActions::ActionsMatcher
11
+ private
12
+
13
+ def actual_actions
14
+ policy_info.permitted_actions
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -8,6 +8,11 @@ module Pundit
8
8
  require_relative 'matchers/utils/all_actions/permitted_actions_error_formatter'
9
9
  require_relative 'matchers/utils/all_actions/permitted_actions_matcher'
10
10
 
11
+ require_relative 'matchers/utils/only_actions/forbidden_actions_error_formatter'
12
+ require_relative 'matchers/utils/only_actions/forbidden_actions_matcher'
13
+ require_relative 'matchers/utils/only_actions/permitted_actions_error_formatter'
14
+ require_relative 'matchers/utils/only_actions/permitted_actions_matcher'
15
+
11
16
  class Configuration
12
17
  attr_accessor :user_alias
13
18
 
@@ -26,12 +31,12 @@ module Pundit
26
31
  end
27
32
  end
28
33
 
29
- RSpec::Matchers.define :forbid_action do |action, *args|
34
+ RSpec::Matchers.define :forbid_action do |action, *args, **kwargs|
30
35
  match do |policy|
31
36
  if args.any?
32
- !policy.public_send("#{action}?", *args)
37
+ !policy.public_send("#{action}?", *args, **kwargs)
33
38
  else
34
- !policy.public_send("#{action}?")
39
+ !policy.public_send("#{action}?", **kwargs)
35
40
  end
36
41
  end
37
42
 
@@ -53,6 +58,7 @@ module Pundit
53
58
  actions.flatten!
54
59
  match do |policy|
55
60
  return false if actions.count < 1
61
+
56
62
  @allowed_actions = actions.select do |action|
57
63
  policy.public_send("#{action}?")
58
64
  end
@@ -62,14 +68,14 @@ module Pundit
62
68
  attr_reader :allowed_actions
63
69
 
64
70
  zero_actions_failure_message = 'At least one action must be ' \
65
- 'specified when using the forbid_actions matcher.'
71
+ 'specified when using the forbid_actions matcher.'
66
72
 
67
73
  failure_message do |policy|
68
74
  if actions.count.zero?
69
75
  zero_actions_failure_message
70
76
  else
71
77
  "#{policy.class} expected to forbid #{actions}, but allowed " \
72
- "#{allowed_actions} for " +
78
+ "#{allowed_actions} for " +
73
79
  policy.public_send(Pundit::Matchers.configuration.user_alias)
74
80
  .inspect + '.'
75
81
  end
@@ -80,7 +86,7 @@ module Pundit
80
86
  zero_actions_failure_message
81
87
  else
82
88
  "#{policy.class} expected to permit #{actions}, but forbade " \
83
- "#{allowed_actions} for " +
89
+ "#{allowed_actions} for " +
84
90
  policy.public_send(Pundit::Matchers.configuration.user_alias)
85
91
  .inspect + '.'
86
92
  end
@@ -107,7 +113,7 @@ module Pundit
107
113
 
108
114
  RSpec::Matchers.define :forbid_mass_assignment_of do |attributes|
109
115
  # Map single object argument to an array, if necessary
110
- attributes = attributes.is_a?(Array) ? attributes : [attributes]
116
+ attributes = [attributes] unless attributes.is_a?(Array)
111
117
 
112
118
  match do |policy|
113
119
  return false if attributes.count < 1
@@ -130,22 +136,22 @@ module Pundit
130
136
  end
131
137
 
132
138
  zero_attributes_failure_message = 'At least one attribute must be ' \
133
- 'specified when using the forbid_mass_assignment_of matcher.'
139
+ 'specified when using the forbid_mass_assignment_of matcher.'
134
140
 
135
141
  failure_message do |policy|
136
142
  if attributes.count.zero?
137
143
  zero_attributes_failure_message
138
144
  elsif defined? @action
139
145
  "#{policy.class} expected to forbid the mass assignment of the " \
140
- "attributes #{attributes} when authorising the #{@action} action, " \
141
- 'but allowed the mass assignment of the attributes ' \
142
- "#{allowed_attributes} for " +
146
+ "attributes #{attributes} when authorising the #{@action} action, " \
147
+ 'but allowed the mass assignment of the attributes ' \
148
+ "#{allowed_attributes} for " +
143
149
  policy.public_send(Pundit::Matchers.configuration.user_alias)
144
150
  .inspect + '.'
145
151
  else
146
152
  "#{policy.class} expected to forbid the mass assignment of the " \
147
- "attributes #{attributes}, but allowed the mass assignment of " \
148
- "the attributes #{allowed_attributes} for " +
153
+ "attributes #{attributes}, but allowed the mass assignment of " \
154
+ "the attributes #{allowed_attributes} for " +
149
155
  policy.public_send(Pundit::Matchers.configuration.user_alias)
150
156
  .inspect + '.'
151
157
  end
@@ -156,15 +162,15 @@ module Pundit
156
162
  zero_attributes_failure_message
157
163
  elsif defined? @action
158
164
  "#{policy.class} expected to permit the mass assignment of the " \
159
- "attributes #{attributes} when authorising the #{@action} action, " \
160
- 'but permitted the mass assignment of the attributes ' \
161
- "#{allowed_attributes} for " +
165
+ "attributes #{attributes} when authorising the #{@action} action, " \
166
+ 'but permitted the mass assignment of the attributes ' \
167
+ "#{allowed_attributes} for " +
162
168
  policy.public_send(Pundit::Matchers.configuration.user_alias)
163
169
  .inspect + '.'
164
170
  else
165
171
  "#{policy.class} expected to permit the mass assignment of the " \
166
- "attributes #{attributes}, but permitted the mass assignment of " \
167
- "the attributes #{allowed_attributes} for " +
172
+ "attributes #{attributes}, but permitted the mass assignment of " \
173
+ "the attributes #{allowed_attributes} for " +
168
174
  policy.public_send(Pundit::Matchers.configuration.user_alias)
169
175
  .inspect + '.'
170
176
  end
@@ -189,12 +195,12 @@ module Pundit
189
195
  end
190
196
  end
191
197
 
192
- RSpec::Matchers.define :permit_action do |action, *args|
198
+ RSpec::Matchers.define :permit_action do |action, *args, **kwargs|
193
199
  match do |policy|
194
200
  if args.any?
195
- policy.public_send("#{action}?", *args)
201
+ policy.public_send("#{action}?", *args, **kwargs)
196
202
  else
197
- policy.public_send("#{action}?")
203
+ policy.public_send("#{action}?", **kwargs)
198
204
  end
199
205
  end
200
206
 
@@ -215,6 +221,7 @@ module Pundit
215
221
  actions.flatten!
216
222
  match do |policy|
217
223
  return false if actions.count < 1
224
+
218
225
  @forbidden_actions = actions.reject do |action|
219
226
  policy.public_send("#{action}?")
220
227
  end
@@ -235,6 +242,7 @@ module Pundit
235
242
  tests would pass.'
236
243
 
237
244
  return true if actions.count < 1
245
+
238
246
  @forbidden_actions = actions.reject do |action|
239
247
  policy.public_send("#{action}?")
240
248
  end
@@ -244,14 +252,14 @@ module Pundit
244
252
  attr_reader :forbidden_actions
245
253
 
246
254
  zero_actions_failure_message = 'At least one action must be specified ' \
247
- 'when using the permit_actions matcher.'
255
+ 'when using the permit_actions matcher.'
248
256
 
249
257
  failure_message do |policy|
250
258
  if actions.count.zero?
251
259
  zero_actions_failure_message
252
260
  else
253
261
  "#{policy.class} expected to permit #{actions}, but forbade " \
254
- "#{forbidden_actions} for " +
262
+ "#{forbidden_actions} for " +
255
263
  policy.public_send(Pundit::Matchers.configuration.user_alias)
256
264
  .inspect + '.'
257
265
  end
@@ -262,7 +270,7 @@ module Pundit
262
270
  zero_actions_failure_message
263
271
  else
264
272
  "#{policy.class} expected to forbid #{actions}, but allowed " \
265
- "#{forbidden_actions} for " +
273
+ "#{forbidden_actions} for " +
266
274
  policy.public_send(Pundit::Matchers.configuration.user_alias)
267
275
  .inspect + '.'
268
276
  end
@@ -289,7 +297,7 @@ module Pundit
289
297
 
290
298
  RSpec::Matchers.define :permit_mass_assignment_of do |attributes|
291
299
  # Map single object argument to an array, if necessary
292
- attributes = attributes.is_a?(Array) ? attributes : [attributes]
300
+ attributes = [attributes] unless attributes.is_a?(Array)
293
301
 
294
302
  match do |policy|
295
303
  return false if attributes.count < 1
@@ -312,22 +320,22 @@ module Pundit
312
320
  end
313
321
 
314
322
  zero_attributes_failure_message = 'At least one attribute must be ' \
315
- 'specified when using the permit_mass_assignment_of matcher.'
323
+ 'specified when using the permit_mass_assignment_of matcher.'
316
324
 
317
325
  failure_message do |policy|
318
326
  if attributes.count.zero?
319
327
  zero_attributes_failure_message
320
328
  elsif defined? @action
321
329
  "#{policy.class} expected to permit the mass assignment of the " \
322
- "attributes #{attributes} when authorising the #{@action} action, " \
323
- 'but forbade the mass assignment of the attributes ' \
324
- "#{forbidden_attributes} for " +
330
+ "attributes #{attributes} when authorising the #{@action} action, " \
331
+ 'but forbade the mass assignment of the attributes ' \
332
+ "#{forbidden_attributes} for " +
325
333
  policy.public_send(Pundit::Matchers.configuration.user_alias)
326
334
  .inspect + '.'
327
335
  else
328
336
  "#{policy.class} expected to permit the mass assignment of the " \
329
- "attributes #{attributes}, but forbade the mass assignment of the " \
330
- "attributes #{forbidden_attributes} for " +
337
+ "attributes #{attributes}, but forbade the mass assignment of the " \
338
+ "attributes #{forbidden_attributes} for " +
331
339
  policy.public_send(Pundit::Matchers.configuration.user_alias)
332
340
  .inspect + '.'
333
341
  end
@@ -338,15 +346,15 @@ module Pundit
338
346
  zero_attributes_failure_message
339
347
  elsif defined? @action
340
348
  "#{policy.class} expected to forbid the mass assignment of the " \
341
- "attributes #{attributes} when authorising the #{@action} action, " \
342
- 'but forbade the mass assignment of the attributes ' \
343
- "#{forbidden_attributes} for " +
349
+ "attributes #{attributes} when authorising the #{@action} action, " \
350
+ 'but forbade the mass assignment of the attributes ' \
351
+ "#{forbidden_attributes} for " +
344
352
  policy.public_send(Pundit::Matchers.configuration.user_alias)
345
353
  .inspect + '.'
346
354
  else
347
355
  "#{policy.class} expected to forbid the mass assignment of the " \
348
- "attributes #{attributes}, but forbade the mass assignment of the " \
349
- "attributes #{forbidden_attributes} for " +
356
+ "attributes #{attributes}, but forbade the mass assignment of the " \
357
+ "attributes #{forbidden_attributes} for " +
350
358
  policy.public_send(Pundit::Matchers.configuration.user_alias)
351
359
  .inspect + '.'
352
360
  end
@@ -383,6 +391,18 @@ module Pundit
383
391
  end
384
392
  end
385
393
 
394
+ RSpec::Matchers.define :permit_only_actions do |actions|
395
+ match do |policy|
396
+ @matcher = Pundit::Matchers::Utils::OnlyActions::PermittedActionsMatcher.new(policy, actions)
397
+ @matcher.match?
398
+ end
399
+
400
+ failure_message do
401
+ formatter = Pundit::Matchers::Utils::OnlyActions::PermittedActionsErrorFormatter.new(@matcher)
402
+ formatter.message
403
+ end
404
+ end
405
+
386
406
  RSpec::Matchers.define :forbid_all_actions do
387
407
  match do |policy|
388
408
  @matcher = Pundit::Matchers::Utils::AllActions::ForbiddenActionsMatcher.new(policy)
@@ -394,6 +414,18 @@ module Pundit
394
414
  formatter.message
395
415
  end
396
416
  end
417
+
418
+ RSpec::Matchers.define :forbid_only_actions do |actions|
419
+ match do |policy|
420
+ @matcher = Pundit::Matchers::Utils::OnlyActions::ForbiddenActionsMatcher.new(policy, actions)
421
+ @matcher.match?
422
+ end
423
+
424
+ failure_message do
425
+ formatter = Pundit::Matchers::Utils::OnlyActions::ForbiddenActionsErrorFormatter.new(@matcher)
426
+ formatter.message
427
+ end
428
+ end
397
429
  end
398
430
 
399
431
  if defined?(Pundit)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pundit-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Alley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-16 00:00:00.000000000 Z
11
+ date: 2023-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails
@@ -57,11 +57,18 @@ files:
57
57
  - lib/pundit/matchers/utils/all_actions/forbidden_actions_matcher.rb
58
58
  - lib/pundit/matchers/utils/all_actions/permitted_actions_error_formatter.rb
59
59
  - lib/pundit/matchers/utils/all_actions/permitted_actions_matcher.rb
60
+ - lib/pundit/matchers/utils/only_actions/actions_matcher.rb
61
+ - lib/pundit/matchers/utils/only_actions/error_message_formatter.rb
62
+ - lib/pundit/matchers/utils/only_actions/forbidden_actions_error_formatter.rb
63
+ - lib/pundit/matchers/utils/only_actions/forbidden_actions_matcher.rb
64
+ - lib/pundit/matchers/utils/only_actions/permitted_actions_error_formatter.rb
65
+ - lib/pundit/matchers/utils/only_actions/permitted_actions_matcher.rb
60
66
  - lib/pundit/matchers/utils/policy_info.rb
61
67
  homepage: http://github.com/punditcommunity/pundit-matchers
62
68
  licenses:
63
69
  - MIT
64
- metadata: {}
70
+ metadata:
71
+ rubygems_mfa_required: 'true'
65
72
  post_install_message:
66
73
  rdoc_options: []
67
74
  require_paths:
@@ -70,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
77
  requirements:
71
78
  - - ">="
72
79
  - !ruby/object:Gem::Version
73
- version: '0'
80
+ version: '3.0'
74
81
  required_rubygems_version: !ruby/object:Gem::Requirement
75
82
  requirements:
76
83
  - - ">="