actionpack 4.0.1 → 4.2.11.1
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 +5 -5
- data/CHANGELOG.md +402 -1173
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/abstract_controller/base.rb +39 -7
- data/lib/abstract_controller/callbacks.rb +32 -53
- data/lib/abstract_controller/collector.rb +11 -1
- data/lib/abstract_controller/helpers.rb +26 -16
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
- data/lib/abstract_controller/rendering.rb +57 -127
- data/lib/abstract_controller/url_for.rb +1 -1
- data/lib/abstract_controller.rb +1 -2
- data/lib/action_controller/base.rb +19 -10
- data/lib/action_controller/caching/fragments.rb +7 -1
- data/lib/action_controller/caching.rb +2 -12
- data/lib/action_controller/log_subscriber.rb +29 -20
- data/lib/action_controller/metal/conditional_get.rb +37 -12
- data/lib/action_controller/metal/data_streaming.rb +1 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
- data/lib/action_controller/metal/exceptions.rb +1 -1
- data/lib/action_controller/metal/flash.rb +17 -0
- data/lib/action_controller/metal/force_ssl.rb +2 -2
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +6 -2
- data/lib/action_controller/metal/http_authentication.rb +45 -23
- data/lib/action_controller/metal/instrumentation.rb +9 -6
- data/lib/action_controller/metal/live.rb +173 -20
- data/lib/action_controller/metal/mime_responds.rb +127 -232
- data/lib/action_controller/metal/params_wrapper.rb +16 -9
- data/lib/action_controller/metal/rack_delegation.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +34 -26
- data/lib/action_controller/metal/renderers.rb +39 -12
- data/lib/action_controller/metal/rendering.rb +41 -14
- data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
- data/lib/action_controller/metal/streaming.rb +19 -21
- data/lib/action_controller/metal/strong_parameters.rb +166 -22
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -12
- data/lib/action_controller/metal.rb +14 -8
- data/lib/action_controller/model_naming.rb +1 -1
- data/lib/action_controller/railtie.rb +5 -1
- data/lib/action_controller/test_case.rb +160 -94
- data/lib/action_controller.rb +2 -18
- data/lib/action_dispatch/http/cache.rb +5 -4
- data/lib/action_dispatch/http/filter_parameters.rb +2 -2
- data/lib/action_dispatch/http/filter_redirect.rb +5 -4
- data/lib/action_dispatch/http/headers.rb +46 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
- data/lib/action_dispatch/http/mime_type.rb +25 -26
- data/lib/action_dispatch/http/mime_types.rb +1 -0
- data/lib/action_dispatch/http/parameter_filter.rb +1 -1
- data/lib/action_dispatch/http/parameters.rb +25 -41
- data/lib/action_dispatch/http/request.rb +49 -32
- data/lib/action_dispatch/http/response.rb +127 -25
- data/lib/action_dispatch/http/upload.rb +9 -21
- data/lib/action_dispatch/http/url.rb +97 -70
- data/lib/action_dispatch/journey/formatter.rb +35 -19
- data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
- data/lib/action_dispatch/journey/nodes/node.rb +4 -0
- data/lib/action_dispatch/journey/parser.rb +51 -59
- data/lib/action_dispatch/journey/parser.y +12 -10
- data/lib/action_dispatch/journey/path/pattern.rb +16 -19
- data/lib/action_dispatch/journey/route.rb +8 -19
- data/lib/action_dispatch/journey/router/strexp.rb +9 -6
- data/lib/action_dispatch/journey/router/utils.rb +54 -18
- data/lib/action_dispatch/journey/router.rb +53 -75
- data/lib/action_dispatch/journey/routes.rb +4 -0
- data/lib/action_dispatch/journey/scanner.rb +5 -5
- data/lib/action_dispatch/journey/visitors.rb +81 -60
- data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
- data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +7 -7
- data/lib/action_dispatch/middleware/cookies.rb +119 -43
- data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
- data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
- data/lib/action_dispatch/middleware/flash.rb +37 -24
- data/lib/action_dispatch/middleware/params_parser.rb +2 -2
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
- data/lib/action_dispatch/middleware/reloader.rb +11 -2
- data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
- data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
- data/lib/action_dispatch/middleware/ssl.rb +10 -7
- data/lib/action_dispatch/middleware/static.rb +79 -23
- data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
- data/lib/action_dispatch/railtie.rb +5 -2
- data/lib/action_dispatch/request/session.rb +12 -0
- data/lib/action_dispatch/request/utils.rb +35 -0
- data/lib/action_dispatch/routing/endpoint.rb +10 -0
- data/lib/action_dispatch/routing/inspector.rb +11 -17
- data/lib/action_dispatch/routing/mapper.rb +519 -312
- data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
- data/lib/action_dispatch/routing/redirection.rb +51 -26
- data/lib/action_dispatch/routing/route_set.rb +331 -206
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
- data/lib/action_dispatch/routing/url_for.rb +19 -5
- data/lib/action_dispatch/routing.rb +9 -6
- data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
- data/lib/action_dispatch/testing/assertions/response.rb +9 -15
- data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
- data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
- data/lib/action_dispatch/testing/assertions.rb +11 -7
- data/lib/action_dispatch/testing/integration.rb +31 -29
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +1 -5
- data/lib/action_dispatch.rb +5 -8
- data/lib/action_pack/gem_version.rb +15 -0
- data/lib/action_pack/version.rb +4 -7
- data/lib/action_pack.rb +1 -1
- metadata +77 -159
- data/lib/abstract_controller/layouts.rb +0 -423
- data/lib/abstract_controller/view_paths.rb +0 -96
- data/lib/action_controller/deprecated/integration_test.rb +0 -5
- data/lib/action_controller/deprecated.rb +0 -7
- data/lib/action_controller/metal/responder.rb +0 -287
- data/lib/action_controller/record_identifier.rb +0 -31
- data/lib/action_controller/vendor/html-scanner.rb +0 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
- data/lib/action_view/base.rb +0 -201
- data/lib/action_view/buffers.rb +0 -49
- data/lib/action_view/context.rb +0 -36
- data/lib/action_view/dependency_tracker.rb +0 -93
- data/lib/action_view/digestor.rb +0 -113
- data/lib/action_view/flows.rb +0 -76
- data/lib/action_view/helpers/active_model_helper.rb +0 -49
- data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
- data/lib/action_view/helpers/asset_url_helper.rb +0 -355
- data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
- data/lib/action_view/helpers/cache_helper.rb +0 -196
- data/lib/action_view/helpers/capture_helper.rb +0 -216
- data/lib/action_view/helpers/controller_helper.rb +0 -25
- data/lib/action_view/helpers/csrf_helper.rb +0 -30
- data/lib/action_view/helpers/date_helper.rb +0 -1083
- data/lib/action_view/helpers/debug_helper.rb +0 -39
- data/lib/action_view/helpers/form_helper.rb +0 -1880
- data/lib/action_view/helpers/form_options_helper.rb +0 -838
- data/lib/action_view/helpers/form_tag_helper.rb +0 -785
- data/lib/action_view/helpers/javascript_helper.rb +0 -117
- data/lib/action_view/helpers/number_helper.rb +0 -441
- data/lib/action_view/helpers/output_safety_helper.rb +0 -38
- data/lib/action_view/helpers/record_tag_helper.rb +0 -106
- data/lib/action_view/helpers/rendering_helper.rb +0 -90
- data/lib/action_view/helpers/sanitize_helper.rb +0 -256
- data/lib/action_view/helpers/tag_helper.rb +0 -173
- data/lib/action_view/helpers/tags/base.rb +0 -148
- data/lib/action_view/helpers/tags/check_box.rb +0 -64
- data/lib/action_view/helpers/tags/checkable.rb +0 -16
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
- data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
- data/lib/action_view/helpers/tags/collection_select.rb +0 -28
- data/lib/action_view/helpers/tags/color_field.rb +0 -25
- data/lib/action_view/helpers/tags/date_field.rb +0 -13
- data/lib/action_view/helpers/tags/date_select.rb +0 -72
- data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
- data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
- data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
- data/lib/action_view/helpers/tags/email_field.rb +0 -8
- data/lib/action_view/helpers/tags/file_field.rb +0 -8
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
- data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
- data/lib/action_view/helpers/tags/label.rb +0 -66
- data/lib/action_view/helpers/tags/month_field.rb +0 -13
- data/lib/action_view/helpers/tags/number_field.rb +0 -18
- data/lib/action_view/helpers/tags/password_field.rb +0 -12
- data/lib/action_view/helpers/tags/radio_button.rb +0 -31
- data/lib/action_view/helpers/tags/range_field.rb +0 -8
- data/lib/action_view/helpers/tags/search_field.rb +0 -24
- data/lib/action_view/helpers/tags/select.rb +0 -40
- data/lib/action_view/helpers/tags/tel_field.rb +0 -8
- data/lib/action_view/helpers/tags/text_area.rb +0 -18
- data/lib/action_view/helpers/tags/text_field.rb +0 -29
- data/lib/action_view/helpers/tags/time_field.rb +0 -13
- data/lib/action_view/helpers/tags/time_select.rb +0 -8
- data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
- data/lib/action_view/helpers/tags/url_field.rb +0 -8
- data/lib/action_view/helpers/tags/week_field.rb +0 -13
- data/lib/action_view/helpers/tags.rb +0 -39
- data/lib/action_view/helpers/text_helper.rb +0 -443
- data/lib/action_view/helpers/translation_helper.rb +0 -107
- data/lib/action_view/helpers/url_helper.rb +0 -635
- data/lib/action_view/helpers.rb +0 -58
- data/lib/action_view/locale/en.yml +0 -56
- data/lib/action_view/log_subscriber.rb +0 -30
- data/lib/action_view/lookup_context.rb +0 -241
- data/lib/action_view/model_naming.rb +0 -12
- data/lib/action_view/path_set.rb +0 -77
- data/lib/action_view/railtie.rb +0 -43
- data/lib/action_view/record_identifier.rb +0 -84
- data/lib/action_view/renderer/abstract_renderer.rb +0 -47
- data/lib/action_view/renderer/partial_renderer.rb +0 -492
- data/lib/action_view/renderer/renderer.rb +0 -50
- data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
- data/lib/action_view/renderer/template_renderer.rb +0 -96
- data/lib/action_view/routing_url_for.rb +0 -107
- data/lib/action_view/tasks/dependencies.rake +0 -17
- data/lib/action_view/template/error.rb +0 -138
- data/lib/action_view/template/handlers/builder.rb +0 -26
- data/lib/action_view/template/handlers/erb.rb +0 -146
- data/lib/action_view/template/handlers/raw.rb +0 -11
- data/lib/action_view/template/handlers.rb +0 -53
- data/lib/action_view/template/resolver.rb +0 -326
- data/lib/action_view/template/text.rb +0 -34
- data/lib/action_view/template/types.rb +0 -57
- data/lib/action_view/template.rb +0 -339
- data/lib/action_view/test_case.rb +0 -270
- data/lib/action_view/testing/resolvers.rb +0 -50
- data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
- data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
- data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
- data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
- data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
- data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
- data/lib/action_view/vendor/html-scanner.rb +0 -20
- data/lib/action_view.rb +0 -93
@@ -2,6 +2,9 @@ require 'rack/session/abstract/id'
|
|
2
2
|
require 'active_support/core_ext/object/to_query'
|
3
3
|
require 'active_support/core_ext/module/anonymous'
|
4
4
|
require 'active_support/core_ext/hash/keys'
|
5
|
+
require 'active_support/deprecation'
|
6
|
+
|
7
|
+
require 'rails-dom-testing'
|
5
8
|
|
6
9
|
module ActionController
|
7
10
|
module TemplateAssertions
|
@@ -12,13 +15,16 @@ module ActionController
|
|
12
15
|
teardown :teardown_subscriptions
|
13
16
|
end
|
14
17
|
|
18
|
+
RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
|
19
|
+
|
15
20
|
def setup_subscriptions
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
@_files = Hash.new(0)
|
21
|
+
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
|
22
|
+
instance_variable_set("@_#{instance_variable}", Hash.new(0))
|
23
|
+
end
|
20
24
|
|
21
|
-
|
25
|
+
@_subscribers = []
|
26
|
+
|
27
|
+
@_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
|
22
28
|
path = payload[:layout]
|
23
29
|
if path
|
24
30
|
@_layouts[path] += 1
|
@@ -28,42 +34,48 @@ module ActionController
|
|
28
34
|
end
|
29
35
|
end
|
30
36
|
|
31
|
-
ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
|
32
|
-
|
33
|
-
|
34
|
-
partial = path =~ /^.*\/_[^\/]*$/
|
35
|
-
|
36
|
-
if partial
|
37
|
-
@_partials[path] += 1
|
38
|
-
@_partials[path.split("/").last] += 1
|
39
|
-
end
|
37
|
+
@_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
|
38
|
+
if virtual_path = payload[:virtual_path]
|
39
|
+
partial = virtual_path =~ /^.*\/_[^\/]*$/
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
next if payload[:virtual_path] # files don't have virtual path
|
41
|
+
if partial
|
42
|
+
@_partials[virtual_path] += 1
|
43
|
+
@_partials[virtual_path.split("/").last] += 1
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
@_templates[virtual_path] += 1
|
47
|
+
else
|
48
|
+
path = payload[:identifier]
|
49
|
+
if path
|
50
|
+
@_files[path] += 1
|
51
|
+
@_files[path.split("/").last] += 1
|
52
|
+
end
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
57
|
def teardown_subscriptions
|
56
|
-
|
57
|
-
|
58
|
+
return unless defined?(@_subscribers)
|
59
|
+
|
60
|
+
@_subscribers.each do |subscriber|
|
61
|
+
ActiveSupport::Notifications.unsubscribe(subscriber)
|
62
|
+
end
|
58
63
|
end
|
59
64
|
|
60
65
|
def process(*args)
|
61
|
-
|
62
|
-
@_templates = Hash.new(0)
|
63
|
-
@_layouts = Hash.new(0)
|
66
|
+
reset_template_assertion
|
64
67
|
super
|
65
68
|
end
|
66
69
|
|
70
|
+
def reset_template_assertion
|
71
|
+
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
|
72
|
+
ivar_name = "@_#{instance_variable}"
|
73
|
+
if instance_variable_defined?(ivar_name)
|
74
|
+
instance_variable_get(ivar_name).clear
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
67
79
|
# Asserts that the request was rendered with the appropriate template file or partials.
|
68
80
|
#
|
69
81
|
# # assert that the "new" view template was rendered
|
@@ -87,6 +99,13 @@ module ActionController
|
|
87
99
|
# # assert that no partials were rendered
|
88
100
|
# assert_template partial: false
|
89
101
|
#
|
102
|
+
# # assert that a file was rendered
|
103
|
+
# assert_template file: "README.rdoc"
|
104
|
+
#
|
105
|
+
# # assert that no file was rendered
|
106
|
+
# assert_template file: nil
|
107
|
+
# assert_template file: false
|
108
|
+
#
|
90
109
|
# In a view test case, you can also assert that specific locals are passed
|
91
110
|
# to partials:
|
92
111
|
#
|
@@ -136,6 +155,8 @@ module ActionController
|
|
136
155
|
|
137
156
|
if options[:file]
|
138
157
|
assert_includes @_files.keys, options[:file]
|
158
|
+
elsif options.key?(:file)
|
159
|
+
assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
|
139
160
|
end
|
140
161
|
|
141
162
|
if expected_partial = options[:partial]
|
@@ -197,7 +218,7 @@ module ActionController
|
|
197
218
|
value = value.dup
|
198
219
|
end
|
199
220
|
|
200
|
-
if extra_keys.include?(key
|
221
|
+
if extra_keys.include?(key)
|
201
222
|
non_path_parameters[key] = value
|
202
223
|
else
|
203
224
|
if value.is_a?(Array)
|
@@ -206,13 +227,16 @@ module ActionController
|
|
206
227
|
value = value.to_param
|
207
228
|
end
|
208
229
|
|
209
|
-
path_parameters[key
|
230
|
+
path_parameters[key] = value
|
210
231
|
end
|
211
232
|
end
|
212
233
|
|
213
234
|
# Clear the combined params hash in case it was already referenced.
|
214
235
|
@env.delete("action_dispatch.request.parameters")
|
215
236
|
|
237
|
+
# Clear the filter cache variables so they're not stale
|
238
|
+
@filtered_parameters = @filtered_env = @filtered_path = nil
|
239
|
+
|
216
240
|
params = self.request_parameters.dup
|
217
241
|
%w(controller action only_path).each do |k|
|
218
242
|
params.delete(k)
|
@@ -228,7 +252,6 @@ module ActionController
|
|
228
252
|
@formats = nil
|
229
253
|
@env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
|
230
254
|
@env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
|
231
|
-
@symbolized_path_params = nil
|
232
255
|
@method = @request_method = nil
|
233
256
|
@fullpath = @ip = @remote_ip = @protocol = nil
|
234
257
|
@env['action_dispatch.request.query_parameters'] = {}
|
@@ -255,6 +278,29 @@ module ActionController
|
|
255
278
|
end
|
256
279
|
end
|
257
280
|
|
281
|
+
class LiveTestResponse < Live::Response
|
282
|
+
def recycle!
|
283
|
+
@body = nil
|
284
|
+
initialize
|
285
|
+
end
|
286
|
+
|
287
|
+
def body
|
288
|
+
@body ||= super
|
289
|
+
end
|
290
|
+
|
291
|
+
# Was the response successful?
|
292
|
+
alias_method :success?, :successful?
|
293
|
+
|
294
|
+
# Was the URL not found?
|
295
|
+
alias_method :missing?, :not_found?
|
296
|
+
|
297
|
+
# Were we redirected?
|
298
|
+
alias_method :redirect?, :redirection?
|
299
|
+
|
300
|
+
# Was there a server-side error?
|
301
|
+
alias_method :error?, :server_error?
|
302
|
+
end
|
303
|
+
|
258
304
|
# Methods #destroy and #load! are overridden to avoid calling methods on the
|
259
305
|
# @store object, which does not exist for the TestSession class.
|
260
306
|
class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
|
@@ -283,6 +329,10 @@ module ActionController
|
|
283
329
|
clear
|
284
330
|
end
|
285
331
|
|
332
|
+
def fetch(key, *args, &block)
|
333
|
+
@data.fetch(key.to_s, *args, &block)
|
334
|
+
end
|
335
|
+
|
286
336
|
private
|
287
337
|
|
288
338
|
def load!
|
@@ -404,6 +454,7 @@ module ActionController
|
|
404
454
|
extend ActiveSupport::Concern
|
405
455
|
include ActionDispatch::TestProcess
|
406
456
|
include ActiveSupport::Testing::ConstantLookup
|
457
|
+
include Rails::Dom::Testing::Assertions
|
407
458
|
|
408
459
|
attr_reader :response, :request
|
409
460
|
|
@@ -427,7 +478,6 @@ module ActionController
|
|
427
478
|
end
|
428
479
|
|
429
480
|
def controller_class=(new_class)
|
430
|
-
prepare_controller_class(new_class) if new_class
|
431
481
|
self._controller_class = new_class
|
432
482
|
end
|
433
483
|
|
@@ -444,11 +494,6 @@ module ActionController
|
|
444
494
|
Class === constant && constant < ActionController::Metal
|
445
495
|
end
|
446
496
|
end
|
447
|
-
|
448
|
-
def prepare_controller_class(new_class)
|
449
|
-
new_class.send :include, ActionController::TestCase::RaiseActionExceptions
|
450
|
-
end
|
451
|
-
|
452
497
|
end
|
453
498
|
|
454
499
|
# Simulate a GET request with the given parameters.
|
@@ -460,8 +505,8 @@ module ActionController
|
|
460
505
|
# - +session+: A hash of parameters to store in the session. This may be +nil+.
|
461
506
|
# - +flash+: A hash of parameters to store in the flash. This may be +nil+.
|
462
507
|
#
|
463
|
-
# You can also simulate POST, PATCH, PUT, DELETE,
|
464
|
-
# +post+, +patch+, +put+, +delete+,
|
508
|
+
# You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
|
509
|
+
# +post+, +patch+, +put+, +delete+, and +head+.
|
465
510
|
#
|
466
511
|
# Note that the request method is not verified. The different methods are
|
467
512
|
# available to make the tests more expressive.
|
@@ -522,25 +567,50 @@ module ActionController
|
|
522
567
|
end
|
523
568
|
end
|
524
569
|
|
570
|
+
# Simulate a HTTP request to +action+ by specifying request method,
|
571
|
+
# parameters and set/volley the response.
|
572
|
+
#
|
573
|
+
# - +action+: The controller action to call.
|
574
|
+
# - +http_method+: Request method used to send the http request. Possible values
|
575
|
+
# are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+.
|
576
|
+
# - +parameters+: The HTTP parameters. This may be +nil+, a hash, or a
|
577
|
+
# string that is appropriately encoded (+application/x-www-form-urlencoded+
|
578
|
+
# or +multipart/form-data+).
|
579
|
+
# - +session+: A hash of parameters to store in the session. This may be +nil+.
|
580
|
+
# - +flash+: A hash of parameters to store in the flash. This may be +nil+.
|
581
|
+
#
|
582
|
+
# Example calling +create+ action and sending two params:
|
583
|
+
#
|
584
|
+
# process :create, 'POST', user: { name: 'Gaurish Sharma', email: 'user@example.com' }
|
585
|
+
#
|
586
|
+
# Example sending parameters, +nil+ session and setting a flash message:
|
587
|
+
#
|
588
|
+
# process :view, 'GET', { id: 7 }, nil, { notice: 'This is flash message' }
|
589
|
+
#
|
590
|
+
# To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests
|
591
|
+
# prefer using #get, #post, #patch, #put, #delete and #head methods
|
592
|
+
# respectively which will make tests more expressive.
|
593
|
+
#
|
594
|
+
# Note that the request method is not verified.
|
525
595
|
def process(action, http_method = 'GET', *args)
|
526
596
|
check_required_ivars
|
527
|
-
http_method, args = handle_old_process_api(http_method, args, caller)
|
528
597
|
|
529
598
|
if args.first.is_a?(String) && http_method != 'HEAD'
|
530
599
|
@request.env['RAW_POST_DATA'] = args.shift
|
531
600
|
end
|
532
601
|
|
533
602
|
parameters, session, flash = args
|
603
|
+
parameters ||= {}
|
534
604
|
|
535
605
|
# Ensure that numbers and symbols passed as params are converted to
|
536
606
|
# proper params, as is the case when engaging rack.
|
537
607
|
parameters = paramify_values(parameters) if html_format?(parameters)
|
538
608
|
|
539
609
|
@html_document = nil
|
610
|
+
@html_scanner_document = nil
|
540
611
|
|
541
612
|
unless @controller.respond_to?(:recycle!)
|
542
613
|
@controller.extend(Testing::Functional)
|
543
|
-
@controller.class.class_eval { include Testing }
|
544
614
|
end
|
545
615
|
|
546
616
|
@request.recycle!
|
@@ -549,7 +619,6 @@ module ActionController
|
|
549
619
|
|
550
620
|
@request.env['REQUEST_METHOD'] = http_method
|
551
621
|
|
552
|
-
parameters ||= {}
|
553
622
|
controller_class_name = @controller.class.anonymous? ?
|
554
623
|
"anonymous" :
|
555
624
|
@controller.class.controller_path
|
@@ -566,27 +635,34 @@ module ActionController
|
|
566
635
|
|
567
636
|
name = @request.parameters[:action]
|
568
637
|
|
638
|
+
@controller.recycle!
|
569
639
|
@controller.process(name)
|
570
640
|
|
571
641
|
if cookies = @request.env['action_dispatch.cookies']
|
572
|
-
|
642
|
+
unless @response.committed?
|
643
|
+
cookies.write(@response)
|
644
|
+
end
|
573
645
|
end
|
574
646
|
@response.prepare!
|
575
647
|
|
576
648
|
@assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
|
577
|
-
|
578
|
-
|
649
|
+
|
650
|
+
if flash_value = @request.flash.to_session_value
|
651
|
+
@request.session['flash'] = flash_value
|
652
|
+
end
|
653
|
+
|
579
654
|
@response
|
580
655
|
end
|
581
656
|
|
582
657
|
def setup_controller_request_and_response
|
583
|
-
@request = build_request
|
584
|
-
@response = build_response
|
585
|
-
@response.request = @request
|
586
|
-
|
587
658
|
@controller = nil unless defined? @controller
|
588
659
|
|
660
|
+
response_klass = TestResponse
|
661
|
+
|
589
662
|
if klass = self.class.controller_class
|
663
|
+
if klass < ActionController::Live
|
664
|
+
response_klass = LiveTestResponse
|
665
|
+
end
|
590
666
|
unless @controller
|
591
667
|
begin
|
592
668
|
@controller = klass.new
|
@@ -596,6 +672,10 @@ module ActionController
|
|
596
672
|
end
|
597
673
|
end
|
598
674
|
|
675
|
+
@request = build_request
|
676
|
+
@response = build_response response_klass
|
677
|
+
@response.request = @request
|
678
|
+
|
599
679
|
if @controller
|
600
680
|
@controller.request = @request
|
601
681
|
@controller.params = {}
|
@@ -606,8 +686,8 @@ module ActionController
|
|
606
686
|
TestRequest.new
|
607
687
|
end
|
608
688
|
|
609
|
-
def build_response
|
610
|
-
|
689
|
+
def build_response(klass)
|
690
|
+
klass.new
|
611
691
|
end
|
612
692
|
|
613
693
|
included do
|
@@ -618,6 +698,11 @@ module ActionController
|
|
618
698
|
end
|
619
699
|
|
620
700
|
private
|
701
|
+
|
702
|
+
def document_root_element
|
703
|
+
html_document.root
|
704
|
+
end
|
705
|
+
|
621
706
|
def check_required_ivars
|
622
707
|
# Sanity check for required instance variables so we can give an
|
623
708
|
# understandable error message.
|
@@ -628,27 +713,36 @@ module ActionController
|
|
628
713
|
end
|
629
714
|
end
|
630
715
|
|
631
|
-
def handle_old_process_api(http_method, args, callstack)
|
632
|
-
# 4.0: Remove this method.
|
633
|
-
if http_method.is_a?(Hash)
|
634
|
-
ActiveSupport::Deprecation.warn("TestCase#process now expects the HTTP method as second argument: process(action, http_method, params, session, flash)", callstack)
|
635
|
-
args.unshift(http_method)
|
636
|
-
http_method = args.last.is_a?(String) ? args.last : "GET"
|
637
|
-
end
|
638
|
-
|
639
|
-
[http_method, args]
|
640
|
-
end
|
641
|
-
|
642
716
|
def build_request_uri(action, parameters)
|
643
717
|
unless @request.env["PATH_INFO"]
|
644
718
|
options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
|
645
719
|
options.update(
|
646
|
-
:only_path => true,
|
647
720
|
:action => action,
|
648
721
|
:relative_url_root => nil,
|
649
|
-
:_recall => @request.
|
722
|
+
:_recall => @request.path_parameters)
|
723
|
+
|
724
|
+
if route_name = options.delete(:use_route)
|
725
|
+
ActiveSupport::Deprecation.warn <<-MSG.squish
|
726
|
+
Passing the `use_route` option in functional tests are deprecated.
|
727
|
+
Support for this option in the `process` method (and the related
|
728
|
+
`get`, `head`, `post`, `patch`, `put` and `delete` helpers) will
|
729
|
+
be removed in the next version without replacement.
|
730
|
+
|
731
|
+
Functional tests are essentially unit tests for controllers and
|
732
|
+
they should not require knowledge to how the application's routes
|
733
|
+
are configured. Instead, you should explicitly pass the appropiate
|
734
|
+
params to the `process` method.
|
735
|
+
|
736
|
+
Previously the engines guide also contained an incorrect example
|
737
|
+
that recommended using this option to test an engine's controllers
|
738
|
+
within the dummy application. That recommendation was incorrect
|
739
|
+
and has since been corrected. Instead, you should override the
|
740
|
+
`@routes` variable in the test case with `Foo::Engine.routes`. See
|
741
|
+
the updated engines guide for details.
|
742
|
+
MSG
|
743
|
+
end
|
650
744
|
|
651
|
-
url, query_string = @routes.
|
745
|
+
url, query_string = @routes.path_for(options, route_name).split("?", 2)
|
652
746
|
|
653
747
|
@request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
|
654
748
|
@request.env["PATH_INFO"] = url
|
@@ -657,39 +751,11 @@ module ActionController
|
|
657
751
|
end
|
658
752
|
|
659
753
|
def html_format?(parameters)
|
660
|
-
return true unless parameters.
|
754
|
+
return true unless parameters.key?(:format)
|
661
755
|
Mime.fetch(parameters[:format]) { Mime['html'] }.html?
|
662
756
|
end
|
663
757
|
end
|
664
758
|
|
665
|
-
# When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
|
666
|
-
# (skipping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
|
667
|
-
# rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
|
668
|
-
# than 0.0.0.0.
|
669
|
-
#
|
670
|
-
# The exception is stored in the exception accessor for further inspection.
|
671
|
-
module RaiseActionExceptions
|
672
|
-
def self.included(base) #:nodoc:
|
673
|
-
unless base.method_defined?(:exception) && base.method_defined?(:exception=)
|
674
|
-
base.class_eval do
|
675
|
-
attr_accessor :exception
|
676
|
-
protected :exception, :exception=
|
677
|
-
end
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
protected
|
682
|
-
def rescue_action_without_handler(e)
|
683
|
-
self.exception = e
|
684
|
-
|
685
|
-
if request.remote_addr == "0.0.0.0"
|
686
|
-
raise(e)
|
687
|
-
else
|
688
|
-
super(e)
|
689
|
-
end
|
690
|
-
end
|
691
|
-
end
|
692
|
-
|
693
759
|
include Behavior
|
694
760
|
end
|
695
761
|
end
|
data/lib/action_controller.rb
CHANGED
@@ -17,6 +17,7 @@ module ActionController
|
|
17
17
|
autoload :ConditionalGet
|
18
18
|
autoload :Cookies
|
19
19
|
autoload :DataStreaming
|
20
|
+
autoload :EtagWithTemplateDigest
|
20
21
|
autoload :Flash
|
21
22
|
autoload :ForceSSL
|
22
23
|
autoload :Head
|
@@ -33,40 +34,23 @@ module ActionController
|
|
33
34
|
autoload :Rendering
|
34
35
|
autoload :RequestForgeryProtection
|
35
36
|
autoload :Rescue
|
36
|
-
autoload :Responder
|
37
37
|
autoload :Streaming
|
38
38
|
autoload :StrongParameters
|
39
39
|
autoload :Testing
|
40
40
|
autoload :UrlFor
|
41
41
|
end
|
42
42
|
|
43
|
-
autoload :Integration, 'action_controller/deprecated/integration_test'
|
44
|
-
autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
|
45
|
-
autoload :Routing, 'action_controller/deprecated'
|
46
43
|
autoload :TestCase, 'action_controller/test_case'
|
47
44
|
autoload :TemplateAssertions, 'action_controller/test_case'
|
48
45
|
|
49
|
-
eager_autoload do
|
50
|
-
autoload :RecordIdentifier
|
51
|
-
end
|
52
|
-
|
53
46
|
def self.eager_load!
|
54
47
|
super
|
55
48
|
ActionController::Caching.eager_load!
|
56
|
-
HTML.eager_load!
|
57
49
|
end
|
58
50
|
end
|
59
51
|
|
60
|
-
# All of these simply register additional autoloads
|
61
|
-
require 'action_view'
|
62
|
-
require 'action_view/vendor/html-scanner'
|
63
|
-
|
64
|
-
ActiveSupport.on_load(:action_view) do
|
65
|
-
ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
|
66
|
-
end
|
67
|
-
|
68
52
|
# Common Active Support usage in Action Controller
|
69
|
-
require 'active_support/core_ext/
|
53
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
70
54
|
require 'active_support/core_ext/load_error'
|
71
55
|
require 'active_support/core_ext/module/attr_internal'
|
72
56
|
require 'active_support/core_ext/name_error'
|
@@ -69,17 +69,17 @@ module ActionDispatch
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def date
|
72
|
-
if date_header = headers[
|
72
|
+
if date_header = headers[DATE]
|
73
73
|
Time.httpdate(date_header)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def date?
|
78
|
-
headers.include?(
|
78
|
+
headers.include?(DATE)
|
79
79
|
end
|
80
80
|
|
81
81
|
def date=(utc_time)
|
82
|
-
headers[
|
82
|
+
headers[DATE] = utc_time.httpdate
|
83
83
|
end
|
84
84
|
|
85
85
|
def etag=(etag)
|
@@ -89,10 +89,11 @@ module ActionDispatch
|
|
89
89
|
|
90
90
|
private
|
91
91
|
|
92
|
+
DATE = 'Date'.freeze
|
92
93
|
LAST_MODIFIED = "Last-Modified".freeze
|
93
94
|
ETAG = "ETag".freeze
|
94
95
|
CACHE_CONTROL = "Cache-Control".freeze
|
95
|
-
SPECIAL_KEYS = %w[extras no-cache max-age public must-revalidate]
|
96
|
+
SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate])
|
96
97
|
|
97
98
|
def cache_control_segments
|
98
99
|
if cache_control = self[CACHE_CONTROL]
|
@@ -6,8 +6,8 @@ module ActionDispatch
|
|
6
6
|
module Http
|
7
7
|
# Allows you to specify sensitive parameters which will be replaced from
|
8
8
|
# the request log by looking in the query string of the request and all
|
9
|
-
#
|
10
|
-
# value of the params hash and all
|
9
|
+
# sub-hashes of the params hash to filter. If a block is given, each key and
|
10
|
+
# value of the params hash and all sub-hashes is passed to it, the value
|
11
11
|
# or key can be replaced using String#replace or similar method.
|
12
12
|
#
|
13
13
|
# env["action_dispatch.parameter_filter"] = [:password]
|
@@ -5,7 +5,8 @@ module ActionDispatch
|
|
5
5
|
FILTERED = '[FILTERED]'.freeze # :nodoc:
|
6
6
|
|
7
7
|
def filtered_location
|
8
|
-
|
8
|
+
filters = location_filter
|
9
|
+
if !filters.empty? && location_filter_match?(filters)
|
9
10
|
FILTERED
|
10
11
|
else
|
11
12
|
location
|
@@ -15,15 +16,15 @@ module ActionDispatch
|
|
15
16
|
private
|
16
17
|
|
17
18
|
def location_filter
|
18
|
-
if request
|
19
|
+
if request
|
19
20
|
request.env['action_dispatch.redirect_filter'] || []
|
20
21
|
else
|
21
22
|
[]
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
def location_filter_match?
|
26
|
-
|
26
|
+
def location_filter_match?(filters)
|
27
|
+
filters.any? do |filter|
|
27
28
|
if String === filter
|
28
29
|
location.include?(filter)
|
29
30
|
elsif Regexp === filter
|
@@ -1,34 +1,63 @@
|
|
1
1
|
module ActionDispatch
|
2
2
|
module Http
|
3
|
+
# Provides access to the request's HTTP headers from the environment.
|
4
|
+
#
|
5
|
+
# env = { "CONTENT_TYPE" => "text/plain" }
|
6
|
+
# headers = ActionDispatch::Http::Headers.new(env)
|
7
|
+
# headers["Content-Type"] # => "text/plain"
|
3
8
|
class Headers
|
4
|
-
CGI_VARIABLES = %
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
CGI_VARIABLES = Set.new(%W[
|
10
|
+
AUTH_TYPE
|
11
|
+
CONTENT_LENGTH
|
12
|
+
CONTENT_TYPE
|
13
|
+
GATEWAY_INTERFACE
|
14
|
+
HTTPS
|
15
|
+
PATH_INFO
|
16
|
+
PATH_TRANSLATED
|
17
|
+
QUERY_STRING
|
18
|
+
REMOTE_ADDR
|
19
|
+
REMOTE_HOST
|
20
|
+
REMOTE_IDENT
|
21
|
+
REMOTE_USER
|
22
|
+
REQUEST_METHOD
|
23
|
+
SCRIPT_NAME
|
24
|
+
SERVER_NAME
|
25
|
+
SERVER_PORT
|
26
|
+
SERVER_PROTOCOL
|
27
|
+
SERVER_SOFTWARE
|
28
|
+
]).freeze
|
29
|
+
|
12
30
|
HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
|
13
31
|
|
14
32
|
include Enumerable
|
15
33
|
attr_reader :env
|
16
34
|
|
17
|
-
def initialize(env = {})
|
35
|
+
def initialize(env = {}) # :nodoc:
|
18
36
|
@env = env
|
19
37
|
end
|
20
38
|
|
39
|
+
# Returns the value for the given key mapped to @env.
|
21
40
|
def [](key)
|
22
41
|
@env[env_name(key)]
|
23
42
|
end
|
24
43
|
|
44
|
+
# Sets the given value for the key mapped to @env.
|
25
45
|
def []=(key, value)
|
26
46
|
@env[env_name(key)] = value
|
27
47
|
end
|
28
48
|
|
29
|
-
def key?(key)
|
49
|
+
def key?(key)
|
50
|
+
@env.key? env_name(key)
|
51
|
+
end
|
30
52
|
alias :include? :key?
|
31
53
|
|
54
|
+
# Returns the value for the given key mapped to @env.
|
55
|
+
#
|
56
|
+
# If the key is not found and an optional code block is not provided,
|
57
|
+
# raises a <tt>KeyError</tt> exception.
|
58
|
+
#
|
59
|
+
# If the code block is provided, then it will be run and
|
60
|
+
# its result returned.
|
32
61
|
def fetch(key, *args, &block)
|
33
62
|
@env.fetch env_name(key), *args, &block
|
34
63
|
end
|
@@ -37,12 +66,17 @@ module ActionDispatch
|
|
37
66
|
@env.each(&block)
|
38
67
|
end
|
39
68
|
|
69
|
+
# Returns a new Http::Headers instance containing the contents of
|
70
|
+
# <tt>headers_or_env</tt> and the original instance.
|
40
71
|
def merge(headers_or_env)
|
41
72
|
headers = Http::Headers.new(env.dup)
|
42
73
|
headers.merge!(headers_or_env)
|
43
74
|
headers
|
44
75
|
end
|
45
76
|
|
77
|
+
# Adds the contents of <tt>headers_or_env</tt> to original instance
|
78
|
+
# entries; duplicate keys are overwritten with the values from
|
79
|
+
# <tt>headers_or_env</tt>.
|
46
80
|
def merge!(headers_or_env)
|
47
81
|
headers_or_env.each do |key, value|
|
48
82
|
self[env_name(key)] = value
|
@@ -50,6 +84,8 @@ module ActionDispatch
|
|
50
84
|
end
|
51
85
|
|
52
86
|
private
|
87
|
+
# Converts a HTTP header name to an environment variable name if it is
|
88
|
+
# not contained within the headers hash.
|
53
89
|
def env_name(key)
|
54
90
|
key = key.to_s
|
55
91
|
if key =~ HTTP_HEADER
|