actionpack 7.1.3 → 7.2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -501
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +15 -7
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +198 -126
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +123 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +210 -205
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +86 -60
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +18 -9
  70. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +31 -24
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +20 -44
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +94 -75
  79. data/lib/action_dispatch/http/response.rb +73 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +671 -636
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +39 -16
@@ -1,248 +1,250 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  # The routing module provides URL rewriting in native Ruby. It's a way to
5
7
  # redirect incoming requests to controllers and actions. This replaces
6
- # mod_rewrite rules. Best of all, Rails' \Routing works with any web server.
7
- # 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`.
8
10
  #
9
11
  # Think of creating routes as drawing a map for your requests. The map tells
10
12
  # them where to go based on some predefined pattern:
11
13
  #
12
- # Rails.application.routes.draw do
13
- # Pattern 1 tells some request to go to one place
14
- # Pattern 2 tell them to go to another
15
- # ...
16
- # 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
17
19
  #
18
20
  # The following symbols are special:
19
21
  #
20
- # :controller maps to your controller name
21
- # :action maps to an action with your controllers
22
+ # :controller maps to your controller name
23
+ # :action maps to an action with your controllers
22
24
  #
23
- # 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`.
24
26
  #
25
- # == Resources
27
+ # ## Resources
26
28
  #
27
- # Resource routing allows you to quickly declare all of the common routes
28
- # for a given resourceful controller. Instead of declaring separate routes
29
- # for your +index+, +show+, +new+, +edit+, +create+, +update+, and +destroy+
30
- # 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:
31
33
  #
32
- # resources :photos
34
+ # resources :photos
33
35
  #
34
- # Sometimes, you have a resource that clients always look up without
35
- # referencing an ID. A common example, /profile always shows the profile of
36
- # the currently logged in user. In this case, you can use a singular resource
37
- # 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.
38
40
  #
39
- # resource :profile
41
+ # resource :profile
40
42
  #
41
- # It's common to have resources that are logically children of other
42
- # resources:
43
+ # It's common to have resources that are logically children of other resources:
43
44
  #
44
- # resources :magazines do
45
- # resources :ads
46
- # end
45
+ # resources :magazines do
46
+ # resources :ads
47
+ # end
47
48
  #
48
49
  # You may wish to organize groups of controllers under a namespace. Most
49
- # commonly, you might group a number of administrative controllers under
50
- # an +admin+ namespace. You would place these controllers under the
51
- # <tt>app/controllers/admin</tt> directory, and you can group them together
52
- # 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:
53
54
  #
54
- # namespace "admin" do
55
- # resources :posts, :comments
56
- # end
55
+ # namespace "admin" do
56
+ # resources :posts, :comments
57
+ # end
57
58
  #
58
59
  # Alternatively, you can add prefixes to your path without using a separate
59
- # directory by using +scope+. +scope+ takes additional options which
60
- # apply to all enclosed routes.
60
+ # directory by using `scope`. `scope` takes additional options which apply to
61
+ # all enclosed routes.
61
62
  #
62
- # scope path: "/cpanel", as: 'admin' do
63
- # resources :posts, :comments
64
- # end
63
+ # scope path: "/cpanel", as: 'admin' do
64
+ # resources :posts, :comments
65
+ # end
65
66
  #
66
67
  # For more, see Routing::Mapper::Resources#resources,
67
68
  # Routing::Mapper::Scoping#namespace, and Routing::Mapper::Scoping#scope.
68
69
  #
69
- # == Non-resourceful routes
70
+ # ## Non-resourceful routes
70
71
  #
71
- # For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
72
- # 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`.
73
74
  #
74
- # get 'post/:id', to: 'posts#show'
75
- # post 'post/:id', to: 'posts#create_comment'
75
+ # get 'post/:id', to: 'posts#show'
76
+ # post 'post/:id', to: 'posts#create_comment'
76
77
  #
77
- # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
78
- # 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.
79
80
  #
