actionpack 7.0.8.1 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -500
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +119 -106
  7. data/lib/abstract_controller/caching/fragments.rb +51 -52
  8. data/lib/abstract_controller/caching.rb +2 -0
  9. data/lib/abstract_controller/callbacks.rb +94 -67
  10. data/lib/abstract_controller/collector.rb +6 -6
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +2 -0
  13. data/lib/abstract_controller/helpers.rb +121 -91
  14. data/lib/abstract_controller/logger.rb +2 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
  16. data/lib/abstract_controller/rendering.rb +14 -13
  17. data/lib/abstract_controller/translation.rb +12 -30
  18. data/lib/abstract_controller/url_for.rb +9 -5
  19. data/lib/abstract_controller.rb +8 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/api.rb +78 -73
  22. data/lib/action_controller/base.rb +199 -141
  23. data/lib/action_controller/caching.rb +16 -11
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +21 -16
  26. data/lib/action_controller/log_subscriber.rb +19 -5
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  29. data/lib/action_controller/metal/conditional_get.rb +187 -174
  30. data/lib/action_controller/metal/content_security_policy.rb +26 -25
  31. data/lib/action_controller/metal/cookies.rb +4 -2
  32. data/lib/action_controller/metal/data_streaming.rb +65 -54
  33. data/lib/action_controller/metal/default_headers.rb +6 -2
  34. data/lib/action_controller/metal/etag_with_flash.rb +4 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
  36. data/lib/action_controller/metal/exceptions.rb +19 -9
  37. data/lib/action_controller/metal/flash.rb +12 -10
  38. data/lib/action_controller/metal/head.rb +20 -16
  39. data/lib/action_controller/metal/helpers.rb +64 -67
  40. data/lib/action_controller/metal/http_authentication.rb +214 -200
  41. data/lib/action_controller/metal/implicit_render.rb +21 -17
  42. data/lib/action_controller/metal/instrumentation.rb +22 -12
  43. data/lib/action_controller/metal/live.rb +125 -92
  44. data/lib/action_controller/metal/logging.rb +6 -4
  45. data/lib/action_controller/metal/mime_responds.rb +151 -142
  46. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  47. data/lib/action_controller/metal/params_wrapper.rb +58 -58
  48. data/lib/action_controller/metal/permissions_policy.rb +14 -13
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +110 -84
  51. data/lib/action_controller/metal/renderers.rb +50 -49
  52. data/lib/action_controller/metal/rendering.rb +103 -82
  53. data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
  54. data/lib/action_controller/metal/rescue.rb +12 -8
  55. data/lib/action_controller/metal/streaming.rb +174 -132
  56. data/lib/action_controller/metal/strong_parameters.rb +598 -473
  57. data/lib/action_controller/metal/testing.rb +2 -0
  58. data/lib/action_controller/metal/url_for.rb +23 -14
  59. data/lib/action_controller/metal.rb +145 -61
  60. data/lib/action_controller/railtie.rb +25 -9
  61. data/lib/action_controller/railties/helpers.rb +2 -0
  62. data/lib/action_controller/renderer.rb +105 -66
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +157 -128
  65. data/lib/action_controller.rb +17 -3
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +28 -29
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +69 -49
  71. data/lib/action_dispatch/http/filter_parameters.rb +27 -12
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +23 -21
  74. data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
  75. data/lib/action_dispatch/http/mime_type.rb +60 -30
  76. data/lib/action_dispatch/http/mime_types.rb +5 -1
  77. data/lib/action_dispatch/http/parameters.rb +12 -10
  78. data/lib/action_dispatch/http/permissions_policy.rb +32 -34
  79. data/lib/action_dispatch/http/rack_cache.rb +4 -0
  80. data/lib/action_dispatch/http/request.rb +132 -79
  81. data/lib/action_dispatch/http/response.rb +136 -103
  82. data/lib/action_dispatch/http/upload.rb +19 -15
  83. data/lib/action_dispatch/http/url.rb +75 -73
  84. data/lib/action_dispatch/journey/formatter.rb +19 -6
  85. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  88. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  90. data/lib/action_dispatch/journey/parser.rb +4 -3
  91. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  92. data/lib/action_dispatch/journey/path/pattern.rb +18 -15
  93. data/lib/action_dispatch/journey/route.rb +12 -9
  94. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  95. data/lib/action_dispatch/journey/router.rb +13 -10
  96. data/lib/action_dispatch/journey/routes.rb +6 -4
  97. data/lib/action_dispatch/journey/scanner.rb +4 -2
  98. data/lib/action_dispatch/journey/visitors.rb +2 -0
  99. data/lib/action_dispatch/journey.rb +2 -0
  100. data/lib/action_dispatch/log_subscriber.rb +25 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
  102. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  103. data/lib/action_dispatch/middleware/callbacks.rb +4 -0
  104. data/lib/action_dispatch/middleware/cookies.rb +192 -194
  105. data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
  106. data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
  107. data/lib/action_dispatch/middleware/debug_view.rb +9 -2
  108. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
  109. data/lib/action_dispatch/middleware/executor.rb +9 -1
  110. data/lib/action_dispatch/middleware/flash.rb +65 -46
  111. data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
  112. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
  113. data/lib/action_dispatch/middleware/reloader.rb +9 -5
  114. data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
  115. data/lib/action_dispatch/middleware/request_id.rb +15 -8
  116. data/lib/action_dispatch/middleware/server_timing.rb +8 -6
  117. data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
  118. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
  119. data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
  120. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
  121. data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
  122. data/lib/action_dispatch/middleware/ssl.rb +60 -45
  123. data/lib/action_dispatch/middleware/stack.rb +15 -9
  124. data/lib/action_dispatch/middleware/static.rb +40 -34
  125. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  126. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  130. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
  139. data/lib/action_dispatch/railtie.rb +12 -4
  140. data/lib/action_dispatch/request/session.rb +39 -27
  141. data/lib/action_dispatch/request/utils.rb +10 -3
  142. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  143. data/lib/action_dispatch/routing/inspector.rb +59 -9
  144. data/lib/action_dispatch/routing/mapper.rb +686 -639
  145. data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
  146. data/lib/action_dispatch/routing/redirection.rb +52 -38
  147. data/lib/action_dispatch/routing/route_set.rb +106 -62
  148. data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
  149. data/lib/action_dispatch/routing/url_for.rb +131 -122
  150. data/lib/action_dispatch/routing.rb +152 -150
  151. data/lib/action_dispatch/system_test_case.rb +91 -81
  152. data/lib/action_dispatch/system_testing/browser.rb +27 -19
  153. data/lib/action_dispatch/system_testing/driver.rb +16 -22
  154. data/lib/action_dispatch/system_testing/server.rb +2 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  158. data/lib/action_dispatch/testing/assertions/response.rb +36 -26
  159. data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
  160. data/lib/action_dispatch/testing/assertions.rb +5 -1
  161. data/lib/action_dispatch/testing/integration.rb +240 -229
  162. data/lib/action_dispatch/testing/request_encoder.rb +6 -1
  163. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  164. data/lib/action_dispatch/testing/test_process.rb +14 -9
  165. data/lib/action_dispatch/testing/test_request.rb +4 -2
  166. data/lib/action_dispatch/testing/test_response.rb +34 -19
  167. data/lib/action_dispatch.rb +52 -21
  168. data/lib/action_pack/gem_version.rb +5 -3
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +91 -32
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "rack/session/abstract/id"
4
6
  require "active_support/core_ext/hash/conversions"
