shoulda-matchers 4.0.0.rc1 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +72 -40
  4. data/lib/shoulda/matchers/action_controller.rb +2 -0
  5. data/lib/shoulda/matchers/active_model.rb +2 -3
  6. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +1 -0
  7. data/lib/shoulda/matchers/active_record.rb +2 -0
  8. data/lib/shoulda/matchers/active_record/association_matcher.rb +34 -0
  9. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +27 -4
  10. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +27 -4
  11. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +1 -1
  12. data/lib/shoulda/matchers/independent.rb +2 -1
  13. data/lib/shoulda/matchers/rails_shim.rb +5 -9
  14. data/lib/shoulda/matchers/version.rb +1 -1
  15. data/lib/shoulda/matchers/warn.rb +1 -0
  16. data/shoulda-matchers.gemspec +11 -3
  17. metadata +13 -340
  18. data/.gitignore +0 -12
  19. data/.hound.yml +0 -3
  20. data/.hound/ruby.yml +0 -1062
  21. data/.python-version +0 -1
  22. data/.rubocop.yml +0 -15
  23. data/.travis.yml +0 -21
  24. data/.yardopts +0 -10
  25. data/Appraisals +0 -105
  26. data/CONTRIBUTING.md +0 -172
  27. data/Gemfile +0 -15
  28. data/Gemfile.lock +0 -59
  29. data/MAINTAINING.md +0 -250
  30. data/NEWS.md +0 -1235
  31. data/Rakefile +0 -46
  32. data/bin/setup +0 -190
  33. data/custom_plan.rb +0 -104
  34. data/doc_config/gh-pages/index.html.erb +0 -9
  35. data/doc_config/yard/setup.rb +0 -22
  36. data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -5967
  37. data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +0 -12
  38. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +0 -66
  39. data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +0 -69
  40. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +0 -312
  41. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -26
  42. data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +0 -1
  43. data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +0 -8
  44. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -281
  45. data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +0 -1
  46. data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +0 -289
  47. data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +0 -6
  48. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +0 -35
  49. data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +0 -14
  50. data/doc_config/yard/templates/default/layout/html/fonts.erb +0 -1
  51. data/doc_config/yard/templates/default/layout/html/footer.erb +0 -6
  52. data/doc_config/yard/templates/default/layout/html/layout.erb +0 -23
  53. data/doc_config/yard/templates/default/layout/html/search.erb +0 -13
  54. data/doc_config/yard/templates/default/layout/html/setup.rb +0 -40
  55. data/doc_config/yard/templates/default/method_details/html/source.erb +0 -10
  56. data/doc_config/yard/templates/default/module/html/box_info.erb +0 -31
  57. data/gemfiles/4.2.gemfile +0 -39
  58. data/gemfiles/4.2.gemfile.lock +0 -246
  59. data/gemfiles/5.0.gemfile +0 -37
  60. data/gemfiles/5.0.gemfile.lock +0 -238
  61. data/gemfiles/5.1.gemfile +0 -38
  62. data/gemfiles/5.1.gemfile.lock +0 -254
  63. data/gemfiles/5.2.gemfile +0 -40
  64. data/gemfiles/5.2.gemfile.lock +0 -273
  65. data/script/install_gems_in_all_appraisals +0 -16
  66. data/script/run_all_tests +0 -16
  67. data/script/supported_ruby_versions +0 -7
  68. data/script/update_gem_in_all_appraisals +0 -17
  69. data/script/update_gems_in_all_appraisals +0 -16
  70. data/spec/acceptance/active_model_integration_spec.rb +0 -23
  71. data/spec/acceptance/independent_matchers_spec.rb +0 -125
  72. data/spec/acceptance/multiple_libraries_integration_spec.rb +0 -55
  73. data/spec/acceptance/rails_integration_spec.rb +0 -156
  74. data/spec/acceptance_spec_helper.rb +0 -23
  75. data/spec/doublespeak_spec_helper.rb +0 -2
  76. data/spec/report_warnings.rb +0 -7
  77. data/spec/spec_helper.rb +0 -20
  78. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +0 -133
  79. data/spec/support/acceptance/helpers.rb +0 -33
  80. data/spec/support/acceptance/helpers/active_model_helpers.rb +0 -11
  81. data/spec/support/acceptance/helpers/array_helpers.rb +0 -13
  82. data/spec/support/acceptance/helpers/base_helpers.rb +0 -19
  83. data/spec/support/acceptance/helpers/command_helpers.rb +0 -68
  84. data/spec/support/acceptance/helpers/file_helpers.rb +0 -19
  85. data/spec/support/acceptance/helpers/gem_helpers.rb +0 -31
  86. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -11
  87. data/spec/support/acceptance/helpers/n_unit_helpers.rb +0 -25
  88. data/spec/support/acceptance/helpers/pluralization_helpers.rb +0 -13
  89. data/spec/support/acceptance/helpers/rails_migration_helpers.rb +0 -21
  90. data/spec/support/acceptance/helpers/rails_version_helpers.rb +0 -11
  91. data/spec/support/acceptance/helpers/rspec_helpers.rb +0 -24
  92. data/spec/support/acceptance/helpers/ruby_version_helpers.rb +0 -9
  93. data/spec/support/acceptance/helpers/step_helpers.rb +0 -127
  94. data/spec/support/acceptance/matchers/have_output.rb +0 -31
  95. data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +0 -55
  96. data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +0 -103
  97. data/spec/support/tests/bundle.rb +0 -94
  98. data/spec/support/tests/command_runner.rb +0 -230
  99. data/spec/support/tests/current_bundle.rb +0 -55
  100. data/spec/support/tests/database.rb +0 -28
  101. data/spec/support/tests/database_adapters/postgresql.rb +0 -25
  102. data/spec/support/tests/database_adapters/sqlite3.rb +0 -26
  103. data/spec/support/tests/database_configuration.rb +0 -33
  104. data/spec/support/tests/database_configuration_registry.rb +0 -28
  105. data/spec/support/tests/filesystem.rb +0 -100
  106. data/spec/support/tests/version.rb +0 -45
  107. data/spec/support/unit/active_record/create_table.rb +0 -54
  108. data/spec/support/unit/attribute.rb +0 -45
  109. data/spec/support/unit/capture.rb +0 -46
  110. data/spec/support/unit/change_value.rb +0 -111
  111. data/spec/support/unit/create_model_arguments/basic.rb +0 -135
  112. data/spec/support/unit/create_model_arguments/has_many.rb +0 -15
  113. data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +0 -74
  114. data/spec/support/unit/helpers/action_pack_versions.rb +0 -22
  115. data/spec/support/unit/helpers/active_model_helpers.rb +0 -27
  116. data/spec/support/unit/helpers/active_model_versions.rb +0 -32
  117. data/spec/support/unit/helpers/active_record_versions.rb +0 -44
  118. data/spec/support/unit/helpers/active_resource_builder.rb +0 -27
  119. data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +0 -15
  120. data/spec/support/unit/helpers/class_builder.rb +0 -90
  121. data/spec/support/unit/helpers/column_type_helpers.rb +0 -26
  122. data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +0 -17
  123. data/spec/support/unit/helpers/controller_builder.rb +0 -63
  124. data/spec/support/unit/helpers/database_helpers.rb +0 -20
  125. data/spec/support/unit/helpers/i18n_faker.rb +0 -15
  126. data/spec/support/unit/helpers/mailer_builder.rb +0 -12
  127. data/spec/support/unit/helpers/message_helpers.rb +0 -19
  128. data/spec/support/unit/helpers/model_builder.rb +0 -114
  129. data/spec/support/unit/helpers/rails_versions.rb +0 -42
  130. data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +0 -44
  131. data/spec/support/unit/i18n.rb +0 -7
  132. data/spec/support/unit/load_environment.rb +0 -12
  133. data/spec/support/unit/matchers/deprecate.rb +0 -60
  134. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +0 -51
  135. data/spec/support/unit/matchers/fail_with_message_matcher.rb +0 -64
  136. data/spec/support/unit/matchers/print_warning_including.rb +0 -67
  137. data/spec/support/unit/model_creation_strategies/active_model.rb +0 -111
  138. data/spec/support/unit/model_creation_strategies/active_record.rb +0 -77
  139. data/spec/support/unit/model_creators.rb +0 -19
  140. data/spec/support/unit/model_creators/active_model.rb +0 -39
  141. data/spec/support/unit/model_creators/active_record.rb +0 -42
  142. data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +0 -95
  143. data/spec/support/unit/model_creators/active_record/has_many.rb +0 -67
  144. data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +0 -42
  145. data/spec/support/unit/model_creators/basic.rb +0 -102
  146. data/spec/support/unit/rails_application.rb +0 -151
  147. data/spec/support/unit/record_builder_with_i18n_validation_message.rb +0 -69
  148. data/spec/support/unit/record_validating_confirmation_builder.rb +0 -54
  149. data/spec/support/unit/record_with_different_error_attribute_builder.rb +0 -92
  150. data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +0 -79
  151. data/spec/support/unit/shared_examples/numerical_submatcher.rb +0 -17
  152. data/spec/support/unit/shared_examples/set_session_or_flash.rb +0 -360
  153. data/spec/support/unit/validation_matcher_scenario.rb +0 -60
  154. data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +0 -82
  155. data/spec/unit/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +0 -28
  156. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +0 -629
  157. data/spec/unit/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +0 -42
  158. data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +0 -76
  159. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +0 -62
  160. data/spec/unit/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +0 -90
  161. data/spec/unit/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +0 -31
  162. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -330
  163. data/spec/unit/shoulda/matchers/action_controller/route_params_spec.rb +0 -30
  164. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +0 -67
  165. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -17
  166. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +0 -562
  167. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -117
  168. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +0 -829
  169. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -86
  170. data/spec/unit/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +0 -20
  171. data/spec/unit/shoulda/matchers/active_model/helpers_spec.rb +0 -162
  172. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +0 -290
  173. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +0 -109
  174. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -172
  175. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -264
  176. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -1049
  177. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -335
  178. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +0 -1865
  179. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -406
  180. data/spec/unit/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -107
  181. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +0 -1672
  182. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +0 -251
  183. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +0 -690
  184. data/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +0 -111
  185. data/spec/unit/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +0 -85
  186. data/spec/unit/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +0 -41
  187. data/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb +0 -169
  188. data/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb +0 -86
  189. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +0 -1682
  190. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +0 -190
  191. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +0 -21
  192. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +0 -271
  193. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +0 -77
  194. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +0 -72
  195. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +0 -101
  196. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +0 -78
  197. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +0 -27
  198. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +0 -43
  199. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -650
  200. data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +0 -406
  201. data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +0 -252
  202. data/spec/unit_spec_helper.rb +0 -54
  203. data/spec/warnings_spy.rb +0 -64
  204. data/spec/warnings_spy/filesystem.rb +0 -45
  205. data/spec/warnings_spy/partitioner.rb +0 -36
  206. data/spec/warnings_spy/reader.rb +0 -53
  207. data/spec/warnings_spy/reporter.rb +0 -88
  208. data/tasks/documentation.rb +0 -199
  209. data/zeus.json +0 -11
