actionpack 7.0.8.1 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -500
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +119 -106
  7. data/lib/abstract_controller/caching/fragments.rb +51 -52
  8. data/lib/abstract_controller/caching.rb +2 -0
  9. data/lib/abstract_controller/callbacks.rb +94 -67
  10. data/lib/abstract_controller/collector.rb +6 -6
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +2 -0
  13. data/lib/abstract_controller/helpers.rb +121 -91
  14. data/lib/abstract_controller/logger.rb +2 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
  16. data/lib/abstract_controller/rendering.rb +14 -13
  17. data/lib/abstract_controller/translation.rb +12 -30
  18. data/lib/abstract_controller/url_for.rb +9 -5
  19. data/lib/abstract_controller.rb +8 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/api.rb +78 -73
  22. data/lib/action_controller/base.rb +199 -141
  23. data/lib/action_controller/caching.rb +16 -11
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +21 -16
  26. data/lib/action_controller/log_subscriber.rb +19 -5
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  29. data/lib/action_controller/metal/conditional_get.rb +187 -174
  30. data/lib/action_controller/metal/content_security_policy.rb +26 -25
  31. data/lib/action_controller/metal/cookies.rb +4 -2
  32. data/lib/action_controller/metal/data_streaming.rb +65 -54
  33. data/lib/action_controller/metal/default_headers.rb +6 -2
  34. data/lib/action_controller/metal/etag_with_flash.rb +4 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
  36. data/lib/action_controller/metal/exceptions.rb +19 -9
  37. data/lib/action_controller/metal/flash.rb +12 -10
  38. data/lib/action_controller/metal/head.rb +20 -16
  39. data/lib/action_controller/metal/helpers.rb +64 -67
  40. data/lib/action_controller/metal/http_authentication.rb +214 -200
  41. data/lib/action_controller/metal/implicit_render.rb +21 -17
  42. data/lib/action_controller/metal/instrumentation.rb +22 -12
  43. data/lib/action_controller/metal/live.rb +125 -92
  44. data/lib/action_controller/metal/logging.rb +6 -4
  45. data/lib/action_controller/metal/mime_responds.rb +151 -142
  46. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  47. data/lib/action_controller/metal/params_wrapper.rb +58 -58
  48. data/lib/action_controller/metal/permissions_policy.rb +14 -13
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +110 -84
  51. data/lib/action_controller/metal/renderers.rb +50 -49
  52. data/lib/action_controller/metal/rendering.rb +103 -82
  53. data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
  54. data/lib/action_controller/metal/rescue.rb +12 -8
  55. data/lib/action_controller/metal/streaming.rb +174 -132
  56. data/lib/action_controller/metal/strong_parameters.rb +598 -473
  57. data/lib/action_controller/metal/testing.rb +2 -0
  58. data/lib/action_controller/metal/url_for.rb +23 -14
  59. data/lib/action_controller/metal.rb +145 -61
  60. data/lib/action_controller/railtie.rb +25 -9
  61. data/lib/action_controller/railties/helpers.rb +2 -0
  62. data/lib/action_controller/renderer.rb +105 -66
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +157 -128
  65. data/lib/action_controller.rb +17 -3
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +28 -29
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +69 -49
  71. data/lib/action_dispatch/http/filter_parameters.rb +27 -12
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +23 -21
  74. data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
  75. data/lib/action_dispatch/http/mime_type.rb +60 -30
  76. data/lib/action_dispatch/http/mime_types.rb +5 -1
  77. data/lib/action_dispatch/http/parameters.rb +12 -10
  78. data/lib/action_dispatch/http/permissions_policy.rb +32 -34
  79. data/lib/action_dispatch/http/rack_cache.rb +4 -0
  80. data/lib/action_dispatch/http/request.rb +132 -79
  81. data/lib/action_dispatch/http/response.rb +136 -103
  82. data/lib/action_dispatch/http/upload.rb +19 -15
  83. data/lib/action_dispatch/http/url.rb +75 -73
  84. data/lib/action_dispatch/journey/formatter.rb +19 -6
  85. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  88. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  90. data/lib/action_dispatch/journey/parser.rb +4 -3
  91. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  92. data/lib/action_dispatch/journey/path/pattern.rb +18 -15
  93. data/lib/action_dispatch/journey/route.rb +12 -9
  94. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  95. data/lib/action_dispatch/journey/router.rb +13 -10
  96. data/lib/action_dispatch/journey/routes.rb +6 -4
  97. data/lib/action_dispatch/journey/scanner.rb +4 -2
  98. data/lib/action_dispatch/journey/visitors.rb +2 -0
  99. data/lib/action_dispatch/journey.rb +2 -0
  100. data/lib/action_dispatch/log_subscriber.rb +25 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
  102. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  103. data/lib/action_dispatch/middleware/callbacks.rb +4 -0
  104. data/lib/action_dispatch/middleware/cookies.rb +192 -194
  105. data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
  106. data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
  107. data/lib/action_dispatch/middleware/debug_view.rb +9 -2
  108. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
  109. data/lib/action_dispatch/middleware/executor.rb +9 -1
  110. data/lib/action_dispatch/middleware/flash.rb +65 -46
  111. data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
  112. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
  113. data/lib/action_dispatch/middleware/reloader.rb +9 -5
  114. data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
  115. data/lib/action_dispatch/middleware/request_id.rb +15 -8
  116. data/lib/action_dispatch/middleware/server_timing.rb +8 -6
  117. data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
  118. data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
  119. data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
  120. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
  121. data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
  122. data/lib/action_dispatch/middleware/ssl.rb +60 -45
  123. data/lib/action_dispatch/middleware/stack.rb +15 -9
  124. data/lib/action_dispatch/middleware/static.rb +40 -34
  125. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
  126. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
  130. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
  132. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
  139. data/lib/action_dispatch/railtie.rb +12 -4
  140. data/lib/action_dispatch/request/session.rb +39 -27
  141. data/lib/action_dispatch/request/utils.rb +10 -3
  142. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  143. data/lib/action_dispatch/routing/inspector.rb +59 -9
  144. data/lib/action_dispatch/routing/mapper.rb +686 -639
  145. data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
  146. data/lib/action_dispatch/routing/redirection.rb +52 -38
  147. data/lib/action_dispatch/routing/route_set.rb +106 -62
  148. data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
  149. data/lib/action_dispatch/routing/url_for.rb +131 -122
  150. data/lib/action_dispatch/routing.rb +152 -150
  151. data/lib/action_dispatch/system_test_case.rb +91 -81
  152. data/lib/action_dispatch/system_testing/browser.rb +27 -19
  153. data/lib/action_dispatch/system_testing/driver.rb +16 -22
  154. data/lib/action_dispatch/system_testing/server.rb +2 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  157. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  158. data/lib/action_dispatch/testing/assertions/response.rb +36 -26
  159. data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
  160. data/lib/action_dispatch/testing/assertions.rb +5 -1
  161. data/lib/action_dispatch/testing/integration.rb +240 -229
  162. data/lib/action_dispatch/testing/request_encoder.rb +6 -1
  163. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  164. data/lib/action_dispatch/testing/test_process.rb +14 -9
  165. data/lib/action_dispatch/testing/test_request.rb +4 -2
  166. data/lib/action_dispatch/testing/test_response.rb +34 -19
  167. data/lib/action_dispatch.rb +52 -21
  168. data/lib/action_pack/gem_version.rb +5 -3
  169. data/lib/action_pack/version.rb +3 -1
  170. data/lib/action_pack.rb +18 -17
  171. metadata +91 -32
