actionpack 4.2.10 → 7.2.0.rc1

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 (202) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +86 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +13 -14
  5. data/lib/abstract_controller/asset_paths.rb +5 -1
  6. data/lib/abstract_controller/base.rb +166 -136
  7. data/lib/abstract_controller/caching/fragments.rb +149 -0
  8. data/lib/abstract_controller/caching.rb +68 -0
  9. data/lib/abstract_controller/callbacks.rb +126 -57
  10. data/lib/abstract_controller/collector.rb +13 -15
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +8 -0
  13. data/lib/abstract_controller/helpers.rb +181 -132
  14. data/lib/abstract_controller/logger.rb +5 -1
  15. data/lib/abstract_controller/railties/routes_helpers.rb +10 -3
  16. data/lib/abstract_controller/rendering.rb +56 -56
  17. data/lib/abstract_controller/translation.rb +29 -15
  18. data/lib/abstract_controller/url_for.rb +15 -11
  19. data/lib/abstract_controller.rb +21 -5
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +154 -0
  22. data/lib/action_controller/base.rb +219 -155
  23. data/lib/action_controller/caching.rb +28 -68
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +55 -0
  26. data/lib/action_controller/log_subscriber.rb +35 -22
  27. data/lib/action_controller/metal/allow_browser.rb +119 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +259 -122
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +9 -5
  32. data/lib/action_controller/metal/data_streaming.rb +87 -104
  33. data/lib/action_controller/metal/default_headers.rb +21 -0
  34. data/lib/action_controller/metal/etag_with_flash.rb +22 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +35 -26
  36. data/lib/action_controller/metal/exceptions.rb +71 -24
  37. data/lib/action_controller/metal/flash.rb +26 -19
  38. data/lib/action_controller/metal/head.rb +45 -36
  39. data/lib/action_controller/metal/helpers.rb +80 -64
  40. data/lib/action_controller/metal/http_authentication.rb +297 -244
  41. data/lib/action_controller/metal/implicit_render.rb +57 -9
  42. data/lib/action_controller/metal/instrumentation.rb +76 -64
  43. data/lib/action_controller/metal/live.rb +238 -176
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +177 -166
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +145 -118
  48. data/lib/action_controller/metal/permissions_policy.rb +38 -0
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +203 -64
  51. data/lib/action_controller/metal/renderers.rb +108 -65
  52. data/lib/action_controller/metal/rendering.rb +216 -56
  53. data/lib/action_controller/metal/request_forgery_protection.rb +496 -163
  54. data/lib/action_controller/metal/rescue.rb +19 -21
  55. data/lib/action_controller/metal/streaming.rb +179 -138
  56. data/lib/action_controller/metal/strong_parameters.rb +1058 -382
  57. data/lib/action_controller/metal/testing.rb +11 -17
  58. data/lib/action_controller/metal/url_for.rb +37 -21
  59. data/lib/action_controller/metal.rb +236 -138
  60. data/lib/action_controller/railtie.rb +89 -11
  61. data/lib/action_controller/railties/helpers.rb +5 -1
  62. data/lib/action_controller/renderer.rb +161 -0
  63. data/lib/action_controller/template_assertions.rb +13 -0
  64. data/lib/action_controller/test_case.rb +425 -497
  65. data/lib/action_controller.rb +44 -22
  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 +119 -63
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +364 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +36 -34
  72. data/lib/action_dispatch/http/filter_redirect.rb +24 -12
  73. data/lib/action_dispatch/http/headers.rb +66 -31
  74. data/lib/action_dispatch/http/mime_negotiation.rb +106 -75
  75. data/lib/action_dispatch/http/mime_type.rb +196 -136
  76. data/lib/action_dispatch/http/mime_types.rb +25 -7
  77. data/lib/action_dispatch/http/parameters.rb +97 -45
  78. data/lib/action_dispatch/http/permissions_policy.rb +187 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +6 -0
  80. data/lib/action_dispatch/http/request.rb +299 -170
  81. data/lib/action_dispatch/http/response.rb +311 -160
  82. data/lib/action_dispatch/http/upload.rb +52 -23
  83. data/lib/action_dispatch/http/url.rb +201 -125
  84. data/lib/action_dispatch/journey/formatter.rb +110 -50
  85. data/lib/action_dispatch/journey/gtg/builder.rb +37 -50
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +20 -17
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +96 -36
  88. data/lib/action_dispatch/journey/nfa/dot.rb +5 -14
  89. data/lib/action_dispatch/journey/nodes/node.rb +100 -20
  90. data/lib/action_dispatch/journey/parser.rb +19 -17
  91. data/lib/action_dispatch/journey/parser.y +4 -3
  92. data/lib/action_dispatch/journey/parser_extras.rb +14 -4
  93. data/lib/action_dispatch/journey/path/pattern.rb +79 -63
  94. data/lib/action_dispatch/journey/route.rb +108 -44
  95. data/lib/action_dispatch/journey/router/utils.rb +41 -29
  96. data/lib/action_dispatch/journey/router.rb +64 -57
  97. data/lib/action_dispatch/journey/routes.rb +23 -21
  98. data/lib/action_dispatch/journey/scanner.rb +28 -17
  99. data/lib/action_dispatch/journey/visitors.rb +100 -54
  100. data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
  101. data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
  102. data/lib/action_dispatch/journey.rb +7 -5
  103. data/lib/action_dispatch/log_subscriber.rb +25 -0
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  106. data/lib/action_dispatch/middleware/callbacks.rb +7 -6
  107. data/lib/action_dispatch/middleware/cookies.rb +471 -328
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +149 -66
  109. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  110. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +275 -73
  112. data/lib/action_dispatch/middleware/executor.rb +32 -0
  113. data/lib/action_dispatch/middleware/flash.rb +143 -101
  114. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +36 -27
  116. data/lib/action_dispatch/middleware/reloader.rb +10 -92
  117. data/lib/action_dispatch/middleware/remote_ip.rb +133 -107
  118. data/lib/action_dispatch/middleware/request_id.rb +29 -15
  119. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +49 -27
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +33 -16
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +86 -80
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +66 -36
  125. data/lib/action_dispatch/middleware/ssl.rb +134 -36
  126. data/lib/action_dispatch/middleware/stack.rb +109 -44
  127. data/lib/action_dispatch/middleware/static.rb +159 -90
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +7 -24
  132. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
  136. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -7
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +3 -3
  140. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +139 -15
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +6 -6
  146. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +7 -7
  147. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +9 -9
  148. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  149. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
  150. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
  151. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +7 -4
  152. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +125 -93
  153. data/lib/action_dispatch/railtie.rb +44 -16
  154. data/lib/action_dispatch/request/session.rb +159 -69
  155. data/lib/action_dispatch/request/utils.rb +97 -23
  156. data/lib/action_dispatch/routing/endpoint.rb +11 -2
  157. data/lib/action_dispatch/routing/inspector.rb +195 -106
  158. data/lib/action_dispatch/routing/mapper.rb +1338 -955
  159. data/lib/action_dispatch/routing/polymorphic_routes.rb +234 -201
  160. data/lib/action_dispatch/routing/redirection.rb +78 -51
  161. data/lib/action_dispatch/routing/route_set.rb +460 -374
  162. data/lib/action_dispatch/routing/routes_proxy.rb +36 -12
  163. data/lib/action_dispatch/routing/url_for.rb +172 -124
  164. data/lib/action_dispatch/routing.rb +159 -158
  165. data/lib/action_dispatch/system_test_case.rb +206 -0
  166. data/lib/action_dispatch/system_testing/browser.rb +84 -0
  167. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  168. data/lib/action_dispatch/system_testing/server.rb +33 -0
  169. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  170. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  171. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  172. data/lib/action_dispatch/testing/assertions/response.rb +71 -39
  173. data/lib/action_dispatch/testing/assertions/routing.rb +228 -103
  174. data/lib/action_dispatch/testing/assertions.rb +9 -6
  175. data/lib/action_dispatch/testing/integration.rb +486 -306
  176. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  177. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  178. data/lib/action_dispatch/testing/test_process.rb +35 -22
  179. data/lib/action_dispatch/testing/test_request.rb +29 -34
  180. data/lib/action_dispatch/testing/test_response.rb +48 -15
  181. data/lib/action_dispatch.rb +82 -40
  182. data/lib/action_pack/gem_version.rb +8 -4
  183. data/lib/action_pack/version.rb +6 -2
  184. data/lib/action_pack.rb +21 -18
  185. metadata +146 -56
  186. data/lib/action_controller/caching/fragments.rb +0 -103
  187. data/lib/action_controller/metal/force_ssl.rb +0 -97
  188. data/lib/action_controller/metal/hide_actions.rb +0 -40
  189. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  190. data/lib/action_controller/middleware.rb +0 -39
  191. data/lib/action_controller/model_naming.rb +0 -12
  192. data/lib/action_dispatch/http/parameter_filter.rb +0 -72
  193. data/lib/action_dispatch/journey/backwards.rb +0 -5
  194. data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
  195. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
  196. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
  197. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  198. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  199. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +0 -27
  200. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  201. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  202. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "nokogiri"
