actionpack 4.2.11.3 → 5.0.0.beta1

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 (125) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +379 -462
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller.rb +0 -2
  6. data/lib/abstract_controller/base.rb +17 -32
  7. data/lib/abstract_controller/callbacks.rb +52 -19
  8. data/lib/abstract_controller/collector.rb +4 -9
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  11. data/lib/abstract_controller/rendering.rb +27 -22
  12. data/lib/abstract_controller/translation.rb +8 -7
  13. data/lib/action_controller.rb +4 -3
  14. data/lib/action_controller/api.rb +146 -0
  15. data/lib/action_controller/base.rb +6 -10
  16. data/lib/action_controller/caching.rb +1 -3
  17. data/lib/action_controller/caching/fragments.rb +48 -3
  18. data/lib/action_controller/form_builder.rb +48 -0
  19. data/lib/action_controller/log_subscriber.rb +1 -10
  20. data/lib/action_controller/metal.rb +89 -62
  21. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  22. data/lib/action_controller/metal/conditional_get.rb +65 -24
  23. data/lib/action_controller/metal/cookies.rb +0 -2
  24. data/lib/action_controller/metal/data_streaming.rb +2 -22
  25. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  26. data/lib/action_controller/metal/exceptions.rb +11 -6
  27. data/lib/action_controller/metal/force_ssl.rb +6 -6
  28. data/lib/action_controller/metal/head.rb +14 -7
  29. data/lib/action_controller/metal/helpers.rb +9 -5
  30. data/lib/action_controller/metal/http_authentication.rb +37 -38
  31. data/lib/action_controller/metal/implicit_render.rb +23 -6
  32. data/lib/action_controller/metal/instrumentation.rb +0 -1
  33. data/lib/action_controller/metal/live.rb +17 -55
  34. data/lib/action_controller/metal/mime_responds.rb +17 -37
  35. data/lib/action_controller/metal/params_wrapper.rb +8 -8
  36. data/lib/action_controller/metal/redirecting.rb +32 -9
  37. data/lib/action_controller/metal/renderers.rb +10 -8
  38. data/lib/action_controller/metal/rendering.rb +38 -6
  39. data/lib/action_controller/metal/request_forgery_protection.rb +67 -35
  40. data/lib/action_controller/metal/rescue.rb +2 -4
  41. data/lib/action_controller/metal/streaming.rb +4 -4
  42. data/lib/action_controller/metal/strong_parameters.rb +231 -78
  43. data/lib/action_controller/metal/testing.rb +1 -12
  44. data/lib/action_controller/metal/url_for.rb +12 -5
  45. data/lib/action_controller/renderer.rb +111 -0
  46. data/lib/action_controller/template_assertions.rb +9 -0
  47. data/lib/action_controller/test_case.rb +267 -363
  48. data/lib/action_dispatch.rb +2 -1
  49. data/lib/action_dispatch/http/cache.rb +23 -26
  50. data/lib/action_dispatch/http/filter_parameters.rb +6 -8
  51. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  52. data/lib/action_dispatch/http/headers.rb +28 -11
  53. data/lib/action_dispatch/http/mime_negotiation.rb +40 -26
  54. data/lib/action_dispatch/http/mime_type.rb +92 -61
  55. data/lib/action_dispatch/http/mime_types.rb +1 -4
  56. data/lib/action_dispatch/http/parameter_filter.rb +18 -8
  57. data/lib/action_dispatch/http/parameters.rb +45 -41
  58. data/lib/action_dispatch/http/request.rb +146 -82
  59. data/lib/action_dispatch/http/response.rb +180 -99
  60. data/lib/action_dispatch/http/url.rb +117 -8
  61. data/lib/action_dispatch/journey/formatter.rb +34 -28
  62. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  64. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  65. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  66. data/lib/action_dispatch/journey/parser_extras.rb +4 -0
  67. data/lib/action_dispatch/journey/path/pattern.rb +37 -41
  68. data/lib/action_dispatch/journey/route.rb +71 -17
  69. data/lib/action_dispatch/journey/router.rb +5 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  71. data/lib/action_dispatch/journey/routes.rb +14 -15
  72. data/lib/action_dispatch/journey/visitors.rb +86 -43
  73. data/lib/action_dispatch/middleware/cookies.rb +184 -135
  74. data/lib/action_dispatch/middleware/debug_exceptions.rb +115 -45
  75. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -20
  76. data/lib/action_dispatch/middleware/flash.rb +61 -45
  77. data/lib/action_dispatch/middleware/load_interlock.rb +21 -0
  78. data/lib/action_dispatch/middleware/params_parser.rb +30 -46
  79. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  80. data/lib/action_dispatch/middleware/reloader.rb +2 -4
  81. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  82. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  83. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  84. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  85. data/lib/action_dispatch/middleware/session/cookie_store.rb +29 -23
  86. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  87. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  88. data/lib/action_dispatch/middleware/ssl.rb +93 -36
  89. data/lib/action_dispatch/middleware/stack.rb +43 -48
  90. data/lib/action_dispatch/middleware/static.rb +52 -40
  91. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  92. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  95. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  97. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  98. data/lib/action_dispatch/railtie.rb +0 -2
  99. data/lib/action_dispatch/request/session.rb +66 -34
  100. data/lib/action_dispatch/request/utils.rb +51 -19
  101. data/lib/action_dispatch/routing.rb +3 -8
  102. data/lib/action_dispatch/routing/inspector.rb +6 -30
  103. data/lib/action_dispatch/routing/mapper.rb +447 -322
  104. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  105. data/lib/action_dispatch/routing/redirection.rb +3 -3
  106. data/lib/action_dispatch/routing/route_set.rb +124 -227
  107. data/lib/action_dispatch/routing/url_for.rb +27 -10
  108. data/lib/action_dispatch/testing/assertions.rb +1 -1
  109. data/lib/action_dispatch/testing/assertions/response.rb +27 -9
  110. data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
  111. data/lib/action_dispatch/testing/integration.rb +237 -76
  112. data/lib/action_dispatch/testing/test_process.rb +5 -5
  113. data/lib/action_dispatch/testing/test_request.rb +12 -21
  114. data/lib/action_dispatch/testing/test_response.rb +1 -4
  115. data/lib/action_pack.rb +1 -1
  116. data/lib/action_pack/gem_version.rb +4 -4
  117. metadata +26 -25
  118. data/lib/action_controller/metal/hide_actions.rb +0 -40
  119. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  120. data/lib/action_controller/middleware.rb +0 -39
  121. data/lib/action_controller/model_naming.rb +0 -12
  122. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  123. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  124. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  125. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -2,19 +2,8 @@ module ActionController
