actionpack 7.0.8.1 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -500
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +119 -106
  7. data/lib/abstract_controller/caching/fragments.rb +51 -52
  8. data/lib/abstract_controller/caching.rb +2 -0
  9. data/lib/abstract_controller/callbacks.rb +94 -67
  10. data/lib/abstract_controller/collector.rb +6 -6
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +2 -0
  13. data/lib/abstract_controller/helpers.rb +121 -91
  14. data/lib/abstract_controller/logger.rb +2 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
  16. data/lib/abstract_controller/rendering.rb +14 -13
  17. data/lib/abstract_controller/translation.rb +12 -30
  18. data/lib/abstract_controller/url_for.rb +9 -5
  19. data/lib/abstract_controller.rb +8 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/api.rb +78 -73
  22. data/lib/action_controller/base.rb +199 -141
  23. data/lib/action_controller/caching.rb +16 -11
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +21 -16
  26. data/lib/action_controller/log_subscriber.rb +19 -5
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  29. data/lib/action_controller/metal/conditional_get.rb +187 -174
  30. data/lib/action_controller/metal/content_security_policy.rb +26 -25
  31. data/lib/action_controller/metal/cookies.rb +4 -2
  32. data/lib/action_controller/metal/data_streaming.rb +65 -54
  33. data/lib/action_controller/metal/default_headers.rb +6 -2
  34. data/lib/action_controller/metal/etag_with_flash.rb +4 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
  36. data/lib/action_controller/metal/exceptions.rb +19 -9
  37. data/lib/action_controller/metal/flash.rb +12 -10
  38. data/lib/action_controller/metal/head.rb +20 -16
  39. data/lib/action_controller/metal/helpers.rb +64 -67
  40. data/lib/action_controller/metal/http_authentication.rb +214 -200
  41. data/lib/action_controller/metal/implicit_render.rb +21 -17
  42. data/lib/action_controller/metal/instrumentation.rb +22 -12
  43. data/lib/action_controller/metal/live.rb +125 -92
  44. data/lib/action_controller/metal/logging.rb +6 -4
  45. data/lib/action_controller/metal/mime_responds.rb +151 -142
  46. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  47. data/lib/action_controller/metal/params_wrapper.rb +58 -58
  48. data/lib/action_controller/metal/permissions_policy.rb +14 -13
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +110 -84
  51. data/lib/action_controller/metal/renderers.rb +50 -49
  52. data/lib/action_controller/metal/rendering.rb +103 -82
  53. data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
  54. data/lib/action_controller/metal/rescue.rb +12 -8
  55. data/lib/action_controller/metal/streaming.rb +174 -132
  56. data/lib/action_controller/metal/strong_parameters.rb +598 -473
  57. data/lib/action_controller/metal/testing.rb +2 -0
  58. data/lib/action_controller/metal/url_for.rb +23 -14
  59. data/lib/action_controller/metal.rb +145 -61
  60. data/lib/action_controller/railtie.rb +25 -9
  61. data/lib/action_controller/railties/helpers.rb +2 -0
  62. data/lib/action_controller/renderer.rb +105 -66
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +157 -128
  65. data/lib/action_controller.rb +17 -3
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +28 -29
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +69 -49
  71. data/lib/action_dispatch/http/filter_parameters.rb +27 -12
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +23 -21
  74. data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
  75. data/lib/action_dispatch/http/mime_type.rb +60 -30
  76. data/lib/action_dispatch/http/mime_types.rb +5 -1
  77. data/lib/action_dispatch/http/parameters.rb +12 -10
  78. data/lib/action_dispatch/http/permissions_policy.rb +32 -34
  79. data/lib/action_dispatch/http/rack_cache.rb +4 -0
  80. data/lib/action_dispatch/http/request.rb +132 -79
  81. data/lib/action_dispatch/http/response.rb +136 -103
  82. data/lib/action_dispatch/http/upload.rb +19 -15
  83. data/lib/action_dispatch/http/url.rb +75 -73
  84. data/lib/action_dispatch/journey/formatter.rb +19 -6
  85. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  88. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  90. data/lib/action_dispatch/journey/parser.rb +4 -3
  91. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  92. data/lib/action_dispatch/journey/path/pattern.rb +18 -15
  93. data/lib/action_dispatch/journey/route.rb +12 -9
  94. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  95. data/lib/action_dispatch/journey/router.rb +13 -10
  96. data/lib/action_dispatch/journey/routes.rb +6 -4
  97. data/lib/action_dispatch/journey/scanner.rb +4 -2
  98. data/lib/action_dispatch/journey/visitors.rb +2 -0
  99. data/lib/action_dispatch/journey.rb +2 -0
  100. data/lib/action_dispatch/log_subscriber.rb +25 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
  102. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  103. data/lib/action_dispatch/middleware/callbacks.rb +4 -0
  104. data/lib/action_dispatch/middleware/cookies.rb +192 -194
  105. data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
  106. data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
  107. data/lib/action_dispatch/middleware/debug_view.rb +9 -2
  108. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
  109. data/lib/action_dispatch/middleware/executor.rb +9 -1
  110. data/lib/action_dispatch/middleware/flash.rb +65 -46
  111. data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
  112. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
  113. data/lib/action_dispatch/middleware/reloader.rb +9 -5
  114. data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
  115. data/lib/action_dispatch/middleware/request_id.rb +15 -8
  116. data/lib/action_dispatch/middleware/server_timing.rb +8 -6
  117. data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
  118. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
  119. data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
  120. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
  121. data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
  122. data/lib/action_dispatch/middleware/ssl.rb +60 -45
  123. data/lib/action_dispatch/middleware/stack.rb +15 -9
  124. data/lib/action_dispatch/middleware/static.rb +40 -34
  125. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  126. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  130. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
  139. data/lib/action_dispatch/railtie.rb +12 -4
  140. data/lib/action_dispatch/request/session.rb +39 -27
  141. data/lib/action_dispatch/request/utils.rb +10 -3
  142. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  143. data/lib/action_dispatch/routing/inspector.rb +59 -9
  144. data/lib/action_dispatch/routing/mapper.rb +686 -639
  145. data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
  146. data/lib/action_dispatch/routing/redirection.rb +52 -38
  147. data/lib/action_dispatch/routing/route_set.rb +106 -62
  148. data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
  149. data/lib/action_dispatch/routing/url_for.rb +131 -122
  150. data/lib/action_dispatch/routing.rb +152 -150
  151. data/lib/action_dispatch/system_test_case.rb +91 -81
  152. data/lib/action_dispatch/system_testing/browser.rb +27 -19
  153. data/lib/action_dispatch/system_testing/driver.rb +16 -22
  154. data/lib/action_dispatch/system_testing/server.rb +2 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  158. data/lib/action_dispatch/testing/assertions/response.rb +36 -26
  159. data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
  160. data/lib/action_dispatch/testing/assertions.rb +5 -1
  161. data/lib/action_dispatch/testing/integration.rb +240 -229
  162. data/lib/action_dispatch/testing/request_encoder.rb +6 -1
  163. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  164. data/lib/action_dispatch/testing/test_process.rb +14 -9
  165. data/lib/action_dispatch/testing/test_request.rb +4 -2
  166. data/lib/action_dispatch/testing/test_response.rb +34 -19
  167. data/lib/action_dispatch.rb +52 -21
  168. data/lib/action_pack/gem_version.rb +5 -3
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +91 -32
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "uri"
4
6
  require "active_support/core_ext/hash/indifferent_access"
