shoulda-matchers 3.1.3 → 4.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound/ruby.yml +336 -316
- data/.python-version +1 -0
- data/.rubocop.yml +3 -1
- data/.travis.yml +7 -6
- data/Appraisals +76 -44
- data/CONTRIBUTING.md +137 -66
- data/Gemfile +5 -5
- data/Gemfile.lock +30 -35
- data/MAINTAINING.md +250 -0
- data/MIT-LICENSE +1 -1
- data/NEWS.md +176 -4
- data/README.md +138 -200
- data/Rakefile +7 -0
- data/bin/setup +190 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/global.css +4 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -6
- data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -17
- data/doc_config/yard/templates/default/fulldoc/html/setup.rb +27 -0
- data/gemfiles/4.2.gemfile +21 -20
- data/gemfiles/4.2.gemfile.lock +143 -140
- data/gemfiles/5.0.gemfile +37 -0
- data/gemfiles/5.0.gemfile.lock +238 -0
- data/gemfiles/5.1.gemfile +38 -0
- data/gemfiles/5.1.gemfile.lock +254 -0
- data/gemfiles/5.2.gemfile +40 -0
- data/gemfiles/5.2.gemfile.lock +273 -0
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +18 -6
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -1
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +87 -27
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +1 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +0 -4
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +5 -0
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -0
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +26 -11
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +39 -4
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +116 -47
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +127 -38
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +55 -37
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +30 -1
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +11 -4
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +11 -6
- data/lib/shoulda/matchers/active_record.rb +3 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +172 -22
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +11 -6
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +46 -0
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +51 -0
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +268 -38
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +111 -0
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +207 -79
- data/lib/shoulda/matchers/doublespeak/object_double.rb +5 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +100 -21
- data/lib/shoulda/matchers/rails_shim.rb +133 -52
- data/lib/shoulda/matchers/routing.rb +2 -2
- data/lib/shoulda/matchers/util.rb +23 -1
- data/lib/shoulda/matchers/util/word_wrap.rb +6 -2
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/install_gems_in_all_appraisals +3 -1
- data/script/run_all_tests +3 -1
- data/script/supported_ruby_versions +7 -0
- data/script/update_gem_in_all_appraisals +3 -1
- data/script/update_gems_in_all_appraisals +3 -1
- data/shoulda-matchers.gemspec +3 -3
- data/spec/acceptance/independent_matchers_spec.rb +2 -2
- data/spec/acceptance/multiple_libraries_integration_spec.rb +1 -1
- data/spec/acceptance/rails_integration_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -3
- data/spec/support/acceptance/helpers.rb +2 -0
- data/spec/support/acceptance/helpers/command_helpers.rb +17 -4
- data/spec/support/acceptance/helpers/rails_migration_helpers.rb +21 -0
- data/spec/support/acceptance/helpers/step_helpers.rb +1 -1
- data/spec/support/tests/current_bundle.rb +3 -9
- data/spec/support/tests/filesystem.rb +2 -2
- data/spec/support/unit/attribute.rb +0 -2
- data/spec/support/unit/capture.rb +9 -3
- data/spec/support/unit/helpers/action_pack_versions.rb +22 -0
- data/spec/support/unit/helpers/active_model_versions.rb +4 -0
- data/spec/support/unit/helpers/active_record_versions.rb +22 -2
- data/spec/support/unit/helpers/active_resource_builder.rb +2 -2
- data/spec/support/unit/helpers/controller_builder.rb +1 -1
- data/spec/support/unit/helpers/message_helpers.rb +19 -0
- data/spec/support/unit/helpers/rails_versions.rb +14 -0
- data/spec/support/unit/matchers/fail_with_message_matcher.rb +7 -5
- data/spec/support/unit/matchers/print_warning_including.rb +21 -13
- data/spec/support/unit/model_creation_strategies/active_record.rb +1 -1
- data/spec/support/unit/model_creators/active_record.rb +0 -1
- data/spec/support/unit/model_creators/basic.rb +7 -2
- data/spec/support/unit/rails_application.rb +25 -0
- data/spec/support/unit/record_validating_confirmation_builder.rb +5 -2
- data/spec/support/unit/validation_matcher_scenario.rb +0 -2
- data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +18 -18
- data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +33 -5
- data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +1 -1
- data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +80 -78
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +7 -9
- data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +28 -4
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +19 -1
- data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +27 -4
- data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +62 -5
- data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +52 -18
- data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +51 -4
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +99 -71
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +41 -15
- data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +445 -15
- data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +615 -93
- data/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb +169 -0
- data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +167 -97
- data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +2 -4
- data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +152 -19
- data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +258 -94
- data/spec/unit_spec_helper.rb +9 -1
- data/zeus.json +1 -1
- metadata +31 -16
- data/gemfiles/4.0.0.gemfile +0 -38
- data/gemfiles/4.0.0.gemfile.lock +0 -223
- data/gemfiles/4.0.1.gemfile +0 -38
- data/gemfiles/4.0.1.gemfile.lock +0 -225
- data/gemfiles/4.1.gemfile +0 -38
- data/gemfiles/4.1.gemfile.lock +0 -220
- data/script/SUPPORTED_VERSIONS +0 -1
@@ -24,13 +24,15 @@ module UnitTests
|
|
24
24
|
lines << Shoulda::Matchers::Util.indent(expected, 2)
|
25
25
|
|
26
26
|
if @actual
|
27
|
+
diff = differ.diff(@actual, expected)[1..-1]
|
28
|
+
|
27
29
|
lines << 'Actually failed with:'
|
28
30
|
lines << Shoulda::Matchers::Util.indent(@actual, 2)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
2
|
33
|
-
|
31
|
+
|
32
|
+
if diff
|
33
|
+
lines << 'Diff:'
|
34
|
+
lines << Shoulda::Matchers::Util.indent(diff, 2)
|
35
|
+
end
|
34
36
|
else
|
35
37
|
lines << 'However, the expectation did not fail at all.'
|
36
38
|
end
|
@@ -11,43 +11,51 @@ module UnitTests
|
|
11
11
|
|
12
12
|
def matches?(block)
|
13
13
|
@captured_stderr = collapse_whitespace(capture(:stderr, &block))
|
14
|
+
@was_negated = false
|
14
15
|
captured_stderr.include?(expected_warning)
|
15
16
|
end
|
16
17
|
|
18
|
+
def does_not_match?(block)
|
19
|
+
!matches?(block).tap do
|
20
|
+
@was_negated = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
def failure_message
|
18
|
-
"Expected block to #{expectation}\
|
25
|
+
"Expected block to #{expectation}\n\nHowever, #{aberration}"
|
19
26
|
end
|
20
|
-
alias_method :failure_message_for_should, :failure_message
|
21
27
|
|
22
28
|
def failure_message_when_negated
|
23
|
-
"Expected block not to #{expectation},
|
29
|
+
"Expected block not to #{expectation}\n\nHowever, #{aberration}"
|
24
30
|
end
|
25
|
-
alias_method :failure_message_for_should_not,
|
26
|
-
:failure_message_when_negated
|
27
31
|
|
28
32
|
def description
|
29
|
-
"should #{
|
33
|
+
"should print a warning containing #{expected_warning.inspect}"
|
30
34
|
end
|
31
35
|
|
32
36
|
def supports_block_expectations?
|
33
37
|
true
|
34
38
|
end
|
35
39
|
|
36
|
-
|
40
|
+
private
|
37
41
|
|
38
42
|
attr_reader :expected_warning, :captured_stderr
|
39
43
|
|
40
|
-
|
44
|
+
def was_negated?
|
45
|
+
@was_negated
|
46
|
+
end
|
41
47
|
|
42
48
|
def expectation
|
43
|
-
"print a warning
|
49
|
+
"print a warning containing:\n\n #{expected_warning}"
|
44
50
|
end
|
45
51
|
|
46
|
-
def
|
47
|
-
if
|
48
|
-
|
52
|
+
def aberration
|
53
|
+
if was_negated?
|
54
|
+
'it did.'
|
55
|
+
elsif captured_stderr.empty?
|
56
|
+
'it actually printed nothing.'
|
49
57
|
else
|
50
|
-
":\n #{captured_stderr}"
|
58
|
+
"it actually printed:\n\n #{captured_stderr}"
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
@@ -79,8 +79,13 @@ module UnitTests
|
|
79
79
|
overrides[:changing_values_with]
|
80
80
|
)
|
81
81
|
|
82
|
-
if
|
83
|
-
write_attribute(
|
82
|
+
if (
|
83
|
+
respond_to?(:write_attribute) && (
|
84
|
+
!self.class.respond_to?(:reflect_on_association) ||
|
85
|
+
!self.class.reflect_on_association(attribute_name)
|
86
|
+
)
|
87
|
+
)
|
88
|
+
write_attribute(attribute_name, new_value)
|
84
89
|
else
|
85
90
|
super(new_value)
|
86
91
|
end
|
@@ -2,6 +2,7 @@ require_relative '../tests/bundle'
|
|
2
2
|
require_relative '../tests/command_runner'
|
3
3
|
require_relative '../tests/database'
|
4
4
|
require_relative '../tests/filesystem'
|
5
|
+
require_relative 'helpers/rails_versions'
|
5
6
|
|
6
7
|
require 'yaml'
|
7
8
|
|
@@ -74,7 +75,12 @@ module UnitTests
|
|
74
75
|
def generate
|
75
76
|
rails_new
|
76
77
|
fix_available_locales_warning
|
78
|
+
remove_bootsnap
|
77
79
|
write_database_configuration
|
80
|
+
|
81
|
+
if bundle.version_of("rails") >= 5
|
82
|
+
add_initializer_for_time_zone_aware_types
|
83
|
+
end
|
78
84
|
end
|
79
85
|
|
80
86
|
def rails_new
|
@@ -93,10 +99,29 @@ end
|
|
93
99
|
end
|
94
100
|
end
|
95
101
|
|
102
|
+
def remove_bootsnap
|
103
|
+
# Rails 5.2 introduced bootsnap, which is helpful when you're developing
|
104
|
+
# or deploying an app, but we don't really need it (and it messes with
|
105
|
+
# Zeus anyhow)
|
106
|
+
fs.comment_lines_matching(
|
107
|
+
'config/boot.rb',
|
108
|
+
%r{\Arequire 'bootsnap/setup'},
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
96
112
|
def write_database_configuration
|
97
113
|
YAML.dump(database.config.to_hash, fs.open('config/database.yml', 'w'))
|
98
114
|
end
|
99
115
|
|
116
|
+
def add_initializer_for_time_zone_aware_types
|
117
|
+
path = 'config/initializers/configure_time_zone_aware_types.rb'
|
118
|
+
fs.write(path, <<-TEXT)
|
119
|
+
Rails.application.configure do
|
120
|
+
config.active_record.time_zone_aware_types = [:datetime, :time]
|
121
|
+
end
|
122
|
+
TEXT
|
123
|
+
end
|
124
|
+
|
100
125
|
def load_environment
|
101
126
|
require environment_file_path
|
102
127
|
end
|
@@ -13,7 +13,7 @@ module UnitTests
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def model_name
|
16
|
-
'Example'
|
16
|
+
options.fetch(:model_name, 'Example')
|
17
17
|
end
|
18
18
|
|
19
19
|
def record
|
@@ -29,7 +29,10 @@ module UnitTests
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def confirmation_attribute
|
32
|
-
|
32
|
+
options.fetch(
|
33
|
+
:confirmation_attribute,
|
34
|
+
:"#{attribute_to_confirm}_confirmation"
|
35
|
+
)
|
33
36
|
end
|
34
37
|
|
35
38
|
def attribute_that_receives_error
|
@@ -54,29 +54,29 @@ describe Shoulda::Matchers::ActionController::CallbackMatcher, type: :controller
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
if action_pack_lt_5?
|
58
|
+
describe '#use_before_filter' do
|
59
|
+
it_behaves_like 'CallbackMatcher', :before, :filter
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
describe '#use_after_filter' do
|
63
|
+
it_behaves_like 'CallbackMatcher', :after, :filter
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
describe '#use_around_filter' do
|
67
|
+
it_behaves_like 'CallbackMatcher', :around, :filter
|
68
|
+
end
|
67
69
|
end
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
71
|
+
describe '#use_before_action' do
|
72
|
+
it_behaves_like 'CallbackMatcher', :before, :action
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
75
|
+
describe '#use_after_action' do
|
76
|
+
it_behaves_like 'CallbackMatcher', :after, :action
|
77
|
+
end
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
end
|
79
|
+
describe '#use_around_action' do
|
80
|
+
it_behaves_like 'CallbackMatcher', :around, :action
|
81
81
|
end
|
82
82
|
end
|
@@ -498,7 +498,12 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
498
498
|
|
499
499
|
matcher.matches?(controller)
|
500
500
|
|
501
|
-
|
501
|
+
expect_to_have_made_controller_request(
|
502
|
+
verb: :post,
|
503
|
+
action: :create,
|
504
|
+
params: {},
|
505
|
+
context: context,
|
506
|
+
)
|
502
507
|
end
|
503
508
|
end
|
504
509
|
|
@@ -511,7 +516,12 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
511
516
|
|
512
517
|
matcher.matches?(controller)
|
513
518
|
|
514
|
-
|
519
|
+
expect_to_have_made_controller_request(
|
520
|
+
verb: :patch,
|
521
|
+
action: :update,
|
522
|
+
params: {},
|
523
|
+
context: context,
|
524
|
+
)
|
515
525
|
end
|
516
526
|
else
|
517
527
|
it 'PUTs to the controller' do
|
@@ -521,7 +531,12 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
521
531
|
|
522
532
|
matcher.matches?(controller)
|
523
533
|
|
524
|
-
|
534
|
+
expect_to_have_made_controller_request(
|
535
|
+
verb: :put,
|
536
|
+
action: :update,
|
537
|
+
params: {},
|
538
|
+
context: context,
|
539
|
+
)
|
525
540
|
end
|
526
541
|
end
|
527
542
|
end
|
@@ -536,7 +551,12 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
536
551
|
|
537
552
|
matcher.matches?(controller)
|
538
553
|
|
539
|
-
|
554
|
+
expect_to_have_made_controller_request(
|
555
|
+
verb: :delete,
|
556
|
+
action: :hide,
|
557
|
+
params: {},
|
558
|
+
context: context,
|
559
|
+
)
|
540
560
|
end
|
541
561
|
end
|
542
562
|
end
|
@@ -566,7 +586,7 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
566
586
|
end
|
567
587
|
end
|
568
588
|
|
569
|
-
|
589
|
+
head :ok
|
570
590
|
end
|
571
591
|
end
|
572
592
|
|
@@ -598,4 +618,12 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
|
|
598
618
|
def build_context
|
599
619
|
double('context', post: nil, put: nil, patch: nil, delete: nil)
|
600
620
|
end
|
621
|
+
|
622
|
+
def expect_to_have_made_controller_request(context:, verb:, action:, params:)
|
623
|
+
if action_pack_gte_5?
|
624
|
+
expect(context).to have_received(verb).with(action, params: params)
|
625
|
+
else
|
626
|
+
expect(context).to have_received(verb).with(action, params)
|
627
|
+
end
|
628
|
+
end
|
601
629
|
end
|
@@ -69,7 +69,7 @@ describe Shoulda::Matchers::ActionController::RenderTemplateMatcher, type: :cont
|
|
69
69
|
|
70
70
|
context 'a controller that does not render a template' do
|
71
71
|
it 'rejects rendering a template' do
|
72
|
-
expect(build_fake_response {
|
72
|
+
expect(build_fake_response { head :ok }).
|
73
73
|
not_to render_template(:show)
|
74
74
|
end
|
75
75
|
end
|
@@ -1,115 +1,117 @@
|
|
1
1
|
require 'unit_spec_helper'
|
2
2
|
|
3
3
|
describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher, type: :model do
|
4
|
-
|
5
|
-
context '
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
if action_pack_lt_5?
|
5
|
+
context '#description' do
|
6
|
+
context 'without a role' do
|
7
|
+
it 'includes the attribute name' do
|
8
|
+
expect(described_class.new(:attr).description).
|
9
|
+
to eq 'allow mass assignment of attr'
|
10
|
+
end
|
9
11
|
end
|
10
|
-
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
if active_model_3_1?
|
14
|
+
context 'with a role' do
|
15
|
+
it 'includes the attribute name and the role' do
|
16
|
+
expect(described_class.new(:attr).as(:admin).description).
|
17
|
+
to eq 'allow mass assignment of attr as admin'
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
context 'an attribute that is blacklisted from mass-assignment' do
|
24
|
+
it 'rejects being mass-assignable' do
|
25
|
+
model = define_model(:example, blacklisted: :string) do
|
26
|
+
attr_protected :blacklisted
|
27
|
+
end.new
|
27
28
|
|
28
|
-
|
29
|
+
expect(model).not_to allow_mass_assignment_of(:blacklisted)
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
context 'an attribute that is not whitelisted for mass-assignment' do
|
34
|
+
it 'rejects being mass-assignable' do
|
35
|
+
model = define_model(:example, not_whitelisted: :string,
|
36
|
+
whitelisted: :string) do
|
37
|
+
attr_accessible :whitelisted
|
38
|
+
end.new
|
38
39
|
|
39
|
-
|
40
|
+
expect(model).not_to allow_mass_assignment_of(:not_whitelisted)
|
41
|
+
end
|
40
42
|
end
|
41
|
-
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
context 'an attribute that is whitelisted for mass-assignment' do
|
45
|
+
it 'accepts being mass-assignable' do
|
46
|
+
expect(define_model(:example, whitelisted: :string) do
|
47
|
+
attr_accessible :whitelisted
|
48
|
+
end.new).to allow_mass_assignment_of(:whitelisted)
|
49
|
+
end
|
48
50
|
end
|
49
|
-
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
context 'an attribute not included in the mass-assignment blacklist' do
|
53
|
+
it 'accepts being mass-assignable' do
|
54
|
+
model = define_model(:example, not_blacklisted: :string,
|
55
|
+
blacklisted: :string) do
|
56
|
+
attr_protected :blacklisted
|
57
|
+
end.new
|
57
58
|
|
58
|
-
|
59
|
+
expect(model).to allow_mass_assignment_of(:not_blacklisted)
|
60
|
+
end
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
unless active_model_3_2? || active_model_4_0?
|
64
|
+
context 'an attribute on a class with no protected attributes' do
|
65
|
+
it 'accepts being mass-assignable' do
|
66
|
+
expect(no_protected_attributes).to allow_mass_assignment_of(:attr)
|
67
|
+
end
|
67
68
|
|
68
|
-
|
69
|
-
|
69
|
+
it 'assigns a negative failure message' do
|
70
|
+
matcher = allow_mass_assignment_of(:attr)
|
70
71
|
|
71
|
-
|
72
|
+
expect(matcher.matches?(no_protected_attributes)).to eq true
|
72
73
|
|
73
|
-
|
74
|
+
expect(matcher.failure_message_when_negated).not_to be_nil
|
75
|
+
end
|
74
76
|
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def no_protected_attributes
|
78
|
-
define_model(:example, attr: :string).new
|
79
|
-
end
|
80
|
-
end
|
81
77
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
def all_protected_attributes
|
88
|
-
define_model(:example, attr: :string) do
|
89
|
-
attr_accessible nil
|
90
|
-
end.new
|
78
|
+
def no_protected_attributes
|
79
|
+
define_model(:example, attr: :string).new
|
80
|
+
end
|
91
81
|
end
|
92
|
-
end
|
93
82
|
|
94
|
-
|
95
|
-
context 'an attribute included in the mass-assignment whitelist for admin role only' do
|
83
|
+
context 'an attribute on a class with all protected attributes' do
|
96
84
|
it 'rejects being mass-assignable' do
|
97
|
-
expect(
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'accepts being mass-assignable for admin' do
|
101
|
-
expect(mass_assignable_as_admin).to allow_mass_assignment_of(:attr).as(:admin)
|
85
|
+
expect(all_protected_attributes).not_to allow_mass_assignment_of(:attr)
|
102
86
|
end
|
103
87
|
|
104
|
-
def
|
88
|
+
def all_protected_attributes
|
105
89
|
define_model(:example, attr: :string) do
|
106
|
-
attr_accessible
|
90
|
+
attr_accessible nil
|
107
91
|
end.new
|
108
92
|
end
|
109
93
|
end
|
110
|
-
end
|
111
94
|
|
112
|
-
|
113
|
-
|
95
|
+
if active_model_3_1?
|
96
|
+
context 'an attribute included in the mass-assignment whitelist for admin role only' do
|
97
|
+
it 'rejects being mass-assignable' do
|
98
|
+
expect(mass_assignable_as_admin).not_to allow_mass_assignment_of(:attr)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'accepts being mass-assignable for admin' do
|
102
|
+
expect(mass_assignable_as_admin).to allow_mass_assignment_of(:attr).as(:admin)
|
103
|
+
end
|
104
|
+
|
105
|
+
def mass_assignable_as_admin
|
106
|
+
define_model(:example, attr: :string) do
|
107
|
+
attr_accessible :attr, as: :admin
|
108
|
+
end.new
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def define_model(name, columns, &block)
|
114
|
+
super(name, columns, whitelist_attributes: false, &block)
|
115
|
+
end
|
114
116
|
end
|
115
117
|
end
|