2
2
  module Testing
3
3
  extend ActiveSupport::Concern
4
4
 
5
- include RackDelegation
6
-
7
- # TODO : Rewrite tests using controller.headers= to use Rack env
8
- def headers=(new_headers)
9
- @_response ||= ActionDispatch::Response.new
10
- @_response.headers.replace(new_headers)
11
- end
12
-
13
5
  # Behavior specific to functional tests
14
6
  module Functional # :nodoc:
15
- def set_response!(request)
16
- end
17
-
18
7
  def recycle!
19
8
  @_url_options = nil
20
9
  self.formats = nil
@@ -24,7 +13,7 @@ module ActionController
24
13
 
25
14
  module ClassMethods
26
15
  def before_filters
27
- _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
16
+ _process_action_callbacks.find_all{|x| x.kind == :before}.map(&:name)
28
17
  end
29
18
  end
30
19
  end
@@ -4,7 +4,10 @@ module ActionController
4
4
  #
5
5
  # In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
6
6
  # url options like the +host+. In order to do so, this module requires the host class
7
- # to implement +env+ and +request+, which need to be a Rack-compatible.
7
+ # to implement +env+ which needs to be Rack-compatible and +request+
8
+ # which is either an instance of +ActionDispatch::Request+ or an object
9
+ # that responds to the +host+, +optional_port+, +protocol+ and
10
+ # +symbolized_path_parameter+ methods.
8
11
  #
9
12
  # class RootUrl
10
13
  # include ActionController::UrlFor
@@ -30,15 +33,19 @@ module ActionController
30
33
  :_recall => request.path_parameters
31
34
  }.merge!(super).freeze
32
35
 
33
- if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) ||
34
- (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
35
- (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze])
36
+ if (same_origin = _routes.equal?(request.routes)) ||
37
+ (script_name = request.engine_script_name(_routes)) ||
38
+ (original_script_name = request.original_script_name)
36
39
 
37
40
  options = @_url_options.dup
38
41
  if original_script_name
39
42
  options[:original_script_name] = original_script_name
40
43
  else
41
- options[:script_name] = same_origin ? request.script_name.dup : script_name
44
+ if same_origin
45
+ options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
46
+ else
47
+ options[:script_name] = script_name
48
+ end
42
49
  end
43
50
  options.freeze
44
51
  else