5
7
  require "active_support/core_ext/object/to_query"
@@ -16,10 +18,10 @@ module ActionController
16
18
  end
17
19
 
18
20
  module Live
19
- # Disable controller / rendering threads in tests. User tests can access
20
- # the database on the main thread, so they could open a txn, then the
21
- # controller thread will open a new connection and try to access data
22
- # that's only visible to the main thread's txn. This is the problem in #23483.
21
+ # Disable controller / rendering threads in tests. User tests can access the
22
+ # database on the main thread, so they could open a txn, then the controller
23
+ # thread will open a new connection and try to access data that's only visible
24
+ # to the main thread's txn. This is the problem in #23483.
23
25
  silence_redefinition_of_method :new_controller_thread
24
26
  def new_controller_thread # :nodoc:
25
27
  yield
@@ -29,8 +31,8 @@ module ActionController
29
31
  Buffer.queue_size = nil
30
32
  end
31
33
 
32
- # ActionController::TestCase will be deprecated and moved to a gem in the future.
33
- # Please use ActionDispatch::IntegrationTest going forward.
34
+ # ActionController::TestCase will be deprecated and moved to a gem in the
35
+ # future. Please use ActionDispatch::IntegrationTest going forward.
34
36
  class TestRequest < ActionDispatch::TestRequest # :nodoc:
35
37
  DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
36
38
  DEFAULT_ENV.delete "PATH_INFO"
@@ -127,6 +129,9 @@ module ActionController
127
129
  fetch_header("PATH_INFO") do |k|
128
130
  set_header k, generated_path
129
131
  end
132
+ fetch_header("ORIGINAL_FULLPATH") do |k|
133
+ set_header k, fullpath
134
+ end
130
135
  path_parameters[:controller] = controller_path
131
136
  path_parameters[:action] = action
132
137
 
@@ -182,11 +187,12 @@ module ActionController
182
187
  class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash # :nodoc:
183
188
  DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
184
189
 
185
- def initialize(session = {})
190
+ def initialize(session = {}, id = Rack::Session::SessionId.new(SecureRandom.hex(16)))
186
191
  super(nil, nil)
187
- @id = Rack::Session::SessionId.new(SecureRandom.hex(16))
192
+ @id = id
188
193
  @data = stringify_keys(session)
189
194
  @loaded = true
195
+ @initially_empty = @data.empty?
190
196
  end
191
197
 
192
198
  def exists?
@@ -218,120 +224,137 @@ module ActionController
218
224
  true
219
225
  end
220
226
 
227
+ def id_was
228
+ @id
229
+ end
230
+
221
231
  private
222
232
  def load!
223
233
  @id
224
234
  end
225
235
  end
226
236
 
227
- # Superclass for ActionController functional tests. Functional tests allow you to
228
- # test a single controller action per test method.
237
+ # # Action Controller Test Case
229
238
  #
230
- # == Use integration style controller tests over functional style controller tests.
239
+ # Superclass for ActionController functional tests. Functional tests allow you
240
+ # to test a single controller action per test method.
241
+ #
242
+ # ## Use integration style controller tests over functional style controller tests.
231
243
  #
232
244
  # Rails discourages the use of functional tests in favor of integration tests
233
245
  # (use ActionDispatch::IntegrationTest).
234
246
  #
235
- # New Rails applications no longer generate functional style controller tests and they should
236
- # only be used for backward compatibility. Integration style controller tests perform actual
237
- # requests, whereas functional style controller tests merely simulate a request. Besides,
238
- # integration tests are as fast as functional tests and provide lot of helpers such as +as+,
239
- # +parsed_body+ for effective testing of controller actions including even API endpoints.
247
+ # New Rails applications no longer generate functional style controller tests
248
+ # and they should only be used for backward compatibility. Integration style
249
+ # controller tests perform actual requests, whereas functional style controller
250
+ # tests merely simulate a request. Besides, integration tests are as fast as
251
+ # functional tests and provide lot of helpers such as `as`, `parsed_body` for
252
+ # effective testing of controller actions including even API endpoints.
240
253
  #
241
- # == Basic example
254
+ # ## Basic example
242
255
  #
243
256
  # Functional tests are written as follows:
244
- # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+, or +head+ method to simulate
245
- # an HTTP request.
246
- # 2. Then, one asserts whether the current state is as expected. "State" can be anything:
247
- # the controller's HTTP response, the database contents, etc.
257
+ # 1. First, one uses the `get`, `post`, `patch`, `put`, `delete`, or `head`
258
+ # method to simulate an HTTP request.
259
+ # 2. Then, one asserts whether the current state is as expected. "State" can be
260
+ # anything: the controller's HTTP response, the database contents, etc.
261
+ #
248
262
  #
249
263
  # For example:
250
264
  #
251
- # class BooksControllerTest < ActionController::TestCase
252
- # def test_create
253
- # # Simulate a POST response with the given HTTP parameters.
254
- # post(:create, params: { book: { title: "Love Hina" }})
265
+ # class BooksControllerTest < ActionController::TestCase
266
+ # def test_create
267
+ # # Simulate a POST response with the given HTTP parameters.
268
+ # post(:create, params: { book: { title: "Love Hina" }})
255
269
  #
256
- # # Asserts that the controller tried to redirect us to
257
- # # the created book's URI.
258
- # assert_response :found
270
+ # # Asserts that the controller tried to redirect us to
271
+ # # the created book's URI.
272
+ # assert_response :found
259
273
  #
260
- # # Asserts that the controller really put the book in the database.
261
- # assert_not_nil Book.find_by(title: "Love Hina")
274
+ # # Asserts that the controller really put the book in the database.
275
+ # assert_not_nil Book.find_by(title: "Love Hina")
276
+ # end
262
277
  # end