@@ -1,256 +1,258 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/string/filters"
3
+ # :markup: markdown
4
4
 
5
5
  module ActionDispatch
6
6
  # The routing module provides URL rewriting in native Ruby. It's a way to
7
7
  # redirect incoming requests to controllers and actions. This replaces
8
- # mod_rewrite rules. Best of all, Rails' \Routing works with any web server.
9
- # Routes are defined in <tt>config/routes.rb</tt>.
8
+ # mod_rewrite rules. Best of all, Rails' Routing works with any web server.
9
+ # Routes are defined in `config/routes.rb`.
10
10
  #
11
11
  # Think of creating routes as drawing a map for your requests. The map tells
12
12
  # them where to go based on some predefined pattern:
13
13
  #
14
- # Rails.application.routes.draw do
15
- # Pattern 1 tells some request to go to one place
16
- # Pattern 2 tell them to go to another
17
- # ...
18
- # end
14
+ # Rails.application.routes.draw do
15
+ # Pattern 1 tells some request to go to one place
16
+ # Pattern 2 tell them to go to another
17
+ # ...
18
+ # end
19
19
  #
20
20
  # The following symbols are special:
21
21
  #
22
- # :controller maps to your controller name
23
- # :action maps to an action with your controllers
22
+ # :controller maps to your controller name
23
+ # :action maps to an action with your controllers
24
24
  #
