shoulda-matchers 4.5.1 → 5.0.0
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 +4 -4
- data/README.md +12 -10
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +0 -87
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +3 -6
- data/lib/shoulda/matchers/active_model.rb +0 -1
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validator.rb +1 -6
- data/lib/shoulda/matchers/active_record/association_matcher.rb +20 -22
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +10 -1
- data/lib/shoulda/matchers/rails_shim.rb +0 -39
- data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +2 -2
- metadata +6 -7
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -161
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 319b0cb3944a37309b11169bd71ffddde2d6af35b262795e7c16466d6d2c497c
|
4
|
+
data.tar.gz: 22ac49d578766e24a18826bcde86443a09afa41c1cfc9ee7932f94f214623a36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05a067ef5aa288661855f6257a55ce887bdf19f6684cd965c145669815a3d432a236cd7fb88e21647d0251e4e971b6c45b03af04def19b5cefbef26279276d81
|
7
|
+
data.tar.gz: f06e9c331d39d82fd450332cb0b81e108852c7fac2a28927ada2fbccc11b31226206023f69eb6ecccd7dceaaca4c9b3410b818ed86babd3f7f37bb4c778013df
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][
|
1
|
+
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][github-actions-badge]][github-actions] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
|
2
2
|
|
3
3
|
[version-badge]: https://img.shields.io/gem/v/shoulda-matchers.svg
|
4
4
|
[rubygems]: https://rubygems.org/gems/shoulda-matchers
|
5
|
-
[
|
6
|
-
[
|
5
|
+
[github-actions-badge]: https://img.shields.io/github/workflow/status/thoughtbot/shoulda-matchers/Test
|
6
|
+
[github-actions]: https://github.com/thoughtbot/shoulda-matchers/actions
|
7
7
|
[downloads-total]: https://img.shields.io/gem/dt/shoulda-matchers.svg
|
8
8
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
9
9
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
@@ -55,7 +55,7 @@ Start by including `shoulda-matchers` in your Gemfile:
|
|
55
55
|
|
56
56
|
```ruby
|
57
57
|
group :test do
|
58
|
-
gem 'shoulda-matchers', '~>
|
58
|
+
gem 'shoulda-matchers', '~> 5.0'
|
59
59
|
end
|
60
60
|
```
|
61
61
|
|
@@ -430,11 +430,11 @@ about any of them, make sure to [consult the documentation][rubydocs]!
|
|
430
430
|
makes assertions on the `session` hash.
|
431
431
|
* **[set_flash](lib/shoulda/matchers/action_controller/set_flash_matcher.rb)**
|
432
432
|
makes assertions on the `flash` hash.
|
433
|
-
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
433
|
+
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L29)**
|
434
434
|
tests that an `after_action` callback is defined in your controller.
|
435
|
-
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
435
|
+
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L75)**
|
436
436
|
tests that an `around_action` callback is defined in your controller.
|
437
|
-
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
437
|
+
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L4)**
|
438
438
|
tests that a `before_action` callback is defined in your controller.
|
439
439
|
|
440
440
|
### Routing matchers
|
@@ -468,12 +468,14 @@ machine, understanding the codebase, and creating a good pull request.
|
|
468
468
|
|
469
469
|
## Compatibility
|
470
470
|
|
471
|
-
Shoulda Matchers is
|
472
|
-
|
471
|
+
Shoulda Matchers is tested and supported against Ruby 2.6+, Rails
|
472
|
+
5.2+, RSpec 3.x, and Minitest 5.x.
|
473
473
|
|
474
|
-
For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
474
|
+
- For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
475
|
+
- For Ruby < 3.0 and Rails < 6.1 compatibility, please use [v4.5.1][v4.5.1].
|
475
476
|
|
476
477
|
[v3.1.3]: https://github.com/thoughtbot/shoulda-matchers/tree/v3.1.3
|
478
|
+
[v4.5.1]: https://github.com/thoughtbot/shoulda-matchers/tree/v4.5.1
|
477
479
|
|
478
480
|
## Versioning
|
479
481
|
|
@@ -1,64 +1,6 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
module ActionController
|
4
|
-
# The `use_before_filter` matcher is used to test that a before_filter
|
5
|
-
# callback is defined within your controller.
|
6
|
-
#
|
7
|
-
# class UsersController < ApplicationController
|
8
|
-
# before_filter :authenticate_user!
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# # RSpec
|
12
|
-
# RSpec.describe UsersController, type: :controller do
|
13
|
-
# it { should use_before_filter(:authenticate_user!) }
|
14
|
-
# it { should_not use_before_filter(:prevent_ssl) }
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# # Minitest (Shoulda)
|
18
|
-
# class UsersControllerTest < ActionController::TestCase
|
19
|
-
# should use_before_filter(:authenticate_user!)
|
20
|
-
# should_not use_before_filter(:prevent_ssl)
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @note This method is only available when using shoulda-matchers under
|
24
|
-
# Rails 4.x.
|
25
|
-
# @return [CallbackMatcher]
|
26
|
-
#
|
27
|
-
if RailsShim.action_pack_lt_5?
|
28
|
-
def use_before_filter(callback)
|
29
|
-
CallbackMatcher.new(callback, :before, :filter)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# The `use_after_filter` matcher is used to test that an after_filter
|
34
|
-
# callback is defined within your controller.
|
35
|
-
#
|
36
|
-
# class IssuesController < ApplicationController
|
37
|
-
# after_filter :log_activity
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# # RSpec
|
41
|
-
# RSpec.describe IssuesController, type: :controller do
|
42
|
-
# it { should use_after_filter(:log_activity) }
|
43
|
-
# it { should_not use_after_filter(:destroy_user) }
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# # Minitest (Shoulda)
|
47
|
-
# class IssuesControllerTest < ActionController::TestCase
|
48
|
-
# should use_after_filter(:log_activity)
|
49
|
-
# should_not use_after_filter(:destroy_user)
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# @note This method is only available when using shoulda-matchers under
|
53
|
-
# Rails 4.x.
|
54
|
-
# @return [CallbackMatcher]
|
55
|
-
#
|
56
|
-
if RailsShim.action_pack_lt_5?
|
57
|
-
def use_after_filter(callback)
|
58
|
-
CallbackMatcher.new(callback, :after, :filter)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
4
|
# The `use_before_action` matcher is used to test that a before_action
|
63
5
|
# callback is defined within your controller.
|
64
6
|
#
|
@@ -109,35 +51,6 @@ module Shoulda
|
|
109
51
|
CallbackMatcher.new(callback, :after, :action)
|
110
52
|
end
|
111
53
|
|
112
|
-
# The `use_around_filter` matcher is used to test that an around_filter
|
113
|
-
# callback is defined within your controller.
|
114
|
-
#
|
115
|
-
# class ChangesController < ApplicationController
|
116
|
-
# around_filter :wrap_in_transaction
|
117
|
-
# end
|
118
|
-
#
|
119
|
-
# # RSpec
|
120
|
-
# RSpec.describe ChangesController, type: :controller do
|
121
|
-
# it { should use_around_filter(:wrap_in_transaction) }
|
122
|
-
# it { should_not use_around_filter(:save_view_context) }
|
123
|
-
# end
|
124
|
-
#
|
125
|
-
# # Minitest (Shoulda)
|
126
|
-
# class ChangesControllerTest < ActionController::TestCase
|
127
|
-
# should use_around_filter(:wrap_in_transaction)
|
128
|
-
# should_not use_around_filter(:save_view_context)
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# @note This method is only available when using shoulda-matchers under
|
132
|
-
# Rails 4.x.
|
133
|
-
# @return [CallbackMatcher]
|
134
|
-
#
|
135
|
-
if RailsShim.action_pack_lt_5?
|
136
|
-
def use_around_filter(callback)
|
137
|
-
CallbackMatcher.new(callback, :around, :filter)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
54
|
# The `use_around_action` matcher is used to test that an around_action
|
142
55
|
# callback is defined within your controller.
|
143
56
|
#
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
1
2
|
module Shoulda
|
2
3
|
module Matchers
|
3
4
|
module ActionController
|
@@ -34,10 +35,7 @@ module Shoulda
|
|
34
35
|
expected_value === actual_value
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
-
def empty?
|
39
|
-
flash.empty?
|
40
|
-
end
|
38
|
+
delegate :empty?, to: :flash
|
41
39
|
|
42
40
|
def use_now!
|
43
41
|
@use_now = true
|
@@ -251,12 +251,9 @@ module Shoulda
|
|
251
251
|
parameters_double_registry.register
|
252
252
|
|
253
253
|
Doublespeak.with_doubles_activated do
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
action,
|
258
|
-
request_params,
|
259
|
-
)
|
254
|
+
params = { params: request_params }
|
255
|
+
|
256
|
+
context.__send__(verb, action, **params)
|
260
257
|
end
|
261
258
|
|
262
259
|
unpermitted_parameter_names.empty?
|
@@ -26,7 +26,6 @@ require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
|
26
26
|
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
27
27
|
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
28
28
|
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
29
|
-
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
|
30
29
|
require 'shoulda/matchers/active_model/errors'
|
31
30
|
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
32
31
|
|
@@ -113,7 +113,7 @@ module Shoulda
|
|
113
113
|
case column_type
|
114
114
|
when :integer, :float then 1
|
115
115
|
when :decimal then BigDecimal(1, 0)
|
116
|
-
when :datetime, :time, :timestamp then Time.
|
116
|
+
when :datetime, :time, :timestamp then Time.current
|
117
117
|
when :date then Date.new
|
118
118
|
when :binary then '0'
|
119
119
|
else 'an arbitrary value'
|
@@ -643,7 +643,7 @@ module Shoulda
|
|
643
643
|
if number_of_submatchers_for_failure_message > 1
|
644
644
|
"In checking that #{model.name} #{submatcher_description}, " +
|
645
645
|
failure_message[0].downcase +
|
646
|
-
failure_message[1
|
646
|
+
failure_message[1..]
|
647
647
|
else
|
648
648
|
failure_message
|
649
649
|
end
|
@@ -327,8 +327,8 @@ validation for you? Instead of using `validate_presence_of`, try
|
|
327
327
|
end
|
328
328
|
|
329
329
|
def collection_association?
|
330
|
-
association? &&
|
331
|
-
|
330
|
+
association? && [:has_many, :has_and_belongs_to_many].include?(
|
331
|
+
association_reflection.macro,
|
332
332
|
)
|
333
333
|
end
|
334
334
|
|
@@ -98,12 +98,7 @@ module Shoulda
|
|
98
98
|
|
99
99
|
all_validation_errors = record.errors.dup
|
100
100
|
|
101
|
-
validation_error_messages =
|
102
|
-
if record.errors.respond_to?(:[])
|
103
|
-
record.errors[attribute]
|
104
|
-
else
|
105
|
-
record.errors.on(attribute)
|
106
|
-
end
|
101
|
+
validation_error_messages = record.errors[attribute]
|
107
102
|
|
108
103
|
{
|
109
104
|
all_validation_errors: all_validation_errors,
|
@@ -1004,7 +1004,7 @@ module Shoulda
|
|
1004
1004
|
@submatchers = []
|
1005
1005
|
@missing = ''
|
1006
1006
|
|
1007
|
-
if macro == :belongs_to
|
1007
|
+
if macro == :belongs_to
|
1008
1008
|
required(belongs_to_required_by_default?)
|
1009
1009
|
end
|
1010
1010
|
end
|
@@ -1394,23 +1394,25 @@ module Shoulda
|
|
1394
1394
|
end
|
1395
1395
|
|
1396
1396
|
def class_has_foreign_key?(klass)
|
1397
|
+
@missing = validate_foreign_key(klass)
|
1398
|
+
|
1399
|
+
@missing.nil?
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def validate_foreign_key(klass)
|
1397
1403
|
if options.key?(:foreign_key) && !foreign_key_correct?
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
@missing = foreign_key_failure_message(klass, foreign_key)
|
1402
|
-
false
|
1403
|
-
else
|
1404
|
-
true
|
1404
|
+
foreign_key_failure_message(klass, options[:foreign_key])
|
1405
|
+
elsif !has_column?(klass, actual_foreign_key)
|
1406
|
+
foreign_key_failure_message(klass, actual_foreign_key)
|
1405
1407
|
end
|
1406
1408
|
end
|
1407
1409
|
|
1408
1410
|
def has_column?(klass, column)
|
1409
1411
|
case column
|
1410
1412
|
when Array
|
1411
|
-
column.all? { |c| has_column?(klass, c) }
|
1413
|
+
column.all? { |c| has_column?(klass, c.to_s) }
|
1412
1414
|
else
|
1413
|
-
column_names_for(klass).include?(column)
|
1415
|
+
column_names_for(klass).include?(column.to_s)
|
1414
1416
|
end
|
1415
1417
|
end
|
1416
1418
|
|
@@ -1442,19 +1444,15 @@ module Shoulda
|
|
1442
1444
|
end
|
1443
1445
|
end
|
1444
1446
|
|
1445
|
-
def
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
end
|
1453
|
-
|
1454
|
-
if key.is_a?(Array)
|
1455
|
-
key.map(&:to_s)
|
1447
|
+
def actual_foreign_key
|
1448
|
+
return unless foreign_key_reflection
|
1449
|
+
|
1450
|
+
if foreign_key_reflection.options[:foreign_key]
|
1451
|
+
foreign_key_reflection.options[:foreign_key]
|
1452
|
+
elsif foreign_key_reflection.respond_to?(:foreign_key)
|
1453
|
+
foreign_key_reflection.foreign_key
|
1456
1454
|
else
|
1457
|
-
|
1455
|
+
foreign_key_reflection.primary_key_name
|
1458
1456
|
end
|
1459
1457
|
end
|
1460
1458
|
|
@@ -6,16 +6,22 @@ module Shoulda
|
|
6
6
|
#
|
7
7
|
# class Process < ActiveRecord::Base
|
8
8
|
# enum status: [:running, :stopped, :suspended]
|
9
|
+
#
|
10
|
+
# alias_attribute :kind, :SomeLegacyField
|
11
|
+
#
|
12
|
+
# enum kind: [:foo, :bar]
|
9
13
|
# end
|
10
14
|
#
|
11
15
|
# # RSpec
|
12
16
|
# RSpec.describe Process, type: :model do
|
13
17
|
# it { should define_enum_for(:status) }
|
18
|
+
# it { should define_enum_for(:kind) }
|
14
19
|
# end
|
15
20
|
#
|
16
21
|
# # Minitest (Shoulda)
|
17
22
|
# class ProcessTest < ActiveSupport::TestCase
|
18
23
|
# should define_enum_for(:status)
|
24
|
+
# should define_enum_for(:kind)
|
19
25
|
# end
|
20
26
|
#
|
21
27
|
# #### Qualifiers
|
@@ -370,7 +376,10 @@ module Shoulda
|
|
370
376
|
end
|
371
377
|
|
372
378
|
def column
|
373
|
-
|
379
|
+
key = attribute_name.to_s
|
380
|
+
column_name = model.attribute_alias(key) || key
|
381
|
+
|
382
|
+
model.columns_hash[column_name]
|
374
383
|
end
|
375
384
|
|
376
385
|
def model
|
@@ -3,24 +3,12 @@ module Shoulda
|
|
3
3
|
# @private
|
4
4
|
module RailsShim # rubocop:disable Metrics/ModuleLength
|
5
5
|
class << self
|
6
|
-
def action_pack_gte_5?
|
7
|
-
Gem::Requirement.new('>= 5').satisfied_by?(action_pack_version)
|
8
|
-
end
|
9
|
-
|
10
|
-
def action_pack_lt_5?
|
11
|
-
Gem::Requirement.new('< 5').satisfied_by?(action_pack_version)
|
12
|
-
end
|
13
|
-
|
14
6
|
def action_pack_version
|
15
7
|
Gem::Version.new(::ActionPack::VERSION::STRING)
|
16
8
|
rescue NameError
|
17
9
|
Gem::Version.new('0')
|
18
10
|
end
|
19
11
|
|
20
|
-
def active_record_gte_5?
|
21
|
-
Gem::Requirement.new('>= 5').satisfied_by?(active_record_version)
|
22
|
-
end
|
23
|
-
|
24
12
|
def active_record_gte_6?
|
25
13
|
Gem::Requirement.new('>= 6').satisfied_by?(active_record_version)
|
26
14
|
end
|
@@ -57,17 +45,6 @@ module Shoulda
|
|
57
45
|
)
|
58
46
|
end
|
59
47
|
|
60
|
-
def make_controller_request(context, verb, action, request_params)
|
61
|
-
params =
|
62
|
-
if action_pack_gte_5?
|
63
|
-
{ params: request_params }
|
64
|
-
else
|
65
|
-
request_params
|
66
|
-
end
|
67
|
-
|
68
|
-
context.__send__(verb, action, params)
|
69
|
-
end
|
70
|
-
|
71
48
|
def serialized_attributes_for(model)
|
72
49
|
attribute_types_for(model).
|
73
50
|
inject({}) do |hash, (attribute_name, attribute_type)|
|
@@ -85,26 +62,10 @@ module Shoulda
|
|
85
62
|
serialized_attributes_for(model)[attribute_name.to_s]
|
86
63
|
end
|
87
64
|
|
88
|
-
def tables_and_views(connection)
|
89
|
-
if active_record_gte_5?
|
90
|
-
connection.data_sources
|
91
|
-
else
|
92
|
-
connection.tables
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
65
|
def verb_for_update
|
97
66
|
:patch
|
98
67
|
end
|
99
68
|
|
100
|
-
def validation_message_key_for_association_required_option
|
101
|
-
if active_record_gte_5?
|
102
|
-
:required
|
103
|
-
else
|
104
|
-
:blank
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
69
|
def parent_of(mod)
|
109
70
|
if mod.respond_to?(:module_parent)
|
110
71
|
mod.module_parent
|
data/shoulda-matchers.gemspec
CHANGED
@@ -36,6 +36,6 @@ Gem::Specification.new do |s|
|
|
36
36
|
'shoulda-matchers.gemspec']
|
37
37
|
s.require_paths = ['lib']
|
38
38
|
|
39
|
-
s.required_ruby_version = '>= 2.
|
40
|
-
s.add_dependency('activesupport', '>=
|
39
|
+
s.required_ruby_version = '>= 2.6.0'
|
40
|
+
s.add_dependency('activesupport', '>= 5.2.0')
|
41
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoulda-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammer Saleh
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2021-
|
17
|
+
date: 2021-07-10 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activesupport
|
@@ -22,14 +22,14 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version:
|
25
|
+
version: 5.2.0
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 5.2.0
|
33
33
|
description: 'Shoulda Matchers provides RSpec- and Minitest-compatible one-liners
|
34
34
|
to test common Rails functionality that, if written by hand, would be much longer,
|
35
35
|
more complex, and error-prone. '
|
@@ -60,7 +60,6 @@ files:
|
|
60
60
|
- lib/shoulda/matchers/action_controller/set_session_matcher.rb
|
61
61
|
- lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb
|
62
62
|
- lib/shoulda/matchers/active_model.rb
|
63
|
-
- lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb
|
64
63
|
- lib/shoulda/matchers/active_model/allow_value_matcher.rb
|
65
64
|
- lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb
|
66
65
|
- lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb
|
@@ -186,14 +185,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
185
|
requirements:
|
187
186
|
- - ">="
|
188
187
|
- !ruby/object:Gem::Version
|
189
|
-
version: 2.
|
188
|
+
version: 2.6.0
|
190
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
190
|
requirements:
|
192
191
|
- - ">="
|
193
192
|
- !ruby/object:Gem::Version
|
194
193
|
version: '0'
|
195
194
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
195
|
+
rubygems_version: 3.2.15
|
197
196
|
signing_key:
|
198
197
|
specification_version: 4
|
199
198
|
summary: Simple one-liner tests for common Rails functionality
|
@@ -1,161 +0,0 @@
|
|
1
|
-
module Shoulda
|
2
|
-
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
# The `allow_mass_assignment_of` matcher tests usage of Rails 3's
|
5
|
-
# `attr_accessible` and `attr_protected` macros, asserting that an
|
6
|
-
# attribute in your model is contained in either the whitelist or
|
7
|
-
# blacklist and thus can or cannot be set via mass assignment.
|
8
|
-
#
|
9
|
-
# class Post
|
10
|
-
# include ActiveModel::Model
|
11
|
-
# include ActiveModel::MassAssignmentSecurity
|
12
|
-
# attr_accessor :title
|
13
|
-
#
|
14
|
-
# attr_accessible :title
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# class User
|
18
|
-
# include ActiveModel::Model
|
19
|
-
# include ActiveModel::MassAssignmentSecurity
|
20
|
-
# attr_accessor :encrypted_password
|
21
|
-
#
|
22
|
-
# attr_protected :encrypted_password
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# # RSpec
|
26
|
-
# RSpec.describe Post, type: :model do
|
27
|
-
# it { should allow_mass_assignment_of(:title) }
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# RSpec.describe User, type: :model do
|
31
|
-
# it { should_not allow_mass_assignment_of(:encrypted_password) }
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# # Minitest (Shoulda)
|
35
|
-
# class PostTest < ActiveSupport::TestCase
|
36
|
-
# should allow_mass_assignment_of(:title)
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# class UserTest < ActiveSupport::TestCase
|
40
|
-
# should_not allow_mass_assignment_of(:encrypted_password)
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# #### Optional qualifiers
|
44
|
-
#
|
45
|
-
# ##### as
|
46
|
-
#
|
47
|
-
# Use `as` if your mass-assignment rules apply only under a certain role
|
48
|
-
# *(Rails >= 3.1 only)*.
|
49
|
-
#
|
50
|
-
# class Post
|
51
|
-
# include ActiveModel::Model
|
52
|
-
# include ActiveModel::MassAssignmentSecurity
|
53
|
-
# attr_accessor :title
|
54
|
-
#
|
55
|
-
# attr_accessible :title, as: :admin
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# # RSpec
|
59
|
-
# RSpec.describe Post, type: :model do
|
60
|
-
# it { should allow_mass_assignment_of(:title).as(:admin) }
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# # Minitest (Shoulda)
|
64
|
-
# class PostTest < ActiveSupport::TestCase
|
65
|
-
# should allow_mass_assignment_of(:title).as(:admin)
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# @return [AllowMassAssignmentOfMatcher]
|
69
|
-
#
|
70
|
-
def allow_mass_assignment_of(value)
|
71
|
-
AllowMassAssignmentOfMatcher.new(value)
|
72
|
-
end
|
73
|
-
|
74
|
-
# @private
|
75
|
-
class AllowMassAssignmentOfMatcher
|
76
|
-
attr_reader :failure_message, :failure_message_when_negated
|
77
|
-
|
78
|
-
def initialize(attribute)
|
79
|
-
@attribute = attribute.to_s
|
80
|
-
@options = {}
|
81
|
-
end
|
82
|
-
|
83
|
-
def as(role)
|
84
|
-
@options[:role] = role
|
85
|
-
self
|
86
|
-
end
|
87
|
-
|
88
|
-
def matches?(subject)
|
89
|
-
@subject = subject
|
90
|
-
if attr_mass_assignable?
|
91
|
-
if whitelisting?
|
92
|
-
@failure_message_when_negated = "#{@attribute} was made "\
|
93
|
-
'accessible'
|
94
|
-
elsif protected_attributes.empty?
|
95
|
-
@failure_message_when_negated = 'no attributes were protected'
|
96
|
-
else
|
97
|
-
@failure_message_when_negated =
|
98
|
-
"#{class_name} is protecting " <<
|
99
|
-
"#{protected_attributes.to_a.to_sentence}, " <<
|
100
|
-
"but not #{@attribute}."
|
101
|
-
end
|
102
|
-
true
|
103
|
-
else
|
104
|
-
@failure_message =
|
105
|
-
if whitelisting?
|
106
|
-
"Expected #{@attribute} to be accessible"
|
107
|
-
else
|
108
|
-
"Did not expect #{@attribute} to be protected"
|
109
|
-
end
|
110
|
-
false
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def description
|
115
|
-
[base_description, role_description].compact.join(' ')
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
def base_description
|
121
|
-
"allow mass assignment of #{@attribute}"
|
122
|
-
end
|
123
|
-
|
124
|
-
def role_description
|
125
|
-
if role != :default
|
126
|
-
"as #{role}"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def role
|
131
|
-
@options[:role] || :default
|
132
|
-
end
|
133
|
-
|
134
|
-
def protected_attributes
|
135
|
-
@_protected_attributes ||= (@subject.class.protected_attributes || [])
|
136
|
-
end
|
137
|
-
|
138
|
-
def accessible_attributes
|
139
|
-
@_accessible_attributes ||=
|
140
|
-
(@subject.class.accessible_attributes || [])
|
141
|
-
end
|
142
|
-
|
143
|
-
def whitelisting?
|
144
|
-
authorizer.is_a?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
145
|
-
end
|
146
|
-
|
147
|
-
def attr_mass_assignable?
|
148
|
-
!authorizer.deny?(@attribute)
|
149
|
-
end
|
150
|
-
|
151
|
-
def authorizer
|
152
|
-
@subject.class.active_authorizer[role]
|
153
|
-
end
|
154
|
-
|
155
|
-
def class_name
|
156
|
-
@subject.class.name
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|