@@ -0,0 +1,111 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
3
+ module ActionController
4
+ # ActionController::Renderer allows to render arbitrary templates
5
+ # without requirement of being in controller actions.
6
+ #
7
+ # You get a concrete renderer class by invoking ActionController::Base#renderer.
8
+ # For example,
9
+ #
10
+ # ApplicationController.renderer
11
+ #
12
+ # It allows you to call method #render directly.
13
+ #
14
+ # ApplicationController.renderer.render template: '...'
15
+ #
16
+ # You can use a shortcut on controller to replace previous example with:
17
+ #
18
+ # ApplicationController.render template: '...'
19
+ #
20
+ # #render method allows you to use any options as when rendering in controller.
21
+ # For example,
22
+ #
23
+ # FooController.render :action, locals: { ... }, assigns: { ... }
24
+ #
25
+ # The template will be rendered in a Rack environment which is accessible through
26
+ # ActionController::Renderer#env. You can set it up in two ways:
27
+ #
28
+ # * by changing renderer defaults, like
29
+ #
30
+ # ApplicationController.renderer.defaults # => hash with default Rack environment
31
+ #
32
+ # * by initializing an instance of renderer by passing it a custom environment.
33
+ #
34
+ # ApplicationController.renderer.new(method: 'post', https: true)
35
+ #
36
+ class Renderer
37
+ attr_reader :defaults, :controller
38
+
39
+ DEFAULTS = {
40
+ http_host: 'example.org',
41
+ https: false,
42
+ method: 'get',
43
+ script_name: '',
44
+ input: ''
45
+ }.freeze
46
+
47
+ # Create a new renderer instance for a specific controller class.
48
+ def self.for(controller, env = {}, defaults = DEFAULTS)
49
+ new(controller, env, defaults)
50
+ end
51
+
52
+ # Create a new renderer for the same controller but with a new env.
53
+ def new(env = {})
54
+ self.class.new controller, env, defaults
55
+ end
56
+
57
+ # Create a new renderer for the same controller but with new defaults.
58
+ def with_defaults(defaults)
59
+ self.class.new controller, env, self.defaults.merge(defaults)
60
+ end
61
+
62
+ # Accepts a custom Rack environment to render templates in.
63
+ # It will be merged with ActionController::Renderer.defaults
64
+ def initialize(controller, env, defaults)
65
+ @controller = controller
66
+ @defaults = defaults
67
+ @env = normalize_keys defaults.merge(env)
68
+ end
69
+
70
+ # Render templates with any options from ActionController::Base#render_to_string.
71
+ def render(*args)
72
+ raise 'missing controller' unless controller
73
+
74
+ request = ActionDispatch::Request.new @env
75
+ request.routes = controller._routes
76
+
77
+ instance = controller.new
78
+ instance.set_request! request
79
+ instance.set_response! controller.make_response!(request)
80
+ instance.render_to_string(*args)
81
+ end
82
+
83
+ private
84
+ def normalize_keys(env)
85
+ new_env = {}
86
+ env.each_pair { |k,v| new_env[rack_key_for(k)] = rack_value_for(k, v) }
87
+ new_env
88
+ end
89
+
90
+ RACK_KEY_TRANSLATION = {
91
+ http_host: 'HTTP_HOST',
92
+ https: 'HTTPS',
93
+ method: 'REQUEST_METHOD',
94
+ script_name: 'SCRIPT_NAME',
95
+ input: 'rack.input'
96
+ }
97
+
98
+ IDENTITY = ->(_) { _ }
99
+
100
+ RACK_VALUE_TRANSLATION = {
101
+ https: ->(v) { v ? 'on' : 'off' },
102
+ method: ->(v) { v.upcase },
103
+ }
104
+
105
+ def rack_key_for(key); RACK_KEY_TRANSLATION[key]; end
106
+
107
+ def rack_value_for(key, value)
108
+ RACK_VALUE_TRANSLATION.fetch(key, IDENTITY).call value
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,9 @@
1
+ module ActionController
2
+ module TemplateAssertions
3
+ def assert_template(options = {}, message = nil)
4
+ raise NoMethodError,
5
+ "assert_template has been extracted to a gem. To continue using it,
6
+ add `gem 'rails-controller-testing'` to your Gemfile."
7
+ end
8
+ end
9
+ end
@@ -1,224 +1,60 @@
1
1
  require 'rack/session/abstract/id'
2
+ require 'active_support/core_ext/hash/conversions'
2
3
  require 'active_support/core_ext/object/to_query'
3
4
  require 'active_support/core_ext/module/anonymous'
4
5
  require 'active_support/core_ext/hash/keys'
5
- require 'active_support/deprecation'
6
-
6
+ require 'action_controller/template_assertions'
7
7
  require 'rails-dom-testing'
8
8
 
9
9
  module ActionController
10
- module TemplateAssertions
11
- extend ActiveSupport::Concern
10
+ # :stopdoc:
11
+ # ActionController::TestCase will be deprecated and moved to a gem in Rails 5.1.
12
+ # Please use ActionDispatch::IntegrationTest going forward.
13
+ class TestRequest < ActionDispatch::TestRequest #:nodoc:
14
+ DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
15
+ DEFAULT_ENV.delete 'PATH_INFO'
12
16
 
13
- included do
14
- setup :setup_subscriptions
15
- teardown :teardown_subscriptions
17
+ def self.new_session
18
+ TestSession.new
16
19
  end
17
20
 
18
- RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
19
-
20
- def setup_subscriptions
21
- RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
22
- instance_variable_set("@_#{instance_variable}", Hash.new(0))
23
- end
24
-
25
- @_subscribers = []
26
-
27
- @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
28
- path = payload[:layout]
29
- if path
30
- @_layouts[path] += 1
31
- if path =~ /^layouts\/(.*)/
32
- @_layouts[$1] += 1
33
- end
34
- end
35
- end
36
-
37
- @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
38
- if virtual_path = payload[:virtual_path]
39
- partial = virtual_path =~ /^.*\/_[^\/]*$/
40
-
41
- if partial
42
- @_partials[virtual_path] += 1
43
- @_partials[virtual_path.split("/").last] += 1
44
- end
45
-
46
- @_templates[virtual_path] += 1
47
- else
48
- path = payload[:identifier]
49
- if path
50
- @_files[path] += 1
51
- @_files[path.split("/").last] += 1
52
- end
53
- end
54
- end
21
+ # Create a new test request with default `env` values
22
+ def self.create
23
+ env = {}
24
+ env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
25
+ env["rack.request.cookie_hash"] = {}.with_indifferent_access
26
+ new(default_env.merge(env), new_session)
55
27
  end
56
28
 
57
- def teardown_subscriptions
58
- return unless defined?(@_subscribers)
59
-
60
- @_subscribers.each do |subscriber|
61
- ActiveSupport::Notifications.unsubscribe(subscriber)
62
- end
29
+ def self.default_env
30
+ DEFAULT_ENV
63
31
  end
32
+ private_class_method :default_env
64
33
 
65
- def process(*args)
66
- reset_template_assertion
67
- super
68
- end
34
+ def initialize(env, session)
35
+ super(env)
69
36
 
70
- def reset_template_assertion
71
- RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
72
- ivar_name = "@_#{instance_variable}"
73
- if instance_variable_defined?(ivar_name)
74
- instance_variable_get(ivar_name).clear
75
- end
76
- end
37
+ self.session = session
38
+ self.session_options = TestSession::DEFAULT_OPTIONS
39
+ @custom_param_parsers = {
40
+ Mime[:xml] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
41
+ }
77
42
  end
78
43
 
