aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG.md66
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb51
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb2
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb1
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb7
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb8
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb25
-rw-r--r--actionpack/lib/action_controller/railtie.rb4
-rw-r--r--actionpack/lib/action_controller/test_case.rb31
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb12
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb18
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/upload.rb10
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb52
-rw-r--r--actionpack/lib/action_dispatch/journey/formatter.rb6
-rw-r--r--actionpack/lib/action_dispatch/journey/router.rb3
-rw-r--r--actionpack/lib/action_dispatch/journey/router/utils.rb12
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/flash.rb9
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb1
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb48
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb77
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb6
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb2
-rw-r--r--actionpack/test/abstract_unit.rb142
-rw-r--r--actionpack/test/controller/http_token_authentication_test.rb24
-rw-r--r--actionpack/test/controller/integration_test.rb3
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb2
-rw-r--r--actionpack/test/controller/mime/respond_to_test.rb13
-rw-r--r--actionpack/test/controller/new_base/render_body_test.rb8
-rw-r--r--actionpack/test/controller/new_base/render_html_test.rb8
-rw-r--r--actionpack/test/controller/new_base/render_plain_test.rb8
-rw-r--r--actionpack/test/controller/new_base/render_template_test.rb4
-rw-r--r--actionpack/test/controller/new_base/render_text_test.rb8
-rw-r--r--actionpack/test/controller/parameters/always_permitted_parameters_test.rb29
-rw-r--r--actionpack/test/controller/redirect_test.rb10
-rw-r--r--actionpack/test/controller/render_json_test.rb2
-rw-r--r--actionpack/test/controller/routing_test.rb285
-rw-r--r--actionpack/test/controller/test_case_test.rb6
-rw-r--r--actionpack/test/controller/url_for_integration_test.rb81
-rw-r--r--actionpack/test/controller/url_for_test.rb8
-rw-r--r--actionpack/test/dispatch/mapper_test.rb4
-rw-r--r--actionpack/test/dispatch/mount_test.rb17
-rw-r--r--actionpack/test/dispatch/prefix_generation_test.rb3
-rw-r--r--actionpack/test/dispatch/request/multipart_params_parsing_test.rb6
-rw-r--r--actionpack/test/dispatch/request_test.rb20
-rw-r--r--actionpack/test/dispatch/routing/concerns_test.rb3
-rw-r--r--actionpack/test/dispatch/routing_test.rb116
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb3
-rw-r--r--actionpack/test/dispatch/uploaded_file_test.rb6
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb4
-rw-r--r--actionpack/test/fixtures/test/_changing_priority.html.erb1
-rw-r--r--actionpack/test/fixtures/test/_changing_priority.json.erb1
-rw-r--r--actionpack/test/fixtures/test/_counter.html.erb1
-rw-r--r--actionpack/test/fixtures/test/_customer.erb1
-rw-r--r--actionpack/test/fixtures/test/_customer_counter.erb1
-rw-r--r--actionpack/test/fixtures/test/_customer_counter_with_as.erb1
-rw-r--r--actionpack/test/fixtures/test/_customer_greeting.erb1
-rw-r--r--actionpack/test/fixtures/test/_customer_with_var.erb1
-rw-r--r--actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb1
-rw-r--r--actionpack/test/fixtures/test/_first_json_partial.json.erb1
-rw-r--r--actionpack/test/fixtures/test/_form.erb1
-rw-r--r--actionpack/test/fixtures/test/_hash_greeting.erb1
-rw-r--r--actionpack/test/fixtures/test/_hash_object.erb2
-rw-r--r--actionpack/test/fixtures/test/_hello.builder1
-rw-r--r--actionpack/test/fixtures/test/_json_change_priority.json.erb0
-rw-r--r--actionpack/test/fixtures/test/_labelling_form.erb1
-rw-r--r--actionpack/test/fixtures/test/_layout_for_partial.html.erb3
-rw-r--r--actionpack/test/fixtures/test/_partial_for_use_in_layout.html.erb1
-rw-r--r--actionpack/test/fixtures/test/_partial_html_erb.html.erb1
-rw-r--r--actionpack/test/fixtures/test/_partial_name_local_variable.erb1
-rw-r--r--actionpack/test/fixtures/test/_partial_only.erb1
-rw-r--r--actionpack/test/fixtures/test/_partial_only_html.html1
-rw-r--r--actionpack/test/fixtures/test/_partial_with_partial.erb2
-rw-r--r--actionpack/test/fixtures/test/_person.erb2
-rw-r--r--actionpack/test/fixtures/test/_raise_indentation.html.erb13
-rw-r--r--actionpack/test/fixtures/test/_second_json_partial.json.erb1
-rw-r--r--actionpack/test/fixtures/test/action_talk_to_layout.erb2
-rw-r--r--actionpack/test/fixtures/test/calling_partial_with_layout.html.erb1
-rw-r--r--actionpack/test/fixtures/test/capturing.erb4
-rw-r--r--actionpack/test/fixtures/test/change_priority.html.erb2
-rw-r--r--actionpack/test/fixtures/test/content_for.erb1
-rw-r--r--actionpack/test/fixtures/test/content_for_concatenated.erb3
-rw-r--r--actionpack/test/fixtures/test/content_for_with_parameter.erb2
-rw-r--r--actionpack/test/fixtures/test/formatted_html_erb.html.erb1
-rw-r--r--actionpack/test/fixtures/test/greeting.html.erb1
-rw-r--r--actionpack/test/fixtures/test/greeting.xml.erb1
-rw-r--r--actionpack/test/fixtures/test/hello,world.erb1
-rw-r--r--actionpack/test/fixtures/test/hello.builder4
-rw-r--r--actionpack/test/fixtures/test/hello_world_container.builder3
-rw-r--r--actionpack/test/fixtures/test/hello_world_from_rxml.builder3
-rw-r--r--actionpack/test/fixtures/test/hello_world_with_layout_false.erb1
-rw-r--r--actionpack/test/fixtures/test/html_template.html.erb1
-rw-r--r--actionpack/test/fixtures/test/hyphen-ated.erb1
-rw-r--r--actionpack/test/fixtures/test/list.erb1
-rw-r--r--actionpack/test/fixtures/test/non_erb_block_content_for.builder4
-rw-r--r--actionpack/test/fixtures/test/potential_conflicts.erb4
-rw-r--r--actionpack/test/fixtures/test/proper_block_detection.erb1
-rw-r--r--actionpack/test/fixtures/test/render_file_from_template.html.erb1
-rw-r--r--actionpack/test/fixtures/test/render_file_with_locals_and_default.erb1
-rw-r--r--actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb1
-rw-r--r--actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb1
-rw-r--r--actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb1
-rw-r--r--actionpack/test/fixtures/test/render_partial_inside_directory.html.erb1
-rw-r--r--actionpack/test/fixtures/test/render_to_string_test.erb1
-rw-r--r--actionpack/test/fixtures/test/render_two_partials.html.erb2
-rw-r--r--actionpack/test/fixtures/test/using_layout_around_block.html.erb1
-rw-r--r--actionpack/test/fixtures/test/with_html_partial.html.erb1
-rw-r--r--actionpack/test/fixtures/test/with_partial.html.erb1
-rw-r--r--actionpack/test/fixtures/test/with_partial.text.erb1
-rw-r--r--actionpack/test/fixtures/test/with_xml_template.html.erb1
-rw-r--r--actionpack/test/journey/router/utils_test.rb5
115 files changed, 899 insertions, 498 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index c38b31903b..f73f5bc797 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,66 @@
+* Preserve original path in `ShowExceptions` middleware by stashing it as
+ `env["action_dispatch.original_path"]`
+
+ `ActionDispatch::ShowExceptions` overwrites `PATH_INFO` with the status code
+ for the exception defined in `ExceptionWrapper`, so the path
+ the user was visiting when an exception occurred was not previously
+ available to any custom exceptions_app. The original `PATH_INFO` is now
+ stashed in `env["action_dispatch.original_path"]`.
+
+ *Grey Baker*
+
+* Use `String#bytesize` instead of `String#size` when checking for cookie
+ overflow.
+
+ *Agis Anastasopoulos*
+
+* `render nothing: true` or rendering a `nil` body no longer add a single
+ space to the response body.
+
+ The old behavior was added as a workaround for a bug in an early version of
+ Safari, where the HTTP headers are not returned correctly if the response
+ body has a 0-length. This is been fixed since and the workaround is no
+ longer necessary.
+
+ Use `render body: ' '` if the old behavior is desired.
+
+ See #14883 for details.
+
+ *Godfrey Chan*
+
+* Prepend a JS comment to JSONP callbacks. Addresses CVE-2014-4671
+ ("Rosetta Flash")
+
+ *Greg Campbell*
+
+* Because URI paths may contain non US-ASCII characters we need to force
+ the encoding of any unescaped URIs to UTF-8 if they are US-ASCII.
+ This essentially replicates the functionality of the monkey patch to
+ URI.parser.unescape in active_support/core_ext/uri.rb.
+
+ Fixes #16104.
+
+ *Karl Entwistle*
+
+* Generate shallow paths for all children of shallow resources.
+
+ Fixes #15783.
+
+ *Seb Jacobs*
+
+* JSONP responses are now rendered with the `text/javascript` content type
+ when rendering through a `respond_to` block.
+
+ Fixes #15081.
+
+ *Lucas Mazza*
+
+* Add `config.action_controller.always_permitted_parameters` to configure which
+ parameters are permitted globally. The default value of this configuration is
+ `['controller', 'action']`.
+
+ *Gary S. Weaver*, *Rafael Chacon*
+
* Fix env['PATH_INFO'] missing leading slash when a rack app mounted at '/'.
Fixes #15511.
@@ -26,6 +89,8 @@
application. Use of a symbol should be replaced with `action: symbol`.
Use of a string without a "#" should be replaced with `controller: string`.
+ *Aaron Patterson*
+
* Fix URL generation with `:trailing_slash` such that it does not add
a trailing slash after `.:format`
@@ -164,5 +229,4 @@
*Tony Wooster*
-
Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionpack/CHANGELOG.md) for previous changes.
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 1d6009bab8..d509891fe3 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
s.add_dependency 'activesupport', version
- s.add_dependency 'rack', '~> 1.5.2'
+ s.add_dependency 'rack', '~> 1.6.0.alpha'
s.add_dependency 'rack-test', '~> 0.6.2'
s.add_dependency 'actionview', version
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index b1acca2435..89fa75f025 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -16,50 +16,51 @@ module ActionController
end
def process_action(event)
- return unless logger.info?
-
- payload = event.payload
- additions = ActionController::Base.log_process_action(payload)
-
- status = payload[:status]
- if status.nil? && payload[:exception].present?
- exception_class_name = payload[:exception].first
- status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
+ info do
+ payload = event.payload
+ additions = ActionController::Base.log_process_action(payload)
+
+ status = payload[:status]
+ if status.nil? && payload[:exception].present?
+ exception_class_name = payload[:exception].first
+ status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
+ end
+ message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
+ message << " (#{additions.join(" | ")})" unless additions.blank?
+ message
end
- message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
- message << " (#{additions.join(" | ")})" unless additions.blank?
-
- info(message)
end
def halted_callback(event)
- info("Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected")
+ info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
end
def send_file(event)
- info("Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)")
+ info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
end
def redirect_to(event)
- info("Redirected to #{event.payload[:location]}")
+ info { "Redirected to #{event.payload[:location]}" }
end
def send_data(event)
- info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
+ info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" }
end
def unpermitted_parameters(event)
- unpermitted_keys = event.payload[:keys]
- debug("Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.join(", ")}")
+ debug do
+ unpermitted_keys = event.payload[:keys]
+ "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.join(", ")}"
+ end
end
def deep_munge(event)
- message = "Value for params[:#{event.payload[:keys].join('][:')}] was set "\
- "to nil, because it was one of [], [null] or [null, null, ...]. "\
- "Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation "\
- "for more information."\
-
- debug(message)
+ debug do
+ "Value for params[:#{event.payload[:keys].join('][:')}] was set "\
+ "to nil, because it was one of [], [null] or [null, null, ...]. "\
+ "Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation "\
+ "for more information."\
+ end
end
%w(write_fragment read_fragment exist_fragment?
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 5b52c19802..25c123edf7 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -471,7 +471,7 @@ module ActionController
# pairs by the standardized `:`, `;`, or `\t` delimiters defined in
# `AUTHN_PAIR_DELIMITERS`.
def raw_params(auth)
- auth.sub(TOKEN_REGEX, '').split(/"\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
+ auth.sub(TOKEN_REGEX, '').split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
end
# Encodes the given token and options into an Authorization header value.
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 3feb737277..ca8c0278d0 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -68,6 +68,7 @@ module ActionController
# <tt>ActionController::RedirectBackError</tt>.
def redirect_to(options = {}, response_status = {}) #:doc:
raise ActionControllerError.new("Cannot redirect to nil!") unless options
+ raise ActionControllerError.new("Cannot redirect to a parameter hash!") if options.is_a?(ActionController::Parameters)
raise AbstractController::DoubleRenderError if response_body
self.status = _extract_redirect_to_status(options, response_status)
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index 46405cef55..02c4e563f5 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -112,8 +112,11 @@ module ActionController
json = json.to_json(options) unless json.kind_of?(String)
if options[:callback].present?
- self.content_type ||= Mime::JS
- "#{options[:callback]}(#{json})"
+ if self.content_type.nil? || self.content_type == Mime::JSON
+ self.content_type = Mime::JS
+ end
+
+ "/**/#{options[:callback]}(#{json})"
else
self.content_type ||= Mime::JSON
json
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 93e7d6954c..7bbff0450a 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -67,8 +67,8 @@ module ActionController
options[:html] = ERB::Util.html_escape(options[:html])
end
- if options.delete(:nothing) || _any_render_format_is_nil?(options)
- options[:body] = " "
+ if options.delete(:nothing)
+ options[:body] = nil
end
if options[:status]
@@ -86,10 +86,6 @@ module ActionController
end
end
- def _any_render_format_is_nil?(options)
- RENDER_FORMATS_IN_PRIORITY.any? { |format| options.key?(format) && options[format].nil? }
- end
-
# Process controller specific options, as status, content-type and location.
def _process_options(options) #:nodoc:
status, content_type, location = options.values_at(:status, :content_type, :location)
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index b70962cf44..bc27ecaa20 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/array/wrap'
+require 'active_support/deprecation'
require 'active_support/rescuable'
require 'action_dispatch/http/upload'
require 'stringio'
@@ -39,7 +40,7 @@ module ActionController
# == Action Controller \Parameters
#
# Allows to choose which attributes should be whitelisted for mass updating
- # and thus prevent accidentally exposing that which shouldn’t be exposed.
+ # and thus prevent accidentally exposing that which shouldn't be exposed.
# Provides two methods for this purpose: #require and #permit. The former is
# used to mark parameters as required. The latter is used to set the parameter
# as permitted and limit which attributes should be allowed for mass updating.
@@ -101,9 +102,23 @@ module ActionController
cattr_accessor :permit_all_parameters, instance_accessor: false
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
- # Never raise an UnpermittedParameters exception because of these params
- # are present. They are added by Rails and it's of no concern.
- NEVER_UNPERMITTED_PARAMS = %w( controller action )
+ # By default, never raise an UnpermittedParameters exception if these
+ # params are present. The default includes both 'controller' and 'action'
+ # because they are added by Rails and should be of no concern. One way
+ # to change these is to specify `always_permitted_parameters` in your
+ # config. For instance:
+ #
+ # config.always_permitted_parameters = %w( controller action format )
+ cattr_accessor :always_permitted_parameters
+ self.always_permitted_parameters = %w( controller action )
+
+ def self.const_missing(const_name)
+ super unless const_name == :NEVER_UNPERMITTED_PARAMS
+ ActiveSupport::Deprecation.warn "`ActionController::Parameters::NEVER_UNPERMITTED_PARAMS`"\
+ " has been deprecated. Use "\
+ "`ActionController::Parameters.always_permitted_parameters` instead."
+ self.always_permitted_parameters
+ end
# Returns a new instance of <tt>ActionController::Parameters</tt>.
# Also, sets the +permitted+ attribute to the default value of
@@ -389,7 +404,7 @@ module ActionController
end
def unpermitted_keys(params)
- self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
+ self.keys - params.keys - self.always_permitted_parameters
end
#
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index a2fc814221..28b20052b5 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -23,6 +23,10 @@ module ActionController
options = app.config.action_controller
ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
+ if app.config.action_controller[:always_permitted_parameters]
+ ActionController::Parameters.always_permitted_parameters =
+ app.config.action_controller.delete(:always_permitted_parameters)
+ end
ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
(Rails.env.test? || Rails.env.development?) ? :log : false
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index b117170514..a18c35e3e9 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -30,25 +30,21 @@ module ActionController
end
@_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
- path = payload[:virtual_path]
- next unless path
- partial = path =~ /^.*\/_[^\/]*$/
+ if virtual_path = payload[:virtual_path]
+ partial = virtual_path =~ /^.*\/_[^\/]*$/
- if partial
- @_partials[path] += 1
- @_partials[path.split("/").last] += 1
- end
-
- @_templates[path] += 1
- end
-
- @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
- next if payload[:virtual_path] # files don't have virtual path
+ if partial
+ @_partials[virtual_path] += 1
+ @_partials[virtual_path.split("/").last] += 1
+ end
- path = payload[:identifier]
- if path
- @_files[path] += 1
- @_files[path.split("/").last] += 1
+ @_templates[virtual_path] += 1
+ else
+ path = payload[:identifier]
+ if path
+ @_files[path] += 1
+ @_files[path.split("/").last] += 1
+ end
end
end
end
@@ -233,7 +229,6 @@ module ActionController
@formats = nil
@env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
@env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
- @symbolized_path_params = nil
@method = @request_method = nil
@fullpath = @ip = @remote_ip = @protocol = nil
@env['action_dispatch.request.query_parameters'] = {}
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 0b2b60d2e4..9c8f65deac 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -54,8 +54,14 @@ module ActionDispatch
end
def formats
- @env["action_dispatch.request.formats"] ||=
- if parameters[:format]
+ @env["action_dispatch.request.formats"] ||= begin
+ params_readable = begin
+ parameters[:format]
+ rescue ActionController::BadRequest
+ false
+ end
+
+ if params_readable
Array(Mime[parameters[:format]])
elsif use_accept_header && valid_accept_header
accepts
@@ -64,8 +70,8 @@ module ActionDispatch
else
[Mime::HTML]
end
+ end
end
-
# Sets the \variant for template.
def variant=(variant)
if variant.is_a?(Symbol)
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index 5f7627cf96..20ae48d458 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/indifferent_access'
+require 'active_support/deprecation'
module ActionDispatch
module Http
@@ -24,8 +25,10 @@ module ActionDispatch
@env[PARAMETERS_KEY] = parameters
end
- # The same as <tt>path_parameters</tt> with explicitly symbolized keys.
def symbolized_path_parameters
+ ActiveSupport::Deprecation.warn(
+ "`symbolized_path_parameters` is deprecated. Please use `path_parameters`"
+ )
path_parameters
end
@@ -33,31 +36,22 @@ module ActionDispatch
# Returned hash keys are strings:
#
# {'action' => 'my_action', 'controller' => 'my_controller'}
- #
- # See <tt>symbolized_path_parameters</tt> for symbolized keys.
def path_parameters
@env[PARAMETERS_KEY] ||= {}
end
private
- # Convert nested Hash to HashWithIndifferentAccess
- # and UTF-8 encode both keys and values in nested Hash.
+ # Convert nested Hash to HashWithIndifferentAccess.
#
- # TODO: Validate that the characters are UTF-8. If they aren't,
- # you'll get a weird error down the road, but our form handling
- # should really prevent that from happening
def normalize_encode_params(params)
case params
- when String
- params.force_encoding(Encoding::UTF_8).encode!
when Hash
if params.has_key?(:tempfile)
UploadedFile.new(params)
else
params.each_with_object({}) do |(key, val), new_hash|
- new_key = key.is_a?(String) ? key.dup.force_encoding(Encoding::UTF_8).encode! : key
- new_hash[new_key] = if val.is_a?(Array)
+ new_hash[key] = if val.is_a?(Array)
val.map! { |el| normalize_encode_params(el) }
else
normalize_encode_params(val)
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 4d4b443fb4..01f117be99 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -209,8 +209,8 @@ module ActionDispatch
end
# Returns true if the "X-Requested-With" header contains "XMLHttpRequest"
- # (case-insensitive). All major JavaScript libraries send this header with
- # every Ajax request.
+ # (case-insensitive), which may need to be manually added depending on the
+ # choice of JavaScript libraries and frameworks.
def xml_http_request?
@env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
end
diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb
index 45bf751d09..540e11a4a0 100644
--- a/actionpack/lib/action_dispatch/http/upload.rb
+++ b/actionpack/lib/action_dispatch/http/upload.rb
@@ -27,7 +27,8 @@ module ActionDispatch
@tempfile = hash[:tempfile]
raise(ArgumentError, ':tempfile is required') unless @tempfile
- @original_filename = encode_filename(hash[:filename])
+ @original_filename = hash[:filename]
+ @original_filename &&= @original_filename.encode "UTF-8"
@content_type = hash[:type]
@headers = hash[:head]
end
@@ -66,13 +67,6 @@ module ActionDispatch
def eof?
@tempfile.eof?
end
-
- private
-
- def encode_filename(filename)
- # Encode the filename in the utf8 encoding, unless it is nil
- filename.force_encoding(Encoding::UTF_8).encode! if filename
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index 3997c6ee98..473f692b05 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -29,36 +29,53 @@ module ActionDispatch
end
def url_for(options)
- unless options[:host] || options[:only_path]
+ if options[:only_path]
+ path_for options
+ else
+ full_url_for options
+ end
+ end
+
+ def full_url_for(options)
+ host = options[:host]
+ protocol = options[:protocol]
+ port = options[:port]
+
+ unless host
raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
end
- path = options[:script_name].to_s.chomp("/")
- path << options[:path].to_s
+ build_host_url(host, port, protocol, options, path_for(options))
+ end
- path = add_trailing_slash(path) if options[:trailing_slash]
+ def path_for(options)
+ result = options[:script_name].to_s.chomp("/")
+ result << options[:path].to_s
- result = if options[:only_path]
- path
- else
- build_host_url(options).concat path
- end
+ result = add_trailing_slash(result) if options[:trailing_slash]
+
+ result = add_params options, result
+ add_anchor options, result
+ end
+ private
+
+ def add_params(options, result)
if options.key? :params
- params = options[:params].is_a?(Hash) ?
- options[:params] :
- { params: options[:params] }
+ param = options[:params]
+ params = param.is_a?(Hash) ? param : { params: param }
params.reject! { |_,v| v.to_param.nil? }
result << "?#{params.to_query}" unless params.empty?
end
+ result
+ end
+ def add_anchor(options, result)
result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
result
end
- private
-
def extract_domain_from(host, tld_length)
host.split('.').last(1 + tld_length).join('.')
end
@@ -80,10 +97,7 @@ module ActionDispatch
path
end
- def build_host_url(options)
- protocol = options[:protocol]
- host = options[:host]
- port = options[:port]
+ def build_host_url(host, port, protocol, options, path)
if match = host.match(HOST_REGEXP)
protocol ||= match[1] unless protocol == false
host = match[2]
@@ -104,7 +118,7 @@ module ActionDispatch
result << ":#{normalized_port}"
}
- result
+ result.concat path
end
def named_host?(host)
diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb
index 6d58323789..59b353b1b7 100644
--- a/actionpack/lib/action_dispatch/journey/formatter.rb
+++ b/actionpack/lib/action_dispatch/journey/formatter.rb
@@ -12,12 +12,12 @@ module ActionDispatch
@cache = nil
end
- def generate(name, options, recall = {}, parameterize = nil)
- constraints = recall.merge(options)
+ def generate(name, options, path_parameters, parameterize = nil)
+ constraints = path_parameters.merge(options)
missing_keys = []
match_route(name, constraints) do |route|
- parameterized_parts = extract_parameterized_parts(route, options, recall, parameterize)
+ parameterized_parts = extract_parameterized_parts(route, options, path_parameters, parameterize)
# Skip this route unless a name has been provided or it is a
# standard Rails route since we can't determine whether an options
diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb
index fe3fc0a9fa..21817b374c 100644
--- a/actionpack/lib/action_dispatch/journey/router.rb
+++ b/actionpack/lib/action_dispatch/journey/router.rb
@@ -105,7 +105,8 @@ module ActionDispatch
routes.concat get_routes_as_head(routes)
end
- routes.sort_by!(&:precedence).select! { |r| r.matches?(req) }
+ routes.select! { |r| r.matches?(req) }
+ routes.sort_by!(&:precedence)
routes.map! { |r|
match_data = r.path.match(req.path_info)
diff --git a/actionpack/lib/action_dispatch/journey/router/utils.rb b/actionpack/lib/action_dispatch/journey/router/utils.rb
index ac4ecb1e65..2b0a6575d4 100644
--- a/actionpack/lib/action_dispatch/journey/router/utils.rb
+++ b/actionpack/lib/action_dispatch/journey/router/utils.rb
@@ -25,9 +25,10 @@ module ActionDispatch
# http://tools.ietf.org/html/rfc3986
class UriEncoder # :nodoc:
ENCODE = "%%%02X".freeze
- ENCODING = Encoding::US_ASCII
- EMPTY = "".force_encoding(ENCODING).freeze
- DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(ENCODING) }
+ US_ASCII = Encoding::US_ASCII
+ UTF_8 = Encoding::UTF_8
+ EMPTY = "".force_encoding(US_ASCII).freeze
+ DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(US_ASCII) }
ALPHA = "a-zA-Z".freeze
DIGIT = "0-9".freeze
@@ -53,12 +54,13 @@ module ActionDispatch
end
def unescape_uri(uri)
- uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(uri.encoding)
+ encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding
+ uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding)
end
protected
def escape(component, pattern)
- component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(ENCODING)
+ component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(US_ASCII)
end
def percent_encode(unsafe)
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 22b16b628d..ac9e5effe2 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -289,8 +289,8 @@ module ActionDispatch
end
end
- # Sets the cookie named +name+. The second argument may be the very cookie
- # value, or a hash of options as documented above.
+ # Sets the cookie named +name+. The second argument may be the cookie's
+ # value or a hash of options as documented above.
def []=(name, options)
if options.is_a?(Hash)
options.symbolize_keys!
@@ -468,7 +468,7 @@ module ActionDispatch
options = { :value => @verifier.generate(serialize(name, options)) }
end
- raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
+ raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
@parent_jar[name] = options
end
@@ -526,7 +526,7 @@ module ActionDispatch
options[:value] = @encryptor.encrypt_and_sign(serialize(name, options[:value]))
- raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
+ raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
@parent_jar[name] = options
end
diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb
index 4821d2a899..e90f8b9ce6 100644
--- a/actionpack/lib/action_dispatch/middleware/flash.rb
+++ b/actionpack/lib/action_dispatch/middleware/flash.rb
@@ -10,7 +10,7 @@ module ActionDispatch
end
end
- # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
+ # The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed
# to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
# action that sets <tt>flash[:notice] = "Post successfully created"</tt> before redirecting to a display action that can
# then expose the flash to its template. Actually, that exposure is automatically done.
@@ -37,8 +37,11 @@ module ActionDispatch
# flash.alert = "You must be logged in"
# flash.notice = "Post successfully created"
#
- # This example just places a string in the flash, but you can put any object in there. And of course, you can put as
- # many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
+ # This example places a string in the flash. And of course, you can put as many as you like at a time too. If you want to pass
+ # non-primitive types, you will have to handle that in your application. Example: To show messages with links, you will have to
+ # use sanitize helper.
+ #
+ # Just remember: They'll be gone by the time the next action has been performed.
#
# See docs on the FlashHash class for more details about the flash.
class Flash
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 0864e7ef2a..ed25c67ae5 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -49,7 +49,7 @@ module ActionDispatch
# reasonably sure that your upgrade is otherwise complete. Additionally,
# you should take care to make sure you are not relying on the ability to
# decode signed cookies generated by your app in external applications or
- # Javascript before upgrading.
+ # JavaScript before upgrading.
#
# Note that changing the secret key will invalidate all existing sessions!
class CookieStore < Rack::Session::Abstract::ID
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index 1d4f0f89a6..f0779279c1 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -42,6 +42,7 @@ module ActionDispatch
wrapper = ExceptionWrapper.new(env, exception)
status = wrapper.status_code
env["action_dispatch.exception"] = wrapper.exception
+ env["action_dispatch.original_path"] = env["PATH_INFO"]
env["PATH_INFO"] = "/#{status}"
response = @exceptions_app.call(env)
response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index aac5546aa1..32d963ba76 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -66,7 +66,7 @@ module ActionDispatch
attr_reader :requirements, :conditions, :defaults
attr_reader :to, :default_controller, :default_action, :as, :anchor
- def self.build(scope, path, options)
+ def self.build(scope, set, path, options)
options = scope[:options].merge(options) if scope[:options]
options.delete :only
@@ -77,12 +77,13 @@ module ActionDispatch
defaults = (scope[:defaults] || {}).merge options.delete(:defaults) || {}
- new scope, path, defaults, options
+ new scope, set, path, defaults, options
end
- def initialize(scope, path, defaults, options)
+ def initialize(scope, set, path, defaults, options)
@requirements, @conditions = {}, {}
@defaults = defaults
+ @set = set
@to = options.delete :to
@default_controller = options.delete(:controller) || scope[:controller]
@@ -249,9 +250,9 @@ module ActionDispatch
Constraints.new(to, blocks, false)
else
if blocks.any?
- Constraints.new(dispatcher, blocks, true)
+ Constraints.new(dispatcher(defaults), blocks, true)
else
- dispatcher
+ dispatcher(defaults)
end
end
end
@@ -348,8 +349,8 @@ module ActionDispatch
parser.parse path
end
- def dispatcher
- Routing::RouteSet::Dispatcher.new(defaults)
+ def dispatcher(defaults)
+ @set.dispatcher defaults
end
end
@@ -576,13 +577,21 @@ module ActionDispatch
raise "A rack application must be specified" unless path
- options[:as] ||= app_name(app)
+ rails_app = rails_app? app
+
+ if rails_app
+ options[:as] ||= app.railtie_name
+ else
+ # non rails apps can't have an :as
+ options[:as] = nil
+ end
+
target_as = name_for_action(options[:as], path)
options[:via] ||= :all
match(path, options.merge(:to => app, :anchor => false, :format => false))
- define_generate_prefix(app, target_as)
+ define_generate_prefix(app, target_as) if rails_app
self
end
@@ -603,20 +612,11 @@ module ActionDispatch
end
private
- def app_name(app)
- return unless app.respond_to?(:routes)
-
- if app.respond_to?(:railtie_name)
- app.railtie_name
- else
- class_name = app.class.is_a?(Class) ? app.name : app.class.name
- ActiveSupport::Inflector.underscore(class_name).tr("/", "_")
- end
+ def rails_app?(app)
+ app.is_a?(Class) && app < Rails::Railtie
end
def define_generate_prefix(app, name)
- return unless app.respond_to?(:routes) && app.routes.respond_to?(:define_mounted_helper)
-
_route = @set.named_routes.routes[name.to_sym]
_routes = @set
app.routes.define_mounted_helper(name)
@@ -717,7 +717,7 @@ module ActionDispatch
# resources :posts, module: "admin"
#
# If you want to route /admin/posts to +PostsController+
- # (without the Admin:: module prefix), you could use
+ # (without the <tt>Admin::</tt> module prefix), you could use
#
# scope "/admin" do
# resources :posts
@@ -1434,7 +1434,7 @@ module ActionDispatch
end
with_scope_level(:nested) do
- if shallow? && shallow_nesting_depth > 1
+ if shallow? && shallow_nesting_depth >= 1
shallow_scope(parent_resource.nested_scope, nested_options) { yield }
else
scope(parent_resource.nested_scope, nested_options) { yield }
@@ -1545,13 +1545,13 @@ module ActionDispatch
action = nil
end
- if !options.fetch(:as, true)
+ if !options.fetch(:as, true) # if it's set to nil or false
options.delete(:as)
else
options[:as] = name_for_action(options[:as], action)
end
- mapping = Mapping.build(@scope, URI.parser.escape(path), options)
+ mapping = Mapping.build(@scope, @set, URI.parser.escape(path), options)
app, conditions, requirements, defaults, as, anchor = mapping.to_route
@set.add_route(app, conditions, requirements, defaults, as, anchor)
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 69535faabd..80c705608d 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -134,11 +134,11 @@ module ActionDispatch
end
class UrlHelper # :nodoc:
- def self.create(route, options)
+ def self.create(route, options, route_name, url_strategy)
if optimize_helper?(route)
- OptimizedUrlHelper.new(route, options)
+ OptimizedUrlHelper.new(route, options, route_name, url_strategy)
else
- new route, options
+ new route, options, route_name, url_strategy
end
end
@@ -146,20 +146,22 @@ module ActionDispatch
!route.glob? && route.path.requirements.empty?
end
+ attr_reader :url_strategy, :route_name
+
class OptimizedUrlHelper < UrlHelper # :nodoc:
attr_reader :arg_size
- def initialize(route, options)
+ def initialize(route, options, route_name, url_strategy)
super
@required_parts = @route.required_parts
@arg_size = @required_parts.size
end
- def call(t, args)
- if args.size == arg_size && !args.last.is_a?(Hash) && optimize_routes_generation?(t)
+ def call(t, args, inner_options)
+ if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
options = t.url_options.merge @options
options[:path] = optimized_helper(args)
- ActionDispatch::Http::URL.url_for(options)
+ url_strategy.call options
else
super
end
@@ -201,21 +203,27 @@ module ActionDispatch
end
end
- def initialize(route, options)
+ def initialize(route, options, route_name, url_strategy)
@options = options
@segment_keys = route.segment_keys.uniq
@route = route
+ @url_strategy = url_strategy
+ @route_name = route_name
end
- def call(t, args)
+ def call(t, args, inner_options)
controller_options = t.url_options
options = controller_options.merge @options
- hash = handle_positional_args(controller_options, args, options, @segment_keys)
- t._routes.url_for(hash)
+ hash = handle_positional_args(controller_options,
+ inner_options || {},
+ args,
+ options,
+ @segment_keys)
+
+ t._routes.url_for(hash, route_name, url_strategy)
end
- def handle_positional_args(controller_options, args, result, path_params)
- inner_options = args.extract_options!
+ def handle_positional_args(controller_options, inner_options, args, result, path_params)
if args.size > 0
if args.size < path_params.size - 1 # take format into account
@@ -245,13 +253,15 @@ module ActionDispatch
#
# foo_url(bar, baz, bang, sort_by: 'baz')
#
- def define_url_helper(route, name, options)
- helper = UrlHelper.create(route, options.dup)
+ def define_url_helper(route, name, opts, route_key, url_strategy)
+ helper = UrlHelper.create(route, opts, route_key, url_strategy)
@module.remove_possible_method name
@module.module_eval do
define_method(name) do |*args|
- helper.call self, args
+ options = nil
+ options = args.pop if args.last.is_a? Hash
+ helper.call self, args, options
end
end
@@ -259,13 +269,18 @@ module ActionDispatch
end
def define_named_route_methods(name, route)
- define_url_helper route, :"#{name}_path",
- route.defaults.merge(:use_route => name, :only_path => true)
- define_url_helper route, :"#{name}_url",
- route.defaults.merge(:use_route => name, :only_path => false)
+ define_url_helper route, :"#{name}_path", route.defaults, name, PATH
+ define_url_helper route, :"#{name}_url", route.defaults, name, FULL
end
end
+ # :stopdoc:
+ # strategy for building urls to send to the client
+ PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
+ FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
+ UNKNOWN = ->(options) { ActionDispatch::Http::URL.url_for(options) }
+ # :startdoc:
+
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
attr_accessor :disable_clear_and_finalize, :resources_path_names
attr_accessor :default_url_options, :request_class
@@ -334,6 +349,10 @@ module ActionDispatch
@prepend.each { |blk| eval_block(blk) }
end
+ def dispatcher(defaults)
+ Routing::RouteSet::Dispatcher.new(defaults)
+ end
+
module MountedHelpers #:nodoc:
extend ActiveSupport::Concern
include UrlFor
@@ -491,8 +510,8 @@ module ActionDispatch
attr_reader :options, :recall, :set, :named_route
- def initialize(options, recall, set)
- @named_route = options.delete(:use_route)
+ def initialize(named_route, options, recall, set)
+ @named_route = named_route
@options = options.dup
@recall = recall.dup
@set = set
@@ -608,13 +627,15 @@ module ActionDispatch
end
def generate_extras(options, recall={})
- path, params = generate(options, recall)
+ route_key = options.delete :use_route
+ path, params = generate(route_key, options, recall)
return path, params.keys
end
- def generate(options, recall = {})
- Generator.new(options, recall, self).generate
+ def generate(route_key, options, recall = {})
+ Generator.new(route_key, options, recall, self).generate
end
+ private :generate
RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
:trailing_slash, :anchor, :params, :only_path, :script_name,
@@ -633,7 +654,7 @@ module ActionDispatch
end
# The +options+ argument must be a hash whose keys are *symbols*.
- def url_for(options)
+ def url_for(options, route_name = nil, url_strategy = UNKNOWN)
options = default_url_options.merge options
user = password = nil
@@ -655,7 +676,7 @@ module ActionDispatch
path_options = options.dup
RESERVED_OPTIONS.each { |ro| path_options.delete ro }
- path, params = generate(path_options, recall)
+ path, params = generate(route_name, path_options, recall)
if options.key? :params
params.merge! options[:params]
@@ -667,7 +688,7 @@ module ActionDispatch
options[:user] = user
options[:password] = password
- ActionDispatch::Http::URL.url_for(options)
+ url_strategy.call options
end
def call(env)
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index e624fe3c4a..e1c73f8f07 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -152,7 +152,9 @@ module ActionDispatch
when nil
_routes.url_for(url_options.symbolize_keys)
when Hash
- _routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
+ route_name = options.delete :use_route
+ _routes.url_for(options.symbolize_keys.reverse_merge!(url_options),
+ route_name)
when String
options
when Symbol
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 17765d851b..cb2cb10870 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -188,8 +188,8 @@ module ActionDispatch
# This makes app.url_for and app.foo_path available in the console
if app.respond_to?(:routes)
singleton_class.class_eval do
- include app.routes.url_helpers if app.routes.respond_to?(:url_helpers)
- include app.routes.mounted_helpers if app.routes.respond_to?(:mounted_helpers)
+ include app.routes.url_helpers
+ include app.routes.mounted_helpers
end
end
@@ -200,7 +200,7 @@ module ActionDispatch
@url_options ||= default_url_options.dup.tap do |url_options|
url_options.reverse_merge!(controller.url_options) if controller
- if @app.respond_to?(:routes) && @app.routes.respond_to?(:default_url_options)
+ if @app.respond_to?(:routes)
url_options.reverse_merge!(@app.routes.default_url_options)
end
diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb
index 57c678843b..de3dc5f924 100644
--- a/actionpack/lib/action_dispatch/testing/test_request.rb
+++ b/actionpack/lib/action_dispatch/testing/test_request.rb
@@ -39,7 +39,7 @@ module ActionDispatch
end
def action=(action_name)
- path_parameters["action"] = action_name.to_s
+ path_parameters[:action] = action_name.to_s
end
def if_modified_since=(last_modified)
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 6584d20840..0f7b3a08e1 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -15,6 +15,10 @@ silence_warnings do
Encoding.default_external = "UTF-8"
end
+require 'drb'
+require 'drb/unix'
+require 'tempfile'
+
require 'active_support/testing/autorun'
require 'abstract_controller'
require 'action_controller'
@@ -105,6 +109,7 @@ end
module ActiveSupport
class TestCase
include ActionDispatch::DrawOnce
+ parallelize_me! if ActiveSupport::Testing::Isolation.forking_env?
end
end
@@ -305,22 +310,95 @@ end
module ActionDispatch
module RoutingVerbs
- def get(uri_or_host, path = nil)
+ def send_request(uri_or_host, method, path)
host = uri_or_host.host unless path
path ||= uri_or_host.path
params = {'PATH_INFO' => path,
- 'REQUEST_METHOD' => 'GET',
+ 'REQUEST_METHOD' => method,
'HTTP_HOST' => host}
- routes.call(params)[2].join
+ routes.call(params)
+ end
+
+ def request_path_params(path, options = {})
+ method = options[:method] || 'GET'
+ resp = send_request URI('http://localhost' + path), method.to_s.upcase, nil
+ status = resp.first
+ if status == 404
+ raise ActionController::RoutingError, "No route matches #{path.inspect}"
+ end
+ controller.request.path_parameters
+ end
+
+ def get(uri_or_host, path = nil)
+ send_request(uri_or_host, 'GET', path)[2].join
+ end
+
+ def post(uri_or_host, path = nil)
+ send_request(uri_or_host, 'POST', path)[2].join
+ end
+
+ def put(uri_or_host, path = nil)
+ send_request(uri_or_host, 'PUT', path)[2].join
+ end
+
+ def delete(uri_or_host, path = nil)
+ send_request(uri_or_host, 'DELETE', path)[2].join
+ end
+
+ def patch(uri_or_host, path = nil)
+ send_request(uri_or_host, 'PATCH', path)[2].join
end
end
end
module RoutingTestHelpers
- def url_for(set, options, recall = {})
- set.url_for options.merge(:only_path => true, :_recall => recall)
+ def url_for(set, options)
+ route_name = options.delete :use_route
+ set.url_for options.merge(:only_path => true), route_name
+ end
+
+ def make_set(strict = true)
+ tc = self
+ TestSet.new ->(c) { tc.controller = c }, strict
+ end
+
+ class TestSet < ActionDispatch::Routing::RouteSet
+ attr_reader :strict
+
+ def initialize(block, strict = false)
+ @block = block
+ @strict = strict
+ super()
+ end
+
+ class Dispatcher < ActionDispatch::Routing::RouteSet::Dispatcher
+ def initialize(defaults, set, block)
+ super(defaults)
+ @block = block
+ @set = set
+ end
+
+ def controller(params, default_controller=true)
+ super(params, @set.strict)
+ end
+
+ def controller_reference(controller_param)
+ block = @block
+ set = @set
+ super if @set.strict
+ Class.new(ActionController::Base) {
+ include set.url_helpers
+ define_method(:process) { |name| block.call(self) }
+ def to_a; [200, {}, []]; end
+ }
+ end
+ end
+
+ def dispatcher defaults
+ TestSet::Dispatcher.new defaults, self, @block
+ end
end
end
@@ -359,3 +437,57 @@ end
def jruby_skip(message = '')
skip message if defined?(JRUBY_VERSION)
end
+
+class ForkingExecutor
+ class Server
+ include DRb::DRbUndumped
+
+ def initialize
+ @queue = Queue.new
+ end
+
+ def record reporter, result
+ reporter.record result
+ end
+
+ def << o
+ o[2] = DRbObject.new(o[2]) if o
+ @queue << o
+ end
+ def pop; @queue.pop; end
+ end
+
+ def initialize size
+ @size = size
+ @queue = Server.new
+ file = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('tests', 'fd')
+ @url = "drbunix://#{file}"
+ @pool = nil
+ DRb.start_service @url, @queue
+ end
+
+ def << work; @queue << work; end
+
+ def shutdown
+ pool = @size.times.map {
+ fork {
+ DRb.stop_service
+ queue = DRbObject.new_with_uri @url
+ while job = queue.pop
+ klass = job[0]
+ method = job[1]
+ reporter = job[2]
+ result = Minitest.run_one_method klass, method
+ queue.record reporter, result
+ end
+ }
+ }
+ @size.times { @queue << nil }
+ pool.each { |pid| Process.waitpid pid }
+ end
+end
+
+if ActiveSupport::Testing::Isolation.forking_env?
+ # Use N processes (N defaults to 4)
+ Minitest.parallel_executor = ForkingExecutor.new((ENV['N'] || 4).to_i)
+end
diff --git a/actionpack/test/controller/http_token_authentication_test.rb b/actionpack/test/controller/http_token_authentication_test.rb
index ef90fff178..8c6c8a0aa7 100644
--- a/actionpack/test/controller/http_token_authentication_test.rb
+++ b/actionpack/test/controller/http_token_authentication_test.rb
@@ -139,16 +139,36 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
assert_equal(expected, actual)
end
+ test "token_and_options returns correct token with nounce option" do
+ token = "rcHu+HzSFw89Ypyhn/896A="
+ nonce_hash = {nonce: "123abc"}
+ actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token, nonce_hash))
+ expected_token = token
+ expected_nonce = {"nonce" => nonce_hash[:nonce]}
+ assert_equal(expected_token, actual.first)
+ assert_equal(expected_nonce, actual.last)
+ end
+
test "token_and_options returns nil with no value after the equal sign" do
actual = ActionController::HttpAuthentication::Token.token_and_options(malformed_request).first
expected = nil
assert_equal(expected, actual)
end
+ test "raw_params returns a tuple of two key value pair strings" do
+ auth = sample_request("rcHu+HzSFw89Ypyhn/896A=").authorization.to_s
+ actual = ActionController::HttpAuthentication::Token.raw_params(auth)
+ expected = ["token=\"rcHu+HzSFw89Ypyhn/896A=\"", "nonce=\"def\""]
+ assert_equal(expected, actual)
+ end
+
private
- def sample_request(token)
- @sample_request ||= OpenStruct.new authorization: %{Token token="#{token}", nonce="def"}
+ def sample_request(token, options = {nonce: "def"})
+ authorization = options.inject([%{Token token="#{token}"}]) do |arr, (k, v)|
+ arr << "#{k}=\"#{v}\""
+ end.join(", ")
+ @sample_request ||= OpenStruct.new authorization: authorization
end
def malformed_request
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 214eab2f0d..78cce3aa64 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'controller/fake_controllers'
require 'action_view/vendor/html-scanner'
+require 'rails/engine'
class SessionTest < ActiveSupport::TestCase
StubApp = lambda { |env|
@@ -595,7 +596,7 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
@routes ||= ActionDispatch::Routing::RouteSet.new
end
- class MountedApp
+ class MountedApp < Rails::Engine
def self.routes
@routes ||= ActionDispatch::Routing::RouteSet.new
end
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index 18037b3d2f..49be7caf38 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -85,7 +85,7 @@ class ACLogSubscriberTest < ActionController::TestCase
@old_logger = ActionController::Base.logger
- @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__))
+ @cache_path = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('tmp', 'cache')
@controller.cache_store = :file_store, @cache_path
ActionController::LogSubscriber.attach_to :action_controller
end
diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb
index 41503e11a8..1bc7ad3015 100644
--- a/actionpack/test/controller/mime/respond_to_test.rb
+++ b/actionpack/test/controller/mime/respond_to_test.rb
@@ -128,6 +128,12 @@ class RespondToController < ActionController::Base
end
end
+ def json_with_callback
+ respond_to do |type|
+ type.json { render :json => 'JS', :callback => 'alert' }
+ end
+ end
+
def iphone_with_html_response_type
request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
@@ -511,6 +517,13 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
end
+ def test_json_with_callback_sets_javascript_content_type
+ @request.accept = 'application/json'
+ get :json_with_callback
+ assert_equal '/**/alert(JS)', @response.body
+ assert_equal 'text/javascript', @response.content_type
+ end
+
def test_xhr
xhr :get, :js_or_html
assert_equal 'JS', @response.body
diff --git a/actionpack/test/controller/new_base/render_body_test.rb b/actionpack/test/controller/new_base/render_body_test.rb
index fad848349a..f4a3db8b41 100644
--- a/actionpack/test/controller/new_base/render_body_test.rb
+++ b/actionpack/test/controller/new_base/render_body_test.rb
@@ -111,17 +111,17 @@ module RenderBody
assert_status 404
end
- test "rendering body with nil returns an empty body padded for Safari" do
+ test "rendering body with nil returns an empty body" do
get "/render_body/with_layout/with_nil"
- assert_body " "
+ assert_body ""
assert_status 200
end
- test "Rendering body with nil and custom status code returns an empty body padded for Safari and the status" do
+ test "Rendering body with nil and custom status code returns an empty body and the status" do
get "/render_body/with_layout/with_nil_and_status"
- assert_body " "
+ assert_body ""
assert_status 403
end
diff --git a/actionpack/test/controller/new_base/render_html_test.rb b/actionpack/test/controller/new_base/render_html_test.rb
index bfe0271df7..fe11501eeb 100644
--- a/actionpack/test/controller/new_base/render_html_test.rb
+++ b/actionpack/test/controller/new_base/render_html_test.rb
@@ -114,17 +114,17 @@ module RenderHtml
assert_status 404
end
- test "rendering text with nil returns an empty body padded for Safari" do
+ test "rendering text with nil returns an empty body" do
get "/render_html/with_layout/with_nil"
- assert_body " "
+ assert_body ""
assert_status 200
end
- test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do
+ test "Rendering text with nil and custom status code returns an empty body and the status" do
get "/render_html/with_layout/with_nil_and_status"
- assert_body " "
+ assert_body ""
assert_status 403
end
diff --git a/actionpack/test/controller/new_base/render_plain_test.rb b/actionpack/test/controller/new_base/render_plain_test.rb
index dba2e9f13e..0e36d36b50 100644
--- a/actionpack/test/controller/new_base/render_plain_test.rb
+++ b/actionpack/test/controller/new_base/render_plain_test.rb
@@ -106,17 +106,17 @@ module RenderPlain
assert_status 404
end
- test "rendering text with nil returns an empty body padded for Safari" do
+ test "rendering text with nil returns an empty body" do
get "/render_plain/with_layout/with_nil"
- assert_body " "
+ assert_body ""
assert_status 200
end
- test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do
+ test "Rendering text with nil and custom status code returns an empty body and the status" do
get "/render_plain/with_layout/with_nil_and_status"
- assert_body " "
+ assert_body ""
assert_status 403
end
diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb
index b7a9cf92f2..e87811776a 100644
--- a/actionpack/test/controller/new_base/render_template_test.rb
+++ b/actionpack/test/controller/new_base/render_template_test.rb
@@ -9,7 +9,7 @@ module RenderTemplate
"locals.html.erb" => "The secret is <%= secret %>",
"xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend",
"with_raw.html.erb" => "Hello <%=raw '<strong>this is raw</strong>' %>",
- "with_implicit_raw.html.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in a html template",
+ "with_implicit_raw.html.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in an html template",
"with_implicit_raw.text.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in a text template",
"test/with_json.html.erb" => "<%= render :template => 'test/with_json', :formats => [:json] %>",
"test/with_json.json.erb" => "<%= render :template => 'test/final', :formats => [:json] %>",
@@ -114,7 +114,7 @@ module RenderTemplate
get :with_implicit_raw
- assert_body "Hello <strong>this is also raw</strong> in a html template"
+ assert_body "Hello <strong>this is also raw</strong> in an html template"
assert_status 200
get :with_implicit_raw, format: 'text'
diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb
index abb81d7e71..10bad57cd6 100644
--- a/actionpack/test/controller/new_base/render_text_test.rb
+++ b/actionpack/test/controller/new_base/render_text_test.rb
@@ -106,17 +106,17 @@ module RenderText
assert_status 404
end
- test "rendering text with nil returns an empty body padded for Safari" do
+ test "rendering text with nil returns an empty body" do
get "/render_text/with_layout/with_nil"
- assert_body " "
+ assert_body ""
assert_status 200
end
- test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do
+ test "Rendering text with nil and custom status code returns an empty body and the status" do
get "/render_text/with_layout/with_nil_and_status"
- assert_body " "
+ assert_body ""
assert_status 403
end
diff --git a/actionpack/test/controller/parameters/always_permitted_parameters_test.rb b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb
new file mode 100644
index 0000000000..059f310d49
--- /dev/null
+++ b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb
@@ -0,0 +1,29 @@
+require 'abstract_unit'
+require 'action_controller/metal/strong_parameters'
+
+class AlwaysPermittedParametersTest < ActiveSupport::TestCase
+ def setup
+ ActionController::Parameters.action_on_unpermitted_parameters = :raise
+ ActionController::Parameters.always_permitted_parameters = %w( controller action format )
+ end
+
+ def teardown
+ ActionController::Parameters.action_on_unpermitted_parameters = false
+ ActionController::Parameters.always_permitted_parameters = %w( controller action )
+ end
+
+ test "shows deprecations warning on NEVER_UNPERMITTED_PARAMS" do
+ assert_deprecated do
+ ActionController::Parameters::NEVER_UNPERMITTED_PARAMS
+ end
+ end
+
+ test "permits parameters that are whitelisted" do
+ params = ActionController::Parameters.new({
+ book: { pages: 65 },
+ format: "json"
+ })
+ permitted = params.permit book: [:pages]
+ assert permitted.permitted?
+ end
+end
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index 4331333b98..103ca9c776 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -90,6 +90,10 @@ class RedirectController < ActionController::Base
redirect_to nil
end
+ def redirect_to_params
+ redirect_to ActionController::Parameters.new(status: 200, protocol: 'javascript', f: '%0Aeval(name)')
+ end
+
def redirect_to_with_block
redirect_to proc { "http://www.rubyonrails.org/" }
end
@@ -281,6 +285,12 @@ class RedirectTest < ActionController::TestCase
end
end
+ def test_redirect_to_params
+ assert_raise(ActionController::ActionControllerError) do
+ get :redirect_to_params
+ end
+ end
+
def test_redirect_to_with_block
get :redirect_to_with_block
assert_response :redirect
diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb
index de8d1cbd9b..ada978aa11 100644
--- a/actionpack/test/controller/render_json_test.rb
+++ b/actionpack/test/controller/render_json_test.rb
@@ -101,7 +101,7 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json_with_callback
xhr :get, :render_json_hello_world_with_callback
- assert_equal 'alert({"hello":"world"})', @response.body
+ assert_equal '/**/alert({"hello":"world"})', @response.body
assert_equal 'text/javascript', @response.content_type
end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 721dad4dd9..c18914cc8e 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -77,10 +77,11 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
include ActionDispatch::RoutingVerbs
attr_reader :rs
+ attr_accessor :controller
alias :routes :rs
def setup
- @rs = ::ActionDispatch::Routing::RouteSet.new
+ @rs = make_set
@response = nil
end
@@ -317,11 +318,16 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
assert_equal '/admin/user/show/10', url_for(rs, { :controller => 'admin/user', :action => 'show', :id => 10 })
- assert_equal '/admin/user/show', url_for(rs, { :action => 'show' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
- assert_equal '/admin/user/list/10', url_for(rs, {}, { :controller => 'admin/user', :action => 'list', :id => '10' })
+ get URI('http://test.host/admin/user/list/10')
- assert_equal '/admin/stuff', url_for(rs, { :controller => 'stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
- assert_equal '/stuff', url_for(rs, { :controller => '/stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
+ assert_equal({ :controller => 'admin/user', :action => 'list', :id => '10' },
+ controller.request.path_parameters)
+
+ assert_equal '/admin/user/show', controller.url_for({ :action => 'show', :only_path => true })
+ assert_equal '/admin/user/list/10', controller.url_for({:only_path => true})
+
+ assert_equal '/admin/stuff', controller.url_for({ :controller => 'stuff', :only_path => true })
+ assert_equal '/stuff', controller.url_for({ :controller => '/stuff', :only_path => true })
end
def test_ignores_leading_slash
@@ -518,9 +524,10 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_changing_controller
rs.draw { get ':controller/:action/:id' }
+ get URI('http://test.host/admin/user/index/10')
+
assert_equal '/admin/stuff/show/10',
- url_for(rs, {:controller => 'stuff', :action => 'show', :id => 10},
- {:controller => 'admin/user', :action => 'index'})
+ controller.url_for({:controller => 'stuff', :action => 'show', :id => 10, :only_path => true})
end
def test_paths_escaped
@@ -579,8 +586,12 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
get '*path' => 'content#show_file'
end
+ get URI('http://test.host/pages/boo')
+ assert_equal({:controller=>"content", :action=>"show_file", :path=>"pages/boo"},
+ controller.request.path_parameters)
+
assert_equal '/pages/boo',
- url_for(rs, {}, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
+ controller.url_for(:only_path => true)
end
def test_backwards
@@ -589,7 +600,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
get ':controller(/:action(/:id))'
end
- assert_equal '/page/20', url_for(rs, { :id => 20 }, { :controller => 'pages', :action => 'show' })
+ get URI('http://test.host/pages/show')
+ assert_equal '/page/20', controller.url_for({ :id => 20, :only_path => true })
assert_equal '/page/20', url_for(rs, { :controller => 'pages', :id => 20, :action => 'show' })
assert_equal '/pages/boo', url_for(rs, { :controller => 'pages', :action => 'boo' })
end
@@ -630,7 +642,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_action_expiry
rs.draw { get ':controller(/:action(/:id))' }
- assert_equal '/content', url_for(rs, { :controller => 'content' }, { :controller => 'content', :action => 'show' })
+ get URI('http://test.host/content/show')
+ assert_equal '/content', controller.url_for(:controller => 'content', :only_path => true)
end
def test_requirement_should_prevent_optional_id
@@ -673,14 +686,18 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
assert_equal '/pages/2005/6/12',
url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12 })
+ get URI('http://test.host/pages/2005/6/12')
+ assert_equal({ :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' },
+ controller.request.path_parameters)
+
assert_equal '/pages/2005/6/4',
- url_for(rs, { :day => 4 }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
+ controller.url_for({ :day => 4, :only_path => true })
assert_equal '/pages/2005/6',
- url_for(rs, { :day => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
+ controller.url_for({ :day => nil, :only_path => true })
assert_equal '/pages/2005',
- url_for(rs, { :day => nil, :month => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
+ controller.url_for({ :day => nil, :month => nil, :only_path => true })
end
def test_root_url_generation_with_controller_and_action
@@ -838,9 +855,15 @@ end
class RouteSetTest < ActiveSupport::TestCase
include RoutingTestHelpers
+ include ActionDispatch::RoutingVerbs
- def set
- @set ||= ROUTING::RouteSet.new
+ attr_reader :set
+ alias :routes :set
+ attr_accessor :controller
+
+ def setup
+ super
+ @set = make_set
end
def request
@@ -941,7 +964,8 @@ class RouteSetTest < ActiveSupport::TestCase
get '/admin/users' => 'admin/users#index', :as => "users"
end
- MockController.build(set.url_helpers).new
+ get URI('http://test.host/people')
+ controller
end
def test_named_route_url_method
@@ -1038,12 +1062,12 @@ class RouteSetTest < ActiveSupport::TestCase
get '/:controller(/:action(/:id))'
end
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
- assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
+ assert_equal({:controller => 'pages', :action => 'index'}, request_path_params('/pages'))
+ assert_equal({:controller => 'pages', :action => 'index'}, request_path_params('/pages/index'))
+ assert_equal({:controller => 'pages', :action => 'list'}, request_path_params('/pages/list'))
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/pages/show/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/page/10'))
end
def test_route_constraints_on_request_object_with_anchors_are_valid
@@ -1095,9 +1119,7 @@ class RouteSetTest < ActiveSupport::TestCase
get "/people" => "missing#index"
end
- assert_raise(ActionController::RoutingError) {
- set.recognize_path("/people", :method => :get)
- }
+ assert_raises(ActionController::RoutingError) { request_path_params '/people' }
end
def test_recognize_with_encoded_id_and_regex
@@ -1105,8 +1127,8 @@ class RouteSetTest < ActiveSupport::TestCase
get 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/
end
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
- assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/page/10'))
+ assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, request_path_params('/page/hello+world'))
end
def test_recognize_with_http_methods
@@ -1119,40 +1141,40 @@ class RouteSetTest < ActiveSupport::TestCase
delete "/people/:id" => "people#destroy"
end
- params = set.recognize_path("/people", :method => :get)
+ params = request_path_params("/people", :method => :get)
assert_equal("index", params[:action])
- params = set.recognize_path("/people", :method => :post)
+ params = request_path_params("/people", :method => :post)
assert_equal("create", params[:action])
- params = set.recognize_path("/people/5", :method => :put)
+ params = request_path_params("/people/5", :method => :put)
assert_equal("update", params[:action])
- params = set.recognize_path("/people/5", :method => :patch)
+ params = request_path_params("/people/5", :method => :patch)
assert_equal("update", params[:action])
assert_raise(ActionController::UnknownHttpMethod) {
- set.recognize_path("/people", :method => :bacon)
+ request_path_params("/people", :method => :bacon)
}
- params = set.recognize_path("/people/5", :method => :get)
+ params = request_path_params("/people/5", :method => :get)
assert_equal("show", params[:action])
assert_equal("5", params[:id])
- params = set.recognize_path("/people/5", :method => :put)
+ params = request_path_params("/people/5", :method => :put)
assert_equal("update", params[:action])
assert_equal("5", params[:id])
- params = set.recognize_path("/people/5", :method => :patch)
+ params = request_path_params("/people/5", :method => :patch)
assert_equal("update", params[:action])
assert_equal("5", params[:id])
- params = set.recognize_path("/people/5", :method => :delete)
+ params = request_path_params("/people/5", :method => :delete)
assert_equal("destroy", params[:action])
assert_equal("5", params[:id])
assert_raise(ActionController::RoutingError) {
- set.recognize_path("/people/5", :method => :post)
+ request_path_params("/people/5", :method => :post)
}
end
@@ -1162,11 +1184,11 @@ class RouteSetTest < ActiveSupport::TestCase
root :to => "people#index"
end
- params = set.recognize_path("/people", :method => :get)
+ params = request_path_params("/people", :method => :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
- params = set.recognize_path("/", :method => :get)
+ params = request_path_params("/", :method => :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
end
@@ -1177,7 +1199,7 @@ class RouteSetTest < ActiveSupport::TestCase
:year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
end
- params = set.recognize_path("/articles/2005/11/05/a-very-interesting-article", :method => :get)
+ params = request_path_params("/articles/2005/11/05/a-very-interesting-article", :method => :get)
assert_equal("permalink", params[:action])
assert_equal("2005", params[:year])
assert_equal("11", params[:month])
@@ -1191,7 +1213,7 @@ class RouteSetTest < ActiveSupport::TestCase
get '/profile' => 'profile#index'
end
- set.recognize_path("/profile") rescue nil
+ request_path_params("/profile") rescue nil
assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
end
@@ -1204,17 +1226,17 @@ class RouteSetTest < ActiveSupport::TestCase
get "people/:id(.:format)" => "people#show"
end
- params = set.recognize_path("/people/5", :method => :get)
+ params = request_path_params("/people/5", :method => :get)
assert_equal("show", params[:action])
assert_equal("5", params[:id])
- params = set.recognize_path("/people/5", :method => :put)
+ params = request_path_params("/people/5", :method => :put)
assert_equal("update", params[:action])
- params = set.recognize_path("/people/5", :method => :patch)
+ params = request_path_params("/people/5", :method => :patch)
assert_equal("update", params[:action])
- params = set.recognize_path("/people/5.png", :method => :get)
+ params = request_path_params("/people/5.png", :method => :get)
assert_equal("show", params[:action])
assert_equal("5", params[:id])
assert_equal("png", params[:format])
@@ -1233,7 +1255,7 @@ class RouteSetTest < ActiveSupport::TestCase
def test_root_map
set.draw { root :to => 'people#index' }
- params = set.recognize_path("", :method => :get)
+ params = request_path_params("", :method => :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
end
@@ -1247,7 +1269,7 @@ class RouteSetTest < ActiveSupport::TestCase
end
- params = set.recognize_path("/api/inventory", :method => :get)
+ params = request_path_params("/api/inventory", :method => :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
@@ -1259,7 +1281,7 @@ class RouteSetTest < ActiveSupport::TestCase
end
end
- params = set.recognize_path("/api", :method => :get)
+ params = request_path_params("/api", :method => :get)
assert_equal("api/products", params[:controller])
assert_equal("index", params[:action])
end
@@ -1271,7 +1293,7 @@ class RouteSetTest < ActiveSupport::TestCase
end
end
- params = set.recognize_path("/prefix/inventory", :method => :get)
+ params = request_path_params("/prefix/inventory", :method => :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
@@ -1283,38 +1305,36 @@ class RouteSetTest < ActiveSupport::TestCase
end
end
- params = set.recognize_path("/inventory", :method => :get)
+ params = request_path_params("/inventory", :method => :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
- def test_generate_changes_controller_module
- set.draw { get ':controller/:action/:id' }
- current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
-
- assert_equal "/foo/bar/baz/7",
- url_for(set, { :controller => "foo/bar", :action => "baz", :id => 7 }, current)
- end
-
def test_id_is_sticky_when_it_ought_to_be
+ @set = make_set false
+
set.draw do
get ':controller/:id/:action'
end
- url = url_for(set, { :action => "destroy" }, { :controller => "people", :action => "show", :id => "7" })
- assert_equal "/people/7/destroy", url
+ get URI('http://test.host/people/7/show')
+
+ assert_equal "/people/7/destroy", controller.url_for(:action => 'destroy', :only_path => true)
end
def test_use_static_path_when_possible
+ @set = make_set false
+
set.draw do
get 'about' => "welcome#about"
get ':controller/:action/:id'
end
- url = url_for(set, { :controller => "welcome", :action => "about" },
- { :controller => "welcome", :action => "get", :id => "7" })
+ get URI('http://test.host/welcom/get/7')
- assert_equal "/about", url
+ assert_equal "/about", controller.url_for(:controller => 'welcome',
+ :action => 'about',
+ :only_path => true)
end
def test_generate
@@ -1349,38 +1369,51 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_named_routes_are_never_relative_to_modules
+ @set = make_set false
+
set.draw do
get "/connection/manage(/:action)" => 'connection/manage#index'
get "/connection/connection" => "connection/connection#index"
get '/connection' => 'connection#index', :as => 'family_connection'
end
- url = url_for(set, { :controller => "connection" }, { :controller => 'connection/manage' })
+ assert_equal({ :controller => 'connection/manage',
+ :action => 'index', }, request_path_params('/connection/manage'))
+
+ url = controller.url_for({ :controller => "connection", :only_path => true })
assert_equal "/connection/connection", url
- url = url_for(set, { :use_route => :family_connection, :controller => "connection" }, { :controller => 'connection/manage' })
+ url = controller.url_for({ :use_route => :family_connection,
+ :controller => "connection", :only_path => true })
assert_equal "/connection", url
end
def test_action_left_off_when_id_is_recalled
+ @set = make_set false
+
set.draw do
get ':controller(/:action(/:id))'
end
- assert_equal '/books', url_for(set,
- {:controller => 'books', :action => 'index'},
- {:controller => 'books', :action => 'show', :id => '10'}
- )
+
+ get URI('http://test.host/books/show/10')
+
+ assert_equal '/books', controller.url_for(:controller => 'books',
+ :only_path => true,
+ :action => 'index')
end
def test_query_params_will_be_shown_when_recalled
+ @set = make_set false
+
set.draw do
get 'show_weblog/:parameter' => 'weblog#show'
get ':controller(/:action(/:id))'
end
- assert_equal '/weblog/edit?parameter=1', url_for(set,
- {:action => 'edit', :parameter => 1},
- {:controller => 'weblog', :action => 'show', :parameter => 1}
- )
+
+ get URI('http://test.host/weblog/show/1')
+
+ assert_equal '/weblog/edit?parameter=1', controller.url_for(
+ {:action => 'edit', :parameter => 1, :only_path => true})
end
def test_format_is_not_inherit
@@ -1388,22 +1421,30 @@ class RouteSetTest < ActiveSupport::TestCase
get '/posts(.:format)' => 'posts#index'
end
- assert_equal '/posts', url_for(set,
- {:controller => 'posts'},
- {:controller => 'posts', :action => 'index', :format => 'xml'}
- )
+ get URI('http://test.host/posts.xml')
+ assert_equal({:controller => 'posts', :action => 'index', :format => 'xml'},
+ controller.request.path_parameters)
+
+ assert_equal '/posts', controller.url_for(
+ {:controller => 'posts', :only_path => true})
- assert_equal '/posts.xml', url_for(set,
- {:controller => 'posts', :format => 'xml'},
- {:controller => 'posts', :action => 'index', :format => 'xml'}
- )
+ assert_equal '/posts.xml', controller.url_for(
+ {:controller => 'posts', :format => 'xml', :only_path => true})
end
def test_expiry_determination_should_consider_values_with_to_param
+ @set = make_set false
+
set.draw { get 'projects/:project_id/:controller/:action' }
- assert_equal '/projects/1/weblog/show', url_for(set,
- { :action => 'show', :project_id => 1 },
- { :controller => 'weblog', :action => 'show', :project_id => '1' })
+
+ get URI('http://test.host/projects/1/weblog/show')
+
+ assert_equal(
+ { :controller => 'weblog', :action => 'show', :project_id => '1' },
+ controller.request.path_parameters)
+
+ assert_equal '/projects/1/weblog/show',
+ controller.url_for({ :action => 'show', :project_id => 1, :only_path => true })
end
def test_named_route_in_nested_resource
@@ -1606,7 +1647,6 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_slashes_are_implied
- @set = nil
set.draw { get("/:controller(/:action(/:id))") }
assert_equal '/content', url_for(set, { :controller => 'content', :action => 'index' })
@@ -1704,7 +1744,43 @@ class RouteSetTest < ActiveSupport::TestCase
assert_equal '/ibocorp', url_for(set, { :controller => 'ibocorp', :action => "show", :page => 1 })
end
+ include ActionDispatch::RoutingVerbs
+
+ class TestSet < ROUTING::RouteSet
+ def initialize(block)
+ @block = block
+ super()
+ end
+
+ class Dispatcher < ROUTING::RouteSet::Dispatcher
+ def initialize(defaults, set, block)
+ super(defaults)
+ @block = block
+ @set = set
+ end
+
+ def controller_reference(controller_param)
+ block = @block
+ set = @set
+ Class.new(ActionController::Base) {
+ include set.url_helpers
+ define_method(:process) { |name| block.call(self) }
+ def to_a; [200, {}, []]; end
+ }
+ end
+ end
+
+ def dispatcher defaults
+ TestSet::Dispatcher.new defaults, self, @block
+ end
+ end
+
+ alias :routes :set
+
def test_generate_with_optional_params_recalls_last_request
+ controller = nil
+ @set = TestSet.new ->(c) { controller = c }
+
set.draw do
get "blog/", :controller => "blog", :action => "index"
@@ -1719,23 +1795,29 @@ class RouteSetTest < ActiveSupport::TestCase
get "*anything", :controller => "blog", :action => "unknown_request"
end
- assert_equal({:controller => "blog", :action => "index"}, set.recognize_path("/blog"))
- assert_equal({:controller => "blog", :action => "show", :id => "123"}, set.recognize_path("/blog/show/123"))
- assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :day => nil, :month => nil }, set.recognize_path("/blog/2004"))
- assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => nil }, set.recognize_path("/blog/2004/12"))
- assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => "25"}, set.recognize_path("/blog/2004/12/25"))
- assert_equal({:controller => "articles", :action => "edit", :id => "123"}, set.recognize_path("/blog/articles/edit/123"))
- assert_equal({:controller => "articles", :action => "show_stats"}, set.recognize_path("/blog/articles/show_stats"))
- assert_equal({:controller => "blog", :action => "unknown_request", :anything => "blog/wibble"}, set.recognize_path("/blog/wibble"))
- assert_equal({:controller => "blog", :action => "unknown_request", :anything => "junk"}, set.recognize_path("/junk"))
+ recognize_path = ->(path) {
+ get(URI("http://example.org" + path))
+ controller.request.path_parameters
+ }
+
+ assert_equal({:controller => "blog", :action => "index"}, recognize_path.("/blog"))
+ assert_equal({:controller => "blog", :action => "show", :id => "123"}, recognize_path.("/blog/show/123"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :day => nil, :month => nil }, recognize_path.("/blog/2004"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => nil }, recognize_path.("/blog/2004/12"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => "25"}, recognize_path.("/blog/2004/12/25"))
+ assert_equal({:controller => "articles", :action => "edit", :id => "123"}, recognize_path.("/blog/articles/edit/123"))
+ assert_equal({:controller => "articles", :action => "show_stats"}, recognize_path.("/blog/articles/show_stats"))
+ assert_equal({:controller => "blog", :action => "unknown_request", :anything => "blog/wibble"}, recognize_path.("/blog/wibble"))
+ assert_equal({:controller => "blog", :action => "unknown_request", :anything => "junk"}, recognize_path.("/junk"))
+
+ get URI('http://example.org/blog/2006/07/28')
- last_request = set.recognize_path("/blog/2006/07/28").freeze
- assert_equal({:controller => "blog", :action => "show_date", :year => "2006", :month => "07", :day => "28"}, last_request)
- assert_equal("/blog/2006/07/25", url_for(set, { :day => 25 }, last_request))
- assert_equal("/blog/2005", url_for(set, { :year => 2005 }, last_request))
- assert_equal("/blog/show/123", url_for(set, { :action => "show" , :id => 123 }, last_request))
- assert_equal("/blog/2006", url_for(set, { :year => 2006 }, last_request))
- assert_equal("/blog/2006", url_for(set, { :year => 2006, :month => nil }, last_request))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2006", :month => "07", :day => "28"}, controller.request.path_parameters)
+ assert_equal("/blog/2006/07/25", controller.url_for({ :day => 25, :only_path => true }))
+ assert_equal("/blog/2005", controller.url_for({ :year => 2005, :only_path => true }))
+ assert_equal("/blog/show/123", controller.url_for({ :action => "show" , :id => 123, :only_path => true }))
+ assert_equal("/blog/2006", controller.url_for({ :year => 2006, :only_path => true }))
+ assert_equal("/blog/2006", controller.url_for({ :year => 2006, :month => nil, :only_path => true }))
end
private
@@ -1808,6 +1890,9 @@ class RackMountIntegrationTests < ActiveSupport::TestCase
root :to => "news#index"
}
+ attr_reader :routes
+ attr_reader :controller
+
def setup
@routes = ActionDispatch::Routing::RouteSet.new
@routes.draw(&Mapping)
diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb
index 1141feeff7..3b3b15c061 100644
--- a/actionpack/test/controller/test_case_test.rb
+++ b/actionpack/test/controller/test_case_test.rb
@@ -737,12 +737,12 @@ XML
assert_equal "baz", @request.filtered_parameters[:foo]
end
- def test_symbolized_path_params_reset_after_request
+ def test_path_params_reset_after_request
get :test_params, :id => "foo"
- assert_equal "foo", @request.symbolized_path_parameters[:id]
+ assert_equal "foo", @request.path_parameters[:id]
@request.recycle!
get :test_params
- assert_nil @request.symbolized_path_parameters[:id]
+ assert_nil @request.path_parameters[:id]
end
def test_request_protocol_is_reset_after_request
diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb
index 6c2311e7a5..24a09222b1 100644
--- a/actionpack/test/controller/url_for_integration_test.rb
+++ b/actionpack/test/controller/url_for_integration_test.rb
@@ -6,6 +6,7 @@ require 'active_support/core_ext/object/with_options'
module ActionPack
class URLForIntegrationTest < ActiveSupport::TestCase
include RoutingTestHelpers
+ include ActionDispatch::RoutingVerbs
Model = Struct.new(:to_param)
@@ -61,8 +62,11 @@ module ActionPack
root :to => "news#index"
}
+ attr_reader :routes
+ attr_accessor :controller
+
def setup
- @routes = ActionDispatch::Routing::RouteSet.new
+ @routes = make_set false
@routes.draw(&Mapping)
end
@@ -70,9 +74,9 @@ module ActionPack
['/admin/users',[ { :use_route => 'admin_users' }]],
['/admin/users',[ { :controller => 'admin/users' }]],
['/admin/users',[ { :controller => 'admin/users', :action => 'index' }]],
- ['/admin/users',[ { :action => 'index' }, { :controller => 'admin/users' }]],
- ['/admin/users',[ { :controller => 'users', :action => 'index' }, { :controller => 'admin/accounts' }]],
- ['/people',[ { :controller => '/people', :action => 'index' }, { :controller => 'admin/accounts' }]],
+ ['/admin/users',[ { :action => 'index' }, { :controller => 'admin/users', :action => 'index' }, '/admin/users']],
+ ['/admin/users',[ { :controller => 'users', :action => 'index' }, { :controller => 'admin/accounts', :action => 'show', :id => '1' }, '/admin/accounts/show/1']],
+ ['/people',[ { :controller => '/people', :action => 'index' }, {:controller=>"admin/accounts", :action=>"foo", :id=>"bar"}, '/admin/accounts/foo/bar']],
['/admin/posts',[ { :controller => 'admin/posts' }]],
['/admin/posts/new',[ { :controller => 'admin/posts', :action => 'new' }]],
@@ -86,11 +90,11 @@ module ActionPack
['/archive?year=january',[ { :controller => 'archive', :action => 'index', :year => 'january' }]],
['/people',[ { :controller => 'people', :action => 'index' }]],
- ['/people',[ { :action => 'index' }, { :controller => 'people' }]],
- ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/people',[ {}, { :controller => 'people', :action => 'index' }]],
- ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'show', :id => '1' }]],
+ ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'index' }, '/people']],
+ ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
+ ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
+ ['/people',[ {}, { :controller => 'people', :action => 'index' }, '/people']],
+ ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
['/people/new',[ { :use_route => 'new_person' }]],
['/people/new',[ { :controller => 'people', :action => 'new' }]],
['/people/1',[ { :use_route => 'person', :id => '1' }]],
@@ -98,11 +102,11 @@ module ActionPack
['/people/1.xml',[ { :controller => 'people', :action => 'show', :id => '1', :format => 'xml' }]],
['/people/1',[ { :controller => 'people', :action => 'show', :id => 1 }]],
['/people/1',[ { :controller => 'people', :action => 'show', :id => Model.new('1') }]],
- ['/people/1',[ { :action => 'show', :id => '1' }, { :controller => 'people', :action => 'index' }]],
- ['/people/1',[ { :action => 'show', :id => 1 }, { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/people/1',[ {}, { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'index', :id => '1' }]],
+ ['/people/1',[ { :action => 'show', :id => '1' }, { :controller => 'people', :action => 'index' }, '/people']],
+ ['/people/1',[ { :action => 'show', :id => 1 }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
+ ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
+ ['/people/1',[ {}, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']],
+ ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'index', :id => '1' }, '/people/index/1']],
['/people/1/edit',[ { :controller => 'people', :action => 'edit', :id => '1' }]],
['/people/1/edit.xml',[ { :controller => 'people', :action => 'edit', :id => '1', :format => 'xml' }]],
['/people/1/edit',[ { :use_route => 'edit_person', :id => '1' }]],
@@ -118,16 +122,15 @@ module ActionPack
['/project',[ { :controller => 'project', :action => 'index' }]],
['/projects/1',[ { :controller => 'project', :action => 'index', :project_id => '1' }]],
- ['/projects/1',[ { :controller => 'project', :action => 'index'}, {:project_id => '1' }]],
+ ['/projects/1',[ { :controller => 'project', :action => 'index'}, {:project_id => '1', :controller => 'project', :action => 'index' }, '/projects/1']],
['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index', :project_id => '1' }]],
- ['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index' }, { :project_id => '1' }]],
+ ['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index' }, { :controller => 'project', :action => 'index', :project_id => '1' }, '/projects/1']],
['/clients',[ { :controller => 'projects', :action => 'index' }]],
['/clients?project_id=1',[ { :controller => 'projects', :action => 'index', :project_id => '1' }]],
- ['/clients',[ { :controller => 'projects', :action => 'index' }, { :project_id => '1' }]],
- ['/clients',[ { :action => 'index' }, { :controller => 'projects', :action => 'index', :project_id => '1' }]],
+ ['/clients',[ { :controller => 'projects', :action => 'index' }, { :project_id => '1', :controller => 'project', :action => 'index' }, '/projects/1']],
- ['/comment/20',[ { :id => 20 }, { :controller => 'comments', :action => 'show' }]],
+ ['/comment/20',[ { :id => 20 }, { :controller => 'comments', :action => 'show' }, '/comments/show']],
['/comment/20',[ { :controller => 'comments', :id => 20, :action => 'show' }]],
['/comments/boo',[ { :controller => 'comments', :action => 'boo' }]],
@@ -144,24 +147,21 @@ module ActionPack
['/notes',[ { :page_id => nil, :controller => 'notes' }]],
['/notes',[ { :controller => 'notes' }]],
['/notes/print',[ { :controller => 'notes', :action => 'print' }]],
- ['/notes/print',[ {}, { :controller => 'notes', :action => 'print' }]],
-
- ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1' }]],
- ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1', :foo => 'bar' }]],
- ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1' }]],
- ['/notes/index/1',[ { :action => 'index' }, { :controller => 'notes', :id => '1' }]],
- ['/notes/index/1',[ {}, { :controller => 'notes', :id => '1' }]],
- ['/notes/show/1',[ {}, { :controller => 'notes', :action => 'show', :id => '1' }]],
- ['/notes/index/1',[ { :controller => 'notes', :id => '1' }, { :foo => 'bar' }]],
- ['/posts',[ { :controller => 'posts' }, { :controller => 'notes', :action => 'show', :id => '1' }]],
- ['/notes/list',[ { :action => 'list' }, { :controller => 'notes', :action => 'show', :id => '1' }]],
+ ['/notes/print',[ {}, { :controller => 'notes', :action => 'print' }, '/notes/print']],
+
+ ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :action => 'index', :id => '1' }, '/notes/index/1']],
+ ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']],
+ ['/notes/index/1',[ { :action => 'index' }, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']],
+ ['/notes/index/1',[ {}, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']],
+ ['/notes/show/1',[ {}, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']],
+ ['/posts',[ { :controller => 'posts' }, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']],
+ ['/notes/list',[ { :action => 'list' }, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']],
['/posts/ping',[ { :controller => 'posts', :action => 'ping' }]],
['/posts/show/1',[ { :controller => 'posts', :action => 'show', :id => '1' }]],
['/posts',[ { :controller => 'posts' }]],
['/posts',[ { :controller => 'posts', :action => 'index' }]],
- ['/posts',[ { :controller => 'posts' }, { :controller => 'posts', :action => 'index' }]],
- ['/posts/create',[ { :action => 'create' }, { :controller => 'posts' }]],
+ ['/posts/create',[ { :action => 'create' }, {:day=>nil, :month=>nil, :controller=>"posts", :action=>"show_date"}, '/blog']],
['/posts?foo=bar',[ { :controller => 'posts', :foo => 'bar' }]],
['/posts?foo%5B%5D=bar&foo%5B%5D=baz', [{ :controller => 'posts', :foo => ['bar', 'baz'] }]],
['/posts?page=2', [{ :controller => 'posts', :page => 2 }]],
@@ -169,9 +169,20 @@ module ActionPack
['/news.rss', [{ :controller => 'news', :action => 'index', :format => 'rss' }]],
].each_with_index do |(url, params), i|
- define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do
- assert_equal url, url_for(@routes, *params), params.inspect
- end
+ if params.length > 1
+ hash, path_params, route = *params
+ hash[:only_path] = true
+
+ define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do
+ get URI('http://test.host' + route.to_s)
+ assert_equal path_params, controller.request.path_parameters
+ assert_equal url, controller.url_for(hash), params.inspect
+ end
+ else
+ define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do
+ assert_equal url, url_for(@routes, params.first), params.inspect
+ end
+ end
end
end
end
diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb
index 7210c68e73..9f086af664 100644
--- a/actionpack/test/controller/url_for_test.rb
+++ b/actionpack/test/controller/url_for_test.rb
@@ -287,12 +287,12 @@ module AbstractController
# We need to create a new class in order to install the new named route.
kls = Class.new { include set.url_helpers }
controller = kls.new
- assert controller.respond_to?(:home_url)
+ assert_respond_to controller, :home_url
assert_equal '/brave/new/world',
- controller.send(:url_for, :controller => 'brave', :action => 'new', :id => 'world', :only_path => true)
+ controller.url_for(:controller => 'brave', :action => 'new', :id => 'world', :only_path => true)
- assert_equal("/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'unused', :only_path => true))
- assert_equal("/home/sweet/home/alabama", controller.send(:home_path, 'alabama'))
+ assert_equal("/home/sweet/home/alabama", controller.home_path(:user => 'alabama', :host => 'unused', :only_path => true))
+ assert_equal("/home/sweet/home/alabama", controller.home_path('alabama'))
end
end
diff --git a/actionpack/test/dispatch/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb
index d8d3209dac..3e554a9cf6 100644
--- a/actionpack/test/dispatch/mapper_test.rb
+++ b/actionpack/test/dispatch/mapper_test.rb
@@ -3,7 +3,7 @@ require 'abstract_unit'
module ActionDispatch
module Routing
class MapperTest < ActiveSupport::TestCase
- class FakeSet
+ class FakeSet < ActionDispatch::Routing::RouteSet
attr_reader :routes
alias :set :routes
@@ -38,7 +38,7 @@ module ActionDispatch
def test_mapping_requirements
options = { :controller => 'foo', :action => 'bar', :via => :get }
- m = Mapper::Mapping.build({}, '/store/:name(*rest)', options)
+ m = Mapper::Mapping.build({}, FakeSet.new, '/store/:name(*rest)', options)
_, _, requirements, _ = m.to_route
assert_equal(/.+?/, requirements[:rest])
end
diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb
index bd3f6274de..d5a4d8ee11 100644
--- a/actionpack/test/dispatch/mount_test.rb
+++ b/actionpack/test/dispatch/mount_test.rb
@@ -1,12 +1,18 @@
require 'abstract_unit'
+require 'rails/engine'
class TestRoutingMount < ActionDispatch::IntegrationTest
Router = ActionDispatch::Routing::RouteSet.new
- class FakeEngine
+ class AppWithRoutes < Rails::Engine
def self.routes
@routes ||= ActionDispatch::Routing::RouteSet.new
end
+ end
+
+ # Test for mounting apps that respond to routes, but aren't Rails-like apps.
+ class SinatraLikeApp
+ def self.routes; Object.new; end
def self.call(env)
[200, {"Content-Type" => "text/html"}, ["OK"]]
@@ -21,22 +27,23 @@ class TestRoutingMount < ActionDispatch::IntegrationTest
mount SprocketsApp, :at => "/sprockets"
mount SprocketsApp => "/shorthand"
- mount FakeEngine, :at => "/fakeengine", :as => :fake
- mount FakeEngine, :at => "/getfake", :via => :get
+ mount SinatraLikeApp, :at => "/fakeengine", :as => :fake
+ mount SinatraLikeApp, :at => "/getfake", :via => :get
scope "/its_a" do
mount SprocketsApp, :at => "/sprocket"
end
resources :users do
- mount FakeEngine, :at => "/fakeengine", :as => :fake_mounted_at_resource
+ mount AppWithRoutes, :at => "/fakeengine", :as => :fake_mounted_at_resource
end
mount SprocketsApp, :at => "/", :via => :get
end
+ APP = RoutedRackApp.new Router
def app
- Router
+ APP
end
def test_app_name_is_properly_generated_when_engine_is_mounted_in_resources
diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb
index cd31e8e326..c6e4eefa7a 100644
--- a/actionpack/test/dispatch/prefix_generation_test.rb
+++ b/actionpack/test/dispatch/prefix_generation_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'rack/test'
+require 'rails/engine'
module TestGenerationPrefix
class Post
@@ -23,7 +24,7 @@ module TestGenerationPrefix
class WithMountedEngine < ActionDispatch::IntegrationTest
include Rack::Test::Methods
- class BlogEngine
+ class BlogEngine < Rails::Engine
def self.routes
@routes ||= begin
routes = ActionDispatch::Routing::RouteSet.new
diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
index 2db3fee6bb..926472163e 100644
--- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
@@ -8,7 +8,11 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
end
def parse
- self.class.last_request_parameters = request.request_parameters
+ self.class.last_request_parameters = begin
+ request.request_parameters
+ rescue EOFError
+ {}
+ end
self.class.last_parameters = request.parameters
head :ok
end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index e4950a5d6b..1ef2b062dd 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -798,6 +798,12 @@ class RequestFormat < BaseRequestTest
assert_not request.format.json?
end
+ test "format does not throw exceptions when malformed parameters" do
+ request = stub_request("QUERY_STRING" => "x[y]=1&x[y][][w]=2")
+ assert request.formats
+ assert request.format.html?
+ end
+
test "formats with xhr request" do
request = stub_request 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
request.expects(:parameters).at_least_once.returns({})
@@ -893,15 +899,15 @@ class RequestParameters < BaseRequestTest
assert_equal({"bar" => 2}, request.query_parameters)
end
- test "parameters still accessible after rack parse error" do
+ test "parameters not accessible after rack parse error" do
request = stub_request("QUERY_STRING" => "x[y]=1&x[y][][w]=2")
- assert_raises(ActionController::BadRequest) do
- # rack will raise a TypeError when parsing this query string
- request.parameters
+ 2.times do
+ assert_raises(ActionController::BadRequest) do
+ # rack will raise a TypeError when parsing this query string
+ request.parameters
+ end
end
-
- assert_equal({}, request.parameters)
end
test "we have access to the original exception" do
@@ -1066,7 +1072,7 @@ class RequestEtag < BaseRequestTest
end
end
-class RequestVarient < BaseRequestTest
+class RequestVariant < BaseRequestTest
test "setting variant" do
request = stub_request
diff --git a/actionpack/test/dispatch/routing/concerns_test.rb b/actionpack/test/dispatch/routing/concerns_test.rb
index 9f37701656..7ef513b0c8 100644
--- a/actionpack/test/dispatch/routing/concerns_test.rb
+++ b/actionpack/test/dispatch/routing/concerns_test.rb
@@ -36,7 +36,8 @@ class RoutingConcernsTest < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = RoutedRackApp.new Routes
+ def app; APP end
def test_accessing_concern_from_resources
get "/posts/1/comments"
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 778dbfc74d..269c7b4159 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -2022,6 +2022,28 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal '/blogs/1/posts/2/comments/new', new_blog_post_comment_path(:blog_id => 1, :post_id => 2)
end
+ def test_direct_children_of_shallow_resources
+ draw do
+ resources :blogs do
+ resources :posts, shallow: true do
+ resources :comments
+ end
+ end
+ end
+
+ post '/posts/1/comments'
+ assert_equal 'comments#create', @response.body
+ assert_equal '/posts/1/comments', post_comments_path('1')
+
+ get '/posts/2/comments/new'
+ assert_equal 'comments#new', @response.body
+ assert_equal '/posts/2/comments/new', new_post_comment_path('2')
+
+ get '/posts/1/comments'
+ assert_equal 'comments#index', @response.body
+ assert_equal '/posts/1/comments', post_comments_path('1')
+ end
+
def test_shallow_nested_resources_within_scope
draw do
scope '/hello' do
@@ -2831,7 +2853,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- def test_symbolized_path_parameters_is_not_stale
+ def test_path_parameters_is_not_stale
draw do
scope '/countries/:country', :constraints => lambda { |params, req| %w(all France).include?(params[:country]) } do
get '/', :to => 'countries#index'
@@ -3148,7 +3170,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get '/downloads/1/1.tar'
assert_equal 'downloads#show', @response.body
- assert_equal expected_params, @request.symbolized_path_parameters
+ assert_equal expected_params, @request.path_parameters
assert_equal '/downloads/1/1.tar', download_path('1')
assert_equal '/downloads/1/1.tar', download_path('1', '1')
end
@@ -3421,19 +3443,19 @@ private
def draw(&block)
self.class.stub_controllers do |routes|
- @app = routes
- @app.default_url_options = { host: 'www.example.com' }
- @app.draw(&block)
+ routes.default_url_options = { host: 'www.example.com' }
+ routes.draw(&block)
+ @app = RoutedRackApp.new routes
end
end
def url_for(options = {})
- @app.url_helpers.url_for(options)
+ @app.routes.url_helpers.url_for(options)
end
def method_missing(method, *args, &block)
if method.to_s =~ /_(path|url)$/
- @app.url_helpers.send(method, *args, &block)
+ @app.routes.url_helpers.send(method, *args, &block)
else
super
end
@@ -3501,8 +3523,10 @@ class TestAltApp < ActionDispatch::IntegrationTest
get "/" => TestAltApp::AltApp.new
end
+ APP = build_app AltRoutes
+
def app
- AltRoutes
+ APP
end
def test_alt_request_without_header
@@ -3529,15 +3553,16 @@ class TestAppendingRoutes < ActionDispatch::IntegrationTest
def setup
super
s = self
- @app = ActionDispatch::Routing::RouteSet.new
- @app.append do
+ routes = ActionDispatch::Routing::RouteSet.new
+ routes.append do
get '/hello' => s.simple_app('fail')
get '/goodbye' => s.simple_app('goodbye')
end
- @app.draw do
+ routes.draw do
get '/hello' => s.simple_app('hello')
end
+ @app = self.class.build_app routes
end
def test_goodbye_should_be_available
@@ -3566,8 +3591,9 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
end
def draw(&block)
- @app = ActionDispatch::Routing::RouteSet.new
- @app.draw(&block)
+ routes = ActionDispatch::Routing::RouteSet.new
+ routes.draw(&block)
+ @app = self.class.build_app routes
end
def test_missing_controller
@@ -3667,8 +3693,10 @@ class TestDefaultScope < ActionDispatch::IntegrationTest
resources :posts
end
+ APP = build_app DefaultScopeRoutes
+
def app
- DefaultScopeRoutes
+ APP
end
include DefaultScopeRoutes.url_helpers
@@ -3693,11 +3721,14 @@ class TestHttpMethods < ActionDispatch::IntegrationTest
lambda { |env| [ 200, { 'Content-Type' => 'text/plain' }, [response] ] }
end
- setup do
+ attr_reader :app
+
+ def setup
s = self
- @app = ActionDispatch::Routing::RouteSet.new
+ routes = ActionDispatch::Routing::RouteSet.new
+ @app = RoutedRackApp.new routes
- @app.draw do
+ routes.draw do
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789).each do |method|
match '/' => s.simple_app(method), :via => method.underscore.to_sym
end
@@ -3728,7 +3759,8 @@ class TestUriPathEscaping < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test 'escapes slash in generated path segment' do
assert_equal '/a%20b%2Fc+d', segment_path(:segment => 'a b/c+d')
@@ -3759,7 +3791,8 @@ class TestUnicodePaths < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test 'recognizes unicode path' do
get "/#{Rack::Utils.escape("ほげ")}"
@@ -3790,7 +3823,8 @@ class TestMultipleNestedController < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test "controller option which starts with '/' from multiple nested controller" do
get "/foo/bar/baz"
@@ -3809,7 +3843,8 @@ class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test 'recognizes tilde path' do
get "/~user"
@@ -3836,7 +3871,8 @@ class TestRedirectInterpolation < ActionDispatch::IntegrationTest
end
end
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test "redirect escapes interpolated parameters with redirect proc" do
get "/foo/1%3E"
@@ -3878,7 +3914,8 @@ class TestConstraintsAccessingParameters < ActionDispatch::IntegrationTest
end
end
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test "parameters are reset between constraint checks" do
get "/bar"
@@ -3898,7 +3935,8 @@ class TestGlobRoutingMapper < ActionDispatch::IntegrationTest
end
#include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
def test_glob_constraint
get "/dummy"
@@ -3930,7 +3968,8 @@ class TestOptimizedNamedRoutes < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test 'enabled when not mounted and default_url_options is empty' do
assert Routes.url_helpers.optimize_routes_generation?
@@ -4002,7 +4041,8 @@ class TestNamedRouteUrlHelpers < ActionDispatch::IntegrationTest
end
end
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
include Routes.url_helpers
@@ -4037,7 +4077,8 @@ class TestUrlConstraints < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
test "constraints are copied to defaults when using constraints method" do
assert_equal 'http://admin.example.com/', admin_root_url
@@ -4118,8 +4159,9 @@ class TestOptionalRootSegments < ActionDispatch::IntegrationTest
end
end
+ APP = build_app Routes
def app
- Routes
+ APP
end
include Routes.url_helpers
@@ -4150,7 +4192,8 @@ class TestPortConstraints < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
def test_integer_port_constraints
get 'http://www.example.com/integer'
@@ -4198,7 +4241,8 @@ class TestFormatConstraints < ActionDispatch::IntegrationTest
end
include Routes.url_helpers
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
def test_string_format_constraints
get 'http://www.example.com/string'
@@ -4267,8 +4311,9 @@ class TestRouteDefaults < ActionDispatch::IntegrationTest
end
end
+ APP = build_app Routes
def app
- Routes
+ APP
end
include Routes.url_helpers
@@ -4296,8 +4341,9 @@ class TestRackAppRouteGeneration < ActionDispatch::IntegrationTest
end
end
+ APP = build_app Routes
def app
- Routes
+ APP
end
include Routes.url_helpers
@@ -4322,8 +4368,9 @@ class TestRedirectRouteGeneration < ActionDispatch::IntegrationTest
end
end
+ APP = build_app Routes
def app
- Routes
+ APP
end
include Routes.url_helpers
@@ -4346,7 +4393,8 @@ class TestUrlGenerationErrors < ActionDispatch::IntegrationTest
end
end
- def app; Routes end
+ APP = build_app Routes
+ def app; APP end
include Routes.url_helpers
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index 38bd234f37..323fbc285e 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -37,7 +37,7 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
get "/", {}, {'action_dispatch.show_exceptions' => true}
assert_response 500
assert_equal "500 error fixture\n", body
-
+
get "/bad_params", {}, {'action_dispatch.show_exceptions' => true}
assert_response 400
assert_equal "400 error fixture\n", body
@@ -92,6 +92,7 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
exceptions_app = lambda do |env|
assert_kind_of AbstractController::ActionNotFound, env["action_dispatch.exception"]
assert_equal "/404", env["PATH_INFO"]
+ assert_equal "/not_found_original_exception", env["action_dispatch.original_path"]
[404, { "Content-Type" => "text/plain" }, ["YOU FAILED BRO"]]
end
diff --git a/actionpack/test/dispatch/uploaded_file_test.rb b/actionpack/test/dispatch/uploaded_file_test.rb
index 9f6381f118..55ebbd5143 100644
--- a/actionpack/test/dispatch/uploaded_file_test.rb
+++ b/actionpack/test/dispatch/uploaded_file_test.rb
@@ -18,6 +18,12 @@ module ActionDispatch
assert_equal "UTF-8", uf.original_filename.encoding.to_s
end
+ def test_filename_should_always_be_in_utf_8
+ uf = Http::UploadedFile.new(:filename => 'foo'.encode(Encoding::SHIFT_JIS),
+ :tempfile => Object.new)
+ assert_equal "UTF-8", uf.original_filename.encoding.to_s
+ end
+
def test_content_type
uf = Http::UploadedFile.new(:type => 'foo', :tempfile => Object.new)
assert_equal 'foo', uf.content_type
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index a4dfd0a63d..8f79e7bf9a 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -20,12 +20,14 @@ module TestUrlGeneration
mount MyRouteGeneratingController.action(:index), at: '/bar'
end
+ APP = build_app Routes
+
def _routes
Routes
end
def app
- Routes
+ APP
end
test "generating URLS normally" do
diff --git a/actionpack/test/fixtures/test/_changing_priority.html.erb b/actionpack/test/fixtures/test/_changing_priority.html.erb
deleted file mode 100644
index 3225efc49a..0000000000
--- a/actionpack/test/fixtures/test/_changing_priority.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-HTML \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_changing_priority.json.erb b/actionpack/test/fixtures/test/_changing_priority.json.erb
deleted file mode 100644
index 7fa41dce66..0000000000
--- a/actionpack/test/fixtures/test/_changing_priority.json.erb
+++ /dev/null
@@ -1 +0,0 @@
-JSON \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_counter.html.erb b/actionpack/test/fixtures/test/_counter.html.erb
deleted file mode 100644
index fd245bfc70..0000000000
--- a/actionpack/test/fixtures/test/_counter.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= counter_counter %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_customer.erb b/actionpack/test/fixtures/test/_customer.erb
deleted file mode 100644
index d8220afeda..0000000000
--- a/actionpack/test/fixtures/test/_customer.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello: <%= customer.name rescue "Anonymous" %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_customer_counter.erb b/actionpack/test/fixtures/test/_customer_counter.erb
deleted file mode 100644
index 3435979dba..0000000000
--- a/actionpack/test/fixtures/test/_customer_counter.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= customer_counter.name %><%= customer_counter_counter %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_customer_counter_with_as.erb b/actionpack/test/fixtures/test/_customer_counter_with_as.erb
deleted file mode 100644
index 1241eb604d..0000000000
--- a/actionpack/test/fixtures/test/_customer_counter_with_as.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= client.name %><%= client_counter %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_customer_greeting.erb b/actionpack/test/fixtures/test/_customer_greeting.erb
deleted file mode 100644
index 6acbcb20c4..0000000000
--- a/actionpack/test/fixtures/test/_customer_greeting.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= greeting %>: <%= customer_greeting.name %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_customer_with_var.erb b/actionpack/test/fixtures/test/_customer_with_var.erb
deleted file mode 100644
index 00047dd20e..0000000000
--- a/actionpack/test/fixtures/test/_customer_with_var.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= customer.name %> <%= customer.name %> <%= customer.name %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb b/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb
deleted file mode 100644
index 1cc8d41475..0000000000
--- a/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello <%= name %>
diff --git a/actionpack/test/fixtures/test/_first_json_partial.json.erb b/actionpack/test/fixtures/test/_first_json_partial.json.erb
deleted file mode 100644
index 790ee896db..0000000000
--- a/actionpack/test/fixtures/test/_first_json_partial.json.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render :partial => "test/second_json_partial" %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_form.erb b/actionpack/test/fixtures/test/_form.erb
deleted file mode 100644
index 01107f1cb2..0000000000
--- a/actionpack/test/fixtures/test/_form.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= form.label :title %>
diff --git a/actionpack/test/fixtures/test/_hash_greeting.erb b/actionpack/test/fixtures/test/_hash_greeting.erb
deleted file mode 100644
index fc54a36f2a..0000000000
--- a/actionpack/test/fixtures/test/_hash_greeting.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= greeting %>: <%= hash_greeting[:first_name] %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_hash_object.erb b/actionpack/test/fixtures/test/_hash_object.erb
deleted file mode 100644
index 34a92c6a56..0000000000
--- a/actionpack/test/fixtures/test/_hash_object.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= hash_object[:first_name] %>
-<%= hash_object[:first_name].reverse %>
diff --git a/actionpack/test/fixtures/test/_hello.builder b/actionpack/test/fixtures/test/_hello.builder
deleted file mode 100644
index ef52f632d1..0000000000
--- a/actionpack/test/fixtures/test/_hello.builder
+++ /dev/null
@@ -1 +0,0 @@
-xm.hello \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_json_change_priority.json.erb b/actionpack/test/fixtures/test/_json_change_priority.json.erb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/actionpack/test/fixtures/test/_json_change_priority.json.erb
+++ /dev/null
diff --git a/actionpack/test/fixtures/test/_labelling_form.erb b/actionpack/test/fixtures/test/_labelling_form.erb
deleted file mode 100644
index 1b95763165..0000000000
--- a/actionpack/test/fixtures/test/_labelling_form.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= labelling_form.label :title %>
diff --git a/actionpack/test/fixtures/test/_layout_for_partial.html.erb b/actionpack/test/fixtures/test/_layout_for_partial.html.erb
deleted file mode 100644
index 666efadbb6..0000000000
--- a/actionpack/test/fixtures/test/_layout_for_partial.html.erb
+++ /dev/null
@@ -1,3 +0,0 @@
-Before (<%= name %>)
-<%= yield %>
-After \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_partial_for_use_in_layout.html.erb b/actionpack/test/fixtures/test/_partial_for_use_in_layout.html.erb
deleted file mode 100644
index 3a03a64e31..0000000000
--- a/actionpack/test/fixtures/test/_partial_for_use_in_layout.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-Inside from partial (<%= name %>) \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_partial_html_erb.html.erb b/actionpack/test/fixtures/test/_partial_html_erb.html.erb
deleted file mode 100644
index 4b54875782..0000000000
--- a/actionpack/test/fixtures/test/_partial_html_erb.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= "partial.html.erb" %>
diff --git a/actionpack/test/fixtures/test/_partial_name_local_variable.erb b/actionpack/test/fixtures/test/_partial_name_local_variable.erb
deleted file mode 100644
index cc3a91c89f..0000000000
--- a/actionpack/test/fixtures/test/_partial_name_local_variable.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= partial_name_local_variable %>
diff --git a/actionpack/test/fixtures/test/_partial_only.erb b/actionpack/test/fixtures/test/_partial_only.erb
deleted file mode 100644
index a44b3eed40..0000000000
--- a/actionpack/test/fixtures/test/_partial_only.erb
+++ /dev/null
@@ -1 +0,0 @@
-only partial \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_partial_only_html.html b/actionpack/test/fixtures/test/_partial_only_html.html
deleted file mode 100644
index d2d630bd40..0000000000
--- a/actionpack/test/fixtures/test/_partial_only_html.html
+++ /dev/null
@@ -1 +0,0 @@
-only html partial \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_partial_with_partial.erb b/actionpack/test/fixtures/test/_partial_with_partial.erb
deleted file mode 100644
index ee0d5037b6..0000000000
--- a/actionpack/test/fixtures/test/_partial_with_partial.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= render 'test/partial' %>
-partial with partial
diff --git a/actionpack/test/fixtures/test/_person.erb b/actionpack/test/fixtures/test/_person.erb
deleted file mode 100644
index b2e5688956..0000000000
--- a/actionpack/test/fixtures/test/_person.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-Second: <%= name %>
-Third: <%= @name %>
diff --git a/actionpack/test/fixtures/test/_raise_indentation.html.erb b/actionpack/test/fixtures/test/_raise_indentation.html.erb
deleted file mode 100644
index f9a93728fe..0000000000
--- a/actionpack/test/fixtures/test/_raise_indentation.html.erb
+++ /dev/null
@@ -1,13 +0,0 @@
-<p>First paragraph</p>
-<p>Second paragraph</p>
-<p>Third paragraph</p>
-<p>Fourth paragraph</p>
-<p>Fifth paragraph</p>
-<p>Sixth paragraph</p>
-<p>Seventh paragraph</p>
-<p>Eight paragraph</p>
-<p>Ninth paragraph</p>
-<p>Tenth paragraph</p>
-<%= raise "error here!" %>
-<p>Eleventh paragraph</p>
-<p>Twelfth paragraph</p> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/_second_json_partial.json.erb b/actionpack/test/fixtures/test/_second_json_partial.json.erb
deleted file mode 100644
index 5ebb7f1afd..0000000000
--- a/actionpack/test/fixtures/test/_second_json_partial.json.erb
+++ /dev/null
@@ -1 +0,0 @@
-Third level \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/action_talk_to_layout.erb b/actionpack/test/fixtures/test/action_talk_to_layout.erb
deleted file mode 100644
index 36e896daa8..0000000000
--- a/actionpack/test/fixtures/test/action_talk_to_layout.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<% @title = "Talking to the layout" -%>
-Action was here! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/calling_partial_with_layout.html.erb b/actionpack/test/fixtures/test/calling_partial_with_layout.html.erb
deleted file mode 100644
index ac44bc0d81..0000000000
--- a/actionpack/test/fixtures/test/calling_partial_with_layout.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render(:layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => { :name => "David" }) %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/capturing.erb b/actionpack/test/fixtures/test/capturing.erb
deleted file mode 100644
index 1addaa40d9..0000000000
--- a/actionpack/test/fixtures/test/capturing.erb
+++ /dev/null
@@ -1,4 +0,0 @@
-<% days = capture do %>
- Dreamy days
-<% end %>
-<%= days %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/change_priority.html.erb b/actionpack/test/fixtures/test/change_priority.html.erb
deleted file mode 100644
index 5618977d05..0000000000
--- a/actionpack/test/fixtures/test/change_priority.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= render :partial => "test/json_change_priority", formats: :json %>
-HTML Template, but <%= render :partial => "test/changing_priority" %> partial \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/content_for.erb b/actionpack/test/fixtures/test/content_for.erb
deleted file mode 100644
index 1fb829f54c..0000000000
--- a/actionpack/test/fixtures/test/content_for.erb
+++ /dev/null
@@ -1 +0,0 @@
-<% content_for :title do -%>Putting stuff in the title!<% end -%>Great stuff! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/content_for_concatenated.erb b/actionpack/test/fixtures/test/content_for_concatenated.erb
deleted file mode 100644
index e65f629574..0000000000
--- a/actionpack/test/fixtures/test/content_for_concatenated.erb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% content_for :title, "Putting stuff "
- content_for :title, "in the title!" -%>
-Great stuff! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/content_for_with_parameter.erb b/actionpack/test/fixtures/test/content_for_with_parameter.erb
deleted file mode 100644
index aeb6f73ce0..0000000000
--- a/actionpack/test/fixtures/test/content_for_with_parameter.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<% content_for :title, "Putting stuff in the title!" -%>
-Great stuff! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/formatted_html_erb.html.erb b/actionpack/test/fixtures/test/formatted_html_erb.html.erb
deleted file mode 100644
index 1c64efabd8..0000000000
--- a/actionpack/test/fixtures/test/formatted_html_erb.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-formatted html erb \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/greeting.html.erb b/actionpack/test/fixtures/test/greeting.html.erb
deleted file mode 100644
index 62fb0293f0..0000000000
--- a/actionpack/test/fixtures/test/greeting.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<p>This is grand!</p>
diff --git a/actionpack/test/fixtures/test/greeting.xml.erb b/actionpack/test/fixtures/test/greeting.xml.erb
deleted file mode 100644
index 62fb0293f0..0000000000
--- a/actionpack/test/fixtures/test/greeting.xml.erb
+++ /dev/null
@@ -1 +0,0 @@
-<p>This is grand!</p>
diff --git a/actionpack/test/fixtures/test/hello,world.erb b/actionpack/test/fixtures/test/hello,world.erb
deleted file mode 100644
index bc8fa5e0ca..0000000000
--- a/actionpack/test/fixtures/test/hello,world.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello w*rld! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/hello.builder b/actionpack/test/fixtures/test/hello.builder
deleted file mode 100644
index a471553941..0000000000
--- a/actionpack/test/fixtures/test/hello.builder
+++ /dev/null
@@ -1,4 +0,0 @@
-xml.html do
- xml.p "Hello #{@name}"
- xml << render(:file => "test/greeting")
-end \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/hello_world_container.builder b/actionpack/test/fixtures/test/hello_world_container.builder
deleted file mode 100644
index e48d75c405..0000000000
--- a/actionpack/test/fixtures/test/hello_world_container.builder
+++ /dev/null
@@ -1,3 +0,0 @@
-xml.test do
- render :partial => 'hello', :locals => { :xm => xml }
-end \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/hello_world_from_rxml.builder b/actionpack/test/fixtures/test/hello_world_from_rxml.builder
deleted file mode 100644
index 619a97ba96..0000000000
--- a/actionpack/test/fixtures/test/hello_world_from_rxml.builder
+++ /dev/null
@@ -1,3 +0,0 @@
-xml.html do
- xml.p "Hello"
-end
diff --git a/actionpack/test/fixtures/test/hello_world_with_layout_false.erb b/actionpack/test/fixtures/test/hello_world_with_layout_false.erb
deleted file mode 100644
index 6769dd60bd..0000000000
--- a/actionpack/test/fixtures/test/hello_world_with_layout_false.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello world! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/html_template.html.erb b/actionpack/test/fixtures/test/html_template.html.erb
deleted file mode 100644
index 1bbc2b7f09..0000000000
--- a/actionpack/test/fixtures/test/html_template.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render :partial => "test/first_json_partial", formats: :json %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/hyphen-ated.erb b/actionpack/test/fixtures/test/hyphen-ated.erb
deleted file mode 100644
index cd0875583a..0000000000
--- a/actionpack/test/fixtures/test/hyphen-ated.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello world!
diff --git a/actionpack/test/fixtures/test/list.erb b/actionpack/test/fixtures/test/list.erb
deleted file mode 100644
index 0a4bda58ee..0000000000
--- a/actionpack/test/fixtures/test/list.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= @test_unchanged = 'goodbye' %><%= render :partial => 'customer', :collection => @customers %><%= @test_unchanged %>
diff --git a/actionpack/test/fixtures/test/non_erb_block_content_for.builder b/actionpack/test/fixtures/test/non_erb_block_content_for.builder
deleted file mode 100644
index d539a425a4..0000000000
--- a/actionpack/test/fixtures/test/non_erb_block_content_for.builder
+++ /dev/null
@@ -1,4 +0,0 @@
-content_for :title do
- 'Putting stuff in the title!'
-end
-xml << "Great stuff!"
diff --git a/actionpack/test/fixtures/test/potential_conflicts.erb b/actionpack/test/fixtures/test/potential_conflicts.erb
deleted file mode 100644
index a5e964e359..0000000000
--- a/actionpack/test/fixtures/test/potential_conflicts.erb
+++ /dev/null
@@ -1,4 +0,0 @@
-First: <%= @name %>
-<%= render :partial => "person", :locals => { :name => "Stephan" } -%>
-Fourth: <%= @name %>
-Fifth: <%= name %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/proper_block_detection.erb b/actionpack/test/fixtures/test/proper_block_detection.erb
deleted file mode 100644
index b55efbb25d..0000000000
--- a/actionpack/test/fixtures/test/proper_block_detection.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= @todo %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_file_from_template.html.erb b/actionpack/test/fixtures/test/render_file_from_template.html.erb
deleted file mode 100644
index fde9f4bb64..0000000000
--- a/actionpack/test/fixtures/test/render_file_from_template.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render :file => @path %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_file_with_locals_and_default.erb b/actionpack/test/fixtures/test/render_file_with_locals_and_default.erb
deleted file mode 100644
index 9b4900acc5..0000000000
--- a/actionpack/test/fixtures/test/render_file_with_locals_and_default.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= secret ||= 'one' %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb b/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb
deleted file mode 100644
index 0740b2d07c..0000000000
--- a/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hey HTML!
diff --git a/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb b/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb
deleted file mode 100644
index 4a11845cfe..0000000000
--- a/actionpack/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-Hello HTML! \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb b/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb
deleted file mode 100644
index 892ae5eca2..0000000000
--- a/actionpack/test/fixtures/test/render_implicit_js_template_without_layout.js.erb
+++ /dev/null
@@ -1 +0,0 @@
-alert('hello'); \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb b/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb
deleted file mode 100644
index 1461b95186..0000000000
--- a/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render partial: 'test/_directory/partial_with_locales', locals: {'name' => 'Jane'} %>
diff --git a/actionpack/test/fixtures/test/render_to_string_test.erb b/actionpack/test/fixtures/test/render_to_string_test.erb
deleted file mode 100644
index 6e267e8634..0000000000
--- a/actionpack/test/fixtures/test/render_to_string_test.erb
+++ /dev/null
@@ -1 +0,0 @@
-The value of foo is: ::<%= @foo %>::
diff --git a/actionpack/test/fixtures/test/render_two_partials.html.erb b/actionpack/test/fixtures/test/render_two_partials.html.erb
deleted file mode 100644
index 3db6025860..0000000000
--- a/actionpack/test/fixtures/test/render_two_partials.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%= render :partial => 'partial', :locals => {'first' => '1'} %>
-<%= render :partial => 'partial', :locals => {'second' => '2'} %>
diff --git a/actionpack/test/fixtures/test/using_layout_around_block.html.erb b/actionpack/test/fixtures/test/using_layout_around_block.html.erb
deleted file mode 100644
index 3d6661df9a..0000000000
--- a/actionpack/test/fixtures/test/using_layout_around_block.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render(:layout => "layout_for_partial", :locals => { :name => "David" }) do %>Inside from block<% end %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/test/with_html_partial.html.erb b/actionpack/test/fixtures/test/with_html_partial.html.erb
deleted file mode 100644
index d84d909d64..0000000000
--- a/actionpack/test/fixtures/test/with_html_partial.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<strong><%= render :partial => "partial_only_html" %></strong>
diff --git a/actionpack/test/fixtures/test/with_partial.html.erb b/actionpack/test/fixtures/test/with_partial.html.erb
deleted file mode 100644
index 7502364cf5..0000000000
--- a/actionpack/test/fixtures/test/with_partial.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<strong><%= render :partial => "partial_only" %></strong>
diff --git a/actionpack/test/fixtures/test/with_partial.text.erb b/actionpack/test/fixtures/test/with_partial.text.erb
deleted file mode 100644
index 5f068ebf27..0000000000
--- a/actionpack/test/fixtures/test/with_partial.text.erb
+++ /dev/null
@@ -1 +0,0 @@
-**<%= render :partial => "partial_only" %>**
diff --git a/actionpack/test/fixtures/test/with_xml_template.html.erb b/actionpack/test/fixtures/test/with_xml_template.html.erb
deleted file mode 100644
index e54a7cd001..0000000000
--- a/actionpack/test/fixtures/test/with_xml_template.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render :template => "test/greeting", :formats => :xml %>
diff --git a/actionpack/test/journey/router/utils_test.rb b/actionpack/test/journey/router/utils_test.rb
index 584fd56a5c..9b2b85ec73 100644
--- a/actionpack/test/journey/router/utils_test.rb
+++ b/actionpack/test/journey/router/utils_test.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require 'abstract_unit'
module ActionDispatch
@@ -20,6 +21,10 @@ module ActionDispatch
assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d")
end
+ def test_uri_unescape_with_utf8_string
+ assert_equal "Šašinková", Utils.unescape_uri("%C5%A0a%C5%A1inkov%C3%A1".force_encoding(Encoding::US_ASCII))
+ end
+
def test_normalize_path_not_greedy
assert_equal "/foo%20bar%20baz", Utils.normalize_path("/foo%20bar%20baz")
end