263
- # end
264
278
  #
265
279
  # You can also send a real document in the simulated HTTP request.
266
280
  #
267
- # def test_create
268
- # json = {book: { title: "Love Hina" }}.to_json
269
- # post :create, body: json
270
- # end
281
+ # def test_create
282
+ # json = {book: { title: "Love Hina" }}.to_json
283
+ # post :create, body: json
284
+ # end
285
+ #
286
+ # ## Special instance variables
287
+ #
288
+ # ActionController::TestCase will also automatically provide the following
289
+ # instance variables for use in the tests:
290
+ #
291
+ # @controller
292
+ # : The controller instance that will be tested.
271
293
  #
272
- # == Special instance variables
294
+ # @request
295
+ # : An ActionController::TestRequest, representing the current HTTP request.
296
+ # You can modify this object before sending the HTTP request. For example,
297
+ # you might want to set some session properties before sending a GET
298
+ # request.
273
299
  #
274
- # ActionController::TestCase will also automatically provide the following instance
275
- # variables for use in the tests:
300
+ # @response
301
+ # : An ActionDispatch::TestResponse object, representing the response of the
302
+ # last HTTP response. In the above example, `@response` becomes valid after
303
+ # calling `post`. If the various assert methods are not sufficient, then you
304
+ # may use this object to inspect the HTTP response in detail.
276
305
  #
277
- # <b>@controller</b>::
278
- # The controller instance that will be tested.
279
- # <b>@request</b>::
280
- # An ActionController::TestRequest, representing the current HTTP
281
- # request. You can modify this object before sending the HTTP request. For example,
282
- # you might want to set some session properties before sending a GET request.
283
- # <b>@response</b>::
284
- # An ActionDispatch::TestResponse object, representing the response
285
- # of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
286
- # after calling +post+. If the various assert methods are not sufficient, then you
287
- # may use this object to inspect the HTTP response in detail.
288
306
  #
289
- # == Controller is automatically inferred
307
+ # ## Controller is automatically inferred
290
308
  #
291
309
  # ActionController::TestCase will automatically infer the controller under test
292
310
  # from the test class name. If the controller cannot be inferred from the test
293
- # class name, you can explicitly set it with +tests+.
311
+ # class name, you can explicitly set it with `tests`.
294
312
  #
295
- # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
296
- # tests WidgetController
297
- # end
313
+ # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
314
+ # tests WidgetController
315
+ # end
316
+ #
317
+ # ## Testing controller internals
298
318
  #
299
- # == \Testing controller internals
319
+ # In addition to these specific assertions, you also have easy access to various
320
+ # collections that the regular test/unit assertions can be used against. These
321
+ # collections are:
300
322
  #
301
- # In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions
302
- # can be used against. These collections are:
323
+ # * session: Objects being saved in the session.
324
+ # * flash: The flash objects currently in the session.
325
+ # * cookies: Cookies being sent to the user on this request.
303
326
  #
304
- # * session: Objects being saved in the session.
305
- # * flash: The flash objects currently in the session.
306
- # * cookies: \Cookies being sent to the user on this request.
307
327
  #
308
328
  # These collections can be used just like any other hash:
309
329
  #
310
- # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
311
- # assert flash.empty? # makes sure that there's nothing in the flash
330
+ # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
331
+ # assert flash.empty? # makes sure that there's nothing in the flash
312
332
  #
313
- # On top of the collections, you have the complete URL that a given action redirected to available in <tt>redirect_to_url</tt>.
333
+ # On top of the collections, you have the complete URL that a given action
334
+ # redirected to available in `redirect_to_url`.
314
335
  #
315
- # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another
316
- # action call which can then be asserted against.
336
+ # For redirects within the same controller, you can even call follow_redirect
337
+ # and the redirect will be followed, triggering another action call which can
338
+ # then be asserted against.
317
339
  #
318
- # == Manipulating session and cookie variables
340
+ # ## Manipulating session and cookie variables
319
341
  #
320
- # Sometimes you need to set up the session and cookie variables for a test.
321
- # To do this just assign a value to the session or cookie collection:
342
+ # Sometimes you need to set up the session and cookie variables for a test. To
343
+ # do this just assign a value to the session or cookie collection:
322
344
  #