5
7
  require "active_support/core_ext/string/access"
@@ -7,43 +9,158 @@ require "action_controller/metal/exceptions"
7
9
 
8
10
  module ActionDispatch
9
11
  module Assertions
10
- # Suite of assertions to test routes generated by \Rails and the handling of requests made to them.
12
+ # Suite of assertions to test routes generated by Rails and the handling of
13
+ # requests made to them.
11
14
  module RoutingAssertions
15
+ extend ActiveSupport::Concern
16
+
17
+ module WithIntegrationRouting # :nodoc:
18
+ extend ActiveSupport::Concern
19
+
20
+ module ClassMethods
21
+ def with_routing(&block)
22
+ old_routes = nil
23
+ old_integration_session = nil
24
+
25
+ setup do
26
+ old_routes = app.routes
27
+ old_integration_session = integration_session
28
+ create_routes(&block)
29
+ end
30
+
31
+ teardown do
32
+ reset_routes(old_routes, old_integration_session)
33
+ end
34
+ end
35
+ end
36
+
37
+ def with_routing(&block)
38
+ old_routes = app.routes
39
+ old_integration_session = integration_session
40
+ create_routes(&block)
41
+ ensure
42
+ reset_routes(old_routes, old_integration_session)
43
+ end
44
+
45
+ private
46
+ def create_routes
47
+ app = self.app
48
+ routes = ActionDispatch::Routing::RouteSet.new
49
+ rack_app = app.config.middleware.build(routes)
50
+ https = integration_session.https?
51
+ host = integration_session.host
52
+
53
+ app.instance_variable_set(:@routes, routes)
54
+ app.instance_variable_set(:@app, rack_app)
55
+ @integration_session = Class.new(ActionDispatch::Integration::Session) do
56
+ include app.routes.url_helpers
57
+ include app.routes.mounted_helpers
58
+ end.new(app)
59
+ @integration_session.https! https
60
+ @integration_session.host! host
61
+ @routes = routes
62
+
63
+ yield routes
64
+ end
65
+
66
+ def reset_routes(old_routes, old_integration_session)
67
+ old_rack_app = app.config.middleware.build(old_routes)
68
+
69
+ app.instance_variable_set(:@routes, old_routes)
70
+ app.instance_variable_set(:@app, old_rack_app)
71
+ @integration_session = old_integration_session
72
+ @routes = old_routes
73
+ end
74
+ end
75
+
76
+ module ClassMethods
77
+ # A helper to make it easier to test different route configurations. This method
78
+ # temporarily replaces @routes with a new RouteSet instance before each test.
79
+ #
80
+ # The new instance is yielded to the passed block. Typically the block will
81
+ # create some routes using `set.draw { match ... }`:
82
+ #
83
+ # with_routing do |set|
84
+ # set.draw do
85
+ # resources :users
86
+ # end
87
+ # end
88
+ #
89
+ def with_routing(&block)
90
+ old_routes, old_controller = nil
91
+
92
+ setup do
93
+ old_routes, old_controller = @routes, @controller
94
+ create_routes(&block)
95
+ end
96
+
97
+ teardown do
98
+ reset_routes(old_routes, old_controller)
99
+ end
100
+ end
101
+ end
102
+
12
103
  def setup # :nodoc:
13
104
  @routes ||= nil
14
105
  super
15
106
  end
16
107
 
17
- # Asserts that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash)
18
- # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+.
108
+ # A helper to make it easier to test different route configurations. This method
109
+ # temporarily replaces @routes with a new RouteSet instance.
110
+ #
111
+ # The new instance is yielded to the passed block. Typically the block will
112
+ # create some routes using `set.draw { match ... }`:
113
+ #
114
+ # with_routing do |set|
115
+ # set.draw do
116
+ # resources :users
117
+ # end
118
+ # assert_equal "/users", users_path
119
+ # end
120
+ #
121
+ def with_routing(&block)
122
+ old_routes, old_controller = @routes, @controller
123
+ create_routes(&block)
124
+ ensure
125
+ reset_routes(old_routes, old_controller)
126
+ end
127
+
128
+ # Asserts that the routing of the given `path` was handled correctly and that
129
+ # the parsed options (given in the `expected_options` hash) match `path`.
130
+ # Basically, it asserts that Rails recognizes the route given by
131
+ # `expected_options`.
19
132
  #
20
- # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes
21
- # requiring a specific HTTP method. The hash should contain a +:path+ with the incoming request path
22
- # and a +:method+ containing the required HTTP verb.
133
+ # Pass a hash in the second argument (`path`) to specify the request method.
134
+ # This is useful for routes requiring a specific HTTP method. The hash should
135
+ # contain a `:path` with the incoming request path and a `:method` containing
136
+ # the required HTTP verb.
23
137
  #
24
- # # Asserts that POSTing to /items will call the create action on ItemsController
25
- # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
138
+ # # Asserts that POSTing to /items will call the create action on ItemsController
139
+ # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
26
140
  #
27
- # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
28
- # to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the extras
29
- # argument because appending the query string on the path directly will not work. For example:
141
+ # You can also pass in `extras` with a hash containing URL parameters that would
142
+ # normally be in the query string. This can be used to assert that values in the
143
+ # query string will end up in the params hash correctly. To test query strings
144
+ # you must use the extras argument because appending the query string on the
145
+ # path directly will not work. For example:
30
146
  #
31
- # # Asserts that a path of '/items/list/1?view=print' returns the correct options
32
- # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
147
+ # # Asserts that a path of '/items/list/1?view=print' returns the correct options
148
+ # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
33
149
  #
34
- # The +message+ parameter allows you to pass in an error message that is displayed upon failure.
150
+ # The `message` parameter allows you to pass in an error message that is
151
+ # displayed upon failure.
35
152
  #