79
- # Asserts that the request was rendered with the appropriate template file or partials.
80
- #
81
- # # assert that the "new" view template was rendered
82
- # assert_template "new"
83
- #
84
- # # assert that the exact template "admin/posts/new" was rendered
85
- # assert_template %r{\Aadmin/posts/new\Z}
86
- #
87
- # # assert that the layout 'admin' was rendered
88
- # assert_template layout: 'admin'
89
- # assert_template layout: 'layouts/admin'
90
- # assert_template layout: :admin
91
- #
92
- # # assert that no layout was rendered
93
- # assert_template layout: nil
94
- # assert_template layout: false
95
- #
96
- # # assert that the "_customer" partial was rendered twice
97
- # assert_template partial: '_customer', count: 2
98
- #
99
- # # assert that no partials were rendered
100
- # assert_template partial: false
101
- #
102
- # # assert that a file was rendered
103
- # assert_template file: "README.rdoc"
104
- #
105
- # # assert that no file was rendered
106
- # assert_template file: nil
107
- # assert_template file: false
108
- #
109
- # In a view test case, you can also assert that specific locals are passed
110
- # to partials:
111
- #
112
- # # assert that the "_customer" partial was rendered with a specific object
113
- # assert_template partial: '_customer', locals: { customer: @customer }
114
- def assert_template(options = {}, message = nil)
115
- # Force body to be read in case the template is being streamed.
116
- response.body
117
-
118
- case options
119
- when NilClass, Regexp, String, Symbol
120
- options = options.to_s if Symbol === options
121
- rendered = @_templates
122
- msg = message || sprintf("expecting <%s> but rendering with <%s>",
123
- options.inspect, rendered.keys)
124
- matches_template =
125
- case options
126
- when String
127
- !options.empty? && rendered.any? do |t, num|
128
- options_splited = options.split(File::SEPARATOR)
129
- t_splited = t.split(File::SEPARATOR)
130
- t_splited.last(options_splited.size) == options_splited
131
- end
132
- when Regexp
133
- rendered.any? { |t,num| t.match(options) }
134
- when NilClass
135
- rendered.blank?
136
- end
137
- assert matches_template, msg
138
- when Hash
139
- options.assert_valid_keys(:layout, :partial, :locals, :count, :file)
140
-
141
- if options.key?(:layout)
142
- expected_layout = options[:layout]
143
- msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
144
- expected_layout, @_layouts.keys)
145
-
146
- case expected_layout
147
- when String, Symbol
148
- assert_includes @_layouts.keys, expected_layout.to_s, msg
149
- when Regexp
150
- assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
151
- when nil, false
152
- assert(@_layouts.empty?, msg)
153
- end
154
- end
155
-
156
- if options[:file]
157
- assert_includes @_files.keys, options[:file]
158
- elsif options.key?(:file)
159
- assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
160
- end
161
-
162
- if expected_partial = options[:partial]
163
- if expected_locals = options[:locals]
164
- if defined?(@_rendered_views)
165
- view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
166
-
167
- partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
168
- assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
169
-
170
- msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
171
- expected_locals,
172
- @_rendered_views.locals_for(view)]
173
- assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
174
- else
175
- warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
176
- end
177
- elsif expected_count = options[:count]
178
- actual_count = @_partials[expected_partial]
179
- msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
180
- expected_partial, expected_count, actual_count)
181
- assert(actual_count == expected_count.to_i, msg)
182
- else
183
- msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
184
- options[:partial], @_partials.keys)
185
- assert_includes @_partials, expected_partial, msg
186
- end
187
- elsif options.key?(:partial)
188
- assert @_partials.empty?,
189
- "Expected no partials to be rendered"
190
- end
191
- else
192
- raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
193
- end
44
+ def query_string=(string)
45
+ set_header Rack::QUERY_STRING, string
194
46
  end
195
- end
196
-
197
- class TestRequest < ActionDispatch::TestRequest #:nodoc:
198
- DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
199
- DEFAULT_ENV.delete 'PATH_INFO'
200
-
201
- def initialize(env = {})
202
- super
203
47
 
204
- self.session = TestSession.new
205
- self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16))
48
+ def content_type=(type)
49
+ set_header 'CONTENT_TYPE', type
206
50
  end
207
51
 
208
- def assign_parameters(routes, controller_path, action, parameters = {})
209
- parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
210
- extra_keys = routes.extra_keys(parameters)
211
- non_path_parameters = get? ? query_parameters : request_parameters
212
- parameters.each do |key, value|
213
- if value.is_a?(Array) && (value.frozen? || value.any?(&:frozen?))
214
- value = value.map{ |v| v.duplicable? ? v.dup : v }
215
- elsif value.is_a?(Hash) && (value.frozen? || value.any?{ |k,v| v.frozen? })
216
- value = Hash[value.map{ |k,v| [k, v.duplicable? ? v.dup : v] }]
217
- elsif value.frozen? && value.duplicable?
218
- value = value.dup
219
- end
52
+ def assign_parameters(routes, controller_path, action, parameters, generated_path, query_string_keys)
53
+ non_path_parameters = {}
54
+ path_parameters = {}
220
55
 
221
- if extra_keys.include?(key)
56
+ parameters.each do |key, value|
57
+ if query_string_keys.include?(key)
222
58
  non_path_parameters[key] = value
223
59
  else
224
60
  if value.is_a?(Array)
@@ -231,72 +67,88 @@ module ActionController
231
67
  end
232
68
  end
233
69
 