323
- # session[:key] = "value"
324
- # cookies[:key] = "value"
345
+ # session[:key] = "value"
346
+ # cookies[:key] = "value"
325
347
  #
326
348
  # To clear the cookies for a test just clear the cookie collection:
327
349
  #
328
- # cookies.clear
350
+ # cookies.clear
329
351
  #
330
- # == \Testing named routes
352
+ # ## Testing named routes
331
353
  #
332
- # If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
354
+ # If you're using named routes, they can be easily tested using the original
355
+ # named routes' methods straight in the test case.
333
356
  #
334
- # assert_redirected_to page_url(title: 'foo')
357
+ # assert_redirected_to page_url(title: 'foo')
335
358
  class TestCase < ActiveSupport::TestCase
336
359
  singleton_class.attr_accessor :executor_around_each_request
337
360
 
@@ -344,12 +367,12 @@ module ActionController
344
367
  attr_reader :response, :request
345
368
 
346
369
  module ClassMethods
347
- # Sets the controller class name. Useful if the name can't be inferred from test class.
348
- # Normalizes +controller_class+ before using.
370
+ # Sets the controller class name. Useful if the name can't be inferred from test
371
+ # class. Normalizes `controller_class` before using.
349
372
  #
350
- # tests WidgetController
351
- # tests :widget
352
- # tests 'widget'
373
+ # tests WidgetController
374
+ # tests :widget
375
+ # tests 'widget'
353
376
  def tests(controller_class)
354
377
  case controller_class
355
378
  when String, Symbol
@@ -382,88 +405,93 @@ module ActionController
382
405
 
383
406
  # Simulate a GET request with the given parameters.
384
407
  #
385
- # - +action+: The controller action to call.
386
- # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
387
- # - +body+: The request body with a string that is appropriately encoded
388
- # (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
389
- # - +session+: A hash of parameters to store in the session. This may be +nil+.
390
- # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
408
+ # * `action`: The controller action to call.
409
+ # * `params`: The hash with HTTP parameters that you want to pass. This may be
410
+ # `nil`.
411
+ # * `body`: The request body with a string that is appropriately encoded
412
+ # (`application/x-www-form-urlencoded` or `multipart/form-data`).
413
+ # * `session`: A hash of parameters to store in the session. This may be
414
+ # `nil`.
415
+ # * `flash`: A hash of parameters to store in the flash. This may be `nil`.
391
416
  #
392
- # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
393
- # +post+, +patch+, +put+, +delete+, and +head+.
394
- # Example sending parameters, session, and setting a flash message:
395
417
  #
396
- # get :show,
397
- # params: { id: 7 },
398
- # session: { user_id: 1 },
399
- # flash: { notice: 'This is flash message' }
418
+ # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with `post`,
419
+ # `patch`, `put`, `delete`, and `head`. Example sending parameters, session, and
420
+ # setting a flash message:
421
+ #
422
+ # get :show,
423
+ # params: { id: 7 },
424
+ # session: { user_id: 1 },
425
+ # flash: { notice: 'This is flash message' }
400
426
  #
401
427
  # Note that the request method is not verified. The different methods are
402
428
  # available to make the tests more expressive.
403
429
  def get(action, **args)
404
- res = process(action, method: "GET", **args)
405
- cookies.update res.cookies
406
- res
430
+ process(action, method: "GET", **args)
407
431
  end
408
432
 
409
433
  # Simulate a POST request with the given parameters and set/volley the response.
410
- # See +get+ for more details.
434
+ # See `get` for more details.
411
435
  def post(action, **args)
412
436
  process(action, method: "POST", **args)
413
437
  end
414
438
 
415
- # Simulate a PATCH request with the given parameters and set/volley the response.
416
- # See +get+ for more details.
439
+ # Simulate a PATCH request with the given parameters and set/volley the
440
+ # response. See `get` for more details.
417
441
  def patch(action, **args)
418
442
  process(action, method: "PATCH", **args)
419
443
  end
420
444
 
421
445
  # Simulate a PUT request with the given parameters and set/volley the response.
422
- # See +get+ for more details.
446
+ # See `get` for more details.
423
447
  def put(action, **args)
424
448
  process(action, method: "PUT", **args)
425
449
  end
426
450
 
427
- # Simulate a DELETE request with the given parameters and set/volley the response.
428
- # See +get+ for more details.
451
+ # Simulate a DELETE request with the given parameters and set/volley the
452
+ # response. See `get` for more details.
429
453
  def delete(action, **args)