6
+
7
+ module ActionDispatch
8
+ class RequestEncoder # :nodoc:
9
+ class IdentityEncoder
10
+ def content_type; end
11
+ def accept_header; end
12
+ def encode_params(params); params; end
13
+ def response_parser; -> body { body }; end
14
+ end
15
+
16
+ @encoders = { identity: IdentityEncoder.new }
17
+
18
+ attr_reader :response_parser
19
+
20
+ def initialize(mime_name, param_encoder, response_parser)
21
+ @mime = Mime[mime_name]
22
+
23
+ unless @mime
24
+ raise ArgumentError, "Can't register a request encoder for " \
25
+ "unregistered MIME Type: #{mime_name}. See `Mime::Type.register`."
26
+ end
27
+
28
+ @response_parser = response_parser || -> body { body }
29
+ @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
30
+ end
31
+
32
+ def content_type
33
+ @mime.to_s
34
+ end
35
+
36
+ def accept_header
37
+ @mime.to_s
38
+ end
39
+
40
+ def encode_params(params)
41
+ @param_encoder.call(params) if params
42
+ end
43
+
44
+ def self.parser(content_type)
45
+ type = Mime::Type.lookup(content_type).ref if content_type
46
+ encoder(type).response_parser
47
+ end
48
+
49
+ def self.encoder(name)
50
+ @encoders[name] || @encoders[:identity]
51
+ end
52
+
53
+ def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil)
54
+ @encoders[mime_name] = new(mime_name, param_encoder, response_parser)
55
+ end
56
+
57
+ register_encoder :html, response_parser: -> body { Rails::Dom::Testing.html_document.parse(body) }
58
+ register_encoder :json, response_parser: -> body { JSON.parse(body, object_class: ActiveSupport::HashWithIndifferentAccess) }
59
+ end
60
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch
4
+ module TestHelpers
5
+ module PageDumpHelper
6
+ class InvalidResponse < StandardError; end
7
+
8
+ # Saves the content of response body to a file and tries to open it in your browser.
9
+ # Launchy must be present in your Gemfile for the page to open automatically.
10
+ def save_and_open_page(path = html_dump_default_path)
11
+ save_page(path).tap { |s_path| open_file(s_path) }
12
+ end
13
+
14
+ private
15
+ def save_page(path = html_dump_default_path)
16
+ raise InvalidResponse.new("Response is a redirection!") if response.redirection?
17
+ path = Pathname.new(path)
18
+ path.dirname.mkpath
19
+ File.write(path, response.body)
20
+ path
21
+ end
22
+
23
+ def open_file(path)
24
+ require "launchy"
25
+ Launchy.open(path)
26
+ rescue LoadError
27
+ warn "File saved to #{path}.\nPlease install the launchy gem to open the file automatically."
28
+ end
29
+
30
+ def html_dump_default_path
31
+ Rails.root.join("tmp/html_dump", "#{method_name}_#{DateTime.current.to_i}.html").to_s
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,13 +1,41 @@
1
- require 'action_dispatch/middleware/cookies'
2
- require 'action_dispatch/middleware/flash'
3
- require 'active_support/core_ext/hash/indifferent_access'
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "action_dispatch/middleware/cookies"
6
+ require "action_dispatch/middleware/flash"
4
7
 