234
- # Clear the combined params hash in case it was already referenced.
235
- @env.delete("action_dispatch.request.parameters")
70
+ if get?
71
+ if self.query_string.blank?
72
+ self.query_string = non_path_parameters.to_query
73
+ end
74
+ else
75
+ if ENCODER.should_multipart?(non_path_parameters)
76
+ self.content_type = ENCODER.content_type
77
+ data = ENCODER.build_multipart non_path_parameters
78
+ else
79
+ fetch_header('CONTENT_TYPE') do |k|
80
+ set_header k, 'application/x-www-form-urlencoded'
81
+ end
236
82
 
237
- # Clear the filter cache variables so they're not stale
238
- @filtered_parameters = @filtered_env = @filtered_path = nil
83
+ case content_mime_type.to_sym
84
+ when nil
85
+ raise "Unknown Content-Type: #{content_type}"
86
+ when :json
87
+ data = ActiveSupport::JSON.encode(non_path_parameters)
88
+ when :xml
89
+ data = non_path_parameters.to_xml
90
+ when :url_encoded_form
91
+ data = non_path_parameters.to_query
92
+ else
93
+ @custom_param_parsers[content_mime_type] = ->(_) { non_path_parameters }
94
+ data = non_path_parameters.to_query
95
+ end
96
+ end
239
97
 
240
- params = self.request_parameters.dup
241
- %w(controller action only_path).each do |k|
242
- params.delete(k)
243
- params.delete(k.to_sym)
98
+ set_header 'CONTENT_LENGTH', data.length.to_s
99
+ set_header 'rack.input', StringIO.new(data)
244
100
  end
245
- data = params.to_query
246
101
 
247
- @env['CONTENT_LENGTH'] = data.length.to_s
248
- @env['rack.input'] = StringIO.new(data)
249
- end
102
+ fetch_header("PATH_INFO") do |k|
103
+ set_header k, generated_path
104
+ end
105
+ path_parameters[:controller] = controller_path
106
+ path_parameters[:action] = action
250
107
 
251
- def recycle!
252
- @formats = nil
253
- @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
254
- @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
255
- @method = @request_method = nil
256
- @fullpath = @ip = @remote_ip = @protocol = nil
257
- @env['action_dispatch.request.query_parameters'] = {}
258
- @set_cookies ||= {}
259
- @set_cookies.update(Hash[cookie_jar.instance_variable_get("@set_cookies").map{ |k,o| [k,o[:value]] }])
260
- deleted_cookies = cookie_jar.instance_variable_get("@delete_cookies")
261
- @set_cookies.reject!{ |k,v| deleted_cookies.include?(k) }
262
- cookie_jar.update(rack_cookies)
263
- cookie_jar.update(cookies)
264
- cookie_jar.update(@set_cookies)
265
- cookie_jar.recycle!
108
+ self.path_parameters = path_parameters
266
109
  end
267
110
 
268
- private
111
+ ENCODER = Class.new do
112
+ include Rack::Test::Utils
113
+
114
+ def should_multipart?(params)
115
+ # FIXME: lifted from Rack-Test. We should push this separation upstream
116
+ multipart = false
117
+ query = lambda { |value|
118
+ case value
119
+ when Array
120
+ value.each(&query)
121
+ when Hash
122
+ value.values.each(&query)
123
+ when Rack::Test::UploadedFile
124
+ multipart = true
125
+ end
126
+ }
127
+ params.values.each(&query)
128
+ multipart
129
+ end
269
130
 
270
- def default_env
271
- DEFAULT_ENV
272
- end
273
- end
131
+ public :build_multipart
274
132
 
275
- class TestResponse < ActionDispatch::TestResponse
276
- def recycle!
277
- initialize
278
- end
279
- end
133
+ def content_type
134
+ "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}"
135
+ end
136
+ end.new
280
137
 
281
- class LiveTestResponse < Live::Response
282
- def recycle!
283
- @body = nil
284
- initialize
285
- end
138
+ private
286
139
 
287
- def body
288
- @body ||= super
140
+ def params_parsers
141
+ super.merge @custom_param_parsers
289
142
  end
143
+ end
290
144
 
145
+ class LiveTestResponse < Live::Response
291
146
  # Was the response successful?
292
147
  alias_method :success?, :successful?
293
148
 
294
149
  # Was the URL not found?
295
150
  alias_method :missing?, :not_found?
296
151
 
297
- # Were we redirected?
298
- alias_method :redirect?, :redirection?
299
-
300
152
  # Was there a server-side error?
301
153
  alias_method :error?, :server_error?
302
154
  end
@@ -304,7 +156,7 @@ module ActionController
304
156
  # Methods #destroy and #load! are overridden to avoid calling methods on the
305
157
  # @store object, which does not exist for the TestSession class.
306
158
  class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
307
- DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
159
+ DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
308
160
 
309
161
  def initialize(session = {})
310
162
  super(nil, nil)
@@ -359,13 +211,13 @@ module ActionController
359
211
  # class BooksControllerTest < ActionController::TestCase
360
212
  # def test_create
361
213
  # # Simulate a POST response with the given HTTP parameters.
362
- # post(:create, book: { title: "Love Hina" })
214
+ # post(:create, params: { book: { title: "Love Hina" }})
363
215
  #
364
- # # Assert that the controller tried to redirect us to
216
+ # # Asserts that the controller tried to redirect us to
365
217
  # # the created book's URI.
366
218
  # assert_response :found
367
219
  #
368
- # # Assert that the controller really put the book in the database.
220
+ # # Asserts that the controller really put the book in the database.
369
221
  # assert_not_nil Book.find_by(title: "Love Hina")
