actionpack 4.2.11.1 → 6.1.3.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 +291 -489
- data/MIT-LICENSE +1 -1
- data/README.rdoc +9 -9
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +81 -51
- data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/callbacks.rb +61 -33
- data/lib/abstract_controller/collector.rb +9 -13
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +115 -99
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
- data/lib/abstract_controller/rendering.rb +48 -47
- data/lib/abstract_controller/translation.rb +17 -8
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +13 -5
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/base.rb +29 -24
- data/lib/action_controller/caching.rb +12 -57
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +17 -19
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +134 -46
- data/lib/action_controller/metal/content_security_policy.rb +51 -0
- data/lib/action_controller/metal/cookies.rb +6 -4
- data/lib/action_controller/metal/data_streaming.rb +30 -50
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
- data/lib/action_controller/metal/exceptions.rb +63 -15
- data/lib/action_controller/metal/flash.rb +9 -8
- data/lib/action_controller/metal/head.rb +26 -21
- data/lib/action_controller/metal/helpers.rb +37 -18
- data/lib/action_controller/metal/http_authentication.rb +81 -73
- data/lib/action_controller/metal/implicit_render.rb +53 -9
- data/lib/action_controller/metal/instrumentation.rb +32 -35
- data/lib/action_controller/metal/live.rb +102 -120
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +49 -47
- data/lib/action_controller/metal/parameter_encoding.rb +82 -0
- data/lib/action_controller/metal/params_wrapper.rb +83 -66
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +53 -32
- data/lib/action_controller/metal/renderers.rb +87 -44
- data/lib/action_controller/metal/rendering.rb +77 -50
- data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
- data/lib/action_controller/metal/rescue.rb +10 -17
- data/lib/action_controller/metal/streaming.rb +12 -11
- data/lib/action_controller/metal/strong_parameters.rb +714 -186
- data/lib/action_controller/metal/testing.rb +2 -17
- data/lib/action_controller/metal/url_for.rb +19 -10
- data/lib/action_controller/metal.rb +104 -87
- data/lib/action_controller/railtie.rb +28 -10
- data/lib/action_controller/railties/helpers.rb +3 -1
- data/lib/action_controller/renderer.rb +141 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +296 -422
- data/lib/action_controller.rb +34 -23
- data/lib/action_dispatch/http/cache.rb +107 -56
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +286 -0
- data/lib/action_dispatch/http/filter_parameters.rb +32 -25
- data/lib/action_dispatch/http/filter_redirect.rb +10 -12
- data/lib/action_dispatch/http/headers.rb +55 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
- data/lib/action_dispatch/http/mime_type.rb +153 -121
- data/lib/action_dispatch/http/mime_types.rb +20 -6
- data/lib/action_dispatch/http/parameters.rb +90 -40
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +226 -121
- data/lib/action_dispatch/http/response.rb +248 -113
- data/lib/action_dispatch/http/upload.rb +21 -7
- data/lib/action_dispatch/http/url.rb +182 -100
- data/lib/action_dispatch/journey/formatter.rb +90 -43
- data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
- data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
- data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
- data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
- data/lib/action_dispatch/journey/nodes/node.rb +29 -15
- data/lib/action_dispatch/journey/parser.rb +17 -16
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +12 -4
- data/lib/action_dispatch/journey/path/pattern.rb +58 -54
- data/lib/action_dispatch/journey/route.rb +100 -32
- data/lib/action_dispatch/journey/router/utils.rb +29 -18
- data/lib/action_dispatch/journey/router.rb +55 -51
- data/lib/action_dispatch/journey/routes.rb +17 -17
- data/lib/action_dispatch/journey/scanner.rb +26 -17
- data/lib/action_dispatch/journey/visitors.rb +98 -54
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +3 -6
- data/lib/action_dispatch/middleware/cookies.rb +347 -217
- data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +78 -54
- data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
- data/lib/action_dispatch/middleware/reloader.rb +5 -91
- data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
- data/lib/action_dispatch/middleware/request_id.rb +17 -10
- data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
- data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
- data/lib/action_dispatch/middleware/ssl.rb +118 -35
- data/lib/action_dispatch/middleware/stack.rb +82 -41
- data/lib/action_dispatch/middleware/static.rb +156 -89
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.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 +87 -64
- data/lib/action_dispatch/railtie.rb +27 -13
- data/lib/action_dispatch/request/session.rb +109 -61
- data/lib/action_dispatch/request/utils.rb +90 -23
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +141 -102
- data/lib/action_dispatch/routing/mapper.rb +811 -473
- data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
- data/lib/action_dispatch/routing/redirection.rb +37 -27
- data/lib/action_dispatch/routing/route_set.rb +363 -331
- data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
- data/lib/action_dispatch/routing/url_for.rb +66 -26
- data/lib/action_dispatch/routing.rb +36 -36
- data/lib/action_dispatch/system_test_case.rb +190 -0
- data/lib/action_dispatch/system_testing/browser.rb +86 -0
- data/lib/action_dispatch/system_testing/driver.rb +67 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
- data/lib/action_dispatch/testing/assertion_response.rb +46 -0
- data/lib/action_dispatch/testing/assertions/response.rb +44 -22
- data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
- data/lib/action_dispatch/testing/assertions.rb +6 -4
- data/lib/action_dispatch/testing/integration.rb +391 -220
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +53 -22
- data/lib/action_dispatch/testing/test_request.rb +27 -34
- data/lib/action_dispatch/testing/test_response.rb +11 -11
- data/lib/action_dispatch.rb +35 -21
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +4 -2
- metadata +78 -48
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- 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/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- 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
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/array/extract_options"
|
2
4
|
|
3
5
|
module ActionDispatch
|
4
6
|
module Routing
|
@@ -8,9 +10,10 @@ module ActionDispatch
|
|
8
10
|
attr_accessor :scope, :routes
|
9
11
|
alias :_routes :routes
|
10
12
|
|
11
|
-
def initialize(routes, scope, helpers)
|
13
|
+
def initialize(routes, scope, helpers, script_namer = nil)
|
12
14
|
@routes, @scope = routes, scope
|
13
15
|
@helpers = helpers
|
16
|
+
@script_namer = script_namer
|
14
17
|
end
|
15
18
|
|
16
19
|
def url_options
|
@@ -19,7 +22,8 @@ module ActionDispatch
|
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
22
|
-
|
25
|
+
private
|
26
|
+
def respond_to_missing?(method, _)
|
23
27
|
super || @helpers.respond_to?(method)
|
24
28
|
end
|
25
29
|
|
@@ -28,15 +32,38 @@ module ActionDispatch
|
|
28
32
|
self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
29
33
|
def #{method}(*args)
|
30
34
|
options = args.extract_options!
|
31
|
-
|
35
|
+
options = url_options.merge((options || {}).symbolize_keys)
|
36
|
+
|
37
|
+
if @script_namer
|
38
|
+
options[:script_name] = merge_script_names(
|
39
|
+
options[:script_name],
|
40
|
+
@script_namer.call(options)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
args << options
|
32
45
|
@helpers.#{method}(*args)
|
33
46
|
end
|
34
47
|
RUBY
|
35
|
-
|
48
|
+
public_send(method, *args)
|
36
49
|
else
|
37
50
|
super
|
38
51
|
end
|
39
52
|
end
|
53
|
+
|
54
|
+
# Keeps the part of the script name provided by the global
|
55
|
+
# context via ENV["SCRIPT_NAME"], which `mount` doesn't know
|
56
|
+
# about since it depends on the specific request, but use our
|
57
|
+
# script name resolver for the mount point dependent part.
|
58
|
+
def merge_script_names(previous_script_name, new_script_name)
|
59
|
+
return new_script_name unless previous_script_name
|
60
|
+
|
61
|
+
resolved_parts = new_script_name.count("/")
|
62
|
+
previous_parts = previous_script_name.count("/")
|
63
|
+
context_parts = previous_parts - resolved_parts + 1
|
64
|
+
|
65
|
+
(previous_script_name.split("/").slice(0, context_parts).join("/")) + new_script_name
|
66
|
+
end
|
40
67
|
end
|
41
68
|
end
|
42
69
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionDispatch
|
2
4
|
module Routing
|
3
5
|
# In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
|
4
|
-
# is also possible:
|
6
|
+
# is also possible: a URL can be generated from one of your routing definitions.
|
5
7
|
# URL generation functionality is centralized in this module.
|
6
8
|
#
|
7
9
|
# See ActionDispatch::Routing for general information about routing and routes.rb.
|
@@ -52,9 +54,11 @@ module ActionDispatch
|
|
52
54
|
# argument.
|
53
55
|
#
|
54
56
|
# 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
|
-
#
|
57
|
+
# So within mailers, you only have to type +url_for+ instead of 'ActionController::UrlFor#url_for'
|
58
|
+
# in full. However, mailers don't have hostname information, and you still have to provide
|
59
|
+
# the +:host+ argument or set the default host that will be used in all mailers using the
|
60
|
+
# configuration option +config.action_mailer.default_url_options+. For more information on
|
61
|
+
# url_for in mailers read the ActionMailer#Base documentation.
|
58
62
|
#
|
59
63
|
#
|
60
64
|
# == URL generation for named routes
|
@@ -103,18 +107,19 @@ module ActionDispatch
|
|
103
107
|
@_routes = nil
|
104
108
|
super
|
105
109
|
end
|
110
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
106
111
|
|
107
112
|
# Hook overridden in controller to add request information
|
108
|
-
# with
|
113
|
+
# with +default_url_options+. Application logic should not
|
109
114
|
# go into url_options.
|
110
115
|
def url_options
|
111
116
|
default_url_options
|
112
117
|
end
|
113
118
|
|
114
|
-
# Generate a
|
119
|
+
# Generate a URL based on the options provided, default_url_options and the
|
115
120
|
# routes defined in routes.rb. The following options are supported:
|
116
121
|
#
|
117
|
-
# * <tt>:only_path</tt> - If true, the relative
|
122
|
+
# * <tt>:only_path</tt> - If true, the relative URL is returned. Defaults to +false+.
|
118
123
|
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
|
119
124
|
# * <tt>:host</tt> - Specifies the host the link should be targeted at.
|
120
125
|
# If <tt>:only_path</tt> is false, this option must be
|
@@ -129,6 +134,7 @@ module ActionDispatch
|
|
129
134
|
# <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1.
|
130
135
|
# * <tt>:port</tt> - Optionally specify the port to connect to.
|
131
136
|
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
|
137
|
+
# * <tt>:params</tt> - The query parameters to be appended to the path.
|
132
138
|
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
|
133
139
|
# * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
|
134
140
|
#
|
@@ -147,14 +153,32 @@ module ActionDispatch
|
|
147
153
|
# # => 'http://somehost.org/myapp/tasks/testing'
|
148
154
|
# url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
|
149
155
|
# # => '/myapp/tasks/testing'
|
156
|
+
#
|
157
|
+
# Missing routes keys may be filled in from the current request's parameters
|
158
|
+
# (e.g. +:controller+, +:action+, +:id+ and any other parameters that are
|
159
|
+
# placed in the path). Given that the current action has been reached
|
160
|
+
# through <tt>GET /users/1</tt>:
|
161
|
+
#
|
162
|
+
# url_for(only_path: true) # => '/users/1'
|
163
|
+
# url_for(only_path: true, action: 'edit') # => '/users/1/edit'
|
164
|
+
# url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit'
|
165
|
+
#
|
166
|
+
# Notice that no +:id+ parameter was provided to the first +url_for+ call
|
167
|
+
# and the helper used the one from the route's path. Any path parameter
|
168
|
+
# implicitly used by +url_for+ can always be overwritten like shown on the
|
169
|
+
# last +url_for+ calls.
|
150
170
|
def url_for(options = nil)
|
171
|
+
full_url_for(options)
|
172
|
+
end
|
173
|
+
|
174
|
+
def full_url_for(options = nil) # :nodoc:
|
151
175
|
case options
|
152
176
|
when nil
|
153
177
|
_routes.url_for(url_options.symbolize_keys)
|
154
|
-
when Hash
|
178
|
+
when Hash, ActionController::Parameters
|
155
179
|
route_name = options.delete :use_route
|
156
|
-
|
157
|
-
|
180
|
+
merged_url_options = options.to_h.symbolize_keys.reverse_merge!(url_options)
|
181
|
+
_routes.url_for(merged_url_options, route_name)
|
158
182
|
when String
|
159
183
|
options
|
160
184
|
when Symbol
|
@@ -169,27 +193,43 @@ module ActionDispatch
|
|
169
193
|
end
|
170
194
|
end
|
171
195
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
196
|
+
# Allows calling direct or regular named route.
|
197
|
+
#
|
198
|
+
# resources :buckets
|
199
|
+
#
|
200
|
+
# direct :recordable do |recording|
|
201
|
+
# route_for(:bucket, recording.bucket)
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# direct :threadable do |threadable|
|
205
|
+
# route_for(:recordable, threadable.parent)
|
206
|
+
# end
|
207
|
+
#
|
208
|
+
# This maintains the context of the original caller on
|
209
|
+
# whether to return a path or full URL, e.g:
|
210
|
+
#
|
211
|
+
# threadable_path(threadable) # => "/buckets/1"
|
212
|
+
# threadable_url(threadable) # => "http://example.com/buckets/1"
|
213
|
+
#
|
214
|
+
def route_for(name, *args)
|
215
|
+
public_send(:"#{name}_url", *args)
|
183
216
|
end
|
184
217
|
|
185
|
-
|
186
|
-
|
187
|
-
|
218
|
+
protected
|
219
|
+
def optimize_routes_generation?
|
220
|
+
_routes.optimize_routes_generation? && default_url_options.empty?
|
221
|
+
end
|
188
222
|
|
189
223
|
private
|
224
|
+
def _with_routes(routes) # :doc:
|
225
|
+
old_routes, @_routes = @_routes, routes
|
226
|
+
yield
|
227
|
+
ensure
|
228
|
+
@_routes = old_routes
|
229
|
+
end
|
190
230
|
|
191
|
-
def
|
192
|
-
|
231
|
+
def _routes_context # :doc:
|
232
|
+
self
|
193
233
|
end
|
194
234
|
end
|
195
235
|
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'active_support/dependencies/autoload'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/filters"
|
5
4
|
|
6
5
|
module ActionDispatch
|
7
6
|
# The routing module provides URL rewriting in native Ruby. It's a way to
|
@@ -58,7 +57,7 @@ module ActionDispatch
|
|
58
57
|
# resources :posts, :comments
|
59
58
|
# end
|
60
59
|
#
|
61
|
-
#
|
60
|
+
# Alternatively, you can add prefixes to your path without using a separate
|
62
61
|
# directory by using +scope+. +scope+ takes additional options which
|
63
62
|
# apply to all enclosed routes.
|
64
63
|
#
|
@@ -75,16 +74,16 @@ module ActionDispatch
|
|
75
74
|
# For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
|
76
75
|
# methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
|
77
76
|
#
|
78
|
-
# get 'post/:id'
|
79
|
-
# post 'post/:id'
|
77
|
+
# get 'post/:id', to: 'posts#show'
|
78
|
+
# post 'post/:id', to: 'posts#create_comment'
|
79
|
+
#
|
80
|
+
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
|
81
|
+
# URL will route to the <tt>show</tt> action.
|
80
82
|
#
|
81
83
|
# If your route needs to respond to more than one HTTP method (or all methods) then using the
|
82
84
|
# <tt>:via</tt> option on <tt>match</tt> is preferable.
|
83
85
|
#
|
84
|
-
# match 'post/:id'
|
85
|
-
#
|
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.
|
86
|
+
# match 'post/:id', to: 'posts#show', via: [:get, :post]
|
88
87
|
#
|
89
88
|
# == Named routes
|
90
89
|
#
|
@@ -94,8 +93,8 @@ module ActionDispatch
|
|
94
93
|
#
|
95
94
|
# Example:
|
96
95
|
#
|
97
|
-
# # In routes.rb
|
98
|
-
# get '/login'
|
96
|
+
# # In config/routes.rb
|
97
|
+
# get '/login', to: 'accounts#login', as: 'login'
|
99
98
|
#
|
100
99
|
# # With render, redirect_to, tests, etc.
|
101
100
|
# redirect_to login_url
|
@@ -106,7 +105,7 @@ module ActionDispatch
|
|
106
105
|
#
|
107
106
|
# Use <tt>root</tt> as a shorthand to name a route for the root path "/".
|
108
107
|
#
|
109
|
-
# # In routes.rb
|
108
|
+
# # In config/routes.rb
|
110
109
|
# root to: 'blogs#index'
|
111
110
|
#
|
112
111
|
# # would recognize http://www.example.com/ as
|
@@ -119,21 +118,21 @@ module ActionDispatch
|
|
119
118
|
# Note: when using +controller+, the route is simply named after the
|
120
119
|
# method you call on the block parameter rather than map.
|
121
120
|
#
|
122
|
-
# # In routes.rb
|
121
|
+
# # In config/routes.rb
|
123
122
|
# controller :blog do
|
124
|
-
# get 'blog/show'
|
125
|
-
# get 'blog/delete'
|
126
|
-
# get 'blog/edit
|
123
|
+
# get 'blog/show', to: :list
|
124
|
+
# get 'blog/delete', to: :delete
|
125
|
+
# get 'blog/edit', to: :edit
|
127
126
|
# end
|
128
127
|
#
|
129
128
|
# # provides named routes for show, delete, and edit
|
130
|
-
# link_to @article.title,
|
129
|
+
# link_to @article.title, blog_show_path(id: @article.id)
|
131
130
|
#
|
132
131
|
# == Pretty URLs
|
133
132
|
#
|
134
133
|
# Routes can generate pretty URLs. For example:
|
135
134
|
#
|
136
|
-
# get '/articles/:year/:month/:day'
|
135
|
+
# get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
|
137
136
|
# year: /\d{4}/,
|
138
137
|
# month: /\d{1,2}/,
|
139
138
|
# day: /\d{1,2}/
|
@@ -148,22 +147,23 @@ module ActionDispatch
|
|
148
147
|
# You can specify a regular expression to define a format for a parameter.
|
149
148
|
#
|
150
149
|
# controller 'geocode' do
|
151
|
-
# get 'geocode/:postalcode'
|
150
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
152
151
|
# postalcode: /\d{5}(-\d{4})?/
|
153
152
|
# }
|
153
|
+
# end
|
154
154
|
#
|
155
155
|
# Constraints can include the 'ignorecase' and 'extended syntax' regular
|
156
156
|
# expression modifiers:
|
157
157
|
#
|
158
158
|
# controller 'geocode' do
|
159
|
-
# get 'geocode/:postalcode'
|
159
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
160
160
|
# postalcode: /hx\d\d\s\d[a-z]{2}/i
|
161
161
|
# }
|
162
162
|
# end
|
163
163
|
#
|
164
164
|
# controller 'geocode' do
|
165
|
-
# get 'geocode/:postalcode'
|
166
|
-
# postalcode: /#
|
165
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
166
|
+
# postalcode: /# Postalcode format
|
167
167
|
# \d{5} #Prefix
|
168
168
|
# (-\d{4})? #Suffix
|
169
169
|
# /x
|
@@ -178,13 +178,13 @@ module ActionDispatch
|
|
178
178
|
#
|
179
179
|
# You can redirect any path to another path using the redirect helper in your router:
|
180
180
|
#
|
181
|
-
# get "/stories"
|
181
|
+
# get "/stories", to: redirect("/posts")
|
182
182
|
#
|
183
183
|
# == Unicode character routes
|
184
184
|
#
|
185
185
|
# You can specify unicode character routes in your router:
|
186
186
|
#
|
187
|
-
# get "こんにちは"
|
187
|
+
# get "こんにちは", to: "welcome#index"
|
188
188
|
#
|
189
189
|
# == Routing to Rack Applications
|
190
190
|
#
|
@@ -192,7 +192,7 @@ module ActionDispatch
|
|
192
192
|
# index action in the PostsController, you can specify any Rack application
|
193
193
|
# as the endpoint for a matcher:
|
194
194
|
#
|
195
|
-
# get "/application.js"
|
195
|
+
# get "/application.js", to: Sprockets
|
196
196
|
#
|
197
197
|
# == Reloading routes
|
198
198
|
#
|
@@ -200,7 +200,7 @@ module ActionDispatch
|
|
200
200
|
#
|
201
201
|
# Rails.application.reload_routes!
|
202
202
|
#
|
203
|
-
# This will clear all named routes and reload routes.rb if the file has been modified from
|
203
|
+
# This will clear all named routes and reload config/routes.rb if the file has been modified from
|
204
204
|
# last load. To absolutely force reloading, use <tt>reload!</tt>.
|
205
205
|
#
|
206
206
|
# == Testing Routes
|
@@ -210,8 +210,8 @@ module ActionDispatch
|
|
210
210
|
# === +assert_routing+
|
211
211
|
#
|
212
212
|
# def test_movie_route_properly_splits
|
213
|
-
#
|
214
|
-
#
|
213
|
+
# opts = {controller: "plugin", action: "checkout", id: "2"}
|
214
|
+
# assert_routing "plugin/checkout/2", opts
|
215
215
|
# end
|
216
216
|
#
|
217
217
|
# +assert_routing+ lets you test whether or not the route properly resolves into options.
|
@@ -219,8 +219,8 @@ module ActionDispatch
|
|
219
219
|
# === +assert_recognizes+
|
220
220
|
#
|
221
221
|
# def test_route_has_options
|
222
|
-
#
|
223
|
-
#
|
222
|
+
# opts = {controller: "plugin", action: "show", id: "12"}
|
223
|
+
# assert_recognizes opts, "/plugins/show/12"
|
224
224
|
# end
|
225
225
|
#
|
226
226
|
# Note the subtle difference between the two: +assert_routing+ tests that
|
@@ -232,7 +232,6 @@ module ActionDispatch
|
|
232
232
|
# def send_to_jail
|
233
233
|
# get '/jail'
|
234
234
|
# assert_response :success
|
235
|
-
# assert_template "jail/front"
|
236
235
|
# end
|
237
236
|
#
|
238
237
|
# def goes_to_login
|
@@ -242,10 +241,11 @@ module ActionDispatch
|
|
242
241
|
#
|
243
242
|
# == View a list of all your routes
|
244
243
|
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
# Target specific controllers by prefixing the command with <tt>CONTROLLER=x</tt>.
|
244
|
+
# rails routes
|
248
245
|
#
|
246
|
+
# Target a specific controller with <tt>-c</tt>, or grep routes
|
247
|
+
# using <tt>-g</tt>. Useful in conjunction with <tt>--expanded</tt>
|
248
|
+
# which displays routes vertically.
|
249
249
|
module Routing
|
250
250
|
extend ActiveSupport::Autoload
|
251
251
|
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
gem "capybara", ">= 3.26"
|
4
|
+
|
5
|
+
require "capybara/dsl"
|
6
|
+
require "capybara/minitest"
|
7
|
+
require "action_controller"
|
8
|
+
require "action_dispatch/system_testing/driver"
|
9
|
+
require "action_dispatch/system_testing/browser"
|
10
|
+
require "action_dispatch/system_testing/server"
|
11
|
+
require "action_dispatch/system_testing/test_helpers/screenshot_helper"
|
12
|
+
require "action_dispatch/system_testing/test_helpers/setup_and_teardown"
|
13
|
+
|
14
|
+
module ActionDispatch
|
15
|
+
# = System Testing
|
16
|
+
#
|
17
|
+
# System tests let you test applications in the browser. Because system
|
18
|
+
# tests use a real browser experience, you can test all of your JavaScript
|
19
|
+
# easily from your test suite.
|
20
|
+
#
|
21
|
+
# To create a system test in your application, extend your test class
|
22
|
+
# from <tt>ApplicationSystemTestCase</tt>. System tests use Capybara as a
|
23
|
+
# base and allow you to configure the settings through your
|
24
|
+
# <tt>application_system_test_case.rb</tt> file that is generated with a new
|
25
|
+
# application or scaffold.
|
26
|
+
#
|
27
|
+
# Here is an example system test:
|
28
|
+
#
|
29
|
+
# require "application_system_test_case"
|
30
|
+
#
|
31
|
+
# class Users::CreateTest < ApplicationSystemTestCase
|
32
|
+
# test "adding a new user" do
|
33
|
+
# visit users_path
|
34
|
+
# click_on 'New User'
|
35
|
+
#
|
36
|
+
# fill_in 'Name', with: 'Arya'
|
37
|
+
# click_on 'Create User'
|
38
|
+
#
|
39
|
+
# assert_text 'Arya'
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# When generating an application or scaffold, an +application_system_test_case.rb+
|
44
|
+
# file will also be generated containing the base class for system testing.
|
45
|
+
# This is where you can change the driver, add Capybara settings, and other
|
46
|
+
# configuration for your system tests.
|
47
|
+
#
|
48
|
+
# require "test_helper"
|
49
|
+
#
|
50
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
51
|
+
# driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# By default, <tt>ActionDispatch::SystemTestCase</tt> is driven by the
|
55
|
+
# Selenium driver, with the Chrome browser, and a browser size of 1400x1400.
|
56
|
+
#
|
57
|
+
# Changing the driver configuration options is easy. Let's say you want to use
|
58
|
+
# the Firefox browser instead of Chrome. In your +application_system_test_case.rb+
|
59
|
+
# file add the following:
|
60
|
+
#
|
61
|
+
# require "test_helper"
|
62
|
+
#
|
63
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
64
|
+
# driven_by :selenium, using: :firefox
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# +driven_by+ has a required argument for the driver name. The keyword
|
68
|
+
# arguments are +:using+ for the browser and +:screen_size+ to change the
|
69
|
+
# size of the browser screen. These two options are not applicable for
|
70
|
+
# headless drivers and will be silently ignored if passed.
|
71
|
+
#
|
72
|
+
# Headless browsers such as headless Chrome and headless Firefox are also supported.
|
73
|
+
# You can use these browsers by setting the +:using+ argument to +:headless_chrome+ or +:headless_firefox+.
|
74
|
+
#
|
75
|
+
# To use a headless driver, like Poltergeist, update your Gemfile to use
|
76
|
+
# Poltergeist instead of Selenium and then declare the driver name in the
|
77
|
+
# +application_system_test_case.rb+ file. In this case, you would leave out
|
78
|
+
# the +:using+ option because the driver is headless, but you can still use
|
79
|
+
# +:screen_size+ to change the size of the browser screen, also you can use
|
80
|
+
# +:options+ to pass options supported by the driver. Please refer to your
|
81
|
+
# driver documentation to learn about supported options.
|
82
|
+
#
|
83
|
+
# require "test_helper"
|
84
|
+
# require "capybara/poltergeist"
|
85
|
+
#
|
86
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
87
|
+
# driven_by :poltergeist, screen_size: [1400, 1400], options:
|
88
|
+
# { js_errors: true }
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# Some drivers require browser capabilities to be passed as a block instead
|
92
|
+
# of through the +options+ hash.
|
93
|
+
#
|
94
|
+
# As an example, if you want to add mobile emulation on chrome, you'll have to
|
95
|
+
# create an instance of selenium's +Chrome::Options+ object and add
|
96
|
+
# capabilities with a block.
|
97
|
+
#
|
98
|
+
# The block will be passed an instance of <tt><Driver>::Options</tt> where you can
|
99
|
+
# define the capabilities you want. Please refer to your driver documentation
|
100
|
+
# to learn about supported options.
|
101
|
+
#
|
102
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
103
|
+
# driven_by :selenium, using: :chrome, screen_size: [1024, 768] do |driver_option|
|
104
|
+
# driver_option.add_emulation(device_name: 'iPhone 6')
|
105
|
+
# driver_option.add_extension('path/to/chrome_extension.crx')
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# Because <tt>ActionDispatch::SystemTestCase</tt> is a shim between Capybara
|
110
|
+
# and Rails, any driver that is supported by Capybara is supported by system
|
111
|
+
# tests as long as you include the required gems and files.
|
112
|
+
class SystemTestCase < ActiveSupport::TestCase
|
113
|
+
include Capybara::DSL
|
114
|
+
include Capybara::Minitest::Assertions
|
115
|
+
include SystemTesting::TestHelpers::SetupAndTeardown
|
116
|
+
include SystemTesting::TestHelpers::ScreenshotHelper
|
117
|
+
|
118
|
+
def initialize(*) # :nodoc:
|
119
|
+
super
|
120
|
+
self.class.driven_by(:selenium) unless self.class.driver?
|
121
|
+
self.class.driver.use
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.start_application # :nodoc:
|
125
|
+
Capybara.app = Rack::Builder.new do
|
126
|
+
map "/" do
|
127
|
+
run Rails.application
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
SystemTesting::Server.new.run
|
132
|
+
end
|
133
|
+
|
134
|
+
class_attribute :driver, instance_accessor: false
|
135
|
+
|
136
|
+
# System Test configuration options
|
137
|
+
#
|
138
|
+
# The default settings are Selenium, using Chrome, with a screen size
|
139
|
+
# of 1400x1400.
|
140
|
+
#
|
141
|
+
# Examples:
|
142
|
+
#
|
143
|
+
# driven_by :poltergeist
|
144
|
+
#
|
145
|
+
# driven_by :selenium, screen_size: [800, 800]
|
146
|
+
#
|
147
|
+
# driven_by :selenium, using: :chrome
|
148
|
+
#
|
149
|
+
# driven_by :selenium, using: :headless_chrome
|
150
|
+
#
|
151
|
+
# driven_by :selenium, using: :firefox
|
152
|
+
#
|
153
|
+
# driven_by :selenium, using: :headless_firefox
|
154
|
+
def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
|
155
|
+
driver_options = { using: using, screen_size: screen_size, options: options }
|
156
|
+
|
157
|
+
self.driver = SystemTesting::Driver.new(driver, **driver_options, &capabilities)
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
def url_helpers
|
162
|
+
@url_helpers ||=
|
163
|
+
if ActionDispatch.test_app
|
164
|
+
Class.new do
|
165
|
+
include ActionDispatch.test_app.routes.url_helpers
|
166
|
+
include ActionDispatch.test_app.routes.mounted_helpers
|
167
|
+
|
168
|
+
def url_options
|
169
|
+
default_url_options.reverse_merge(host: Capybara.app_host || Capybara.current_session.server_url)
|
170
|
+
end
|
171
|
+
end.new
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def method_missing(name, *args, &block)
|
176
|
+
if url_helpers.respond_to?(name)
|
177
|
+
url_helpers.public_send(name, *args, &block)
|
178
|
+
else
|
179
|
+
super
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def respond_to_missing?(name, include_private = false)
|
184
|
+
url_helpers.respond_to?(name)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
ActiveSupport.run_load_hooks :action_dispatch_system_test_case, ActionDispatch::SystemTestCase
|
190
|
+
ActionDispatch::SystemTestCase.start_application
|