25
- # Other names simply map to a parameter as in the case of <tt>:id</tt>.
25
+ # Other names simply map to a parameter as in the case of `:id`.
26
26
  #
27
- # == Resources
27
+ # ## Resources
28
28
  #
29
- # Resource routing allows you to quickly declare all of the common routes
30
- # for a given resourceful controller. Instead of declaring separate routes
31
- # for your +index+, +show+, +new+, +edit+, +create+, +update+, and +destroy+
32
- # actions, a resourceful route declares them in a single line of code:
29
+ # Resource routing allows you to quickly declare all of the common routes for a
30
+ # given resourceful controller. Instead of declaring separate routes for your
31
+ # `index`, `show`, `new`, `edit`, `create`, `update`, and `destroy` actions, a
32
+ # resourceful route declares them in a single line of code:
33
33
  #
34
- # resources :photos
34
+ # resources :photos
35
35
  #
36
- # Sometimes, you have a resource that clients always look up without
37
- # referencing an ID. A common example, /profile always shows the profile of
38
- # the currently logged in user. In this case, you can use a singular resource
39
- # to map /profile (rather than /profile/:id) to the show action.
36
+ # Sometimes, you have a resource that clients always look up without referencing
37
+ # an ID. A common example, /profile always shows the profile of the currently
38
+ # logged in user. In this case, you can use a singular resource to map /profile
39
+ # (rather than /profile/:id) to the show action.
40
40
  #
41
- # resource :profile
41
+ # resource :profile
42
42
  #
43
- # It's common to have resources that are logically children of other
44
- # resources:
43
+ # It's common to have resources that are logically children of other resources:
45
44
  #
46
- # resources :magazines do
47
- # resources :ads
48
- # end
45
+ # resources :magazines do
46
+ # resources :ads
47
+ # end
49
48
  #
50
49
  # You may wish to organize groups of controllers under a namespace. Most
51
- # commonly, you might group a number of administrative controllers under
52
- # an +admin+ namespace. You would place these controllers under the
53
- # <tt>app/controllers/admin</tt> directory, and you can group them together
54
- # in your router:
50
+ # commonly, you might group a number of administrative controllers under an
51
+ # `admin` namespace. You would place these controllers under the
52
+ # `app/controllers/admin` directory, and you can group them together in your
53
+ # router:
55
54
  #
56
- # namespace "admin" do
57
- # resources :posts, :comments
58
- # end
55
+ # namespace "admin" do
56
+ # resources :posts, :comments
57
+ # end
59
58
  #
60
59
  # Alternatively, you can add prefixes to your path without using a separate
61
- # directory by using +scope+. +scope+ takes additional options which
62
- # apply to all enclosed routes.
60
+ # directory by using `scope`. `scope` takes additional options which apply to
61
+ # all enclosed routes.
63
62
  #
