actionpack 4.2.11.3 → 5.0.7.2
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 +890 -384
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/base.rb +28 -38
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
- data/lib/abstract_controller/caching.rb +62 -0
- data/lib/abstract_controller/callbacks.rb +54 -19
- data/lib/abstract_controller/collector.rb +4 -9
- data/lib/abstract_controller/error.rb +4 -0
- data/lib/abstract_controller/helpers.rb +4 -3
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
- data/lib/abstract_controller/rendering.rb +28 -18
- data/lib/abstract_controller/translation.rb +8 -7
- data/lib/abstract_controller.rb +6 -2
- data/lib/action_controller/api/api_rendering.rb +14 -0
- data/lib/action_controller/api.rb +147 -0
- data/lib/action_controller/base.rb +14 -11
- data/lib/action_controller/caching.rb +13 -58
- data/lib/action_controller/form_builder.rb +48 -0
- data/lib/action_controller/log_subscriber.rb +3 -10
- data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
- data/lib/action_controller/metal/conditional_get.rb +106 -34
- data/lib/action_controller/metal/cookies.rb +1 -3
- data/lib/action_controller/metal/data_streaming.rb +14 -34
- data/lib/action_controller/metal/etag_with_template_digest.rb +8 -2
- data/lib/action_controller/metal/exceptions.rb +11 -6
- data/lib/action_controller/metal/force_ssl.rb +11 -11
- data/lib/action_controller/metal/head.rb +14 -8
- data/lib/action_controller/metal/helpers.rb +15 -6
- data/lib/action_controller/metal/http_authentication.rb +44 -35
- data/lib/action_controller/metal/implicit_render.rb +61 -6
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/live.rb +71 -88
- data/lib/action_controller/metal/mime_responds.rb +27 -42
- data/lib/action_controller/metal/params_wrapper.rb +9 -9
- data/lib/action_controller/metal/redirecting.rb +32 -9
- data/lib/action_controller/metal/renderers.rb +83 -40
- data/lib/action_controller/metal/rendering.rb +38 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
- data/lib/action_controller/metal/rescue.rb +3 -12
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +527 -134
- data/lib/action_controller/metal/testing.rb +1 -12
- data/lib/action_controller/metal/url_for.rb +12 -5
- data/lib/action_controller/metal.rb +88 -63
- data/lib/action_controller/railtie.rb +11 -7
- data/lib/action_controller/renderer.rb +113 -0
- data/lib/action_controller/template_assertions.rb +9 -0
- data/lib/action_controller/test_case.rb +311 -374
- data/lib/action_controller.rb +12 -9
- data/lib/action_dispatch/http/cache.rb +73 -34
- data/lib/action_dispatch/http/filter_parameters.rb +16 -12
- data/lib/action_dispatch/http/filter_redirect.rb +7 -8
- data/lib/action_dispatch/http/headers.rb +45 -14
- data/lib/action_dispatch/http/mime_negotiation.rb +42 -23
- data/lib/action_dispatch/http/mime_type.rb +126 -90
- data/lib/action_dispatch/http/mime_types.rb +3 -4
- data/lib/action_dispatch/http/parameter_filter.rb +19 -9
- data/lib/action_dispatch/http/parameters.rb +70 -40
- data/lib/action_dispatch/http/request.rb +144 -89
- data/lib/action_dispatch/http/response.rb +215 -102
- data/lib/action_dispatch/http/upload.rb +6 -2
- data/lib/action_dispatch/http/url.rb +117 -8
- data/lib/action_dispatch/journey/formatter.rb +47 -30
- data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
- data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
- data/lib/action_dispatch/journey/nodes/node.rb +14 -4
- data/lib/action_dispatch/journey/parser.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +38 -42
- data/lib/action_dispatch/journey/route.rb +88 -26
- data/lib/action_dispatch/journey/router/utils.rb +5 -5
- data/lib/action_dispatch/journey/router.rb +8 -10
- data/lib/action_dispatch/journey/routes.rb +14 -15
- data/lib/action_dispatch/journey/visitors.rb +89 -44
- data/lib/action_dispatch/middleware/callbacks.rb +10 -1
- data/lib/action_dispatch/middleware/cookies.rb +188 -134
- data/lib/action_dispatch/middleware/debug_exceptions.rb +128 -49
- data/lib/action_dispatch/middleware/debug_locks.rb +122 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
- data/lib/action_dispatch/middleware/executor.rb +19 -0
- data/lib/action_dispatch/middleware/flash.rb +66 -45
- data/lib/action_dispatch/middleware/params_parser.rb +32 -46
- data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +14 -58
- data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
- data/lib/action_dispatch/middleware/request_id.rb +11 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
- data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
- data/lib/action_dispatch/middleware/ssl.rb +124 -36
- data/lib/action_dispatch/middleware/stack.rb +44 -40
- data/lib/action_dispatch/middleware/static.rb +51 -35
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
- data/lib/action_dispatch/railtie.rb +2 -2
- data/lib/action_dispatch/request/session.rb +69 -33
- data/lib/action_dispatch/request/utils.rb +51 -19
- data/lib/action_dispatch/routing/inspector.rb +32 -43
- data/lib/action_dispatch/routing/mapper.rb +515 -348
- data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
- data/lib/action_dispatch/routing/redirection.rb +5 -4
- data/lib/action_dispatch/routing/route_set.rb +148 -240
- data/lib/action_dispatch/routing/url_for.rb +27 -10
- data/lib/action_dispatch/routing.rb +17 -13
- data/lib/action_dispatch/testing/assertion_response.rb +45 -0
- data/lib/action_dispatch/testing/assertions/response.rb +38 -20
- data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/integration.rb +377 -149
- data/lib/action_dispatch/testing/request_encoder.rb +53 -0
- data/lib/action_dispatch/testing/test_process.rb +24 -20
- data/lib/action_dispatch/testing/test_request.rb +22 -31
- data/lib/action_dispatch/testing/test_response.rb +12 -4
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +32 -34
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
- /data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActionDispatch
|
2
2
|
module Routing
|
3
3
|
# In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
|
4
|
-
# is also possible:
|
4
|
+
# is also possible: a URL can be generated from one of your routing definitions.
|
5
5
|
# URL generation functionality is centralized in this module.
|
6
6
|
#
|
7
7
|
# See ActionDispatch::Routing for general information about routing and routes.rb.
|
@@ -52,9 +52,11 @@ module ActionDispatch
|
|
52
52
|
# argument.
|
53
53
|
#
|
54
54
|
# For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
|
55
|
-
# So within mailers, you only have to type
|
56
|
-
# in full. However, mailers don't have hostname information, and
|
57
|
-
#
|
55
|
+
# So within mailers, you only have to type +url_for+ instead of 'ActionController::UrlFor#url_for'
|
56
|
+
# in full. However, mailers don't have hostname information, and you still have to provide
|
57
|
+
# the +:host+ argument or set the default host that will be used in all mailers using the
|
58
|
+
# configuration option +config.action_mailer.default_url_options+. For more information on
|
59
|
+
# url_for in mailers read the ActionMailer#Base documentation.
|
58
60
|
#
|
59
61
|
#
|
60
62
|
# == URL generation for named routes
|
@@ -147,6 +149,20 @@ module ActionDispatch
|
|
147
149
|
# # => 'http://somehost.org/myapp/tasks/testing'
|
148
150
|
# url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
|
149
151
|
# # => '/myapp/tasks/testing'
|
152
|
+
#
|
153
|
+
# Missing routes keys may be filled in from the current request's parameters
|
154
|
+
# (e.g. +:controller+, +:action+, +:id+ and any other parameters that are
|
155
|
+
# placed in the path). Given that the current action has been reached
|
156
|
+
# through `GET /users/1`:
|
157
|
+
#
|
158
|
+
# url_for(only_path: true) # => '/users/1'
|
159
|
+
# url_for(only_path: true, action: 'edit') # => '/users/1/edit'
|
160
|
+
# url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit'
|
161
|
+
#
|
162
|
+
# Notice that no +:id+ parameter was provided to the first +url_for+ call
|
163
|
+
# and the helper used the one from the route's path. Any path parameter
|
164
|
+
# implicitly used by +url_for+ can always be overwritten like shown on the
|
165
|
+
# last +url_for+ calls.
|
150
166
|
def url_for(options = nil)
|
151
167
|
case options
|
152
168
|
when nil
|
@@ -155,6 +171,13 @@ module ActionDispatch
|
|
155
171
|
route_name = options.delete :use_route
|
156
172
|
_routes.url_for(options.symbolize_keys.reverse_merge!(url_options),
|
157
173
|
route_name)
|
174
|
+
when ActionController::Parameters
|
175
|
+
unless options.permitted?
|
176
|
+
raise ArgumentError.new(ActionDispatch::Routing::INSECURE_URL_PARAMETERS_MESSAGE)
|
177
|
+
end
|
178
|
+
route_name = options.delete :use_route
|
179
|
+
_routes.url_for(options.to_h.symbolize_keys.
|
180
|
+
reverse_merge!(url_options), route_name)
|
158
181
|
when String
|
159
182
|
options
|
160
183
|
when Symbol
|
@@ -185,12 +208,6 @@ module ActionDispatch
|
|
185
208
|
def _routes_context
|
186
209
|
self
|
187
210
|
end
|
188
|
-
|
189
|
-
private
|
190
|
-
|
191
|
-
def _generate_paths_by_default
|
192
|
-
true
|
193
|
-
end
|
194
211
|
end
|
195
212
|
end
|
196
213
|
end
|
@@ -1,8 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'active_support/core_ext/object/to_param'
|
3
|
-
require 'active_support/core_ext/regexp'
|
4
|
-
require 'active_support/dependencies/autoload'
|
5
|
-
|
6
1
|
module ActionDispatch
|
7
2
|
# The routing module provides URL rewriting in native Ruby. It's a way to
|
8
3
|
# redirect incoming requests to controllers and actions. This replaces
|
@@ -58,7 +53,7 @@ module ActionDispatch
|
|
58
53
|
# resources :posts, :comments
|
59
54
|
# end
|
60
55
|
#
|
61
|
-
#
|
56
|
+
# Alternatively, you can add prefixes to your path without using a separate
|
62
57
|
# directory by using +scope+. +scope+ takes additional options which
|
63
58
|
# apply to all enclosed routes.
|
64
59
|
#
|
@@ -78,14 +73,14 @@ module ActionDispatch
|
|
78
73
|
# get 'post/:id' => 'posts#show'
|
79
74
|
# post 'post/:id' => 'posts#create_comment'
|
80
75
|
#
|
76
|
+
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
|
77
|
+
# URL will route to the <tt>show</tt> action.
|
78
|
+
#
|
81
79
|
# If your route needs to respond to more than one HTTP method (or all methods) then using the
|
82
80
|
# <tt>:via</tt> option on <tt>match</tt> is preferable.
|
83
81
|
#
|
84
82
|
# match 'post/:id' => 'posts#show', via: [:get, :post]
|
85
83
|
#
|
86
|
-
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
|
87
|
-
# URL will route to the <tt>show</tt> action.
|
88
|
-
#
|
89
84
|
# == Named routes
|
90
85
|
#
|
91
86
|
# Routes can be named by passing an <tt>:as</tt> option,
|
@@ -151,6 +146,7 @@ module ActionDispatch
|
|
151
146
|
# get 'geocode/:postalcode' => :show, constraints: {
|
152
147
|
# postalcode: /\d{5}(-\d{4})?/
|
153
148
|
# }
|
149
|
+
# end
|
154
150
|
#
|
155
151
|
# Constraints can include the 'ignorecase' and 'extended syntax' regular
|
156
152
|
# expression modifiers:
|
@@ -163,7 +159,7 @@ module ActionDispatch
|
|
163
159
|
#
|
164
160
|
# controller 'geocode' do
|
165
161
|
# get 'geocode/:postalcode' => :show, constraints: {
|
166
|
-
# postalcode: /#
|
162
|
+
# postalcode: /# Postalcode format
|
167
163
|
# \d{5} #Prefix
|
168
164
|
# (-\d{4})? #Suffix
|
169
165
|
# /x
|
@@ -232,7 +228,6 @@ module ActionDispatch
|
|
232
228
|
# def send_to_jail
|
233
229
|
# get '/jail'
|
234
230
|
# assert_response :success
|
235
|
-
# assert_template "jail/front"
|
236
231
|
# end
|
237
232
|
#
|
238
233
|
# def goes_to_login
|
@@ -242,9 +237,9 @@ module ActionDispatch
|
|
242
237
|
#
|
243
238
|
# == View a list of all your routes
|
244
239
|
#
|
245
|
-
#
|
240
|
+
# rails routes
|
246
241
|
#
|
247
|
-
# Target specific controllers by prefixing the command with <tt
|
242
|
+
# Target specific controllers by prefixing the command with <tt>-c</tt> option.
|
248
243
|
#
|
249
244
|
module Routing
|
250
245
|
extend ActiveSupport::Autoload
|
@@ -257,5 +252,14 @@ module ActionDispatch
|
|
257
252
|
|
258
253
|
SEPARATORS = %w( / . ? ) #:nodoc:
|
259
254
|
HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
|
255
|
+
|
256
|
+
#:stopdoc:
|
257
|
+
INSECURE_URL_PARAMETERS_MESSAGE = <<-MSG.squish
|
258
|
+
Attempting to generate a URL from non-sanitized request parameters!
|
259
|
+
|
260
|
+
An attacker can inject malicious data into the generated URL, such as
|
261
|
+
changing the host. Whitelist and sanitize passed parameters to be secure.
|
262
|
+
MSG
|
263
|
+
#:startdoc:
|
260
264
|
end
|
261
265
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
# This is a class that abstracts away an asserted response. It purposely
|
3
|
+
# does not inherit from Response because it doesn't need it. That means it
|
4
|
+
# does not have headers or a body.
|
5
|
+
class AssertionResponse
|
6
|
+
attr_reader :code, :name
|
7
|
+
|
8
|
+
GENERIC_RESPONSE_CODES = { # :nodoc:
|
9
|
+
success: "2XX",
|
10
|
+
missing: "404",
|
11
|
+
redirect: "3XX",
|
12
|
+
error: "5XX"
|
13
|
+
}
|
14
|
+
|
15
|
+
# Accepts a specific response status code as an Integer (404) or String
|
16
|
+
# ('404') or a response status range as a Symbol pseudo-code (:success,
|
17
|
+
# indicating any 200-299 status code).
|
18
|
+
def initialize(code_or_name)
|
19
|
+
if code_or_name.is_a?(Symbol)
|
20
|
+
@name = code_or_name
|
21
|
+
@code = code_from_name(code_or_name)
|
22
|
+
else
|
23
|
+
@name = name_from_code(code_or_name)
|
24
|
+
@code = code_or_name
|
25
|
+
end
|
26
|
+
|
27
|
+
raise ArgumentError, "Invalid response name: #{name}" if @code.nil?
|
28
|
+
raise ArgumentError, "Invalid response code: #{code}" if @name.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def code_and_name
|
32
|
+
"#{code}: #{name}"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def code_from_name(name)
|
38
|
+
GENERIC_RESPONSE_CODES[name] || Rack::Utils::SYMBOL_TO_STATUS_CODE[name]
|
39
|
+
end
|
40
|
+
|
41
|
+
def name_from_code(code)
|
42
|
+
GENERIC_RESPONSE_CODES.invert[code] || Rack::Utils::HTTP_STATUS_CODES[code]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,8 +1,14 @@
|
|
1
|
-
|
2
1
|
module ActionDispatch
|
3
2
|
module Assertions
|
4
3
|
# A small suite of assertions that test responses from \Rails applications.
|
5
4
|
module ResponseAssertions
|
5
|
+
RESPONSE_PREDICATES = { # :nodoc:
|
6
|
+
success: :successful?,
|
7
|
+
missing: :not_found?,
|
8
|
+
redirect: :redirection?,
|
9
|
+
error: :server_error?,
|
10
|
+
}
|
11
|
+
|
6
12
|
# Asserts that the response is one of the following types:
|
7
13
|
#
|
8
14
|
# * <tt>:success</tt> - Status code was in the 200-299 range
|
@@ -14,43 +20,35 @@ module ActionDispatch
|
|
14
20
|
# or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
|
15
21
|
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
|
16
22
|
#
|
17
|
-
# #
|
23
|
+
# # Asserts that the response was a redirection
|
18
24
|
# assert_response :redirect
|
19
25
|
#
|
20
|
-
# #
|
26
|
+
# # Asserts that the response code was status code 401 (unauthorized)
|
21
27
|
# assert_response 401
|
22
28
|
def assert_response(type, message = nil)
|
23
|
-
message ||=
|
29
|
+
message ||= generate_response_message(type)
|
24
30
|
|
25
|
-
if
|
26
|
-
|
27
|
-
assert @response.send("#{type}?"), message
|
28
|
-
else
|
29
|
-
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
|
30
|
-
if code.nil?
|
31
|
-
raise ArgumentError, "Invalid response type :#{type}"
|
32
|
-
end
|
33
|
-
assert_equal code, @response.response_code, message
|
34
|
-
end
|
31
|
+
if RESPONSE_PREDICATES.keys.include?(type)
|
32
|
+
assert @response.send(RESPONSE_PREDICATES[type]), message
|
35
33
|
else
|
36
|
-
assert_equal type, @response.response_code, message
|
34
|
+
assert_equal AssertionResponse.new(type).code, @response.response_code, message
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
|
-
#
|
38
|
+
# Asserts that the redirection options passed in match those of the redirect called in the latest action.
|
41
39
|
# This match can be partial, such that <tt>assert_redirected_to(controller: "weblog")</tt> will also
|
42
40
|
# match the redirection of <tt>redirect_to(controller: "weblog", action: "show")</tt> and so on.
|
43
41
|
#
|
44
|
-
# #
|
42
|
+
# # Asserts that the redirection was to the "index" action on the WeblogController
|
45
43
|
# assert_redirected_to controller: "weblog", action: "index"
|
46
44
|
#
|
47
|
-
# #
|
45
|
+
# # Asserts that the redirection was to the named route login_url
|
48
46
|
# assert_redirected_to login_url
|
49
47
|
#
|
50
|
-
# #
|
48
|
+
# # Asserts that the redirection was to the url for @customer
|
51
49
|
# assert_redirected_to @customer
|
52
50
|
#
|
53
|
-
# #
|
51
|
+
# # Asserts that the redirection matches the regular expression
|
54
52
|
# assert_redirected_to %r(\Ahttp://example.org)
|
55
53
|
def assert_redirected_to(options = {}, message=nil)
|
56
54
|
assert_response(:redirect, message)
|
@@ -77,6 +75,26 @@ module ActionDispatch
|
|
77
75
|
handle._compute_redirect_to_location(@request, fragment)
|
78
76
|
end
|
79
77
|
end
|
78
|
+
|
79
|
+
def generate_response_message(expected, actual = @response.response_code)
|
80
|
+
"Expected response to be a <#{code_with_name(expected)}>,"\
|
81
|
+
" but was a <#{code_with_name(actual)}>"
|
82
|
+
.concat location_if_redirected
|
83
|
+
end
|
84
|
+
|
85
|
+
def location_if_redirected
|
86
|
+
return '' unless @response.redirection? && @response.location.present?
|
87
|
+
location = normalize_argument_to_redirection(@response.location)
|
88
|
+
" redirect to <#{location}>"
|
89
|
+
end
|
90
|
+
|
91
|
+
def code_with_name(code_or_name)
|
92
|
+
if RESPONSE_PREDICATES.values.include?("#{code_or_name}?".to_sym)
|
93
|
+
code_or_name = RESPONSE_PREDICATES.invert["#{code_or_name}?".to_sym]
|
94
|
+
end
|
95
|
+
|
96
|
+
AssertionResponse.new(code_or_name).code_and_name
|
97
|
+
end
|
80
98
|
end
|
81
99
|
end
|
82
100
|
end
|
@@ -14,14 +14,14 @@ module ActionDispatch
|
|
14
14
|
# requiring a specific HTTP method. The hash should contain a :path with the incoming request path
|
15
15
|
# and a :method containing the required HTTP verb.
|
16
16
|
#
|
17
|
-
# #
|
17
|
+
# # Asserts that POSTing to /items will call the create action on ItemsController
|
18
18
|
# assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
|
19
19
|
#
|
20
20
|
# You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
|
21
|
-
# to assert that values in the query string
|
21
|
+
# to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the
|
22
22
|
# extras argument, appending the query string on the path directly will not work. For example:
|
23
23
|
#
|
24
|
-
# #
|
24
|
+
# # Asserts that a path of '/items/list/1?view=print' returns the correct options
|
25
25
|
# assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
|
26
26
|
#
|
27
27
|
# The +message+ parameter allows you to pass in an error message that is displayed upon failure.
|
@@ -86,8 +86,9 @@ module ActionDispatch
|
|
86
86
|
end
|
87
87
|
# Load routes.rb if it hasn't been loaded.
|
88
88
|
|
89
|
-
|
90
|
-
|
89
|
+
options = options.clone
|
90
|
+
generated_path, query_string_keys = @routes.generate_extras(options, defaults)
|
91
|
+
found_extras = options.reject { |k, _| ! query_string_keys.include? k }
|
91
92
|
|
92
93
|
msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
|
93
94
|
assert_equal(extras, found_extras, msg)
|
@@ -104,19 +105,19 @@ module ActionDispatch
|
|
104
105
|
# The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
|
105
106
|
# +message+ parameter allows you to specify a custom error message to display upon failure.
|
106
107
|
#
|
107
|
-
# #
|
108
|
+
# # Asserts a basic route: a controller with the default action (index)
|
108
109
|
# assert_routing '/home', controller: 'home', action: 'index'
|
109
110
|
#
|
110
111
|
# # Test a route generated with a specific controller, action, and parameter (id)
|
111
112
|
# assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
|
112
113
|
#
|
113
|
-
# #
|
114
|
+
# # Asserts a basic route (controller + default action), with an error message if it fails
|
114
115
|
# assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
|
115
116
|
#
|
116
117
|
# # Tests a route, providing a defaults hash
|
117
118
|
# assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
|
118
119
|
#
|
119
|
-
# # Tests a route with
|
120
|
+
# # Tests a route with an HTTP method
|
120
121
|
# assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
|
121
122
|
def assert_routing(path, options, defaults={}, extras={}, message=nil)
|
122
123
|
assert_recognizes(options, path, extras, message)
|
@@ -150,9 +151,12 @@ module ActionDispatch
|
|
150
151
|
old_controller, @controller = @controller, @controller.clone
|
151
152
|
_routes = @routes
|
152
153
|
|
153
|
-
@controller.singleton_class.
|
154
|
-
|
155
|
-
|
154
|
+
@controller.singleton_class.include(_routes.url_helpers)
|
155
|
+
|
156
|
+
if @controller.respond_to? :view_context_class
|
157
|
+
@controller.view_context_class = Class.new(@controller.view_context_class) do
|
158
|
+
include _routes.url_helpers
|
159
|
+
end
|
156
160
|
end
|
157
161
|
end
|
158
162
|
yield @routes
|
@@ -183,7 +187,7 @@ module ActionDispatch
|
|
183
187
|
end
|
184
188
|
|
185
189
|
# Assume given controller
|
186
|
-
request = ActionController::TestRequest.
|
190
|
+
request = ActionController::TestRequest.create
|
187
191
|
|
188
192
|
if path =~ %r{://}
|
189
193
|
fail_on(URI::InvalidURIError, msg) do
|
@@ -12,7 +12,7 @@ module ActionDispatch
|
|
12
12
|
include Rails::Dom::Testing::Assertions
|
13
13
|
|
14
14
|
def html_document
|
15
|
-
@html_document ||= if @response.content_type.to_s =~ /xml
|
15
|
+
@html_document ||= if @response.content_type.to_s =~ /xml\z/
|
16
16
|
Nokogiri::XML::Document.parse(@response.body)
|
17
17
|
else
|
18
18
|
Nokogiri::HTML::Document.parse(@response.body)
|