actionpack 4.2.10 → 5.0.0

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.

Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +553 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller/base.rb +28 -38
  6. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +51 -11
  7. data/lib/abstract_controller/caching.rb +62 -0
  8. data/lib/abstract_controller/callbacks.rb +52 -19
  9. data/lib/abstract_controller/collector.rb +4 -9
  10. data/lib/abstract_controller/error.rb +4 -0
  11. data/lib/abstract_controller/helpers.rb +4 -3
  12. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  13. data/lib/abstract_controller/rendering.rb +28 -18
  14. data/lib/abstract_controller/translation.rb +8 -7
  15. data/lib/abstract_controller.rb +6 -2
  16. data/lib/action_controller/api/api_rendering.rb +14 -0
  17. data/lib/action_controller/api.rb +147 -0
  18. data/lib/action_controller/base.rb +10 -13
  19. data/lib/action_controller/caching.rb +13 -58
  20. data/lib/action_controller/form_builder.rb +48 -0
  21. data/lib/action_controller/log_subscriber.rb +3 -10
  22. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  23. data/lib/action_controller/metal/conditional_get.rb +106 -34
  24. data/lib/action_controller/metal/cookies.rb +1 -3
  25. data/lib/action_controller/metal/data_streaming.rb +11 -32
  26. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  27. data/lib/action_controller/metal/exceptions.rb +11 -6
  28. data/lib/action_controller/metal/force_ssl.rb +10 -10
  29. data/lib/action_controller/metal/head.rb +14 -8
  30. data/lib/action_controller/metal/helpers.rb +15 -6
  31. data/lib/action_controller/metal/http_authentication.rb +44 -35
  32. data/lib/action_controller/metal/implicit_render.rb +61 -6
  33. data/lib/action_controller/metal/instrumentation.rb +5 -5
  34. data/lib/action_controller/metal/live.rb +66 -88
  35. data/lib/action_controller/metal/mime_responds.rb +27 -42
  36. data/lib/action_controller/metal/params_wrapper.rb +8 -8
  37. data/lib/action_controller/metal/redirecting.rb +32 -9
  38. data/lib/action_controller/metal/renderers.rb +85 -40
  39. data/lib/action_controller/metal/rendering.rb +38 -6
  40. data/lib/action_controller/metal/request_forgery_protection.rb +126 -48
  41. data/lib/action_controller/metal/rescue.rb +3 -12
  42. data/lib/action_controller/metal/streaming.rb +4 -4
  43. data/lib/action_controller/metal/strong_parameters.rb +293 -90
  44. data/lib/action_controller/metal/testing.rb +1 -12
  45. data/lib/action_controller/metal/url_for.rb +12 -5
  46. data/lib/action_controller/metal.rb +88 -63
  47. data/lib/action_controller/renderer.rb +111 -0
  48. data/lib/action_controller/template_assertions.rb +9 -0
  49. data/lib/action_controller/test_case.rb +288 -368
  50. data/lib/action_controller.rb +12 -9
  51. data/lib/action_dispatch/http/cache.rb +73 -34
  52. data/lib/action_dispatch/http/filter_parameters.rb +15 -11
  53. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  54. data/lib/action_dispatch/http/headers.rb +44 -13
  55. data/lib/action_dispatch/http/mime_negotiation.rb +41 -23
  56. data/lib/action_dispatch/http/mime_type.rb +126 -90
  57. data/lib/action_dispatch/http/mime_types.rb +3 -4
  58. data/lib/action_dispatch/http/parameter_filter.rb +18 -8
  59. data/lib/action_dispatch/http/parameters.rb +54 -41
  60. data/lib/action_dispatch/http/request.rb +149 -82
  61. data/lib/action_dispatch/http/response.rb +206 -102
  62. data/lib/action_dispatch/http/url.rb +117 -8
  63. data/lib/action_dispatch/journey/formatter.rb +39 -28
  64. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  65. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  66. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  67. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  68. data/lib/action_dispatch/journey/parser_extras.rb +4 -0
  69. data/lib/action_dispatch/journey/path/pattern.rb +38 -42
  70. data/lib/action_dispatch/journey/route.rb +74 -19
  71. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  72. data/lib/action_dispatch/journey/router.rb +5 -9
  73. data/lib/action_dispatch/journey/routes.rb +14 -15
  74. data/lib/action_dispatch/journey/visitors.rb +86 -43
  75. data/lib/action_dispatch/middleware/callbacks.rb +10 -1
  76. data/lib/action_dispatch/middleware/cookies.rb +189 -135
  77. data/lib/action_dispatch/middleware/debug_exceptions.rb +124 -49
  78. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -21
  79. data/lib/action_dispatch/middleware/executor.rb +19 -0
  80. data/lib/action_dispatch/middleware/flash.rb +66 -45
  81. data/lib/action_dispatch/middleware/params_parser.rb +32 -46
  82. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  83. data/lib/action_dispatch/middleware/reloader.rb +14 -58
  84. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  85. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  86. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  87. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  88. data/lib/action_dispatch/middleware/session/cookie_store.rb +30 -24
  89. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  90. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  91. data/lib/action_dispatch/middleware/ssl.rb +115 -36
  92. data/lib/action_dispatch/middleware/stack.rb +44 -40
  93. data/lib/action_dispatch/middleware/static.rb +51 -35
  94. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  95. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  96. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  97. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  98. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  99. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  100. data/lib/action_dispatch/railtie.rb +2 -2
  101. data/lib/action_dispatch/request/session.rb +69 -33
  102. data/lib/action_dispatch/request/utils.rb +51 -19
  103. data/lib/action_dispatch/routing/inspector.rb +32 -43
  104. data/lib/action_dispatch/routing/mapper.rb +491 -338
  105. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  106. data/lib/action_dispatch/routing/redirection.rb +3 -3
  107. data/lib/action_dispatch/routing/route_set.rb +145 -238
  108. data/lib/action_dispatch/routing/url_for.rb +27 -10
  109. data/lib/action_dispatch/routing.rb +17 -13
  110. data/lib/action_dispatch/testing/assertion_response.rb +45 -0
  111. data/lib/action_dispatch/testing/assertions/response.rb +38 -20
  112. data/lib/action_dispatch/testing/assertions/routing.rb +11 -10
  113. data/lib/action_dispatch/testing/assertions.rb +1 -1
  114. data/lib/action_dispatch/testing/integration.rb +368 -97
  115. data/lib/action_dispatch/testing/test_process.rb +5 -6
  116. data/lib/action_dispatch/testing/test_request.rb +22 -31
  117. data/lib/action_dispatch/testing/test_response.rb +7 -4
  118. data/lib/action_dispatch.rb +3 -1
  119. data/lib/action_pack/gem_version.rb +3 -3
  120. data/lib/action_pack.rb +1 -1
  121. metadata +30 -34
  122. data/lib/action_controller/metal/hide_actions.rb +0 -40
  123. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  124. data/lib/action_controller/middleware.rb +0 -39
  125. data/lib/action_controller/model_naming.rb +0 -12
  126. data/lib/action_dispatch/journey/backwards.rb +0 -5
  127. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  128. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  129. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  130. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
  131. /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: an URL can be generated from one of your routing definitions.
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 'url_for' instead of 'ActionController::UrlFor#url_for'
56
- # in full. However, mailers don't have hostname information, and that's why you'll still
57
- # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
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
- # Alternately, you can add prefixes to your path without using a separate
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: /# Postcode format
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
- # rake routes
240
+ # rails routes
246
241
  #