5
8
  module ActionDispatch
6
9
  module TestProcess
10
+ module FixtureFile
11
+ # Shortcut for
12
+ # `Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.file_f
13
+ # ixture_path, path), type)`:
14
+ #
15
+ # post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png') }
16
+ #
17
+ # Default fixture files location is `test/fixtures/files`.
18
+ #
19
+ # To upload binary files on Windows, pass `:binary` as the last parameter. This
20
+ # will not affect other platforms:
21
+ #
22
+ # post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png', :binary) }
23
+ def file_fixture_upload(path, mime_type = nil, binary = false)
24
+ if self.class.file_fixture_path && !File.exist?(path)
25
+ path = file_fixture(path)
26
+ end
27
+
28
+ Rack::Test::UploadedFile.new(path, mime_type, binary)
29
+ end
30
+ alias_method :fixture_file_upload, :file_fixture_upload
31
+ end
32
+
33
+ include FixtureFile
34
+
7
35
  def assigns(key = nil)
8
- assigns = {}.with_indifferent_access
9
- @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
10
- key.nil? ? assigns : assigns[key]
36
+ raise NoMethodError,
37
+ 'assigns has been extracted to a gem. To continue using it,
38
+ add `gem "rails-controller-testing"` to your Gemfile.'
11
39
  end
