actionpack 7.1.3 → 7.2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -501
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +15 -7
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +74 -72
- data/lib/action_controller/base.rb +198 -126
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +210 -205
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +525 -480
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +10 -3
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +18 -9
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +31 -24
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +20 -44
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +94 -75
- data/lib/action_dispatch/http/response.rb +73 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +8 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +671 -636
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -28
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +39 -16
@@ -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
|
-
#
|
21
|
-
#
|
22
|
-
#
|
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
|
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"
|
@@ -232,116 +234,127 @@ module ActionController
|
|
232
234
|
end
|
233
235
|
end
|
234
236
|
|
235
|
-
#
|
237
|
+
# # Action Controller Test Case
|
236
238
|
#
|
237
|
-
# Superclass for ActionController functional tests. Functional tests allow you
|
238
|
-
# test a single controller action per test method.
|
239
|
+
# Superclass for ActionController functional tests. Functional tests allow you
|
240
|
+
# to test a single controller action per test method.
|
239
241
|
#
|
240
|
-
#
|
242
|
+
# ## Use integration style controller tests over functional style controller tests.
|
241
243
|
#
|
242
|
-
#
|
244
|
+
# Rails discourages the use of functional tests in favor of integration tests
|
243
245
|
# (use ActionDispatch::IntegrationTest).
|
244
246
|
#
|
245
|
-
# New
|
246
|
-
# only be used for backward compatibility. Integration style
|
247
|
-
# requests, whereas functional style controller
|
248
|
-
#
|
249
|
-
#
|
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.
|
250
253
|
#
|
251
|
-
#
|
254
|
+
# ## Basic example
|
252
255
|
#
|
253
256
|
# Functional tests are written as follows:
|
254
|
-
# 1.
|
255
|
-
#
|
256
|
-
# 2.
|
257
|
-
#
|
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
|
+
#
|
258
262
|
#
|
259
263
|
# For example:
|
260
264
|
#
|
261
|
-
#
|
262
|
-
#
|
263
|
-
#
|
264
|
-
#
|
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" }})
|
265
269
|
#
|
266
|
-
#
|
267
|
-
#
|
268
|
-
#
|
270
|
+
# # Asserts that the controller tried to redirect us to
|
271
|
+
# # the created book's URI.
|
272
|
+
# assert_response :found
|
269
273
|
#
|
270
|
-
#
|
271
|
-
#
|
274
|
+
# # Asserts that the controller really put the book in the database.
|
275
|
+
# assert_not_nil Book.find_by(title: "Love Hina")
|
276
|
+
# end
|
272
277
|
# end
|
273
|
-
# end
|
274
278
|
#
|
275
279
|
# You can also send a real document in the simulated HTTP request.
|
276
280
|
#
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
+
# def test_create
|
282
|
+
# json = {book: { title: "Love Hina" }}.to_json
|
283
|
+
# post :create, body: json
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# ## Special instance variables
|
281
287
|
#
|
282
|
-
#
|
288
|
+
# ActionController::TestCase will also automatically provide the following
|
289
|
+
# instance variables for use in the tests:
|
283
290
|
#
|
284
|
-
#
|
285
|
-
#
|
291
|
+
# @controller
|
292
|
+
# : The controller instance that will be tested.
|
286
293
|
#
|
287
|
-
#
|
288
|
-
#
|
289
|
-
#
|
290
|
-
#
|
291
|
-
#
|
292
|
-
# you might want to set some session properties before sending a GET request.
|
293
|
-
# <b>@response</b>::
|
294
|
-
# An ActionDispatch::TestResponse object, representing the response
|
295
|
-
# of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
|
296
|
-
# after calling +post+. If the various assert methods are not sufficient, then you
|
297
|
-
# may use this object to inspect the HTTP response in detail.
|
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.
|
298
299
|
#
|
299
|
-
#
|
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.
|
305
|
+
#
|
306
|
+
#
|
307
|
+
# ## Controller is automatically inferred
|
300
308
|
#
|
301
309
|
# ActionController::TestCase will automatically infer the controller under test
|
302
310
|
# from the test class name. If the controller cannot be inferred from the test
|
303
|
-
# class name, you can explicitly set it with
|
311
|
+
# class name, you can explicitly set it with `tests`.
|
312
|
+
#
|
313
|
+
# class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
|
314
|
+
# tests WidgetController
|
315
|
+
# end
|
304
316
|
#
|
305
|
-
#
|
306
|
-
# tests WidgetController
|
307
|
-
# end
|
317
|
+
# ## Testing controller internals
|
308
318
|
#
|
309
|
-
#
|
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:
|
310
322
|
#
|
311
|
-
#
|
312
|
-
#
|
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.
|
313
326
|
#
|
314
|
-
# * session: Objects being saved in the session.
|
315
|
-
# * flash: The flash objects currently in the session.
|
316
|
-
# * cookies: \Cookies being sent to the user on this request.
|
317
327
|
#
|
318
328
|
# These collections can be used just like any other hash:
|
319
329
|
#
|
320
|
-
#
|
321
|
-
#
|
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
|
322
332
|
#
|
323
|
-
# On top of the collections, you have the complete URL that a given action
|
333
|
+
# On top of the collections, you have the complete URL that a given action
|
334
|
+
# redirected to available in `redirect_to_url`.
|
324
335
|
#
|
325
|
-
# For redirects within the same controller, you can even call follow_redirect
|
326
|
-
# action call which can
|
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.
|
327
339
|
#
|
328
|
-
#
|
340
|
+
# ## Manipulating session and cookie variables
|
329
341
|
#
|
330
|
-
# Sometimes you need to set up the session and cookie variables for a test.
|
331
|
-
#
|
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:
|
332
344
|
#
|
333
|
-
#
|
334
|
-
#
|
345
|
+
# session[:key] = "value"
|
346
|
+
# cookies[:key] = "value"
|
335
347
|
#
|
336
348
|
# To clear the cookies for a test just clear the cookie collection:
|
337
349
|
#
|
338
|
-
#
|
350
|
+
# cookies.clear
|
339
351
|
#
|
340
|
-
#
|
352
|
+
# ## Testing named routes
|
341
353
|
#
|
342
|
-
# If you're using named routes, they can be easily tested using the original
|
354
|
+
# If you're using named routes, they can be easily tested using the original
|
355
|
+
# named routes' methods straight in the test case.
|
343
356
|
#
|
344
|
-
#
|
357
|
+
# assert_redirected_to page_url(title: 'foo')
|
345
358
|
class TestCase < ActiveSupport::TestCase
|
346
359
|
singleton_class.attr_accessor :executor_around_each_request
|
347
360
|
|
@@ -354,12 +367,12 @@ module ActionController
|
|
354
367
|
attr_reader :response, :request
|
355
368
|
|
356
369
|
module ClassMethods
|
357
|
-
# Sets the controller class name. Useful if the name can't be inferred from test
|
358
|
-
# Normalizes
|
370
|
+
# Sets the controller class name. Useful if the name can't be inferred from test
|
371
|
+
# class. Normalizes `controller_class` before using.
|
359
372
|
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
#
|
373
|
+
# tests WidgetController
|
374
|
+
# tests :widget
|
375
|
+
# tests 'widget'
|
363
376
|
def tests(controller_class)
|
364
377
|
case controller_class
|
365
378
|
when String, Symbol
|
@@ -392,21 +405,24 @@ module ActionController
|
|
392
405
|
|
393
406
|
# Simulate a GET request with the given parameters.
|
394
407
|
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
#
|
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`.
|
416
|
+
#
|
401
417
|
#
|
402
|
-
# You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
|
403
|
-
#
|
404
|
-
#
|
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:
|
405
421
|
#
|
406
|
-
#
|
407
|
-
#
|
408
|
-
#
|
409
|
-
#
|
422
|
+
# get :show,
|
423
|
+
# params: { id: 7 },
|
424
|
+
# session: { user_id: 1 },
|
425
|
+
# flash: { notice: 'This is flash message' }
|
410
426
|
#
|
411
427
|
# Note that the request method is not verified. The different methods are
|
412
428
|
# available to make the tests more expressive.
|
@@ -417,67 +433,71 @@ module ActionController
|
|
417
433
|
end
|
418
434
|
|
419
435
|
# Simulate a POST request with the given parameters and set/volley the response.
|
420
|
-
# See
|
436
|
+
# See `get` for more details.
|
421
437
|
def post(action, **args)
|
422
438
|
process(action, method: "POST", **args)
|
423
439
|
end
|
424
440
|
|
425
|
-
# Simulate a PATCH request with the given parameters and set/volley the
|
426
|
-
# See
|
441
|
+
# Simulate a PATCH request with the given parameters and set/volley the
|
442
|
+
# response. See `get` for more details.
|
427
443
|
def patch(action, **args)
|
428
444
|
process(action, method: "PATCH", **args)
|
429
445
|
end
|
430
446
|
|
431
447
|
# Simulate a PUT request with the given parameters and set/volley the response.
|
432
|
-
# See
|
448
|
+
# See `get` for more details.
|
433
449
|
def put(action, **args)
|
434
450
|
process(action, method: "PUT", **args)
|
435
451
|
end
|
436
452
|
|
437
|
-
# Simulate a DELETE request with the given parameters and set/volley the
|
438
|
-
# See
|
453
|
+
# Simulate a DELETE request with the given parameters and set/volley the
|
454
|
+
# response. See `get` for more details.
|
439
455
|
def delete(action, **args)
|
440
456
|
process(action, method: "DELETE", **args)
|
441
457
|
end
|
442
458
|
|
443
459
|
# Simulate a HEAD request with the given parameters and set/volley the response.
|
444
|
-
# See
|
460
|
+
# See `get` for more details.
|
445
461
|
def head(action, **args)
|
446
462
|
process(action, method: "HEAD", **args)
|
447
463
|
end
|
448
464
|
|
449
|
-
# Simulate an HTTP request to
|
450
|
-
#
|
465
|
+
# Simulate an HTTP request to `action` by specifying request method, parameters
|
466
|
+
# and set/volley the response.
|
467
|
+
#
|
468
|
+
# * `action`: The controller action to call.
|
469
|
+
# * `method`: Request method used to send the HTTP request. Possible values
|
470
|
+
# are `GET`, `POST`, `PATCH`, `PUT`, `DELETE`, `HEAD`. Defaults to `GET`.
|
471
|
+
# Can be a symbol.
|
472
|
+
# * `params`: The hash with HTTP parameters that you want to pass. This may be
|
473
|
+
# `nil`.
|
474
|
+
# * `body`: The request body with a string that is appropriately encoded
|
475
|
+
# (`application/x-www-form-urlencoded` or `multipart/form-data`).
|
476
|
+
# * `session`: A hash of parameters to store in the session. This may be
|
477
|
+
# `nil`.
|
478
|
+
# * `flash`: A hash of parameters to store in the flash. This may be `nil`.
|
479
|
+
# * `format`: Request format. Defaults to `nil`. Can be string or symbol.
|
480
|
+
# * `as`: Content type. Defaults to `nil`. Must be a symbol that corresponds
|
481
|
+
# to a mime type.
|
451
482
|
#
|
452
|
-
# - +action+: The controller action to call.
|
453
|
-
# - +method+: Request method used to send the HTTP request. Possible values
|
454
|
-
# are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. Can be a symbol.
|
455
|
-
# - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
|
456
|
-
# - +body+: The request body with a string that is appropriately encoded
|
457
|
-
# (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
|
458
|
-
# - +session+: A hash of parameters to store in the session. This may be +nil+.
|
459
|
-
# - +flash+: A hash of parameters to store in the flash. This may be +nil+.
|
460
|
-
# - +format+: Request format. Defaults to +nil+. Can be string or symbol.
|
461
|
-
# - +as+: Content type. Defaults to +nil+. Must be a symbol that corresponds
|
462
|
-
# to a mime type.
|
463
483
|
#
|
464
|
-
# Example calling
|
484
|
+
# Example calling `create` action and sending two params:
|
465
485
|
#
|
466
|
-
#
|
467
|
-
#
|
468
|
-
#
|
469
|
-
#
|
470
|
-
#
|
471
|
-
#
|
472
|
-
#
|
486
|
+
# process :create,
|
487
|
+
# method: 'POST',
|
488
|
+
# params: {
|
489
|
+
# user: { name: 'Gaurish Sharma', email: 'user@example.com' }
|
490
|
+
# },
|
491
|
+
# session: { user_id: 1 },
|
492
|
+
# flash: { notice: 'This is flash message' }
|
473
493
|
#
|
474
|
-
# To simulate
|
475
|
-
# prefer using #get, #post, #patch, #put, #delete and #head methods
|
476
|
-
#
|
494
|
+
# To simulate `GET`, `POST`, `PATCH`, `PUT`, `DELETE`, and `HEAD` requests
|
495
|
+
# prefer using #get, #post, #patch, #put, #delete and #head methods respectively
|
496
|
+
# which will make tests more expressive.
|
477
497
|
#
|
478
498
|
# It's not recommended to make more than one request in the same test. Instance
|
479
499
|
# variables that are set in one request will not persist to the next request,
|
480
|
-
# but it's not guaranteed that all
|
500
|
+
# but it's not guaranteed that all Rails internal state will be reset. Prefer
|
481
501
|
# ActionDispatch::IntegrationTest for making multiple requests in the same test.
|
482
502
|
#
|
483
503
|
# Note that the request method is not verified.
|
@@ -654,8 +674,8 @@ module ActionController
|
|
654
674
|
end
|
655
675
|
|
656
676
|
def check_required_ivars
|
657
|
-
# Check for required instance variables so we can give an
|
658
|
-
#
|
677
|
+
# Check for required instance variables so we can give an understandable error
|
678
|
+
# message.
|
659
679
|
[:@routes, :@controller, :@request, :@response].each do |iv_name|
|
660
680
|
if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
|
661
681
|
raise "#{iv_name} is nil: make sure you set it in your test's setup method."
|
data/lib/action_controller.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "abstract_controller"
|
4
6
|
require "action_dispatch"
|
5
7
|
require "action_controller/deprecator"
|
6
8
|
require "action_controller/metal/strong_parameters"
|
7
9
|
require "action_controller/metal/exceptions"
|
8
10
|
|
9
|
-
#
|
11
|
+
# # Action Controller
|
10
12
|
#
|
11
13
|
# Action Controller is a module of Action Pack.
|
12
14
|
#
|
@@ -27,6 +29,7 @@ module ActionController
|
|
27
29
|
end
|
28
30
|
|
29
31
|
autoload_under "metal" do
|
32
|
+
autoload :AllowBrowser
|
30
33
|
autoload :ConditionalGet
|
31
34
|
autoload :ContentSecurityPolicy
|
32
35
|
autoload :Cookies
|
@@ -46,6 +49,7 @@ module ActionController
|
|
46
49
|
autoload :Logging
|
47
50
|
autoload :MimeResponds
|
48
51
|
autoload :ParamsWrapper
|
52
|
+
autoload :RateLimiting
|
49
53
|
autoload :Redirecting
|
50
54
|
autoload :Renderers
|
51
55
|
autoload :Rendering
|
@@ -62,8 +66,11 @@ module ActionController
|
|
62
66
|
autoload :ApiRendering
|
63
67
|
end
|
64
68
|
|
65
|
-
|
66
|
-
|
69
|
+
autoload_at "action_controller/test_case" do
|
70
|
+
autoload :TestCase
|
71
|
+
autoload :TestRequest
|
72
|
+
autoload :TemplateAssertions
|
73
|
+
end
|
67
74
|
end
|
68
75
|
|
69
76
|
# Common Active Support usage in Action Controller
|
@@ -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 (
|
36
|
-
#
|
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
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
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
|
-
#
|
91
|
-
#
|
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
|
-
#
|
96
|
-
#
|
97
|
-
#
|
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
|
-
#
|
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
|
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
|
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
|
@@ -171,10 +173,9 @@ module ActionDispatch
|
|
171
173
|
MUST_REVALIDATE = "must-revalidate"
|
172
174
|
|
173
175
|
def handle_conditional_get!
|
174
|
-
# Normally default cache control setting is handled by ETag
|
175
|
-
#
|
176
|
-
#
|
177
|
-
# 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.
|
178
179
|
if (etag? || last_modified?) && !self._cache_control
|
179
180
|
self._cache_control = DEFAULT_CACHE_CONTROL
|
180
181
|
end
|
@@ -186,8 +187,8 @@ module ActionDispatch
|
|
186
187
|
return if control.empty? && cache_control.empty? # Let middleware handle default behavior
|
187
188
|
|
188
189
|
if cache_control.any?
|
189
|
-
# Any caching directive coming from a controller overrides
|
190
|
-
#
|
190
|
+
# Any caching directive coming from a controller overrides no-cache/no-store in
|
191
|
+
# the default Cache-Control header.
|
191
192
|
control.delete(:no_cache)
|
192
193
|
control.delete(:no_store)
|
193
194
|
|