36
- # # Check the default route (i.e., the index action)
37
- # assert_recognizes({controller: 'items', action: 'index'}, 'items')
153
+ # # Check the default route (i.e., the index action)
154
+ # assert_recognizes({controller: 'items', action: 'index'}, 'items')
38
155
  #
39
- # # Test a specific action
40
- # assert_recognizes({controller: 'items', action: 'list'}, 'items/list')
156
+ # # Test a specific action
157
+ # assert_recognizes({controller: 'items', action: 'list'}, 'items/list')
41
158
  #
42
- # # Test an action with a parameter
43
- # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1')
159
+ # # Test an action with a parameter
160
+ # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1')
44
161
  #
45
- # # Test a custom route
46
- # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
162
+ # # Test a custom route
163
+ # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
47
164
  def assert_recognizes(expected_options, path, extras = {}, msg = nil)
48
165
  if path.is_a?(Hash) && path[:method].to_s == "all"
49
166
  [:get, :post, :put, :delete].each do |method|
@@ -65,25 +182,27 @@ module ActionDispatch
65
182
  end
66
183
  end
67
184
 
68
- # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+.
69
- # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in
70
- # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures.
185
+ # Asserts that the provided options can be used to generate the provided path.
186
+ # This is the inverse of `assert_recognizes`. The `extras` parameter is used to
187
+ # tell the request the names and values of additional request parameters that
188
+ # would be in a query string. The `message` parameter allows you to specify a
189
+ # custom error message for assertion failures.
71
190
  #
72
- # The +defaults+ parameter is unused.
191
+ # The `defaults` parameter is unused.
73
192
  #
74
- # # Asserts that the default action is generated for a route with no action
75
- # assert_generates "/items", controller: "items", action: "index"
193
+ # # Asserts that the default action is generated for a route with no action
194
+ # assert_generates "/items", controller: "items", action: "index"
76
195
  #
77
- # # Tests that the list action is properly routed
78
- # assert_generates "/items/list", controller: "items", action: "list"
196
+ # # Tests that the list action is properly routed
197
+ # assert_generates "/items/list", controller: "items", action: "list"
79
198
  #
80
- # # Tests the generation of a route with a parameter
81
- # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }
199
+ # # Tests the generation of a route with a parameter
200
+ # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }
82
201
  #
83
- # # Asserts that the generated route gives us our custom route
84
- # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
202
+ # # Asserts that the generated route gives us our custom route
203
+ # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
85
204
  def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)
86
- if %r{://}.match?(expected_path)
205
+ if expected_path.include?("://")
87
206
  fail_on(URI::InvalidURIError, message) do
88
207
  uri = URI.parse(expected_path)
89
208
  expected_path = uri.path.to_s.empty? ? "/" : uri.path
@@ -104,27 +223,28 @@ module ActionDispatch
104
223
  assert_equal(expected_path, generated_path, msg)
105
224
  end
106
225
 
107
- # Asserts that path and options match both ways; in other words, it verifies that <tt>path</tt> generates
108
- # <tt>options</tt> and then that <tt>options</tt> generates <tt>path</tt>. This essentially combines +assert_recognizes+
109
- # and +assert_generates+ into one step.
226
+ # Asserts that path and options match both ways; in other words, it verifies
227
+ # that `path` generates `options` and then that `options` generates `path`. This
228
+ # essentially combines `assert_recognizes` and `assert_generates` into one step.
110
229
  #
111
- # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
112
- # +message+ parameter allows you to specify a custom error message to display upon failure.
230
+ # The `extras` hash allows you to specify options that would normally be
231
+ # provided as a query string to the action. The `message` parameter allows you
232
+ # to specify a custom error message to display upon failure.
113
233
  #
114
- # # Asserts a basic route: a controller with the default action (index)
115
- # assert_routing '/home', controller: 'home', action: 'index'
234
+ # # Asserts a basic route: a controller with the default action (index)
235
+ # assert_routing '/home', controller: 'home', action: 'index'
116
236
  #
117
- # # Test a route generated with a specific controller, action, and parameter (id)
118
- # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
237
+ # # Test a route generated with a specific controller, action, and parameter (id)
238
+ # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
119
239
  #
120
- # # Asserts a basic route (controller + default action), with an error message if it fails
121
- # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
240
+ # # Asserts a basic route (controller + default action), with an error message if it fails
241
+ # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
122
242
  #
123
- # # Tests a route, providing a defaults hash
124
- # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
243
+ # # Tests a route, providing a defaults hash
244
+ # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
125
245
  #
126
- # # Tests a route with an HTTP method
127
- # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
246
+ # # Tests a route with an HTTP method
247
+ # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
128
248
  def assert_routing(path, options, defaults = {}, extras = {}, message = nil)
129
249
  assert_recognizes(options, path, extras, message)
130
250
 
@@ -137,59 +257,47 @@ module ActionDispatch
137
257
  assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message)