64
- # scope path: "/cpanel", as: 'admin' do
65
- # resources :posts, :comments
66
- # end
63
+ # scope path: "/cpanel", as: 'admin' do
64
+ # resources :posts, :comments
65
+ # end
67
66
  #
68
67
  # For more, see Routing::Mapper::Resources#resources,
69
68
  # Routing::Mapper::Scoping#namespace, and Routing::Mapper::Scoping#scope.
70
69
  #
71
- # == Non-resourceful routes
70
+ # ## Non-resourceful routes
72
71
  #
73
- # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
74
- # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
72
+ # For routes that don't fit the `resources` mold, you can use the HTTP helper
73
+ # methods `get`, `post`, `patch`, `put` and `delete`.
75
74
  #
76
- # get 'post/:id', to: 'posts#show'
77
- # post 'post/:id', to: 'posts#create_comment'
75
+ # get 'post/:id', to: 'posts#show'
76
+ # post 'post/:id', to: 'posts#create_comment'
78
77
  #
79
- # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
80
- # URL will route to the <tt>show</tt> action.
78
+ # Now, if you POST to `/posts/:id`, it will route to the `create_comment`
79
+ # action. A GET on the same URL will route to the `show` action.
81
80
  #
82
- # If your route needs to respond to more than one HTTP method (or all methods) then using the
83
- # <tt>:via</tt> option on <tt>match</tt> is preferable.
81
+ # If your route needs to respond to more than one HTTP method (or all methods)
82
+ # then using the `:via` option on `match` is preferable.
84
83
  #
85
- # match 'post/:id', to: 'posts#show', via: [:get, :post]
84
+ # match 'post/:id', to: 'posts#show', via: [:get, :post]
86
85
  #
87
- # == Named routes
86
+ # ## Named routes
88
87
  #
89
- # Routes can be named by passing an <tt>:as</tt> option,
90
- # allowing for easy reference within your source as +name_of_route_url+
91
- # for the full URL and +name_of_route_path+ for the URI path.
88
+ # Routes can be named by passing an `:as` option, allowing for easy reference
89
+ # within your source as `name_of_route_url` for the full URL and
90
+ # `name_of_route_path` for the URI path.
92
91
  #
93
92
  # Example:
94
93
  #
95
- # # In config/routes.rb
96
- # get '/login', to: 'accounts#login', as: 'login'
94
+ # # In config/routes.rb
95
+ # get '/login', to: 'accounts#login', as: 'login'
97
96
  #
98
- # # With render, redirect_to, tests, etc.
99
- # redirect_to login_url
97
+ # # With render, redirect_to, tests, etc.
98
+ # redirect_to login_url
100
99
  #
101
100
  # Arguments can be passed as well.
102
101
  #
103
- # redirect_to show_item_path(id: 25)
102
+ # redirect_to show_item_path(id: 25)
104
103
  #
105
- # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
104
+ # Use `root` as a shorthand to name a route for the root path "/".
106
105
  #
107
- # # In config/routes.rb
108
- # root to: 'blogs#index'
106
+ # # In config/routes.rb
107
+ # root to: 'blogs#index'
109
108
  #
110
- # # would recognize http://www.example.com/ as
111
- # params = { controller: 'blogs', action: 'index' }
109
+ # # would recognize http://www.example.com/ as
110
+ # params = { controller: 'blogs', action: 'index' }
112
111
  #
113
- # # and provide these named routes
114
- # root_url # => 'http://www.example.com/'
115
- # root_path # => '/'
112
+ # # and provide these named routes
113
+ # root_url # => 'http://www.example.com/'
114
+ # root_path # => '/'
116
115
  #
117
- # Note: when using +controller+, the route is simply named after the
118
- # method you call on the block parameter rather than map.
116
+ # Note: when using `controller`, the route is simply named after the method you
117
+ # call on the block parameter rather than map.
119
118
  #