80
- # If your route needs to respond to more than one HTTP method (or all methods) then using the
81
- # <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.
82
83
  #
83
- # match 'post/:id', to: 'posts#show', via: [:get, :post]
84
+ # match 'post/:id', to: 'posts#show', via: [:get, :post]
84
85
  #
85
- # == Named routes
86
+ # ## Named routes
86
87
  #
87
- # Routes can be named by passing an <tt>:as</tt> option,
88
- # allowing for easy reference within your source as +name_of_route_url+
89
- # 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.
90
91
  #
91
92
  # Example:
92
93
  #
93
- # # In config/routes.rb
94
- # get '/login', to: 'accounts#login', as: 'login'
94
+ # # In config/routes.rb
95
+ # get '/login', to: 'accounts#login', as: 'login'
95
96
  #
96
- # # With render, redirect_to, tests, etc.
97
- # redirect_to login_url
97
+ # # With render, redirect_to, tests, etc.
98
+ # redirect_to login_url
98
99
  #
99
100
  # Arguments can be passed as well.
100
101
  #
101
- # redirect_to show_item_path(id: 25)
102
+ # redirect_to show_item_path(id: 25)
102
103
  #
103
- # 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 "/".
104
105
  #
105
- # # In config/routes.rb
106
- # root to: 'blogs#index'
106
+ # # In config/routes.rb
107
+ # root to: 'blogs#index'
107
108
  #
108
- # # would recognize http://www.example.com/ as
109
- # params = { controller: 'blogs', action: 'index' }
109
+ # # would recognize http://www.example.com/ as
110
+ # params = { controller: 'blogs', action: 'index' }
110
111
  #
111
- # # and provide these named routes
112
- # root_url # => 'http://www.example.com/'
113
- # root_path # => '/'
112
+ # # and provide these named routes
113
+ # root_url # => 'http://www.example.com/'
114
+ # root_path # => '/'
114
115
  #
115
- # Note: when using +controller+, the route is simply named after the
116
- # 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.
117
118
  #
118
- # # In config/routes.rb
119
- # controller :blog do
120
- # get 'blog/show' => :list
121
- # get 'blog/delete' => :delete
122
- # get 'blog/edit' => :edit
123
- # 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
124
125
  #
125
- # # provides named routes for show, delete, and edit
126
- # 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)
127
128
  #
128
- # == Pretty URLs
129
+ # ## Pretty URLs
129
130
  #
130
131
  # Routes can generate pretty URLs. For example:
131
132
  #
132
- # get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
133
- # year: /\d{4}/,
134
- # month: /\d{1,2}/,
135
- # day: /\d{1,2}/
136
- # }
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
+ # }
137
138
  #
138
139
  # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
139
140
  # maps to
140
141
  #
141
- # params = {year: '2005', month: '11', day: '06'}
142
+ # params = {year: '2005', month: '11', day: '06'}
142
143
  #
143
- # == Regular Expressions and parameters
144
+ # ## Regular Expressions and parameters
144
145
  # You can specify a regular expression to define a format for a parameter.
145
146
  #
146
- # controller 'geocode' do
147
- # get 'geocode/:postalcode', to: :show, constraints: {
148
- # postalcode: /\d{5}(-\d{4})?/
149
- # }
150
- # end
147
+ # controller 'geocode' do
148
+ # get 'geocode/:postalcode', to: :show, constraints: {
149
+ # postalcode: /\d{5}(-\d{4})?/
150
+ # }
151
+ # end
151
152
  #
152
153
  # Constraints can include the 'ignorecase' and 'extended syntax' regular
153
154
  # expression modifiers:
154
155
  #
155
- # controller 'geocode' do
156
- # get 'geocode/:postalcode', to: :show, constraints: {
157
- # postalcode: /hx\d\d\s\d[a-z]{2}/i
158
- # }
159
- # end
160
- #
161
- # controller 'geocode' do
162
- # get 'geocode/:postalcode', to: :show, constraints: {
163
- # postalcode: /# Postalcode format
164
- # \d{5} #Prefix
165
- # (-\d{4})? #Suffix
166
- # /x
167
- # }
168
- # 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
169
170
  #
