actionpack 7.0.8 → 7.1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +360 -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 +7 -4
- 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 +40 -18
- 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 = "2"
|
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
|