120
- # # In config/routes.rb
121
- # controller :blog do
122
- # get 'blog/show', to: :list
123
- # get 'blog/delete', to: :delete
124
- # get 'blog/edit', to: :edit
125
- # end
119
+ # # In config/routes.rb
120
+ # controller :blog do
121
+ # get 'blog/show' => :list
122
+ # get 'blog/delete' => :delete
123
+ # get 'blog/edit' => :edit
124
+ # end
126
125
  #
127
- # # provides named routes for show, delete, and edit
128
- # link_to @article.title, blog_show_path(id: @article.id)
126
+ # # provides named routes for show, delete, and edit
127
+ # link_to @article.title, blog_show_path(id: @article.id)
129
128
  #
130
- # == Pretty URLs
129
+ # ## Pretty URLs
131
130
  #
132
131
  # Routes can generate pretty URLs. For example:
133
132
  #
134
- # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
135
- # year: /\d{4}/,
136
- # month: /\d{1,2}/,
137
- # day: /\d{1,2}/
138
- # }
133
+ # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
134
+ # year: /\d{4}/,
135
+ # month: /\d{1,2}/,
136
+ # day: /\d{1,2}/
137
+ # }
139
138
  #
140
139
  # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
141
140
  # maps to
142
141
  #
143
- # params = {year: '2005', month: '11', day: '06'}
142
+ # params = {year: '2005', month: '11', day: '06'}
144
143
  #
145
- # == Regular Expressions and parameters
144
+ # ## Regular Expressions and parameters
146
145
  # You can specify a regular expression to define a format for a parameter.
147
146
  #
148
- # controller 'geocode' do
149
- # get 'geocode/:postalcode', to: :show, constraints: {
150
- # postalcode: /\d{5}(-\d{4})?/
151
- # }
152
- # end
147
+ # controller 'geocode' do
148
+ # get 'geocode/:postalcode', to: :show, constraints: {
149
+ # postalcode: /\d{5}(-\d{4})?/
150
+ # }
151
+ # end
153
152
  #
154
153
  # Constraints can include the 'ignorecase' and 'extended syntax' regular
155
154
  # expression modifiers:
156
155
  #
157
- # controller 'geocode' do
158
- # get 'geocode/:postalcode', to: :show, constraints: {
159
- # postalcode: /hx\d\d\s\d[a-z]{2}/i
160
- # }
161
- # end
162
- #
163
- # controller 'geocode' do
164
- # get 'geocode/:postalcode', to: :show, constraints: {
165
- # postalcode: /# Postalcode format
166
- # \d{5} #Prefix
167
- # (-\d{4})? #Suffix
168
- # /x
169
- # }
170
- # end
156
+ # controller 'geocode' do
157
+ # get 'geocode/:postalcode', to: :show, constraints: {
158
+ # postalcode: /hx\d\d\s\d[a-z]{2}/i
159
+ # }
160
+ # end
161
+ #
162
+ # controller 'geocode' do
163
+ # get 'geocode/:postalcode', to: :show, constraints: {
164
+ # postalcode: /# Postalcode format
165
+ # \d{5} #Prefix
166
+ # (-\d{4})? #Suffix
167
+ # /x
168
+ # }
169
+ # end
171
170
  #
172
- # Using the multiline modifier will raise an +ArgumentError+.
173
- # Encoding regular expression modifiers are silently ignored. The
174
- # match will always use the default encoding or ASCII.
171
+ # Using the multiline modifier will raise an `ArgumentError`. Encoding regular
172
+ # expression modifiers are silently ignored. The match will always use the
173
+ # default encoding or ASCII.
175
174
  #
176
- # == External redirects
175
+ # ## External redirects
177
176
  #
178
- # You can redirect any path to another path using the redirect helper in your router:
177
+ # You can redirect any path to another path using the redirect helper in your
178
+ # router:
179
179
  #
180
- # get "/stories", to: redirect("/posts")
180
+ # get "/stories", to: redirect("/posts")
181
181
  #
182
- # == Unicode character routes
182
+ # ## Unicode character routes
183
183
  #
184
184
  # You can specify unicode character routes in your router:
