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.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +291 -489
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +81 -51
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +61 -33
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +115 -99
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +21 -3
  15. data/lib/abstract_controller/rendering.rb +48 -47
  16. data/lib/abstract_controller/translation.rb +17 -8
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +13 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +29 -24
  22. data/lib/action_controller/caching.rb +12 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +17 -19
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +134 -46
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +6 -4
  29. data/lib/action_controller/metal/data_streaming.rb +30 -50
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +21 -16
  33. data/lib/action_controller/metal/exceptions.rb +63 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/head.rb +26 -21
  36. data/lib/action_controller/metal/helpers.rb +37 -18
  37. data/lib/action_controller/metal/http_authentication.rb +81 -73
  38. data/lib/action_controller/metal/implicit_render.rb +53 -9
  39. data/lib/action_controller/metal/instrumentation.rb +32 -35
  40. data/lib/action_controller/metal/live.rb +102 -120
  41. data/lib/action_controller/metal/logging.rb +20 -0
  42. data/lib/action_controller/metal/mime_responds.rb +49 -47
  43. data/lib/action_controller/metal/parameter_encoding.rb +82 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +83 -66
  45. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  46. data/lib/action_controller/metal/redirecting.rb +53 -32
  47. data/lib/action_controller/metal/renderers.rb +87 -44
  48. data/lib/action_controller/metal/rendering.rb +77 -50
  49. data/lib/action_controller/metal/request_forgery_protection.rb +267 -103
  50. data/lib/action_controller/metal/rescue.rb +10 -17
  51. data/lib/action_controller/metal/streaming.rb +12 -11
  52. data/lib/action_controller/metal/strong_parameters.rb +714 -186
  53. data/lib/action_controller/metal/testing.rb +2 -17
  54. data/lib/action_controller/metal/url_for.rb +19 -10
  55. data/lib/action_controller/metal.rb +104 -87
  56. data/lib/action_controller/railtie.rb +28 -10
  57. data/lib/action_controller/railties/helpers.rb +3 -1
  58. data/lib/action_controller/renderer.rb +141 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +296 -422
  61. data/lib/action_controller.rb +34 -23
  62. data/lib/action_dispatch/http/cache.rb +107 -56
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +286 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +32 -25
  66. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  67. data/lib/action_dispatch/http/headers.rb +55 -22
  68. data/lib/action_dispatch/http/mime_negotiation.rb +79 -51
  69. data/lib/action_dispatch/http/mime_type.rb +153 -121
  70. data/lib/action_dispatch/http/mime_types.rb +20 -6
  71. data/lib/action_dispatch/http/parameters.rb +90 -40
  72. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  74. data/lib/action_dispatch/http/request.rb +226 -121
  75. data/lib/action_dispatch/http/response.rb +248 -113
  76. data/lib/action_dispatch/http/upload.rb +21 -7
  77. data/lib/action_dispatch/http/url.rb +182 -100
  78. data/lib/action_dispatch/journey/formatter.rb +90 -43
  79. data/lib/action_dispatch/journey/gtg/builder.rb +28 -41
  80. data/lib/action_dispatch/journey/gtg/simulator.rb +11 -16
  81. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -21
  82. data/lib/action_dispatch/journey/nfa/dot.rb +3 -14
  83. data/lib/action_dispatch/journey/nodes/node.rb +29 -15
  84. data/lib/action_dispatch/journey/parser.rb +17 -16
  85. data/lib/action_dispatch/journey/parser.y +4 -3
  86. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  87. data/lib/action_dispatch/journey/path/pattern.rb +58 -54
  88. data/lib/action_dispatch/journey/route.rb +100 -32
  89. data/lib/action_dispatch/journey/router/utils.rb +29 -18
  90. data/lib/action_dispatch/journey/router.rb +55 -51
  91. data/lib/action_dispatch/journey/routes.rb +17 -17
  92. data/lib/action_dispatch/journey/scanner.rb +26 -17
  93. data/lib/action_dispatch/journey/visitors.rb +98 -54
  94. data/lib/action_dispatch/journey.rb +5 -5
  95. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  96. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  97. data/lib/action_dispatch/middleware/cookies.rb +347 -217
  98. data/lib/action_dispatch/middleware/debug_exceptions.rb +135 -63
  99. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  100. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  101. data/lib/action_dispatch/middleware/exception_wrapper.rb +115 -71
  102. data/lib/action_dispatch/middleware/executor.rb +21 -0
  103. data/lib/action_dispatch/middleware/flash.rb +78 -54
  104. data/lib/action_dispatch/middleware/host_authorization.rb +130 -0
  105. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  106. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  107. data/lib/action_dispatch/middleware/remote_ip.rb +53 -45
  108. data/lib/action_dispatch/middleware/request_id.rb +17 -10
  109. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  110. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  111. data/lib/action_dispatch/middleware/session/cookie_store.rb +74 -75
  112. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  113. data/lib/action_dispatch/middleware/show_exceptions.rb +28 -23
  114. data/lib/action_dispatch/middleware/ssl.rb +118 -35
  115. data/lib/action_dispatch/middleware/stack.rb +82 -41
  116. data/lib/action_dispatch/middleware/static.rb +156 -89
  117. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  125. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  129. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +105 -8
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  135. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  138. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +87 -64
  141. data/lib/action_dispatch/railtie.rb +27 -13
  142. data/lib/action_dispatch/request/session.rb +109 -61
  143. data/lib/action_dispatch/request/utils.rb +90 -23
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +141 -102
  146. data/lib/action_dispatch/routing/mapper.rb +811 -473
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +167 -143
  148. data/lib/action_dispatch/routing/redirection.rb +37 -27
  149. data/lib/action_dispatch/routing/route_set.rb +363 -331
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +66 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +190 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +86 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +67 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +138 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +29 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -22
  161. data/lib/action_dispatch/testing/assertions/routing.rb +47 -31
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +391 -220
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +53 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +35 -21
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +78 -48
  173. data/lib/action_controller/metal/force_ssl.rb +0 -97
  174. data/lib/action_controller/metal/hide_actions.rb +0 -40
  175. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  176. data/lib/action_controller/middleware.rb +0 -39
  177. data/lib/action_controller/model_naming.rb +0 -12
  178. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  179. data/lib/action_dispatch/journey/backwards.rb +0 -5
  180. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  181. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  182. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  183. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  184. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  185. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  186. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  187. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/array/extract_options'
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
- def respond_to?(method, include_private = false)
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
- args << url_options.merge((options || {}).symbolize_keys)
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
- send(method, *args)
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: an URL can be generated from one of your routing definitions.
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 '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.
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 `default_url_options`. Application logic should not
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 url based on the options provided, default_url_options and the
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 url is returned. Defaults to +false+.
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
- _routes.url_for(options.symbolize_keys.reverse_merge!(url_options),
157
- route_name)
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
- protected
173
-
174
- def optimize_routes_generation?
175
- _routes.optimize_routes_generation? && default_url_options.empty?
176
- end
177
-
178
- def _with_routes(routes)
179
- old_routes, @_routes = @_routes, routes
180
- yield
181
- ensure
182
- @_routes = old_routes
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
- def _routes_context
186
- self
187
- end
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 _generate_paths_by_default
192
- true
231
+ def _routes_context # :doc:
232
+ self
193
233
  end
194
234
  end
195
235
  end
@@ -1,7 +1,6 @@
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'
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
- # Alternately, you can add prefixes to your path without using a separate
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' => 'posts#show'
79
- # post 'post/:id' => 'posts#create_comment'
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' => 'posts#show', via: [:get, :post]
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' => 'accounts#login', as: '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' => :list
125
- # get 'blog/delete' => :delete
126
- # get 'blog/edit/:id' => :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, show_path(id: @article.id)
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' => 'articles#find_by_id', constraints: {
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' => :show, constraints: {
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' => :show, constraints: {
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' => :show, constraints: {
166
- # postalcode: /# Postcode format
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" => redirect("/posts")
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 "こんにちは" => "welcome#index"
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" => Sprockets
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
- # opts = {controller: "plugin", action: "checkout", id: "2"}
214
- # assert_routing "plugin/checkout/2", opts
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
- # opts = {controller: "plugin", action: "show", id: "12"}
223
- # assert_recognizes opts, "/plugins/show/12"
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
- # rake routes
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