12
40
 
13
41
  def session
@@ -19,26 +47,11 @@ module ActionDispatch
19
47
  end
20
48
 
21
49
  def cookies
22
- @request.cookie_jar
50
+ @cookie_jar ||= Cookies::CookieJar.build(@request, @request.cookies)
23
51
  end
24
52
 
25
53
  def redirect_to_url
26
54
  @response.redirect_url
27
55
  end
28
-
29
- # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionController::TestCase.fixture_path, path), type)</tt>:
30
- #
31
- # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png')
32
- #
33
- # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
34
- # This will not affect other platforms:
35
- #
36
- # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary)
37
- def fixture_file_upload(path, mime_type = nil, binary = false)
38
- if self.class.respond_to?(:fixture_path) && self.class.fixture_path
39
- path = File.join(self.class.fixture_path, path)
40
- end
41
- Rack::Test::UploadedFile.new(path, mime_type, binary)
42
- end
43
56
  end
44
57
  end
@@ -1,41 +1,48 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
2
- require 'rack/utils'
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "active_support/core_ext/hash/indifferent_access"
6
+ require "rack/utils"
3
7
 
4
8
  module ActionDispatch
5
9
  class TestRequest < Request
6
- DEFAULT_ENV = Rack::MockRequest.env_for('/',
7
- 'HTTP_HOST' => 'test.host',
8
- 'REMOTE_ADDR' => '0.0.0.0',
9
- 'HTTP_USER_AGENT' => 'Rails Testing'
10
+ DEFAULT_ENV = Rack::MockRequest.env_for("/",
11
+ "HTTP_HOST" => "test.host".b,
12
+ "REMOTE_ADDR" => "0.0.0.0".b,
13
+ "HTTP_USER_AGENT" => "Rails Testing".b,
10
14
  )
11
15
 
12
- def self.new(env = {})
13
- super
16
+ # Create a new test request with default `env` values.
17
+ def self.create(env = {})
18
+ env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
19
+ env["rack.request.cookie_hash"] ||= {}.with_indifferent_access
20
+ new(default_env.merge(env))
14
21
  end
15
22
 
16
- def initialize(env = {})
17
- env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
18
- super(default_env.merge(env))
23
+ def self.default_env
24
+ DEFAULT_ENV
19
25
  end
26
+ private_class_method :default_env
20
27
 
21
28
  def request_method=(method)
22
- @env['REQUEST_METHOD'] = method.to_s.upcase
29
+ super(method.to_s.upcase)
23
30
  end
24
31
 
25
32
  def host=(host)
26
- @env['HTTP_HOST'] = host
33
+ set_header("HTTP_HOST", host)
27
34
  end
28
35
 
29
36
  def port=(number)
30
- @env['SERVER_PORT'] = number.to_i
37
+ set_header("SERVER_PORT", number)
31
38
  end
32
39
 
33
40
  def request_uri=(uri)
34
- @env['REQUEST_URI'] = uri
41
+ set_header("REQUEST_URI", uri)
35
42
  end
36
43
 
37
44
  def path=(path)
38
- @env['PATH_INFO'] = path
45
+ set_header("PATH_INFO", path)
39
46
  end
40
47
 
41
48
  def action=(action_name)
@@ -43,36 +50,24 @@ module ActionDispatch
43
50
  end
44
51
 
45
52
  def if_modified_since=(last_modified)
46
- @env['HTTP_IF_MODIFIED_SINCE'] = last_modified
53
+ set_header("HTTP_IF_MODIFIED_SINCE", last_modified)
47
54
  end
48
55
 
49
56
  def if_none_match=(etag)
50
- @env['HTTP_IF_NONE_MATCH'] = etag
57
+ set_header("HTTP_IF_NONE_MATCH", etag)
51
58
  end
52
59
 
53
60
  def remote_addr=(addr)
54
- @env['REMOTE_ADDR'] = addr
61
+ set_header("REMOTE_ADDR", addr)
55
62
  end
56
63
 
57
64
  def user_agent=(user_agent)
58
- @env['HTTP_USER_AGENT'] = user_agent
65
+ set_header("HTTP_USER_AGENT", user_agent)
59
66
  end
60
67
 
61
68
  def accept=(mime_types)
62
- @env.delete('action_dispatch.request.accepts')
63
- @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",")
64
- end
65
-
66
- alias :rack_cookies :cookies
67
-
68
- def cookies
69
- @cookies ||= {}.with_indifferent_access
70
- end
71
-
72
- private
73
-
74
- def default_env
75
- DEFAULT_ENV
69
+ delete_header("action_dispatch.request.accepts")
70
+ set_header("HTTP_ACCEPT", Array(mime_types).collect(&:to_s).join(","))
76
71
  end