430
454
  process(action, method: "DELETE", **args)
431
455
  end
432
456
 
433
457
  # Simulate a HEAD request with the given parameters and set/volley the response.
434
- # See +get+ for more details.
458
+ # See `get` for more details.
435
459
  def head(action, **args)
436
460
  process(action, method: "HEAD", **args)
437
461
  end
438
462
 
439
- # Simulate an HTTP request to +action+ by specifying request method,
440
- # parameters and set/volley the response.
463
+ # Simulate an HTTP request to `action` by specifying request method, parameters
464
+ # and set/volley the response.
465
+ #
466
+ # * `action`: The controller action to call.
467
+ # * `method`: Request method used to send the HTTP request. Possible values
468
+ # are `GET`, `POST`, `PATCH`, `PUT`, `DELETE`, `HEAD`. Defaults to `GET`.
469
+ # Can be a symbol.
470
+ # * `params`: The hash with HTTP parameters that you want to pass. This may be
471
+ # `nil`.
472
+ # * `body`: The request body with a string that is appropriately encoded
473
+ # (`application/x-www-form-urlencoded` or `multipart/form-data`).
474
+ # * `session`: A hash of parameters to store in the session. This may be
475
+ # `nil`.
476
+ # * `flash`: A hash of parameters to store in the flash. This may be `nil`.
477
+ # * `format`: Request format. Defaults to `nil`. Can be string or symbol.
478
+ # * `as`: Content type. Defaults to `nil`. Must be a symbol that corresponds
479
+ # to a mime type.
441
480
  #
442
- # - +action+: The controller action to call.
443
- # - +method+: Request method used to send the HTTP request. Possible values
444
- # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. Can be a symbol.
445
- # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
446
- # - +body+: The request body with a string that is appropriately encoded
447
- # (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
448
- # - +session+: A hash of parameters to store in the session. This may be +nil+.
449
- # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
450
- # - +format+: Request format. Defaults to +nil+. Can be string or symbol.
451
- # - +as+: Content type. Defaults to +nil+. Must be a symbol that corresponds
452
- # to a mime type.
453
481
  #
454
- # Example calling +create+ action and sending two params:
482
+ # Example calling `create` action and sending two params:
455
483
  #
456
- # process :create,
457
- # method: 'POST',
458
- # params: {
459
- # user: { name: 'Gaurish Sharma', email: 'user@example.com' }
460
- # },
461
- # session: { user_id: 1 },
462
- # flash: { notice: 'This is flash message' }
484
+ # process :create,
485
+ # method: 'POST',
486
+ # params: {
487
+ # user: { name: 'Gaurish Sharma', email: 'user@example.com' }
488
+ # },
489
+ # session: { user_id: 1 },
490
+ # flash: { notice: 'This is flash message' }
463
491
  #
464
- # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, and +HEAD+ requests
465
- # prefer using #get, #post, #patch, #put, #delete and #head methods
466
- # respectively which will make tests more expressive.
492
+ # To simulate `GET`, `POST`, `PATCH`, `PUT`, `DELETE`, and `HEAD` requests
493
+ # prefer using #get, #post, #patch, #put, #delete and #head methods respectively
494
+ # which will make tests more expressive.
467
495
  #
468
496
  # It's not recommended to make more than one request in the same test. Instance
469
497
  # variables that are set in one request will not persist to the next request,
@@ -607,6 +635,7 @@ module ActionController
607
635
  unless @request.cookie_jar.committed?
608
636
  @request.cookie_jar.write(@response)
609
637
  cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
638
+ cookies.update(@response.cookies)
610
639
  end
611
640
  end
612
641
  @response.prepare!
@@ -644,8 +673,8 @@ module ActionController
644
673
  end
645
674
 
646
675
  def check_required_ivars
647
- # Check for required instance variables so we can give an
648
- # understandable error message.
676
+ # Check for required instance variables so we can give an understandable error
677
+ # message.
649
678
  [:@routes, :@controller, :@request, :@response].each do |iv_name|
650
679
  if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
651
680
  raise "#{iv_name} is nil: make sure you set it in your test's setup method."
@@ -1,10 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "abstract_controller"
4
6
  require "action_dispatch"
7
+ require "action_controller/deprecator"
5
8
  require "action_controller/metal/strong_parameters"
6
9
  require "action_controller/metal/exceptions"
7
10
 
