shoulda-matchers 4.5.1 → 5.0.0.rc1

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: a62f760706ab97ba90edd181dbdf330ce6e8203c8ec3ec37a258022e202a53a6
4
- data.tar.gz: 68f333b57646a8a437b73ff43f617efa9231674fb92f68de73365eb1408932f0
3
+ metadata.gz: b4bebbe2dbe599d4b1c19061803f12abb87578322e17a96a56d0442399ef72a9
4
+ data.tar.gz: 4742002f75d6cc61f6eb4419a4729632c000519ff1bd1e9c52754c251835294d
5
5
  SHA512:
6
- metadata.gz: ea01851ee8521ff08ab6b1caea192c161e34286e5fd361cbceb6b84404813fa952acb73c70481c3140b2c5116ffce8bb386bf1feea70754f827a3918292b1bfb
7
- data.tar.gz: 286ac5e78d534651889c5e3ed3843e1afa50d0fd77ed896c4ca3cf3622596cb7e1f47d2ae053e38100ce443dbfd80fbf1a8d099ecdfbbcf8d70912dbe3f42ad3
6
+ metadata.gz: 7b7c3f78337afc8da72887fa743956839d637e6eb277b0c6ba06a55837468b4ec598ae1bf534b58c9287b5b3e381e7ffe228a19b32a78c434f1048ffa6378441
7
+ data.tar.gz: 5944d64e1ab63143363ad0a2ee1f32fe761178664fe2e1bff38b71b324341719ec48619cc687d1b185dc1544e32badc65a21f16c694b33147db100fd93a33d2e
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][travis-badge]][travis] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
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
- [travis-badge]: https://img.shields.io/travis/thoughtbot/shoulda-matchers/master.svg
6
- [travis]: https://travis-ci.org/thoughtbot/shoulda-matchers
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
@@ -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#L79)**
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#L129)**
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#L54)**
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 [tested][travis] and supported against Ruby 2.4+, Rails
472
- 4.2+, RSpec 3.x, and Minitest 5.x.
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
- Shoulda::Matchers::RailsShim.make_controller_request(
255
- context,
256
- verb,
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.now
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..-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? && association_reflection.macro.in?(
331
- [:has_many, :has_and_belongs_to_many],
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 && RailsShim.active_record_gte_5?
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
- @missing = foreign_key_failure_message(klass, options[:foreign_key])
1399
- false
1400
- elsif !has_column?(klass, foreign_key)
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 foreign_key
1446
- key = if foreign_key_reflection
1447
- if foreign_key_reflection.respond_to?(:foreign_key)
1448
- foreign_key_reflection.foreign_key
1449
- else
1450
- foreign_key_reflection.primary_key_name
1451
- end
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
- key.to_s
1455
+ foreign_key_reflection.primary_key_name
1458
1456
  end
1459
1457
  end
1460
1458
 
@@ -42,7 +42,7 @@ module Shoulda
42
42
  end
43
43
 
44
44
  def join_table_exists?
45
- if RailsShim.tables_and_views(connection).
45
+ if connection.data_sources.
46
46
  include?(join_table_name.to_s)
47
47
  true
48
48
  else
@@ -65,7 +65,7 @@ module Shoulda
65
65
  end
66
66
 
67
67
  def validation_message_key
68
- RailsShim.validation_message_key_for_association_required_option
68
+ :required
69
69
  end
70
70
  end
71
71
  end
@@ -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
- model.columns_hash[attribute_name.to_s]
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
@@ -185,7 +185,7 @@ module Shoulda
185
185
  leftover = ''
186
186
  else
187
187
  fitted_line = line[0..index].rstrip
188
- leftover = line[index + 1..-1]
188
+ leftover = line[index + 1..]
189
189
  end
190
190
 
191
191
  { fitted_line: fitted_line, leftover: leftover }
@@ -1,6 +1,6 @@
1
1
  module Shoulda
2
2
  module Matchers
3
3
  # @private
4
- VERSION = '4.5.1'.freeze
4
+ VERSION = '5.0.0.rc1'.freeze
5
5
  end
6
6
  end
@@ -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.4.0'
40
- s.add_dependency('activesupport', '>= 4.2.0')
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.5.1
4
+ version: 5.0.0.rc1
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-01-22 00:00:00.000000000 Z
17
+ date: 2021-06-04 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: 4.2.0
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: 4.2.0
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.4.0
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
- version: '0'
193
+ version: 1.3.1
195
194
  requirements: []
196
- rubygems_version: 3.1.4
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