actionpack 7.0.8.1 → 7.1.3.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +365 -353
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +61 -18
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +3 -3
- data/lib/abstract_controller/translation.rb +1 -20
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +5 -3
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +2 -0
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +2 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +17 -8
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +24 -0
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +7 -7
- data/lib/action_controller/metal/renderers.rb +2 -2
- data/lib/action_controller/metal/rendering.rb +0 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +139 -50
- data/lib/action_controller/metal/rescue.rb +2 -0
- data/lib/action_controller/metal/streaming.rb +70 -30
- data/lib/action_controller/metal/strong_parameters.rb +132 -52
- data/lib/action_controller/metal/url_for.rb +7 -0
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +22 -9
- data/lib/action_controller/renderer.rb +98 -65
- data/lib/action_controller/test_case.rb +15 -5
- data/lib/action_controller.rb +8 -1
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +1 -3
- data/lib/action_dispatch/http/content_security_policy.rb +9 -8
- data/lib/action_dispatch/http/filter_parameters.rb +11 -5
- data/lib/action_dispatch/http/headers.rb +2 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +35 -12
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -23
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +48 -14
- data/lib/action_dispatch/http/response.rb +80 -59
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +81 -98
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +6 -3
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +17 -16
- data/lib/action_dispatch/middleware/request_id.rb +2 -0
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +19 -15
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +12 -8
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +46 -37
- data/lib/action_dispatch/railtie.rb +14 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +35 -24
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +52 -22
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +5 -1
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +20 -19
- data/lib/action_dispatch/system_testing/driver.rb +13 -21
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +13 -6
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +37 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +64 -28
@@ -9,6 +9,36 @@ module ActionDispatch
|
|
9
9
|
module Assertions
|
10
10
|
# Suite of assertions to test routes generated by \Rails and the handling of requests made to them.
|
11
11
|
module RoutingAssertions
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# A helper to make it easier to test different route configurations.
|
16
|
+
# This method temporarily replaces @routes with a new RouteSet instance
|
17
|
+
# before each test.
|
18
|
+
#
|
19
|
+
# The new instance is yielded to the passed block. Typically the block
|
20
|
+
# will create some routes using <tt>set.draw { match ... }</tt>:
|
21
|
+
#
|
22
|
+
# with_routing do |set|
|
23
|
+
# set.draw do
|
24
|
+
# resources :users
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
def with_routing(&block)
|
29
|
+
old_routes, old_controller = nil
|
30
|
+
|
31
|
+
setup do
|
32
|
+
old_routes, old_controller = @routes, @controller
|
33
|
+
create_routes(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
teardown do
|
37
|
+
reset_routes(old_routes, old_controller)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
12
42
|
def setup # :nodoc:
|
13
43
|
@routes ||= nil
|
14
44
|
super
|
@@ -83,7 +113,7 @@ module ActionDispatch
|
|
83
113
|
# # Asserts that the generated route gives us our custom route
|
84
114
|
# assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
|
85
115
|
def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)
|
86
|
-
if
|
116
|
+
if expected_path.include?("://")
|
87
117
|
fail_on(URI::InvalidURIError, message) do
|
88
118
|
uri = URI.parse(expected_path)
|
89
119
|
expected_path = uri.path.to_s.empty? ? "/" : uri.path
|
@@ -150,33 +180,11 @@ module ActionDispatch
|
|
150
180
|
# assert_equal "/users", users_path
|
151
181
|
# end
|
152
182
|
#
|
153
|
-
def with_routing
|
154
|
-
old_routes,
|
155
|
-
|
156
|
-
old_controller, @controller = @controller, @controller.clone
|
157
|
-
_routes = @routes
|
158
|
-
|
159
|
-
@controller.singleton_class.include(_routes.url_helpers)
|
160
|
-
|
161
|
-
if @controller.respond_to? :view_context_class
|
162
|
-
view_context_class = Class.new(@controller.view_context_class) do
|
163
|
-
include _routes.url_helpers
|
164
|
-
end
|
165
|
-
|
166
|
-
custom_view_context = Module.new {
|
167
|
-
define_method(:view_context_class) do
|
168
|
-
view_context_class
|
169
|
-
end
|
170
|
-
}
|
171
|
-
@controller.extend(custom_view_context)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
yield @routes
|
183
|
+
def with_routing(&block)
|
184
|
+
old_routes, old_controller = @routes, @controller
|
185
|
+
create_routes(&block)
|
175
186
|
ensure
|
176
|
-
|
177
|
-
if defined?(@controller) && @controller
|
178
|
-
@controller = old_controller
|
179
|
-
end
|
187
|
+
reset_routes(old_routes, old_controller)
|
180
188
|
end
|
181
189
|
|
182
190
|
# ROUTES TODO: These assertions should really work in an integration context
|
@@ -190,6 +198,37 @@ module ActionDispatch
|
|
190
198
|
ruby2_keywords(:method_missing)
|
191
199
|
|
192
200
|
private
|
201
|
+
def create_routes
|
202
|
+
@routes = ActionDispatch::Routing::RouteSet.new
|
203
|
+
if defined?(@controller) && @controller
|
204
|
+
@controller = @controller.clone
|
205
|
+
_routes = @routes
|
206
|
+
|
207
|
+
@controller.singleton_class.include(_routes.url_helpers)
|
208
|
+
|
209
|
+
if @controller.respond_to? :view_context_class
|
210
|
+
view_context_class = Class.new(@controller.view_context_class) do
|
211
|
+
include _routes.url_helpers
|
212
|
+
end
|
213
|
+
|
214
|
+
custom_view_context = Module.new {
|
215
|
+
define_method(:view_context_class) do
|
216
|
+
view_context_class
|
217
|
+
end
|
218
|
+
}
|
219
|
+
@controller.extend(custom_view_context)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
yield @routes
|
223
|
+
end
|
224
|
+
|
225
|
+
def reset_routes(old_routes, old_controller)
|
226
|
+
@routes = old_routes
|
227
|
+
if defined?(@controller) && @controller
|
228
|
+
@controller = old_controller
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
193
232
|
# Recognizes the route for a given path.
|
194
233
|
def recognized_request_for(path, extras = {}, msg)
|
195
234
|
if path.is_a?(Hash)
|
@@ -202,7 +241,7 @@ module ActionDispatch
|
|
202
241
|
controller = @controller if defined?(@controller)
|
203
242
|
request = ActionController::TestRequest.create controller&.class
|
204
243
|
|
205
|
-
if
|
244
|
+
if path.include?("://")
|
206
245
|
fail_on(URI::InvalidURIError, msg) do
|
207
246
|
uri = URI.parse(path)
|
208
247
|
request.env["rack.url_scheme"] = uri.scheme || "http"
|
@@ -6,6 +6,8 @@ require "action_dispatch/testing/assertions/routing"
|
|
6
6
|
|
7
7
|
module ActionDispatch
|
8
8
|
module Assertions
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
9
11
|
include ResponseAssertions
|
10
12
|
include RoutingAssertions
|
11
13
|
include Rails::Dom::Testing::Assertions
|
@@ -14,7 +16,7 @@ module ActionDispatch
|
|
14
16
|
@html_document ||= if @response.media_type&.end_with?("xml")
|
15
17
|
Nokogiri::XML::Document.parse(@response.body)
|
16
18
|
else
|
17
|
-
|
19
|
+
Rails::Dom::Testing.html_document.parse(@response.body)
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "stringio"
|
4
4
|
require "uri"
|
5
5
|
require "rack/test"
|
6
|
-
require "
|
6
|
+
require "active_support/test_case"
|
7
7
|
|
8
8
|
require "action_dispatch/testing/request_encoder"
|
9
9
|
|
@@ -58,7 +58,9 @@ module ActionDispatch
|
|
58
58
|
# the same HTTP verb will be used when redirecting, otherwise a GET request
|
59
59
|
# will be performed. Any arguments are passed to the
|
60
60
|
# underlying request.
|
61
|
-
|
61
|
+
#
|
62
|
+
# The HTTP_REFERER header will be set to the previous url.
|
63
|
+
def follow_redirect!(headers: {}, **args)
|
62
64
|
raise "not a redirect! #{status} #{status_message}" unless redirect?
|
63
65
|
|
64
66
|
method =
|
@@ -68,7 +70,11 @@ module ActionDispatch
|
|
68
70
|
:get
|
69
71
|
end
|
70
72
|
|
71
|
-
|
73
|
+
if [ :HTTP_REFERER, "HTTP_REFERER" ].none? { |key| headers.key? key }
|
74
|
+
headers["HTTP_REFERER"] = request.url
|
75
|
+
end
|
76
|
+
|
77
|
+
public_send(method, response.location, headers: headers, **args)
|
72
78
|
status
|
73
79
|
end
|
74
80
|
end
|
@@ -78,9 +84,8 @@ module ActionDispatch
|
|
78
84
|
# multiple sessions and run them side-by-side, you can also mimic (to some
|
79
85
|
# limited extent) multiple simultaneous users interacting with your system.
|
80
86
|
#
|
81
|
-
# Typically, you will instantiate a new session using
|
82
|
-
#
|
83
|
-
# Integration::Session directly.
|
87
|
+
# Typically, you will instantiate a new session using Runner#open_session,
|
88
|
+
# rather than instantiating a \Session directly.
|
84
89
|
class Session
|
85
90
|
DEFAULT_HOST = "www.example.com"
|
86
91
|
|
@@ -122,7 +127,7 @@ module ActionDispatch
|
|
122
127
|
|
123
128
|
include ActionDispatch::Routing::UrlFor
|
124
129
|
|
125
|
-
# Create and initialize a new Session instance.
|
130
|
+
# Create and initialize a new \Session instance.
|
126
131
|
def initialize(app)
|
127
132
|
super()
|
128
133
|
@app = app
|
@@ -206,9 +211,10 @@ module ActionDispatch
|
|
206
211
|
# Supports +:json+ by default and will set the appropriate request headers.
|
207
212
|
# The headers will be merged into the Rack env hash.
|
208
213
|
#
|
209
|
-
# This method is rarely used directly. Use
|
210
|
-
# HTTP methods in integration
|
211
|
-
#
|
214
|
+
# This method is rarely used directly. Use RequestHelpers#get,
|
215
|
+
# RequestHelpers#post, or other standard HTTP methods in integration
|
216
|
+
# tests. +#process+ is only required when using a request method that
|
217
|
+
# doesn't have a method defined in the integration tests.
|
212
218
|
#
|
213
219
|
# This method returns the response status, after performing the request.
|
214
220
|
# Furthermore, if this method was called from an ActionDispatch::IntegrationTest object,
|
@@ -226,7 +232,7 @@ module ActionDispatch
|
|
226
232
|
method = :post
|
227
233
|
end
|
228
234
|
|
229
|
-
if
|
235
|
+
if path.include?("://")
|
230
236
|
path = build_expanded_path(path) do |location|
|
231
237
|
https! URI::HTTPS === location if location.scheme
|
232
238
|
|
@@ -252,10 +258,13 @@ module ActionDispatch
|
|
252
258
|
"REQUEST_URI" => path,
|
253
259
|
"HTTP_HOST" => host,
|
254
260
|
"REMOTE_ADDR" => remote_addr,
|
255
|
-
"CONTENT_TYPE" => request_encoder.content_type,
|
256
261
|
"HTTP_ACCEPT" => request_encoder.accept_header || accept
|
257
262
|
}
|
258
263
|
|
264
|
+
if request_encoder.content_type
|
265
|
+
request_env["CONTENT_TYPE"] = request_encoder.content_type
|
266
|
+
end
|
267
|
+
|
259
268
|
wrapped_headers = Http::Headers.from_hash({})
|
260
269
|
wrapped_headers.merge!(headers) if headers
|
261
270
|
|
@@ -440,8 +449,9 @@ module ActionDispatch
|
|
440
449
|
# more completely than either unit or functional tests do, exercising the
|
441
450
|
# entire stack, from the dispatcher to the database.
|
442
451
|
#
|
443
|
-
# At its simplest, you simply extend <tt>IntegrationTest</tt> and write your
|
444
|
-
# using the get/
|
452
|
+
# At its simplest, you simply extend <tt>IntegrationTest</tt> and write your
|
453
|
+
# tests using the Integration::RequestHelpers#get and/or
|
454
|
+
# Integration::RequestHelpers#post methods:
|
445
455
|
#
|
446
456
|
# require "test_helper"
|
447
457
|
#
|
@@ -612,7 +622,7 @@ module ActionDispatch
|
|
612
622
|
# the request format to JSON unless overridden), sets the content type to
|
613
623
|
# "application/json" and encodes the parameters as JSON.
|
614
624
|
#
|
615
|
-
# Calling
|
625
|
+
# Calling TestResponse#parsed_body on the response parses the response body based on the
|
616
626
|
# last response MIME type.
|
617
627
|
#
|
618
628
|
# Out of the box, only <tt>:json</tt> is supported. But for any custom MIME
|
@@ -624,9 +634,9 @@ module ActionDispatch
|
|
624
634
|
#
|
625
635
|
# Where +param_encoder+ defines how the params should be encoded and
|
626
636
|
# +response_parser+ defines how the response body should be parsed through
|
627
|
-
#
|
637
|
+
# TestResponse#parsed_body.
|
628
638
|
#
|
629
|
-
# Consult the Rails Testing Guide for more.
|
639
|
+
# Consult the {Rails Testing Guide}[https://guides.rubyonrails.org/testing.html] for more.
|
630
640
|
|
631
641
|
class IntegrationTest < ActiveSupport::TestCase
|
632
642
|
include TestProcess::FixtureFile
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "nokogiri"
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
class RequestEncoder # :nodoc:
|
5
7
|
class IdentityEncoder
|
@@ -50,6 +52,7 @@ module ActionDispatch
|
|
50
52
|
@encoders[mime_name] = new(mime_name, param_encoder, response_parser)
|
51
53
|
end
|
52
54
|
|
53
|
-
register_encoder :
|
55
|
+
register_encoder :html, response_parser: -> body { Rails::Dom::Testing.html_document.parse(body) }
|
56
|
+
register_encoder :json, response_parser: -> body { JSON.parse(body, object_class: ActiveSupport::HashWithIndifferentAccess) }
|
54
57
|
end
|
55
58
|
end
|
@@ -8,21 +8,22 @@ module ActionDispatch
|
|
8
8
|
module FixtureFile
|
9
9
|
# Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.file_fixture_path, path), type)</tt>:
|
10
10
|
#
|
11
|
-
# post :change_avatar, params: { avatar:
|
11
|
+
# post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png') }
|
12
12
|
#
|
13
13
|
# Default fixture files location is <tt>test/fixtures/files</tt>.
|
14
14
|
#
|
15
15
|
# To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
|
16
16
|
# This will not affect other platforms:
|
17
17
|
#
|
18
|
-
# post :change_avatar, params: { avatar:
|
19
|
-
def
|
18
|
+
# post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png', :binary) }
|
19
|
+
def file_fixture_upload(path, mime_type = nil, binary = false)
|
20
20
|
if self.class.file_fixture_path && !File.exist?(path)
|
21
21
|
path = file_fixture(path)
|
22
22
|
end
|
23
23
|
|
24
24
|
Rack::Test::UploadedFile.new(path, mime_type, binary)
|
25
25
|
end
|
26
|
+
alias_method :fixture_file_upload, :file_fixture_upload
|
26
27
|
end
|
27
28
|
|
28
29
|
include FixtureFile
|
@@ -19,19 +19,33 @@ module ActionDispatch
|
|
19
19
|
#
|
20
20
|
# ==== Examples
|
21
21
|
# get "/posts"
|
22
|
-
# response.content_type
|
23
|
-
# response.parsed_body.class
|
24
|
-
# response.parsed_body
|
22
|
+
# response.content_type # => "text/html; charset=utf-8"
|
23
|
+
# response.parsed_body.class # => Nokogiri::HTML5::Document
|
24
|
+
# response.parsed_body.to_html # => "<!DOCTYPE html>\n<html>\n..."
|
25
|
+
#
|
26
|
+
# assert_pattern { response.parsed_body.at("main") => { content: "Hello, world" } }
|
27
|
+
#
|
28
|
+
# response.parsed_body.at("main") => {name:, content:}
|
29
|
+
# assert_equal "main", name
|
30
|
+
# assert_equal "Some main content", content
|
25
31
|
#
|
26
32
|
# get "/posts.json"
|
27
|
-
# response.content_type
|
28
|
-
# response.parsed_body.class
|
29
|
-
# response.parsed_body
|
33
|
+
# response.content_type # => "application/json; charset=utf-8"
|
34
|
+
# response.parsed_body.class # => Array
|
35
|
+
# response.parsed_body # => [{"id"=>42, "title"=>"Title"},...
|
36
|
+
#
|
37
|
+
# assert_pattern { response.parsed_body => [{ id: 42 }] }
|
30
38
|
#
|
31
39
|
# get "/posts/42.json"
|
32
|
-
# response.content_type
|
33
|
-
# response.parsed_body.class
|
34
|
-
# response.parsed_body
|
40
|
+
# response.content_type # => "application/json; charset=utf-8"
|
41
|
+
# response.parsed_body.class # => ActiveSupport::HashWithIndifferentAccess
|
42
|
+
# response.parsed_body # => {"id"=>42, "title"=>"Title"}
|
43
|
+
#
|
44
|
+
# assert_pattern { response.parsed_body => [{ title: /title/i }] }
|
45
|
+
#
|
46
|
+
# response.parsed_body => {id:, title:}
|
47
|
+
# assert_equal 42, id
|
48
|
+
# assert_equal "Title", title
|
35
49
|
def parsed_body
|
36
50
|
@parsed_body ||= response_parser.call(body)
|
37
51
|
end
|
data/lib/action_dispatch.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c)
|
4
|
+
# Copyright (c) David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -29,16 +29,29 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
29
29
|
|
30
30
|
require "action_pack"
|
31
31
|
require "rack"
|
32
|
+
require "action_dispatch/deprecator"
|
32
33
|
|
33
|
-
module Rack
|
34
|
+
module Rack # :nodoc:
|
34
35
|
autoload :Test, "rack/test"
|
35
36
|
end
|
36
37
|
|
38
|
+
# = Action Dispatch
|
39
|
+
#
|
40
|
+
# Action Dispatch is a module of Action Pack.
|
41
|
+
#
|
42
|
+
# Action Dispatch parses information about the web request, handles
|
43
|
+
# routing as defined by the user, and does advanced processing related to HTTP
|
44
|
+
# such as MIME-type negotiation, decoding parameters in POST, PATCH, or PUT
|
45
|
+
# bodies, handling HTTP caching logic, cookies and sessions.
|
37
46
|
module ActionDispatch
|
47
|
+
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
38
48
|
extend ActiveSupport::Autoload
|
39
49
|
|
40
|
-
class
|
50
|
+
class DeprecatedIllegalStateError < StandardError
|
41
51
|
end
|
52
|
+
deprecate_constant "IllegalStateError", "ActionDispatch::DeprecatedIllegalStateError",
|
53
|
+
message: "ActionDispatch::IllegalStateError is deprecated without replacement.",
|
54
|
+
deprecator: ActionDispatch.deprecator
|
42
55
|
|
43
56
|
class MissingController < NameError
|
44
57
|
end
|
@@ -53,6 +66,7 @@ module ActionDispatch
|
|
53
66
|
end
|
54
67
|
|
55
68
|
autoload_under "middleware" do
|
69
|
+
autoload :AssumeSSL
|
56
70
|
autoload :HostAuthorization
|
57
71
|
autoload :RequestId
|
58
72
|
autoload :Callbacks
|
@@ -73,6 +87,7 @@ module ActionDispatch
|
|
73
87
|
autoload :Static
|
74
88
|
end
|
75
89
|
|
90
|
+
autoload :Constants
|
76
91
|
autoload :Journey
|
77
92
|
autoload :MiddlewareStack, "action_dispatch/middleware/stack"
|
78
93
|
autoload :Routing
|
@@ -94,6 +109,19 @@ module ActionDispatch
|
|
94
109
|
autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
|
95
110
|
autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
|
96
111
|
autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
|
112
|
+
|
113
|
+
def self.resolve_store(session_store) # :nodoc:
|
114
|
+
self.const_get(session_store.to_s.camelize)
|
115
|
+
rescue NameError
|
116
|
+
raise <<~ERROR
|
117
|
+
Unable to resolve session store #{session_store.inspect}.
|
118
|
+
|
119
|
+
#{session_store.inspect} resolves to ActionDispatch::Session::#{session_store.to_s.camelize},
|
120
|
+
but that class is undefined.
|
121
|
+
|
122
|
+
Is #{session_store.inspect} spelled correctly, and are any necessary gems installed?
|
123
|
+
ERROR
|
124
|
+
end
|
97
125
|
end
|
98
126
|
|
99
127
|
mattr_accessor :test_app
|
@@ -109,12 +137,17 @@ module ActionDispatch
|
|
109
137
|
end
|
110
138
|
|
111
139
|
autoload :SystemTestCase, "action_dispatch/system_test_case"
|
140
|
+
|
141
|
+
def eager_load!
|
142
|
+
super
|
143
|
+
Routing.eager_load!
|
144
|
+
end
|
112
145
|
end
|
113
146
|
|
114
147
|
autoload :Mime, "action_dispatch/http/mime_type"
|
115
148
|
|
116
149
|
ActiveSupport.on_load(:action_view) do
|
117
150
|
ActionView::Base.default_formats ||= Mime::SET.symbols
|
118
|
-
ActionView::Template
|
151
|
+
ActionView::Template.mime_types_implementation = Mime
|
119
152
|
ActionView::LookupContext::DetailsKey.clear
|
120
153
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionPack
|
4
|
-
# Returns the currently loaded version of Action Pack as a
|
4
|
+
# Returns the currently loaded version of Action Pack as a +Gem::Version+.
|
5
5
|
def self.gem_version
|
6
6
|
Gem::Version.new VERSION::STRING
|
7
7
|
end
|
8
8
|
|
9
9
|
module VERSION
|
10
10
|
MAJOR = 7
|
11
|
-
MINOR =
|
12
|
-
TINY =
|
13
|
-
PRE = "
|
11
|
+
MINOR = 1
|
12
|
+
TINY = 3
|
13
|
+
PRE = "4"
|
14
14
|
|
15
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
16
16
|
end
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_pack.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c)
|
4
|
+
# Copyright (c) David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|