77
72
  end
78
73
  end
@@ -1,25 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "action_dispatch/testing/request_encoder"
6
+
1
7
  module ActionDispatch
2
- # Integration test methods such as ActionDispatch::Integration::Session#get
3
- # and ActionDispatch::Integration::Session#post return objects of class
4
- # TestResponse, which represent the HTTP response results of the requested
5
- # controller actions.
8
+ # Integration test methods such as Integration::RequestHelpers#get and
9
+ # Integration::RequestHelpers#post return objects of class TestResponse, which
10
+ # represent the HTTP response results of the requested controller actions.
6
11
  #
7
12
  # See Response for more information on controller response objects.
8
13
  class TestResponse < Response
9
14
  def self.from_response(response)
10
- new response.status, response.headers, response.body, default_headers: nil
15
+ new response.status, response.headers, response.body
11
16
  end
12
17
 
13
- # Was the response successful?
14
- alias_method :success?, :successful?
15
-
16
- # Was the URL not found?
17
- alias_method :missing?, :not_found?
18
-
19
- # Were we redirected?
20
- alias_method :redirect?, :redirection?
18
+ # Returns a parsed body depending on the response MIME type. When a parser
19
+ # corresponding to the MIME type is not found, it returns the raw body.
20
+ #
21
+ # #### Examples
22
+ # get "/posts"
23
+ # response.content_type # => "text/html; charset=utf-8"
24
+ # response.parsed_body.class # => Nokogiri::HTML5::Document
25
+ # response.parsed_body.to_html # => "<!DOCTYPE html>\n<html>\n..."
26
+ #
27
+ # assert_pattern { response.parsed_body.at("main") => { content: "Hello, world" } }
28
+ #
29
+ # response.parsed_body.at("main") => {name:, content:}
30
+ # assert_equal "main", name
31
+ # assert_equal "Some main content", content
32
+ #
33
+ # get "/posts.json"
34
+ # response.content_type # => "application/json; charset=utf-8"
35
+ # response.parsed_body.class # => Array
36
+ # response.parsed_body # => [{"id"=>42, "title"=>"Title"},...
37
+ #
38
+ # assert_pattern { response.parsed_body => [{ id: 42 }] }
39
+ #
40
+ # get "/posts/42.json"
41
+ # response.content_type # => "application/json; charset=utf-8"
42
+ # response.parsed_body.class # => ActiveSupport::HashWithIndifferentAccess
43
+ # response.parsed_body # => {"id"=>42, "title"=>"Title"}
44
+ #
45
+ # assert_pattern { response.parsed_body => [{ title: /title/i }] }
46
+ #
47
+ # response.parsed_body => {id:, title:}
48
+ # assert_equal 42, id
49
+ # assert_equal "Title", title
50
+ def parsed_body
51
+ @parsed_body ||= response_parser.call(body)
52
+ end
21
53
 