370
222
  # end
371
223
  # end
@@ -389,7 +241,7 @@ module ActionController
389
241
  # request. You can modify this object before sending the HTTP request. For example,
390
242
  # you might want to set some session properties before sending a GET request.
391
243
  # <b>@response</b>::
392
- # An ActionController::TestResponse object, representing the response
244
+ # An ActionDispatch::TestResponse object, representing the response
393
245
  # of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
394
246
  # after calling +post+. If the various assert methods are not sufficient, then you
395
247
  # may use this object to inspect the HTTP response in detail.
@@ -412,21 +264,15 @@ module ActionController
412
264
  # In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions
413
265
  # can be used against. These collections are:
414
266
  #
415
- # * assigns: Instance variables assigned in the action that are available for the view.
416
267
  # * session: Objects being saved in the session.
417
268
  # * flash: The flash objects currently in the session.
418
269
  # * cookies: \Cookies being sent to the user on this request.
419
270
  #
420
271
  # These collections can be used just like any other hash:
421
272
  #
422
- # assert_not_nil assigns(:person) # makes sure that a @person instance variable was set
423
273
  # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
424
274
  # assert flash.empty? # makes sure that there's nothing in the flash
425
275
  #
426
- # For historic reasons, the assigns hash uses string-based keys. So <tt>assigns[:person]</tt> won't work, but <tt>assigns["person"]</tt> will. To
427
- # appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing.
428
- # So <tt>assigns(:person)</tt> will work just like <tt>assigns["person"]</tt>, but again, <tt>assigns[:person]</tt> will not work.
429
- #
430
276
  # On top of the collections, you have the complete url that a given action redirected to available in <tt>redirect_to_url</tt>.
431
277
  #
432
278
  # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another
@@ -499,169 +345,227 @@ module ActionController
499
345
  # Simulate a GET request with the given parameters.
500
346
  #
501
347
  # - +action+: The controller action to call.
502
- # - +parameters+: The HTTP parameters that you want to pass. This may
503
- # be +nil+, a hash, or a string that is appropriately encoded
348
+ # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
349
+ # - +body+: The request body with a string that is appropriately encoded
504
350
  # (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
505
351
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
506
352
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
507
353
  #
508
354
  # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
509
355
  # +post+, +patch+, +put+, +delete+, and +head+.
356
+ # Example sending parameters, session and setting a flash message:
357
+ #
358
+ # get :show,
359
+ # params: { id: 7 },
360
+ # session: { user_id: 1 },
361
+ # flash: { notice: 'This is flash message' }
510
362
  #
511
363
  # Note that the request method is not verified. The different methods are
512
364
  # available to make the tests more expressive.
513
365
  def get(action, *args)
514
- process(action, "GET", *args)
366
+ res = process_with_kwargs("GET", action, *args)
367
+ cookies.update res.cookies
368
+ res
515
369
  end
516
370
 
517
371
  # Simulate a POST request with the given parameters and set/volley the response.
518
372
  # See +get+ for more details.
519
373
  def post(action, *args)
520
- process(action, "POST", *args)
374
+ process_with_kwargs("POST", action, *args)
521
375
  end
522
376
 
523
377
  # Simulate a PATCH request with the given parameters and set/volley the response.
524
378
  # See +get+ for more details.
525
379
  def patch(action, *args)
526
- process(action, "PATCH", *args)
380
+ process_with_kwargs("PATCH", action, *args)
527
381
  end
528
382
 
529
383
  # Simulate a PUT request with the given parameters and set/volley the response.
530
384
  # See +get+ for more details.
531
385
  def put(action, *args)
532
- process(action, "PUT", *args)
386
+ process_with_kwargs("PUT", action, *args)
533
387
  end
534
388
 
535
389
  # Simulate a DELETE request with the given parameters and set/volley the response.
536
390
  # See +get+ for more details.
537
391
  def delete(action, *args)
538
- process(action, "DELETE", *args)
392
+ process_with_kwargs("DELETE", action, *args)
539
393
  end
540
394
 
541
395
  # Simulate a HEAD request with the given parameters and set/volley the response.
542
396
  # See +get+ for more details.
543
397
  def head(action, *args)
544
- process(action, "HEAD", *args)
398
+ process_with_kwargs("HEAD", action, *args)
545
399
  end
546
400
 
547
- def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
401
+ def xml_http_request(*args)
402
+ ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc)
403
+ xhr and xml_http_request methods are deprecated in favor of
404
+ `get :index, xhr: true` and `post :create, xhr: true`
405
+ MSG
406
+
548
407
  @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