11
+ # # Action Controller
12
+ #
13
+ # Action Controller is a module of Action Pack.
14
+ #
15
+ # Action Controller provides a base controller class that can be subclassed to
16
+ # implement filters and actions to handle requests. The result of an action is
17
+ # typically content generated from views.
8
18
  module ActionController
9
19
  extend ActiveSupport::Autoload
10
20
 
@@ -19,6 +29,7 @@ module ActionController
19
29
  end
20
30
 
21
31
  autoload_under "metal" do
32
+ autoload :AllowBrowser
22
33
  autoload :ConditionalGet
23
34
  autoload :ContentSecurityPolicy
24
35
  autoload :Cookies
@@ -38,6 +49,7 @@ module ActionController
38
49
  autoload :Logging
39
50
  autoload :MimeResponds
40
51
  autoload :ParamsWrapper
52
+ autoload :RateLimiting
41
53
  autoload :Redirecting
42
54
  autoload :Renderers
43
55
  autoload :Rendering
@@ -54,13 +66,15 @@ module ActionController
54
66
  autoload :ApiRendering
55
67
  end
56
68
 
57
- autoload :TestCase, "action_controller/test_case"
58
- autoload :TemplateAssertions, "action_controller/test_case"
69
+ autoload_at "action_controller/test_case" do
70
+ autoload :TestCase
71
+ autoload :TestRequest
72
+ autoload :TemplateAssertions
73
+ end
59
74
  end
60
75
 
61
76
  # Common Active Support usage in Action Controller
62
77
  require "active_support/core_ext/module/attribute_accessors"
63
- require "active_support/core_ext/load_error"
64
78
  require "active_support/core_ext/module/attr_internal"
65
79
  require "active_support/core_ext/name_error"
66
80
  require "active_support/inflector"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "rack/version"
6
+
7
+ module ActionDispatch
8
+ module Constants
9
+ # Response Header keys for Rack 2.x and 3.x
10
+ if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
11
+ VARY = "Vary"
12
+ CONTENT_ENCODING = "Content-Encoding"
13
+ CONTENT_SECURITY_POLICY = "Content-Security-Policy"
14
+ CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
15
+ LOCATION = "Location"
16
+ FEATURE_POLICY = "Feature-Policy"
17
+ X_REQUEST_ID = "X-Request-Id"
18
+ X_CASCADE = "X-Cascade"
19
+ SERVER_TIMING = "Server-Timing"
20
+ STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security"
21
+ else
22
+ VARY = "vary"
23
+ CONTENT_ENCODING = "content-encoding"
24
+ CONTENT_SECURITY_POLICY = "content-security-policy"
25
+ CONTENT_SECURITY_POLICY_REPORT_ONLY = "content-security-policy-report-only"
26
+ LOCATION = "location"
27
+ FEATURE_POLICY = "feature-policy"
28
+ X_REQUEST_ID = "x-request-id"
29
+ X_CASCADE = "x-cascade"
30
+ SERVER_TIMING = "server-timing"
31
+ STRICT_TRANSPORT_SECURITY = "strict-transport-security"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module ActionDispatch
6
+ def self.deprecator # :nodoc:
7
+ @deprecator ||= ActiveSupport::Deprecation.new
8
+ end
9
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Http
5
7
  module Cache
@@ -32,8 +34,8 @@ module ActionDispatch
32
34
  end
33
35
  end
34
36
 
35
- # Check response freshness (+Last-Modified+ and ETag) against request
36
- # +If-Modified-Since+ and +If-None-Match+ conditions. If both headers are
37
+ # Check response freshness (`Last-Modified` and ETag) against request
38
+ # `If-Modified-Since` and `If-None-Match` conditions. If both headers are
37
39
  # supplied, both must match, or the request is not considered fresh.
38
40
  def fresh?(response)
39
41
  last_modified = if_modified_since
@@ -79,25 +81,24 @@ module ActionDispatch
79
81
  set_header DATE, utc_time.httpdate
80
82
  end
81
83
 
82
- # This method sets a weak ETag validator on the response so browsers
83
- # and proxies may cache the response, keyed on the ETag. On subsequent
84
- # requests, the +If-None-Match+ header is set to the cached ETag. If it
85
- # matches the current ETag, we can return a <tt>304 Not Modified</tt> response
86
- # with no body, letting the browser or proxy know that their cache is
87
- # current. Big savings in request time and network bandwidth.
84
+ # This method sets a weak ETag validator on the response so browsers and proxies
85
+ # may cache the response, keyed on the ETag. On subsequent requests, the
86
+ # `If-None-Match` header is set to the cached ETag. If it matches the current
87
+ # ETag, we can return a `304 Not Modified` response with no body, letting the
88
+ # browser or proxy know that their cache is current. Big savings in request time
89
+ # and network bandwidth.
88
90
  #