@@ -1,60 +0,0 @@
1
- require 'forwardable'
2
-
3
- module UnitTests
4
- class ValidationMatcherScenario
5
- extend Forwardable
6
-
7
- def initialize(arguments)
8
- @arguments = arguments.dup
9
- @matcher_proc = @arguments.delete(:matcher_proc)
10
-
11
- @specified_model_creator = @arguments.delete(:model_creator) do
12
- raise KeyError.new(<<-MESSAGE)
13
- :model_creator is missing. You can either provide it as an option or as
14
- a method.
15
- MESSAGE
16
- end
17
-
18
- @model_creator = model_creator_class.new(@arguments)
19
- end
20
-
21
- def record
22
- @_record ||= model.new.tap do |record|
23
- attribute_default_values_by_name.each do |attribute_name, default_value|
24
- record.public_send("#{attribute_name}=", default_value)
25
- end
26
- end
27
- end
28
-
29
- def model
30
- @_model ||= model_creator.call
31
- end
32
-
33
- def matcher
34
- @_matcher ||= matcher_proc.call(attribute_name)
35
- end
36
-
37
- protected
38
-
39
- attr_reader(
40
- :arguments,
41
- :existing_value,
42
- :matcher_proc,
43
- :model_creator,
44
- :specified_model_creator,
45
- )
46
-
47
- private
48
-
49
- def_delegators(
50
- :model_creator,
51
- :attribute_name,
52
- :attribute_default_values_by_name,
53
- )
54
-
55
- def model_creator_class
56
- UnitTests::ModelCreators.retrieve(specified_model_creator) ||
57
- specified_model_creator
58
- end
59
- end
60
- end
@@ -1,82 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActionController::CallbackMatcher, type: :controller do
4
- shared_examples 'CallbackMatcher' do |kind, callback_type|
5
- let(:kind) { kind }
6
- let(:callback_type) { callback_type }
7
- let(:method_name) { :authenticate_user! }
8
- let(:matcher) { described_class.new(method_name, kind, callback_type) }
9
- let(:controller) { define_controller('HookController').new }
10
-
11
- def match
12
- __send__("use_#{kind}_#{callback_type}", method_name)
13
- end
14
-
15
- it "matches when a #{kind} hook is in place" do
16
- add_callback(kind, callback_type, method_name)
17
-
18
- expect(controller).to match
19
- end
20
-
21
- it "does not match when a #{kind} hook is missing" do
22
- expect(controller).not_to match
23
- end
24
-
25
- describe 'description' do
26
- it 'includes the filter kind and name' do
27
- expect(matcher.description).to eq "have #{method_name.inspect} as a #{kind}_#{callback_type}"
28
- end
29
- end
30
-
31
- describe 'failure message' do
32
- it 'includes the filter kind and name that was expected' do
33
- message = "Expected that HookController would have #{method_name.inspect} as a #{kind}_#{callback_type}"
34
-
35
- expect {
36
- expect(controller).to send("use_#{kind}_#{callback_type}", method_name)
37
- }.to fail_with_message(message)
38
- end
39
- end
40
-
41
- describe 'failure message when negated' do
42
- it 'includes the filter kind and name that was expected' do
43
- add_callback(kind, callback_type, method_name)
44
- message = "Expected that HookController would not have #{method_name.inspect} as a #{kind}_#{callback_type}"
45
-
46
- expect { expect(controller).not_to match }.to fail_with_message(message)
47
- end
48
- end
49
-
50
- private
51
-
52
- def add_callback(kind, callback_type, callback)
53
- controller.class.__send__("#{kind}_#{callback_type}", callback)
54
- end
55
- end
56
-
57
- if action_pack_lt_5?
58
- describe '#use_before_filter' do
59
- it_behaves_like 'CallbackMatcher', :before, :filter
60
- end
61
-
62
- describe '#use_after_filter' do
63
- it_behaves_like 'CallbackMatcher', :after, :filter
64
- end
65
-
66
- describe '#use_around_filter' do
67
- it_behaves_like 'CallbackMatcher', :around, :filter
68
- end
69
- end
70
-
71
- describe '#use_before_action' do
72
- it_behaves_like 'CallbackMatcher', :before, :action
73
- end
74
-
75
- describe '#use_after_action' do
76
- it_behaves_like 'CallbackMatcher', :after, :action
77
- end
78
-
79
- describe '#use_around_action' do
80
- it_behaves_like 'CallbackMatcher', :around, :action
81
- end
82
- end
@@ -1,28 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActionController::FilterParamMatcher, type: :controller do
4
- it 'accepts filtering a filtered parameter' do
5
- filter(:secret)
6
-
7
- expect(nil).to filter_param(:secret)
8
- end
9
-
10
- it 'accepts filtering a parameter matching a filtered regex' do
11
- filter(/(?!tip)pin(?!g)/)
12
-
13
- expect(nil).to filter_param(:pin)
14
- end
15
-
16
- it 'rejects filtering an unfiltered parameter' do
17
- filter(:secret)
18
- matcher = filter_param(:other)
19
-
20
- expect(matcher.matches?(nil)).to eq false
21
-
22
- expect(matcher.failure_message).to match(/Expected other to be filtered.*secret/)
23
- end
24
-
25
- def filter(param)
26
- Rails.application.config.filter_parameters = [param]
27
- end
28
- end
@@ -1,629 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller do
4
- shared_examples 'basic tests' do
5
- it 'accepts a subset of the permitted attributes' do
6
- define_controller_with_strong_parameters(action: :create) do |ctrl|
7
- params_with_conditional_require(ctrl.params).permit(:name, :age)
8
- end
9
-
10
- expect(controller).to permit_with_conditional_slice_of_params(
11
- permit(:name).for(:create)
12
- )
13
- end
14
-
15
- it 'accepts all of the permitted attributes' do
16
- define_controller_with_strong_parameters(action: :create) do |ctrl|
17
- params_with_conditional_require(ctrl.params).permit(:name, :age)
18
- end
19
-
20
- expect(controller).to permit_with_conditional_slice_of_params(
21
- permit(:name, :age).for(:create)
22
- )
23
- end
24
-
25
- it 'rejects attributes that have not been permitted' do
26
- define_controller_with_strong_parameters(action: :create) do |ctrl|
27
- params_with_conditional_require(ctrl.params).permit(:name)
28
- end
29
-
30
- expect(controller).not_to permit_with_conditional_slice_of_params(
31
- permit(:name, :admin).for(:create)
32
- )
33
- end
34
-
35
- it 'rejects when #permit has not been called' do
36
- define_controller_with_strong_parameters(action: :create)
37
-
38
- expect(controller).not_to permit_with_conditional_slice_of_params(
39
- permit(:name).for(:create)
40
- )
41
- end
42
-
43
- it 'tracks multiple calls to #permit for different subparameters' do
44
- sets_of_attributes = [
45
- [:eta, :diner_id],
46
- [:phone_number, :address_1, :address_2, :city, :state, :zip]
47
- ]
48
-
49
- define_controller_with_strong_parameters(action: :create) do |ctrl|
50
- params_with_conditional_require(ctrl.params, :order).
51
- permit(sets_of_attributes[0])
52
-
53
- params_with_conditional_require(ctrl.params, :diner).
54
- permit(sets_of_attributes[1])
55
- end
56
-
57
- expect(controller).to permit_with_conditional_slice_of_params(
58
- permit(*sets_of_attributes[0]).for(:create),
59
- all_params: [:order, :diner],
60
- selected_param: :order
61
- )
62
-
63
- expect(controller).to permit_with_conditional_slice_of_params(
64
- permit(*sets_of_attributes[1]).for(:create),
65
- all_params: [:order, :diner],
66
- selected_param: :diner
67
- )
68
- end
69
- end
70
-
71
- it 'requires an action' do
72
- assertion = -> { expect(controller).to permit(:name) }
73
-
74
- define_controller_with_strong_parameters
75
-
76
- expect(&assertion).to raise_error(described_class::ActionNotDefinedError)
77
- end
78
-
79
- it 'requires a verb for a non-restful action' do
80
- define_controller_with_strong_parameters
81
-
82
- assertion = lambda do
83
- expect(controller).to permit(:name).for(:authorize)
84
- end
85
-
86
- expect(&assertion).to raise_error(described_class::VerbNotDefinedError)
87
- end
88
-
89
- context 'when operating on the entire params hash' do
90
- include_context 'basic tests' do
91
- def permit_with_conditional_slice_of_params(permit, options = {})
92
- permit
93
- end
94
-
95
- def params_with_conditional_require(params, *filters)
96
- params
97
- end
98
- end
99
- end
100
-
101
- context 'when operating on a slice of the params hash' do
102
- include_context 'basic tests' do
103
- def permit_with_conditional_slice_of_params(
104
- permit,
105
- all_params: [:user],
106
- selected_param: :user
107
- )
108
- params = all_params.reduce({}) do |hash, param|
109
- hash.merge(param => { any: 'value' })
110
- end
111
-
112
- permit.add_params(params).on(selected_param)
113
- end
114
-
115
- def params_with_conditional_require(params, *filters)
116
- if filters.none?
117
- filters = [:user]
118
- end
119
-
120
- params.require(*filters)
121
- end
122
- end
123
-
124
- it 'rejects if asserting that parameters were not permitted, but on the wrong slice' do
125
- define_controller_with_strong_parameters(action: :create) do
126
- params.require(:order).permit(:eta, :diner_id)
127
- end
128
-
129
- expect(controller).
130
- not_to permit(:eta, :diner_id).
131
- for(:create, params: { order: { some: 'value' } }).
132
- on(:something_else)
133
- end
134
-
135
- it 'tracks multiple calls to #permit for the same subparameter' do
136
- define_controller_with_strong_parameters(action: :create) do
137
- params.require(:foo).permit(:bar)
138
- params.require(:foo).permit(:baz)
139
- end
140
-
141
- params = {
142
- foo: {
143
- bar: 'some value',
144
- baz: 'some value'
145
- }
146
- }
147
- expect(controller).
148
- to permit(:bar).
149
- on(:foo).
150
- for(:create, params: params)
151
- expect(controller).
152
- to permit(:baz).
153
- on(:foo).
154
- for(:create, params: params)
155
- end
156
- end
157
-
158
- it 'can be used more than once in the same test' do
159
- define_controller_with_strong_parameters(action: :create) do
160
- params.permit(:name)
161
- end
162
-
163
- expect(controller).to permit(:name).for(:create)
164
- expect(controller).not_to permit(:admin).for(:create)
165
- end
166
-
167
- it 'allows extra parameters to be provided if the route requires them' do
168
- options = {
169
- controller_name: 'Posts',
170
- action: :show,
171
- routes: -> { get '/posts/:slug', to: 'posts#show' }
172
- }
173
-
174
- define_controller_with_strong_parameters(options) do
175
- params.permit(:name)
176
- end
177
-
178
- expect(controller).
179
- to permit(:name).
180
- for(:show, verb: :get, params: { slug: 'foo' })
181
- end
182
-
183
- it 'works with #update specifically' do
184
- define_controller_with_strong_parameters(action: :update) do
185
- params.permit(:name)
186
- end
187
-
188
- expect(controller).
189
- to permit(:name).
190
- for(:update, params: { id: 1 })
191
- end
192
-
193
- it 'works when multiple ActionController::Parameters were instantiated' do
194
- define_controller_with_strong_parameters(action: :create) do
195
- params.permit(:name)
196
- params.dup
197
- end
198
-
199
- expect(controller).to permit(:name).for(:create)
200
- end
201
-
202
- describe '#matches?' do
203
- it 'does not raise an error when #fetch was used instead of #require (issue #495)' do
204
- matcher = permit(:eta, :diner_id).for(:create)
205
- matching = -> { matcher.matches?(controller) }
206
-
207
- define_controller_with_strong_parameters(action: :create) do
208
- params.fetch(:order, {}).permit(:eta, :diner_id)
209
- end
210
-
211
- expect(&matching).not_to raise_error
212
- end
213
-
214
- context 'stubbing params on the controller' do
215
- it 'still allows the original params hash to be modified and accessed prior to the call to #require' do
216
- actual_user_params = nil
217
- actual_foo_param = nil
218
- matcher = permit(:name).for(
219
- :create,
220
- params: { user: { some: 'params' } }
221
- )
222
-
223
- define_controller_with_strong_parameters(action: :create) do
224
- params[:foo] = 'bar'
225
- actual_foo_param = params[:foo]
226
- actual_user_params = params[:user]
227
-
228
- params.permit(:name)
229
- end
230
-
231
- matcher.matches?(controller)
232
-
233
- expect(actual_user_params).to eq('some' => 'params')
234
- expect(actual_foo_param).to eq 'bar'
235
- end
236
-
237
- it 'still allows #require to return a slice of the params' do
238
- expected_user_params = { 'foo' => 'bar' }
239
- actual_user_params = nil
240
- matcher = permit(:name).for(
241
- :update,
242
- params: { id: 1, user: expected_user_params }
243
- )
244
-
245
- define_controller_with_strong_parameters(action: :update) do
246
- actual_user_params = params.require(:user)
247
- begin
248
- actual_user_params.permit(:name)
249
- rescue
250
- end
251
- end
252
-
253
- matcher.matches?(controller)
254
-
255
- expect(actual_user_params).to eq expected_user_params
256
- end
257
-
258
- it 'does not permanently stub the params hash' do
259
- matcher = permit(:name).for(:create)
260
- params_access = -> { controller.params.require(:user) }
261
-
262
- define_controller_with_strong_parameters(action: :create)
263
-
264
- matcher.matches?(controller)
265
-
266
- expect(&params_access).
267
- to raise_error(::ActionController::ParameterMissing)
268
- end
269
-
270
- it 'prevents permanently stubbing params on error' do
271
- matcher = permit(:name).for(:create)
272
- params_access = -> { controller.params.require(:user) }
273
-
274
- define_controller_raising_exception
275
-
276
- begin
277
- matcher.matches?(controller)
278
- rescue simulated_error_class
279
- end
280
-
281
- expect(&params_access).
282
- to raise_error(::ActionController::ParameterMissing)
283
- end
284
- end
285
- end
286
-
287
- describe '#description' do
288
- it 'returns the correct string' do
289
- options = { action: :create, method: :post }
290
-
291
- define_controller_with_strong_parameters(options) do
292
- params.permit(:name, :age)
293
- end
294
-
295
- matcher = described_class.new([:name, :age, :height]).for(:create)
296
- expect(matcher.description).to eq(
297
- '(for POST #create) restrict parameters to :name, :age, and :height'
298
- )
299
- end
300
-
301
- context 'when a verb is specified' do
302
- it 'returns the correct string' do
303
- options = { action: :some_action }
304
-
305
- define_controller_with_strong_parameters(options) do
306
- params.permit(:name, :age)
307
- end
308
-
309
- matcher = described_class.
310
- new([:name]).
311
- for(:some_action, verb: :put)
312
- expect(matcher.description).to eq(
313
- '(for PUT #some_action) restrict parameters to :name'
314
- )
315
- end
316
- end
317
- end
318
-
319
- describe 'positive failure message' do
320
- context 'when no parameters were permitted' do
321
- it 'returns the correct message' do
322
- define_controller_with_strong_parameters(action: :create)
323
-
324
- assertion = lambda do
325
- expect(@controller).
326
- to permit(:name, :age, :city, :country).
327
- for(:create)
328
- end
329
-
330
- message =
331
- 'Expected POST #create to restrict parameters to ' +
332
- ":name, :age, :city, and :country,\n" +
333
- 'but it did not restrict any parameters.'
334
-
335
- expect(&assertion).to fail_with_message(message)
336
- end
337
- end
338
-
339
- context 'when some, but not all, parameters were permitted' do
340
- it 'returns the correct message, including missing attributes' do
341
- define_controller_with_strong_parameters(action: :create) do
342
- params.permit(:name, :age)
343
- end
344
-
345
- assertion = lambda do
346
- expect(@controller).
347
- to permit(:name, :age, :city, :country).
348
- for(:create)
349
- end
350
-
351
- message =
352
- 'Expected POST #create to restrict parameters to ' +
353
- ":name, :age, :city, and :country,\n" +
354
- 'but the restricted parameters were :name and :age instead.'
355
-
356
- expect(&assertion).to fail_with_message(message)
357
- end
358
- end
359
-
360
- context 'qualified with #on' do
361
- context 'when the subparameter was never required' do
362
- it 'returns the correct message' do
363
- define_controller_with_strong_parameters(action: :create) do
364
- params.permit(:name, :age)
365
- end
366
-
367
- assertion = lambda do
368
- expect(@controller).
369
- to permit(:name, :age, :city, :country).
370
- for(:create).
371
- on(:person)
372
- end
373
-
374
- message =
375
- 'Expected POST #create to restrict parameters on :person to ' +
376
- ":name, :age, :city, and :country,\n" +
377
- 'but it did not restrict any parameters.'
378
-
379
- expect(&assertion).to fail_with_message(message)
380
- end
381
- end
382
-
383
- context 'when the subparameter was required' do
384
- context 'but no parameters were permitted' do
385
- it 'returns the correct message' do
386
- define_controller_with_strong_parameters(action: :create) do
387
- params.require(:person)
388
- end
389
-
390
- assertion = lambda do
391
- params = {
392
- person: {
393
- name: 'some name',
394
- age: 'some age'
395
- }
396
- }
397
- expect(@controller).
398
- to permit(:name, :age, :city, :country).
399
- for(:create, params: params).
400
- on(:person)
401
- end
402
-
403
- message =
404
- 'Expected POST #create to restrict parameters on :person to ' +
405
- ":name, :age, :city, and :country,\n" +
406
- 'but it did not restrict any parameters.'
407
-
408
- expect(&assertion).to fail_with_message(message)
409
- end
410
- end
411
-
412
- context 'but some, but not all, parameters were permitted' do
413
- it 'returns the correct message' do
414
- define_controller_with_strong_parameters(action: :create) do
415
- params.require(:person).permit(:name, :age)
416
- end
417
-
418
- assertion = lambda do
419
- params = {
420
- person: {
421
- name: 'some name',
422
- age: 'some age'
423
- }
424
- }
425
- expect(@controller).
426
- to permit(:name, :age, :city, :country).
427
- for(:create, params: params).
428
- on(:person)
429
- end
430
-
431
- message =
432
- 'Expected POST #create to restrict parameters on :person to ' +
433
- ":name, :age, :city, and :country,\n" +
434
- 'but the restricted parameters were :name and :age instead.'
435
-
436
- expect(&assertion).to fail_with_message(message)
437
- end
438
- end
439
- end
440
- end
441
- end
442
-
443
- describe 'negative failure message' do
444
- it 'returns the correct message' do
445
- define_controller_with_strong_parameters(action: :create) do
446
- params.permit(:name, :age, :city, :country)
447
- end
448
-
449
- assertion = lambda do
450
- expect(@controller).
451
- not_to permit(:name, :age, :city, :country).
452
- for(:create)
453
- end
454
-
455
- message =
456
- 'Expected POST #create not to restrict parameters to ' +
457
- ":name, :age, :city, and :country,\n" +
458
- 'but it did.'
459
-
460
- expect(&assertion).to fail_with_message(message)
461
- end
462
-
463
- context 'qualified with #on' do
464
- it 'returns the correct message' do
465
- define_controller_with_strong_parameters(action: :create) do
466
- params.require(:person).permit(:name, :age)
467
- end
468
-
469
- assertion = lambda do
470
- params = {
471
- person: {
472
- name: 'some name',
473
- age: 'some age'
474
- }
475
- }
476
- expect(@controller).
477
- not_to permit(:name, :age).
478
- for(:create, params: params).
479
- on(:person)
480
- end
481
-
482
- message =
483
- 'Expected POST #create not to restrict parameters on :person to ' +
484
- ":name and :age,\n" +
485
- 'but it did.'
486
-
487
- expect(&assertion).to fail_with_message(message)
488
- end
489
- end
490
- end
491
-
492
- describe '#for' do
493
- context 'when given :create' do
494
- it 'POSTs to the controller' do
495
- controller = ActionController::Base.new
496
- context = build_context
497
- matcher = permit(:name).for(:create).in_context(context)
498
-
499
- matcher.matches?(controller)
500
-
501
- expect_to_have_made_controller_request(
502
- verb: :post,
503
- action: :create,
504
- params: {},
505
- context: context,
506
- )
507
- end
508
- end
509
-
510
- context 'when given :update' do
511
- if rails_gte_4_1?
512
- it 'PATCHes to the controller' do
513
- controller = ActionController::Base.new
514
- context = build_context
515
- matcher = permit(:name).for(:update).in_context(context)
516
-
517
- matcher.matches?(controller)
518
-
519
- expect_to_have_made_controller_request(
520
- verb: :patch,
521
- action: :update,
522
- params: {},
523
- context: context,
524
- )
525
- end
526
- else
527
- it 'PUTs to the controller' do
528
- controller = ActionController::Base.new
529
- context = build_context
530
- matcher = permit(:name).for(:update).in_context(context)
531
-
532
- matcher.matches?(controller)
533
-
534
- expect_to_have_made_controller_request(
535
- verb: :put,
536
- action: :update,
537
- params: {},
538
- context: context,
539
- )
540
- end
541
- end
542
- end
543
-
544
- context 'when given a custom action and verb' do
545
- it 'calls the action with the verb' do
546
- controller = ActionController::Base.new
547
- context = build_context
548
- matcher = permit(:name).
549
- for(:hide, verb: :delete).
550
- in_context(context)
551
-
552
- matcher.matches?(controller)
553
-
554
- expect_to_have_made_controller_request(
555
- verb: :delete,
556
- action: :hide,
557
- params: {},
558
- context: context,
559
- )
560
- end
561
- end
562
- end
563
-
564
- let(:simulated_error_class) do
565
- Class.new(StandardError)
566
- end
567
-
568
- def define_controller_with_strong_parameters(options = {}, &action_body)
569
- model_name = options.fetch(:model_name, 'User')
570
- controller_name = options.fetch(:controller_name, 'UsersController')
571
- collection_name = controller_name.
572
- to_s.sub(/Controller$/, '').underscore.
573
- to_sym
574
- action_name = options.fetch(:action, :some_action)
575
- routes = options.fetch(:routes, -> { resources collection_name })
576
-
577
- define_model(model_name)
578
-
579
- controller_class = define_controller(controller_name) do
580
- define_method action_name do
581
- if action_body
582
- if action_body.arity == 0
583
- instance_eval(&action_body)
584
- else
585
- action_body.call(self)
586
- end
587
- end
588
-
589
- head :ok
590
- end
591
- end
592
-
593
- setup_rails_controller_test(controller_class)
594
-
595
- define_routes(&routes)
596
-
597
- controller_class
598
- end
599
-
600
- def define_controller_raising_exception
601
- _simulated_error_class = simulated_error_class
602
-
603
- controller_class = define_controller('Examples') do
604
- define_method :create do
605
- raise _simulated_error_class
606
- end
607
- end
608
-
609
- setup_rails_controller_test(controller_class)
610
-
611
- define_routes do
612
- get 'examples', to: 'examples#create'
613
- end
614
-
615
- controller_class
616
- end
617
-
618
- def build_context
619
- double('context', post: nil, put: nil, patch: nil, delete: nil)
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
629
- end