549
- @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
550
- __send__(request_method, action, parameters, session, flash).tap do
408
+ @request.env['HTTP_ACCEPT'] ||= [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ')
409
+ __send__(*args).tap do
551
410
  @request.env.delete 'HTTP_X_REQUESTED_WITH'
552
411
  @request.env.delete 'HTTP_ACCEPT'
553
412
  end
554
413
  end
555
414
  alias xhr :xml_http_request
556
415
 
557
- def paramify_values(hash_or_array_or_value)
558
- case hash_or_array_or_value
559
- when Hash
560
- Hash[hash_or_array_or_value.map{|key, value| [key, paramify_values(value)] }]
561
- when Array
562
- hash_or_array_or_value.map {|i| paramify_values(i)}
563
- when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile
564
- hash_or_array_or_value
565
- else
566
- hash_or_array_or_value.to_param
567
- end
568
- end
569
-
570
416
  # Simulate a HTTP request to +action+ by specifying request method,
571
417
  # parameters and set/volley the response.
572
418
  #
573
419
  # - +action+: The controller action to call.
574
- # - +http_method+: Request method used to send the http request. Possible values
575
- # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+.
576
- # - +parameters+: The HTTP parameters. This may be +nil+, a hash, or a
577
- # string that is appropriately encoded (+application/x-www-form-urlencoded+
578
- # or +multipart/form-data+).
420
+ # - +method+: Request method used to send the HTTP request. Possible values
421
+ # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. Can be a symbol.
422
+ # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
423
+ # - +body+: The request body with a string that is appropriately encoded
424
+ # (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
579
425
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
580
426
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
427
+ # - +format+: Request format. Defaults to +nil+. Can be string or symbol.
581
428
  #
582
429
  # Example calling +create+ action and sending two params:
583
430
  #
584
- # process :create, 'POST', user: { name: 'Gaurish Sharma', email: 'user@example.com' }
585
- #
586
- # Example sending parameters, +nil+ session and setting a flash message:
587
- #
588
- # process :view, 'GET', { id: 7 }, nil, { notice: 'This is flash message' }
431
+ # process :create,
432
+ # method: 'POST',
433
+ # params: {
434
+ # user: { name: 'Gaurish Sharma', email: 'user@example.com' }
435
+ # },
436
+ # session: { user_id: 1 },
437
+ # flash: { notice: 'This is flash message' }
589
438
  #
590
439
  # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests
591
440
  # prefer using #get, #post, #patch, #put, #delete and #head methods
592
441
  # respectively which will make tests more expressive.
593
442
  #
594
443
  # Note that the request method is not verified.
595
- def process(action, http_method = 'GET', *args)
444
+ def process(action, *args)
596
445
  check_required_ivars
597
446
 
598
- if args.first.is_a?(String) && http_method != 'HEAD'
599
- @request.env['RAW_POST_DATA'] = args.shift
447
+ if kwarg_request?(args)
448
+ parameters, session, body, flash, http_method, format, xhr = args[0].values_at(:params, :session, :body, :flash, :method, :format, :xhr)
449
+ else
450
+ http_method, parameters, session, flash = args
451
+ format = nil
452
+
453
+ if parameters.is_a?(String) && http_method != 'HEAD'
454
+ body = parameters
455
+ parameters = nil
456
+ end
457
+
458
+ if parameters.present? || session.present? || flash.present?
459
+ non_kwarg_request_warning
460
+ end
461
+ end
462
+
463
+ if body.present?
464
+ @request.set_header 'RAW_POST_DATA', body
465
+ end
466
+
467
+ if http_method.present?
468
+ http_method = http_method.to_s.upcase
469
+ else
470
+ http_method = "GET"
600
471
  end
601
472
 
602
- parameters, session, flash = args
603
473
  parameters ||= {}
604
474
 
605
- # Ensure that numbers and symbols passed as params are converted to
606
- # proper params, as is the case when engaging rack.
607
- parameters = paramify_values(parameters) if html_format?(parameters)
475
+ if format.present?
476
+ parameters[:format] = format
477
+ end
608
478
 
609
479
  @html_document = nil
610
- @html_scanner_document = nil
611
480
 
612
481
  unless @controller.respond_to?(:recycle!)
613
482
  @controller.extend(Testing::Functional)
614
483
  end
615
484
 
616
- @request.recycle!
617
- @response.recycle!
485
+ self.cookies.update @request.cookies
486
+ self.cookies.update_cookies_from_jar
487
+ @request.set_header 'HTTP_COOKIE', cookies.to_header
488
+ @request.delete_header 'action_dispatch.cookies'
489
+
490
+ @request = TestRequest.new scrub_env!(@request.env), @request.session
491
+ @response = build_response @response_klass
492
+ @response.request = @request
618
493
  @controller.recycle!
619
494
 
620
- @request.env['REQUEST_METHOD'] = http_method
495
+ @request.set_header 'REQUEST_METHOD', http_method
496
+
497
+ parameters = parameters.symbolize_keys
621
498
 
622
- controller_class_name = @controller.class.anonymous? ?
623
- "anonymous" :
624
- @controller.class.controller_path
499
+ generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s))
500
+ generated_path = generated_path(generated_extras)
501
+ query_string_keys = query_parameter_names(generated_extras)
625
502
 
626
- @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)
503
+ @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters, generated_path, query_string_keys)
627
504
 
628
505
  @request.session.update(session) if session
629
506
  @request.flash.update(flash || {})
630
507
 
631
- @controller.request = @request
632
- @controller.response = @response
633
-
634
- build_request_uri(action, parameters)
508
+ if xhr
509
+ @request.set_header 'HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'
510
+ @request.fetch_header('HTTP_ACCEPT') do |k|
511
+ @request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ')
512
+ end
513
+ end
635
514
 
636
- name = @request.parameters[:action]
515
+ @request.fetch_header("SCRIPT_NAME") do |k|
516
+ @request.set_header k, @controller.config.relative_url_root
517
+ end
637
518
 
638
519
  @controller.recycle!
639
- @controller.process(name)
520
+ @controller.dispatch(action, @request, @response)
521
+ @request = @controller.request
522
+ @response = @controller.response
523
+
524
+ @request.delete_header 'HTTP_COOKIE'
640
525
 
641
- if cookies = @request.env['action_dispatch.cookies']
642
- unless @response.committed?
643
- cookies.write(@response)
526
+ if @request.have_cookie_jar?
527
+ unless @request.cookie_jar.committed?
528
+ @request.cookie_jar.write(@response)
529
+ self.cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
644
530
  end