89
- # Weak ETags are considered to be semantically equivalent but not
90
- # byte-for-byte identical. This is perfect for browser caching of HTML
91
- # pages where we don't care about exact equality, just what the user
92
- # is viewing.
91
+ # Weak ETags are considered to be semantically equivalent but not byte-for-byte
92
+ # identical. This is perfect for browser caching of HTML pages where we don't
93
+ # care about exact equality, just what the user is viewing.
93
94
  #
94
- # Strong ETags are considered byte-for-byte identical. They allow a
95
- # browser or proxy cache to support +Range+ requests, useful for paging
96
- # through a PDF file or scrubbing through a video. Some CDNs only
97
- # support strong ETags and will ignore weak ETags entirely.
95
+ # Strong ETags are considered byte-for-byte identical. They allow a browser or
96
+ # proxy cache to support `Range` requests, useful for paging through a PDF file
97
+ # or scrubbing through a video. Some CDNs only support strong ETags and will
98
+ # ignore weak ETags entirely.
98
99
  #
99
- # Weak ETags are what we almost always need, so they're the default.
100
- # Check out #strong_etag= to provide a strong ETag validator.
100
+ # Weak ETags are what we almost always need, so they're the default. Check out
101
+ # #strong_etag= to provide a strong ETag validator.
101
102
  def etag=(weak_validators)
102
103
  self.weak_etag = weak_validators
103
104
  end
@@ -112,12 +113,13 @@ module ActionDispatch
112
113
 
113
114
  def etag?; etag; end
114
115
 
115
- # True if an ETag is set, and it's a weak validator (preceded with <tt>W/</tt>).
116
+ # True if an ETag is set, and it's a weak validator (preceded with `W/`).
116
117
  def weak_etag?
117
118
  etag? && etag.start_with?('W/"')
118
119
  end
119
120
 
120
- # True if an ETag is set, and it isn't a weak validator (not preceded with <tt>W/</tt>).
121
+ # True if an ETag is set, and it isn't a weak validator (not preceded with
122
+ # `W/`).
121
123
  def strong_etag?
122
124
  etag? && !weak_etag?
123
125
  end
@@ -138,15 +140,13 @@ module ActionDispatch
138
140
  def cache_control_segments
139
141
  if cache_control = _cache_control
140
142
  cache_control.delete(" ").split(",")
141
- else
142
- []
143
143
  end
144
144
  end
145
145
 
146
146
  def cache_control_headers
147
147
  cache_control = {}
148
148
 
149
- cache_control_segments.each do |segment|
149
+ cache_control_segments&.each do |segment|
150
150
  directive, argument = segment.split("=", 2)
151
151
 
152
152
  if SPECIAL_KEYS.include? directive
@@ -173,10 +173,9 @@ module ActionDispatch
173
173
  MUST_REVALIDATE = "must-revalidate"
174
174
 
175
175
  def handle_conditional_get!
176
- # Normally default cache control setting is handled by ETag
177
- # middleware. But, if an etag is already set, the middleware
178
- # defaults to `no-cache` unless a default `Cache-Control` value is
179
- # previously set. So, set a default one here.
176
+ # Normally default cache control setting is handled by ETag middleware. But, if
177
+ # an etag is already set, the middleware defaults to `no-cache` unless a default
178
+ # `Cache-Control` value is previously set. So, set a default one here.
180
179
  if (etag? || last_modified?) && !self._cache_control
181
180
  self._cache_control = DEFAULT_CACHE_CONTROL
182
181
  end
@@ -188,8 +187,8 @@ module ActionDispatch
188
187
  return if control.empty? && cache_control.empty? # Let middleware handle default behavior
189
188
 
190
189
  if cache_control.any?
191
- # Any caching directive coming from a controller overrides
192
- # no-cache/no-store in the default Cache-Control header.
190
+ # Any caching directive coming from a controller overrides no-cache/no-store in
191
+ # the default Cache-Control header.
193
192
  control.delete(:no_cache)
194
193
  control.delete(:no_store)
195
194