185
185
  #
186
- # get "こんにちは", to: "welcome#index"
186
+ # get "こんにちは", to: "welcome#index"
187
187
  #
188
- # == Routing to Rack Applications
188
+ # ## Routing to Rack Applications
189
189
  #
190
- # Instead of a String, like <tt>posts#index</tt>, which corresponds to the
191
- # index action in the PostsController, you can specify any Rack application
192
- # as the endpoint for a matcher:
190
+ # Instead of a String, like `posts#index`, which corresponds to the index action
191
+ # in the PostsController, you can specify any Rack application as the endpoint
192
+ # for a matcher:
193
193
  #
194
- # get "/application.js", to: Sprockets
194
+ # get "/application.js", to: Sprockets
195
195
  #
196
- # == Reloading routes
196
+ # ## Reloading routes
197
197
  #
198
198
  # You can reload routes if you feel you must:
199
199
  #
200
- # Rails.application.reload_routes!
200
+ # Rails.application.reload_routes!
201
201
  #
202
- # This will clear all named routes and reload config/routes.rb if the file has been modified from
203
- # last load. To absolutely force reloading, use <tt>reload!</tt>.
202
+ # This will clear all named routes and reload config/routes.rb if the file has
203
+ # been modified from last load. To absolutely force reloading, use `reload!`.
204
204
  #
205
- # == Testing Routes
205
+ # ## Testing Routes
206
206
  #
207
207
  # The two main methods for testing your routes:
208
208
  #
209
- # === +assert_routing+
209
+ # ### `assert_routing`
210
210
  #
211
- # def test_movie_route_properly_splits
212
- # opts = {controller: "plugin", action: "checkout", id: "2"}
213
- # assert_routing "plugin/checkout/2", opts
214
- # end
211
+ # def test_movie_route_properly_splits
212
+ # opts = {controller: "plugin", action: "checkout", id: "2"}
213
+ # assert_routing "plugin/checkout/2", opts
214
+ # end
215
215
  #
216
- # +assert_routing+ lets you test whether or not the route properly resolves into options.
216
+ # `assert_routing` lets you test whether or not the route properly resolves into
217
+ # options.
217
218
  #
218
- # === +assert_recognizes+
219
+ # ### `assert_recognizes`
219
220
  #
220
- # def test_route_has_options
221
- # opts = {controller: "plugin", action: "show", id: "12"}
222
- # assert_recognizes opts, "/plugins/show/12"
223
- # end
221
+ # def test_route_has_options
222
+ # opts = {controller: "plugin", action: "show", id: "12"}
223
+ # assert_recognizes opts, "/plugins/show/12"
224
+ # end
224
225
  #
225
- # Note the subtle difference between the two: +assert_routing+ tests that
226
- # a URL fits options while +assert_recognizes+ tests that a URL
227
- # breaks into parameters properly.
226
+ # Note the subtle difference between the two: `assert_routing` tests that a URL
227
+ # fits options while `assert_recognizes` tests that a URL breaks into parameters
228
+ # properly.
228
229
  #
229
- # In tests you can simply pass the URL or named route to +get+ or +post+.
230
+ # In tests you can simply pass the URL or named route to `get` or `post`.
230
231
  #
231
- # def send_to_jail
232
- # get '/jail'
233
- # assert_response :success
234
- # end
232
+ # def send_to_jail
233
+ # get '/jail'
234
+ # assert_response :success
235
+ # end
235
236
  #
236
- # def goes_to_login
237
- # get login_url
238
- # #...
239
- # end
237
+ # def goes_to_login
238
+ # get login_url
239
+ # #...
240
+ # end
240
241
  #
241
- # == View a list of all your routes
242
+ # ## View a list of all your routes
242
243
  #
243
- # rails routes
244
+ # $ bin/rails routes
244
245
  #
