actionpack 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +311 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +58 -0
  5. data/lib/abstract_controller.rb +27 -0
  6. data/lib/abstract_controller/asset_paths.rb +12 -0
  7. data/lib/abstract_controller/base.rb +267 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/caching/fragments.rb +150 -0
  10. data/lib/abstract_controller/callbacks.rb +224 -0
  11. data/lib/abstract_controller/collector.rb +43 -0
  12. data/lib/abstract_controller/error.rb +6 -0
  13. data/lib/abstract_controller/helpers.rb +194 -0
  14. data/lib/abstract_controller/logger.rb +14 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
  16. data/lib/abstract_controller/rendering.rb +127 -0
  17. data/lib/abstract_controller/translation.rb +32 -0
  18. data/lib/abstract_controller/url_for.rb +35 -0
  19. data/lib/action_controller.rb +67 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/api/api_rendering.rb +16 -0
  22. data/lib/action_controller/base.rb +271 -0
  23. data/lib/action_controller/caching.rb +46 -0
  24. data/lib/action_controller/form_builder.rb +50 -0
  25. data/lib/action_controller/log_subscriber.rb +81 -0
  26. data/lib/action_controller/metal.rb +256 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  28. data/lib/action_controller/metal/conditional_get.rb +280 -0
  29. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  30. data/lib/action_controller/metal/cookies.rb +16 -0
  31. data/lib/action_controller/metal/data_streaming.rb +151 -0
  32. data/lib/action_controller/metal/default_headers.rb +17 -0
  33. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  35. data/lib/action_controller/metal/exceptions.rb +74 -0
  36. data/lib/action_controller/metal/flash.rb +61 -0
  37. data/lib/action_controller/metal/force_ssl.rb +58 -0
  38. data/lib/action_controller/metal/head.rb +60 -0
  39. data/lib/action_controller/metal/helpers.rb +122 -0
  40. data/lib/action_controller/metal/http_authentication.rb +518 -0
  41. data/lib/action_controller/metal/implicit_render.rb +63 -0
  42. data/lib/action_controller/metal/instrumentation.rb +105 -0
  43. data/lib/action_controller/metal/live.rb +314 -0
  44. data/lib/action_controller/metal/mime_responds.rb +324 -0
  45. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  46. data/lib/action_controller/metal/params_wrapper.rb +297 -0
  47. data/lib/action_controller/metal/redirecting.rb +133 -0
  48. data/lib/action_controller/metal/renderers.rb +181 -0
  49. data/lib/action_controller/metal/rendering.rb +122 -0
  50. data/lib/action_controller/metal/request_forgery_protection.rb +456 -0
  51. data/lib/action_controller/metal/rescue.rb +28 -0
  52. data/lib/action_controller/metal/streaming.rb +223 -0
  53. data/lib/action_controller/metal/strong_parameters.rb +1105 -0
  54. data/lib/action_controller/metal/testing.rb +16 -0
  55. data/lib/action_controller/metal/url_for.rb +58 -0
  56. data/lib/action_controller/railtie.rb +89 -0
  57. data/lib/action_controller/railties/helpers.rb +24 -0
  58. data/lib/action_controller/renderer.rb +130 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +626 -0
  61. data/lib/action_dispatch.rb +114 -0
  62. data/lib/action_dispatch/http/cache.rb +226 -0
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +284 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +86 -0
  66. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  67. data/lib/action_dispatch/http/headers.rb +132 -0
  68. data/lib/action_dispatch/http/mime_negotiation.rb +177 -0
  69. data/lib/action_dispatch/http/mime_type.rb +350 -0
  70. data/lib/action_dispatch/http/mime_types.rb +50 -0
  71. data/lib/action_dispatch/http/parameter_filter.rb +12 -0
  72. data/lib/action_dispatch/http/parameters.rb +136 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +63 -0
  74. data/lib/action_dispatch/http/request.rb +427 -0
  75. data/lib/action_dispatch/http/response.rb +534 -0
  76. data/lib/action_dispatch/http/upload.rb +92 -0
  77. data/lib/action_dispatch/http/url.rb +350 -0
  78. data/lib/action_dispatch/journey.rb +7 -0
  79. data/lib/action_dispatch/journey/formatter.rb +189 -0
  80. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  81. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  82. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  83. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  84. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  85. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  86. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +141 -0
  88. data/lib/action_dispatch/journey/parser.rb +199 -0
  89. data/lib/action_dispatch/journey/parser.y +50 -0
  90. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  91. data/lib/action_dispatch/journey/path/pattern.rb +203 -0
  92. data/lib/action_dispatch/journey/route.rb +204 -0
  93. data/lib/action_dispatch/journey/router.rb +153 -0
  94. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  95. data/lib/action_dispatch/journey/routes.rb +81 -0
  96. data/lib/action_dispatch/journey/scanner.rb +71 -0
  97. data/lib/action_dispatch/journey/visitors.rb +268 -0
  98. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  99. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  100. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
  102. data/lib/action_dispatch/middleware/callbacks.rb +34 -0
  103. data/lib/action_dispatch/middleware/cookies.rb +663 -0
  104. data/lib/action_dispatch/middleware/debug_exceptions.rb +185 -0
  105. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  106. data/lib/action_dispatch/middleware/debug_view.rb +68 -0
  107. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -0
  108. data/lib/action_dispatch/middleware/executor.rb +21 -0
  109. data/lib/action_dispatch/middleware/flash.rb +300 -0
  110. data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
  111. data/lib/action_dispatch/middleware/public_exceptions.rb +61 -0
  112. data/lib/action_dispatch/middleware/reloader.rb +12 -0
  113. data/lib/action_dispatch/middleware/remote_ip.rb +181 -0
  114. data/lib/action_dispatch/middleware/request_id.rb +43 -0
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +113 -0
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
  120. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  121. data/lib/action_dispatch/middleware/stack.rb +148 -0
  122. data/lib/action_dispatch/middleware/static.rb +129 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +24 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +29 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +38 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +165 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  143. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  146. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  147. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  148. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  149. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +203 -0
  150. data/lib/action_dispatch/railtie.rb +58 -0
  151. data/lib/action_dispatch/request/session.rb +242 -0
  152. data/lib/action_dispatch/request/utils.rb +78 -0
  153. data/lib/action_dispatch/routing.rb +261 -0
  154. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  155. data/lib/action_dispatch/routing/inspector.rb +274 -0
  156. data/lib/action_dispatch/routing/mapper.rb +2289 -0
  157. data/lib/action_dispatch/routing/polymorphic_routes.rb +351 -0
  158. data/lib/action_dispatch/routing/redirection.rb +201 -0
  159. data/lib/action_dispatch/routing/route_set.rb +887 -0
  160. data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
  161. data/lib/action_dispatch/routing/url_for.rb +237 -0
  162. data/lib/action_dispatch/system_test_case.rb +168 -0
  163. data/lib/action_dispatch/system_testing/browser.rb +80 -0
  164. data/lib/action_dispatch/system_testing/driver.rb +68 -0
  165. data/lib/action_dispatch/system_testing/server.rb +31 -0
  166. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +97 -0
  167. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +33 -0
  168. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  169. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  170. data/lib/action_dispatch/testing/assertions.rb +24 -0
  171. data/lib/action_dispatch/testing/assertions/response.rb +106 -0
  172. data/lib/action_dispatch/testing/assertions/routing.rb +234 -0
  173. data/lib/action_dispatch/testing/integration.rb +659 -0
  174. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  175. data/lib/action_dispatch/testing/test_process.rb +50 -0
  176. data/lib/action_dispatch/testing/test_request.rb +71 -0
  177. data/lib/action_dispatch/testing/test_response.rb +25 -0
  178. data/lib/action_pack.rb +26 -0
  179. data/lib/action_pack/gem_version.rb +17 -0
  180. data/lib/action_pack/version.rb +10 -0
  181. metadata +329 -0
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/extract_options"
4
+
5
+ module ActionDispatch
6
+ module Routing
7
+ class RoutesProxy #:nodoc:
8
+ include ActionDispatch::Routing::UrlFor
9
+
10
+ attr_accessor :scope, :routes
11
+ alias :_routes :routes
12
+
13
+ def initialize(routes, scope, helpers, script_namer = nil)
14
+ @routes, @scope = routes, scope
15
+ @helpers = helpers
16
+ @script_namer = script_namer
17
+ end
18
+
19
+ def url_options
20
+ scope.send(:_with_routes, routes) do
21
+ scope.url_options
22
+ end
23
+ end
24
+
25
+ private
26
+ def respond_to_missing?(method, _)
27
+ super || @helpers.respond_to?(method)
28
+ end
29
+
30
+ def method_missing(method, *args)
31
+ if @helpers.respond_to?(method)
32
+ self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
33
+ def #{method}(*args)
34
+ options = args.extract_options!
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
45
+ @helpers.#{method}(*args)
46
+ end
47
+ RUBY
48
+ public_send(method, *args)
49
+ else
50
+ super
51
+ end
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
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch
4
+ module Routing
5
+ # In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
6
+ # is also possible: a URL can be generated from one of your routing definitions.
7
+ # URL generation functionality is centralized in this module.
8
+ #
9
+ # See ActionDispatch::Routing for general information about routing and routes.rb.
10
+ #
11
+ # <b>Tip:</b> If you need to generate URLs from your models or some other place,
12
+ # then ActionController::UrlFor is what you're looking for. Read on for
13
+ # an introduction. In general, this module should not be included on its own,
14
+ # as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
15
+ #
16
+ # == URL generation from parameters
17
+ #
18
+ # As you may know, some functions, such as ActionController::Base#url_for
19
+ # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
20
+ # of parameters. For example, you've probably had the chance to write code
21
+ # like this in one of your views:
22
+ #
23
+ # <%= link_to('Click here', controller: 'users',
24
+ # action: 'new', message: 'Welcome!') %>
25
+ # # => <a href="/users/new?message=Welcome%21">Click here</a>
26
+ #
27
+ # link_to, and all other functions that require URL generation functionality,
28
+ # actually use ActionController::UrlFor under the hood. And in particular,
29
+ # they use the ActionController::UrlFor#url_for method. One can generate
30
+ # the same path as the above example by using the following code:
31
+ #
32
+ # include UrlFor
33
+ # url_for(controller: 'users',
34
+ # action: 'new',
35
+ # message: 'Welcome!',
36
+ # only_path: true)
37
+ # # => "/users/new?message=Welcome%21"
38
+ #
39
+ # Notice the <tt>only_path: true</tt> part. This is because UrlFor has no
40
+ # information about the website hostname that your Rails app is serving. So if you
41
+ # want to include the hostname as well, then you must also pass the <tt>:host</tt>
42
+ # argument:
43
+ #
44
+ # include UrlFor
45
+ # url_for(controller: 'users',
46
+ # action: 'new',
47
+ # message: 'Welcome!',
48
+ # host: 'www.example.com')
49
+ # # => "http://www.example.com/users/new?message=Welcome%21"
50
+ #
51
+ # By default, all controllers and views have access to a special version of url_for,
52
+ # that already knows what the current hostname is. So if you use url_for in your
53
+ # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
54
+ # argument.
55
+ #
56
+ # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
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.
62
+ #
63
+ #
64
+ # == URL generation for named routes
65
+ #
66
+ # UrlFor also allows one to access methods that have been auto-generated from
67
+ # named routes. For example, suppose that you have a 'users' resource in your
68
+ # <tt>config/routes.rb</tt>:
69
+ #
70
+ # resources :users
71
+ #
72
+ # This generates, among other things, the method <tt>users_path</tt>. By default,
73
+ # this method is accessible from your controllers, views and mailers. If you need
74
+ # to access this auto-generated method from other places (such as a model), then
75
+ # you can do that by including Rails.application.routes.url_helpers in your class:
76
+ #
77
+ # class User < ActiveRecord::Base
78
+ # include Rails.application.routes.url_helpers
79
+ #
80
+ # def base_uri
81
+ # user_path(self)
82
+ # end
83
+ # end
84
+ #
85
+ # User.find(1).base_uri # => "/users/1"
86
+ #
87
+ module UrlFor
88
+ extend ActiveSupport::Concern
89
+ include PolymorphicRoutes
90
+
91
+ included do
92
+ unless method_defined?(:default_url_options)
93
+ # Including in a class uses an inheritable hash. Modules get a plain hash.
94
+ if respond_to?(:class_attribute)
95
+ class_attribute :default_url_options
96
+ else
97
+ mattr_writer :default_url_options
98
+ end
99
+
100
+ self.default_url_options = {}
101
+ end
102
+
103
+ include(*_url_for_modules) if respond_to?(:_url_for_modules)
104
+ end
105
+
106
+ def initialize(*)
107
+ @_routes = nil
108
+ super
109
+ end
110
+
111
+ # Hook overridden in controller to add request information
112
+ # with +default_url_options+. Application logic should not
113
+ # go into url_options.
114
+ def url_options
115
+ default_url_options
116
+ end
117
+
118
+ # Generate a URL based on the options provided, default_url_options and the
119
+ # routes defined in routes.rb. The following options are supported:
120
+ #
121
+ # * <tt>:only_path</tt> - If true, the relative URL is returned. Defaults to +false+.
122
+ # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
123
+ # * <tt>:host</tt> - Specifies the host the link should be targeted at.
124
+ # If <tt>:only_path</tt> is false, this option must be
125
+ # provided either explicitly, or via +default_url_options+.
126
+ # * <tt>:subdomain</tt> - Specifies the subdomain of the link, using the +tld_length+
127
+ # to split the subdomain from the host.
128
+ # If false, removes all subdomains from the host part of the link.
129
+ # * <tt>:domain</tt> - Specifies the domain of the link, using the +tld_length+
130
+ # to split the domain from the host.
131
+ # * <tt>:tld_length</tt> - Number of labels the TLD id composed of, only used if
132
+ # <tt>:subdomain</tt> or <tt>:domain</tt> are supplied. Defaults to
133
+ # <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1.
134
+ # * <tt>:port</tt> - Optionally specify the port to connect to.
135
+ # * <tt>:anchor</tt> - An anchor name to be appended to the path.
136
+ # * <tt>:params</tt> - The query parameters to be appended to the path.
137
+ # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
138
+ # * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
139
+ #
140
+ # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
141
+ # +url_for+ is forwarded to the Routes module.
142
+ #
143
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080'
144
+ # # => 'http://somehost.org:8080/tasks/testing'
145
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true
146
+ # # => '/tasks/testing#ok'
147
+ # url_for controller: 'tasks', action: 'testing', trailing_slash: true
148
+ # # => 'http://somehost.org/tasks/testing/'
149
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33'
150
+ # # => 'http://somehost.org/tasks/testing?number=33'
151
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp"
152
+ # # => 'http://somehost.org/myapp/tasks/testing'
153
+ # url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
154
+ # # => '/myapp/tasks/testing'
155
+ #
156
+ # Missing routes keys may be filled in from the current request's parameters
157
+ # (e.g. +:controller+, +:action+, +:id+ and any other parameters that are
158
+ # placed in the path). Given that the current action has been reached
159
+ # through <tt>GET /users/1</tt>:
160
+ #
161
+ # url_for(only_path: true) # => '/users/1'
162
+ # url_for(only_path: true, action: 'edit') # => '/users/1/edit'
163
+ # url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit'
164
+ #
165
+ # Notice that no +:id+ parameter was provided to the first +url_for+ call
166
+ # and the helper used the one from the route's path. Any path parameter
167
+ # implicitly used by +url_for+ can always be overwritten like shown on the
168
+ # last +url_for+ calls.
169
+ def url_for(options = nil)
170
+ full_url_for(options)
171
+ end
172
+
173
+ def full_url_for(options = nil) # :nodoc:
174
+ case options
175
+ when nil
176
+ _routes.url_for(url_options.symbolize_keys)
177
+ when Hash, ActionController::Parameters
178
+ route_name = options.delete :use_route
179
+ merged_url_options = options.to_h.symbolize_keys.reverse_merge!(url_options)
180
+ _routes.url_for(merged_url_options, route_name)
181
+ when String
182
+ options
183
+ when Symbol
184
+ HelperMethodBuilder.url.handle_string_call self, options
185
+ when Array
186
+ components = options.dup
187
+ polymorphic_url(components, components.extract_options!)
188
+ when Class
189
+ HelperMethodBuilder.url.handle_class_call self, options
190
+ else
191
+ HelperMethodBuilder.url.handle_model_call self, options
192
+ end
193
+ end
194
+
195
+ # Allows calling direct or regular named route.
196
+ #
197
+ # resources :buckets
198
+ #
199
+ # direct :recordable do |recording|
200
+ # route_for(:bucket, recording.bucket)
201
+ # end
202
+ #
203
+ # direct :threadable do |threadable|
204
+ # route_for(:recordable, threadable.parent)
205
+ # end
206
+ #
207
+ # This maintains the context of the original caller on
208
+ # whether to return a path or full URL, e.g:
209
+ #
210
+ # threadable_path(threadable) # => "/buckets/1"
211
+ # threadable_url(threadable) # => "http://example.com/buckets/1"
212
+ #
213
+ def route_for(name, *args)
214
+ public_send(:"#{name}_url", *args)
215
+ end
216
+
217
+ protected
218
+
219
+ def optimize_routes_generation?
220
+ _routes.optimize_routes_generation? && default_url_options.empty?
221
+ end
222
+
223
+ private
224
+
225
+ def _with_routes(routes) # :doc:
226
+ old_routes, @_routes = @_routes, routes
227
+ yield
228
+ ensure
229
+ @_routes = old_routes
230
+ end
231
+
232
+ def _routes_context # :doc:
233
+ self
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "capybara", ">= 2.15"
4
+
5
+ require "capybara/dsl"
6
+ require "capybara/minitest"
7
+ require "selenium/webdriver"
8
+ require "action_controller"
9
+ require "action_dispatch/system_testing/driver"
10
+ require "action_dispatch/system_testing/browser"
11
+ require "action_dispatch/system_testing/server"
12
+ require "action_dispatch/system_testing/test_helpers/screenshot_helper"
13
+ require "action_dispatch/system_testing/test_helpers/setup_and_teardown"
14
+ require "action_dispatch/system_testing/test_helpers/undef_methods"
15
+
16
+ module ActionDispatch
17
+ # = System Testing
18
+ #
19
+ # System tests let you test applications in the browser. Because system
20
+ # tests use a real browser experience, you can test all of your JavaScript
21
+ # easily from your test suite.
22
+ #
23
+ # To create a system test in your application, extend your test class
24
+ # from <tt>ApplicationSystemTestCase</tt>. System tests use Capybara as a
25
+ # base and allow you to configure the settings through your
26
+ # <tt>application_system_test_case.rb</tt> file that is generated with a new
27
+ # application or scaffold.
28
+ #
29
+ # Here is an example system test:
30
+ #
31
+ # require 'application_system_test_case'
32
+ #
33
+ # class Users::CreateTest < ApplicationSystemTestCase
34
+ # test "adding a new user" do
35
+ # visit users_path
36
+ # click_on 'New User'
37
+ #
38
+ # fill_in 'Name', with: 'Arya'
39
+ # click_on 'Create User'
40
+ #
41
+ # assert_text 'Arya'
42
+ # end
43
+ # end
44
+ #
45
+ # When generating an application or scaffold, an +application_system_test_case.rb+
46
+ # file will also be generated containing the base class for system testing.
47
+ # This is where you can change the driver, add Capybara settings, and other
48
+ # configuration for your system tests.
49
+ #
50
+ # require "test_helper"
51
+ #
52
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
53
+ # driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
54
+ # end
55
+ #
56
+ # By default, <tt>ActionDispatch::SystemTestCase</tt> is driven by the
57
+ # Selenium driver, with the Chrome browser, and a browser size of 1400x1400.
58
+ #
59
+ # Changing the driver configuration options is easy. Let's say you want to use
60
+ # the Firefox browser instead of Chrome. In your +application_system_test_case.rb+
61
+ # file add the following:
62
+ #
63
+ # require "test_helper"
64
+ #
65
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
66
+ # driven_by :selenium, using: :firefox
67
+ # end
68
+ #
69
+ # +driven_by+ has a required argument for the driver name. The keyword
70
+ # arguments are +:using+ for the browser and +:screen_size+ to change the
71
+ # size of the browser screen. These two options are not applicable for
72
+ # headless drivers and will be silently ignored if passed.
73
+ #
74
+ # Headless browsers such as headless Chrome and headless Firefox are also supported.
75
+ # You can use these browsers by setting the +:using+ argument to +:headless_chrome+ or +:headless_firefox+.
76
+ #
77
+ # To use a headless driver, like Poltergeist, update your Gemfile to use
78
+ # Poltergeist instead of Selenium and then declare the driver name in the
79
+ # +application_system_test_case.rb+ file. In this case, you would leave out
80
+ # the +:using+ option because the driver is headless, but you can still use
81
+ # +:screen_size+ to change the size of the browser screen, also you can use
82
+ # +:options+ to pass options supported by the driver. Please refer to your
83
+ # driver documentation to learn about supported options.
84
+ #
85
+ # require "test_helper"
86
+ # require "capybara/poltergeist"
87
+ #
88
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
89
+ # driven_by :poltergeist, screen_size: [1400, 1400], options:
90
+ # { js_errors: true }
91
+ # end
92
+ #
93
+ # Some drivers require browser capabilities to be passed as a block instead
94
+ # of through the +options+ hash.
95
+ #
96
+ # As an example, if you want to add mobile emulation on chrome, you'll have to
97
+ # create an instance of selenium's +Chrome::Options+ object and add
98
+ # capabilities with a block.
99
+ #
100
+ # The block will be passed an instance of <tt><Driver>::Options</tt> where you can
101
+ # define the capabilities you want. Please refer to your driver documentation
102
+ # to learn about supported options.
103
+ #
104
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
105
+ # driven_by :selenium, using: :chrome, screen_size: [1024, 768] do |driver_option|
106
+ # driver_option.add_emulation(device_name: 'iPhone 6')
107
+ # driver_option.add_extension('path/to/chrome_extension.crx')
108
+ # end
109
+ # end
110
+ #
111
+ # Because <tt>ActionDispatch::SystemTestCase</tt> is a shim between Capybara
112
+ # and Rails, any driver that is supported by Capybara is supported by system
113
+ # tests as long as you include the required gems and files.
114
+ class SystemTestCase < IntegrationTest
115
+ include Capybara::DSL
116
+ include Capybara::Minitest::Assertions
117
+ include SystemTesting::TestHelpers::SetupAndTeardown
118
+ include SystemTesting::TestHelpers::ScreenshotHelper
119
+ include SystemTesting::TestHelpers::UndefMethods
120
+
121
+ def initialize(*) # :nodoc:
122
+ super
123
+ self.class.driver.use
124
+ end
125
+
126
+ def self.start_application # :nodoc:
127
+ Capybara.app = Rack::Builder.new do
128
+ map "/" do
129
+ run Rails.application
130
+ end
131
+ end
132
+
133
+ SystemTesting::Server.new.run
134
+ end
135
+
136
+ class_attribute :driver, instance_accessor: false
137
+
138
+ # System Test configuration options
139
+ #
140
+ # The default settings are Selenium, using Chrome, with a screen size
141
+ # of 1400x1400.
142
+ #
143
+ # Examples:
144
+ #
145
+ # driven_by :poltergeist
146
+ #
147
+ # driven_by :selenium, screen_size: [800, 800]
148
+ #
149
+ # driven_by :selenium, using: :chrome
150
+ #
151
+ # driven_by :selenium, using: :headless_chrome
152
+ #
153
+ # driven_by :selenium, using: :firefox
154
+ #
155
+ # driven_by :selenium, using: :headless_firefox
156
+ def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
157
+ driver_options = { using: using, screen_size: screen_size, options: options }
158
+
159
+ self.driver = SystemTesting::Driver.new(driver, driver_options, &capabilities)
160
+ end
161
+
162
+ driven_by :selenium
163
+
164
+ ActiveSupport.run_load_hooks(:action_dispatch_system_test_case, self)
165
+ end
166
+
167
+ SystemTestCase.start_application
168
+ end