22
- # Was there a server-side error?
23
- alias_method :error?, :server_error?
54
+ def response_parser
55
+ @response_parser ||= RequestEncoder.parser(media_type)
56
+ end
24
57
  end
25
58
  end
@@ -1,68 +1,89 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Copyright (c) 2004-2014 David Heinemeier Hansson
4
+ # Copyright (c) David Heinemeier Hansson
3
5
  #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
11
12
  #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
14
15
  #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
22
23
  #++
23
24
 
24
- require 'active_support'
25
- require 'active_support/rails'
26
- require 'active_support/core_ext/module/attribute_accessors'
25
+ # :markup: markdown
26
+
27
+ require "active_support"
28
+ require "active_support/rails"
29
+ require "active_support/core_ext/module/attribute_accessors"
27
30
 
28
- require 'action_pack'
29
- require 'rack'
31
+ require "action_pack"
32
+ require "rack"
33
+ require "action_dispatch/deprecator"
30
34
 
31
- module Rack
32
- autoload :Test, 'rack/test'
35
+ module Rack # :nodoc:
36
+ autoload :Test, "rack/test"
33
37
  end
34
38
 
39
+ # # Action Dispatch
40
+ #
41
+ # Action Dispatch is a module of Action Pack.
42
+ #
43
+ # Action Dispatch parses information about the web request, handles routing as
44
+ # defined by the user, and does advanced processing related to HTTP such as
45
+ # MIME-type negotiation, decoding parameters in POST, PATCH, or PUT bodies,
46
+ # handling HTTP caching logic, cookies and sessions.
35
47
  module ActionDispatch
36
48
  extend ActiveSupport::Autoload
37
49
 
38
- class IllegalStateError < StandardError
50
+ class MissingController < NameError
39
51
  end
40
52
 
41
53
  eager_autoload do
42
- autoload_under 'http' do
54
+ autoload_under "http" do
55
+ autoload :ContentSecurityPolicy
56
+ autoload :PermissionsPolicy
43
57
  autoload :Request
44
58
  autoload :Response
45
59
  end
46
60
  end
47
61
 
48
- autoload_under 'middleware' do
62
+ autoload_under "middleware" do
63
+ autoload :AssumeSSL
64
+ autoload :HostAuthorization
49
65
  autoload :RequestId
50
66
  autoload :Callbacks
51
67
  autoload :Cookies
68
+ autoload :ActionableExceptions
52
69
  autoload :DebugExceptions
70
+ autoload :DebugLocks
71
+ autoload :DebugView
53
72
  autoload :ExceptionWrapper
73
+ autoload :Executor
54
74
  autoload :Flash
55
- autoload :ParamsParser
56
75
  autoload :PublicExceptions
57
76
  autoload :Reloader
58
77
  autoload :RemoteIp
78
+ autoload :ServerTiming
59
79
  autoload :ShowExceptions
60
80
  autoload :SSL
61
81
  autoload :Static
62
82
  end
63
83
 
84
+ autoload :Constants
64
85
  autoload :Journey
65
- autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
86
+ autoload :MiddlewareStack, "action_dispatch/middleware/stack"
66
87
  autoload :Routing
67
88
 
68
89
  module Http