245
- # Target a specific controller with <tt>-c</tt>, or grep routes
246
- # using <tt>-g</tt>. Useful in conjunction with <tt>--expanded</tt>
247
- # which displays routes vertically.
246
+ # Target a specific controller with `-c`, or grep routes using `-g`. Useful in
247
+ # conjunction with `--expanded` which displays routes vertically.
248
248
  module Routing
249
249
  extend ActiveSupport::Autoload
250
250
 
251
251
  autoload :Mapper
252
252
  autoload :RouteSet
253
- autoload :RoutesProxy
253
+ eager_autoload do
254
+ autoload :RoutesProxy
255
+ end
254
256
  autoload :UrlFor
255
257
  autoload :PolymorphicRoutes
256
258
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  gem "capybara", ">= 3.26"
4
6
 
5
7
  require "capybara/dsl"
@@ -12,103 +14,103 @@ require "action_dispatch/system_testing/test_helpers/screenshot_helper"
12
14
  require "action_dispatch/system_testing/test_helpers/setup_and_teardown"
13
15
 
14
16
  module ActionDispatch
15
- # = System Testing
17
+ # # System Testing
16
18
  #
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.
19
+ # System tests let you test applications in the browser. Because system tests
20
+ # use a real browser experience, you can test all of your JavaScript easily from
21
+ # your test suite.
20
22
  #
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.
23
+ # To create a system test in your application, extend your test class from
24
+ # `ApplicationSystemTestCase`. System tests use Capybara as a base and allow you
25
+ # to configure the settings through your `application_system_test_case.rb` file
26
+ # that is generated with a new application or scaffold.
26
27
  #
27
28
  # Here is an example system test:
28
29
  #
29
- # require "application_system_test_case"
30
+ # require "application_system_test_case"
30
31
  #
31
- # class Users::CreateTest < ApplicationSystemTestCase
32
- # test "adding a new user" do
33
- # visit users_path
34
- # click_on 'New User'
32
+ # class Users::CreateTest < ApplicationSystemTestCase
33
+ # test "adding a new user" do
34
+ # visit users_path
35
+ # click_on 'New User'
35
36
  #
36
- # fill_in 'Name', with: 'Arya'
37
- # click_on 'Create User'
37
+ # fill_in 'Name', with: 'Arya'
38
+ # click_on 'Create User'
38
39
  #
39
- # assert_text 'Arya'
40
+ # assert_text 'Arya'
41
+ # end
40
42
  # end
41
- # end
42
43
  #
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.
44
+ # When generating an application or scaffold, an
45
+ # `application_system_test_case.rb` file will also be generated containing the
46
+ # base class for system testing. This is where you can change the driver, add
47
+ # Capybara settings, and other configuration for your system tests.
47
48
  #
48
- # require "test_helper"
49
+ # require "test_helper"
49
50
  #
50
- # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
51
- # driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
52
- # end
51
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
52
+ # driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
53
+ # end
53
54
  #
54
- # By default, <tt>ActionDispatch::SystemTestCase</tt> is driven by the
55
- # Selenium driver, with the Chrome browser, and a browser size of 1400x1400.
55
+ # By default, `ActionDispatch::SystemTestCase` is driven by the Selenium driver,
56
+ # with the Chrome browser, and a browser size of 1400x1400.
56
57
  #
57
58
  # 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"
59
+ # the Firefox browser instead of Chrome. In your
60
+ # `application_system_test_case.rb` file add the following:
62
61
  #
63
- # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
64
- # driven_by :selenium, using: :firefox
65
- # end
62
+ # require "test_helper"
66
63
  #
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+.
64
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
65
+ # driven_by :selenium, using: :firefox
66
+ # end
74
67
  #
75
- # To use a headless driver, like Cuprite, update your Gemfile to use
76
- # Cuprite 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
68
+ # `driven_by` has a required argument for the driver name. The keyword arguments
69
+ # are `:using` for the browser and `:screen_size` to change the size of the
70
+ # browser screen. These two options are not applicable for headless drivers and
71
+ # will be silently ignored if passed.
72
+ #
73
+ # Headless browsers such as headless Chrome and headless Firefox are also
74
+ # supported. You can use these browsers by setting the `:using` argument to
75
+ # `:headless_chrome` or `:headless_firefox`.
76
+ #
77
+ # To use a headless driver, like Cuprite, update your Gemfile to use Cuprite
78
+ # 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 the
80
+ # `: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
81
83
  # driver documentation to learn about supported options.