645
531
  end
646
532
  @response.prepare!
647
533
 
648
- @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
649
-
650
534
  if flash_value = @request.flash.to_session_value
651
535
  @request.session['flash'] = flash_value
536
+ else
537
+ @request.session.delete('flash')
652
538
  end
653
539
 
540
+ if xhr
541
+ @request.delete_header 'HTTP_X_REQUESTED_WITH'
542
+ @request.delete_header 'HTTP_ACCEPT'
543
+ end
544
+ @request.query_string = ''
545
+
654
546
  @response
655
547
  end
656
548
 
549
+ def controller_class_name
550
+ @controller.class.anonymous? ? "anonymous" : @controller.class.controller_path
551
+ end
552
+
553
+ def generated_path(generated_extras)
554
+ generated_extras[0]
555
+ end
556
+
557
+ def query_parameter_names(generated_extras)
558
+ generated_extras[1] + [:controller, :action]
559
+ end
560
+
657
561
  def setup_controller_request_and_response
658
562
  @controller = nil unless defined? @controller
659
563
 
660
- response_klass = TestResponse
564
+ @response_klass = ActionDispatch::TestResponse
661
565
 
662
566
  if klass = self.class.controller_class
663
567
  if klass < ActionController::Live
664
- response_klass = LiveTestResponse
568
+ @response_klass = LiveTestResponse
665
569
  end
666
570
  unless @controller
667
571
  begin
@@ -672,8 +576,8 @@ module ActionController
672
576
  end
673
577
  end
674
578
 
675
- @request = build_request
676
- @response = build_response response_klass
579
+ @request = TestRequest.create
580
+ @response = build_response @response_klass
677
581
  @response.request = @request
678
582
 
679
583
  if @controller
@@ -682,12 +586,8 @@ module ActionController
682
586
  end
683
587
  end
684
588
 
685
- def build_request
686
- TestRequest.new
687
- end
688
-
689
589
  def build_response(klass)
690
- klass.new
590
+ klass.create
691
591
  end
692
592
 
693
593
  included do
@@ -699,6 +599,46 @@ module ActionController
699
599
 
700
600
  private
701
601
 
602
+ def scrub_env!(env)
603
+ env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
604
+ env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
605
+ env.delete 'action_dispatch.request.query_parameters'
606
+ env.delete 'action_dispatch.request.request_parameters'
607
+ env
608
+ end
609
+
610
+ def process_with_kwargs(http_method, action, *args)
611
+ if kwarg_request?(args)
612
+ args.first.merge!(method: http_method)
613
+ process(action, *args)
614
+ else
615
+ non_kwarg_request_warning if args.any?
616
+
617
+ args = args.unshift(http_method)
618
+ process(action, *args)
619
+ end
620
+ end
621
+
622
+ REQUEST_KWARGS = %i(params session flash method body xhr)
623
+ def kwarg_request?(args)
624
+ args[0].respond_to?(:keys) && (
625
+ (args[0].key?(:format) && args[0].keys.size == 1) ||
626
+ args[0].keys.any? { |k| REQUEST_KWARGS.include?(k) }
627
+ )
628
+ end
629
+
630
+ def non_kwarg_request_warning
631
+ ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc)
632
+ ActionController::TestCase HTTP request methods will accept only
633
+ keyword arguments in future Rails versions.
634
+
635
+ Examples:
636
+
637
+ get :show, params: { id: 1 }, session: { user_id: 1 }
638
+ process :update, method: :post, params: { id: 1 }
639
+ MSG
640
+ end
641
+
702
642
  def document_root_element
703
643
  html_document.root
704
644
  end
@@ -713,43 +653,6 @@ module ActionController
713
653
  end
714
654
  end
715
655
 
716
- def build_request_uri(action, parameters)
717
- unless @request.env["PATH_INFO"]
718
- options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
719
- options.update(
720
- :action => action,
721
- :relative_url_root => nil,
722
- :_recall => @request.path_parameters)
723
-
724
- if route_name = options.delete(:use_route)
725
- ActiveSupport::Deprecation.warn <<-MSG.squish
726
- Passing the `use_route` option in functional tests are deprecated.
727
- Support for this option in the `process` method (and the related
728
- `get`, `head`, `post`, `patch`, `put` and `delete` helpers) will
729
- be removed in the next version without replacement.
730
-
731
- Functional tests are essentially unit tests for controllers and
732
- they should not require knowledge to how the application's routes
733
- are configured. Instead, you should explicitly pass the appropiate
734
- params to the `process` method.
735
-
736
- Previously the engines guide also contained an incorrect example
737
- that recommended using this option to test an engine's controllers
738
- within the dummy application. That recommendation was incorrect
739
- and has since been corrected. Instead, you should override the
740
- `@routes` variable in the test case with `Foo::Engine.routes`. See
741
- the updated engines guide for details.
742
- MSG
743
- end
744
-
745
- url, query_string = @routes.path_for(options, route_name).split("?", 2)
746
-
747
- @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
748
- @request.env["PATH_INFO"] = url
749
- @request.env["QUERY_STRING"] = query_string || ""
750
- end
751
- end
752
-
753
656
  def html_format?(parameters)
754
657
  return true unless parameters.key?(:format)
755
658
  Mime.fetch(parameters[:format]) { Mime['html'] }.html?
@@ -758,4 +661,5 @@ module ActionController
758
661
 
759
662
  include Behavior
760
663
  end
664
+ # :startdoc:
761
665
  end