138
258
  end
139
259
 
140
- # A helper to make it easier to test different route configurations.
141
- # This method temporarily replaces @routes with a new RouteSet instance.
142
- #
143
- # The new instance is yielded to the passed block. Typically the block
144
- # will create some routes using <tt>set.draw { match ... }</tt>:
145
- #
146
- # with_routing do |set|
147
- # set.draw do
148
- # resources :users
149
- # end
150
- # assert_equal "/users", users_path
151
- # end
152
- #
153
- def with_routing
154
- old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
155
- if defined?(@controller) && @controller
156
- old_controller, @controller = @controller, @controller.clone
157
- _routes = @routes
260
+ # ROUTES TODO: These assertions should really work in an integration context
261
+ def method_missing(selector, ...)
262
+ if @controller && @routes&.named_routes&.route_defined?(selector)
263
+ @controller.public_send(selector, ...)
264
+ else
265
+ super
266
+ end
267
+ end
158
268
 
159
- @controller.singleton_class.include(_routes.url_helpers)
269
+ private
270
+ def create_routes
271
+ @routes = ActionDispatch::Routing::RouteSet.new
272
+ if @controller
273
+ @controller = @controller.clone
274
+ _routes = @routes
160
275
 
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
276
+ @controller.singleton_class.include(_routes.url_helpers)
165
277
 
166
- custom_view_context = Module.new {
167
- define_method(:view_context_class) do
168
- view_context_class
278
+ if @controller.respond_to? :view_context_class
279
+ view_context_class = Class.new(@controller.view_context_class) do
280
+ include _routes.url_helpers
169
281
  end
170
- }
171
- @controller.extend(custom_view_context)
282
+
283
+ custom_view_context = Module.new {
284
+ define_method(:view_context_class) do
285
+ view_context_class
286
+ end
287
+ }
288
+ @controller.extend(custom_view_context)
289
+ end
172
290
  end
291
+ yield @routes
173
292
  end
174
- yield @routes
175
- ensure
176
- @routes = old_routes
177
- if defined?(@controller) && @controller
178
- @controller = old_controller
179
- end
180
- end
181
293
 
182
- # ROUTES TODO: These assertions should really work in an integration context
183
- def method_missing(selector, *args, &block)
184
- if defined?(@controller) && @controller && defined?(@routes) && @routes && @routes.named_routes.route_defined?(selector)
185
- @controller.public_send(selector, *args, &block)
186
- else
187
- super
294
+ def reset_routes(old_routes, old_controller)
295
+ @routes = old_routes
296
+ if @controller
297
+ @controller = old_controller
298
+ end
188
299
  end
189
- end
190
- ruby2_keywords(:method_missing)
191
300
 
192
- private
193
301
  # Recognizes the route for a given path.
194
302
  def recognized_request_for(path, extras = {}, msg)
195
303
  if path.is_a?(Hash)
@@ -202,7 +310,7 @@ module ActionDispatch
202
310
  controller = @controller if defined?(@controller)
203
311
  request = ActionController::TestRequest.create controller&.class
204
312
 
205
- if %r{://}.match?(path)
313
+ if path.include?("://")
206
314
  fail_on(URI::InvalidURIError, msg) do
207
315
  uri = URI.parse(path)
208
316
  request.env["rack.url_scheme"] = uri.scheme || "http"
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "rails-dom-testing"
4
6
  require "action_dispatch/testing/assertions/response"
5
7
  require "action_dispatch/testing/assertions/routing"
6
8
 
7
9
  module ActionDispatch
8
10
  module Assertions
11
+ extend ActiveSupport::Concern
12
+
9
13
  include ResponseAssertions
10
14
  include RoutingAssertions
11
15
  include Rails::Dom::Testing::Assertions
@@ -14,7 +18,7 @@ module ActionDispatch
14
18
  @html_document ||= if @response.media_type&.end_with?("xml")
15
19
  Nokogiri::XML::Document.parse(@response.body)
16
20
  else
17
- Nokogiri::HTML::Document.parse(@response.body)
21
+ Rails::Dom::Testing.html_document.parse(@response.body)
18
22
  end
19
23
  end
20
24
  end