82
84
  #
83
- # require "test_helper"
84
- # require "capybara/cuprite"
85
+ # require "test_helper"
86
+ # require "capybara/cuprite"
85
87
  #
86
- # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
87
- # driven_by :cuprite, screen_size: [1400, 1400], options:
88
- # { js_errors: true }
89
- # end
88
+ # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
89
+ # driven_by :cuprite, screen_size: [1400, 1400], options:
90
+ # { js_errors: true }
91
+ # end
90
92
  #
91
- # Some drivers require browser capabilities to be passed as a block instead
92
- # of through the +options+ hash.
93
+ # Some drivers require browser capabilities to be passed as a block instead of
94
+ # through the `options` hash.
93
95
  #
94
96
  # 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')
97
+ # create an instance of selenium's `Chrome::Options` object and add capabilities
98
+ # with a block.
99
+ #
100
+ # The block will be passed an instance of `<Driver>::Options` where you can
101
+ # define the capabilities you want. Please refer to your driver documentation to
102
+ # 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
106
109
  # end
107
- # end
108
110
  #
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.
111
+ # Because `ActionDispatch::SystemTestCase` is a shim between Capybara and Rails,
112
+ # any driver that is supported by Capybara is supported by system tests as long
113
+ # as you include the required gems and files.
112
114
  class SystemTestCase < ActiveSupport::TestCase
113
115
  include Capybara::DSL
114
116
  include Capybara::Minitest::Assertions
@@ -137,28 +139,36 @@ module ActionDispatch
137
139
 
138
140
  # System Test configuration options
139
141
  #
140
- # The default settings are Selenium, using Chrome, with a screen size
141
- # of 1400x1400.
142
+ # The default settings are Selenium, using Chrome, with a screen size of
143
+ # 1400x1400.
142
144
  #
143
145
  # Examples:
144
146
  #
145
- # driven_by :cuprite
147
+ # driven_by :cuprite
146
148
  #
147
- # driven_by :selenium, screen_size: [800, 800]
149
+ # driven_by :selenium, screen_size: [800, 800]
148
150
  #
149
- # driven_by :selenium, using: :chrome
151
+ # driven_by :selenium, using: :chrome
150
152
  #
151
- # driven_by :selenium, using: :headless_chrome
153
+ # driven_by :selenium, using: :headless_chrome
152
154
  #
153
- # driven_by :selenium, using: :firefox
155
+ # driven_by :selenium, using: :firefox
154
156
  #
155
- # driven_by :selenium, using: :headless_firefox
157
+ # driven_by :selenium, using: :headless_firefox
156
158
  def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
157
159
  driver_options = { using: using, screen_size: screen_size, options: options }
158
160
 
159
161
  self.driver = SystemTesting::Driver.new(driver, **driver_options, &capabilities)
160
162
  end
161
163
 
164
+ # Configuration for the System Test application server.
165
+ #
166
+ # By default this is localhost. This method allows the host and port to be specified manually.
167
+ def self.served_by(host:, port:)
168
+ Capybara.server_host = host
169
+ Capybara.server_port = port
170
+ end
171
+
162
172
  private
163
173
  def url_helpers
164
174
  @url_helpers ||=
@@ -178,9 +188,9 @@ module ActionDispatch
178
188
  end
179
189
  end
180
190
 
181
- def method_missing(name, *args, &block)
191
+ def method_missing(name, ...)
182
192
  if url_helpers.respond_to?(name)
183
- url_helpers.public_send(name, *args, &block)
193
+ url_helpers.public_send(name, ...)
184
194
  else
185
195
  super
186
196
  end