shoulda-matchers 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -7
- data/.travis.yml +4 -0
- data/Appraisals +8 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +77 -66
- data/MIT-LICENSE +1 -1
- data/NEWS.md +63 -1
- data/README.md +189 -33
- data/Rakefile +6 -5
- data/features/rails_integration.feature +1 -1
- data/features/step_definitions/rails_steps.rb +7 -6
- data/gemfiles/3.0.gemfile +2 -2
- data/gemfiles/3.0.gemfile.lock +14 -5
- data/gemfiles/3.1.gemfile +2 -2
- data/gemfiles/3.1.gemfile.lock +14 -5
- data/gemfiles/3.2.gemfile +2 -2
- data/gemfiles/3.2.gemfile.lock +16 -7
- data/gemfiles/4.0.0.gemfile +2 -2
- data/gemfiles/4.0.0.gemfile.lock +15 -6
- data/gemfiles/4.0.1.gemfile +2 -2
- data/gemfiles/4.0.1.gemfile.lock +15 -6
- data/gemfiles/4.1.gemfile +19 -0
- data/gemfiles/4.1.gemfile.lock +176 -0
- data/lib/shoulda/matchers.rb +17 -1
- data/lib/shoulda/matchers/action_controller.rb +4 -2
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +100 -0
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +4 -4
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +12 -12
- data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +2 -1
- data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +167 -0
- data/lib/shoulda/matchers/active_model.rb +4 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +23 -5
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +0 -4
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +66 -14
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/errors.rb +40 -0
- data/lib/shoulda/matchers/active_model/helpers.rb +6 -6
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +33 -14
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +26 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/{odd_even_number_matcher.rb → numeric_type_matcher.rb} +9 -20
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +26 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +5 -21
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +71 -22
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +6 -1
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +25 -6
- data/lib/shoulda/matchers/active_record.rb +1 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +67 -13
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +40 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +24 -1
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/assertion_error.rb +7 -2
- data/lib/shoulda/matchers/error.rb +24 -0
- data/lib/shoulda/matchers/independent.rb +10 -0
- data/lib/shoulda/matchers/independent/delegate_matcher.rb +157 -0
- data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +34 -0
- data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +36 -0
- data/lib/shoulda/matchers/integrations/rspec.rb +13 -14
- data/lib/shoulda/matchers/integrations/test_unit.rb +11 -9
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +7 -0
- data/shoulda-matchers.gemspec +2 -1
- data/spec/shoulda/matchers/action_controller/callback_matcher_spec.rb +79 -0
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +3 -3
- data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +11 -11
- data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +21 -21
- data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +10 -10
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +45 -18
- data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +8 -8
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +19 -19
- data/spec/shoulda/matchers/action_controller/route_params_spec.rb +6 -6
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +11 -11
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +44 -44
- data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +205 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +24 -24
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +37 -37
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +17 -21
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +24 -24
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +173 -67
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +40 -40
- data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +20 -20
- data/spec/shoulda/matchers/active_model/helpers_spec.rb +27 -25
- data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +126 -13
- data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +27 -26
- data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +15 -15
- data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +8 -8
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +9 -9
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +229 -44
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +44 -25
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +110 -62
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +19 -19
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +30 -30
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +378 -192
- data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +4 -0
- data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +33 -33
- data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +21 -17
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +8 -8
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +14 -14
- data/spec/shoulda/matchers/independent/delegate_matcher/stubbed_target_spec.rb +43 -0
- data/spec/shoulda/matchers/independent/delegate_matcher_spec.rb +184 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/activemodel_helpers.rb +2 -2
- data/spec/support/capture_helpers.rb +19 -0
- data/spec/support/controller_builder.rb +22 -3
- data/spec/support/fail_with_message_including_matcher.rb +33 -0
- data/spec/support/model_builder.rb +1 -1
- data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
- data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
- data/spec/support/test_application.rb +23 -0
- metadata +90 -22
- checksums.yaml +0 -7
- data/spec/shoulda/matchers/active_model/numericality_matchers/odd_even_number_matcher_spec.rb +0 -97
- data/spec/support/shared_examples/numerical_submatcher_spec.rb +0 -23
@@ -7,144 +7,144 @@ describe Shoulda::Matchers::ActionController::SetTheFlashMatcher do
|
|
7
7
|
|
8
8
|
context 'a controller that sets a flash message' do
|
9
9
|
it 'accepts setting any flash message' do
|
10
|
-
controller_with_flash(:
|
10
|
+
expect(controller_with_flash(notice: 'hi')).to set_the_flash
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'accepts setting the exact flash message' do
|
14
|
-
controller_with_flash(:
|
14
|
+
expect(controller_with_flash(notice: 'hi')).to set_the_flash.to('hi')
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'accepts setting a matched flash message' do
|
18
|
-
controller_with_flash(:
|
18
|
+
expect(controller_with_flash(notice: 'hello')).to set_the_flash.to(/he/)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'rejects setting a different flash message' do
|
22
|
-
controller_with_flash(:
|
23
|
-
|
22
|
+
expect(controller_with_flash(notice: 'hi')).
|
23
|
+
not_to set_the_flash.to('other')
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'rejects setting a different pattern' do
|
27
|
-
controller_with_flash(:
|
28
|
-
|
27
|
+
expect(controller_with_flash(notice: 'hi')).
|
28
|
+
not_to set_the_flash.to(/other/)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'a controller that sets a flash.now message' do
|
33
33
|
it 'rejects setting any flash message' do
|
34
|
-
controller_with_flash_now.
|
34
|
+
expect(controller_with_flash_now).not_to set_the_flash
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'accepts setting any flash.now message' do
|
38
|
-
controller_with_flash_now.
|
38
|
+
expect(controller_with_flash_now).to set_the_flash.now
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'accepts setting the exact flash.now message' do
|
42
|
-
controller_with_flash_now(:
|
43
|
-
|
42
|
+
expect(controller_with_flash_now(notice: 'hi')).
|
43
|
+
to set_the_flash.now.to('hi')
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'accepts setting a matched flash.now message' do
|
47
|
-
controller_with_flash_now(:
|
48
|
-
|
47
|
+
expect(controller_with_flash_now(notice: 'flasher')).
|
48
|
+
to set_the_flash.now.to(/lash/)
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'rejects setting a different flash.now message' do
|
52
|
-
controller_with_flash_now(:
|
53
|
-
|
52
|
+
expect(controller_with_flash_now(notice: 'hi')).
|
53
|
+
not_to set_the_flash.now.to('other')
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'rejects setting a different flash.now pattern' do
|
57
|
-
controller_with_flash_now(:
|
58
|
-
|
57
|
+
expect(controller_with_flash_now(notice: 'hi')).
|
58
|
+
not_to set_the_flash.now.to(/other/)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
context 'a controller that sets flash messages for multiple keys' do
|
63
63
|
it 'accepts flash message for either key' do
|
64
|
-
controller = controller_with_flash(:
|
64
|
+
controller = controller_with_flash(notice: 'one', alert: 'two')
|
65
65
|
|
66
|
-
controller.
|
67
|
-
controller.
|
66
|
+
expect(controller).to set_the_flash[:notice]
|
67
|
+
expect(controller).to set_the_flash[:alert]
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'rejects a flash message that is not one of the set keys' do
|
71
|
-
controller_with_flash(:
|
72
|
-
|
71
|
+
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
72
|
+
not_to set_the_flash[:warning]
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'accepts exact flash message of notice' do
|
76
|
-
controller_with_flash(:
|
77
|
-
|
76
|
+
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
77
|
+
to set_the_flash[:notice].to('one')
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'accepts setting a matched flash message of notice' do
|
81
|
-
controller_with_flash(:
|
82
|
-
|
81
|
+
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
82
|
+
to set_the_flash[:notice].to(/on/)
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'rejects setting a different flash message of notice' do
|
86
|
-
controller_with_flash(:
|
87
|
-
|
86
|
+
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
87
|
+
not_to set_the_flash[:notice].to('other')
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'rejects setting a different pattern' do
|
91
|
-
controller_with_flash(:
|
92
|
-
|
91
|
+
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
92
|
+
not_to set_the_flash[:notice].to(/other/)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
context 'a controller that sets flash and flash.now' do
|
97
97
|
it 'accepts setting any flash.now message' do
|
98
|
-
controller =
|
98
|
+
controller = build_fake_response do
|
99
99
|
flash.now[:notice] = 'value'
|
100
100
|
flash[:success] = 'great job'
|
101
101
|
end
|
102
102
|
|
103
|
-
controller.
|
104
|
-
controller.
|
103
|
+
expect(controller).to set_the_flash.now
|
104
|
+
expect(controller).to set_the_flash
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'accepts setting a matched flash.now message' do
|
108
|
-
controller =
|
108
|
+
controller = build_fake_response do
|
109
109
|
flash.now[:notice] = 'value'
|
110
110
|
flash[:success] = 'great job'
|
111
111
|
end
|
112
112
|
|
113
|
-
controller.
|
114
|
-
controller.
|
113
|
+
expect(controller).to set_the_flash.now.to(/value/)
|
114
|
+
expect(controller).to set_the_flash.to(/great/)
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'rejects setting a different flash.now message' do
|
118
|
-
controller =
|
118
|
+
controller = build_fake_response do
|
119
119
|
flash.now[:notice] = 'value'
|
120
120
|
flash[:success] = 'great job'
|
121
121
|
end
|
122
122
|
|
123
|
-
controller.
|
124
|
-
controller.
|
123
|
+
expect(controller).not_to set_the_flash.now.to('other')
|
124
|
+
expect(controller).not_to set_the_flash.to('other')
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
128
|
context 'a controller that does not set a flash message' do
|
129
129
|
it 'rejects setting any flash message' do
|
130
|
-
controller_with_no_flashes.
|
130
|
+
expect(controller_with_no_flashes).not_to set_the_flash
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
134
|
def controller_with_no_flashes
|
135
|
-
|
135
|
+
build_fake_response
|
136
136
|
end
|
137
137
|
|
138
138
|
def controller_with_flash(flash_hash)
|
139
|
-
|
139
|
+
build_fake_response do
|
140
140
|
flash_hash.each do |key, value|
|
141
141
|
flash[key] = value
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
def controller_with_flash_now(flash_hash = { :
|
147
|
-
|
146
|
+
def controller_with_flash_now(flash_hash = { notice: 'hi' })
|
147
|
+
build_fake_response do
|
148
148
|
flash_hash.each do |key, value|
|
149
149
|
flash.now[key] = value
|
150
150
|
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActionController do
|
4
|
+
describe "#permit" do
|
5
|
+
it 'matches when the sent parameter is allowed' do
|
6
|
+
controller_class = controller_for_resource_with_strong_parameters(action: :create) do
|
7
|
+
params.require(:user).permit(:name)
|
8
|
+
end
|
9
|
+
|
10
|
+
expect(controller_class).to permit(:name).for(:create)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'does not match when the sent parameter is not allowed' do
|
14
|
+
controller_class = controller_for_resource_with_strong_parameters(action: :create) do
|
15
|
+
params.require(:user).permit(:name)
|
16
|
+
end
|
17
|
+
|
18
|
+
expect(controller_class).not_to permit(:admin).for(:create)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'matches against multiple attributes' do
|
22
|
+
controller_class = controller_for_resource_with_strong_parameters(action: :create) do
|
23
|
+
params.require(:user).permit(:name, :age)
|
24
|
+
end
|
25
|
+
|
26
|
+
expect(controller_class).to permit(:name, :age).for(:create)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
|
32
|
+
describe '#description' do
|
33
|
+
it 'returns the correct string' do
|
34
|
+
options = { action: :create, method: :post }
|
35
|
+
controller_for_resource_with_strong_parameters(options) do
|
36
|
+
params.permit(:name, :age)
|
37
|
+
end
|
38
|
+
|
39
|
+
matcher = described_class.new([:name, :age, :height]).for(:create)
|
40
|
+
expect(matcher.description).
|
41
|
+
to eq 'permit POST #create to receive parameters :name, :age, and :height'
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when a verb is specified' do
|
45
|
+
it 'returns the correct string' do
|
46
|
+
options = { action: :some_action }
|
47
|
+
controller_for_resource_with_strong_parameters(options) do
|
48
|
+
params.permit(:name, :age)
|
49
|
+
end
|
50
|
+
|
51
|
+
matcher = described_class.new([:name]).
|
52
|
+
for(:some_action, verb: :put)
|
53
|
+
expect(matcher.description).
|
54
|
+
to eq 'permit PUT #some_action to receive parameters :name'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#matches?" do
|
60
|
+
it "is true for a subset of the allowable attributes" do
|
61
|
+
controller_for_resource_with_strong_parameters(action: :create) do
|
62
|
+
params.require(:user).permit(:name)
|
63
|
+
end
|
64
|
+
|
65
|
+
matcher = described_class.new([:name]).in_context(self).for(:create)
|
66
|
+
expect(matcher.matches?).to be_true
|
67
|
+
end
|
68
|
+
|
69
|
+
it "is true for all the allowable attributes" do
|
70
|
+
controller_for_resource_with_strong_parameters(action: :create) do
|
71
|
+
params.require(:user).permit(:name, :age)
|
72
|
+
end
|
73
|
+
|
74
|
+
matcher = described_class.new([:name, :age]).in_context(self).for(:create)
|
75
|
+
expect(matcher.matches?).to be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "is false when any attributes are not allowed" do
|
79
|
+
controller_for_resource_with_strong_parameters(action: :create) do
|
80
|
+
params.require(:user).permit(:name)
|
81
|
+
end
|
82
|
+
|
83
|
+
matcher = described_class.new([:name, :admin]).in_context(self).for(:create)
|
84
|
+
expect(matcher.matches?).to be_false
|
85
|
+
end
|
86
|
+
|
87
|
+
it "is false when permit is not called" do
|
88
|
+
controller_for_resource_with_strong_parameters(action: :create) {}
|
89
|
+
|
90
|
+
matcher = described_class.new([:name]).in_context(self).for(:create)
|
91
|
+
expect(matcher.matches?).to be_false
|
92
|
+
end
|
93
|
+
|
94
|
+
it "requires an action" do
|
95
|
+
matcher = described_class.new([:name])
|
96
|
+
expect { matcher.matches? }
|
97
|
+
.to raise_error(Shoulda::Matchers::ActionController::StrongParametersMatcher::ActionNotDefinedError)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "requires a verb for non-restful action" do
|
101
|
+
matcher = described_class.new([:name]).for(:authorize)
|
102
|
+
expect { matcher.matches? }
|
103
|
+
.to raise_error(Shoulda::Matchers::ActionController::StrongParametersMatcher::VerbNotDefinedError)
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'Stubbing ActionController::Parameters#[]' do
|
107
|
+
it "does not permanently stub []" do
|
108
|
+
controller_for_resource_with_strong_parameters(action: :create) do
|
109
|
+
params.require(:user).permit(:name)
|
110
|
+
end
|
111
|
+
|
112
|
+
described_class.new([:name]).in_context(self).for(:create).matches?
|
113
|
+
|
114
|
+
param = ActionController::Parameters.new(name: 'Ralph')[:name]
|
115
|
+
expect(param.singleton_class).not_to include(
|
116
|
+
Shoulda::Matchers::ActionController::StrongParametersMatcher::StubbedParameters
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'prevents permanently overwriting [] on error' do
|
121
|
+
stub_controller_with_exception
|
122
|
+
|
123
|
+
begin
|
124
|
+
described_class.new([:name]).in_context(self).for(:create).matches?
|
125
|
+
rescue SimulatedError
|
126
|
+
end
|
127
|
+
|
128
|
+
param = ActionController::Parameters.new(name: 'Ralph')[:name]
|
129
|
+
expect(param.singleton_class).not_to include(
|
130
|
+
Shoulda::Matchers::ActionController::StrongParametersMatcher::StubbedParameters
|
131
|
+
)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "failure message" do
|
137
|
+
it "includes all missing attributes" do
|
138
|
+
controller_class = controller_for_resource_with_strong_parameters(action: :create) do
|
139
|
+
params.require(:user).permit(:name, :age)
|
140
|
+
end
|
141
|
+
|
142
|
+
expect {
|
143
|
+
expect(controller_class).to permit(:name, :age, :city, :country).for(:create)
|
144
|
+
}.to fail_with_message("Expected controller to permit city and country, but it did not.")
|
145
|
+
end
|
146
|
+
|
147
|
+
it "includes all attributes that should not have been allowed but were" do
|
148
|
+
controller_class = controller_for_resource_with_strong_parameters(action: :create) do
|
149
|
+
params.require(:user).permit(:name, :age)
|
150
|
+
end
|
151
|
+
|
152
|
+
expect {
|
153
|
+
expect(controller_class).not_to permit(:name, :age).for(:create)
|
154
|
+
}.to fail_with_message("Expected controller not to permit name and age, but it did.")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "#for" do
|
159
|
+
context "when given :create" do
|
160
|
+
it "posts to the controller" do
|
161
|
+
context = stub('context', post: nil)
|
162
|
+
matcher = described_class.new([:name]).in_context(context).for(:create)
|
163
|
+
|
164
|
+
matcher.matches?
|
165
|
+
expect(context).to have_received(:post).with(:create)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when given :update" do
|
170
|
+
it "puts to the controller" do
|
171
|
+
context = stub('context', put: nil)
|
172
|
+
matcher = described_class.new([:name]).in_context(context).for(:update)
|
173
|
+
|
174
|
+
matcher.matches?
|
175
|
+
expect(context).to have_received(:put).with(:update)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "when given a custom action and verb" do
|
180
|
+
it "deletes to the controller" do
|
181
|
+
context = stub('context', delete: nil)
|
182
|
+
matcher = described_class.new([:name]).in_context(context).for(:hide, verb: :delete)
|
183
|
+
|
184
|
+
matcher.matches?
|
185
|
+
expect(context).to have_received(:delete).with(:hide)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def stub_controller_with_exception
|
191
|
+
controller = define_controller('Examples') do
|
192
|
+
def create
|
193
|
+
raise SimulatedError
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
setup_rails_controller_test(controller)
|
198
|
+
|
199
|
+
define_routes do
|
200
|
+
get 'examples', to: 'examples#create'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
class SimulatedError < StandardError; end
|
205
|
+
end
|
@@ -4,16 +4,16 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher do
|
|
4
4
|
context '#description' do
|
5
5
|
context 'without a role' do
|
6
6
|
it 'includes the attribute name' do
|
7
|
-
described_class.new(:attr).description.
|
8
|
-
|
7
|
+
expect(described_class.new(:attr).description).
|
8
|
+
to eq 'allow mass assignment of attr'
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
if active_model_3_1?
|
13
13
|
context 'with a role' do
|
14
14
|
it 'includes the attribute name and the role' do
|
15
|
-
described_class.new(:attr).as(:admin).description.
|
16
|
-
|
15
|
+
expect(described_class.new(:attr).as(:admin).description).
|
16
|
+
to eq 'allow mass assignment of attr as admin'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -21,71 +21,71 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher do
|
|
21
21
|
|
22
22
|
context 'an attribute that is blacklisted from mass-assignment' do
|
23
23
|
it 'rejects being mass-assignable' do
|
24
|
-
model = define_model(:example, :
|
24
|
+
model = define_model(:example, blacklisted: :string) do
|
25
25
|
attr_protected :blacklisted
|
26
26
|
end.new
|
27
27
|
|
28
|
-
model.
|
28
|
+
expect(model).not_to allow_mass_assignment_of(:blacklisted)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'an attribute that is not whitelisted for mass-assignment' do
|
33
33
|
it 'rejects being mass-assignable' do
|
34
|
-
model = define_model(:example, :
|
35
|
-
:
|
34
|
+
model = define_model(:example, not_whitelisted: :string,
|
35
|
+
whitelisted: :string) do
|
36
36
|
attr_accessible :whitelisted
|
37
37
|
end.new
|
38
38
|
|
39
|
-
model.
|
39
|
+
expect(model).not_to allow_mass_assignment_of(:not_whitelisted)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
context 'an attribute that is whitelisted for mass-assignment' do
|
44
44
|
it 'accepts being mass-assignable' do
|
45
|
-
define_model(:example, :
|
45
|
+
expect(define_model(:example, whitelisted: :string) do
|
46
46
|
attr_accessible :whitelisted
|
47
|
-
end.new.
|
47
|
+
end.new).to allow_mass_assignment_of(:whitelisted)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
context 'an attribute not included in the mass-assignment blacklist' do
|
52
52
|
it 'accepts being mass-assignable' do
|
53
|
-
model = define_model(:example, :
|
54
|
-
:
|
53
|
+
model = define_model(:example, not_blacklisted: :string,
|
54
|
+
blacklisted: :string) do
|
55
55
|
attr_protected :blacklisted
|
56
56
|
end.new
|
57
57
|
|
58
|
-
model.
|
58
|
+
expect(model).to allow_mass_assignment_of(:not_blacklisted)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
unless active_model_3_2? || active_model_4_0?
|
63
63
|
context 'an attribute on a class with no protected attributes' do
|
64
64
|
it 'accepts being mass-assignable' do
|
65
|
-
no_protected_attributes.
|
65
|
+
expect(no_protected_attributes).to allow_mass_assignment_of(:attr)
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'assigns a negative failure message' do
|
69
69
|
matcher = allow_mass_assignment_of(:attr)
|
70
70
|
|
71
|
-
matcher.matches?(no_protected_attributes).
|
71
|
+
expect(matcher.matches?(no_protected_attributes)).to eq true
|
72
72
|
|
73
|
-
matcher.failure_message_when_negated.
|
73
|
+
expect(matcher.failure_message_when_negated).not_to be_nil
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def no_protected_attributes
|
78
|
-
define_model(:example, :
|
78
|
+
define_model(:example, attr: :string).new
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
82
|
context 'an attribute on a class with all protected attributes' do
|
83
83
|
it 'rejects being mass-assignable' do
|
84
|
-
all_protected_attributes.
|
84
|
+
expect(all_protected_attributes).not_to allow_mass_assignment_of(:attr)
|
85
85
|
end
|
86
86
|
|
87
87
|
def all_protected_attributes
|
88
|
-
define_model(:example, :
|
88
|
+
define_model(:example, attr: :string) do
|
89
89
|
attr_accessible nil
|
90
90
|
end.new
|
91
91
|
end
|
@@ -94,16 +94,16 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher do
|
|
94
94
|
if active_model_3_1?
|
95
95
|
context 'an attribute included in the mass-assignment whitelist for admin role only' do
|
96
96
|
it 'rejects being mass-assignable' do
|
97
|
-
mass_assignable_as_admin.
|
97
|
+
expect(mass_assignable_as_admin).not_to allow_mass_assignment_of(:attr)
|
98
98
|
end
|
99
99
|
|
100
100
|
it 'accepts being mass-assignable for admin' do
|
101
|
-
mass_assignable_as_admin.
|
101
|
+
expect(mass_assignable_as_admin).to allow_mass_assignment_of(:attr).as(:admin)
|
102
102
|
end
|
103
103
|
|
104
104
|
def mass_assignable_as_admin
|
105
|
-
define_model(:example, :
|
106
|
-
attr_accessible :attr, :
|
105
|
+
define_model(:example, attr: :string) do
|
106
|
+
attr_accessible :attr, as: :admin
|
107
107
|
end.new
|
108
108
|
end
|
109
109
|
end
|