247
- # Target specific controllers by prefixing the command with <tt>CONTROLLER=x</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
- # # assert that the response was a redirection
23
+ # # Asserts that the response was a redirection
18
24
  # assert_response :redirect
19
25
  #
20
- # # assert that the response code was status code 401 (unauthorized)
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 ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>"
29
+ message ||= generate_response_message(type)
24
30
 
25
- if Symbol === type
26
- if [:success, :missing, :redirect, :error].include?(type)
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
- # Assert that the redirection options passed in match those of the redirect called in the latest action.
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
- # # assert that the redirection was to the "index" action on the WeblogController
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
- # # assert that the redirection was to the named route login_url
45
+ # # Asserts that the redirection was to the named route login_url
48
46
  # assert_redirected_to login_url
49
47
  #
50
- # # assert that the redirection was to the url for @customer
48
+ # # Asserts that the redirection was to the url for @customer
51
49
  # assert_redirected_to @customer
52
50
  #
53
- # # asserts that the redirection matches the regular expression
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
- # # assert that POSTing to /items will call the create action on ItemsController
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 string will end up in the params hash correctly. To test query strings you must use the
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
- # # assert that a path of '/items/list/1?view=print' returns the correct options
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
- generated_path, extra_keys = @routes.generate_extras(options, defaults)
90
- found_extras = options.reject { |k, _| ! extra_keys.include? k }
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
- # # Assert a basic route: a controller with the default action (index)
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
- # # Assert a basic route (controller + default action), with an error message if it fails
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 a HTTP method
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,7 +151,7 @@ module ActionDispatch
150
151
  old_controller, @controller = @controller, @controller.clone
151
152
  _routes = @routes
152
153
 
153
- @controller.singleton_class.send(:include, _routes.url_helpers)
154
+ @controller.singleton_class.include(_routes.url_helpers)
154
155
  @controller.view_context_class = Class.new(@controller.view_context_class) do
155
156
  include _routes.url_helpers
156
157
  end
@@ -183,7 +184,7 @@ module ActionDispatch
183
184
  end
184
185
 
185
186
  # Assume given controller
186
- request = ActionController::TestRequest.new
187
+ request = ActionController::TestRequest.create
187
188
 
188
189
  if path =~ %r{://}
189
190
  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)