@@ -72,34 +93,55 @@ module ActionDispatch
72
93
  autoload :Headers
73
94
  autoload :MimeNegotiation
74
95
  autoload :Parameters
75
- autoload :ParameterFilter
76
- autoload :Upload
77
- autoload :UploadedFile, 'action_dispatch/http/upload'
96
+ autoload :UploadedFile, "action_dispatch/http/upload"
78
97
  autoload :URL
79
98
  end
80
99
 
81
100
  module Session
82
- autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store'
83
- autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store'
84
- autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store'
85
- autoload :CacheStore, 'action_dispatch/middleware/session/cache_store'
101
+ autoload :AbstractStore, "action_dispatch/middleware/session/abstract_store"
102
+ autoload :AbstractSecureStore, "action_dispatch/middleware/session/abstract_store"
103
+ autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
104
+ autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
105
+ autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
106
+
107
+ def self.resolve_store(session_store) # :nodoc:
108
+ self.const_get(session_store.to_s.camelize)
109
+ rescue NameError
110
+ raise <<~ERROR
111
+ Unable to resolve session store #{session_store.inspect}.
112
+
113
+ #{session_store.inspect} resolves to ActionDispatch::Session::#{session_store.to_s.camelize},
114
+ but that class is undefined.
115
+
116
+ Is #{session_store.inspect} spelled correctly, and are any necessary gems installed?
117
+ ERROR
118
+ end
86
119
  end
87
120
 
88
121
  mattr_accessor :test_app
89
122
 
90
- autoload_under 'testing' do
123
+ autoload_under "testing" do
91
124
  autoload :Assertions
92
125
  autoload :Integration
93
- autoload :IntegrationTest, 'action_dispatch/testing/integration'
126
+ autoload :IntegrationTest, "action_dispatch/testing/integration"
94
127
  autoload :TestProcess
95
128
  autoload :TestRequest
96
129
  autoload :TestResponse
130
+ autoload :AssertionResponse
131
+ end
132
+
133
+ autoload :SystemTestCase, "action_dispatch/system_test_case"
134
+
135
+ def eager_load!
136
+ super
137
+ Routing.eager_load!
97
138
  end
98
139
  end
99
140
 
100
- autoload :Mime, 'action_dispatch/http/mime_type'
141
+ autoload :Mime, "action_dispatch/http/mime_type"
101
142
 
102
143
  ActiveSupport.on_load(:action_view) do
103
144
  ActionView::Base.default_formats ||= Mime::SET.symbols
104
- ActionView::Template::Types.delegate_to Mime
145
+ ActionView::Template.mime_types_implementation = Mime
146
+ ActionView::LookupContext::DetailsKey.clear
105
147
  end
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
1
5
  module ActionPack
2
- # Returns the version of the currently loaded Action Pack as a <tt>Gem::Version</tt>
6
+ # Returns the currently loaded version of Action Pack as a `Gem::Version`.
3
7
  def self.gem_version
4
8
  Gem::Version.new VERSION::STRING
5
9
  end
6
10
 
7
11
  module VERSION
8
- MAJOR = 4
12
+ MAJOR = 7
9
13
  MINOR = 2
10
- TINY = 10
11
- PRE = nil
14
+ TINY = 0
15
+ PRE = "rc1"
12
16
 
13
17
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
18
  end
@@ -1,7 +1,11 @@
1
- require_relative 'gem_version'
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require_relative "gem_version"
2
6
 
3
7
  module ActionPack
4
- # Returns the version of the currently loaded ActionPack as a <tt>Gem::Version</tt>
8
+ # Returns the currently loaded version of Action Pack as a `Gem::Version`.
5
9
  def self.version
6
10
  gem_version
7
11
  end
data/lib/action_pack.rb CHANGED
@@ -1,24 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Copyright (c) 2004-2014 David Heinemeier Hansson
4
+ # Copyright (c) David Heinemeier Hansson
3
5
  #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
11
12
  #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
14
15
  #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
22
23
  #++
23
24
 
24
- require 'action_pack/version'
25
+ # :markup: markdown
26
+
27
+ require "action_pack/version"