170
- # Using the multiline modifier will raise an +ArgumentError+.
171
- # Encoding regular expression modifiers are silently ignored. The
172
- # 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.
173
174
  #
174
- # == External redirects
175
+ # ## External redirects
175
176
  #
176
- # 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:
177
179
  #
178
- # get "/stories", to: redirect("/posts")
180
+ # get "/stories", to: redirect("/posts")
179
181
  #
180
- # == Unicode character routes
182
+ # ## Unicode character routes
181
183
  #
182
184
  # You can specify unicode character routes in your router:
183
185
  #
184
- # get "こんにちは", to: "welcome#index"
186
+ # get "こんにちは", to: "welcome#index"
185
187
  #
186
- # == Routing to Rack Applications
188
+ # ## Routing to Rack Applications
187
189
  #
188
- # Instead of a String, like <tt>posts#index</tt>, which corresponds to the
189
- # index action in the PostsController, you can specify any Rack application
190
- # 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:
191
193
  #
192
- # get "/application.js", to: Sprockets
194
+ # get "/application.js", to: Sprockets
193
195
  #
194
- # == Reloading routes
196
+ # ## Reloading routes
195
197
  #
196
198
  # You can reload routes if you feel you must:
197
199
  #
198
- # Rails.application.reload_routes!
200
+ # Rails.application.reload_routes!
199
201
  #
200
- # This will clear all named routes and reload config/routes.rb if the file has been modified from
201
- # 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!`.
202
204
  #
203
- # == Testing Routes
205
+ # ## Testing Routes
204
206
  #
205
207
  # The two main methods for testing your routes:
206
208
  #
207
- # === +assert_routing+
209
+ # ### `assert_routing`
208
210
  #
209
- # def test_movie_route_properly_splits
210
- # opts = {controller: "plugin", action: "checkout", id: "2"}
211
- # assert_routing "plugin/checkout/2", opts
212
- # 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
213
215
  #
214
- # +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.
215
218
  #
216
- # === +assert_recognizes+
219
+ # ### `assert_recognizes`
217
220
  #
218
- # def test_route_has_options
219
- # opts = {controller: "plugin", action: "show", id: "12"}
220
- # assert_recognizes opts, "/plugins/show/12"
221
- # end
221
+ # def test_route_has_options
222
+ # opts = {controller: "plugin", action: "show", id: "12"}
223
+ # assert_recognizes opts, "/plugins/show/12"
224
+ # end
222
225
  #
223
- # Note the subtle difference between the two: +assert_routing+ tests that
224
- # a URL fits options while +assert_recognizes+ tests that a URL
225
- # 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.
226
229
  #
227
- # 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`.
228
231
  #
229
- # def send_to_jail
230
- # get '/jail'
231
- # assert_response :success
232
- # end
232
+ # def send_to_jail
233
+ # get '/jail'
234
+ # assert_response :success
235
+ # end
233
236
  #
234
- # def goes_to_login
235
- # get login_url
236
- # #...
237
- # end
237
+ # def goes_to_login
238
+ # get login_url
239
+ # #...
240
+ # end
238
241
  #
239
- # == View a list of all your routes
242
+ # ## View a list of all your routes
240
243
  #
241
- # $ bin/rails routes
244
+ # $ bin/rails routes
242
245
  #
243
- # Target a specific controller with <tt>-c</tt>, or grep routes
244
- # using <tt>-g</tt>. Useful in conjunction with <tt>--expanded</tt>
245
- # 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.
246
248
  module Routing
247
249
  extend ActiveSupport::Autoload
248
250
 
@@ -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, +ActionDispatch::SystemTestCase+ 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 +ActionDispatch::SystemTestCase+ 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