aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test')
-rw-r--r--actionpack/test/abstract/callbacks_test.rb97
-rw-r--r--actionpack/test/abstract/collector_test.rb6
-rw-r--r--actionpack/test/abstract/translation_test.rb26
-rw-r--r--actionpack/test/abstract_unit.rb241
-rw-r--r--actionpack/test/assertions/response_assertions_test.rb85
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb200
-rw-r--r--actionpack/test/controller/api/conditional_get_test.rb20
-rw-r--r--actionpack/test/controller/api/data_streaming_test.rb10
-rw-r--r--actionpack/test/controller/api/force_ssl_test.rb8
-rw-r--r--actionpack/test/controller/api/implicit_render_test.rb4
-rw-r--r--actionpack/test/controller/api/params_wrapper_test.rb10
-rw-r--r--actionpack/test/controller/api/redirect_to_test.rb4
-rw-r--r--actionpack/test/controller/api/renderers_test.rb24
-rw-r--r--actionpack/test/controller/api/url_for_test.rb6
-rw-r--r--actionpack/test/controller/api/with_cookies_test.rb23
-rw-r--r--actionpack/test/controller/api/with_helpers_test.rb44
-rw-r--r--actionpack/test/controller/base_test.rb145
-rw-r--r--actionpack/test/controller/caching_test.rb254
-rw-r--r--actionpack/test/controller/content_type_test.rb22
-rw-r--r--actionpack/test/controller/default_url_options_with_before_action_test.rb10
-rw-r--r--actionpack/test/controller/filters_test.rb316
-rw-r--r--actionpack/test/controller/flash_hash_test.rb164
-rw-r--r--actionpack/test/controller/flash_test.rb128
-rw-r--r--actionpack/test/controller/force_ssl_test.rb101
-rw-r--r--actionpack/test/controller/form_builder_test.rb4
-rw-r--r--actionpack/test/controller/helper_test.rb101
-rw-r--r--actionpack/test/controller/http_basic_authentication_test.rb107
-rw-r--r--actionpack/test/controller/http_digest_authentication_test.rb187
-rw-r--r--actionpack/test/controller/http_token_authentication_test.rb81
-rw-r--r--actionpack/test/controller/integration_test.rb784
-rw-r--r--actionpack/test/controller/live_stream_test.rb182
-rw-r--r--actionpack/test/controller/localized_templates_test.rb4
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb64
-rw-r--r--actionpack/test/controller/metal/renderers_test.rb50
-rw-r--r--actionpack/test/controller/metal_test.rb32
-rw-r--r--actionpack/test/controller/mime/accept_format_test.rb12
-rw-r--r--actionpack/test/controller/mime/respond_to_test.rb284
-rw-r--r--actionpack/test/controller/new_base/bare_metal_test.rb44
-rw-r--r--actionpack/test/controller/new_base/base_test.rb33
-rw-r--r--actionpack/test/controller/new_base/content_negotiation_test.rb7
-rw-r--r--actionpack/test/controller/new_base/content_type_test.rb8
-rw-r--r--actionpack/test/controller/new_base/middleware_test.rb10
-rw-r--r--actionpack/test/controller/new_base/render_action_test.rb57
-rw-r--r--actionpack/test/controller/new_base/render_body_test.rb12
-rw-r--r--actionpack/test/controller/new_base/render_context_test.rb23
-rw-r--r--actionpack/test/controller/new_base/render_file_test.rb28
-rw-r--r--actionpack/test/controller/new_base/render_html_test.rb8
-rw-r--r--actionpack/test/controller/new_base/render_implicit_action_test.rb6
-rw-r--r--actionpack/test/controller/new_base/render_layout_test.rb15
-rw-r--r--actionpack/test/controller/new_base/render_partial_test.rb15
-rw-r--r--actionpack/test/controller/new_base/render_plain_test.rb8
-rw-r--r--actionpack/test/controller/new_base/render_streaming_test.rb24
-rw-r--r--actionpack/test/controller/new_base/render_template_test.rb49
-rw-r--r--actionpack/test/controller/new_base/render_test.rb22
-rw-r--r--actionpack/test/controller/new_base/render_text_test.rb188
-rw-r--r--actionpack/test/controller/new_base/render_xml_test.rb5
-rw-r--r--actionpack/test/controller/output_escaping_test.rb8
-rw-r--r--actionpack/test/controller/parameter_encoding_test.rb52
-rw-r--r--actionpack/test/controller/parameters/accessors_test.rb279
-rw-r--r--actionpack/test/controller/parameters/always_permitted_parameters_test.rb21
-rw-r--r--actionpack/test/controller/parameters/dup_test.rb67
-rw-r--r--actionpack/test/controller/parameters/log_on_unpermitted_params_test.rb56
-rw-r--r--actionpack/test/controller/parameters/multi_parameter_attributes_test.rb13
-rw-r--r--actionpack/test/controller/parameters/mutators_test.rb72
-rw-r--r--actionpack/test/controller/parameters/nested_parameters_permit_test.rb184
-rw-r--r--actionpack/test/controller/parameters/nested_parameters_test.rb187
-rw-r--r--actionpack/test/controller/parameters/parameters_permit_test.rb384
-rw-r--r--actionpack/test/controller/parameters/raise_on_unpermitted_params_test.rb16
-rw-r--r--actionpack/test/controller/parameters/serialization_test.rb54
-rw-r--r--actionpack/test/controller/params_parse_test.rb34
-rw-r--r--actionpack/test/controller/params_wrapper_test.rb234
-rw-r--r--actionpack/test/controller/permitted_params_test.rb4
-rw-r--r--actionpack/test/controller/redirect_test.rb156
-rw-r--r--actionpack/test/controller/render_js_test.rb18
-rw-r--r--actionpack/test/controller/render_json_test.rb57
-rw-r--r--actionpack/test/controller/render_other_test.rb24
-rw-r--r--actionpack/test/controller/render_test.rb479
-rw-r--r--actionpack/test/controller/render_xml_test.rb29
-rw-r--r--actionpack/test/controller/renderer_test.rb106
-rw-r--r--actionpack/test/controller/renderers_test.rb91
-rw-r--r--actionpack/test/controller/request/test_request_test.rb43
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb559
-rw-r--r--actionpack/test/controller/required_params_test.rb42
-rw-r--r--actionpack/test/controller/rescue_test.rb149
-rw-r--r--actionpack/test/controller/resources_test.rb769
-rw-r--r--actionpack/test/controller/routing_test.rb1468
-rw-r--r--actionpack/test/controller/runner_test.rb10
-rw-r--r--actionpack/test/controller/send_file_test.rb135
-rw-r--r--actionpack/test/controller/show_exceptions_test.rb60
-rw-r--r--actionpack/test/controller/streaming_test.rb6
-rw-r--r--actionpack/test/controller/test_case_test.rb661
-rw-r--r--actionpack/test/controller/url_for_integration_test.rb268
-rw-r--r--actionpack/test/controller/url_for_test.rb337
-rw-r--r--actionpack/test/controller/url_rewriter_test.rb63
-rw-r--r--actionpack/test/controller/webservice_test.rb54
-rw-r--r--actionpack/test/dispatch/callbacks_test.rb21
-rw-r--r--actionpack/test/dispatch/content_disposition_test.rb37
-rw-r--r--actionpack/test/dispatch/content_security_policy_test.rb546
-rw-r--r--actionpack/test/dispatch/cookies_test.rb862
-rw-r--r--actionpack/test/dispatch/debug_exceptions_test.rb398
-rw-r--r--actionpack/test/dispatch/debug_locks_test.rb38
-rw-r--r--actionpack/test/dispatch/exception_wrapper_test.rb71
-rw-r--r--actionpack/test/dispatch/executor_test.rb136
-rw-r--r--actionpack/test/dispatch/header_test.rb62
-rw-r--r--actionpack/test/dispatch/live_response_test.rb42
-rw-r--r--actionpack/test/dispatch/mapper_test.rb79
-rw-r--r--actionpack/test/dispatch/middleware_stack_test.rb65
-rw-r--r--actionpack/test/dispatch/mime_type_test.rb56
-rw-r--r--actionpack/test/dispatch/mount_test.rb24
-rw-r--r--actionpack/test/dispatch/prefix_generation_test.rb228
-rw-r--r--actionpack/test/dispatch/rack_cache_test.rb8
-rw-r--r--actionpack/test/dispatch/reloader_test.rb117
-rw-r--r--actionpack/test/dispatch/request/json_params_parsing_test.rb101
-rw-r--r--actionpack/test/dispatch/request/multipart_params_parsing_test.rb120
-rw-r--r--actionpack/test/dispatch/request/query_string_parsing_test.rb72
-rw-r--r--actionpack/test/dispatch/request/session_test.rb119
-rw-r--r--actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb16
-rw-r--r--actionpack/test/dispatch/request_id_test.rb50
-rw-r--r--actionpack/test/dispatch/request_test.rb922
-rw-r--r--actionpack/test/dispatch/response_test.rb351
-rw-r--r--actionpack/test/dispatch/routing/concerns_test.rb6
-rw-r--r--actionpack/test/dispatch/routing/custom_url_helpers_test.rb333
-rw-r--r--actionpack/test/dispatch/routing/inspector_test.rb259
-rw-r--r--actionpack/test/dispatch/routing/ipv6_redirect_test.rb25
-rw-r--r--actionpack/test/dispatch/routing/route_set_test.rb83
-rw-r--r--actionpack/test/dispatch/routing_assertions_test.rb150
-rw-r--r--actionpack/test/dispatch/routing_test.rb4048
-rw-r--r--actionpack/test/dispatch/runner_test.rb19
-rw-r--r--actionpack/test/dispatch/session/abstract_store_test.rb16
-rw-r--r--actionpack/test/dispatch/session/cache_store_test.rb94
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb255
-rw-r--r--actionpack/test/dispatch/session/mem_cache_store_test.rb96
-rw-r--r--actionpack/test/dispatch/session/test_session_test.rb46
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb51
-rw-r--r--actionpack/test/dispatch/ssl_test.rb195
-rw-r--r--actionpack/test/dispatch/static_test.rb118
-rw-r--r--actionpack/test/dispatch/system_testing/driver_test.rb54
-rw-r--r--actionpack/test/dispatch/system_testing/screenshot_helper_test.rb81
-rw-r--r--actionpack/test/dispatch/system_testing/server_test.rb32
-rw-r--r--actionpack/test/dispatch/system_testing/system_test_case_test.rb84
-rw-r--r--actionpack/test/dispatch/test_request_test.rb70
-rw-r--r--actionpack/test/dispatch/test_response_test.rb19
-rw-r--r--actionpack/test/dispatch/uploaded_file_test.rb86
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb26
-rw-r--r--actionpack/test/fixtures/alternate_helpers/foo_helper.rb4
-rw-r--r--actionpack/test/fixtures/collection_cache/index.html.erb2
-rw-r--r--actionpack/test/fixtures/company.rb4
-rw-r--r--actionpack/test/fixtures/functional_caching/_formatted_partial.html.erb1
-rw-r--r--actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb2
-rw-r--r--actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder2
-rw-r--r--actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb2
-rw-r--r--actionpack/test/fixtures/functional_caching/fragment_cached.html.erb2
-rw-r--r--actionpack/test/fixtures/functional_caching/fragment_cached_with_options.html.erb3
-rw-r--r--actionpack/test/fixtures/functional_caching/xml_fragment_cached_with_html_partial.xml.builder5
-rw-r--r--actionpack/test/fixtures/helpers/abc_helper.rb2
-rw-r--r--actionpack/test/fixtures/helpers/fun/games_helper.rb4
-rw-r--r--actionpack/test/fixtures/helpers/fun/pdf_helper.rb4
-rw-r--r--actionpack/test/fixtures/helpers/just_me_helper.rb4
-rw-r--r--actionpack/test/fixtures/helpers/me_too_helper.rb4
-rw-r--r--actionpack/test/fixtures/helpers1_pack/pack1_helper.rb2
-rw-r--r--actionpack/test/fixtures/helpers2_pack/pack2_helper.rb2
-rw-r--r--actionpack/test/fixtures/helpers_typo/admin/users_helper.rb3
-rw-r--r--actionpack/test/fixtures/implicit_render_test/empty_action_with_mobile_variant.html+mobile.erb1
-rw-r--r--actionpack/test/fixtures/implicit_render_test/empty_action_with_template.html.erb1
-rw-r--r--actionpack/test/fixtures/layouts/builder.builder2
-rw-r--r--actionpack/test/fixtures/load_me.rb4
-rw-r--r--actionpack/test/fixtures/multipart/mona_lisa.jpgbin159528 -> 0 bytes
-rw-r--r--actionpack/test/fixtures/multipart/ruby_on_rails.jpgbin0 -> 45142 bytes
-rw-r--r--actionpack/test/fixtures/namespaced/implicit_render_test/hello_world.erb1
-rw-r--r--actionpack/test/fixtures/old_content_type/render_default_for_builder.builder2
-rw-r--r--actionpack/test/fixtures/public/foo/さようなら.html1
-rw-r--r--actionpack/test/fixtures/public/foo/さようなら.html.gzbin0 -> 67 bytes
-rw-r--r--actionpack/test/fixtures/respond_to/using_defaults.xml.builder2
-rw-r--r--actionpack/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder2
-rw-r--r--actionpack/test/fixtures/respond_to/variant_with_implicit_template_rendering.html+mobile.erb (renamed from actionpack/test/fixtures/respond_to/variant_with_implicit_rendering.html+mobile.erb)0
-rw-r--r--actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb4
-rw-r--r--actionpack/test/fixtures/test/formatted_xml_erb.builder2
-rw-r--r--actionpack/test/fixtures/test/hello_xml_world.builder2
-rw-r--r--actionpack/test/fixtures/test/with_implicit_template.erb1
-rw-r--r--actionpack/test/fixtures/公共/foo/さようなら.html1
-rw-r--r--actionpack/test/fixtures/公共/foo/さようなら.html.gzbin0 -> 67 bytes
-rw-r--r--actionpack/test/journey/gtg/builder_test.rb58
-rw-r--r--actionpack/test/journey/gtg/transition_table_test.rb88
-rw-r--r--actionpack/test/journey/nfa/simulator_test.rb60
-rw-r--r--actionpack/test/journey/nfa/transition_table_test.rb52
-rw-r--r--actionpack/test/journey/nodes/symbol_test.rb8
-rw-r--r--actionpack/test/journey/path/pattern_test.rb194
-rw-r--r--actionpack/test/journey/route/definition/parser_test.rb62
-rw-r--r--actionpack/test/journey/route/definition/scanner_test.rb113
-rw-r--r--actionpack/test/journey/route_test.rb74
-rw-r--r--actionpack/test/journey/router/utils_test.rb15
-rw-r--r--actionpack/test/journey/router_test.rb389
-rw-r--r--actionpack/test/journey/routes_test.rb30
-rw-r--r--actionpack/test/lib/controller/fake_controllers.rb2
-rw-r--r--actionpack/test/lib/controller/fake_models.rb14
-rw-r--r--actionpack/test/routing/helper_test.rb4
-rw-r--r--actionpack/test/tmp/.gitignore0
197 files changed, 14587 insertions, 9092 deletions
diff --git a/actionpack/test/abstract/callbacks_test.rb b/actionpack/test/abstract/callbacks_test.rb
index 07571602e4..4512ea27b3 100644
--- a/actionpack/test/abstract/callbacks_test.rb
+++ b/actionpack/test/abstract/callbacks_test.rb
@@ -1,8 +1,9 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module AbstractController
module Testing
-
class ControllerWithCallbacks < AbstractController::Base
include AbstractController::Callbacks
end
@@ -43,7 +44,7 @@ module AbstractController
def aroundz
@aroundz = "FIRST"
yield
- @aroundz << "SECOND"
+ @aroundz += "SECOND"
end
def index
@@ -114,8 +115,8 @@ module AbstractController
end
class CallbacksWithConditions < ControllerWithCallbacks
- before_action :list, :only => :index
- before_action :authenticate, :except => :index
+ before_action :list, only: :index
+ before_action :authenticate, except: :index
def index
self.response_body = @list.join(", ")
@@ -126,14 +127,14 @@ module AbstractController
end
private
- def list
- @list = ["Hello", "World"]
- end
-
- def authenticate
- @list ||= []
- @authenticated = "true"
- end
+ def list
+ @list = ["Hello", "World"]
+ end
+
+ def authenticate
+ @list ||= []
+ @authenticated = "true"
+ end
end
class TestCallbacksWithConditions < ActiveSupport::TestCase
@@ -153,7 +154,7 @@ module AbstractController
test "when :except is specified, an after action is not triggered on that action" do
@controller.process(:index)
- assert !@controller.instance_variable_defined?("@authenticated")
+ assert_not @controller.instance_variable_defined?("@authenticated")
end
end
@@ -170,14 +171,14 @@ module AbstractController
end
private
- def list
- @list = ["Hello", "World"]
- end
-
- def authenticate
- @list = []
- @authenticated = "true"
- end
+ def list
+ @list = ["Hello", "World"]
+ end
+
+ def authenticate
+ @list = []
+ @authenticated = "true"
+ end
end
class TestCallbacksWithArrayConditions < ActiveSupport::TestCase
@@ -197,12 +198,12 @@ module AbstractController
test "when :except is specified with an array, an after action is not triggered on that action" do
@controller.process(:index)
- assert !@controller.instance_variable_defined?("@authenticated")
+ assert_not @controller.instance_variable_defined?("@authenticated")
end
end
class ChangedConditions < Callback2
- before_action :first, :only => :index
+ before_action :first, only: :index
def not_index
@text ||= nil
@@ -265,53 +266,5 @@ module AbstractController
assert_equal "Hello world Howdy!", controller.response_body
end
end
-
- class AliasedCallbacks < ControllerWithCallbacks
- ActiveSupport::Deprecation.silence do
- before_filter :first
- after_filter :second
- around_filter :aroundz
- end
-
- def first
- @text = "Hello world"
- end
-
- def second
- @second = "Goodbye"
- end
-
- def aroundz
- @aroundz = "FIRST"
- yield
- @aroundz << "SECOND"
- end
-
- def index
- @text ||= nil
- self.response_body = @text.to_s
- end
- end
-
- class TestAliasedCallbacks < ActiveSupport::TestCase
- def setup
- @controller = AliasedCallbacks.new
- end
-
- test "before_filter works" do
- @controller.process(:index)
- assert_equal "Hello world", @controller.response_body
- end
-
- test "after_filter works" do
- @controller.process(:index)
- assert_equal "Goodbye", @controller.instance_variable_get("@second")
- end
-
- test "around_filter works" do
- @controller.process(:index)
- assert_equal "FIRSTSECOND", @controller.instance_variable_get("@aroundz")
- end
- end
end
end
diff --git a/actionpack/test/abstract/collector_test.rb b/actionpack/test/abstract/collector_test.rb
index edbb84d462..a4770b66e1 100644
--- a/actionpack/test/abstract/collector_test.rb
+++ b/actionpack/test/abstract/collector_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module AbstractController
module Testing
@@ -55,7 +57,7 @@ module AbstractController
collector.js(:bar) { :baz }
assert_equal [Mime[:html], [], nil], collector.responses[0]
assert_equal [Mime[:text], [:foo], nil], collector.responses[1]
- assert_equal [Mime[:js], [:bar]], collector.responses[2][0,2]
+ assert_equal [Mime[:js], [:bar]], collector.responses[2][0, 2]
assert_equal :baz, collector.responses[2][2].call
end
end
diff --git a/actionpack/test/abstract/translation_test.rb b/actionpack/test/abstract/translation_test.rb
index 1435928578..7138044c03 100644
--- a/actionpack/test/abstract/translation_test.rb
+++ b/actionpack/test/abstract/translation_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module AbstractController
module Testing
@@ -9,21 +11,20 @@ module AbstractController
class TranslationControllerTest < ActiveSupport::TestCase
def setup
@controller = TranslationController.new
- I18n.backend.store_translations(:en, {
+ I18n.backend.store_translations(:en,
one: {
- two: 'bar',
+ two: "bar",
},
abstract_controller: {
testing: {
translation: {
index: {
- foo: 'bar',
+ foo: "bar",
},
- no_action: 'no_action_tr',
+ no_action: "no_action_tr",
},
},
- },
- })
+ })
end
def test_action_controller_base_responds_to_translate
@@ -44,30 +45,31 @@ module AbstractController
def test_lazy_lookup
@controller.stub :action_name, :index do
- assert_equal 'bar', @controller.t('.foo')
+ assert_equal "bar", @controller.t(".foo")
end
end
def test_lazy_lookup_with_symbol
@controller.stub :action_name, :index do
- assert_equal 'bar', @controller.t(:'.foo')
+ assert_equal "bar", @controller.t(:'.foo')
end
end
def test_lazy_lookup_fallback
@controller.stub :action_name, :index do
- assert_equal 'no_action_tr', @controller.t(:'.no_action')
+ assert_equal "no_action_tr", @controller.t(:'.no_action')
end
end
def test_default_translation
@controller.stub :action_name, :index do
- assert_equal 'bar', @controller.t('one.two')
+ assert_equal "bar", @controller.t("one.two")
+ assert_equal "baz", @controller.t(".twoz", default: ["baz", :twoz])
end
end
def test_localize
- time, expected = Time.gm(2000), 'Sat, 01 Jan 2000 00:00:00 +0000'
+ time, expected = Time.gm(2000), "Sat, 01 Jan 2000 00:00:00 +0000"
I18n.stub :localize, expected do
assert_equal expected, @controller.l(time)
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index ef7aab72c6..65dd28b3d7 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -1,40 +1,42 @@
-require File.expand_path('../../../load_paths', __FILE__)
+# frozen_string_literal: true
-$:.unshift(File.dirname(__FILE__) + '/lib')
-$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
-$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
+$:.unshift File.expand_path("lib", __dir__)
+$:.unshift File.expand_path("fixtures/helpers", __dir__)
+$:.unshift File.expand_path("fixtures/alternate_helpers", __dir__)
-require 'active_support/core_ext/kernel/reporting'
+require "active_support/core_ext/kernel/reporting"
# These are the normal settings that will be set up by Railties
# TODO: Have these tests support other combinations of these values
silence_warnings do
- Encoding.default_internal = "UTF-8"
- Encoding.default_external = "UTF-8"
+ Encoding.default_internal = Encoding::UTF_8
+ Encoding.default_external = Encoding::UTF_8
end
-require 'drb'
+require "drb"
begin
- require 'drb/unix'
+ require "drb/unix"
rescue LoadError
puts "'drb/unix' is not available"
end
-PROCESS_COUNT = (ENV['N'] || 4).to_i
+if ENV["TRAVIS"]
+ PROCESS_COUNT = 0
+else
+ PROCESS_COUNT = (ENV["N"] || 4).to_i
+end
-require 'active_support/testing/autorun'
-require 'abstract_controller'
-require 'abstract_controller/railties/routes_helpers'
-require 'action_controller'
-require 'action_view'
-require 'action_view/testing/resolvers'
-require 'action_dispatch'
-require 'active_support/dependencies'
-require 'active_model'
-require 'active_record'
-require 'action_controller/caching'
+require "active_support/testing/autorun"
+require "abstract_controller"
+require "abstract_controller/railties/routes_helpers"
+require "action_controller"
+require "action_view"
+require "action_view/testing/resolvers"
+require "action_dispatch"
+require "active_support/dependencies"
+require "active_model"
-require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
+require "pp" # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
module Rails
class << self
@@ -42,7 +44,7 @@ module Rails
@_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "test")
end
- def root; end;
+ def root; end
end
end
@@ -56,16 +58,14 @@ ActiveSupport::Deprecation.debug = true
# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false
-# Register danish language for testing
-I18n.backend.store_translations 'da', {}
-I18n.backend.store_translations 'pt-BR', {}
-
-FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
+FIXTURE_LOAD_PATH = File.join(__dir__, "fixtures")
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
SharedTestRoutes.draw do
- get ':controller(/:action)'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action)"
+ end
end
module ActionDispatch
@@ -106,6 +106,7 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
middleware.use ActionDispatch::Callbacks
middleware.use ActionDispatch::Cookies
middleware.use ActionDispatch::Flash
+ middleware.use Rack::MethodOverride
middleware.use Rack::Head
yield(middleware) if block_given?
end
@@ -114,34 +115,28 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
self.app = build_app
app.routes.draw do
- get ':controller(/:action)'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action)"
+ end
end
class DeadEndRoutes < ActionDispatch::Routing::RouteSet
# Stub Rails dispatcher so it does not get controller references and
# simply return the controller#action as Rack::Body.
class NullController < ::ActionController::Metal
- def initialize(controller_name)
- @controller = controller_name
- end
-
- def make_response!(request)
- self.class.make_response! request
- end
-
- def dispatch(action, req, res)
- [200, {'Content-Type' => 'text/html'}, ["#{@controller}##{action}"]]
+ def self.dispatch(action, req, res)
+ [200, { "Content-Type" => "text/html" }, ["#{req.params[:controller]}##{action}"]]
end
end
- class NullControllerRequest < DelegateClass(ActionDispatch::Request)
+ class NullControllerRequest < ActionDispatch::Request
def controller_class
- NullController.new params[:controller]
+ NullController
end
end
- def make_request env
- NullControllerRequest.new super
+ def make_request(env)
+ NullControllerRequest.new env
end
end
@@ -158,12 +153,12 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
yield temporary_routes
ensure
self.class.app = old_app
- self.remove!
+ remove!
silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
end
def with_autoload_path(path)
- path = File.join(File.dirname(__FILE__), "fixtures", path)
+ path = File.join(__dir__, "fixtures", path)
if ActiveSupport::Dependencies.autoload_paths.include?(path)
yield
else
@@ -171,7 +166,7 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
ActiveSupport::Dependencies.autoload_paths << path
yield
ensure
- ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
+ ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path }
ActiveSupport::Dependencies.clear
end
end
@@ -182,7 +177,7 @@ end
class Rack::TestCase < ActionDispatch::IntegrationTest
def self.testing(klass = nil)
if klass
- @testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
+ @testing = "/#{klass.name.underscore}".sub(/_controller$/, "")
else
@testing
end
@@ -237,6 +232,7 @@ module ActionController
routes = ActionDispatch::Routing::RouteSet.new
routes.draw(&block)
include routes.url_helpers
+ routes
end
end
@@ -246,36 +242,17 @@ module ActionController
end
end
-
class ::ApplicationController < ActionController::Base
end
-class Workshop
- extend ActiveModel::Naming
- include ActiveModel::Conversion
- attr_accessor :id
-
- def initialize(id)
- @id = id
- end
-
- def persisted?
- id.present?
- end
-
- def to_s
- id.to_s
- end
-end
-
module ActionDispatch
class DebugExceptions
private
- remove_method :stderr_logger
- # Silence logger
- def stderr_logger
- nil
- end
+ remove_method :stderr_logger
+ # Silence logger
+ def stderr_logger
+ nil
+ end
end
end
@@ -285,16 +262,16 @@ module ActionDispatch
host = uri_or_host.host unless path
path ||= uri_or_host.path
- params = {'PATH_INFO' => path,
- 'REQUEST_METHOD' => method,
- 'HTTP_HOST' => host}
+ params = { "PATH_INFO" => path,
+ "REQUEST_METHOD" => method,
+ "HTTP_HOST" => host }
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
+ 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}"
@@ -303,23 +280,23 @@ module ActionDispatch
end
def get(uri_or_host, path = nil)
- send_request(uri_or_host, 'GET', path)[2].join
+ 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
+ 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
+ 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
+ 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
+ send_request(uri_or_host, "PATCH", path)[2].join
end
end
end
@@ -327,7 +304,7 @@ end
module RoutingTestHelpers
def url_for(set, options)
route_name = options.delete :use_route
- set.url_for options.merge(:only_path => true), route_name
+ set.url_for options.merge(only_path: true), route_name
end
def make_set(strict = true)
@@ -365,9 +342,9 @@ module RoutingTestHelpers
private
- def make_request(env)
- Request.new super, url_helpers, @block, strict
- end
+ def make_request(env)
+ Request.new super, url_helpers, @block, strict
+ end
end
end
@@ -376,36 +353,11 @@ class ResourcesController < ActionController::Base
alias_method :show, :index
end
-class ThreadsController < ResourcesController; end
-class MessagesController < ResourcesController; end
class CommentsController < ResourcesController; end
-class ReviewsController < ResourcesController; end
-
-class AccountsController < ResourcesController; end
-class AdminController < ResourcesController; end
-class ProductsController < ResourcesController; end
+class AccountsController < ResourcesController; end
class ImagesController < ResourcesController; end
-module Backoffice
- class ProductsController < ResourcesController; end
- class ImagesController < ResourcesController; end
-
- module Admin
- class ProductsController < ResourcesController; end
- class ImagesController < ResourcesController; end
- end
-end
-
-# Skips the current run on Rubinius using Minitest::Assertions#skip
-def rubinius_skip(message = '')
- skip message if RUBY_ENGINE == 'rbx'
-end
-# Skips the current run on JRuby using Minitest::Assertions#skip
-def jruby_skip(message = '')
- skip message if defined?(JRUBY_VERSION)
-end
-
-require 'active_support/testing/method_call_assertions'
+require "active_support/testing/method_call_assertions"
class ForkingExecutor
class Server
@@ -415,27 +367,25 @@ class ForkingExecutor
@queue = Queue.new
end
- def record reporter, result
+ def record(reporter, result)
reporter.record result
end
- def << o
+ def <<(o)
o[2] = DRbObject.new(o[2]) if o
@queue << o
end
def pop; @queue.pop; end
end
- def initialize size
+ def initialize(size)
@size = size
@queue = Server.new
- file = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('rails-tests', 'fd')
- @url = "drbunix://#{file}"
@pool = nil
- DRb.start_service @url, @queue
+ @url = DRb.start_service("drbunix:", @queue).uri
end
- def << work; @queue << work; end
+ def <<(work); @queue << work; end
def shutdown
pool = @size.times.map {
@@ -459,18 +409,18 @@ class ForkingExecutor
end
private
- def translate_exceptions(result)
- result.failures.map! { |e|
- begin
- Marshal.dump e
- e
- rescue TypeError
- ex = Exception.new e.message
- ex.set_backtrace e.backtrace
- Minitest::UnexpectedError.new ex
- end
- }
- end
+ def translate_exceptions(result)
+ result.failures.map! { |e|
+ begin
+ Marshal.dump e
+ e
+ rescue TypeError
+ ex = Exception.new e.message
+ ex.set_backtrace e.backtrace
+ Minitest::UnexpectedError.new ex
+ end
+ }
+ end
end
if RUBY_ENGINE == "ruby" && PROCESS_COUNT > 0
@@ -480,4 +430,31 @@ end
class ActiveSupport::TestCase
include ActiveSupport::Testing::MethodCallAssertions
+
+ private
+ # Skips the current run on Rubinius using Minitest::Assertions#skip
+ def rubinius_skip(message = "")
+ skip message if RUBY_ENGINE == "rbx"
+ end
+
+ # Skips the current run on JRuby using Minitest::Assertions#skip
+ def jruby_skip(message = "")
+ skip message if defined?(JRUBY_VERSION)
+ end
+end
+
+class DrivenByRackTest < ActionDispatch::SystemTestCase
+ driven_by :rack_test
+end
+
+class DrivenBySeleniumWithChrome < ActionDispatch::SystemTestCase
+ driven_by :selenium, using: :chrome
+end
+
+class DrivenBySeleniumWithHeadlessChrome < ActionDispatch::SystemTestCase
+ driven_by :selenium, using: :headless_chrome
+end
+
+class DrivenBySeleniumWithHeadlessFirefox < ActionDispatch::SystemTestCase
+ driven_by :selenium, using: :headless_firefox
end
diff --git a/actionpack/test/assertions/response_assertions_test.rb b/actionpack/test/assertions/response_assertions_test.rb
index 6c7036aa1a..261579dce5 100644
--- a/actionpack/test/assertions/response_assertions_test.rb
+++ b/actionpack/test/assertions/response_assertions_test.rb
@@ -1,15 +1,18 @@
-require 'abstract_unit'
-require 'action_dispatch/testing/assertions/response'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/testing/assertions/response"
module ActionDispatch
module Assertions
class ResponseAssertionsTest < ActiveSupport::TestCase
include ResponseAssertions
- FakeResponse = Struct.new(:response_code, :location) do
+ FakeResponse = Struct.new(:response_code, :location, :body) do
def initialize(*)
super
self.location ||= "http://test.example.com/posts"
+ self.body ||= ""
end
[:successful, :not_found, :redirection, :server_error].each do |sym|
@@ -19,9 +22,14 @@ module ActionDispatch
end
end
+ def setup
+ @controller = nil
+ @request = nil
+ end
+
def test_assert_response_predicate_methods
[:success, :missing, :redirect, :error].each do |sym|
- @response = FakeResponse.new RESPONSE_PREDICATES[sym].to_s.sub(/\?/, '').to_sym
+ @response = FakeResponse.new RESPONSE_PREDICATES[sym].to_s.sub(/\?/, "").to_sym
assert_response sym
assert_raises(Minitest::Assertion) {
@@ -30,7 +38,7 @@ module ActionDispatch
end
end
- def test_assert_response_fixnum
+ def test_assert_response_integer
@response = FakeResponse.new 400
assert_response 400
@@ -64,13 +72,68 @@ module ActionDispatch
}
end
- def test_message_when_response_is_redirect_but_asserted_for_status_other_than_redirect
- @response = FakeResponse.new :redirection, "http://test.host/posts/redirect/1"
- error = assert_raises(Minitest::Assertion) do
- assert_response :success
- end
+ def test_error_message_shows_404_when_404_asserted_for_success
+ @response = ActionDispatch::Response.new
+ @response.status = 404
+
+ error = assert_raises(Minitest::Assertion) { assert_response :success }
+ expected = "Expected response to be a <2XX: success>,"\
+ " but was a <404: Not Found>"
+ assert_match expected, error.message
+ end
+
+ def test_error_message_shows_404_when_asserted_for_200
+ @response = ActionDispatch::Response.new
+ @response.status = 404
+
+ error = assert_raises(Minitest::Assertion) { assert_response 200 }
+ expected = "Expected response to be a <200: OK>,"\
+ " but was a <404: Not Found>"
+ assert_match expected, error.message
+ end
+
+ def test_error_message_shows_302_redirect_when_302_asserted_for_success
+ @response = ActionDispatch::Response.new
+ @response.status = 302
+ @response.location = "http://test.host/posts/redirect/1"
+
+ error = assert_raises(Minitest::Assertion) { assert_response :success }
+ expected = "Expected response to be a <2XX: success>,"\
+ " but was a <302: Found>" \
+ " redirect to <http://test.host/posts/redirect/1>"
+ assert_match expected, error.message
+ end
+
+ def test_error_message_shows_302_redirect_when_302_asserted_for_301
+ @response = ActionDispatch::Response.new
+ @response.status = 302
+ @response.location = "http://test.host/posts/redirect/2"
+
+ error = assert_raises(Minitest::Assertion) { assert_response 301 }
+ expected = "Expected response to be a <301: Moved Permanently>,"\
+ " but was a <302: Found>" \
+ " redirect to <http://test.host/posts/redirect/2>"
+ assert_match expected, error.message
+ end
+
+ def test_error_message_shows_short_response_body
+ @response = ActionDispatch::Response.new
+ @response.status = 400
+ @response.body = "not too long"
+ error = assert_raises(Minitest::Assertion) { assert_response 200 }
+ expected = "Expected response to be a <200: OK>,"\
+ " but was a <400: Bad Request>" \
+ "\nResponse body: not too long"
+ assert_match expected, error.message
+ end
- expected = "Expected response to be a <success>, but was a redirect to <http://test.host/posts/redirect/1>."
+ def test_error_message_does_not_show_long_response_body
+ @response = ActionDispatch::Response.new
+ @response.status = 400
+ @response.body = "not too long" * 50
+ error = assert_raises(Minitest::Assertion) { assert_response 200 }
+ expected = "Expected response to be a <200: OK>,"\
+ " but was a <400: Bad Request>"
assert_match expected, error.message
end
end
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index 899d92f815..763df3a776 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -1,33 +1,34 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
+# frozen_string_literal: true
-class ActionPackAssertionsController < ActionController::Base
+require "abstract_unit"
+require "controller/fake_controllers"
+class ActionPackAssertionsController < ActionController::Base
def nothing() head :ok end
- def hello_xml_world() render :template => "test/hello_xml_world"; end
+ def hello_xml_world() render template: "test/hello_xml_world"; end
def hello_xml_world_pdf
self.content_type = "application/pdf"
- render :template => "test/hello_xml_world"
+ render template: "test/hello_xml_world"
end
def hello_xml_world_pdf_header
response.headers["Content-Type"] = "application/pdf; charset=utf-8"
- render :template => "test/hello_xml_world"
+ render template: "test/hello_xml_world"
end
def redirect_internal() redirect_to "/nothing"; end
- def redirect_to_action() redirect_to :action => "flash_me", :id => 1, :params => { "panda" => "fun" }; end
+ def redirect_to_action() redirect_to action: "flash_me", id: 1, params: { "panda" => "fun" }; end
- def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end
+ def redirect_to_controller() redirect_to controller: "elsewhere", action: "flash_me"; end
- def redirect_to_controller_with_symbol() redirect_to :controller => :elsewhere, :action => :flash_me; end
+ def redirect_to_controller_with_symbol() redirect_to controller: :elsewhere, action: :flash_me; end
- def redirect_to_path() redirect_to '/some/path' end
+ def redirect_to_path() redirect_to "/some/path" end
- def redirect_invalid_external_route() redirect_to 'ht_tp://www.rubyonrails.org' end
+ def redirect_invalid_external_route() redirect_to "ht_tp://www.rubyonrails.org" end
def redirect_to_named_route() redirect_to route_one_url end
@@ -35,14 +36,14 @@ class ActionPackAssertionsController < ActionController::Base
def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end
- def response404() head '404 AWOL' end
+ def response404() head "404 AWOL" end
- def response500() head '500 Sorry' end
+ def response500() head "500 Sorry" end
- def response599() head '599 Whoah!' end
+ def response599() head "599 Whoah!" end
def flash_me
- flash['hello'] = 'my name is inigo montoya...'
+ flash["hello"] = "my name is inigo montoya..."
render plain: "Inconceivable!"
end
@@ -53,7 +54,7 @@ class ActionPackAssertionsController < ActionController::Base
def assign_this
@howdy = "ho"
- render :inline => "Mr. Henke"
+ render inline: "Mr. Henke"
end
def render_based_on_parameters
@@ -69,7 +70,7 @@ class ActionPackAssertionsController < ActionController::Base
end
def session_stuffing
- session['xmas'] = 'turkey'
+ session["xmas"] = "turkey"
render plain: "ho ho ho"
end
@@ -84,11 +85,11 @@ class ActionPackAssertionsController < ActionController::Base
end
def render_file_absolute_path
- render :file => File.expand_path('../../../README.rdoc', __FILE__)
+ render file: File.expand_path("../../README.rdoc", __dir__)
end
def render_file_relative_path
- render :file => 'README.rdoc'
+ render file: "README.rdoc"
end
end
@@ -97,7 +98,7 @@ end
# is expecting something other than an error.
class AssertResponseWithUnexpectedErrorController < ActionController::Base
def index
- raise 'FAIL'
+ raise "FAIL"
end
def show
@@ -116,21 +117,30 @@ module Admin
end
def redirect_to_absolute_controller
- redirect_to :controller => '/content'
+ redirect_to controller: "/content"
end
def redirect_to_fellow_controller
- redirect_to :controller => 'user'
+ redirect_to controller: "user"
end
def redirect_to_top_level_named_route
- redirect_to top_level_url(:id => "foo")
+ redirect_to top_level_url(id: "foo")
end
end
end
-class ActionPackAssertionsControllerTest < ActionController::TestCase
+class ApiOnlyController < ActionController::API
+ def nothing
+ head :ok
+ end
+
+ def redirect_to_new_route
+ redirect_to new_route_url
+ end
+end
+class ActionPackAssertionsControllerTest < ActionController::TestCase
def test_render_file_absolute_path
get :render_file_absolute_path
assert_match(/\A= Action Pack/, @response.body)
@@ -144,50 +154,67 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
def test_get_request
assert_raise(RuntimeError) { get :raise_exception_on_get }
get :raise_exception_on_post
- assert_equal 'request method: GET', @response.body
+ assert_equal "request method: GET", @response.body
end
def test_post_request
assert_raise(RuntimeError) { post :raise_exception_on_post }
post :raise_exception_on_get
- assert_equal 'request method: POST', @response.body
+ assert_equal "request method: POST", @response.body
end
def test_get_post_request_switch
post :raise_exception_on_get
- assert_equal 'request method: POST', @response.body
+ assert_equal "request method: POST", @response.body
get :raise_exception_on_post
- assert_equal 'request method: GET', @response.body
+ assert_equal "request method: GET", @response.body
post :raise_exception_on_get
- assert_equal 'request method: POST', @response.body
+ assert_equal "request method: POST", @response.body
get :raise_exception_on_post
- assert_equal 'request method: GET', @response.body
+ assert_equal "request method: GET", @response.body
end
def test_string_constraint
with_routing do |set|
set.draw do
- get "photos", :to => 'action_pack_assertions#nothing', :constraints => {:subdomain => "admin"}
+ get "photos", to: "action_pack_assertions#nothing", constraints: { subdomain: "admin" }
+ end
+ end
+ end
+
+ def test_with_routing_works_with_api_only_controllers
+ @controller = ApiOnlyController.new
+
+ with_routing do |set|
+ set.draw do
+ get "new_route", to: "api_only#nothing"
+ get "redirect_to_new_route", to: "api_only#redirect_to_new_route"
end
+
+ process :redirect_to_new_route
+ assert_redirected_to "http://test.host/new_route"
end
end
def test_assert_redirect_to_named_route_failure
with_routing do |set|
set.draw do
- get 'route_one', :to => 'action_pack_assertions#nothing', :as => :route_one
- get 'route_two', :to => 'action_pack_assertions#nothing', :id => 'two', :as => :route_two
- get ':controller/:action'
+ get "route_one", to: "action_pack_assertions#nothing", as: :route_one
+ get "route_two", to: "action_pack_assertions#nothing", id: "two", as: :route_two
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
process :redirect_to_named_route
assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_redirected_to 'http://test.host/route_two'
+ assert_redirected_to "http://test.host/route_two"
end
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to %r(^http://test.host/route_two)
end
assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_redirected_to :controller => 'action_pack_assertions', :action => 'nothing', :id => 'two'
+ assert_redirected_to controller: "action_pack_assertions", action: "nothing", id: "two"
end
assert_raise(ActiveSupport::TestCase::Assertion) do
assert_redirected_to route_two_url
@@ -200,8 +227,11 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
with_routing do |set|
set.draw do
- get 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module
- get ':controller/:action'
+ get "admin/inner_module", to: "admin/inner_module#index", as: :admin_inner_module
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
process :redirect_to_index
# redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}>
@@ -214,8 +244,11 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
with_routing do |set|
set.draw do
- get '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level
- get ':controller/:action'
+ get "/action_pack_assertions/:id", to: "action_pack_assertions#index", as: :top_level
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
process :redirect_to_top_level_named_route
# assert_redirected_to "http://test.host/action_pack_assertions/foo" would pass because of exact match early return
@@ -230,12 +263,15 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
with_routing do |set|
set.draw do
# this controller exists in the admin namespace as well which is the only difference from previous test
- get '/user/:id', :to => 'user#index', :as => :top_level
- get ':controller/:action'
+ get "/user/:id", to: "user#index", as: :top_level
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
process :redirect_to_top_level_named_route
# assert_redirected_to top_level_url('foo') would pass because of exact match early return
- assert_redirected_to top_level_path('foo')
+ assert_redirected_to top_level_path("foo")
end
end
@@ -247,57 +283,57 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
assert_no_match(
/#{request.protocol}#{request.host}\/\/www.rubyonrails.org/,
ex.message,
- 'protocol relative url was incorrectly normalized'
+ "protocol relative url was incorrectly normalized"
)
end
end
def test_template_objects_exist
process :assign_this
- assert !@controller.instance_variable_defined?(:"@hi")
+ assert_not @controller.instance_variable_defined?(:"@hi")
assert @controller.instance_variable_get(:"@howdy")
end
def test_template_objects_missing
process :nothing
- assert !@controller.instance_variable_defined?(:@howdy)
+ assert_not @controller.instance_variable_defined?(:@howdy)
end
def test_empty_flash
process :flash_me_naked
- assert flash.empty?
+ assert_empty flash
end
def test_flash_exist
process :flash_me
- assert flash.any?
- assert flash['hello'].present?
+ assert_predicate flash, :any?
+ assert_predicate flash["hello"], :present?
end
def test_flash_does_not_exist
process :nothing
- assert flash.empty?
+ assert_empty flash
end
def test_session_exist
process :session_stuffing
- assert_equal 'turkey', session['xmas']
+ assert_equal "turkey", session["xmas"]
end
def session_does_not_exist
process :nothing
- assert session.empty?
+ assert_empty session
end
def test_redirection_location
process :redirect_internal
- assert_equal 'http://test.host/nothing', @response.redirect_url
+ assert_equal "http://test.host/nothing", @response.redirect_url
process :redirect_external
- assert_equal 'http://www.rubyonrails.org', @response.redirect_url
+ assert_equal "http://www.rubyonrails.org", @response.redirect_url
process :redirect_external_protocol_relative
- assert_equal '//www.rubyonrails.org', @response.redirect_url
+ assert_equal "//www.rubyonrails.org", @response.redirect_url
end
def test_no_redirect_url
@@ -307,46 +343,46 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
def test_server_error_response_code
process :response500
- assert @response.server_error?
+ assert_predicate @response, :server_error?
process :response599
- assert @response.server_error?
+ assert_predicate @response, :server_error?
process :response404
- assert !@response.server_error?
+ assert_not_predicate @response, :server_error?
end
def test_missing_response_code
process :response404
- assert @response.not_found?
+ assert_predicate @response, :not_found?
end
def test_client_error_response_code
process :response404
- assert @response.client_error?
+ assert_predicate @response, :client_error?
end
def test_redirect_url_match
process :redirect_external
- assert @response.redirect?
+ assert_predicate @response, :redirect?
assert_match(/rubyonrails/, @response.redirect_url)
- assert !/perloffrails/.match(@response.redirect_url)
+ assert_no_match(/perloffrails/, @response.redirect_url)
end
def test_redirection
process :redirect_internal
- assert @response.redirect?
+ assert_predicate @response, :redirect?
process :redirect_external
- assert @response.redirect?
+ assert_predicate @response, :redirect?
process :nothing
- assert !@response.redirect?
+ assert_not_predicate @response, :redirect?
end
def test_successful_response_code
process :nothing
- assert @response.successful?
+ assert_predicate @response, :successful?
end
def test_response_object
@@ -364,24 +400,24 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
def test_assert_redirection_fails_with_incorrect_controller
process :redirect_to_controller
assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_redirected_to :controller => "action_pack_assertions", :action => "flash_me"
+ assert_redirected_to controller: "action_pack_assertions", action: "flash_me"
end
end
def test_assert_redirection_with_extra_controller_option
get :redirect_to_action
- assert_redirected_to :controller => 'action_pack_assertions', :action => "flash_me", :id => 1, :params => { :panda => 'fun' }
+ assert_redirected_to controller: "action_pack_assertions", action: "flash_me", id: 1, params: { panda: "fun" }
end
def test_redirected_to_url_leading_slash
process :redirect_to_path
- assert_redirected_to '/some/path'
+ assert_redirected_to "/some/path"
end
def test_redirected_to_url_no_leading_slash_fails
process :redirect_to_path
assert_raise ActiveSupport::TestCase::Assertion do
- assert_redirected_to 'some/path'
+ assert_redirected_to "some/path"
end
end
@@ -392,43 +428,43 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
def test_redirected_to_url_full_url
process :redirect_to_path
- assert_redirected_to 'http://test.host/some/path'
+ assert_redirected_to "http://test.host/some/path"
end
def test_assert_redirection_with_symbol
process :redirect_to_controller_with_symbol
assert_nothing_raised {
- assert_redirected_to :controller => "elsewhere", :action => "flash_me"
+ assert_redirected_to controller: "elsewhere", action: "flash_me"
}
process :redirect_to_controller_with_symbol
assert_nothing_raised {
- assert_redirected_to :controller => :elsewhere, :action => :flash_me
+ assert_redirected_to controller: :elsewhere, action: :flash_me
}
end
def test_redirected_to_with_nested_controller
@controller = Admin::InnerModuleController.new
get :redirect_to_absolute_controller
- assert_redirected_to :controller => '/content'
+ assert_redirected_to controller: "/content"
get :redirect_to_fellow_controller
- assert_redirected_to :controller => 'admin/user'
+ assert_redirected_to controller: "admin/user"
end
def test_assert_response_uses_exception_message
@controller = AssertResponseWithUnexpectedErrorController.new
- e = assert_raise RuntimeError, 'Expected non-success response' do
+ e = assert_raise RuntimeError, "Expected non-success response" do
get :index
end
assert_response :success
- assert_includes 'FAIL', e.message
+ assert_includes "FAIL", e.message
end
def test_assert_response_failure_response_with_no_exception
@controller = AssertResponseWithUnexpectedErrorController.new
get :show
assert_response 500
- assert_equal 'Boom', response.body
+ assert_equal "Boom", response.body
end
end
@@ -437,21 +473,21 @@ class ActionPackHeaderTest < ActionController::TestCase
def test_rendering_xml_sets_content_type
process :hello_xml_world
- assert_equal('application/xml; charset=utf-8', @response.headers['Content-Type'])
+ assert_equal("application/xml; charset=utf-8", @response.headers["Content-Type"])
end
def test_rendering_xml_respects_content_type
process :hello_xml_world_pdf
- assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
+ assert_equal("application/pdf; charset=utf-8", @response.headers["Content-Type"])
end
def test_rendering_xml_respects_content_type_when_set_in_the_header
process :hello_xml_world_pdf_header
- assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
+ assert_equal("application/pdf; charset=utf-8", @response.headers["Content-Type"])
end
def test_render_text_with_custom_content_type
get :render_text_with_custom_content_type
- assert_equal 'application/rss+xml; charset=utf-8', @response.headers['Content-Type']
+ assert_equal "application/rss+xml; charset=utf-8", @response.headers["Content-Type"]
end
end
diff --git a/actionpack/test/controller/api/conditional_get_test.rb b/actionpack/test/controller/api/conditional_get_test.rb
index b4f1673be0..e366ce9532 100644
--- a/actionpack/test/controller/api/conditional_get_test.rb
+++ b/actionpack/test/controller/api/conditional_get_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'active_support/core_ext/integer/time'
-require 'active_support/core_ext/numeric/time'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/core_ext/integer/time"
+require "active_support/core_ext/numeric/time"
class ConditionalGetApiController < ActionController::API
before_action :handle_last_modified_and_etags, only: :two
@@ -17,9 +19,9 @@ class ConditionalGetApiController < ActionController::API
private
- def handle_last_modified_and_etags
- fresh_when(last_modified: Time.now.utc.beginning_of_day, etag: [ :foo, 123 ])
- end
+ def handle_last_modified_and_etags
+ fresh_when(last_modified: Time.now.utc.beginning_of_day, etag: [ :foo, 123 ])
+ end
end
class ConditionalGetApiTest < ActionController::TestCase
@@ -31,7 +33,7 @@ class ConditionalGetApiTest < ActionController::TestCase
def test_request_gets_last_modified
get :two
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
assert_response :success
end
@@ -51,7 +53,7 @@ class ConditionalGetApiTest < ActionController::TestCase
@request.if_modified_since = @last_modified
get :one
assert_equal 304, @response.status.to_i
- assert @response.body.blank?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :blank?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
end
diff --git a/actionpack/test/controller/api/data_streaming_test.rb b/actionpack/test/controller/api/data_streaming_test.rb
index 0e7d97d1f4..6446ff9e40 100644
--- a/actionpack/test/controller/api/data_streaming_test.rb
+++ b/actionpack/test/controller/api/data_streaming_test.rb
@@ -1,8 +1,10 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module TestApiFileUtils
- def file_path() File.expand_path(__FILE__) end
- def file_data() @data ||= File.open(file_path, 'rb') { |f| f.read } end
+ def file_path() __FILE__ end
+ def file_data() @data ||= File.open(file_path, "rb") { |f| f.read } end
end
class DataStreamingApiController < ActionController::API
@@ -19,7 +21,7 @@ class DataStreamingApiTest < ActionController::TestCase
tests DataStreamingApiController
def test_data
- response = process('two')
+ response = process("two")
assert_kind_of String, response.body
assert_equal file_data, response.body
end
diff --git a/actionpack/test/controller/api/force_ssl_test.rb b/actionpack/test/controller/api/force_ssl_test.rb
index 8578340d82..8191578eb0 100644
--- a/actionpack/test/controller/api/force_ssl_test.rb
+++ b/actionpack/test/controller/api/force_ssl_test.rb
@@ -1,7 +1,11 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class ForceSSLApiController < ActionController::API
- force_ssl
+ ActiveSupport::Deprecation.silence do
+ force_ssl
+ end
def one; end
def two
diff --git a/actionpack/test/controller/api/implicit_render_test.rb b/actionpack/test/controller/api/implicit_render_test.rb
index 26f9cd8f78..288fb333b0 100644
--- a/actionpack/test/controller/api/implicit_render_test.rb
+++ b/actionpack/test/controller/api/implicit_render_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class ImplicitRenderAPITestController < ActionController::API
def empty_action
diff --git a/actionpack/test/controller/api/params_wrapper_test.rb b/actionpack/test/controller/api/params_wrapper_test.rb
index 53b3a0c3cc..814c24bfd8 100644
--- a/actionpack/test/controller/api/params_wrapper_test.rb
+++ b/actionpack/test/controller/api/params_wrapper_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class ParamsWrapperForApiTest < ActionController::TestCase
class UsersController < ActionController::API
@@ -17,10 +19,10 @@ class ParamsWrapperForApiTest < ActionController::TestCase
tests UsersController
def test_specify_wrapper_name
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :test, params: { 'username' => 'sikachu' }
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :test, params: { "username" => "sikachu" }
- expected = { 'username' => 'sikachu', 'person' => { 'username' => 'sikachu' }}
+ expected = { "username" => "sikachu", "person" => { "username" => "sikachu" } }
assert_equal expected, @controller.last_parameters
end
end
diff --git a/actionpack/test/controller/api/redirect_to_test.rb b/actionpack/test/controller/api/redirect_to_test.rb
index 18877c4b3a..f8230dd6a9 100644
--- a/actionpack/test/controller/api/redirect_to_test.rb
+++ b/actionpack/test/controller/api/redirect_to_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class RedirectToApiController < ActionController::API
def one
diff --git a/actionpack/test/controller/api/renderers_test.rb b/actionpack/test/controller/api/renderers_test.rb
index 9405538833..e7a9a4b2da 100644
--- a/actionpack/test/controller/api/renderers_test.rb
+++ b/actionpack/test/controller/api/renderers_test.rb
@@ -1,14 +1,16 @@
-require 'abstract_unit'
-require 'active_support/core_ext/hash/conversions'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/core_ext/hash/conversions"
class RenderersApiController < ActionController::API
class Model
def to_json(options = {})
- { a: 'b' }.to_json(options)
+ { a: "b" }.to_json(options)
end
def to_xml(options = {})
- { a: 'b' }.to_xml(options)
+ { a: "b" }.to_xml(options)
end
end
@@ -19,6 +21,10 @@ class RenderersApiController < ActionController::API
def two
render xml: Model.new
end
+
+ def plain
+ render plain: "Hi from plain", status: 500
+ end
end
class RenderersApiTest < ActionController::TestCase
@@ -27,12 +33,18 @@ class RenderersApiTest < ActionController::TestCase
def test_render_json
get :one
assert_response :success
- assert_equal({ a: 'b' }.to_json, @response.body)
+ assert_equal({ a: "b" }.to_json, @response.body)
end
def test_render_xml
get :two
assert_response :success
- assert_equal({ a: 'b' }.to_xml, @response.body)
+ assert_equal({ a: "b" }.to_xml, @response.body)
+ end
+
+ def test_render_plain
+ get :plain
+ assert_response :internal_server_error
+ assert_equal("Hi from plain", @response.body)
end
end
diff --git a/actionpack/test/controller/api/url_for_test.rb b/actionpack/test/controller/api/url_for_test.rb
index 0d8691a091..aa3428bc85 100644
--- a/actionpack/test/controller/api/url_for_test.rb
+++ b/actionpack/test/controller/api/url_for_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class UrlForApiController < ActionController::API
def one; end
@@ -10,7 +12,7 @@ class UrlForApiTest < ActionController::TestCase
def setup
super
- @request.host = 'www.example.com'
+ @request.host = "www.example.com"
end
def test_url_for
diff --git a/actionpack/test/controller/api/with_cookies_test.rb b/actionpack/test/controller/api/with_cookies_test.rb
new file mode 100644
index 0000000000..1a6e12a4f3
--- /dev/null
+++ b/actionpack/test/controller/api/with_cookies_test.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class WithCookiesController < ActionController::API
+ include ActionController::Cookies
+
+ def with_cookies
+ render plain: cookies[:foobar]
+ end
+end
+
+class WithCookiesTest < ActionController::TestCase
+ tests WithCookiesController
+
+ def test_with_cookies
+ request.cookies[:foobar] = "bazbang"
+
+ get :with_cookies
+
+ assert_equal "bazbang", response.body
+ end
+end
diff --git a/actionpack/test/controller/api/with_helpers_test.rb b/actionpack/test/controller/api/with_helpers_test.rb
new file mode 100644
index 0000000000..00179d3505
--- /dev/null
+++ b/actionpack/test/controller/api/with_helpers_test.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+module ApiWithHelper
+ def my_helper
+ "helper"
+ end
+end
+
+class WithHelpersController < ActionController::API
+ include ActionController::Helpers
+ helper ApiWithHelper
+
+ def with_helpers
+ render plain: self.class.helpers.my_helper
+ end
+end
+
+class SubclassWithHelpersController < WithHelpersController
+ def with_helpers
+ render plain: self.class.helpers.my_helper
+ end
+end
+
+class WithHelpersTest < ActionController::TestCase
+ tests WithHelpersController
+
+ def test_with_helpers
+ get :with_helpers
+
+ assert_equal "helper", response.body
+ end
+end
+
+class SubclassWithHelpersTest < ActionController::TestCase
+ tests WithHelpersController
+
+ def test_with_helpers
+ get :with_helpers
+
+ assert_equal "helper", response.body
+ end
+end
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index e3f669dbb5..558e710df9 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'active_support/logger'
-require 'controller/fake_models'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/logger"
+require "controller/fake_models"
# Provide some controller to run the tests on.
module Submodule
@@ -11,6 +13,12 @@ end
class EmptyController < ActionController::Base
end
+class SimpleController < ActionController::Base
+ def hello
+ self.response_body = "hello"
+ end
+end
+
class NonEmptyController < ActionController::Base
def public_action
head :ok
@@ -19,11 +27,11 @@ end
class DefaultUrlOptionsController < ActionController::Base
def from_view
- render :inline => "<%= #{params[:route]} %>"
+ render inline: "<%= #{params[:route]} %>"
end
def default_url_options
- { :host => 'www.override.com', :action => 'new', :locale => 'en' }
+ { host: "www.override.com", action: "new", locale: "en" }
end
end
@@ -33,17 +41,17 @@ class OptionalDefaultUrlOptionsController < ActionController::Base
end
def default_url_options
- { format: 'atom', id: 'default-id' }
+ { format: "atom", id: "default-id" }
end
end
class UrlOptionsController < ActionController::Base
def from_view
- render :inline => "<%= #{params[:route]} %>"
+ render inline: "<%= #{params[:route]} %>"
end
def url_options
- super.merge(:host => 'www.override.com')
+ super.merge(host: "www.override.com")
end
end
@@ -58,17 +66,16 @@ class ActionMissingController < ActionController::Base
end
class ControllerClassTests < ActiveSupport::TestCase
-
def test_controller_path
- assert_equal 'empty', EmptyController.controller_path
+ assert_equal "empty", EmptyController.controller_path
assert_equal EmptyController.controller_path, EmptyController.new.controller_path
- assert_equal 'submodule/contained_empty', Submodule::ContainedEmptyController.controller_path
+ assert_equal "submodule/contained_empty", Submodule::ContainedEmptyController.controller_path
assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path
end
def test_controller_name
- assert_equal 'empty', EmptyController.controller_name
- assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name
+ assert_equal "empty", EmptyController.controller_name
+ assert_equal "contained_empty", Submodule::ContainedEmptyController.controller_name
end
def test_no_deprecation_when_action_view_record_identifier_is_included
@@ -80,13 +87,13 @@ class ControllerClassTests < ActiveSupport::TestCase
dom_id = RecordIdentifierIncludedController.new.dom_id(record)
end
- assert_equal 'comment_1', dom_id
+ assert_equal "comment_1", dom_id
dom_class = nil
assert_not_deprecated do
dom_class = RecordIdentifierIncludedController.new.dom_class(record)
end
- assert_equal 'comment', dom_class
+ assert_equal "comment", dom_class
end
end
@@ -100,9 +107,9 @@ class ControllerInstanceTests < ActiveSupport::TestCase
end
def test_performed?
- assert !@empty.performed?
+ assert_not_predicate @empty, :performed?
@empty.response_body = ["sweet"]
- assert @empty.performed?
+ assert_predicate @empty, :performed?
end
def test_action_methods
@@ -112,13 +119,34 @@ class ControllerInstanceTests < ActiveSupport::TestCase
end
def test_temporary_anonymous_controllers
- name = 'ExamplesController'
+ name = "ExamplesController"
klass = Class.new(ActionController::Base)
Object.const_set(name, klass)
controller = klass.new
assert_equal "examples", controller.controller_path
end
+
+ def test_response_has_default_headers
+ original_default_headers = ActionDispatch::Response.default_headers
+
+ ActionDispatch::Response.default_headers = {
+ "X-Frame-Options" => "DENY",
+ "X-Content-Type-Options" => "nosniff",
+ "X-XSS-Protection" => "1;"
+ }
+
+ response_headers = SimpleController.action("hello").call(
+ "REQUEST_METHOD" => "GET",
+ "rack.input" => -> { }
+ )[1]
+
+ assert response_headers.key?("X-Frame-Options")
+ assert response_headers.key?("X-Content-Type-Options")
+ assert response_headers.key?("X-XSS-Protection")
+ ensure
+ ActionDispatch::Response.default_headers = original_default_headers
+ end
end
class PerformActionTest < ActionController::TestCase
@@ -152,37 +180,40 @@ class UrlOptionsTest < ActionController::TestCase
def setup
super
- @request.host = 'www.example.com'
+ @request.host = "www.example.com"
end
def test_url_for_query_params_included
rs = ActionDispatch::Routing::RouteSet.new
rs.draw do
- get 'home' => 'pages#home'
+ get "home" => "pages#home"
end
options = {
- :action => "home",
- :controller => "pages",
- :only_path => true,
- :params => { "token" => "secret" }
+ action: "home",
+ controller: "pages",
+ only_path: true,
+ token: "secret"
}
- assert_equal '/home?token=secret', rs.url_for(options)
+ assert_equal "/home?token=secret", rs.url_for(options)
end
def test_url_options_override
with_routing do |set|
set.draw do
- get 'from_view', :to => 'url_options#from_view', :as => :from_view
- get ':controller/:action'
+ get "from_view", to: "url_options#from_view", as: :from_view
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :from_view, params: { route: "from_view_url" }
- assert_equal 'http://www.override.com/from_view', @response.body
- assert_equal 'http://www.override.com/from_view', @controller.send(:from_view_url)
- assert_equal 'http://www.override.com/default_url_options/index', @controller.url_for(:controller => 'default_url_options')
+ assert_equal "http://www.override.com/from_view", @response.body
+ assert_equal "http://www.override.com/from_view", @controller.send(:from_view_url)
+ assert_equal "http://www.override.com/default_url_options/index", @controller.url_for(controller: "default_url_options")
end
end
@@ -192,7 +223,7 @@ class UrlOptionsTest < ActionController::TestCase
get "account/overview"
end
- assert !@controller.class.action_methods.include?("account_overview_path")
+ assert_not_includes @controller.class.action_methods, "account_overview_path"
end
end
end
@@ -202,21 +233,24 @@ class DefaultUrlOptionsTest < ActionController::TestCase
def setup
super
- @request.host = 'www.example.com'
+ @request.host = "www.example.com"
end
def test_default_url_options_override
with_routing do |set|
set.draw do
- get 'from_view', :to => 'default_url_options#from_view', :as => :from_view
- get ':controller/:action'
+ get "from_view", to: "default_url_options#from_view", as: :from_view
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :from_view, params: { route: "from_view_url" }
- assert_equal 'http://www.override.com/from_view?locale=en', @response.body
- assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url)
- assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options')
+ assert_equal "http://www.override.com/from_view?locale=en", @response.body
+ assert_equal "http://www.override.com/from_view?locale=en", @controller.send(:from_view_url)
+ assert_equal "http://www.override.com/default_url_options/new?locale=en", @controller.url_for(controller: "default_url_options")
end
end
@@ -226,22 +260,25 @@ class DefaultUrlOptionsTest < ActionController::TestCase
scope("/:locale") do
resources :descriptions
end
- get ':controller/:action'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :from_view, params: { route: "description_path(1)" }
- assert_equal '/en/descriptions/1', @response.body
- assert_equal '/en/descriptions', @controller.send(:descriptions_path)
- assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl")
- assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl")
- assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml")
- assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml")
- assert_equal '/en/descriptions/1', @controller.send(:description_path, 1)
- assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1)
- assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl")
- assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml")
- assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml")
+ assert_equal "/en/descriptions/1", @response.body
+ assert_equal "/en/descriptions", @controller.send(:descriptions_path)
+ assert_equal "/pl/descriptions", @controller.send(:descriptions_path, "pl")
+ assert_equal "/pl/descriptions", @controller.send(:descriptions_path, locale: "pl")
+ assert_equal "/pl/descriptions.xml", @controller.send(:descriptions_path, "pl", "xml")
+ assert_equal "/en/descriptions.xml", @controller.send(:descriptions_path, format: "xml")
+ assert_equal "/en/descriptions/1", @controller.send(:description_path, 1)
+ assert_equal "/pl/descriptions/1", @controller.send(:description_path, "pl", 1)
+ assert_equal "/pl/descriptions/1", @controller.send(:description_path, 1, locale: "pl")
+ assert_equal "/pl/descriptions/1.xml", @controller.send(:description_path, "pl", 1, "xml")
+ assert_equal "/en/descriptions/1.xml", @controller.send(:description_path, 1, format: "xml")
end
end
end
@@ -250,10 +287,10 @@ class OptionalDefaultUrlOptionsControllerTest < ActionController::TestCase
def test_default_url_options_override_missing_positional_arguments
with_routing do |set|
set.draw do
- get "/things/:id(.:format)" => 'things#show', :as => :thing
+ get "/things/:id(.:format)" => "things#show", :as => :thing
end
- assert_equal '/things/1.atom', thing_path('1')
- assert_equal '/things/default-id.atom', thing_path
+ assert_equal "/things/1.atom", thing_path("1")
+ assert_equal "/things/default-id.atom", thing_path
end
end
end
@@ -263,7 +300,7 @@ class EmptyUrlOptionsTest < ActionController::TestCase
def setup
super
- @request.host = 'www.example.com'
+ @request.host = "www.example.com"
end
def test_ensure_url_for_works_as_expected_when_called_with_no_options_if_default_url_options_is_not_set
@@ -280,7 +317,7 @@ class EmptyUrlOptionsTest < ActionController::TestCase
resources :things
end
- assert_equal '/things', @controller.send(:things_path)
+ assert_equal "/things", @controller.send(:things_path)
end
end
end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index bc0ffd3eaa..6fe036dd15 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -1,10 +1,12 @@
-require 'fileutils'
-require 'abstract_unit'
-require 'lib/controller/fake_models'
+# frozen_string_literal: true
-CACHE_DIR = 'test_cache'
+require "fileutils"
+require "abstract_unit"
+require "lib/controller/fake_models"
+
+CACHE_DIR = "test_cache"
# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
-FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
+FILE_STORE_PATH = File.join(__dir__, "../temp/", CACHE_DIR)
class FragmentCachingMetalTestController < ActionController::Metal
abstract!
@@ -21,15 +23,11 @@ class FragmentCachingMetalTest < ActionController::TestCase
@controller = FragmentCachingMetalTestController.new
@controller.perform_caching = true
@controller.cache_store = @store
- @params = { controller: 'posts', action: 'index' }
+ @params = { controller: "posts", action: "index" }
@controller.params = @params
@controller.request = @request
@controller.response = @response
end
-
- def test_fragment_cache_key
- assert_equal 'views/what a key', @controller.fragment_cache_key('what a key')
- end
end
class CachingController < ActionController::Base
@@ -43,104 +41,125 @@ class FragmentCachingTestController < CachingController
end
class FragmentCachingTest < ActionController::TestCase
+ ModelWithKeyAndVersion = Struct.new(:cache_key, :cache_version)
+
def setup
super
@store = ActiveSupport::Cache::MemoryStore.new
@controller = FragmentCachingTestController.new
@controller.perform_caching = true
@controller.cache_store = @store
- @params = {:controller => 'posts', :action => 'index'}
+ @params = { controller: "posts", action: "index" }
@controller.params = @params
@controller.request = @request
@controller.response = @response
+
+ @m1v1 = ModelWithKeyAndVersion.new("model/1", "1")
+ @m1v2 = ModelWithKeyAndVersion.new("model/1", "2")
+ @m2v1 = ModelWithKeyAndVersion.new("model/2", "1")
+ @m2v2 = ModelWithKeyAndVersion.new("model/2", "2")
end
def test_fragment_cache_key
- assert_equal 'views/what a key', @controller.fragment_cache_key('what a key')
- assert_equal "views/test.host/fragment_caching_test/some_action",
- @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action')
+ assert_deprecated do
+ assert_equal "views/what a key", @controller.fragment_cache_key("what a key")
+ assert_equal "views/test.host/fragment_caching_test/some_action",
+ @controller.fragment_cache_key(controller: "fragment_caching_test", action: "some_action")
+ end
+ end
+
+ def test_combined_fragment_cache_key
+ assert_equal [ :views, "what a key" ], @controller.combined_fragment_cache_key("what a key")
+ assert_equal [ :views, "test.host/fragment_caching_test/some_action" ],
+ @controller.combined_fragment_cache_key(controller: "fragment_caching_test", action: "some_action")
end
def test_read_fragment_with_caching_enabled
- @store.write('views/name', 'value')
- assert_equal 'value', @controller.read_fragment('name')
+ @store.write("views/name", "value")
+ assert_equal "value", @controller.read_fragment("name")
end
def test_read_fragment_with_caching_disabled
@controller.perform_caching = false
- @store.write('views/name', 'value')
- assert_nil @controller.read_fragment('name')
+ @store.write("views/name", "value")
+ assert_nil @controller.read_fragment("name")
+ end
+
+ def test_read_fragment_with_versioned_model
+ @controller.write_fragment([ "stuff", @m1v1 ], "hello")
+ assert_equal "hello", @controller.read_fragment([ "stuff", @m1v1 ])
+ assert_nil @controller.read_fragment([ "stuff", @m1v2 ])
end
def test_fragment_exist_with_caching_enabled
- @store.write('views/name', 'value')
- assert @controller.fragment_exist?('name')
- assert !@controller.fragment_exist?('other_name')
+ @store.write("views/name", "value")
+ assert @controller.fragment_exist?("name")
+ assert_not @controller.fragment_exist?("other_name")
end
def test_fragment_exist_with_caching_disabled
@controller.perform_caching = false
- @store.write('views/name', 'value')
- assert !@controller.fragment_exist?('name')
- assert !@controller.fragment_exist?('other_name')
+ @store.write("views/name", "value")
+ assert_not @controller.fragment_exist?("name")
+ assert_not @controller.fragment_exist?("other_name")
end
def test_write_fragment_with_caching_enabled
- assert_nil @store.read('views/name')
- assert_equal 'value', @controller.write_fragment('name', 'value')
- assert_equal 'value', @store.read('views/name')
+ assert_nil @store.read("views/name")
+ assert_equal "value", @controller.write_fragment("name", "value")
+ assert_equal "value", @store.read("views/name")
end
def test_write_fragment_with_caching_disabled
- assert_nil @store.read('views/name')
+ assert_nil @store.read("views/name")
@controller.perform_caching = false
- assert_equal 'value', @controller.write_fragment('name', 'value')
- assert_nil @store.read('views/name')
+ assert_equal "value", @controller.write_fragment("name", "value")
+ assert_nil @store.read("views/name")
end
def test_expire_fragment_with_simple_key
- @store.write('views/name', 'value')
- @controller.expire_fragment 'name'
- assert_nil @store.read('views/name')
+ @store.write("views/name", "value")
+ @controller.expire_fragment "name"
+ assert_nil @store.read("views/name")
end
def test_expire_fragment_with_regexp
- @store.write('views/name', 'value')
- @store.write('views/another_name', 'another_value')
- @store.write('views/primalgrasp', 'will not expire ;-)')
+ @store.write("views/name", "value")
+ @store.write("views/another_name", "another_value")
+ @store.write("views/primalgrasp", "will not expire ;-)")
@controller.expire_fragment(/name/)
- assert_nil @store.read('views/name')
- assert_nil @store.read('views/another_name')
- assert_equal 'will not expire ;-)', @store.read('views/primalgrasp')
+ assert_nil @store.read("views/name")
+ assert_nil @store.read("views/another_name")
+ assert_equal "will not expire ;-)", @store.read("views/primalgrasp")
end
def test_fragment_for
- @store.write('views/expensive', 'fragment content')
+ @store.write("views/expensive", "fragment content")
fragment_computed = false
view_context = @controller.view_context
- buffer = 'generated till now -> '.html_safe
- buffer << view_context.send(:fragment_for, 'expensive') { fragment_computed = true }
+ buffer = "generated till now -> ".html_safe
+ buffer << view_context.send(:fragment_for, "expensive") { fragment_computed = true }
- assert !fragment_computed
- assert_equal 'generated till now -> fragment content', buffer
+ assert_not fragment_computed
+ assert_equal "generated till now -> fragment content", buffer
end
def test_html_safety
- assert_nil @store.read('views/name')
- content = 'value'.html_safe
- assert_equal content, @controller.write_fragment('name', content)
+ assert_nil @store.read("views/name")
+ content = "value".html_safe
+ assert_equal content, @controller.write_fragment("name", content)
- cached = @store.read('views/name')
+ cached = @store.read("views/name")
assert_equal content, cached
assert_equal String, cached.class
- html_safe = @controller.read_fragment('name')
+ html_safe = @controller.read_fragment("name")
assert_equal content, html_safe
- assert html_safe.html_safe?
+ assert_predicate html_safe, :html_safe?
end
end
@@ -154,6 +173,9 @@ class FunctionalCachingController < CachingController
end
end
+ def xml_fragment_cached_with_html_partial
+ end
+
def formatted_fragment_cached
respond_to do |format|
format.html
@@ -172,6 +194,9 @@ class FunctionalCachingController < CachingController
def fragment_cached_without_digest
end
+
+ def fragment_cached_with_options
+ end
end
class FunctionalFragmentCachingTest < ActionController::TestCase
@@ -181,6 +206,7 @@ class FunctionalFragmentCachingTest < ActionController::TestCase
@controller = FunctionalCachingController.new
@controller.perform_caching = true
@controller.cache_store = @store
+ @controller.enable_fragment_cache_logging = true
end
def test_fragment_caching
@@ -194,7 +220,7 @@ CACHED
assert_equal expected_body, @response.body
assert_equal "This bit's fragment cached",
- @store.read("views/test.host/functional_caching/fragment_cached/#{template_digest("functional_caching/fragment_cached")}")
+ @store.read("views/functional_caching/fragment_cached:#{template_digest("functional_caching/fragment_cached")}/fragment")
end
def test_fragment_caching_in_partials
@@ -203,7 +229,7 @@ CACHED
assert_match(/Old fragment caching in a partial/, @response.body)
assert_match("Old fragment caching in a partial",
- @store.read("views/test.host/functional_caching/html_fragment_cached_with_partial/#{template_digest("functional_caching/_partial")}"))
+ @store.read("views/functional_caching/_partial:#{template_digest("functional_caching/_partial")}/test.host/functional_caching/html_fragment_cached_with_partial"))
end
def test_skipping_fragment_cache_digesting
@@ -215,13 +241,25 @@ CACHED
assert_equal "<p>ERB</p>", @store.read("views/nodigest")
end
+ def test_fragment_caching_with_options
+ time = Time.now
+ get :fragment_cached_with_options
+ assert_response :success
+ expected_body = "<body>\n<p>ERB</p>\n</body>\n"
+
+ assert_equal expected_body, @response.body
+ Time.stub(:now, time + 11) do
+ assert_nil @store.read("views/with_options")
+ end
+ end
+
def test_render_inline_before_fragment_caching
get :inline_fragment_cached
assert_response :success
assert_match(/Some inline content/, @response.body)
assert_match(/Some cached content/, @response.body)
assert_match("Some cached content",
- @store.read("views/test.host/functional_caching/inline_fragment_cached/#{template_digest("functional_caching/inline_fragment_cached")}"))
+ @store.read("views/functional_caching/inline_fragment_cached:#{template_digest("functional_caching/inline_fragment_cached")}/test.host/functional_caching/inline_fragment_cached"))
end
def test_fragment_cache_instrumentation
@@ -248,7 +286,7 @@ CACHED
assert_equal expected_body, @response.body
assert_equal "<p>ERB</p>",
- @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached")}")
+ @store.read("views/functional_caching/formatted_fragment_cached:#{template_digest("functional_caching/formatted_fragment_cached")}/fragment")
end
def test_xml_formatted_fragment_caching
@@ -259,10 +297,9 @@ CACHED
assert_equal expected_body, @response.body
assert_equal " <p>Builder</p>\n",
- @store.read("views/test.host/functional_caching/formatted_fragment_cached/#{template_digest("functional_caching/formatted_fragment_cached")}")
+ @store.read("views/functional_caching/formatted_fragment_cached:#{template_digest("functional_caching/formatted_fragment_cached")}/fragment")
end
-
def test_fragment_caching_with_variant
get :formatted_fragment_cached_with_variant, format: "html", params: { v: :phone }
assert_response :success
@@ -271,7 +308,12 @@ CACHED
assert_equal expected_body, @response.body
assert_equal "<p>PHONE</p>",
- @store.read("views/test.host/functional_caching/formatted_fragment_cached_with_variant/#{template_digest("functional_caching/formatted_fragment_cached_with_variant")}")
+ @store.read("views/functional_caching/formatted_fragment_cached_with_variant:#{template_digest("functional_caching/formatted_fragment_cached_with_variant")}/fragment")
+ end
+
+ def test_fragment_caching_with_html_partials_in_xml
+ get :xml_fragment_cached_with_html_partial, format: "*/*"
+ assert_response :success
end
private
@@ -281,10 +323,9 @@ CACHED
end
class CacheHelperOutputBufferTest < ActionController::TestCase
-
class MockController
def read_fragment(name, options)
- return false
+ false
end
def write_fragment(name, fragment, options)
@@ -300,9 +341,9 @@ class CacheHelperOutputBufferTest < ActionController::TestCase
output_buffer = ActionView::OutputBuffer.new
controller = MockController.new
cache_helper = Class.new do
- def self.controller; end;
- def self.output_buffer; end;
- def self.output_buffer=; end;
+ def self.controller; end
+ def self.output_buffer; end
+ def self.output_buffer=; end
end
cache_helper.extend(ActionView::Helpers::CacheHelper)
@@ -310,7 +351,7 @@ class CacheHelperOutputBufferTest < ActionController::TestCase
cache_helper.stub :output_buffer, output_buffer do
assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do
assert_nothing_raised do
- cache_helper.send :fragment_for, 'Test fragment name', 'Test fragment', &Proc.new{ nil }
+ cache_helper.send :fragment_for, "Test fragment name", "Test fragment", &Proc.new { nil }
end
end
end
@@ -321,9 +362,9 @@ class CacheHelperOutputBufferTest < ActionController::TestCase
output_buffer = ActiveSupport::SafeBuffer.new
controller = MockController.new
cache_helper = Class.new do
- def self.controller; end;
- def self.output_buffer; end;
- def self.output_buffer=; end;
+ def self.controller; end
+ def self.output_buffer; end
+ def self.output_buffer=; end
end
cache_helper.extend(ActionView::Helpers::CacheHelper)
@@ -331,7 +372,7 @@ class CacheHelperOutputBufferTest < ActionController::TestCase
cache_helper.stub :output_buffer, output_buffer do
assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do
assert_nothing_raised do
- cache_helper.send :fragment_for, 'Test fragment name', 'Test fragment', &Proc.new{ nil }
+ cache_helper.send :fragment_for, "Test fragment name", "Test fragment", &Proc.new { nil }
end
end
end
@@ -349,7 +390,7 @@ class ViewCacheDependencyTest < ActionController::TestCase
end
def test_view_cache_dependencies_are_empty_by_default
- assert NoDependenciesController.new.view_cache_dependencies.empty?
+ assert_empty NoDependenciesController.new.view_cache_dependencies
end
def test_view_cache_dependencies_are_listed_in_declaration_order
@@ -361,38 +402,44 @@ class CollectionCacheController < ActionController::Base
attr_accessor :partial_rendered_times
def index
- @customers = [Customer.new('david', params[:id] || 1)]
+ @customers = [Customer.new("david", params[:id] || 1)]
end
def index_ordered
- @customers = [Customer.new('david', 1), Customer.new('david', 2), Customer.new('david', 3)]
- render 'index'
+ @customers = [Customer.new("david", 1), Customer.new("david", 2), Customer.new("david", 3)]
+ render "index"
end
- def index_explicit_render
- @customers = [Customer.new('david', 1)]
- render partial: 'customers/customer', collection: @customers
+ def index_explicit_render_in_controller
+ @customers = [Customer.new("david", 1)]
+ render partial: "customers/customer", collection: @customers, cached: true
end
def index_with_comment
- @customers = [Customer.new('david', 1)]
- render partial: 'customers/commented_customer', collection: @customers, as: :customer
+ @customers = [Customer.new("david", 1)]
+ render partial: "customers/commented_customer", collection: @customers, as: :customer, cached: true
+ end
+
+ def index_with_callable_cache_key
+ @customers = [Customer.new("david", 1)]
+ render partial: "customers/customer", collection: @customers, cached: -> customer { "cached_david" }
end
end
-class AutomaticCollectionCacheTest < ActionController::TestCase
+class CollectionCacheTest < ActionController::TestCase
def setup
super
@controller = CollectionCacheController.new
@controller.perform_caching = true
@controller.partial_rendered_times = 0
@controller.cache_store = ActiveSupport::Cache::MemoryStore.new
- ActionView::PartialRenderer.collection_cache = @controller.cache_store
+ ActionView::PartialRenderer.collection_cache = ActiveSupport::Cache::MemoryStore.new
end
def test_collection_fetches_cached_views
get :index
assert_equal 1, @controller.partial_rendered_times
+ assert_match "david, 1", ActionView::PartialRenderer.collection_cache.read("views/customers/_customer:7c228ab609f0baf0b1f2367469210937/david/1")
get :index
assert_equal 1, @controller.partial_rendered_times
@@ -400,15 +447,18 @@ class AutomaticCollectionCacheTest < ActionController::TestCase
def test_preserves_order_when_reading_from_cache_plus_rendering
get :index, params: { id: 2 }
- get :index_ordered
+ assert_equal 1, @controller.partial_rendered_times
+ assert_select ":root", "david, 2"
- assert_select ':root', "david, 1\n david, 2\n david, 3"
+ get :index_ordered
+ assert_equal 3, @controller.partial_rendered_times
+ assert_select ":root", "david, 1\n david, 2\n david, 3"
end
def test_explicit_render_call_with_options
- get :index_explicit_render
+ get :index_explicit_render_in_controller
- assert_select ':root', "david, 1"
+ assert_select ":root", "david, 1"
end
def test_caching_works_with_beginning_comment
@@ -418,4 +468,44 @@ class AutomaticCollectionCacheTest < ActionController::TestCase
get :index_with_comment
assert_equal 1, @controller.partial_rendered_times
end
+
+ def test_caching_with_callable_cache_key
+ get :index_with_callable_cache_key
+ assert_match "david, 1", ActionView::PartialRenderer.collection_cache.read("views/customers/_customer:7c228ab609f0baf0b1f2367469210937/cached_david")
+ end
+end
+
+class FragmentCacheKeyTestController < CachingController
+ attr_accessor :account_id
+
+ fragment_cache_key "v1"
+ fragment_cache_key { account_id }
+end
+
+class FragmentCacheKeyTest < ActionController::TestCase
+ def setup
+ super
+ @store = ActiveSupport::Cache::MemoryStore.new
+ @controller = FragmentCacheKeyTestController.new
+ @controller.perform_caching = true
+ @controller.cache_store = @store
+ end
+
+ def test_combined_fragment_cache_key
+ @controller.account_id = "123"
+ assert_equal [ :views, "v1", "123", "what a key" ], @controller.combined_fragment_cache_key("what a key")
+
+ @controller.account_id = nil
+ assert_equal [ :views, "v1", "what a key" ], @controller.combined_fragment_cache_key("what a key")
+ end
+
+ def test_combined_fragment_cache_key_with_envs
+ ENV["RAILS_APP_VERSION"] = "55"
+ assert_equal [ :views, "55", "v1", "what a key" ], @controller.combined_fragment_cache_key("what a key")
+
+ ENV["RAILS_CACHE_ID"] = "66"
+ assert_equal [ :views, "66", "v1", "what a key" ], @controller.combined_fragment_cache_key("what a key")
+ ensure
+ ENV["RAILS_CACHE_ID"] = ENV["RAILS_APP_VERSION"] = nil
+ end
end
diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb
index c02607b55e..636b025f2c 100644
--- a/actionpack/test/controller/content_type_test.rb
+++ b/actionpack/test/controller/content_type_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class OldContentTypeController < ActionController::Base
# :ported:
@@ -14,7 +16,7 @@ class OldContentTypeController < ActionController::Base
# :ported:
def render_content_type_from_render
- render body: "hello world!", :content_type => Mime[:rss]
+ render body: "hello world!", content_type: Mime[:rss]
end
# :ported:
@@ -37,7 +39,7 @@ class OldContentTypeController < ActionController::Base
def render_change_for_builder
response.content_type = Mime[:html]
- render :action => "render_default_for_builder"
+ render action: "render_default_for_builder"
end
def render_default_content_types_for_respond_to
@@ -131,13 +133,13 @@ class ContentTypeTest < ActionController::TestCase
private
- def with_default_charset(charset)
- old_default_charset = ActionDispatch::Response.default_charset
- ActionDispatch::Response.default_charset = charset
- yield
- ensure
- ActionDispatch::Response.default_charset = old_default_charset
- end
+ def with_default_charset(charset)
+ old_default_charset = ActionDispatch::Response.default_charset
+ ActionDispatch::Response.default_charset = charset
+ yield
+ ensure
+ ActionDispatch::Response.default_charset = old_default_charset
+ end
end
class AcceptBasedContentTypeTest < ActionController::TestCase
diff --git a/actionpack/test/controller/default_url_options_with_before_action_test.rb b/actionpack/test/controller/default_url_options_with_before_action_test.rb
index 12fbe0424e..fc5b8288cd 100644
--- a/actionpack/test/controller/default_url_options_with_before_action_test.rb
+++ b/actionpack/test/controller/default_url_options_with_before_action_test.rb
@@ -1,7 +1,8 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-class ControllerWithBeforeActionAndDefaultUrlOptions < ActionController::Base
+require "abstract_unit"
+class ControllerWithBeforeActionAndDefaultUrlOptions < ActionController::Base
before_action { I18n.locale = params[:locale] }
after_action { I18n.locale = "en" }
@@ -10,16 +11,15 @@ class ControllerWithBeforeActionAndDefaultUrlOptions < ActionController::Base
end
def redirect
- redirect_to :action => "target"
+ redirect_to action: "target"
end
def default_url_options
- {:locale => "de"}
+ { locale: "de" }
end
end
class ControllerWithBeforeActionAndDefaultUrlOptionsTest < ActionController::TestCase
-
# This test has its roots in issue #1872
test "should redirect with correct locale :de" do
get :redirect, params: { locale: "de" }
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index 08271012e9..425a6e25cc 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -1,8 +1,10 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class ActionController::Base
class << self
- %w(append_around_action prepend_after_action prepend_around_action prepend_before_action skip_after_action skip_before_action skip_action_callback).each do |pending|
+ %w(append_around_action prepend_after_action prepend_around_action prepend_before_action skip_after_action skip_before_action).each do |pending|
define_method(pending) do |*args|
$stderr.puts "#{pending} unimplemented: #{args.inspect}"
end unless method_defined?(pending)
@@ -21,7 +23,7 @@ class FilterTest < ActionController::TestCase
after_action :clean_up
def show
- render :inline => "ran action"
+ render inline: "ran action"
end
private
@@ -37,7 +39,7 @@ class FilterTest < ActionController::TestCase
end
class ChangingTheRequirementsController < TestController
- before_action :ensure_login, :except => [:go_wild]
+ before_action :ensure_login, except: [:go_wild]
def go_wild
render plain: "gobble"
@@ -55,15 +57,15 @@ class FilterTest < ActionController::TestCase
end
end
- protected
- (1..3).each do |i|
- define_method "try_#{i}" do
- instance_variable_set :@try, i
- if action_name == "fail_#{i}"
- head(404)
+ private
+ (1..3).each do |i|
+ define_method "try_#{i}" do
+ instance_variable_set :@try, i
+ if action_name == "fail_#{i}"
+ head(404)
+ end
end
end
- end
end
class RenderingController < ActionController::Base
@@ -72,14 +74,14 @@ class FilterTest < ActionController::TestCase
def show
@ran_action = true
- render :inline => "ran action"
+ render inline: "ran action"
end
private
def before_action_rendering
@ran_filter ||= []
@ran_filter << "before_action_rendering"
- render :inline => "something else"
+ render inline: "something else"
end
def unreached_after_action
@@ -102,19 +104,19 @@ class FilterTest < ActionController::TestCase
def show
@ran_action = true
- render :inline => "ran show action"
+ render inline: "ran show action"
end
def target_of_redirection
@ran_target_of_redirection = true
- render :inline => "ran target_of_redirection action"
+ render inline: "ran target_of_redirection action"
end
private
def before_action_redirects
@ran_filter ||= []
@ran_filter << "before_action_redirects"
- redirect_to(:action => 'target_of_redirection')
+ redirect_to(action: "target_of_redirection")
end
def unreached_after_action
@@ -133,15 +135,15 @@ class FilterTest < ActionController::TestCase
class ConditionalFilterController < ActionController::Base
def show
- render :inline => "ran action"
+ render inline: "ran action"
end
def another_action
- render :inline => "ran action"
+ render inline: "ran action"
end
def show_without_action
- render :inline => "ran action without action"
+ render inline: "ran action without action"
end
private
@@ -157,28 +159,28 @@ class FilterTest < ActionController::TestCase
end
class ConditionalCollectionFilterController < ConditionalFilterController
- before_action :ensure_login, :except => [ :show_without_action, :another_action ]
+ before_action :ensure_login, except: [ :show_without_action, :another_action ]
end
class OnlyConditionSymController < ConditionalFilterController
- before_action :ensure_login, :only => :show
+ before_action :ensure_login, only: :show
end
class ExceptConditionSymController < ConditionalFilterController
- before_action :ensure_login, :except => :show_without_action
+ before_action :ensure_login, except: :show_without_action
end
class BeforeAndAfterConditionController < ConditionalFilterController
- before_action :ensure_login, :only => :show
- after_action :clean_up_tmp, :only => :show
+ before_action :ensure_login, only: :show
+ after_action :clean_up_tmp, only: :show
end
class OnlyConditionProcController < ConditionalFilterController
- before_action(:only => :show) {|c| c.instance_variable_set(:"@ran_proc_action", true) }
+ before_action(only: :show) { |c| c.instance_variable_set(:"@ran_proc_action", true) }
end
class ExceptConditionProcController < ConditionalFilterController
- before_action(:except => :show_without_action) {|c| c.instance_variable_set(:"@ran_proc_action", true) }
+ before_action(except: :show_without_action) { |c| c.instance_variable_set(:"@ran_proc_action", true) }
end
class ConditionalClassFilter
@@ -186,24 +188,24 @@ class FilterTest < ActionController::TestCase
end
class OnlyConditionClassController < ConditionalFilterController
- before_action ConditionalClassFilter, :only => :show
+ before_action ConditionalClassFilter, only: :show
end
class ExceptConditionClassController < ConditionalFilterController
- before_action ConditionalClassFilter, :except => :show_without_action
+ before_action ConditionalClassFilter, except: :show_without_action
end
class AnomolousYetValidConditionController < ConditionalFilterController
- before_action(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:"@ran_proc_action1", true)}, :except => :show_without_action) { |c| c.instance_variable_set(:"@ran_proc_action2", true)}
+ before_action(ConditionalClassFilter, :ensure_login, Proc.new { |c| c.instance_variable_set(:"@ran_proc_action1", true) }, except: :show_without_action) { |c| c.instance_variable_set(:"@ran_proc_action2", true) }
end
class OnlyConditionalOptionsFilter < ConditionalFilterController
- before_action :ensure_login, :only => :index, :if => Proc.new {|c| c.instance_variable_set(:"@ran_conditional_index_proc", true) }
+ before_action :ensure_login, only: :index, if: Proc.new { |c| c.instance_variable_set(:"@ran_conditional_index_proc", true) }
end
class ConditionalOptionsFilter < ConditionalFilterController
- before_action :ensure_login, :if => Proc.new { |c| true }
- before_action :clean_up_tmp, :if => Proc.new { |c| false }
+ before_action :ensure_login, if: Proc.new { |c| true }
+ before_action :clean_up_tmp, if: Proc.new { |c| false }
end
class ConditionalOptionsSkipFilter < ConditionalFilterController
@@ -222,7 +224,7 @@ class FilterTest < ActionController::TestCase
skip_before_action :clean_up_tmp, only: :login, if: -> { true }
def login
- render plain: 'ok'
+ render plain: "ok"
end
end
@@ -234,7 +236,7 @@ class FilterTest < ActionController::TestCase
skip_before_action :clean_up_tmp, if: -> { true }, except: :login
def login
- render plain: 'ok'
+ render plain: "ok"
end
end
@@ -255,14 +257,14 @@ class FilterTest < ActionController::TestCase
class SkippingAndLimitedController < TestController
skip_before_action :ensure_login
- before_action :ensure_login, :only => :index
+ before_action :ensure_login, only: :index
def index
- render plain: 'ok'
+ render plain: "ok"
end
def public
- render plain: 'ok'
+ render plain: "ok"
end
end
@@ -272,7 +274,7 @@ class FilterTest < ActionController::TestCase
before_action :ensure_login
def index
- render plain: 'ok'
+ render plain: "ok"
end
private
@@ -283,20 +285,20 @@ class FilterTest < ActionController::TestCase
end
class ConditionalSkippingController < TestController
- skip_before_action :ensure_login, :only => [ :login ]
- skip_after_action :clean_up, :only => [ :login ]
+ skip_before_action :ensure_login, only: [ :login ]
+ skip_after_action :clean_up, only: [ :login ]
- before_action :find_user, :only => [ :change_password ]
+ before_action :find_user, only: [ :change_password ]
def login
- render :inline => "ran action"
+ render inline: "ran action"
end
def change_password
- render :inline => "ran action"
+ render inline: "ran action"
end
- protected
+ private
def find_user
@ran_filter ||= []
@ran_filter << "find_user"
@@ -304,29 +306,29 @@ class FilterTest < ActionController::TestCase
end
class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
- before_action :conditional_in_parent_before, :only => [:show, :another_action]
- after_action :conditional_in_parent_after, :only => [:show, :another_action]
+ before_action :conditional_in_parent_before, only: [:show, :another_action]
+ after_action :conditional_in_parent_after, only: [:show, :another_action]
private
def conditional_in_parent_before
@ran_filter ||= []
- @ran_filter << 'conditional_in_parent_before'
+ @ran_filter << "conditional_in_parent_before"
end
def conditional_in_parent_after
@ran_filter ||= []
- @ran_filter << 'conditional_in_parent_after'
+ @ran_filter << "conditional_in_parent_after"
end
end
class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
- skip_before_action :conditional_in_parent_before, :only => :another_action
- skip_after_action :conditional_in_parent_after, :only => :another_action
+ skip_before_action :conditional_in_parent_before, only: :another_action
+ skip_after_action :conditional_in_parent_after, only: :another_action
end
class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
- skip_before_action :conditional_in_parent_before, :only => :show
+ skip_before_action :conditional_in_parent_before, only: :show
end
class ProcController < PrependingController
@@ -346,7 +348,7 @@ class FilterTest < ActionController::TestCase
class AroundFilter
def before(controller)
@execution_log = "before"
- controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
+ controller.class.execution_log += " before aroundfilter " if controller.respond_to? :execution_log
controller.instance_variable_set(:"@before_ran", true)
end
@@ -418,17 +420,17 @@ class FilterTest < ActionController::TestCase
class OutOfOrder < StandardError; end
before_action :first
- before_action :second, :only => :foo
+ before_action :second, only: :foo
def foo
- render plain: 'foo'
+ render plain: "foo"
end
def bar
- render plain: 'bar'
+ render plain: "bar"
end
- protected
+ private
def first
@first = true
end
@@ -458,20 +460,20 @@ class FilterTest < ActionController::TestCase
def before_all
@ran_filter ||= []
- @ran_filter << 'before_all'
+ @ran_filter << "before_all"
end
def after_all
@ran_filter ||= []
- @ran_filter << 'after_all'
+ @ran_filter << "after_all"
end
def between_before_all_and_after_all
@ran_filter ||= []
- @ran_filter << 'between_before_all_and_after_all'
+ @ran_filter << "between_before_all_and_after_all"
end
def show
- render plain: 'hello'
+ render plain: "hello"
end
end
@@ -494,50 +496,48 @@ class FilterTest < ActionController::TestCase
end
class NonYieldingAroundFilterController < ActionController::Base
-
before_action :filter_one
around_action :non_yielding_action
before_action :action_two
after_action :action_three
def index
- render :inline => "index"
+ render inline: "index"
end
private
def filter_one
- @filters ||= []
- @filters << "filter_one"
+ @filters ||= []
+ @filters << "filter_one"
end
def action_two
- @filters << "action_two"
+ @filters << "action_two"
end
def non_yielding_action
- @filters << "it didn't yield"
+ @filters << "it didn't yield"
end
def action_three
- @filters << "action_three"
+ @filters << "action_three"
end
-
end
class ImplicitActionsController < ActionController::Base
- before_action :find_only, :only => :edit
- before_action :find_except, :except => :edit
+ before_action :find_only, only: :edit
+ before_action :find_except, except: :edit
private
- def find_only
- @only = 'Only'
- end
+ def find_only
+ @only = "Only"
+ end
- def find_except
- @except = 'Except'
- end
+ def find_except
+ @except = "Except"
+ end
end
def test_non_yielding_around_actions_do_not_raise
@@ -586,7 +586,7 @@ class FilterTest < ActionController::TestCase
assert @controller.instance_variable_get(:@was_audited)
end
- def test_running_anomolous_yet_valid_condition_actions
+ def test_running_anomalous_yet_valid_condition_actions
test_process(AnomolousYetValidConditionController)
assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
assert @controller.instance_variable_get(:@ran_class_action)
@@ -611,12 +611,12 @@ class FilterTest < ActionController::TestCase
end
def test_if_is_ignored_when_used_with_only
- test_process(SkipFilterUsingOnlyAndIf, 'login')
+ test_process(SkipFilterUsingOnlyAndIf, "login")
assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_except_is_ignored_when_used_with_if
- test_process(SkipFilterUsingIfAndExcept, 'login')
+ test_process(SkipFilterUsingIfAndExcept, "login")
assert_equal %w(ensure_login), @controller.instance_variable_get(:@ran_filter)
end
@@ -706,7 +706,7 @@ class FilterTest < ActionController::TestCase
def test_prepending_and_appending_around_action
test_process(MixedFilterController)
- assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " \
" after appended aroundfilter after procfilter after aroundfilter ",
MixedFilterController.execution_log
end
@@ -745,13 +745,13 @@ class FilterTest < ActionController::TestCase
def test_actions_with_mixed_specialization_run_in_order
assert_nothing_raised do
- response = test_process(MixedSpecializationController, 'bar')
- assert_equal 'bar', response.body
+ response = test_process(MixedSpecializationController, "bar")
+ assert_equal "bar", response.body
end
assert_nothing_raised do
- response = test_process(MixedSpecializationController, 'foo')
- assert_equal 'foo', response.body
+ response = test_process(MixedSpecializationController, "foo")
+ assert_equal "foo", response.body
end
end
@@ -787,7 +787,7 @@ class FilterTest < ActionController::TestCase
assert_equal %w( ensure_login find_user ), @controller.instance_variable_get(:@ran_filter)
test_process(ConditionalSkippingController, "login")
- assert !@controller.instance_variable_defined?("@ran_after_action")
+ assert_not @controller.instance_variable_defined?("@ran_after_action")
test_process(ConditionalSkippingController, "change_password")
assert_equal %w( clean_up ), @controller.instance_variable_get("@ran_after_action")
end
@@ -795,7 +795,7 @@ class FilterTest < ActionController::TestCase
def test_conditional_skipping_of_actions_when_parent_action_is_also_conditional
test_process(ChildOfConditionalParentController)
assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), @controller.instance_variable_get(:@ran_filter)
- test_process(ChildOfConditionalParentController, 'another_action')
+ test_process(ChildOfConditionalParentController, "another_action")
assert_not @controller.instance_variable_defined?(:@ran_filter)
end
@@ -819,20 +819,20 @@ class FilterTest < ActionController::TestCase
response = test_process(RescuedController)
end
- assert response.successful?
+ assert_predicate response, :successful?
assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
end
def test_actions_obey_only_and_except_for_implicit_actions
- test_process(ImplicitActionsController, 'show')
- assert_equal 'Except', @controller.instance_variable_get(:@except)
+ test_process(ImplicitActionsController, "show")
+ assert_equal "Except", @controller.instance_variable_get(:@except)
assert_not @controller.instance_variable_defined?(:@only)
- assert_equal 'show', response.body
+ assert_equal "show", response.body
- test_process(ImplicitActionsController, 'edit')
- assert_equal 'Only', @controller.instance_variable_get(:@only)
+ test_process(ImplicitActionsController, "edit")
+ assert_equal "Only", @controller.instance_variable_get(:@only)
assert_not @controller.instance_variable_defined?(:@except)
- assert_equal 'edit', response.body
+ assert_equal "edit", response.body
end
private
@@ -859,14 +859,14 @@ class PostsController < ActionController::Base
private
def default_action
- render :inline => "#{action_name} called"
+ render inline: "#{action_name} called"
end
end
class ControllerWithSymbolAsFilter < PostsController
- around_action :raise_before, :only => :raises_before
- around_action :raise_after, :only => :raises_after
- around_action :without_exception, :only => :no_raise
+ around_action :raise_before, only: :raises_before
+ around_action :raise_after, only: :raises_after
+ around_action :without_exception, only: :no_raise
private
def raise_before
@@ -898,7 +898,7 @@ class ControllerWithFilterClass < PostsController
end
end
- around_action YieldingFilter, :only => :raises_after
+ around_action YieldingFilter, only: :raises_after
end
class ControllerWithFilterInstance < PostsController
@@ -909,11 +909,11 @@ class ControllerWithFilterInstance < PostsController
end
end
- around_action YieldingFilter.new, :only => :raises_after
+ around_action YieldingFilter.new, only: :raises_after
end
class ControllerWithProcFilter < PostsController
- around_action(:only => :no_raise) do |c,b|
+ around_action(only: :no_raise) do |c, b|
c.instance_variable_set(:"@before", true)
b.call
c.instance_variable_set(:"@after", true)
@@ -921,7 +921,7 @@ class ControllerWithProcFilter < PostsController
end
class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
- around_action :raise_before, :raise_after, :without_exception, :only => :raises_both
+ around_action :raise_before, :raise_after, :without_exception, only: :raises_both
end
class ControllerWithAllTypesOfFilters < PostsController
@@ -931,26 +931,26 @@ class ControllerWithAllTypesOfFilters < PostsController
around_action :around_again
private
- def before
- @ran_filter ||= []
- @ran_filter << 'before'
- end
+ def before
+ @ran_filter ||= []
+ @ran_filter << "before"
+ end
- def around
- @ran_filter << 'around (before yield)'
- yield
- @ran_filter << 'around (after yield)'
- end
+ def around
+ @ran_filter << "around (before yield)"
+ yield
+ @ran_filter << "around (after yield)"
+ end
- def after
- @ran_filter << 'after'
- end
+ def after
+ @ran_filter << "after"
+ end
- def around_again
- @ran_filter << 'around_again (before yield)'
- yield
- @ran_filter << 'around_again (after yield)'
- end
+ def around_again
+ @ran_filter << "around_again (before yield)"
+ yield
+ @ran_filter << "around_again (after yield)"
+ end
end
class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
@@ -958,46 +958,39 @@ class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
skip_after_action :after
end
-class SkipFilterUsingSkipActionCallback < ControllerWithAllTypesOfFilters
- ActiveSupport::Deprecation.silence do
- skip_action_callback :around_again
- skip_action_callback :after
- end
-end
-
class YieldingAroundFiltersTest < ActionController::TestCase
include PostsController::AroundExceptions
def test_base
controller = PostsController
- assert_nothing_raised { test_process(controller,'no_raise') }
- assert_nothing_raised { test_process(controller,'raises_before') }
- assert_nothing_raised { test_process(controller,'raises_after') }
- assert_nothing_raised { test_process(controller,'no_action') }
+ assert_nothing_raised { test_process(controller, "no_raise") }
+ assert_nothing_raised { test_process(controller, "raises_before") }
+ assert_nothing_raised { test_process(controller, "raises_after") }
+ assert_nothing_raised { test_process(controller, "no_action") }
end
def test_with_symbol
controller = ControllerWithSymbolAsFilter
- assert_nothing_raised { test_process(controller,'no_raise') }
- assert_raise(Before) { test_process(controller,'raises_before') }
- assert_raise(After) { test_process(controller,'raises_after') }
- assert_nothing_raised { test_process(controller,'no_raise') }
+ assert_nothing_raised { test_process(controller, "no_raise") }
+ assert_raise(Before) { test_process(controller, "raises_before") }
+ assert_raise(After) { test_process(controller, "raises_after") }
+ assert_nothing_raised { test_process(controller, "no_raise") }
end
def test_with_class
controller = ControllerWithFilterClass
- assert_nothing_raised { test_process(controller,'no_raise') }
- assert_raise(After) { test_process(controller,'raises_after') }
+ assert_nothing_raised { test_process(controller, "no_raise") }
+ assert_raise(After) { test_process(controller, "raises_after") }
end
def test_with_instance
controller = ControllerWithFilterInstance
- assert_nothing_raised { test_process(controller,'no_raise') }
- assert_raise(After) { test_process(controller,'raises_after') }
+ assert_nothing_raised { test_process(controller, "no_raise") }
+ assert_raise(After) { test_process(controller, "raises_after") }
end
def test_with_proc
- test_process(ControllerWithProcFilter,'no_raise')
+ test_process(ControllerWithProcFilter, "no_raise")
assert @controller.instance_variable_get(:@before)
assert @controller.instance_variable_get(:@after)
end
@@ -1006,71 +999,50 @@ class YieldingAroundFiltersTest < ActionController::TestCase
controller = ControllerWithNestedFilters
assert_nothing_raised do
begin
- test_process(controller,'raises_both')
+ test_process(controller, "raises_both")
rescue Before, After
end
end
assert_raise Before do
begin
- test_process(controller,'raises_both')
+ test_process(controller, "raises_both")
rescue After
end
end
end
def test_action_order_with_all_action_types
- test_process(ControllerWithAllTypesOfFilters,'no_raise')
- assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
+ test_process(ControllerWithAllTypesOfFilters, "no_raise")
+ assert_equal "before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)", @controller.instance_variable_get(:@ran_filter).join(" ")
end
def test_action_order_with_skip_action_method
- test_process(ControllerWithTwoLessFilters,'no_raise')
- assert_equal 'before around (before yield) around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
+ test_process(ControllerWithTwoLessFilters, "no_raise")
+ assert_equal "before around (before yield) around (after yield)", @controller.instance_variable_get(:@ran_filter).join(" ")
end
def test_first_action_in_multiple_before_action_chain_halts
controller = ::FilterTest::TestMultipleFiltersController.new
- response = test_process(controller, 'fail_1')
- assert_equal '', response.body
+ response = test_process(controller, "fail_1")
+ assert_equal "", response.body
assert_equal 1, controller.instance_variable_get(:@try)
end
def test_second_action_in_multiple_before_action_chain_halts
controller = ::FilterTest::TestMultipleFiltersController.new
- response = test_process(controller, 'fail_2')
- assert_equal '', response.body
+ response = test_process(controller, "fail_2")
+ assert_equal "", response.body
assert_equal 2, controller.instance_variable_get(:@try)
end
def test_last_action_in_multiple_before_action_chain_halts
controller = ::FilterTest::TestMultipleFiltersController.new
- response = test_process(controller, 'fail_3')
- assert_equal '', response.body
+ response = test_process(controller, "fail_3")
+ assert_equal "", response.body
assert_equal 3, controller.instance_variable_get(:@try)
end
- def test_skipping_with_skip_action_callback
- test_process(SkipFilterUsingSkipActionCallback,'no_raise')
- assert_equal 'before around (before yield) around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
- end
-
- def test_deprecated_skip_action_callback
- assert_deprecated do
- Class.new(PostsController) do
- skip_action_callback :clean_up
- end
- end
- end
-
- def test_deprecated_skip_filter
- assert_deprecated do
- Class.new(PostsController) do
- skip_filter :clean_up
- end
- end
- end
-
- protected
+ private
def test_process(controller, action = "show")
@controller = controller.is_a?(Class) ? controller.new : controller
process(action)
diff --git a/actionpack/test/controller/flash_hash_test.rb b/actionpack/test/controller/flash_hash_test.rb
index 081288ef21..e3ec5bb7fc 100644
--- a/actionpack/test/controller/flash_hash_test.rb
+++ b/actionpack/test/controller/flash_hash_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
class FlashHashTest < ActiveSupport::TestCase
@@ -7,116 +9,116 @@ module ActionDispatch
end
def test_set_get
- @hash[:foo] = 'zomg'
- assert_equal 'zomg', @hash[:foo]
+ @hash[:foo] = "zomg"
+ assert_equal "zomg", @hash[:foo]
end
def test_keys
assert_equal [], @hash.keys
- @hash['foo'] = 'zomg'
- assert_equal ['foo'], @hash.keys
+ @hash["foo"] = "zomg"
+ assert_equal ["foo"], @hash.keys
- @hash['bar'] = 'zomg'
- assert_equal ['foo', 'bar'].sort, @hash.keys.sort
+ @hash["bar"] = "zomg"
+ assert_equal ["foo", "bar"].sort, @hash.keys.sort
end
def test_update
- @hash['foo'] = 'bar'
- @hash.update('foo' => 'baz', 'hello' => 'world')
+ @hash["foo"] = "bar"
+ @hash.update("foo" => "baz", "hello" => "world")
- assert_equal 'baz', @hash['foo']
- assert_equal 'world', @hash['hello']
+ assert_equal "baz", @hash["foo"]
+ assert_equal "world", @hash["hello"]
end
def test_key
- @hash['foo'] = 'bar'
+ @hash["foo"] = "bar"
- assert @hash.key?('foo')
+ assert @hash.key?("foo")
assert @hash.key?(:foo)
- assert_not @hash.key?('bar')
+ assert_not @hash.key?("bar")
assert_not @hash.key?(:bar)
end
def test_delete
- @hash['foo'] = 'bar'
- @hash.delete 'foo'
+ @hash["foo"] = "bar"
+ @hash.delete "foo"
- assert !@hash.key?('foo')
- assert_nil @hash['foo']
+ assert_not @hash.key?("foo")
+ assert_nil @hash["foo"]
end
def test_to_hash
- @hash['foo'] = 'bar'
- assert_equal({'foo' => 'bar'}, @hash.to_hash)
+ @hash["foo"] = "bar"
+ assert_equal({ "foo" => "bar" }, @hash.to_hash)
- @hash.to_hash['zomg'] = 'aaron'
- assert !@hash.key?('zomg')
- assert_equal({'foo' => 'bar'}, @hash.to_hash)
+ @hash.to_hash["zomg"] = "aaron"
+ assert_not @hash.key?("zomg")
+ assert_equal({ "foo" => "bar" }, @hash.to_hash)
end
def test_to_session_value
- @hash['foo'] = 'bar'
- assert_equal({'flashes' => {'foo' => 'bar'}}, @hash.to_session_value)
+ @hash["foo"] = "bar"
+ assert_equal({ "discard" => [], "flashes" => { "foo" => "bar" } }, @hash.to_session_value)
- @hash.now['qux'] = 1
- assert_equal({'flashes' => {'foo' => 'bar'}}, @hash.to_session_value)
+ @hash.now["qux"] = 1
+ assert_equal({ "flashes" => { "foo" => "bar" }, "discard" => [] }, @hash.to_session_value)
- @hash.discard('foo')
- assert_equal(nil, @hash.to_session_value)
+ @hash.discard("foo")
+ assert_nil(@hash.to_session_value)
@hash.sweep
- assert_equal(nil, @hash.to_session_value)
+ assert_nil(@hash.to_session_value)
end
def test_from_session_value
# {"session_id"=>"f8e1b8152ba7609c28bbb17ec9263ba7", "flash"=>#<ActionDispatch::Flash::FlashHash:0x00000000000000 @used=#<Set: {"farewell"}>, @closed=false, @flashes={"greeting"=>"Hello", "farewell"=>"Goodbye"}, @now=nil>}
- rails_3_2_cookie = 'BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWY4ZTFiODE1MmJhNzYwOWMyOGJiYjE3ZWM5MjYzYmE3BjsAVEkiCmZsYXNoBjsARm86JUFjdGlvbkRpc3BhdGNoOjpGbGFzaDo6Rmxhc2hIYXNoCToKQHVzZWRvOghTZXQGOgpAaGFzaHsGSSINZmFyZXdlbGwGOwBUVDoMQGNsb3NlZEY6DUBmbGFzaGVzewdJIg1ncmVldGluZwY7AFRJIgpIZWxsbwY7AFRJIg1mYXJld2VsbAY7AFRJIgxHb29kYnllBjsAVDoJQG5vdzA='
+ rails_3_2_cookie = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWY4ZTFiODE1MmJhNzYwOWMyOGJiYjE3ZWM5MjYzYmE3BjsAVEkiCmZsYXNoBjsARm86JUFjdGlvbkRpc3BhdGNoOjpGbGFzaDo6Rmxhc2hIYXNoCToKQHVzZWRvOghTZXQGOgpAaGFzaHsGSSINZmFyZXdlbGwGOwBUVDoMQGNsb3NlZEY6DUBmbGFzaGVzewdJIg1ncmVldGluZwY7AFRJIgpIZWxsbwY7AFRJIg1mYXJld2VsbAY7AFRJIgxHb29kYnllBjsAVDoJQG5vdzA="
session = Marshal.load(Base64.decode64(rails_3_2_cookie))
- hash = Flash::FlashHash.from_session_value(session['flash'])
- assert_equal({'greeting' => 'Hello'}, hash.to_hash)
- assert_equal(nil, hash.to_session_value)
+ hash = Flash::FlashHash.from_session_value(session["flash"])
+ assert_equal({ "greeting" => "Hello" }, hash.to_hash)
+ assert_nil(hash.to_session_value)
end
def test_from_session_value_on_json_serializer
decrypted_data = "{ \"session_id\":\"d98bdf6d129618fc2548c354c161cfb5\", \"flash\":{\"discard\":[\"farewell\"], \"flashes\":{\"greeting\":\"Hello\",\"farewell\":\"Goodbye\"}} }"
session = ActionDispatch::Cookies::JsonSerializer.load(decrypted_data)
- hash = Flash::FlashHash.from_session_value(session['flash'])
+ hash = Flash::FlashHash.from_session_value(session["flash"])
- assert_equal({'greeting' => 'Hello'}, hash.to_hash)
- assert_equal(nil, hash.to_session_value)
+ assert_equal({ "greeting" => "Hello" }, hash.to_hash)
+ assert_nil(hash.to_session_value)
assert_equal "Hello", hash[:greeting]
assert_equal "Hello", hash["greeting"]
end
def test_empty?
- assert @hash.empty?
- @hash['zomg'] = 'bears'
- assert !@hash.empty?
+ assert_empty @hash
+ @hash["zomg"] = "bears"
+ assert_not_empty @hash
@hash.clear
- assert @hash.empty?
+ assert_empty @hash
end
def test_each
- @hash['hello'] = 'world'
- @hash['foo'] = 'bar'
+ @hash["hello"] = "world"
+ @hash["foo"] = "bar"
things = []
- @hash.each do |k,v|
- things << [k,v]
+ @hash.each do |k, v|
+ things << [k, v]
end
assert_equal([%w{ hello world }, %w{ foo bar }].sort, things.sort)
end
def test_replace
- @hash['hello'] = 'world'
- @hash.replace('omg' => 'aaron')
- assert_equal({'omg' => 'aaron'}, @hash.to_hash)
+ @hash["hello"] = "world"
+ @hash.replace("omg" => "aaron")
+ assert_equal({ "omg" => "aaron" }, @hash.to_hash)
end
def test_discard_no_args
- @hash['hello'] = 'world'
+ @hash["hello"] = "world"
@hash.discard
@hash.sweep
@@ -124,49 +126,49 @@ module ActionDispatch
end
def test_discard_one_arg
- @hash['hello'] = 'world'
- @hash['omg'] = 'world'
- @hash.discard 'hello'
+ @hash["hello"] = "world"
+ @hash["omg"] = "world"
+ @hash.discard "hello"
@hash.sweep
- assert_equal({'omg' => 'world'}, @hash.to_hash)
+ assert_equal({ "omg" => "world" }, @hash.to_hash)
end
def test_keep_sweep
- @hash['hello'] = 'world'
+ @hash["hello"] = "world"
@hash.sweep
- assert_equal({'hello' => 'world'}, @hash.to_hash)
+ assert_equal({ "hello" => "world" }, @hash.to_hash)
end
def test_update_sweep
- @hash['hello'] = 'world'
- @hash.update({'hi' => 'mom'})
+ @hash["hello"] = "world"
+ @hash.update("hi" => "mom")
@hash.sweep
- assert_equal({'hello' => 'world', 'hi' => 'mom'}, @hash.to_hash)
+ assert_equal({ "hello" => "world", "hi" => "mom" }, @hash.to_hash)
end
def test_update_delete_sweep
- @hash['hello'] = 'world'
- @hash.delete 'hello'
- @hash.update({'hello' => 'mom'})
+ @hash["hello"] = "world"
+ @hash.delete "hello"
+ @hash.update("hello" => "mom")
@hash.sweep
- assert_equal({'hello' => 'mom'}, @hash.to_hash)
+ assert_equal({ "hello" => "mom" }, @hash.to_hash)
end
def test_delete_sweep
- @hash['hello'] = 'world'
- @hash['hi'] = 'mom'
- @hash.delete 'hi'
+ @hash["hello"] = "world"
+ @hash["hi"] = "mom"
+ @hash.delete "hi"
@hash.sweep
- assert_equal({'hello' => 'world'}, @hash.to_hash)
+ assert_equal({ "hello" => "world" }, @hash.to_hash)
end
def test_clear_sweep
- @hash['hello'] = 'world'
+ @hash["hello"] = "world"
@hash.clear
@hash.sweep
@@ -174,38 +176,38 @@ module ActionDispatch
end
def test_replace_sweep
- @hash['hello'] = 'world'
- @hash.replace({'hi' => 'mom'})
+ @hash["hello"] = "world"
+ @hash.replace("hi" => "mom")
@hash.sweep
- assert_equal({'hi' => 'mom'}, @hash.to_hash)
+ assert_equal({ "hi" => "mom" }, @hash.to_hash)
end
def test_discard_then_add
- @hash['hello'] = 'world'
- @hash['omg'] = 'world'
- @hash.discard 'hello'
- @hash['hello'] = 'world'
+ @hash["hello"] = "world"
+ @hash["omg"] = "world"
+ @hash.discard "hello"
+ @hash["hello"] = "world"
@hash.sweep
- assert_equal({'omg' => 'world', 'hello' => 'world'}, @hash.to_hash)
+ assert_equal({ "omg" => "world", "hello" => "world" }, @hash.to_hash)
end
def test_keep_all_sweep
- @hash['hello'] = 'world'
- @hash['omg'] = 'world'
- @hash.discard 'hello'
+ @hash["hello"] = "world"
+ @hash["omg"] = "world"
+ @hash.discard "hello"
@hash.keep
@hash.sweep
- assert_equal({'omg' => 'world', 'hello' => 'world'}, @hash.to_hash)
+ assert_equal({ "omg" => "world", "hello" => "world" }, @hash.to_hash)
end
def test_double_sweep
- @hash['hello'] = 'world'
+ @hash["hello"] = "world"
@hash.sweep
- assert_equal({'hello' => 'world'}, @hash.to_hash)
+ assert_equal({ "hello" => "world" }, @hash.to_hash)
@hash.sweep
assert_equal({}, @hash.to_hash)
diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb
index b063d769a4..409a4ec2e6 100644
--- a/actionpack/test/controller/flash_test.rb
+++ b/actionpack/test/controller/flash_test.rb
@@ -1,11 +1,13 @@
-require 'abstract_unit'
-require 'active_support/key_generator'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/messages/rotation_configuration"
class FlashTest < ActionController::TestCase
class TestController < ActionController::Base
def set_flash
flash["that"] = "hello"
- render :inline => "hello"
+ render inline: "hello"
end
def set_flash_now
@@ -14,32 +16,32 @@ class FlashTest < ActionController::TestCase
flash.now["foo"] ||= "err"
@flashy = flash.now["that"]
@flash_copy = {}.update flash
- render :inline => "hello"
+ render inline: "hello"
end
def attempt_to_use_flash_now
@flash_copy = {}.update flash
@flashy = flash["that"]
- render :inline => "hello"
+ render inline: "hello"
end
def use_flash
@flash_copy = {}.update flash
@flashy = flash["that"]
- render :inline => "hello"
+ render inline: "hello"
end
def use_flash_and_keep_it
@flash_copy = {}.update flash
@flashy = flash["that"]
flash.keep
- render :inline => "hello"
+ render inline: "hello"
end
def use_flash_and_update_it
flash.update("this" => "hello again")
@flash_copy = {}.update flash
- render :inline => "hello"
+ render inline: "hello"
end
def use_flash_after_reset_session
@@ -49,11 +51,11 @@ class FlashTest < ActionController::TestCase
@flashy_that_reset = flash["that"]
flash["this"] = "good-bye"
@flashy_this = flash["this"]
- render :inline => "hello"
+ render inline: "hello"
end
# methods for test_sweep_after_halted_action_chain
- before_action :halt_and_redir, only: 'filter_halting_action'
+ before_action :halt_and_redir, only: "filter_halting_action"
def std_action
@flash_copy = {}.update(flash)
@@ -66,34 +68,34 @@ class FlashTest < ActionController::TestCase
def halt_and_redir
flash["foo"] = "bar"
- redirect_to :action => "std_action"
+ redirect_to action: "std_action"
@flash_copy = {}.update(flash)
end
def redirect_with_alert
- redirect_to '/nowhere', :alert => "Beware the nowheres!"
+ redirect_to "/nowhere", alert: "Beware the nowheres!"
end
def redirect_with_notice
- redirect_to '/somewhere', :notice => "Good luck in the somewheres!"
+ redirect_to "/somewhere", notice: "Good luck in the somewheres!"
end
def render_with_flash_now_alert
flash.now.alert = "Beware the nowheres now!"
- render :inline => "hello"
+ render inline: "hello"
end
def render_with_flash_now_notice
flash.now.notice = "Good luck in the somewheres now!"
- render :inline => "hello"
+ render inline: "hello"
end
def redirect_with_other_flashes
- redirect_to '/wonderland', :flash => { :joyride => "Horses!" }
+ redirect_to "/wonderland", flash: { joyride: "Horses!" }
end
def redirect_with_foo_flash
- redirect_to "/wonderland", :foo => 'for great justice'
+ redirect_to "/wonderland", foo: "for great justice"
end
end
@@ -172,17 +174,17 @@ class FlashTest < ActionController::TestCase
def test_keep_and_discard_return_values
flash = ActionDispatch::Flash::FlashHash.new
- flash.update(:foo => :foo_indeed, :bar => :bar_indeed)
+ flash.update(foo: :foo_indeed, bar: :bar_indeed)
assert_equal(:foo_indeed, flash.discard(:foo)) # valid key passed
assert_nil flash.discard(:unknown) # non existent key passed
- assert_equal({"foo" => :foo_indeed, "bar" => :bar_indeed}, flash.discard().to_hash) # nothing passed
- assert_equal({"foo" => :foo_indeed, "bar" => :bar_indeed}, flash.discard(nil).to_hash) # nothing passed
+ assert_equal({ "foo" => :foo_indeed, "bar" => :bar_indeed }, flash.discard().to_hash) # nothing passed
+ assert_equal({ "foo" => :foo_indeed, "bar" => :bar_indeed }, flash.discard(nil).to_hash) # nothing passed
assert_equal(:foo_indeed, flash.keep(:foo)) # valid key passed
assert_nil flash.keep(:unknown) # non existent key passed
- assert_equal({"foo" => :foo_indeed, "bar" => :bar_indeed}, flash.keep().to_hash) # nothing passed
- assert_equal({"foo" => :foo_indeed, "bar" => :bar_indeed}, flash.keep(nil).to_hash) # nothing passed
+ assert_equal({ "foo" => :foo_indeed, "bar" => :bar_indeed }, flash.keep().to_hash) # nothing passed
+ assert_equal({ "foo" => :foo_indeed, "bar" => :bar_indeed }, flash.keep(nil).to_hash) # nothing passed
end
def test_redirect_to_with_alert
@@ -227,7 +229,7 @@ class FlashTest < ActionController::TestCase
add_flash_types :foo
end
subclass_controller_with_no_flash_type = Class.new(test_controller_with_flash_type_foo)
- assert subclass_controller_with_no_flash_type._flash_types.include?(:foo)
+ assert_includes subclass_controller_with_no_flash_type._flash_types, :foo
end
def test_does_not_add_flash_type_to_parent_class
@@ -239,8 +241,9 @@ class FlashTest < ActionController::TestCase
end
class FlashIntegrationTest < ActionDispatch::IntegrationTest
- SessionKey = '_myapp_session'
- Generator = ActiveSupport::LegacyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33')
+ SessionKey = "_myapp_session"
+ Generator = ActiveSupport::LegacyKeyGenerator.new("b3c631c314c0bbca50c1b2843150fe33")
+ Rotations = ActiveSupport::Messages::RotationConfiguration.new
class TestController < ActionController::Base
add_flash_types :bar
@@ -256,22 +259,29 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest
end
def use_flash
- render :inline => "flash: #{flash["that"]}"
+ render inline: "flash: #{flash["that"]}"
end
def set_bar
flash[:bar] = "for great justice"
head :ok
end
+
+ def set_flash_optionally
+ flash.now.notice = params[:flash]
+ if stale? etag: "abe"
+ render inline: "maybe flash"
+ end
+ end
end
def test_flash
with_test_route_set do
- get '/set_flash'
+ get "/set_flash"
assert_response :success
assert_equal "hello", @request.flash["that"]
- get '/use_flash'
+ get "/use_flash"
assert_response :success
assert_equal "flash: hello", @response.body
end
@@ -279,7 +289,7 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest
def test_just_using_flash_does_not_stream_a_cookie_back
with_test_route_set do
- get '/use_flash'
+ get "/use_flash"
assert_response :success
assert_nil @response.headers["Set-Cookie"]
assert_equal "flash: ", @response.body
@@ -288,28 +298,65 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest
def test_setting_flash_does_not_raise_in_following_requests
with_test_route_set do
- env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new }
- get '/set_flash', env: env
- get '/set_flash', env: env
+ env = { "action_dispatch.request.flash_hash" => ActionDispatch::Flash::FlashHash.new }
+ get "/set_flash", env: env
+ get "/set_flash", env: env
end
end
def test_setting_flash_now_does_not_raise_in_following_requests
with_test_route_set do
- env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new }
- get '/set_flash_now', env: env
- get '/set_flash_now', env: env
+ env = { "action_dispatch.request.flash_hash" => ActionDispatch::Flash::FlashHash.new }
+ get "/set_flash_now", env: env
+ get "/set_flash_now", env: env
end
end
def test_added_flash_types_method
with_test_route_set do
- get '/set_bar'
+ get "/set_bar"
assert_response :success
- assert_equal 'for great justice', @controller.bar
+ assert_equal "for great justice", @controller.bar
end
end
+ def test_flash_factored_into_etag
+ with_test_route_set do
+ get "/set_flash_optionally"
+ no_flash_etag = response.etag
+
+ get "/set_flash_optionally", params: { flash: "hello!" }
+ hello_flash_etag = response.etag
+
+ assert_not_equal no_flash_etag, hello_flash_etag
+
+ get "/set_flash_optionally", params: { flash: "hello!" }
+ another_hello_flash_etag = response.etag
+
+ assert_equal another_hello_flash_etag, hello_flash_etag
+
+ get "/set_flash_optionally", params: { flash: "goodbye!" }
+ goodbye_flash_etag = response.etag
+
+ assert_not_equal another_hello_flash_etag, goodbye_flash_etag
+ end
+ end
+
+ def test_flash_usable_in_metal_without_helper
+ controller_class = nil
+
+ assert_nothing_raised do
+ controller_class = Class.new(ActionController::Metal) do
+ include ActionController::Flash
+ end
+ end
+
+ controller = controller_class.new
+
+ assert_respond_to controller, :alert
+ assert_respond_to controller, :notice
+ end
+
private
# Overwrite get to send SessionSecret in env hash
@@ -317,17 +364,20 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest
args[0] ||= {}
args[0][:env] ||= {}
args[0][:env]["action_dispatch.key_generator"] ||= Generator
+ args[0][:env]["action_dispatch.cookies_rotations"] = Rotations
super(path, *args)
end
def with_test_route_set
with_routing do |set|
set.draw do
- get ':action', :to => FlashIntegrationTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: FlashIntegrationTest::TestController
+ end
end
@app = self.class.build_app(set) do |middleware|
- middleware.use ActionDispatch::Session::CookieStore, :key => SessionKey
+ middleware.use ActionDispatch::Session::CookieStore, key: SessionKey
middleware.use ActionDispatch::Flash
middleware.delete ActionDispatch::ShowExceptions
end
diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb
index 22f1cc7c22..7f59f6acaf 100644
--- a/actionpack/test/controller/force_ssl_test.rb
+++ b/actionpack/test/controller/force_ssl_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class ForceSSLController < ActionController::Base
def banana
@@ -11,19 +13,23 @@ class ForceSSLController < ActionController::Base
end
class ForceSSLControllerLevel < ForceSSLController
- force_ssl
+ ActiveSupport::Deprecation.silence do
+ force_ssl
+ end
end
class ForceSSLCustomOptions < ForceSSLController
- force_ssl :host => "secure.example.com", :only => :redirect_host
- force_ssl :port => 8443, :only => :redirect_port
- force_ssl :subdomain => 'secure', :only => :redirect_subdomain
- force_ssl :domain => 'secure.com', :only => :redirect_domain
- force_ssl :path => '/foo', :only => :redirect_path
- force_ssl :status => :found, :only => :redirect_status
- force_ssl :flash => { :message => 'Foo, Bar!' }, :only => :redirect_flash
- force_ssl :alert => 'Foo, Bar!', :only => :redirect_alert
- force_ssl :notice => 'Foo, Bar!', :only => :redirect_notice
+ ActiveSupport::Deprecation.silence do
+ force_ssl host: "secure.example.com", only: :redirect_host
+ force_ssl port: 8443, only: :redirect_port
+ force_ssl subdomain: "secure", only: :redirect_subdomain
+ force_ssl domain: "secure.com", only: :redirect_domain
+ force_ssl path: "/foo", only: :redirect_path
+ force_ssl status: :found, only: :redirect_status
+ force_ssl flash: { message: "Foo, Bar!" }, only: :redirect_flash
+ force_ssl alert: "Foo, Bar!", only: :redirect_alert
+ force_ssl notice: "Foo, Bar!", only: :redirect_notice
+ end
def force_ssl_action
render plain: action_name
@@ -53,42 +59,50 @@ class ForceSSLCustomOptions < ForceSSLController
end
class ForceSSLOnlyAction < ForceSSLController
- force_ssl :only => :cheeseburger
+ ActiveSupport::Deprecation.silence do
+ force_ssl only: :cheeseburger
+ end
end
class ForceSSLExceptAction < ForceSSLController
- force_ssl :except => :banana
+ ActiveSupport::Deprecation.silence do
+ force_ssl except: :banana
+ end
end
class ForceSSLIfCondition < ForceSSLController
- force_ssl :if => :use_force_ssl?
+ ActiveSupport::Deprecation.silence do
+ force_ssl if: :use_force_ssl?
+ end
def use_force_ssl?
- action_name == 'cheeseburger'
+ action_name == "cheeseburger"
end
end
class ForceSSLFlash < ForceSSLController
- force_ssl :except => [:banana, :set_flash, :use_flash]
+ ActiveSupport::Deprecation.silence do
+ force_ssl except: [:banana, :set_flash, :use_flash]
+ end
def set_flash
flash["that"] = "hello"
- redirect_to '/force_ssl_flash/cheeseburger'
+ redirect_to "/force_ssl_flash/cheeseburger"
end
def use_flash
@flash_copy = {}.update flash
@flashy = flash["that"]
- render :inline => "hello"
+ render inline: "hello"
end
end
class RedirectToSSL < ForceSSLController
def banana
- force_ssl_redirect || render(plain: 'monkey')
+ force_ssl_redirect || render(plain: "monkey")
end
def cheeseburger
- force_ssl_redirect('secure.cheeseburger.host') || render(plain: 'ihaz')
+ force_ssl_redirect("secure.cheeseburger.host") || render(plain: "ihaz")
end
end
@@ -114,7 +128,7 @@ end
class ForceSSLCustomOptionsTest < ActionController::TestCase
def setup
- @request.env['HTTP_HOST'] = 'www.example.com:80'
+ @request.env["HTTP_HOST"] = "www.example.com:80"
end
def test_redirect_to_custom_host
@@ -229,15 +243,13 @@ class ForceSSLFlashTest < ActionController::TestCase
assert_response 302
assert_equal "http://test.host/force_ssl_flash/cheeseburger", redirect_to_url
- # FIXME: AC::TestCase#build_request_uri doesn't build a new uri if PATH_INFO exists
- @request.env.delete('PATH_INFO')
+ @request.env.delete("PATH_INFO")
get :cheeseburger
assert_response 301
assert_equal "https://test.host/force_ssl_flash/cheeseburger", redirect_to_url
- # FIXME: AC::TestCase#build_request_uri doesn't build a new uri if PATH_INFO exists
- @request.env.delete('PATH_INFO')
+ @request.env.delete("PATH_INFO")
get :use_flash
assert_equal "hello", @controller.instance_variable_get("@flash_copy")["that"]
@@ -251,15 +263,15 @@ class ForceSSLDuplicateRoutesTest < ActionController::TestCase
def test_force_ssl_redirects_to_same_path
with_routing do |set|
set.draw do
- get '/foo', :to => 'force_ssl_controller_level#banana'
- get '/bar', :to => 'force_ssl_controller_level#banana'
+ get "/foo", to: "force_ssl_controller_level#banana"
+ get "/bar", to: "force_ssl_controller_level#banana"
end
- @request.env['PATH_INFO'] = '/bar'
+ @request.env["PATH_INFO"] = "/bar"
get :banana
assert_response 301
- assert_equal 'https://test.host/bar', redirect_to_url
+ assert_equal "https://test.host/bar", redirect_to_url
end
end
end
@@ -270,12 +282,12 @@ class ForceSSLFormatTest < ActionController::TestCase
def test_force_ssl_redirects_to_same_format
with_routing do |set|
set.draw do
- get '/foo', :to => 'force_ssl_controller_level#banana'
+ get "/foo", to: "force_ssl_controller_level#banana"
end
get :banana, format: :json
assert_response 301
- assert_equal 'https://test.host/foo.json', redirect_to_url
+ assert_equal "https://test.host/foo.json", redirect_to_url
end
end
end
@@ -286,18 +298,18 @@ class ForceSSLOptionalSegmentsTest < ActionController::TestCase
def test_force_ssl_redirects_to_same_format
with_routing do |set|
set.draw do
- scope '(:locale)' do
- defaults :locale => 'en' do
- get '/foo', :to => 'force_ssl_controller_level#banana'
+ scope "(:locale)" do
+ defaults locale: "en" do
+ get "/foo", to: "force_ssl_controller_level#banana"
end
end
end
- @request.env['PATH_INFO'] = '/en/foo'
- get :banana, params: { locale: 'en' }
- assert_equal 'en', @controller.params[:locale]
+ @request.env["PATH_INFO"] = "/en/foo"
+ get :banana, params: { locale: "en" }
+ assert_equal "en", @controller.params[:locale]
assert_response 301
- assert_equal 'https://test.host/en/foo', redirect_to_url
+ assert_equal "https://test.host/en/foo", redirect_to_url
end
end
end
@@ -316,9 +328,18 @@ class RedirectToSSLTest < ActionController::TestCase
end
def test_cheeseburgers_does_not_redirect_if_already_https
- request.env['HTTPS'] = 'on'
+ request.env["HTTPS"] = "on"
+ get :cheeseburger
+ assert_response 200
+ assert_equal "ihaz", response.body
+ end
+end
+
+class ForceSSLControllerLevelTest < ActionController::TestCase
+ def test_no_redirect_websocket_ssl_request
+ request.env["rack.url_scheme"] = "wss"
+ request.env["Upgrade"] = "websocket"
get :cheeseburger
assert_response 200
- assert_equal 'ihaz', response.body
end
end
diff --git a/actionpack/test/controller/form_builder_test.rb b/actionpack/test/controller/form_builder_test.rb
index 99eeaf9ab6..2db0834c5e 100644
--- a/actionpack/test/controller/form_builder_test.rb
+++ b/actionpack/test/controller/form_builder_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class FormBuilderController < ActionController::Base
class SpecializedFormBuilder < ActionView::Helpers::FormBuilder ; end
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index 3ecfedefd1..de8072a994 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -1,17 +1,19 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', __FILE__)
+require "abstract_unit"
+
+ActionController::Base.helpers_path = File.expand_path("../fixtures/helpers", __dir__)
module Fun
class GamesController < ActionController::Base
def render_hello_world
- render :inline => "hello: <%= stratego %>"
+ render inline: "hello: <%= stratego %>"
end
end
class PdfController < ActionController::Base
def test
- render :inline => "test: <%= foobar %>"
+ render inline: "test: <%= foobar %>"
end
end
end
@@ -35,11 +37,11 @@ class JustMeController < ActionController::Base
clear_helpers
def flash
- render :inline => "<h1><%= notice %></h1>"
+ render inline: "<h1><%= notice %></h1>"
end
def lib
- render :inline => '<%= useful_function %>'
+ render inline: "<%= useful_function %>"
end
end
@@ -48,7 +50,7 @@ end
class HelpersPathsController < ActionController::Base
paths = ["helpers2_pack", "helpers1_pack"].map do |path|
- File.join(File.expand_path('../../fixtures', __FILE__), path)
+ File.join(File.expand_path("../fixtures", __dir__), path)
end
$:.unshift(*paths)
@@ -56,12 +58,12 @@ class HelpersPathsController < ActionController::Base
helper :all
def index
- render :inline => "<%= conflicting_helper %>"
+ render inline: "<%= conflicting_helper %>"
end
end
class HelpersTypoController < ActionController::Base
- path = File.expand_path('../../fixtures/helpers_typo', __FILE__)
+ path = File.expand_path("../fixtures/helpers_typo", __dir__)
$:.unshift(path)
self.helpers_path = path
end
@@ -89,7 +91,7 @@ class HelpersTypoControllerTest < ActiveSupport::TestCase
end
def test_helper_typo_error_message
- e = assert_raise(NameError) { HelpersTypoController.helper 'admin/users' }
+ e = assert_raise(NameError) { HelpersTypoController.helper "admin/users" }
assert_equal "Couldn't find Admin::UsersHelper, expected it to be defined in helpers/admin/users_helper.rb", e.message
end
@@ -106,7 +108,7 @@ class HelperTest < ActiveSupport::TestCase
def setup
# Increment symbol counter.
- @symbol = (@@counter ||= 'A0').succ!.dup
+ @symbol = (@@counter ||= "A0").succ.dup
# Generate new controller class.
controller_class_name = "Helper#{@symbol}Controller"
@@ -125,13 +127,13 @@ class HelperTest < ActiveSupport::TestCase
def test_helper_method
assert_nothing_raised { @controller_class.helper_method :delegate_method }
- assert master_helper_methods.include?(:delegate_method)
+ assert_includes master_helper_methods, :delegate_method
end
def test_helper_attr
assert_nothing_raised { @controller_class.helper_attr :delegate_attr }
- assert master_helper_methods.include?(:delegate_attr)
- assert master_helper_methods.include?(:delegate_attr=)
+ assert_includes master_helper_methods, :delegate_attr
+ assert_includes master_helper_methods, :delegate_attr=
end
def call_controller(klass, action)
@@ -139,22 +141,12 @@ class HelperTest < ActiveSupport::TestCase
end
def test_helper_for_nested_controller
- assert_equal 'hello: Iz guuut!',
+ assert_equal "hello: Iz guuut!",
call_controller(Fun::GamesController, "render_hello_world").last.body
- # request = ActionController::TestRequest.new
- #
- # resp = Fun::GamesController.action(:render_hello_world).call(request.env)
- # assert_equal 'hello: Iz guuut!', resp.last.body
end
def test_helper_for_acronym_controller
assert_equal "test: baz", call_controller(Fun::PdfController, "test").last.body
- #
- # request = ActionController::TestRequest.new
- # response = ActionDispatch::TestResponse.new
- # request.action = 'test'
- #
- # assert_equal 'test: baz', Fun::PdfController.process(request, response).body
end
def test_default_helpers_only
@@ -178,49 +170,65 @@ class HelperTest < ActiveSupport::TestCase
methods = AllHelpersController._helpers.instance_methods
# abc_helper.rb
- assert methods.include?(:bare_a)
+ assert_includes methods, :bare_a
# fun/games_helper.rb
- assert methods.include?(:stratego)
+ assert_includes methods, :stratego
# fun/pdf_helper.rb
- assert methods.include?(:foobar)
+ assert_includes methods, :foobar
end
def test_all_helpers_with_alternate_helper_dir
- @controller_class.helpers_path = File.expand_path('../../fixtures/alternate_helpers', __FILE__)
+ @controller_class.helpers_path = File.expand_path("../fixtures/alternate_helpers", __dir__)
# Reload helpers
@controller_class._helpers = Module.new
@controller_class.helper :all
# helpers/abc_helper.rb should not be included
- assert !master_helper_methods.include?(:bare_a)
+ assert_not_includes master_helper_methods, :bare_a
# alternate_helpers/foo_helper.rb
- assert master_helper_methods.include?(:baz)
+ assert_includes master_helper_methods, :baz
end
def test_helper_proxy
methods = AllHelpersController.helpers.methods
# Action View
- assert methods.include?(:pluralize)
+ assert_includes methods, :pluralize
+
+ # abc_helper.rb
+ assert_includes methods, :bare_a
+
+ # fun/games_helper.rb
+ assert_includes methods, :stratego
+
+ # fun/pdf_helper.rb
+ assert_includes methods, :foobar
+ end
+
+ def test_helper_proxy_in_instance
+ methods = AllHelpersController.new.helpers.methods
+
+ # Action View
+ assert_includes methods, :pluralize
# abc_helper.rb
- assert methods.include?(:bare_a)
+ assert_includes methods, :bare_a
# fun/games_helper.rb
- assert methods.include?(:stratego)
+ assert_includes methods, :stratego
# fun/pdf_helper.rb
- assert methods.include?(:foobar)
+ assert_includes methods, :foobar
end
def test_helper_proxy_config
- AllHelpersController.config.my_var = 'smth'
+ AllHelpersController.config.my_var = "smth"
- assert_equal 'smth', AllHelpersController.helpers.config.my_var
+ assert_equal "smth", AllHelpersController.helpers.config.my_var
end
private
@@ -237,31 +245,30 @@ class HelperTest < ActiveSupport::TestCase
end
def test_helper=(helper_module)
- silence_warnings { self.class.const_set('TestHelper', helper_module) }
+ silence_warnings { self.class.const_set("TestHelper", helper_module) }
end
end
-
class IsolatedHelpersTest < ActionController::TestCase
class A < ActionController::Base
def index
- render :inline => '<%= shout %>'
+ render inline: "<%= shout %>"
end
end
class B < A
- helper { def shout; 'B' end }
+ helper { def shout; "B" end }
def index
- render :inline => '<%= shout %>'
+ render inline: "<%= shout %>"
end
end
class C < A
- helper { def shout; 'C' end }
+ helper { def shout; "C" end }
def index
- render :inline => '<%= shout %>'
+ render inline: "<%= shout %>"
end
end
@@ -271,7 +278,7 @@ class IsolatedHelpersTest < ActionController::TestCase
def setup
super
- @request.action = 'index'
+ @request.action = "index"
end
def test_helper_in_a
@@ -279,10 +286,10 @@ class IsolatedHelpersTest < ActionController::TestCase
end
def test_helper_in_b
- assert_equal 'B', call_controller(B, "index").last.body
+ assert_equal "B", call_controller(B, "index").last.body
end
def test_helper_in_c
- assert_equal 'C', call_controller(C, "index").last.body
+ assert_equal "C", call_controller(C, "index").last.body
end
end
diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb
index 0a5e5402b9..1544a627ee 100644
--- a/actionpack/test/controller/http_basic_authentication_test.rb
+++ b/actionpack/test/controller/http_basic_authentication_test.rb
@@ -1,83 +1,96 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class HttpBasicAuthenticationTest < ActionController::TestCase
class DummyController < ActionController::Base
before_action :authenticate, only: :index
before_action :authenticate_with_request, only: :display
before_action :authenticate_long_credentials, only: :show
+ before_action :auth_with_special_chars, only: :special_creds
- http_basic_authenticate_with :name => "David", :password => "Goliath", :only => :search
+ http_basic_authenticate_with name: "David", password: "Goliath", only: :search
def index
render plain: "Hello Secret"
end
def display
- render plain: 'Definitely Maybe' if @logged_in
+ render plain: "Definitely Maybe" if @logged_in
end
def show
- render plain: 'Only for loooooong credentials'
+ render plain: "Only for loooooong credentials"
+ end
+
+ def special_creds
+ render plain: "Only for special credentials"
end
def search
- render plain: 'All inline'
+ render plain: "All inline"
end
private
- def authenticate
- authenticate_or_request_with_http_basic do |username, password|
- username == 'lifo' && password == 'world'
+ def authenticate
+ authenticate_or_request_with_http_basic do |username, password|
+ username == "lifo" && password == "world"
+ end
end
- end
- def authenticate_with_request
- if authenticate_with_http_basic { |username, password| username == 'pretty' && password == 'please' }
- @logged_in = true
- else
- request_http_basic_authentication("SuperSecret", "Authentication Failed\n")
+ def authenticate_with_request
+ if authenticate_with_http_basic { |username, password| username == "pretty" && password == "please" }
+ @logged_in = true
+ else
+ request_http_basic_authentication("SuperSecret", "Authentication Failed\n")
+ end
end
- end
- def authenticate_long_credentials
- authenticate_or_request_with_http_basic do |username, password|
- username == '1234567890123456789012345678901234567890' && password == '1234567890123456789012345678901234567890'
+ def auth_with_special_chars
+ authenticate_or_request_with_http_basic do |username, password|
+ username == 'login!@#$%^&*()_+{}[];"\',./<>?`~ \n\r\t' && password == 'pwd:!@#$%^&*()_+{}[];"\',./<>?`~ \n\r\t'
+ end
+ end
+
+ def authenticate_long_credentials
+ authenticate_or_request_with_http_basic do |username, password|
+ username == "1234567890123456789012345678901234567890" && password == "1234567890123456789012345678901234567890"
+ end
end
- end
end
- AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
+ AUTH_HEADERS = ["HTTP_AUTHORIZATION", "X-HTTP_AUTHORIZATION", "X_HTTP_AUTHORIZATION", "REDIRECT_X_HTTP_AUTHORIZATION"]
tests DummyController
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials('lifo', 'world')
+ @request.env[header] = encode_credentials("lifo", "world")
get :index
assert_response :success
- assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
+ assert_equal "Hello Secret", @response.body, "Authentication failed for request header #{header}"
end
test "successful authentication with #{header.downcase} and long credentials" do
- @request.env[header] = encode_credentials('1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890')
+ @request.env[header] = encode_credentials("1234567890123456789012345678901234567890", "1234567890123456789012345678901234567890")
get :show
assert_response :success
- assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials"
+ assert_equal "Only for loooooong credentials", @response.body, "Authentication failed for request header #{header} and long credentials"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials('h4x0r', 'world')
+ @request.env[header] = encode_credentials("h4x0r", "world")
get :index
assert_response :unauthorized
assert_equal "HTTP Basic: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
end
test "unsuccessful authentication with #{header.downcase} and long credentials" do
- @request.env[header] = encode_credentials('h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r', 'worldworldworldworldworldworldworldworld')
+ @request.env[header] = encode_credentials("h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r", "worldworldworldworldworldworldworldworld")
get :show
assert_response :unauthorized
@@ -93,19 +106,19 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
end
def test_encode_credentials_has_no_newline
- username = 'laskjdfhalksdjfhalkjdsfhalksdjfhklsdjhalksdjfhalksdjfhlakdsjfh'
- password = 'kjfhueyt9485osdfasdkljfh4lkjhakldjfhalkdsjf'
+ username = "laskjdfhalksdjfhalkjdsfhalksdjfhklsdjhalksdjfhalksdjfhlakdsjfh"
+ password = "kjfhueyt9485osdfasdkljfh4lkjhakldjfhalkdsjf"
result = ActionController::HttpAuthentication::Basic.encode_credentials(
username, password)
assert_no_match(/\n/, result)
end
- test "succesful authentication with uppercase authorization scheme" do
- @request.env['HTTP_AUTHORIZATION'] = "BASIC #{::Base64.encode64("lifo:world")}"
+ test "successful authentication with uppercase authorization scheme" do
+ @request.env["HTTP_AUTHORIZATION"] = "BASIC #{::Base64.encode64("lifo:world")}"
get :index
assert_response :success
- assert_equal 'Hello Secret', @response.body, 'Authentication failed when authorization scheme BASIC'
+ assert_equal "Hello Secret", @response.body, "Authentication failed when authorization scheme BASIC"
end
test "authentication request without credential" do
@@ -113,46 +126,54 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
assert_response :unauthorized
assert_equal "Authentication Failed\n", @response.body
- assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
+ assert_equal 'Basic realm="SuperSecret"', @response.headers["WWW-Authenticate"]
end
test "authentication request with invalid credential" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'foo')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials("pretty", "foo")
get :display
assert_response :unauthorized
assert_equal "Authentication Failed\n", @response.body
- assert_equal 'Basic realm="SuperSecret"', @response.headers['WWW-Authenticate']
+ assert_equal 'Basic realm="SuperSecret"', @response.headers["WWW-Authenticate"]
end
test "authentication request with valid credential" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials('pretty', 'please')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials("pretty", "please")
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
+ end
+
+ test "authentication request with valid credential special chars" do
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials('login!@#$%^&*()_+{}[];"\',./<>?`~ \n\r\t', 'pwd:!@#$%^&*()_+{}[];"\',./<>?`~ \n\r\t')
+ get :special_creds
+
+ assert_response :success
+ assert_equal "Only for special credentials", @response.body
end
test "authenticate with class method" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'Goliath')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials("David", "Goliath")
get :search
assert_response :success
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'WRONG!')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials("David", "WRONG!")
get :search
assert_response :unauthorized
end
test "authentication request with wrong scheme" do
- header = 'Bearer ' + encode_credentials('David', 'Goliath').split(' ', 2)[1]
- @request.env['HTTP_AUTHORIZATION'] = header
+ header = "Bearer " + encode_credentials("David", "Goliath").split(" ", 2)[1]
+ @request.env["HTTP_AUTHORIZATION"] = header
get :search
assert_response :unauthorized
end
private
- def encode_credentials(username, password)
- "Basic #{::Base64.encode64("#{username}:#{password}")}"
- end
+ def encode_credentials(username, password)
+ "Basic #{::Base64.encode64("#{username}:#{password}")}"
+ end
end
diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb
index f06912bd5a..b133afb343 100644
--- a/actionpack/test/controller/http_digest_authentication_test.rb
+++ b/actionpack/test/controller/http_digest_authentication_test.rb
@@ -1,41 +1,43 @@
-require 'abstract_unit'
-require 'active_support/key_generator'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/key_generator"
class HttpDigestAuthenticationTest < ActionController::TestCase
class DummyDigestController < ActionController::Base
before_action :authenticate, only: :index
before_action :authenticate_with_request, only: :display
- USERS = { 'lifo' => 'world', 'pretty' => 'please',
- 'dhh' => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":"))}
+ USERS = { "lifo" => "world", "pretty" => "please",
+ "dhh" => ::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")) }
def index
render plain: "Hello Secret"
end
def display
- render plain: 'Definitely Maybe' if @logged_in
+ render plain: "Definitely Maybe" if @logged_in
end
private
- def authenticate
- authenticate_or_request_with_http_digest("SuperSecret") do |username|
- # Returns the password
- USERS[username]
+ def authenticate
+ authenticate_or_request_with_http_digest("SuperSecret") do |username|
+ # Returns the password
+ USERS[username]
+ end
end
- end
- def authenticate_with_request
- if authenticate_with_http_digest("SuperSecret") { |username| USERS[username] }
- @logged_in = true
- else
- request_http_digest_authentication("SuperSecret", "Authentication Failed")
+ def authenticate_with_request
+ if authenticate_with_http_digest("SuperSecret") { |username| USERS[username] }
+ @logged_in = true
+ else
+ request_http_digest_authentication("SuperSecret", "Authentication Failed")
+ end
end
- end
end
- AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
+ AUTH_HEADERS = ["HTTP_AUTHORIZATION", "X-HTTP_AUTHORIZATION", "X_HTTP_AUTHORIZATION", "REDIRECT_X_HTTP_AUTHORIZATION"]
tests DummyDigestController
@@ -51,17 +53,17 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials(:username => 'lifo', :password => 'world')
+ @request.env[header] = encode_credentials(username: "lifo", password: "world")
get :index
assert_response :success
- assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
+ assert_equal "Hello Secret", @response.body, "Authentication failed for request header #{header}"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials(:username => 'h4x0r', :password => 'world')
+ @request.env[header] = encode_credentials(username: "h4x0r", password: "world")
get :index
assert_response :unauthorized
@@ -74,21 +76,21 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
assert_response :unauthorized
assert_equal "Authentication Failed", @response.body
- credentials = decode_credentials(@response.headers['WWW-Authenticate'])
- assert_equal 'SuperSecret', credentials[:realm]
+ credentials = decode_credentials(@response.headers["WWW-Authenticate"])
+ assert_equal "SuperSecret", credentials[:realm]
end
test "authentication request with nil credentials" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: nil, password: nil)
get :index
assert_response :unauthorized
assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request"
- assert_not_equal 'Hello Secret', @response.body, "Authentication didn't fail for request"
+ assert_not_equal "Hello Secret", @response.body, "Authentication didn't fail for request"
end
test "authentication request with invalid password" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "foo")
get :display
assert_response :unauthorized
@@ -96,7 +98,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
end
test "authentication request with invalid nonce" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :nonce => "xxyyzz")
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please", nonce: "xxyyzz")
get :display
assert_response :unauthorized
@@ -104,7 +106,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
end
test "authentication request with invalid opaque" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :opaque => "xxyyzz")
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "foo", opaque: "xxyyzz")
get :display
assert_response :unauthorized
@@ -112,7 +114,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
end
test "authentication request with invalid realm" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo', :realm => "NotSecret")
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "foo", realm: "NotSecret")
get :display
assert_response :unauthorized
@@ -120,127 +122,128 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
end
test "authentication request with valid credential" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with valid credential and nil session" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with request-uri that doesn't match credentials digest-uri" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
- @request.env['PATH_INFO'] = "/proxied/uri"
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
+ @request.env["PATH_INFO"] = "/proxied/uri"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with absolute request uri (as in webrick)" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
@request.env["SERVER_NAME"] = "test.host"
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest"
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with absolute uri in credentials (as in IE)" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
- :username => 'pretty', :password => 'please')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(url: "http://test.host/http_digest_authentication_test/dummy_digest",
+ username: "pretty", password: "please")
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with absolute uri in both request and credentials (as in Webrick with IE)" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest",
- :username => 'pretty', :password => 'please')
- @request.env['SERVER_NAME'] = "test.host"
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest"
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(url: "http://test.host/http_digest_authentication_test/dummy_digest",
+ username: "pretty", password: "please")
+ @request.env["SERVER_NAME"] = "test.host"
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with password stored as ha1 digest hash" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'dhh',
- :password => ::Digest::MD5::hexdigest(["dhh","SuperSecret","secret"].join(":")),
- :password_is_ha1 => true)
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(
+ username: "dhh",
+ password: ::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")),
+ password_is_ha1: true)
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with _method" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :method => :post)
- @request.env['rack.methodoverride.original_method'] = 'POST'
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please", method: :post)
+ @request.env["rack.methodoverride.original_method"] = "POST"
put :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "validate_digest_response should fail with nil returning password_procedure" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
- assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: nil, password: nil)
+ assert_not ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret") { nil }
end
test "authentication request with request-uri ending in '/'" do
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest/"
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest/"
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
# simulate normalizing PATH_INFO
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest"
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with request-uri ending in '?'" do
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest/?"
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please')
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest/?"
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(username: "pretty", password: "please")
# simulate normalizing PATH_INFO
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest"
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "authentication request with absolute uri in credentials (as in IE) ending with /" do
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest/"
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:uri => "http://test.host/http_digest_authentication_test/dummy_digest/",
- :username => 'pretty', :password => 'please')
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest/"
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials(uri: "http://test.host/http_digest_authentication_test/dummy_digest/",
+ username: "pretty", password: "please")
# simulate normalizing PATH_INFO
- @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest"
+ @request.env["PATH_INFO"] = "/http_digest_authentication_test/dummy_digest"
get :display
assert_response :success
- assert_equal 'Definitely Maybe', @response.body
+ assert_equal "Definitely Maybe", @response.body
end
test "when sent a basic auth header, returns Unauthorized" do
- @request.env['HTTP_AUTHORIZATION'] = 'Basic Gwf2aXq8ZLF3Hxq='
+ @request.env["HTTP_AUTHORIZATION"] = "Basic Gwf2aXq8ZLF3Hxq="
get :display
@@ -249,32 +252,32 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
private
- def encode_credentials(options)
- options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b", :password_is_ha1 => false)
- password = options.delete(:password)
+ def encode_credentials(options)
+ options.reverse_merge!(nc: "00000001", cnonce: "0a4f113b", password_is_ha1: false)
+ password = options.delete(:password)
- # Perform unauthenticated request to retrieve digest parameters to use on subsequent request
- method = options.delete(:method) || 'GET'
+ # Perform unauthenticated request to retrieve digest parameters to use on subsequent request
+ method = options.delete(:method) || "GET"
- case method.to_s.upcase
- when 'GET'
- get :index
- when 'POST'
- post :index
- end
+ case method.to_s.upcase
+ when "GET"
+ get :index
+ when "POST"
+ post :index
+ end
- assert_response :unauthorized
+ assert_response :unauthorized
- credentials = decode_credentials(@response.headers['WWW-Authenticate'])
- credentials.merge!(options)
- path_info = @request.env['PATH_INFO'].to_s
- uri = options[:uri] || path_info
- credentials.merge!(:uri => uri)
- @request.env["ORIGINAL_FULLPATH"] = path_info
- ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
- end
+ credentials = decode_credentials(@response.headers["WWW-Authenticate"])
+ credentials.merge!(options)
+ path_info = @request.env["PATH_INFO"].to_s
+ uri = options[:uri] || path_info
+ credentials[:uri] = uri
+ @request.env["ORIGINAL_FULLPATH"] = path_info
+ ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
+ end
- def decode_credentials(header)
- ActionController::HttpAuthentication::Digest.decode_credentials(header)
- end
+ def decode_credentials(header)
+ ActionController::HttpAuthentication::Digest.decode_credentials(header)
+ end
end
diff --git a/actionpack/test/controller/http_token_authentication_test.rb b/actionpack/test/controller/http_token_authentication_test.rb
index 9c5a01c318..103123f98c 100644
--- a/actionpack/test/controller/http_token_authentication_test.rb
+++ b/actionpack/test/controller/http_token_authentication_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class HttpTokenAuthenticationTest < ActionController::TestCase
class DummyController < ActionController::Base
@@ -11,67 +13,67 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
def display
- render plain: 'Definitely Maybe'
+ render plain: "Definitely Maybe"
end
def show
- render plain: 'Only for loooooong credentials'
+ render plain: "Only for loooooong credentials"
end
private
- def authenticate
- authenticate_or_request_with_http_token do |token, _|
- token == 'lifo'
+ def authenticate
+ authenticate_or_request_with_http_token do |token, _|
+ token == "lifo"
+ end
end
- end
- def authenticate_with_request
- if authenticate_with_http_token { |token, options| token == '"quote" pretty' && options[:algorithm] == 'test' }
- @logged_in = true
- else
- request_http_token_authentication("SuperSecret", "Authentication Failed\n")
+ def authenticate_with_request
+ if authenticate_with_http_token { |token, options| token == '"quote" pretty' && options[:algorithm] == "test" }
+ @logged_in = true
+ else
+ request_http_token_authentication("SuperSecret", "Authentication Failed\n")
+ end
end
- end
- def authenticate_long_credentials
- authenticate_or_request_with_http_token do |token, options|
- token == '1234567890123456789012345678901234567890' && options[:algorithm] == 'test'
+ def authenticate_long_credentials
+ authenticate_or_request_with_http_token do |token, options|
+ token == "1234567890123456789012345678901234567890" && options[:algorithm] == "test"
+ end
end
- end
end
- AUTH_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION']
+ AUTH_HEADERS = ["HTTP_AUTHORIZATION", "X-HTTP_AUTHORIZATION", "X_HTTP_AUTHORIZATION", "REDIRECT_X_HTTP_AUTHORIZATION"]
tests DummyController
AUTH_HEADERS.each do |header|
test "successful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials('lifo')
+ @request.env[header] = encode_credentials("lifo")
get :index
assert_response :success
- assert_equal 'Hello Secret', @response.body, "Authentication failed for request header #{header}"
+ assert_equal "Hello Secret", @response.body, "Authentication failed for request header #{header}"
end
test "successful authentication with #{header.downcase} and long credentials" do
- @request.env[header] = encode_credentials('1234567890123456789012345678901234567890', :algorithm => 'test')
+ @request.env[header] = encode_credentials("1234567890123456789012345678901234567890", algorithm: "test")
get :show
assert_response :success
- assert_equal 'Only for loooooong credentials', @response.body, "Authentication failed for request header #{header} and long credentials"
+ assert_equal "Only for loooooong credentials", @response.body, "Authentication failed for request header #{header} and long credentials"
end
end
AUTH_HEADERS.each do |header|
test "unsuccessful authentication with #{header.downcase}" do
- @request.env[header] = encode_credentials('h4x0r')
+ @request.env[header] = encode_credentials("h4x0r")
get :index
assert_response :unauthorized
assert_equal "HTTP Token: Access denied.\n", @response.body, "Authentication didn't fail for request header #{header}"
end
test "unsuccessful authentication with #{header.downcase} and long credentials" do
- @request.env[header] = encode_credentials('h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r')
+ @request.env[header] = encode_credentials("h4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0rh4x0r")
get :show
assert_response :unauthorized
@@ -80,7 +82,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
test "authentication request with badly formatted header" do
- @request.env['HTTP_AUTHORIZATION'] = 'Token token$"lifo"'
+ @request.env["HTTP_AUTHORIZATION"] = 'Token token$"lifo"'
get :index
assert_response :unauthorized
@@ -88,10 +90,18 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
test "successful authentication request with Bearer instead of Token" do
- @request.env['HTTP_AUTHORIZATION'] = 'Bearer lifo'
+ @request.env["HTTP_AUTHORIZATION"] = "Bearer lifo"
+ get :index
+
+ assert_response :success
+ end
+
+ test "authentication request with tab in header" do
+ @request.env["HTTP_AUTHORIZATION"] = "Token\ttoken=\"lifo\""
get :index
assert_response :success
+ assert_equal "Hello Secret", @response.body
end
test "authentication request without credential" do
@@ -99,16 +109,16 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
assert_response :unauthorized
assert_equal "Authentication Failed\n", @response.body
- assert_equal 'Token realm="SuperSecret"', @response.headers['WWW-Authenticate']
+ assert_equal 'Token realm="SuperSecret"', @response.headers["WWW-Authenticate"]
end
test "authentication request with invalid credential" do
- @request.env['HTTP_AUTHORIZATION'] = encode_credentials('"quote" pretty')
+ @request.env["HTTP_AUTHORIZATION"] = encode_credentials('"quote" pretty')
get :display
assert_response :unauthorized
assert_equal "Authentication Failed\n", @response.body
- assert_equal 'Token realm="SuperSecret"', @response.headers['WWW-Authenticate']
+ assert_equal 'Token realm="SuperSecret"', @response.headers["WWW-Authenticate"]
end
test "token_and_options returns correct token" do
@@ -119,7 +129,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
test "token_and_options returns correct token with value after the equal sign" do
- token = 'rcHu+=HzSFw89Ypyhn/896A==f34'
+ token = "rcHu+=HzSFw89Ypyhn/896A==f34"
actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token)).first
expected = token
assert_equal(expected, actual)
@@ -140,7 +150,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
test "token_and_options returns empty string with empty token" do
- token = ''
+ token = +""
actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token)).first
expected = token
assert_equal(expected, actual)
@@ -148,18 +158,17 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
test "token_and_options returns correct token with nounce option" do
token = "rcHu+HzSFw89Ypyhn/896A="
- nonce_hash = {nonce: "123abc"}
+ 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]}
+ 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)
+ assert_nil actual
end
test "raw_params returns a tuple of two key value pair strings" do
@@ -182,7 +191,7 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
private
- def sample_request(token, options = {nonce: "def"})
+ def sample_request(token, options = { nonce: "def" })
authorization = options.inject([%{Token token="#{token}"}]) do |arr, (k, v)|
arr << "#{k}=\"#{v}\""
end.join(", ")
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index d0a1d1285f..39ede1442a 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -1,10 +1,12 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
-require 'rails/engine'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
+require "rails/engine"
class SessionTest < ActiveSupport::TestCase
StubApp = lambda { |env|
- [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, ["Hello, World!"]]
+ [200, { "Content-Type" => "text/html", "Content-Length" => "13" }, ["Hello, World!"]]
}
def setup
@@ -12,11 +14,11 @@ class SessionTest < ActiveSupport::TestCase
end
def test_https_bang_works_and_sets_truth_by_default
- assert !@session.https?
+ assert_not_predicate @session, :https?
@session.https!
- assert @session.https?
+ assert_predicate @session, :https?
@session.https! false
- assert !@session.https?
+ assert_not_predicate @session, :https?
end
def test_host!
@@ -31,95 +33,8 @@ class SessionTest < ActiveSupport::TestCase
end
end
- def test_request_via_redirect_uses_given_method
- path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
- assert_called_with @session, :process, [:put, path, params: args, headers: headers] do
- @session.stub :redirect?, false do
- @session.request_via_redirect(:put, path, params: args, headers: headers)
- end
- end
- end
-
- def test_deprecated_request_via_redirect_uses_given_method
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
- assert_called_with @session, :process, [:put, path, params: args, headers: headers] do
- @session.stub :redirect?, false do
- assert_deprecated { @session.request_via_redirect(:put, path, args, headers) }
- end
- end
- end
-
- def test_request_via_redirect_follows_redirects
- path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
- value_series = [true, true, false]
- assert_called @session, :follow_redirect!, times: 2 do
- @session.stub :redirect?, ->{ value_series.shift } do
- @session.request_via_redirect(:get, path, params: args, headers: headers)
- end
- end
- end
-
- def test_request_via_redirect_returns_status
- path = "/somepath"; args = {:id => '1'}; headers = {"X-Test-Header" => "testvalue"}
- @session.stub :redirect?, false do
- @session.stub :status, 200 do
- assert_equal 200, @session.request_via_redirect(:get, path, params: args, headers: headers)
- end
- end
- end
-
- def test_deprecated_get_via_redirect
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
-
- assert_called_with @session, :request_via_redirect, [:get, path, args, headers] do
- assert_deprecated do
- @session.get_via_redirect(path, args, headers)
- end
- end
- end
-
- def test_deprecated_post_via_redirect
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
-
- assert_called_with @session, :request_via_redirect, [:post, path, args, headers] do
- assert_deprecated do
- @session.post_via_redirect(path, args, headers)
- end
- end
- end
-
- def test_deprecated_patch_via_redirect
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
-
- assert_called_with @session, :request_via_redirect, [:patch, path, args, headers] do
- assert_deprecated do
- @session.patch_via_redirect(path, args, headers)
- end
- end
- end
-
- def test_deprecated_put_via_redirect
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
-
- assert_called_with @session, :request_via_redirect, [:put, path, args, headers] do
- assert_deprecated do
- @session.put_via_redirect(path, args, headers)
- end
- end
- end
-
- def test_deprecated_delete_via_redirect
- path = "/somepath"; args = { id: '1' }; headers = { "X-Test-Header" => "testvalue" }
-
- assert_called_with @session, :request_via_redirect, [:delete, path, args, headers] do
- assert_deprecated do
- @session.delete_via_redirect(path, args, headers)
- end
- end
- end
-
def test_get
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:get, path, params: params, headers: headers] do
@session.get(path, params: params, headers: headers)
@@ -127,229 +42,88 @@ class SessionTest < ActiveSupport::TestCase
end
def test_get_with_env_and_headers
- path = "/index"; params = "blah"; headers = { location: 'blah' }; env = { 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }; env = { "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest" }
assert_called_with @session, :process, [:get, path, params: params, headers: headers, env: env] do
@session.get(path, params: params, headers: headers, env: env)
end
end
- def test_deprecated_get
- path = "/index"; params = "blah"; headers = { location: 'blah' }
-
- assert_called_with @session, :process, [:get, path, params: params, headers: headers] do
- assert_deprecated {
- @session.get(path, params, headers)
- }
- end
- end
-
def test_post
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:post, path, params: params, headers: headers] do
- assert_deprecated {
- @session.post(path, params, headers)
- }
- end
- end
-
- def test_deprecated_post
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:post, path, params: params, headers: headers] do
@session.post(path, params: params, headers: headers)
end
end
def test_patch
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:patch, path, params: params, headers: headers] do
@session.patch(path, params: params, headers: headers)
end
end
- def test_deprecated_patch
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:patch, path, params: params, headers: headers] do
- assert_deprecated {
- @session.patch(path, params, headers)
- }
- end
- end
-
def test_put
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:put, path, params: params, headers: headers] do
@session.put(path, params: params, headers: headers)
end
end
- def test_deprecated_put
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:put, path, params: params, headers: headers] do
- assert_deprecated {
- @session.put(path, params, headers)
- }
- end
- end
-
def test_delete
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:delete, path, params: params, headers: headers] do
- assert_deprecated {
- @session.delete(path,params,headers)
- }
- end
- end
-
- def test_deprecated_delete
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:delete, path, params: params, headers: headers] do
@session.delete(path, params: params, headers: headers)
end
end
def test_head
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:head, path, params: params, headers: headers] do
@session.head(path, params: params, headers: headers)
end
end
- def deprecated_test_head
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:head, path, params: params, headers: headers] do
- assert_deprecated {
- @session.head(path, params, headers)
- }
- end
- end
-
def test_xml_http_request_get
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:get, path, params: params, headers: headers, xhr: true] do
- @session.get(path, params: params, headers: headers, xhr: true)
- end
- end
-
- def test_deprecated_xml_http_request_get
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:get, path, params: params, headers: headers, xhr: true] do
@session.get(path, params: params, headers: headers, xhr: true)
end
end
- def test_deprecated_args_xml_http_request_get
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:get, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) {
- @session.xml_http_request(:get, path, params, headers)
- }
- end
- end
-
def test_xml_http_request_post
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:post, path, params: params, headers: headers, xhr: true] do
@session.post(path, params: params, headers: headers, xhr: true)
end
end
- def test_deprecated_xml_http_request_post
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:post, path, params: params, headers: headers, xhr: true] do
- @session.post(path, params: params, headers: headers, xhr: true)
- end
- end
-
- def test_deprecated_args_xml_http_request_post
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:post, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) { @session.xml_http_request(:post,path,params,headers) }
- end
- end
-
def test_xml_http_request_patch
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:patch, path, params: params, headers: headers, xhr: true] do
@session.patch(path, params: params, headers: headers, xhr: true)
end
end
- def test_deprecated_xml_http_request_patch
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:patch, path, params: params, headers: headers, xhr: true] do
- @session.patch(path, params: params, headers: headers, xhr: true)
- end
- end
-
- def test_deprecated_args_xml_http_request_patch
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:patch, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) { @session.xml_http_request(:patch,path,params,headers) }
- end
- end
-
def test_xml_http_request_put
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:put, path, params: params, headers: headers, xhr: true] do
@session.put(path, params: params, headers: headers, xhr: true)
end
end
- def test_deprecated_xml_http_request_put
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:put, path, params: params, headers: headers, xhr: true] do
- @session.put(path, params: params, headers: headers, xhr: true)
- end
- end
-
- def test_deprecated_args_xml_http_request_put
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:put, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) { @session.xml_http_request(:put, path, params, headers) }
- end
- end
-
def test_xml_http_request_delete
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:delete, path, params: params, headers: headers, xhr: true] do
@session.delete(path, params: params, headers: headers, xhr: true)
end
end
- def test_deprecated_xml_http_request_delete
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:delete, path, params: params, headers: headers, xhr: true] do
- assert_deprecated { @session.xml_http_request(:delete, path, params: params, headers: headers) }
- end
- end
-
- def test_deprecated_args_xml_http_request_delete
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:delete, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) { @session.xml_http_request(:delete, path, params, headers) }
- end
- end
-
def test_xml_http_request_head
- path = "/index"; params = "blah"; headers = { location: 'blah' }
+ path = "/index"; params = "blah"; headers = { location: "blah" }
assert_called_with @session, :process, [:head, path, params: params, headers: headers, xhr: true] do
@session.head(path, params: params, headers: headers, xhr: true)
end
end
-
- def test_deprecated_xml_http_request_head
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:head, path, params: params, headers: headers, xhr: true] do
- assert_deprecated(/xml_http_request/) { @session.xml_http_request(:head, path, params: params, headers: headers) }
- end
- end
-
- def test_deprecated_args_xml_http_request_head
- path = "/index"; params = "blah"; headers = { location: 'blah' }
- assert_called_with @session, :process, [:head, path, params: params, headers: headers, xhr: true] do
- assert_deprecated { @session.xml_http_request(:head, path, params, headers) }
- end
- end
end
class IntegrationTestTest < ActiveSupport::TestCase
@@ -361,7 +135,7 @@ class IntegrationTestTest < ActiveSupport::TestCase
session1 = @test.open_session { |sess| }
session2 = @test.open_session # implicit session
- assert !session1.equal?(session2)
+ assert_not session1.equal?(session2)
end
# RSpec mixes Matchers (which has a #method_missing) into
@@ -370,12 +144,12 @@ class IntegrationTestTest < ActiveSupport::TestCase
def test_does_not_prevent_method_missing_passing_up_to_ancestors
mixin = Module.new do
def method_missing(name, *args)
- name.to_s == 'foo' ? 'pass' : super
+ name.to_s == "foo" ? "pass" : super
end
end
- @test.class.superclass.__send__(:include, mixin)
+ @test.class.superclass.include(mixin)
begin
- assert_equal 'pass', @test.foo
+ assert_equal "pass", @test.foo
ensure
# leave other tests as unaffected as possible
mixin.__send__(:remove_method, :method_missing)
@@ -390,7 +164,7 @@ class IntegrationTestUsesCorrectClass < ActionDispatch::IntegrationTest
reset!
%w( get post head patch put delete ).each do |verb|
- assert_nothing_raised("'#{verb}' should use integration test methods") { __send__(verb, '/') }
+ assert_nothing_raised { __send__(verb, "/") }
end
end
end
@@ -401,9 +175,10 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
respond_to do |format|
format.html { render plain: "OK", status: 200 }
format.js { render plain: "JS OK", status: 200 }
- format.xml { render :xml => "<root></root>", :status => 200 }
- format.rss { render :xml => "<root></root>", :status => 200 }
- format.atom { render :xml => "<root></root>", :status => 200 }
+ format.json { render json: "JSON OK", status: 200 }
+ format.xml { render xml: "<root></root>", status: 200 }
+ format.rss { render xml: "<root></root>", status: 200 }
+ format.atom { render xml: "<root></root>", status: 200 }
end
end
@@ -426,7 +201,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
end
def set_cookie
- cookies["foo"] = 'bar'
+ cookies["foo"] = "bar"
head :ok
end
@@ -435,18 +210,18 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
end
def redirect
- redirect_to action_url('get')
+ redirect_to action_url("get")
end
def remove_header
response.headers.delete params[:header]
- head :ok, 'c' => '3'
+ head :ok, "c" => "3"
end
end
def test_get
with_test_route_set do
- get '/get'
+ get "/get"
assert_equal 200, status
assert_equal "OK", status_message
assert_response 200
@@ -463,7 +238,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_get_xml_rss_atom
%w[ application/xml application/rss+xml application/atom+xml ].each do |mime_string|
with_test_route_set do
- get "/get", headers: {"HTTP_ACCEPT" => mime_string}
+ get "/get", headers: { "HTTP_ACCEPT" => mime_string }
assert_equal 200, status
assert_equal "OK", status_message
assert_response 200
@@ -480,7 +255,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_post
with_test_route_set do
- post '/post'
+ post "/post"
assert_equal 201, status
assert_equal "Created", status_message
assert_response 201
@@ -494,55 +269,55 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
end
end
- test 'response cookies are added to the cookie jar for the next request' do
+ test "response cookies are added to the cookie jar for the next request" do
with_test_route_set do
- self.cookies['cookie_1'] = "sugar"
- self.cookies['cookie_2'] = "oatmeal"
- get '/cookie_monster'
+ cookies["cookie_1"] = "sugar"
+ cookies["cookie_2"] = "oatmeal"
+ get "/cookie_monster"
assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"]
- assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies.to_hash)
+ assert_equal({ "cookie_1" => "", "cookie_2" => "oatmeal", "cookie_3" => "chocolate" }, cookies.to_hash)
end
end
- test 'cookie persist to next request' do
+ test "cookie persist to next request" do
with_test_route_set do
- get '/set_cookie'
+ get "/set_cookie"
assert_response :success
assert_equal "foo=bar; path=/", headers["Set-Cookie"]
- assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ assert_equal({ "foo" => "bar" }, cookies.to_hash)
- get '/get_cookie'
+ get "/get_cookie"
assert_response :success
assert_equal "bar", body
- assert_equal nil, headers["Set-Cookie"]
- assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ assert_nil headers["Set-Cookie"]
+ assert_equal({ "foo" => "bar" }, cookies.to_hash)
end
end
- test 'cookie persist to next request on another domain' do
+ test "cookie persist to next request on another domain" do
with_test_route_set do
host! "37s.backpack.test"
- get '/set_cookie'
+ get "/set_cookie"
assert_response :success
assert_equal "foo=bar; path=/", headers["Set-Cookie"]
- assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ assert_equal({ "foo" => "bar" }, cookies.to_hash)
- get '/get_cookie'
+ get "/get_cookie"
assert_response :success
assert_equal "bar", body
- assert_equal nil, headers["Set-Cookie"]
- assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ assert_nil headers["Set-Cookie"]
+ assert_equal({ "foo" => "bar" }, cookies.to_hash)
end
end
def test_redirect
with_test_route_set do
- get '/redirect'
+ get "/redirect"
assert_equal 302, status
assert_equal "Found", status_message
assert_response 302
@@ -556,27 +331,37 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
assert_response :success
assert_equal "/get", path
- get '/moved'
+ get "/moved"
assert_response :redirect
- assert_redirected_to '/method'
+ assert_redirected_to "/method"
end
end
- def test_xml_http_request_get
+ def test_redirect_reset_html_document
with_test_route_set do
- get '/get', xhr: true
- assert_equal 200, status
- assert_equal "OK", status_message
- assert_response 200
- assert_response :success
+ get "/redirect"
+ previous_html_document = html_document
+
+ follow_redirect!
+
assert_response :ok
- assert_equal "JS OK", response.body
+ assert_not_same previous_html_document, html_document
+ end
+ end
+
+ def test_redirect_with_arguments
+ with_test_route_set do
+ get "/redirect"
+ follow_redirect! params: { foo: :bar }
+
+ assert_response :ok
+ assert_equal "bar", request.parameters["foo"]
end
end
- def test_deprecated_xml_http_request_get
+ def test_xml_http_request_get
with_test_route_set do
- assert_deprecated { xhr :get, '/get' }
+ get "/get", xhr: true
assert_equal 200, status
assert_equal "OK", status_message
assert_response 200
@@ -588,21 +373,29 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_request_with_bad_format
with_test_route_set do
- get '/get.php', xhr: true
+ get "/get.php", xhr: true
assert_equal 406, status
assert_response 406
assert_response :not_acceptable
end
end
+ test "creation of multiple integration sessions" do
+ integration_session # initialize first session
+ a = open_session
+ b = open_session
+
+ assert_not_same(a.integration_session, b.integration_session)
+ end
+
def test_get_with_query_string
with_test_route_set do
- get '/get_with_params?foo=bar'
- assert_equal '/get_with_params?foo=bar', request.env["REQUEST_URI"]
- assert_equal '/get_with_params?foo=bar', request.fullpath
+ get "/get_with_params?foo=bar"
+ assert_equal "/get_with_params?foo=bar", request.env["REQUEST_URI"]
+ assert_equal "/get_with_params?foo=bar", request.fullpath
assert_equal "foo=bar", request.env["QUERY_STRING"]
- assert_equal 'foo=bar', request.query_string
- assert_equal 'bar', request.parameters['foo']
+ assert_equal "foo=bar", request.query_string
+ assert_equal "bar", request.parameters["foo"]
assert_equal 200, status
assert_equal "foo: bar", response.body
@@ -611,77 +404,91 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_get_with_parameters
with_test_route_set do
- get '/get_with_params', params: { foo: "bar" }
- assert_equal '/get_with_params', request.env["PATH_INFO"]
- assert_equal '/get_with_params', request.path_info
- assert_equal 'foo=bar', request.env["QUERY_STRING"]
- assert_equal 'foo=bar', request.query_string
- assert_equal 'bar', request.parameters['foo']
+ get "/get_with_params", params: { foo: "bar" }
+ assert_equal "/get_with_params", request.env["PATH_INFO"]
+ assert_equal "/get_with_params", request.path_info
+ assert_equal "foo=bar", request.env["QUERY_STRING"]
+ assert_equal "foo=bar", request.query_string
+ assert_equal "bar", request.parameters["foo"]
assert_equal 200, status
assert_equal "foo: bar", response.body
end
end
+ def test_post_then_get_with_parameters_do_not_leak_across_requests
+ with_test_route_set do
+ post "/post", params: { leaks: "does-leak?" }
+
+ get "/get_with_params", params: { foo: "bar" }
+
+ assert_empty request.env["rack.input"].string
+ assert_equal "foo=bar", request.env["QUERY_STRING"]
+ assert_equal "foo=bar", request.query_string
+ assert_equal "bar", request.parameters["foo"]
+ assert_predicate request.parameters["leaks"], :nil?
+ end
+ end
+
def test_head
with_test_route_set do
- head '/get'
+ head "/get"
assert_equal 200, status
assert_equal "", body
- head '/post'
+ head "/post"
assert_equal 201, status
assert_equal "", body
- get '/get/method'
+ get "/get/method"
assert_equal 200, status
assert_equal "method: get", body
- head '/get/method'
+ head "/get/method"
assert_equal 200, status
assert_equal "", body
end
end
def test_generate_url_with_controller
- assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
+ assert_equal "http://www.example.com/foo", url_for(controller: "foo")
end
def test_port_via_host!
with_test_route_set do
- host! 'www.example.com:8080'
- get '/get'
+ host! "www.example.com:8080"
+ get "/get"
assert_equal 8080, request.port
end
end
def test_port_via_process
with_test_route_set do
- get 'http://www.example.com:8080/get'
+ get "http://www.example.com:8080/get"
assert_equal 8080, request.port
end
end
def test_https_and_port_via_host_and_https!
with_test_route_set do
- host! 'www.example.com'
+ host! "www.example.com"
https! true
- get '/get'
+ get "/get"
assert_equal 443, request.port
assert_equal true, request.ssl?
- host! 'www.example.com:443'
+ host! "www.example.com:443"
https! true
- get '/get'
+ get "/get"
assert_equal 443, request.port
assert_equal true, request.ssl?
- host! 'www.example.com:8443'
+ host! "www.example.com:8443"
https! true
- get '/get'
+ get "/get"
assert_equal 8443, request.port
assert_equal true, request.ssl?
end
@@ -689,11 +496,11 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_https_and_port_via_process
with_test_route_set do
- get 'https://www.example.com/get'
+ get "https://www.example.com/get"
assert_equal 443, request.port
assert_equal true, request.ssl?
- get 'https://www.example.com:8443/get'
+ get "https://www.example.com:8443/get"
assert_equal 8443, request.port
assert_equal true, request.ssl?
end
@@ -701,14 +508,26 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
def test_respect_removal_of_default_headers_by_a_controller_action
with_test_route_set do
- with_default_headers 'a' => '1', 'b' => '2' do
- get '/remove_header', params: { header: 'a' }
+ with_default_headers "a" => "1", "b" => "2" do
+ get "/remove_header", params: { header: "a" }
end
end
- assert_not_includes @response.headers, 'a', 'Response should not include default header removed by the controller action'
- assert_includes @response.headers, 'b'
- assert_includes @response.headers, 'c'
+ assert_not_includes @response.headers, "a", "Response should not include default header removed by the controller action"
+ assert_includes @response.headers, "b"
+ assert_includes @response.headers, "c"
+ end
+
+ def test_accept_not_overridden_when_xhr_true
+ with_test_route_set do
+ get "/get", headers: { "Accept" => "application/json" }, xhr: true
+ assert_equal "application/json", request.accept
+ assert_equal "application/json", response.content_type
+
+ get "/get", headers: { "HTTP_ACCEPT" => "application/json" }, xhr: true
+ assert_equal "application/json", request.accept
+ assert_equal "application/json", response.content_type
+ end
end
private
@@ -728,13 +547,15 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
end
set.draw do
- get 'moved' => redirect('/method')
+ get "moved" => redirect("/method")
- match ':action', :to => controller, :via => [:get, :post], :as => :action
- get 'get/:action', :to => controller, :as => :get_action
+ ActiveSupport::Deprecation.silence do
+ match ":action", to: controller, via: [:get, :post], as: :action
+ get "get/:action", to: controller, as: :get_action
+ end
end
- self.singleton_class.include(set.url_helpers)
+ singleton_class.include(set.url_helpers)
yield
end
@@ -747,9 +568,9 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest
class Poller
def self.call(env)
if env["PATH_INFO"] =~ /^\/success/
- [200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, ["Hello World!"]]
+ [200, { "Content-Type" => "text/plain", "Content-Length" => "12" }, ["Hello World!"]]
else
- [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
+ [404, { "Content-Type" => "text/plain", "Content-Length" => "0" }, []]
end
end
end
@@ -770,15 +591,15 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest
get "/failure"
assert_response 404
assert_response :not_found
- assert_equal '', response.body
+ assert_equal "", response.body
end
def test_generate_url_without_controller
- assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
+ assert_equal "http://www.example.com/foo", url_for(controller: "foo")
end
def test_pass_headers
- get "/success", headers: {"Referer" => "http://www.example.com/foo", "Host" => "http://nohost.com"}
+ get "/success", headers: { "Referer" => "http://www.example.com/foo", "Host" => "http://nohost.com" }
assert_equal "http://nohost.com", @request.env["HTTP_HOST"]
assert_equal "http://www.example.com/foo", @request.env["HTTP_REFERER"]
@@ -817,7 +638,6 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest
get "https://test.com:80"
assert_equal "test.com:80", @request.env["HTTP_HOST"]
end
-
end
class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
@@ -841,7 +661,7 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
end
routes.draw do
- get 'baz', :to => 'application_integration_test/test#index', :as => :baz
+ get "baz", to: "application_integration_test/test#index", as: :baz
end
def self.call(*)
@@ -849,14 +669,14 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
end
routes.draw do
- get '', :to => 'application_integration_test/test#index', :as => :empty_string
+ get "", to: "application_integration_test/test#index", as: :empty_string
- get 'foo', :to => 'application_integration_test/test#index', :as => :foo
- get 'bar', :to => 'application_integration_test/test#index', :as => :bar
+ get "foo", to: "application_integration_test/test#index", as: :foo
+ get "bar", to: "application_integration_test/test#index", as: :bar
- mount MountedApp => '/mounted', :as => "mounted"
- get 'fooz' => proc { |env| [ 200, {'X-Cascade' => 'pass'}, [ "omg" ] ] }, :anchor => false
- get 'fooz', :to => 'application_integration_test/test#index'
+ mount MountedApp => "/mounted", :as => "mounted"
+ get "fooz" => proc { |env| [ 200, { "X-Cascade" => "pass" }, [ "omg" ] ] }, :anchor => false
+ get "fooz", to: "application_integration_test/test#index"
end
def app
@@ -864,30 +684,30 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
end
test "includes route helpers" do
- assert_equal '/', empty_string_path
- assert_equal '/foo', foo_path
- assert_equal '/bar', bar_path
+ assert_equal "/", empty_string_path
+ assert_equal "/foo", foo_path
+ assert_equal "/bar", bar_path
end
test "includes mounted helpers" do
- assert_equal '/mounted/baz', mounted.baz_path
+ assert_equal "/mounted/baz", mounted.baz_path
end
test "path after cascade pass" do
- get '/fooz'
- assert_equal 'index', response.body
- assert_equal '/fooz', path
+ get "/fooz"
+ assert_equal "index", response.body
+ assert_equal "/fooz", path
end
test "route helpers after controller access" do
- get '/'
- assert_equal '/', empty_string_path
+ get "/"
+ assert_equal "/", empty_string_path
- get '/foo'
- assert_equal '/foo', foo_path
+ get "/foo"
+ assert_equal "/foo", foo_path
- get '/bar'
- assert_equal '/bar', bar_path
+ get "/bar"
+ assert_equal "/bar", bar_path
end
test "missing route helper before controller access" do
@@ -895,14 +715,14 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
end
test "missing route helper after controller access" do
- get '/foo'
+ get "/foo"
assert_raise(NameError) { missing_path }
end
test "process do not modify the env passed as argument" do
- env = { :SERVER_NAME => 'server', 'action_dispatch.custom' => 'custom' }
+ env = { :SERVER_NAME => "server", "action_dispatch.custom" => "custom" }
old_env = env.dup
- get '/foo', env: env
+ get "/foo", env: env
assert_equal old_env, env
end
end
@@ -924,7 +744,7 @@ class EnvironmentFilterIntegrationTest < ActionDispatch::IntegrationTest
end
routes.draw do
- match '/post', :to => 'environment_filter_integration_test/test#post', :via => :post
+ match "/post", to: "environment_filter_integration_test/test#post", via: :post
end
def app
@@ -932,11 +752,11 @@ class EnvironmentFilterIntegrationTest < ActionDispatch::IntegrationTest
end
test "filters rack request form vars" do
- post "/post", params: { username: 'cjolly', password: 'secret' }
+ post "/post", params: { username: "cjolly", password: "secret" }
- assert_equal 'cjolly', request.filtered_parameters['username']
- assert_equal '[FILTERED]', request.filtered_parameters['password']
- assert_equal '[FILTERED]', request.filtered_env['rack.request.form_vars']
+ assert_equal "cjolly", request.filtered_parameters["username"]
+ assert_equal "[FILTERED]", request.filtered_parameters["password"]
+ assert_equal "[FILTERED]", request.filtered_env["rack.request.form_vars"]
end
end
@@ -957,7 +777,7 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
class BarController < ActionController::Base
def default_url_options
- { :host => "bar.com" }
+ { host: "bar.com" }
end
def index
@@ -978,9 +798,9 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
end
routes.draw do
- default_url_options :host => "foo.com"
+ default_url_options host: "foo.com"
- scope :module => "url_options_integration_test" do
+ scope module: "url_options_integration_test" do
get "/foo" => "foo#index", :as => :foos
get "/foo/:id" => "foo#show", :as => :foo
get "/foo/:id/edit" => "foo#edit", :as => :edit_foo
@@ -1020,7 +840,7 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
test "current request path parameters are recalled" do
get "/foo/1"
assert_response :success
- assert_equal "/foo/1/edit", url_for(:action => 'edit', :only_path => true)
+ assert_equal "/foo/1/edit", url_for(action: "edit", only_path: true)
end
end
@@ -1044,12 +864,12 @@ class HeadWithStatusActionIntegrationTest < ActionDispatch::IntegrationTest
end
routes.draw do
- get "/foo/status" => 'head_with_status_action_integration_test/foo#status'
+ get "/foo/status" => "head_with_status_action_integration_test/foo#status"
end
test "get /foo/status with head result does not cause stack overflow error" do
assert_nothing_raised do
- get '/foo/status'
+ get "/foo/status"
end
assert_response :ok
end
@@ -1058,7 +878,7 @@ end
class IntegrationWithRoutingTest < ActionDispatch::IntegrationTest
class FooController < ActionController::Base
def index
- render plain: 'ok'
+ render plain: "ok"
end
end
@@ -1068,25 +888,25 @@ class IntegrationWithRoutingTest < ActionDispatch::IntegrationTest
with_routing do |routes|
routes.draw do
namespace klass_namespace do
- resources :foo, path: '/with'
+ resources :foo, path: "/with"
end
end
- get '/integration_with_routing_test/with'
+ get "/integration_with_routing_test/with"
assert_response 200
- assert_equal 'ok', response.body
+ assert_equal "ok", response.body
end
with_routing do |routes|
routes.draw do
namespace klass_namespace do
- resources :foo, path: '/routing'
+ resources :foo, path: "/routing"
end
end
- get '/integration_with_routing_test/routing'
+ get "/integration_with_routing_test/routing"
assert_response 200
- assert_equal 'ok', response.body
+ assert_equal "ok", response.body
end
end
end
@@ -1098,19 +918,24 @@ class IntegrationRequestsWithoutSetup < ActionDispatch::IntegrationTest
class FooController < ActionController::Base
def ok
- cookies[:key] = 'ok'
- render plain: 'ok'
+ cookies[:key] = "ok"
+ render plain: "ok"
end
end
def test_request
with_routing do |routes|
- routes.draw { get ':action' => FooController }
- get '/ok'
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action" => FooController
+ end
+ end
+
+ get "/ok"
assert_response 200
- assert_equal 'ok', response.body
- assert_equal 'ok', cookies['key']
+ assert_equal "ok", response.body
+ assert_equal "ok", cookies["key"]
end
end
end
@@ -1118,11 +943,204 @@ end
# to ensure that session requirements in setup are persisted in the tests
class IntegrationRequestsWithSessionSetup < ActionDispatch::IntegrationTest
setup do
- cookies['user_name'] = 'david'
+ cookies["user_name"] = "david"
end
def test_cookies_set_in_setup_are_persisted_through_the_session
get "/foo"
- assert_equal({"user_name"=>"david"}, cookies.to_hash)
+ assert_equal({ "user_name" => "david" }, cookies.to_hash)
+ end
+end
+
+class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
+ class FooController < ActionController::Base
+ def foos
+ render plain: "ok"
+ end
+
+ def foos_json
+ render json: params.permit(:foo)
+ end
+
+ def foos_wibble
+ render plain: "ok"
+ end
+ end
+
+ def test_standard_json_encoding_works
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ post ":action" => FooController
+ end
+ end
+
+ post "/foos_json.json", params: { foo: "fighters" }.to_json,
+ headers: { "Content-Type" => "application/json" }
+
+ assert_response :success
+ assert_equal({ "foo" => "fighters" }, response.parsed_body)
+ end
+ end
+
+ def test_encoding_as_json
+ post_to_foos as: :json do
+ assert_response :success
+ assert_equal "application/json", request.content_type
+ assert_equal "application/json", request.accepts.first.to_s
+ assert_equal :json, request.format.ref
+ assert_equal({ "foo" => "fighters" }, request.request_parameters)
+ assert_equal({ "foo" => "fighters" }, response.parsed_body)
+ end
+ end
+
+ def test_doesnt_mangle_request_path
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ post ":action" => FooController
+ end
+ end
+
+ post "/foos"
+ assert_equal "/foos", request.path
+
+ post "/foos_json", as: :json
+ assert_equal "/foos_json", request.path
+ end
+ end
+
+ def test_encoding_as_without_mime_registration
+ assert_raise ArgumentError do
+ ActionDispatch::IntegrationTest.register_encoder :wibble
+ end
+ end
+
+ def test_registering_custom_encoder
+ Mime::Type.register "text/wibble", :wibble
+
+ ActionDispatch::IntegrationTest.register_encoder(:wibble,
+ param_encoder: -> params { params })
+
+ post_to_foos as: :wibble do
+ assert_response :success
+ assert_equal "/foos_wibble", request.path
+ assert_equal "text/wibble", request.content_type
+ assert_equal "text/wibble", request.accepts.first.to_s
+ assert_equal :wibble, request.format.ref
+ assert_equal Hash.new, request.request_parameters # Unregistered MIME Type can't be parsed.
+ assert_equal "ok", response.parsed_body
+ end
+ ensure
+ Mime::Type.unregister :wibble
+ end
+
+ def test_parsed_body_without_as_option
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action" => FooController
+ end
+ end
+
+ get "/foos_json.json", params: { foo: "heyo" }
+
+ assert_equal({ "foo" => "heyo" }, response.parsed_body)
+ end
+ end
+
+ def test_get_parameters_with_as_option
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action" => FooController
+ end
+ end
+
+ get "/foos_json?foo=heyo", as: :json
+
+ assert_equal({ "foo" => "heyo" }, response.parsed_body)
+ end
+ end
+
+ def test_get_request_with_json_uses_method_override_and_sends_a_post_request
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action" => FooController
+ end
+ end
+
+ get "/foos_json", params: { foo: "heyo" }, as: :json
+
+ assert_equal "POST", request.method
+ assert_equal "GET", request.headers["X-Http-Method-Override"]
+ assert_equal({ "foo" => "heyo" }, response.parsed_body)
+ end
+ end
+
+ def test_get_request_with_json_excludes_null_query_string
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ":action" => FooController
+ end
+ end
+
+ get "/foos_json", as: :json
+
+ assert_equal "http://www.example.com/foos_json", request.url
+ end
+ end
+
+ private
+ def post_to_foos(as:)
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ post ":action" => FooController
+ end
+ end
+
+ post "/foos_#{as}", params: { foo: "fighters" }, as: as
+
+ yield
+ end
+ end
+end
+
+class IntegrationFileUploadTest < ActionDispatch::IntegrationTest
+ class IntegrationController < ActionController::Base
+ def test_file_upload
+ render plain: params[:file].size
+ end
+ end
+
+ def self.routes
+ @routes ||= ActionDispatch::Routing::RouteSet.new
+ end
+
+ def self.call(env)
+ routes.call(env)
+ end
+
+ def app
+ self.class
+ end
+
+ def self.fixture_path
+ File.expand_path("../fixtures/multipart", __dir__)
+ end
+
+ routes.draw do
+ post "test_file_upload", to: "integration_file_upload_test/integration#test_file_upload"
+ end
+
+ def test_fixture_file_upload
+ post "/test_file_upload",
+ params: {
+ file: fixture_file_upload("/ruby_on_rails.jpg", "image/jpg")
+ }
+ assert_equal "45142", @response.body
end
end
diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb
index 843dafac06..d81c43b87d 100644
--- a/actionpack/test/controller/live_stream_test.rb
+++ b/actionpack/test/controller/live_stream_test.rb
@@ -1,5 +1,8 @@
-require 'abstract_unit'
-require 'concurrent/atomic/count_down_latch'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "timeout"
+require "concurrent/atomic/count_down_latch"
Thread.abort_on_exception = true
module ActionController
@@ -8,10 +11,10 @@ module ActionController
include ActionController::Live
def basic_sse
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
sse = SSE.new(response.stream)
sse.write("{\"name\":\"John\"}")
- sse.write({ name: "Ryan" })
+ sse.write(name: "Ryan")
ensure
sse.close
end
@@ -19,7 +22,7 @@ module ActionController
def sse_with_event
sse = SSE.new(response.stream, event: "send-name")
sse.write("{\"name\":\"John\"}")
- sse.write({ name: "Ryan" })
+ sse.write(name: "Ryan")
ensure
sse.close
end
@@ -27,7 +30,7 @@ module ActionController
def sse_with_retry
sse = SSE.new(response.stream, retry: 1000)
sse.write("{\"name\":\"John\"}")
- sse.write({ name: "Ryan" }, retry: 1500)
+ sse.write({ name: "Ryan" }, { retry: 1500 })
ensure
sse.close
end
@@ -35,7 +38,7 @@ module ActionController
def sse_with_id
sse = SSE.new(response.stream)
sse.write("{\"name\":\"John\"}", id: 1)
- sse.write({ name: "Ryan" }, id: 2)
+ sse.write({ name: "Ryan" }, { id: 2 })
ensure
sse.close
end
@@ -115,7 +118,7 @@ module ActionController
attr_accessor :latch, :tc, :error_latch
def self.controller_path
- 'test'
+ "test"
end
def set_cookie
@@ -125,7 +128,7 @@ module ActionController
end
def render_text
- render plain: 'zomg'
+ render plain: "zomg"
end
def default_header
@@ -134,7 +137,7 @@ module ActionController
end
def basic_stream
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
%w{ hello world }.each do |word|
response.stream.write word
end
@@ -142,7 +145,7 @@ module ActionController
end
def blocking_stream
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
%w{ hello world }.each do |word|
response.stream.write word
latch.wait
@@ -150,11 +153,26 @@ module ActionController
response.stream.close
end
+ def write_sleep_autoload
+ path = File.expand_path("../fixtures", __dir__)
+ ActiveSupport::Dependencies.autoload_paths << path
+
+ response.headers["Content-Type"] = "text/event-stream"
+ response.stream.write "before load"
+ sleep 0.01
+ silence_warning do
+ ::LoadMe
+ end
+ response.stream.close
+ latch.count_down
+
+ ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path }
+ end
+
def thread_locals
- tc.assert_equal 'aaron', Thread.current[:setting]
- tc.assert_not_equal Thread.current.object_id, Thread.current[:originating_thread]
+ tc.assert_equal "aaron", Thread.current[:setting]
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
%w{ hello world }.each do |word|
response.stream.write word
end
@@ -162,20 +180,20 @@ module ActionController
end
def with_stale
- render plain: 'stale' if stale?(etag: "123", template: false)
+ render plain: "stale" if stale?(etag: "123", template: false)
end
def exception_in_view
- render 'doesntexist'
+ render "doesntexist"
end
def exception_in_view_after_commit
response.stream.write ""
- render 'doesntexist'
+ render "doesntexist"
end
def exception_with_callback
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
response.stream.on_error do
response.stream.write %(data: "500 Internal Server Error"\n\n)
@@ -183,11 +201,11 @@ module ActionController
end
response.stream.write "" # make sure the response is committed
- raise 'An exception occurred...'
+ raise "An exception occurred..."
end
def exception_in_controller
- raise Exception, 'Exception in controller'
+ raise Exception, "Exception in controller"
end
def bad_request_error
@@ -195,50 +213,50 @@ module ActionController
end
def exception_in_exception_callback
- response.headers['Content-Type'] = 'text/event-stream'
+ response.headers["Content-Type"] = "text/event-stream"
response.stream.on_error do
- raise 'We need to go deeper.'
+ raise "We need to go deeper."
end
- response.stream.write ''
+ response.stream.write ""
response.stream.write params[:widget][:didnt_check_for_nil]
end
def overfill_buffer_and_die
logger = ActionController::Base.logger || Logger.new($stdout)
response.stream.on_error do
- logger.warn 'Error while streaming'
+ logger.warn "Error while streaming."
error_latch.count_down
end
# Write until the buffer is full. It doesn't expose that
# information directly, so we must hard-code its size:
10.times do
- response.stream.write '.'
+ response.stream.write "."
end
# .. plus one more, because the #each frees up a slot:
- response.stream.write '.'
+ response.stream.write "."
latch.count_down
# This write will block, and eventually raise
- response.stream.write 'x'
+ response.stream.write "x"
20.times do
- response.stream.write '.'
+ response.stream.write "."
end
end
def ignore_client_disconnect
response.stream.ignore_disconnect = true
- response.stream.write '' # commit
+ response.stream.write "" # commit
# These writes will be ignored
15.times do
- response.stream.write 'x'
+ response.stream.write "x"
end
- logger.info 'Work complete'
+ logger.info "Work complete"
latch.count_down
end
end
@@ -246,8 +264,9 @@ module ActionController
tests TestController
def assert_stream_closed
- assert response.stream.closed?, 'stream should be closed'
- assert response.sent?, 'stream should be sent'
+ assert response.stream.closed?, "stream should be closed"
+ assert response.committed?, "response should be committed"
+ assert response.sent?, "response should be sent"
end
def capture_log_output
@@ -261,23 +280,39 @@ module ActionController
end
end
+ def setup
+ super
+
+ def @controller.new_controller_thread
+ Thread.new { yield }
+ end
+ end
+
def test_set_cookie
get :set_cookie
- assert_equal({'hello' => 'world'}, @response.cookies)
+ assert_equal({ "hello" => "world" }, @response.cookies)
assert_equal "hello world", @response.body
end
def test_write_to_stream
get :basic_stream
assert_equal "helloworld", @response.body
- assert_equal 'text/event-stream', @response.headers['Content-Type']
+ assert_equal "text/event-stream", @response.headers["Content-Type"]
+ end
+
+ def test_delayed_autoload_after_write_within_interlock_hook
+ # Simulate InterlockHook
+ ActiveSupport::Dependencies.interlock.start_running
+ res = get :write_sleep_autoload
+ res.each { }
+ ActiveSupport::Dependencies.interlock.done_running
end
def test_async_stream
rubinius_skip "https://github.com/rubinius/rubinius/issues/2934"
@controller.latch = Concurrent::CountDownLatch.new
- parts = ['hello', 'world']
+ parts = ["hello", "world"]
get :blocking_stream
@@ -291,7 +326,7 @@ module ActionController
end
}
- assert t.join(3), 'timeout expired before the thread terminated'
+ assert t.join(3), "timeout expired before the thread terminated"
end
def test_abort_with_full_buffer
@@ -299,7 +334,7 @@ module ActionController
@controller.error_latch = Concurrent::CountDownLatch.new
capture_log_output do |output|
- get :overfill_buffer_and_die, :format => 'plain'
+ get :overfill_buffer_and_die, format: "plain"
t = Thread.new(response) { |resp|
resp.await_commit
@@ -313,7 +348,7 @@ module ActionController
t.join
@controller.error_latch.wait
- assert_match 'Error while streaming', output.rewind && output.read
+ assert_match "Error while streaming", output.rewind && output.read
end
end
@@ -336,26 +371,26 @@ module ActionController
Timeout.timeout(3) do
@controller.latch.wait
end
- assert_match 'Work complete', output.rewind && output.read
+ assert_match "Work complete", output.rewind && output.read
end
end
def test_thread_locals_get_copied
@controller.tc = self
Thread.current[:originating_thread] = Thread.current.object_id
- Thread.current[:setting] = 'aaron'
+ Thread.current[:setting] = "aaron"
get :thread_locals
end
def test_live_stream_default_header
get :default_header
- assert response.headers['Content-Type']
+ assert response.headers["Content-Type"]
end
def test_render_text
get :render_text
- assert_equal 'zomg', response.body
+ assert_equal "zomg", response.body
assert_stream_closed
end
@@ -367,7 +402,7 @@ module ActionController
capture_log_output do |output|
get :exception_in_view_after_commit
assert_match %r((window\.location = "/500\.html"</script></html>)$), response.body
- assert_match 'Missing template test/doesntexist', output.rewind && output.read
+ assert_match "Missing template test/doesntexist", output.rewind && output.read
assert_stream_closed
end
assert response.body
@@ -381,8 +416,8 @@ module ActionController
capture_log_output do |output|
get :exception_in_view_after_commit, format: :json
- assert_equal '', response.body
- assert_match 'Missing template test/doesntexist', output.rewind && output.read
+ assert_equal "", response.body
+ assert_match "Missing template test/doesntexist", output.rewind && output.read
assert_stream_closed
end
end
@@ -391,34 +426,34 @@ module ActionController
current_threads = Thread.list
capture_log_output do |output|
- get :exception_with_callback, format: 'text/event-stream'
+ get :exception_with_callback, format: "text/event-stream"
# Wait on the execution of all threads
(Thread.list - current_threads).each(&:join)
assert_equal %(data: "500 Internal Server Error"\n\n), response.body
- assert_match 'An exception occurred...', output.rewind && output.read
+ assert_match "An exception occurred...", output.rewind && output.read
assert_stream_closed
end
end
def test_exception_in_controller_before_streaming
assert_raises(ActionController::LiveStreamTest::Exception) do
- get :exception_in_controller, format: 'text/event-stream'
+ get :exception_in_controller, format: "text/event-stream"
end
end
def test_bad_request_in_controller_before_streaming
assert_raises(ActionController::BadRequest) do
- get :bad_request_error, format: 'text/event-stream'
+ get :bad_request_error, format: "text/event-stream"
end
end
def test_exceptions_raised_handling_exceptions_and_committed
capture_log_output do |output|
- get :exception_in_exception_callback, format: 'text/event-stream'
- assert_equal '', response.body
- assert_match 'We need to go deeper', output.rewind && output.read
+ get :exception_in_exception_callback, format: "text/event-stream"
+ assert_equal "", response.body
+ assert_match "We need to go deeper", output.rewind && output.read
assert_stream_closed
end
end
@@ -429,7 +464,7 @@ module ActionController
end
def test_stale_with_etag
- @request.if_none_match = Digest::MD5.hexdigest("123")
+ @request.if_none_match = %(W/"#{ActiveSupport::Digest.hexdigest('123')}")
get :with_stale
assert_equal 304, response.status.to_i
end
@@ -442,3 +477,42 @@ module ActionController
end
end
end
+
+class LiveStreamRouterTest < ActionDispatch::IntegrationTest
+ class TestController < ActionController::Base
+ include ActionController::Live
+
+ def index
+ response.headers["Content-Type"] = "text/event-stream"
+ sse = SSE.new(response.stream)
+ sse.write("{\"name\":\"John\"}")
+ sse.write(name: "Ryan")
+ ensure
+ sse.close
+ end
+ end
+
+ def self.call(env)
+ routes.call(env)
+ end
+
+ def self.routes
+ @routes ||= ActionDispatch::Routing::RouteSet.new
+ end
+
+ routes.draw do
+ get "/test" => "live_stream_router_test/test#index"
+ end
+
+ def app
+ self.class
+ end
+
+ test "streaming served through the router" do
+ get "/test"
+
+ assert_response :ok
+ assert_match(/data: {\"name\":\"John\"}/, response.body)
+ assert_match(/data: {\"name\":\"Ryan\"}/, response.body)
+ end
+end
diff --git a/actionpack/test/controller/localized_templates_test.rb b/actionpack/test/controller/localized_templates_test.rb
index 3576015513..d84a76fb46 100644
--- a/actionpack/test/controller/localized_templates_test.rb
+++ b/actionpack/test/controller/localized_templates_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class LocalizedController < ActionController::Base
def hello_world
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index 6ae33be3c8..0562c16284 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -1,10 +1,12 @@
+# frozen_string_literal: true
+
require "abstract_unit"
require "active_support/log_subscriber/test_helper"
require "action_controller/log_subscriber"
module Another
class LogSubscribersController < ActionController::Base
- wrap_parameters :person, :include => :name, :format => :json
+ wrap_parameters :person, include: :name, format: :json
class SpecialException < Exception
end
@@ -31,7 +33,7 @@ module Another
end
def data_sender
- send_data "cool data", :filename => "file.txt"
+ send_data "cool data", filename: "file.txt"
end
def file_sender
@@ -39,27 +41,27 @@ module Another
end
def with_fragment_cache
- render :inline => "<%= cache('foo'){ 'bar' } %>"
+ render inline: "<%= cache('foo'){ 'bar' } %>"
end
def with_fragment_cache_and_percent_in_key
- render :inline => "<%= cache('foo%bar'){ 'Contains % sign in key' } %>"
+ render inline: "<%= cache('foo%bar'){ 'Contains % sign in key' } %>"
end
def with_fragment_cache_if_with_true_condition
- render :inline => "<%= cache_if(true, 'foo') { 'bar' } %>"
+ render inline: "<%= cache_if(true, 'foo') { 'bar' } %>"
end
def with_fragment_cache_if_with_false_condition
- render :inline => "<%= cache_if(false, 'foo') { 'bar' } %>"
+ render inline: "<%= cache_if(false, 'foo') { 'bar' } %>"
end
def with_fragment_cache_unless_with_false_condition
- render :inline => "<%= cache_unless(false, 'foo') { 'bar' } %>"
+ render inline: "<%= cache_unless(false, 'foo') { 'bar' } %>"
end
def with_fragment_cache_unless_with_true_condition
- render :inline => "<%= cache_unless(true, 'foo') { 'bar' } %>"
+ render inline: "<%= cache_unless(true, 'foo') { 'bar' } %>"
end
def with_exception
@@ -80,9 +82,7 @@ module Another
@last_payload = payload
end
- def last_payload
- @last_payload
- end
+ attr_reader :last_payload
end
end
@@ -92,10 +92,11 @@ class ACLogSubscriberTest < ActionController::TestCase
def setup
super
+ ActionController::Base.enable_fragment_cache_logging = true
@old_logger = ActionController::Base.logger
- @cache_path = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('tmp', 'cache')
+ @cache_path = Dir.mktmpdir(%w[tmp cache])
@controller.cache_store = :file_store, @cache_path
ActionController::LogSubscriber.attach_to :action_controller
end
@@ -105,6 +106,7 @@ class ACLogSubscriberTest < ActionController::TestCase
ActiveSupport::LogSubscriber.log_subscribers.clear
FileUtils.rm_rf(@cache_path)
ActionController::Base.logger = @old_logger
+ ActionController::Base.enable_fragment_cache_logging = true
end
def set_logger(logger)
@@ -136,11 +138,11 @@ class ACLogSubscriberTest < ActionController::TestCase
def test_process_action_without_parameters
get :show
wait
- assert_nil logs.detect {|l| l =~ /Parameters/ }
+ assert_nil logs.detect { |l| l =~ /Parameters/ }
end
def test_process_action_with_parameters
- get :show, params: { id: '10' }
+ get :show, params: { id: "10" }
wait
assert_equal 3, logs.size
@@ -148,8 +150,8 @@ class ACLogSubscriberTest < ActionController::TestCase
end
def test_multiple_process_with_parameters
- get :show, params: { id: '10' }
- get :show, params: { id: '20' }
+ get :show, params: { id: "10" }
+ get :show, params: { id: "20" }
wait
@@ -159,8 +161,8 @@ class ACLogSubscriberTest < ActionController::TestCase
end
def test_process_action_with_wrapped_parameters
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :show, params: { id: '10', name: 'jose' }
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :show, params: { id: "10", name: "jose" }
wait
assert_equal 3, logs.size
@@ -183,11 +185,17 @@ class ACLogSubscriberTest < ActionController::TestCase
assert_equal "test_value", @controller.last_payload[:test_key]
end
+ def test_process_action_headers
+ get :show
+ wait
+ assert_equal "Rails Testing", @controller.last_payload[:headers]["User-Agent"]
+ end
+
def test_process_action_with_filter_parameters
@request.env["action_dispatch.parameter_filter"] = [:lifo, :amount]
get :show, params: {
- lifo: 'Pratik', amount: '420', step: '1'
+ lifo: "Pratik", amount: "420", step: "1"
}
wait
@@ -206,7 +214,7 @@ class ACLogSubscriberTest < ActionController::TestCase
end
def test_filter_redirect_url_by_string
- @request.env['action_dispatch.redirect_filter'] = ['secret']
+ @request.env["action_dispatch.redirect_filter"] = ["secret"]
get :filterable_redirector
wait
@@ -215,7 +223,7 @@ class ACLogSubscriberTest < ActionController::TestCase
end
def test_filter_redirect_url_by_regexp
- @request.env['action_dispatch.redirect_filter'] = [/secret\.foo.+/]
+ @request.env["action_dispatch.redirect_filter"] = [/secret\.foo.+/]
get :filterable_redirector
wait
@@ -252,6 +260,20 @@ class ACLogSubscriberTest < ActionController::TestCase
@controller.config.perform_caching = true
end
+ def test_with_fragment_cache_when_log_disabled
+ @controller.config.perform_caching = true
+ ActionController::Base.enable_fragment_cache_logging = false
+ get :with_fragment_cache
+ wait
+
+ assert_equal 2, logs.size
+ assert_equal "Processing by Another::LogSubscribersController#with_fragment_cache as HTML", logs[0]
+ assert_match(/Completed 200 OK in \d+ms/, logs[1])
+ ensure
+ @controller.config.perform_caching = true
+ ActionController::Base.enable_fragment_cache_logging = true
+ end
+
def test_with_fragment_cache_if_with_true
@controller.config.perform_caching = true
get :with_fragment_cache_if_with_true_condition
diff --git a/actionpack/test/controller/metal/renderers_test.rb b/actionpack/test/controller/metal/renderers_test.rb
new file mode 100644
index 0000000000..5f0d125128
--- /dev/null
+++ b/actionpack/test/controller/metal/renderers_test.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/core_ext/hash/conversions"
+
+class MetalRenderingController < ActionController::Metal
+ include AbstractController::Rendering
+ include ActionController::Rendering
+ include ActionController::Renderers
+end
+
+class MetalRenderingJsonController < MetalRenderingController
+ class Model
+ def to_json(options = {})
+ { a: "b" }.to_json(options)
+ end
+
+ def to_xml(options = {})
+ { a: "b" }.to_xml(options)
+ end
+ end
+
+ use_renderers :json
+
+ def one
+ render json: Model.new
+ end
+
+ def two
+ render xml: Model.new
+ end
+end
+
+class RenderersMetalTest < ActionController::TestCase
+ tests MetalRenderingJsonController
+
+ def test_render_json
+ get :one
+ assert_response :success
+ assert_equal({ a: "b" }.to_json, @response.body)
+ assert_equal "application/json", @response.content_type
+ end
+
+ def test_render_xml
+ get :two
+ assert_response :success
+ assert_equal(" ", @response.body)
+ assert_equal "text/plain", @response.content_type
+ end
+end
diff --git a/actionpack/test/controller/metal_test.rb b/actionpack/test/controller/metal_test.rb
new file mode 100644
index 0000000000..7b53092266
--- /dev/null
+++ b/actionpack/test/controller/metal_test.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class MetalControllerInstanceTests < ActiveSupport::TestCase
+ class SimpleController < ActionController::Metal
+ def hello
+ self.response_body = "hello"
+ end
+ end
+
+ def test_response_does_not_have_default_headers
+ original_default_headers = ActionDispatch::Response.default_headers
+
+ ActionDispatch::Response.default_headers = {
+ "X-Frame-Options" => "DENY",
+ "X-Content-Type-Options" => "nosniff",
+ "X-XSS-Protection" => "1;"
+ }
+
+ response_headers = SimpleController.action("hello").call(
+ "REQUEST_METHOD" => "GET",
+ "rack.input" => -> { }
+ )[1]
+
+ assert_not response_headers.key?("X-Frame-Options")
+ assert_not response_headers.key?("X-Content-Type-Options")
+ assert_not response_headers.key?("X-XSS-Protection")
+ ensure
+ ActionDispatch::Response.default_headers = original_default_headers
+ end
+end
diff --git a/actionpack/test/controller/mime/accept_format_test.rb b/actionpack/test/controller/mime/accept_format_test.rb
index e20c08da4e..eed671d593 100644
--- a/actionpack/test/controller/mime/accept_format_test.rb
+++ b/actionpack/test/controller/mime/accept_format_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class StarStarMimeController < ActionController::Base
layout nil
@@ -11,7 +13,7 @@ end
class StarStarMimeControllerTest < ActionController::TestCase
def test_javascript_with_format
@request.accept = "text/javascript"
- get :index, format: 'js'
+ get :index, format: "js"
assert_match "function addition(a,b){ return a+b; }", @response.body
end
@@ -29,7 +31,7 @@ class StarStarMimeControllerTest < ActionController::TestCase
end
class AbstractPostController < ActionController::Base
- self.view_paths = File.dirname(__FILE__) + "/../../fixtures/post_test/"
+ self.view_paths = File.expand_path("../../fixtures/post_test", __dir__)
end
# For testing layouts which are set automatically
@@ -40,7 +42,7 @@ class PostController < AbstractPostController
respond_to(:html, :iphone, :js)
end
-protected
+private
def with_iphone
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
@@ -71,7 +73,7 @@ class MimeControllerLayoutsTest < ActionController::TestCase
@request.accept = "text/iphone"
get :index
- assert_equal 'Hello iPhone', @response.body
+ assert_equal "Hello iPhone", @response.body
end
def test_format_with_inherited_layouts
diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb
index c025c7fa00..00e1d5f3b3 100644
--- a/actionpack/test/controller/mime/respond_to_test.rb
+++ b/actionpack/test/controller/mime/respond_to_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
require "active_support/log_subscriber/test_helper"
class RespondToController < ActionController::Base
@@ -45,13 +47,12 @@ class RespondToController < ActionController::Base
def json_xml_or_html
respond_to do |type|
- type.json { render body: 'JSON' }
- type.xml { render :xml => 'XML' }
- type.html { render body: 'HTML' }
+ type.json { render body: "JSON" }
+ type.xml { render xml: "XML" }
+ type.html { render body: "HTML" }
end
end
-
def forced_xml
request.format = :xml
@@ -74,6 +75,14 @@ class RespondToController < ActionController::Base
end
end
+ def missing_templates
+ respond_to do |type|
+ # This test requires a block that is empty
+ type.json { }
+ type.xml
+ end
+ end
+
def using_defaults_with_type_list
respond_to(:html, :xml)
end
@@ -93,6 +102,26 @@ class RespondToController < ActionController::Base
end
end
+ def using_conflicting_nested_js_then_html
+ respond_to do |outer_type|
+ outer_type.js do
+ respond_to do |inner_type|
+ inner_type.html { render body: "HTML" }
+ end
+ end
+ end
+ end
+
+ def using_non_conflicting_nested_js_then_js
+ respond_to do |outer_type|
+ outer_type.js do
+ respond_to do |inner_type|
+ inner_type.js { render body: "JS" }
+ end
+ end
+ end
+ end
+
def custom_type_handling
respond_to do |type|
type.html { render body: "HTML" }
@@ -101,7 +130,6 @@ class RespondToController < ActionController::Base
end
end
-
def custom_constant_handling
respond_to do |type|
type.html { render body: "HTML" }
@@ -125,8 +153,8 @@ class RespondToController < ActionController::Base
def handle_any_any
respond_to do |type|
- type.html { render body: 'HTML' }
- type.any { render body: 'Whatever you ask for, I got it' }
+ type.html { render body: "HTML" }
+ type.any { render body: "Whatever you ask for, I got it" }
end
end
@@ -138,7 +166,7 @@ class RespondToController < ActionController::Base
def json_with_callback
respond_to do |type|
- type.json { render :json => 'JS', :callback => 'alert' }
+ type.json { render json: "JS", callback: "alert" }
end
end
@@ -155,12 +183,19 @@ class RespondToController < ActionController::Base
request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
respond_to do |type|
- type.html { @type = "Firefox"; render :action => "iphone_with_html_response_type" }
- type.iphone { @type = "iPhone" ; render :action => "iphone_with_html_response_type" }
+ type.html { @type = "Firefox"; render action: "iphone_with_html_response_type" }
+ type.iphone { @type = "iPhone" ; render action: "iphone_with_html_response_type" }
end
end
- def variant_with_implicit_rendering
+ def variant_with_implicit_template_rendering
+ # This has exactly one variant template defined in the file system (+mobile.html.erb),
+ # which raises the regular MissingTemplate error for other variants.
+ end
+
+ def variant_without_implicit_template_rendering
+ # This differs from the above in that it does not have any templates defined in the file
+ # system, which triggers the ImplicitRender (204 No Content) behavior.
end
def variant_with_format_and_custom_render
@@ -208,7 +243,7 @@ class RespondToController < ActionController::Base
def variant_any
respond_to do |format|
format.html do |variant|
- variant.any(:tablet, :phablet){ render body: "any" }
+ variant.any(:tablet, :phablet) { render body: "any" }
variant.phone { render body: "phone" }
end
end
@@ -225,7 +260,7 @@ class RespondToController < ActionController::Base
def variant_inline_any
respond_to do |format|
- format.html.any(:tablet, :phablet){ render body: "any" }
+ format.html.any(:tablet, :phablet) { render body: "any" }
format.html.phone { render body: "phone" }
end
end
@@ -246,7 +281,7 @@ class RespondToController < ActionController::Base
def variant_any_with_none
respond_to do |format|
- format.html.any(:none, :phone){ render body: "none or phone" }
+ format.html.any(:none, :phone) { render body: "none or phone" }
end
end
@@ -254,24 +289,26 @@ class RespondToController < ActionController::Base
respond_to do |format|
format.html { render body: "HTML" }
format.any(:js, :xml) do |variant|
- variant.phone{ render body: "phone" }
- variant.any(:tablet, :phablet){ render body: "tablet" }
+ variant.phone { render body: "phone" }
+ variant.any(:tablet, :phablet) { render body: "tablet" }
end
end
end
- protected
+ private
def set_layout
case action_name
- when "all_types_with_layout", "iphone_with_html_response_type"
- "respond_to/layouts/standard"
- when "iphone_with_html_response_type_without_layout"
- "respond_to/layouts/missing"
+ when "all_types_with_layout", "iphone_with_html_response_type"
+ "respond_to/layouts/standard"
+ when "iphone_with_html_response_type_without_layout"
+ "respond_to/layouts/missing"
end
end
end
class RespondToControllerTest < ActionController::TestCase
+ NO_CONTENT_WARNING = "No template found for RespondToController#variant_without_implicit_template_rendering, rendering head :no_content"
+
def setup
super
@request.host = "www.example.com"
@@ -288,10 +325,10 @@ class RespondToControllerTest < ActionController::TestCase
def test_html
@request.accept = "text/html"
get :js_or_html
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
get :html_or_xml
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
assert_raises(ActionController::UnknownFormat) do
get :just_xml
@@ -301,29 +338,29 @@ class RespondToControllerTest < ActionController::TestCase
def test_all
@request.accept = "*/*"
get :js_or_html
- assert_equal 'HTML', @response.body # js is not part of all
+ assert_equal "HTML", @response.body # js is not part of all
get :html_or_xml
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
get :just_xml
- assert_equal 'XML', @response.body
+ assert_equal "XML", @response.body
end
def test_xml
@request.accept = "application/xml"
get :html_xml_or_rss
- assert_equal 'XML', @response.body
+ assert_equal "XML", @response.body
end
def test_js_or_html
@request.accept = "text/javascript, text/html"
get :js_or_html, xhr: true
- assert_equal 'JS', @response.body
+ assert_equal "JS", @response.body
@request.accept = "text/javascript, text/html"
get :html_or_xml, xhr: true
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
@request.accept = "text/javascript, text/html"
@@ -335,25 +372,25 @@ class RespondToControllerTest < ActionController::TestCase
def test_json_or_yaml_with_leading_star_star
@request.accept = "*/*, application/json"
get :json_xml_or_html
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
@request.accept = "*/* , application/json"
get :json_xml_or_html
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_json_or_yaml
get :json_or_yaml, xhr: true
- assert_equal 'JSON', @response.body
+ assert_equal "JSON", @response.body
- get :json_or_yaml, format: 'json'
- assert_equal 'JSON', @response.body
+ get :json_or_yaml, format: "json"
+ assert_equal "JSON", @response.body
- get :json_or_yaml, format: 'yaml'
- assert_equal 'YAML', @response.body
+ get :json_or_yaml, format: "yaml"
+ assert_equal "YAML", @response.body
- { 'YAML' => %w(text/yaml),
- 'JSON' => %w(application/json text/x-json)
+ { "YAML" => %w(text/yaml),
+ "JSON" => %w(application/json text/x-json)
}.each do |body, content_types|
content_types.each do |content_type|
@request.accept = content_type
@@ -366,20 +403,20 @@ class RespondToControllerTest < ActionController::TestCase
def test_js_or_anything
@request.accept = "text/javascript, */*"
get :js_or_html, xhr: true
- assert_equal 'JS', @response.body
+ assert_equal "JS", @response.body
get :html_or_xml, xhr: true
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
get :just_xml, xhr: true
- assert_equal 'XML', @response.body
+ assert_equal "XML", @response.body
end
def test_using_defaults
@request.accept = "*/*"
get :using_defaults
assert_equal "text/html", @response.content_type
- assert_equal 'Hello world!', @response.body
+ assert_equal "Hello world!", @response.body
@request.accept = "application/xml"
get :using_defaults
@@ -405,7 +442,7 @@ class RespondToControllerTest < ActionController::TestCase
@request.accept = "*/*"
get :using_defaults_with_type_list
assert_equal "text/html", @response.content_type
- assert_equal 'Hello world!', @response.body
+ assert_equal "Hello world!", @response.body
@request.accept = "application/xml"
get :using_defaults_with_type_list
@@ -413,6 +450,20 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal "<p>Hello world!</p>\n", @response.body
end
+ def test_using_conflicting_nested_js_then_html
+ @request.accept = "*/*"
+ assert_raises(ActionController::RespondToMismatchError) do
+ get :using_conflicting_nested_js_then_html
+ end
+ end
+
+ def test_using_non_conflicting_nested_js_then_js
+ @request.accept = "*/*"
+ get :using_non_conflicting_nested_js_then_js
+ assert_equal "text/javascript", @response.content_type
+ assert_equal "JS", @response.body
+ end
+
def test_with_atom_content_type
@request.accept = ""
@request.env["CONTENT_TYPE"] = "application/atom+xml"
@@ -430,7 +481,7 @@ class RespondToControllerTest < ActionController::TestCase
def test_synonyms
@request.accept = "application/javascript"
get :js_or_html
- assert_equal 'JS', @response.body
+ assert_equal "JS", @response.body
@request.accept = "application/x-xml"
get :html_xml_or_rss
@@ -441,82 +492,82 @@ class RespondToControllerTest < ActionController::TestCase
@request.accept = "application/crazy-xml"
get :custom_type_handling
assert_equal "application/crazy-xml", @response.content_type
- assert_equal 'Crazy XML', @response.body
+ assert_equal "Crazy XML", @response.body
@request.accept = "text/html"
get :custom_type_handling
assert_equal "text/html", @response.content_type
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_xhtml_alias
@request.accept = "application/xhtml+xml,application/xml"
get :html_or_xml
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_firefox_simulation
@request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
get :html_or_xml
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_handle_any
@request.accept = "*/*"
get :handle_any
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
@request.accept = "text/javascript"
get :handle_any
- assert_equal 'Either JS or XML', @response.body
+ assert_equal "Either JS or XML", @response.body
@request.accept = "text/xml"
get :handle_any
- assert_equal 'Either JS or XML', @response.body
+ assert_equal "Either JS or XML", @response.body
end
def test_handle_any_any
@request.accept = "*/*"
get :handle_any_any
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_handle_any_any_parameter_format
- get :handle_any_any, format: 'html'
- assert_equal 'HTML', @response.body
+ get :handle_any_any, format: "html"
+ assert_equal "HTML", @response.body
end
def test_handle_any_any_explicit_html
@request.accept = "text/html"
get :handle_any_any
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_handle_any_any_javascript
@request.accept = "text/javascript"
get :handle_any_any
- assert_equal 'Whatever you ask for, I got it', @response.body
+ assert_equal "Whatever you ask for, I got it", @response.body
end
def test_handle_any_any_xml
@request.accept = "text/xml"
get :handle_any_any
- assert_equal 'Whatever you ask for, I got it', @response.body
+ assert_equal "Whatever you ask for, I got it", @response.body
end
- def test_handle_any_any_unkown_format
- get :handle_any_any, format: 'php'
- assert_equal 'Whatever you ask for, I got it', @response.body
+ def test_handle_any_any_unknown_format
+ get :handle_any_any, format: "php"
+ assert_equal "Whatever you ask for, I got it", @response.body
end
def test_browser_check_with_any_any
@request.accept = "application/json, application/xml"
get :json_xml_or_html
- assert_equal 'JSON', @response.body
+ assert_equal "JSON", @response.body
@request.accept = "application/json, application/xml, */*"
get :json_xml_or_html
- assert_equal 'HTML', @response.body
+ assert_equal "HTML", @response.body
end
def test_html_type_with_layout
@@ -526,15 +577,15 @@ class RespondToControllerTest < ActionController::TestCase
end
def test_json_with_callback_sets_javascript_content_type
- @request.accept = 'application/json'
+ @request.accept = "application/json"
get :json_with_callback
- assert_equal '/**/alert(JS)', @response.body
- assert_equal 'text/javascript', @response.content_type
+ assert_equal "/**/alert(JS)", @response.body
+ assert_equal "text/javascript", @response.content_type
end
def test_xhr
get :js_or_html, xhr: true
- assert_equal 'JS', @response.body
+ assert_equal "JS", @response.body
end
def test_custom_constant
@@ -615,31 +666,77 @@ class RespondToControllerTest < ActionController::TestCase
end
end
+ def test_missing_templates
+ get :missing_templates, format: :json
+ assert_response :no_content
+ get :missing_templates, format: :xml
+ assert_response :no_content
+ end
+
def test_invalid_variant
+ assert_raises(ActionController::UnknownFormat) do
+ get :variant_with_implicit_template_rendering, params: { v: :invalid }
+ end
+ end
+
+ def test_variant_not_set_regular_unknown_format
+ assert_raises(ActionController::UnknownFormat) do
+ get :variant_with_implicit_template_rendering
+ end
+ end
+
+ def test_variant_with_implicit_template_rendering
+ get :variant_with_implicit_template_rendering, params: { v: :mobile }
+ assert_equal "text/html", @response.content_type
+ assert_equal "mobile", @response.body
+ end
+
+ def test_variant_without_implicit_rendering_from_browser
+ assert_raises(ActionController::MissingExactTemplate) do
+ get :variant_without_implicit_template_rendering, params: { v: :does_not_matter }
+ end
+ end
+
+ def test_variant_variant_not_set_and_without_implicit_rendering_from_browser
+ assert_raises(ActionController::MissingExactTemplate) do
+ get :variant_without_implicit_template_rendering
+ end
+ end
+
+ def test_variant_without_implicit_rendering_from_xhr
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
- get :variant_with_implicit_rendering, params: { v: :invalid }
+ get :variant_without_implicit_template_rendering, xhr: true, params: { v: :does_not_matter }
assert_response :no_content
- assert_equal 1, logger.logged(:info).select{ |s| s =~ /No template found/ }.size, "Implicit head :no_content not logged"
+
+ assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
ensure
ActionController::Base.logger = old_logger
end
- def test_variant_not_set_regular_template_missing
- get :variant_with_implicit_rendering
+ def test_variant_without_implicit_rendering_from_api
+ logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
+ old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
+
+ get :variant_without_implicit_template_rendering, format: "json", params: { v: :does_not_matter }
assert_response :no_content
+
+ assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
+ ensure
+ ActionController::Base.logger = old_logger
end
- def test_variant_with_implicit_rendering
- get :variant_with_implicit_rendering, params: { v: :implicit }
+ def test_variant_variant_not_set_and_without_implicit_rendering_from_xhr
+ logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
+ old_logger, ActionController::Base.logger = ActionController::Base.logger, logger
+
+ get :variant_without_implicit_template_rendering, xhr: true
assert_response :no_content
- end
- def test_variant_with_implicit_template_rendering
- get :variant_with_implicit_rendering, params: { v: :mobile }
- assert_equal "text/html", @response.content_type
- assert_equal "mobile", @response.body
+ assert_equal 1, logger.logged(:info).select { |s| s == NO_CONTENT_WARNING }.size, "Implicit head :no_content not logged"
+ ensure
+ ActionController::Base.logger = old_logger
end
def test_variant_with_format_and_custom_render
@@ -661,10 +758,6 @@ class RespondToControllerTest < ActionController::TestCase
end
def test_variant_inline_syntax
- get :variant_inline_syntax, format: :js
- assert_equal "text/javascript", @response.content_type
- assert_equal "js", @response.body
-
get :variant_inline_syntax
assert_equal "text/html", @response.content_type
assert_equal "none", @response.body
@@ -674,6 +767,12 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal "phone", @response.body
end
+ def test_variant_inline_syntax_with_format
+ get :variant_inline_syntax, format: :js
+ assert_equal "text/javascript", @response.content_type
+ assert_equal "js", @response.body
+ end
+
def test_variant_inline_syntax_without_block
get :variant_inline_syntax_without_block, params: { v: :phone }
assert_equal "text/html", @response.content_type
@@ -776,24 +875,3 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal "phone", @response.body
end
end
-
-class RespondToWithBlockOnDefaultRenderController < ActionController::Base
- def show
- default_render do
- render body: 'default_render yielded'
- end
- end
-end
-
-class RespondToWithBlockOnDefaultRenderControllerTest < ActionController::TestCase
- def setup
- super
- @request.host = "www.example.com"
- end
-
- def test_default_render_uses_block_when_no_template_exists
- get :show
- assert_equal "default_render yielded", @response.body
- assert_equal "text/plain", @response.content_type
- end
-end
diff --git a/actionpack/test/controller/new_base/bare_metal_test.rb b/actionpack/test/controller/new_base/bare_metal_test.rb
index c226fa57ee..7572d514fb 100644
--- a/actionpack/test/controller/new_base/bare_metal_test.rb
+++ b/actionpack/test/controller/new_base/bare_metal_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "abstract_unit"
module BareMetalTest
@@ -11,7 +13,7 @@ module BareMetalTest
test "response body is a Rack-compatible response" do
status, headers, body = BareController.action(:index).call(Rack::MockRequest.env_for("/"))
assert_equal 200, status
- string = ""
+ string = +""
body.each do |part|
assert part.is_a?(String), "Each part of the body must be a String"
@@ -40,6 +42,22 @@ module BareMetalTest
end
end
+ class BareEmptyController < ActionController::Metal
+ def index
+ self.response_body = nil
+ end
+ end
+
+ class BareEmptyTest < ActiveSupport::TestCase
+ test "response body is nil" do
+ controller = BareEmptyController.new
+ controller.set_request!(ActionDispatch::Request.empty)
+ controller.set_response!(BareController.make_response!(controller.request))
+ controller.index
+ assert_nil controller.response_body
+ end
+ end
+
class HeadController < ActionController::Metal
include ActionController::Head
@@ -86,38 +104,38 @@ module BareMetalTest
test "head :continue (100) does not return a content-type header" do
headers = HeadController.action(:continue).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :switching_protocols (101) does not return a content-type header" do
headers = HeadController.action(:switching_protocols).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :processing (102) does not return a content-type header" do
headers = HeadController.action(:processing).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :no_content (204) does not return a content-type header" do
headers = HeadController.action(:no_content).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :reset_content (205) does not return a content-type header" do
headers = HeadController.action(:reset_content).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :not_modified (304) does not return a content-type header" do
headers = HeadController.action(:not_modified).call(Rack::MockRequest.env_for("/")).second
- assert_nil headers['Content-Type']
- assert_nil headers['Content-Length']
+ assert_nil headers["Content-Type"]
+ assert_nil headers["Content-Length"]
end
test "head :no_content (204) does not return any content" do
diff --git a/actionpack/test/controller/new_base/base_test.rb b/actionpack/test/controller/new_base/base_test.rb
index 0755dafe93..280134f8d2 100644
--- a/actionpack/test/controller/new_base/base_test.rb
+++ b/actionpack/test/controller/new_base/base_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
# Tests the controller dispatching happy path
module Dispatching
@@ -25,7 +27,7 @@ module Dispatching
render body: "actions: #{action_methods.to_a.sort.join(', ')}"
end
- protected
+ private
def authenticate
end
end
@@ -45,7 +47,6 @@ module Dispatching
end
class BaseTest < Rack::TestCase
- # :api: plugin
test "simple dispatching" do
get "/dispatching/simple/index"
@@ -54,14 +55,12 @@ module Dispatching
assert_content_type "text/plain; charset=utf-8"
end
- # :api: plugin
test "directly modifying response body" do
get "/dispatching/simple/modify_response_body"
assert_body "success"
end
- # :api: plugin
test "directly modifying response body twice" do
get "/dispatching/simple/modify_response_body_twice"
@@ -69,48 +68,48 @@ module Dispatching
end
test "controller path" do
- assert_equal 'dispatching/empty', EmptyController.controller_path
+ assert_equal "dispatching/empty", EmptyController.controller_path
assert_equal EmptyController.controller_path, EmptyController.new.controller_path
end
test "non-default controller path" do
- assert_equal 'i_am_not_default', NonDefaultPathController.controller_path
+ assert_equal "i_am_not_default", NonDefaultPathController.controller_path
assert_equal NonDefaultPathController.controller_path, NonDefaultPathController.new.controller_path
end
test "sub controller path" do
- assert_equal 'dispatching/sub_empty', SubEmptyController.controller_path
+ assert_equal "dispatching/sub_empty", SubEmptyController.controller_path
assert_equal SubEmptyController.controller_path, SubEmptyController.new.controller_path
end
test "namespaced controller path" do
- assert_equal 'dispatching/submodule/contained_empty', Submodule::ContainedEmptyController.controller_path
+ assert_equal "dispatching/submodule/contained_empty", Submodule::ContainedEmptyController.controller_path
assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path
end
test "namespaced non-default controller path" do
- assert_equal 'i_am_extremely_not_default', Submodule::ContainedNonDefaultPathController.controller_path
+ assert_equal "i_am_extremely_not_default", Submodule::ContainedNonDefaultPathController.controller_path
assert_equal Submodule::ContainedNonDefaultPathController.controller_path, Submodule::ContainedNonDefaultPathController.new.controller_path
end
test "namespaced sub controller path" do
- assert_equal 'dispatching/submodule/contained_sub_empty', Submodule::ContainedSubEmptyController.controller_path
+ assert_equal "dispatching/submodule/contained_sub_empty", Submodule::ContainedSubEmptyController.controller_path
assert_equal Submodule::ContainedSubEmptyController.controller_path, Submodule::ContainedSubEmptyController.new.controller_path
end
test "controller name" do
- assert_equal 'empty', EmptyController.controller_name
- assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name
+ assert_equal "empty", EmptyController.controller_name
+ assert_equal "contained_empty", Submodule::ContainedEmptyController.controller_name
end
test "non-default path controller name" do
- assert_equal 'non_default_path', NonDefaultPathController.controller_name
- assert_equal 'contained_non_default_path', Submodule::ContainedNonDefaultPathController.controller_name
+ assert_equal "non_default_path", NonDefaultPathController.controller_name
+ assert_equal "contained_non_default_path", Submodule::ContainedNonDefaultPathController.controller_name
end
test "sub controller name" do
- assert_equal 'sub_empty', SubEmptyController.controller_name
- assert_equal 'contained_sub_empty', Submodule::ContainedSubEmptyController.controller_name
+ assert_equal "sub_empty", SubEmptyController.controller_name
+ assert_equal "contained_sub_empty", Submodule::ContainedSubEmptyController.controller_name
end
test "action methods" do
diff --git a/actionpack/test/controller/new_base/content_negotiation_test.rb b/actionpack/test/controller/new_base/content_negotiation_test.rb
index c0e92b3b05..7205e90176 100644
--- a/actionpack/test/controller/new_base/content_negotiation_test.rb
+++ b/actionpack/test/controller/new_base/content_negotiation_test.rb
@@ -1,7 +1,8 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-module ContentNegotiation
+require "abstract_unit"
+module ContentNegotiation
# This has no layout and it works
class BasicController < ActionController::Base
self.view_paths = [ActionView::FixtureResolver.new(
@@ -9,7 +10,7 @@ module ContentNegotiation
)]
def all
- render plain: self.formats.inspect
+ render plain: formats.inspect
end
end
diff --git a/actionpack/test/controller/new_base/content_type_test.rb b/actionpack/test/controller/new_base/content_type_test.rb
index a9dcdde4b8..d3ee4a8a6f 100644
--- a/actionpack/test/controller/new_base/content_type_test.rb
+++ b/actionpack/test/controller/new_base/content_type_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ContentType
class BaseController < ActionController::Base
@@ -43,7 +45,9 @@ module ContentType
test "default response is text/plain and UTF8" do
with_routing do |set|
set.draw do
- get ':controller', :action => 'index'
+ ActiveSupport::Deprecation.silence do
+ get ":controller", action: "index"
+ end
end
get "/content_type/base"
diff --git a/actionpack/test/controller/new_base/middleware_test.rb b/actionpack/test/controller/new_base/middleware_test.rb
index 85a1f351f0..df69650a7b 100644
--- a/actionpack/test/controller/new_base/middleware_test.rb
+++ b/actionpack/test/controller/new_base/middleware_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module MiddlewareTest
class MyMiddleware
@@ -21,7 +23,7 @@ module MiddlewareTest
def call(env)
result = @app.call(env)
- result[1]["Middleware-Order"] << "!"
+ result[1]["Middleware-Order"] += "!"
result
end
end
@@ -56,8 +58,8 @@ module MiddlewareTest
end
class ActionsController < ActionController::Metal
- use MyMiddleware, :only => :show
- middleware.insert_before MyMiddleware, ExclaimerMiddleware, :except => :index
+ use MyMiddleware, only: :show
+ middleware.insert_before MyMiddleware, ExclaimerMiddleware, except: :index
def index
self.response_body = "index"
diff --git a/actionpack/test/controller/new_base/render_action_test.rb b/actionpack/test/controller/new_base/render_action_test.rb
index 3bf1dd0ede..33b55dc5a8 100644
--- a/actionpack/test/controller/new_base/render_action_test.rb
+++ b/actionpack/test/controller/new_base/render_action_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderAction
# This has no layout and it works
@@ -8,7 +10,7 @@ module RenderAction
)]
def hello_world
- render :action => "hello_world"
+ render action: "hello_world"
end
def hello_world_as_string
@@ -16,7 +18,7 @@ module RenderAction
end
def hello_world_as_string_with_options
- render "hello_world", :status => 404
+ render "hello_world", status: 404
end
def hello_world_as_symbol
@@ -24,25 +26,24 @@ module RenderAction
end
def hello_world_with_symbol
- render :action => :hello_world
+ render action: :hello_world
end
def hello_world_with_layout
- render :action => "hello_world", :layout => true
+ render action: "hello_world", layout: true
end
def hello_world_with_layout_false
- render :action => "hello_world", :layout => false
+ render action: "hello_world", layout: false
end
def hello_world_with_layout_nil
- render :action => "hello_world", :layout => nil
+ render action: "hello_world", layout: nil
end
def hello_world_with_custom_layout
- render :action => "hello_world", :layout => "greetings"
+ render action: "hello_world", layout: "greetings"
end
-
end
class RenderActionTest < Rack::TestCase
@@ -127,27 +128,27 @@ module RenderActionWithApplicationLayout
)]
def hello_world
- render :action => "hello_world"
+ render action: "hello_world"
end
def hello_world_with_layout
- render :action => "hello_world", :layout => true
+ render action: "hello_world", layout: true
end
def hello_world_with_layout_false
- render :action => "hello_world", :layout => false
+ render action: "hello_world", layout: false
end
def hello_world_with_layout_nil
- render :action => "hello_world", :layout => nil
+ render action: "hello_world", layout: nil
end
def hello_world_with_custom_layout
- render :action => "hello_world", :layout => "greetings"
+ render action: "hello_world", layout: "greetings"
end
def with_builder_and_layout
- render :action => "hello", :layout => "builder"
+ render action: "hello", layout: "builder"
end
end
@@ -196,7 +197,6 @@ module RenderActionWithApplicationLayout
assert_response "<html>\n<p>Hello</p>\n</html>\n"
end
end
-
end
module RenderActionWithControllerLayout
@@ -207,23 +207,23 @@ module RenderActionWithControllerLayout
)]
def hello_world
- render :action => "hello_world"
+ render action: "hello_world"
end
def hello_world_with_layout
- render :action => "hello_world", :layout => true
+ render action: "hello_world", layout: true
end
def hello_world_with_layout_false
- render :action => "hello_world", :layout => false
+ render action: "hello_world", layout: false
end
def hello_world_with_layout_nil
- render :action => "hello_world", :layout => nil
+ render action: "hello_world", layout: nil
end
def hello_world_with_custom_layout
- render :action => "hello_world", :layout => "greetings"
+ render action: "hello_world", layout: "greetings"
end
end
@@ -260,26 +260,25 @@ end
module RenderActionWithBothLayouts
class BasicController < ActionController::Base
- self.view_paths = [ActionView::FixtureResolver.new({
- "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!",
+ self.view_paths = [ActionView::FixtureResolver.new(
+ "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!",
"layouts/application.html.erb" => "Oh Hi <%= yield %> Bye",
- "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> Bye"
- })]
+ "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> Bye")]
def hello_world
- render :action => "hello_world"
+ render action: "hello_world"
end
def hello_world_with_layout
- render :action => "hello_world", :layout => true
+ render action: "hello_world", layout: true
end
def hello_world_with_layout_false
- render :action => "hello_world", :layout => false
+ render action: "hello_world", layout: false
end
def hello_world_with_layout_nil
- render :action => "hello_world", :layout => nil
+ render action: "hello_world", layout: nil
end
end
diff --git a/actionpack/test/controller/new_base/render_body_test.rb b/actionpack/test/controller/new_base/render_body_test.rb
index f4a3db8b41..d0b61f0665 100644
--- a/actionpack/test/controller/new_base/render_body_test.rb
+++ b/actionpack/test/controller/new_base/render_body_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderBody
class MinimalController < ActionController::Metal
@@ -66,7 +68,7 @@ module RenderBody
end
def with_custom_content_type
- response.headers['Content-Type'] = 'application/json'
+ response.headers["Content-Type"] = "application/json"
render body: '["troll","face"]'
end
@@ -85,7 +87,7 @@ module RenderBody
test "rendering body from an action with default options renders the body with the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_body/simple"
assert_body "hello david"
@@ -95,7 +97,7 @@ module RenderBody
test "rendering body from an action with default options renders the body without the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_body/with_layout"
@@ -150,7 +152,7 @@ module RenderBody
get "/render_body/with_layout/with_custom_content_type"
assert_equal %w{ troll face }, JSON.parse(response.body)
- assert_equal 'application/json', response.headers['Content-Type']
+ assert_equal "application/json", response.headers["Content-Type"]
end
test "rendering body with layout: false" do
diff --git a/actionpack/test/controller/new_base/render_context_test.rb b/actionpack/test/controller/new_base/render_context_test.rb
index 177a1c088d..5e570a1d79 100644
--- a/actionpack/test/controller/new_base/render_context_test.rb
+++ b/actionpack/test/controller/new_base/render_context_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
# This is testing the decoupling of view renderer and view context
# by allowing the controller to be used as view context. This is
@@ -18,24 +20,23 @@ module RenderContext
def hello_world
@value = "Hello"
- render :action => "hello_world", :layout => false
+ render action: "hello_world", layout: false
end
def with_layout
@value = "Hello"
- render :action => "hello_world", :layout => "basic"
+ render action: "hello_world", layout: "basic"
end
- protected
-
- # 3) Set view_context to self
- def view_context
- self
- end
-
- def __controller_method__
+ protected def __controller_method__
"controller context!"
end
+
+ private
+ # 3) Set view_context to self
+ def view_context
+ self
+ end
end
class RenderContextTest < Rack::TestCase
diff --git a/actionpack/test/controller/new_base/render_file_test.rb b/actionpack/test/controller/new_base/render_file_test.rb
index 0c21bb0719..de8af029e0 100644
--- a/actionpack/test/controller/new_base/render_file_test.rb
+++ b/actionpack/test/controller/new_base/render_file_test.rb
@@ -1,36 +1,38 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderFile
class BasicController < ActionController::Base
- self.view_paths = File.dirname(__FILE__)
+ self.view_paths = __dir__
def index
- render :file => File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world])
+ render file: File.expand_path("../../fixtures/test/hello_world", __dir__)
end
def with_instance_variables
- @secret = 'in the sauce'
- render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar')
+ @secret = "in the sauce"
+ render file: File.expand_path("../../fixtures/test/render_file_with_ivar", __dir__)
end
def relative_path
- @secret = 'in the sauce'
- render :file => '../../fixtures/test/render_file_with_ivar'
+ @secret = "in the sauce"
+ render file: "../../fixtures/test/render_file_with_ivar"
end
def relative_path_with_dot
- @secret = 'in the sauce'
- render :file => '../../fixtures/test/dot.directory/render_file_with_ivar'
+ @secret = "in the sauce"
+ render file: "../../fixtures/test/dot.directory/render_file_with_ivar"
end
def pathname
- @secret = 'in the sauce'
- render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar])
+ @secret = "in the sauce"
+ render file: Pathname.new(__dir__).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar])
end
def with_locals
- path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals')
- render :file => path, :locals => {:secret => 'in the sauce'}
+ path = File.expand_path("../../fixtures/test/render_file_with_locals", __dir__)
+ render file: path, locals: { secret: "in the sauce" }
end
end
diff --git a/actionpack/test/controller/new_base/render_html_test.rb b/actionpack/test/controller/new_base/render_html_test.rb
index e9ea57e329..4bea2ba2e9 100644
--- a/actionpack/test/controller/new_base/render_html_test.rb
+++ b/actionpack/test/controller/new_base/render_html_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderHtml
class MinimalController < ActionController::Metal
@@ -88,7 +90,7 @@ module RenderHtml
test "rendering text from an action with default options renders the text with the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_html/simple"
assert_body "hello david"
@@ -98,7 +100,7 @@ module RenderHtml
test "rendering text from an action with default options renders the text without the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_html/with_layout"
diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb
index 5b4885f7e0..8c26d34b00 100644
--- a/actionpack/test/controller/new_base/render_implicit_action_test.rb
+++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderImplicitAction
class SimpleController < ::ApplicationController
@@ -6,7 +8,7 @@ module RenderImplicitAction
"render_implicit_action/simple/hello_world.html.erb" => "Hello world!",
"render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!",
"render_implicit_action/simple/not_implemented.html.erb" => "Not Implemented"
- ), ActionView::FileSystemResolver.new(File.expand_path('../../../controller', __FILE__))]
+ ), ActionView::FileSystemResolver.new(File.expand_path("../../controller", __dir__))]
def hello_world() end
end
diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb
index 7ab3777026..806c6206dc 100644
--- a/actionpack/test/controller/new_base/render_layout_test.rb
+++ b/actionpack/test/controller/new_base/render_layout_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ControllerLayouts
class ImplicitController < ::ApplicationController
@@ -10,15 +12,15 @@ module ControllerLayouts
)]
def index
- render :template => "basic"
+ render template: "basic"
end
def override
- render :template => "basic", :layout => "override"
+ render template: "basic", layout: "override"
end
def layout_false
- render :layout => false
+ render layout: false
end
def builder_override
@@ -32,7 +34,7 @@ module ControllerLayouts
)]
def index
- render :template => "basic"
+ render template: "basic"
end
end
@@ -55,7 +57,6 @@ module ControllerLayouts
get "/controller_layouts/implicit/override"
assert_body "Override! Hello world!"
end
-
end
class LayoutOptionsTest < Rack::TestCase
@@ -76,7 +77,7 @@ module ControllerLayouts
)]
def explicit
- render :layout => "application"
+ render layout: "application"
end
end
diff --git a/actionpack/test/controller/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb
index 9e5022c9f4..a0c7cbc686 100644
--- a/actionpack/test/controller/new_base/render_partial_test.rb
+++ b/actionpack/test/controller/new_base/render_partial_test.rb
@@ -1,9 +1,9 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-module RenderPartial
+require "abstract_unit"
+module RenderPartial
class BasicController < ActionController::Base
-
self.view_paths = [ActionView::FixtureResolver.new(
"render_partial/basic/_basic.html.erb" => "BasicPartial!",
"render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>",
@@ -16,16 +16,16 @@ module RenderPartial
)]
def html_with_json_inside_json
- render :action => "with_json"
+ render action: "with_json"
end
def changing
- @test_unchanged = 'hello'
- render :action => "basic"
+ @test_unchanged = "hello"
+ render action: "basic"
end
def overridden
- @test_unchanged = 'hello'
+ @test_unchanged = "hello"
end
end
@@ -59,5 +59,4 @@ module RenderPartial
assert_response("goodbyeOverriddenPartial!goodbye")
end
end
-
end
diff --git a/actionpack/test/controller/new_base/render_plain_test.rb b/actionpack/test/controller/new_base/render_plain_test.rb
index 0881442bd0..640979e4f5 100644
--- a/actionpack/test/controller/new_base/render_plain_test.rb
+++ b/actionpack/test/controller/new_base/render_plain_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderPlain
class MinimalController < ActionController::Metal
@@ -80,7 +82,7 @@ module RenderPlain
test "rendering text from an action with default options renders the text with the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_plain/simple"
assert_body "hello david"
@@ -90,7 +92,7 @@ module RenderPlain
test "rendering text from an action with default options renders the text without the layout" do
with_routing do |set|
- set.draw { get ':controller', action: 'index' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: "index" } }
get "/render_plain/with_layout"
diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb
index 9ea056194a..23dc6bca40 100644
--- a/actionpack/test/controller/new_base/render_streaming_test.rb
+++ b/actionpack/test/controller/new_base/render_streaming_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderStreaming
class BasicController < ActionController::Base
@@ -12,32 +14,32 @@ module RenderStreaming
layout "application"
def hello_world
- render :stream => true
+ render stream: true
end
def layout_exception
- render :action => "hello_world", :stream => true, :layout => "boom"
+ render action: "hello_world", stream: true, layout: "boom"
end
def template_exception
- render :action => "boom", :stream => true
+ render action: "boom", stream: true
end
def skip
- render :action => "hello_world", :stream => false
+ render action: "hello_world", stream: false
end
def explicit
- render :action => "hello_world", :stream => true
+ render action: "hello_world", stream: true
end
def no_layout
- render :action => "hello_world", :stream => true, :layout => false
+ render action: "hello_world", stream: true, layout: false
end
def explicit_cache
headers["Cache-Control"] = "private"
- render :action => "hello_world", :stream => true
+ render action: "hello_world", stream: true
end
end
@@ -101,12 +103,12 @@ module RenderStreaming
assert_body "Hello world, I'm here!"
assert_status 200
assert_equal "22", headers["Content-Length"]
- assert_equal nil, headers["Transfer-Encoding"]
+ assert_nil headers["Transfer-Encoding"]
end
- def assert_streaming!(cache="no-cache")
+ def assert_streaming!(cache = "no-cache")
assert_status 200
- assert_equal nil, headers["Content-Length"]
+ assert_nil headers["Content-Length"]
assert_equal "chunked", headers["Transfer-Encoding"]
assert_equal cache, headers["Cache-Control"]
end
diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb
index b06ce5db40..14dc958475 100644
--- a/actionpack/test/controller/new_base/render_template_test.rb
+++ b/actionpack/test/controller/new_base/render_template_test.rb
@@ -1,8 +1,9 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module RenderTemplate
class WithoutLayoutController < ActionController::Base
-
self.view_paths = [ActionView::FixtureResolver.new(
"test/basic.html.erb" => "Hello from basic.html.erb",
"shared.html.erb" => "Elastica",
@@ -18,11 +19,11 @@ module RenderTemplate
)]
def index
- render :template => "test/basic"
+ render template: "test/basic"
end
def html_with_json_inside_json
- render :template => "test/with_json"
+ render template: "test/with_json"
end
def index_without_key
@@ -30,46 +31,46 @@ module RenderTemplate
end
def in_top_directory
- render :template => 'shared'
+ render template: "shared"
end
def in_top_directory_with_slash
- render :template => '/shared'
+ render template: "/shared"
end
def in_top_directory_with_slash_without_key
- render '/shared'
+ render "/shared"
end
def with_locals
- render :template => "locals", :locals => { :secret => 'area51' }
+ render template: "locals", locals: { secret: "area51" }
end
def with_locals_without_key
- render "locals", :locals => { :secret => 'area51' }
+ render "locals", locals: { secret: "area51" }
end
def builder_template
- render :template => "xml_template"
+ render template: "xml_template"
end
def with_raw
- render :template => "with_raw"
+ render template: "with_raw"
end
def with_implicit_raw
- render :template => "with_implicit_raw"
+ render template: "with_implicit_raw"
end
def with_error
- render :template => "test/with_error"
+ render template: "test/with_error"
end
private
- def show_detailed_exceptions?
- request.local?
- end
+ def show_detailed_exceptions?
+ request.local?
+ end
end
class TestWithoutLayout < Rack::TestCase
@@ -126,7 +127,7 @@ module RenderTemplate
assert_body "Hello <strong>this is also raw</strong> in an html template"
assert_status 200
- get :with_implicit_raw, params: { format: 'text' }
+ get :with_implicit_raw, params: { format: "text" }
assert_body "Hello <strong>this is also raw</strong> in a text template"
assert_status 200
@@ -154,30 +155,30 @@ module RenderTemplate
)]
def index
- render :template => "test/basic"
+ render template: "test/basic"
end
def with_layout
- render :template => "test/basic", :layout => true
+ render template: "test/basic", layout: true
end
def with_layout_false
- render :template => "test/basic", :layout => false
+ render template: "test/basic", layout: false
end
def with_layout_nil
- render :template => "test/basic", :layout => nil
+ render template: "test/basic", layout: nil
end
def with_custom_layout
- render :template => "test/basic", :layout => "greetings"
+ render template: "test/basic", layout: "greetings"
end
end
class TestWithLayout < Rack::TestCase
test "rendering with implicit layout" do
with_routing do |set|
- set.draw { get ':controller', :action => :index }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller", action: :index } }
get "/render_template/with_layout"
@@ -223,7 +224,7 @@ module RenderTemplate
)]
def with_forward_slash
- render :template => "/test/basic"
+ render template: "/test/basic"
end
end
diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb
index 963f2c2f5c..eb29203f59 100644
--- a/actionpack/test/controller/new_base/render_test.rb
+++ b/actionpack/test/controller/new_base/render_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module Render
class BlankRenderController < ActionController::Base
@@ -18,11 +20,11 @@ module Render
end
def access_request
- render :action => "access_request"
+ render action: "access_request"
end
def render_action_name
- render :action => "access_action_name"
+ render action: "access_action_name"
end
def overridden_with_own_view_paths_appended
@@ -36,9 +38,9 @@ module Render
private
- def secretz
- render plain: "FAIL WHALE!"
- end
+ def secretz
+ render plain: "FAIL WHALE!"
+ end
end
class DoubleRenderController < ActionController::Base
@@ -57,7 +59,9 @@ module Render
test "render with blank" do
with_routing do |set|
set.draw do
- get ":controller", :action => 'index'
+ ActiveSupport::Deprecation.silence do
+ get ":controller", action: "index"
+ end
end
get "/render/blank_render"
@@ -70,7 +74,9 @@ module Render
test "rendering more than once raises an exception" do
with_routing do |set|
set.draw do
- get ":controller", :action => 'index'
+ ActiveSupport::Deprecation.silence do
+ get ":controller", action: "index"
+ end
end
assert_raises(AbstractController::DoubleRenderError) do
diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb
deleted file mode 100644
index 048458178c..0000000000
--- a/actionpack/test/controller/new_base/render_text_test.rb
+++ /dev/null
@@ -1,188 +0,0 @@
-require 'abstract_unit'
-
-module RenderText
- class MinimalController < ActionController::Metal
- include AbstractController::Rendering
- include ActionController::Rendering
-
- def index
- render text: "Hello World!"
- end
- end
-
- class SimpleController < ActionController::Base
- self.view_paths = [ActionView::FixtureResolver.new]
-
- def index
- render text: "hello david"
- end
- end
-
- class WithLayoutController < ::ApplicationController
- self.view_paths = [ActionView::FixtureResolver.new(
- "layouts/application.html.erb" => "<%= yield %>, I'm here!",
- "layouts/greetings.html.erb" => "<%= yield %>, I wish thee well.",
- "layouts/ivar.html.erb" => "<%= yield %>, <%= @ivar %>"
- )]
-
- def index
- render text: "hello david"
- end
-
- def custom_code
- render text: "hello world", status: 404
- end
-
- def with_custom_code_as_string
- render text: "hello world", status: "404 Not Found"
- end
-
- def with_nil
- render text: nil
- end
-
- def with_nil_and_status
- render text: nil, status: 403
- end
-
- def with_false
- render text: false
- end
-
- def with_layout_true
- render text: "hello world", layout: true
- end
-
- def with_layout_false
- render text: "hello world", layout: false
- end
-
- def with_layout_nil
- render text: "hello world", layout: nil
- end
-
- def with_custom_layout
- render text: "hello world", layout: "greetings"
- end
-
- def with_ivar_in_layout
- @ivar = "hello world"
- render text: "hello world", layout: "ivar"
- end
- end
-
- class RenderTextTest < Rack::TestCase
- test "rendering text from a minimal controller" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/minimal/index"
- end
-
- assert_body "Hello World!"
- assert_status 200
- end
-
- test "rendering text from an action with default options renders the text with the layout" do
- with_routing do |set|
- set.draw { get ':controller', action: 'index' }
-
- ActiveSupport::Deprecation.silence do
- get "/render_text/simple"
- end
-
- assert_body "hello david"
- assert_status 200
- end
- end
-
- test "rendering text from an action with default options renders the text without the layout" do
- with_routing do |set|
- set.draw { get ':controller', action: 'index' }
-
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout"
- end
-
- assert_body "hello david"
- assert_status 200
- end
- end
-
- test "rendering text, while also providing a custom status code" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/custom_code"
- end
-
- assert_body "hello world"
- assert_status 404
- end
-
- test "rendering text with nil returns an empty body" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_nil"
- end
-
- assert_body ""
- assert_status 200
- end
-
- test "Rendering text with nil and custom status code returns an empty body and the status" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_nil_and_status"
- end
-
- assert_body ""
- assert_status 403
- end
-
- test "rendering text with false returns the string 'false'" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_false"
- end
-
- assert_body "false"
- assert_status 200
- end
-
- test "rendering text with layout: true" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_layout_true"
- end
-
- assert_body "hello world, I'm here!"
- assert_status 200
- end
-
- test "rendering text with layout: 'greetings'" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_custom_layout"
- end
-
- assert_body "hello world, I wish thee well."
- assert_status 200
- end
-
- test "rendering text with layout: false" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_layout_false"
- end
-
- assert_body "hello world"
- assert_status 200
- end
-
- test "rendering text with layout: nil" do
- ActiveSupport::Deprecation.silence do
- get "/render_text/with_layout/with_layout_nil"
- end
-
- assert_body "hello world"
- assert_status 200
- end
-
- test "rendering text displays deprecation warning" do
- assert_deprecated do
- get "/render_text/with_layout/with_layout_nil"
- end
- end
- end
-end
diff --git a/actionpack/test/controller/new_base/render_xml_test.rb b/actionpack/test/controller/new_base/render_xml_test.rb
index b8527a943d..0dc16d64e2 100644
--- a/actionpack/test/controller/new_base/render_xml_test.rb
+++ b/actionpack/test/controller/new_base/render_xml_test.rb
@@ -1,7 +1,8 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-module RenderXml
+require "abstract_unit"
+module RenderXml
# This has no layout and it works
class BasicController < ActionController::Base
self.view_paths = [ActionView::FixtureResolver.new(
diff --git a/actionpack/test/controller/output_escaping_test.rb b/actionpack/test/controller/output_escaping_test.rb
index c3c549fbfc..d683bc73e6 100644
--- a/actionpack/test/controller/output_escaping_test.rb
+++ b/actionpack/test/controller/output_escaping_test.rb
@@ -1,9 +1,10 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-class OutputEscapingTest < ActiveSupport::TestCase
+require "abstract_unit"
+class OutputEscapingTest < ActiveSupport::TestCase
test "escape_html shouldn't die when passed nil" do
- assert ERB::Util.h(nil).blank?
+ assert_predicate ERB::Util.h(nil), :blank?
end
test "escapeHTML should escape strings" do
@@ -13,5 +14,4 @@ class OutputEscapingTest < ActiveSupport::TestCase
test "escapeHTML shouldn't touch explicitly safe strings" do
assert_equal "<", ERB::Util.h("<".html_safe)
end
-
end
diff --git a/actionpack/test/controller/parameter_encoding_test.rb b/actionpack/test/controller/parameter_encoding_test.rb
new file mode 100644
index 0000000000..e2194e8974
--- /dev/null
+++ b/actionpack/test/controller/parameter_encoding_test.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class ParameterEncodingController < ActionController::Base
+ skip_parameter_encoding :test_bar
+ skip_parameter_encoding :test_all_values_encoding
+
+ def test_foo
+ render body: params[:foo].encoding
+ end
+
+ def test_bar
+ render body: params[:bar].encoding
+ end
+
+ def test_all_values_encoding
+ render body: ::JSON.dump(params.values.map(&:encoding).map(&:name))
+ end
+end
+
+class ParameterEncodingTest < ActionController::TestCase
+ tests ParameterEncodingController
+
+ test "properly transcodes UTF8 parameters into declared encodings" do
+ post :test_foo, params: { "foo" => "foo", "bar" => "bar", "baz" => "baz" }
+
+ assert_response :success
+ assert_equal "UTF-8", @response.body
+ end
+
+ test "properly encodes ASCII_8BIT parameters into binary" do
+ post :test_bar, params: { "foo" => "foo", "bar" => "bar", "baz" => "baz" }
+
+ assert_response :success
+ assert_equal "ASCII-8BIT", @response.body
+ end
+
+ test "properly encodes all ASCII_8BIT parameters into binary" do
+ post :test_all_values_encoding, params: { "foo" => "foo", "bar" => "bar", "baz" => "baz" }
+
+ assert_response :success
+ assert_equal ["ASCII-8BIT"], JSON.parse(@response.body).uniq
+ end
+
+ test "does not raise an error when passed a param declared as ASCII-8BIT that contains invalid bytes" do
+ get :test_bar, params: { "bar" => URI.parser.escape("bar\xE2baz".b) }
+
+ assert_response :success
+ assert_equal "ASCII-8BIT", @response.body
+ end
+end
diff --git a/actionpack/test/controller/parameters/accessors_test.rb b/actionpack/test/controller/parameters/accessors_test.rb
index 97875c3cbb..7789e654d5 100644
--- a/actionpack/test/controller/parameters/accessors_test.rb
+++ b/actionpack/test/controller/parameters/accessors_test.rb
@@ -1,30 +1,44 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
-require 'active_support/core_ext/hash/transform_values'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class ParametersAccessorsTest < ActiveSupport::TestCase
setup do
+ ActionController::Parameters.permit_all_parameters = false
+
@params = ActionController::Parameters.new(
person: {
- age: '32',
+ age: "32",
name: {
- first: 'David',
- last: 'Heinemeier Hansson'
+ first: "David",
+ last: "Heinemeier Hansson"
},
- addresses: [{city: 'Chicago', state: 'Illinois'}]
+ addresses: [{ city: "Chicago", state: "Illinois" }]
}
)
end
test "[] retains permitted status" do
@params.permit!
- assert @params[:person].permitted?
- assert @params[:person][:name].permitted?
+ assert_predicate @params[:person], :permitted?
+ assert_predicate @params[:person][:name], :permitted?
end
test "[] retains unpermitted status" do
- assert_not @params[:person].permitted?
- assert_not @params[:person][:name].permitted?
+ assert_not_predicate @params[:person], :permitted?
+ assert_not_predicate @params[:person][:name], :permitted?
+ end
+
+ test "as_json returns the JSON representation of the parameters hash" do
+ assert_not @params.as_json.key? "parameters"
+ assert_not @params.as_json.key? "permitted"
+ assert @params.as_json.key? "person"
+ end
+
+ test "to_s returns the string representation of the parameters hash" do
+ assert_equal '{"person"=>{"age"=>"32", "name"=>{"first"=>"David", "last"=>"Heinemeier Hansson"}, ' \
+ '"addresses"=>[{"city"=>"Chicago", "state"=>"Illinois"}]}}', @params.to_s
end
test "each carries permitted status" do
@@ -36,6 +50,14 @@ class ParametersAccessorsTest < ActiveSupport::TestCase
@params.each { |key, value| assert_not(value.permitted?) if key == "person" }
end
+ test "each returns key,value array for block with arity 1" do
+ @params.each do |arg|
+ assert_kind_of Array, arg
+ assert_equal "person", arg[0]
+ assert_kind_of ActionController::Parameters, arg[1]
+ end
+ end
+
test "each_pair carries permitted status" do
@params.permit!
@params.each_pair { |key, value| assert(value.permitted?) if key == "person" }
@@ -45,81 +67,272 @@ class ParametersAccessorsTest < ActiveSupport::TestCase
@params.each_pair { |key, value| assert_not(value.permitted?) if key == "person" }
end
+ test "each_pair returns key,value array for block with arity 1" do
+ @params.each_pair do |arg|
+ assert_kind_of Array, arg
+ assert_equal "person", arg[0]
+ assert_kind_of ActionController::Parameters, arg[1]
+ end
+ end
+
+ test "each_value carries permitted status" do
+ @params.permit!
+ @params.each_value do |value|
+ assert_predicate(value, :permitted?)
+ end
+ end
+
+ test "each_value carries unpermitted status" do
+ @params.each_value do |value|
+ assert_not_predicate(value, :permitted?)
+ end
+ end
+
+ test "each_key converts to hash for permitted" do
+ @params.permit!
+ @params.each_key { |key| assert_kind_of(String, key) if key == "person" }
+ end
+
+ test "each_key converts to hash for unpermitted" do
+ @params.each_key { |key| assert_kind_of(String, key) if key == "person" }
+ end
+
+ test "empty? returns true when params contains no key/value pairs" do
+ params = ActionController::Parameters.new
+ assert_empty params
+ end
+
+ test "empty? returns false when any params are present" do
+ assert_not_empty @params
+ end
+
test "except retains permitted status" do
@params.permit!
- assert @params.except(:person).permitted?
- assert @params[:person].except(:name).permitted?
+ assert_predicate @params.except(:person), :permitted?
+ assert_predicate @params[:person].except(:name), :permitted?
end
test "except retains unpermitted status" do
- assert_not @params.except(:person).permitted?
- assert_not @params[:person].except(:name).permitted?
+ assert_not_predicate @params.except(:person), :permitted?
+ assert_not_predicate @params[:person].except(:name), :permitted?
end
test "fetch retains permitted status" do
@params.permit!
- assert @params.fetch(:person).permitted?
- assert @params[:person].fetch(:name).permitted?
+ assert_predicate @params.fetch(:person), :permitted?
+ assert_predicate @params[:person].fetch(:name), :permitted?
end
test "fetch retains unpermitted status" do
- assert_not @params.fetch(:person).permitted?
- assert_not @params[:person].fetch(:name).permitted?
+ assert_not_predicate @params.fetch(:person), :permitted?
+ assert_not_predicate @params[:person].fetch(:name), :permitted?
+ end
+
+ test "has_key? returns true if the given key is present in the params" do
+ assert @params.has_key?(:person)
+ end
+
+ test "has_key? returns false if the given key is not present in the params" do
+ assert_not @params.has_key?(:address)
+ end
+
+ test "has_value? returns true if the given value is present in the params" do
+ params = ActionController::Parameters.new(city: "Chicago", state: "Illinois")
+ assert params.has_value?("Chicago")
+ end
+
+ test "has_value? returns false if the given value is not present in the params" do
+ params = ActionController::Parameters.new(city: "Chicago", state: "Illinois")
+ assert_not params.has_value?("New York")
+ end
+
+ test "include? returns true if the given key is present in the params" do
+ assert @params.include?(:person)
+ end
+
+ test "include? returns false if the given key is not present in the params" do
+ assert_not @params.include?(:address)
+ end
+
+ test "key? returns true if the given key is present in the params" do
+ assert @params.key?(:person)
+ end
+
+ test "key? returns false if the given key is not present in the params" do
+ assert_not @params.key?(:address)
+ end
+
+ test "keys returns an array of the keys of the params" do
+ assert_equal ["person"], @params.keys
+ assert_equal ["age", "name", "addresses"], @params[:person].keys
end
test "reject retains permitted status" do
- assert_not @params.reject { |k| k == "person" }.permitted?
+ assert_not_predicate @params.reject { |k| k == "person" }, :permitted?
end
test "reject retains unpermitted status" do
@params.permit!
- assert @params.reject { |k| k == "person" }.permitted?
+ assert_predicate @params.reject { |k| k == "person" }, :permitted?
end
test "select retains permitted status" do
@params.permit!
- assert @params.select { |k| k == "person" }.permitted?
+ assert_predicate @params.select { |k| k == "person" }, :permitted?
end
test "select retains unpermitted status" do
- assert_not @params.select { |k| k == "person" }.permitted?
+ assert_not_predicate @params.select { |k| k == "person" }, :permitted?
end
test "slice retains permitted status" do
@params.permit!
- assert @params.slice(:person).permitted?
+ assert_predicate @params.slice(:person), :permitted?
end
test "slice retains unpermitted status" do
- assert_not @params.slice(:person).permitted?
+ assert_not_predicate @params.slice(:person), :permitted?
end
test "transform_keys retains permitted status" do
@params.permit!
- assert @params.transform_keys { |k| k }.permitted?
+ assert_predicate @params.transform_keys { |k| k }, :permitted?
end
test "transform_keys retains unpermitted status" do
- assert_not @params.transform_keys { |k| k }.permitted?
+ assert_not_predicate @params.transform_keys { |k| k }, :permitted?
end
test "transform_values retains permitted status" do
@params.permit!
- assert @params.transform_values { |v| v }.permitted?
+ assert_predicate @params.transform_values { |v| v }, :permitted?
end
test "transform_values retains unpermitted status" do
- assert_not @params.transform_values { |v| v }.permitted?
+ assert_not_predicate @params.transform_values { |v| v }, :permitted?
+ end
+
+ test "transform_values converts hashes to parameters" do
+ @params.transform_values do |value|
+ assert_kind_of ActionController::Parameters, value
+ value
+ end
+ end
+
+ test "transform_values without block yieds an enumerator" do
+ assert_kind_of Enumerator, @params.transform_values
+ end
+
+ test "transform_values! converts hashes to parameters" do
+ @params.transform_values! do |value|
+ assert_kind_of ActionController::Parameters, value
+ end
+ end
+
+ test "transform_values! without block yields an enumerator" do
+ assert_kind_of Enumerator, @params.transform_values!
+ end
+
+ test "value? returns true if the given value is present in the params" do
+ params = ActionController::Parameters.new(city: "Chicago", state: "Illinois")
+ assert params.value?("Chicago")
+ end
+
+ test "value? returns false if the given value is not present in the params" do
+ params = ActionController::Parameters.new(city: "Chicago", state: "Illinois")
+ assert_not params.value?("New York")
+ end
+
+ test "values returns an array of the values of the params" do
+ params = ActionController::Parameters.new(city: "Chicago", state: "Illinois")
+ assert_equal ["Chicago", "Illinois"], params.values
end
test "values_at retains permitted status" do
@params.permit!
- assert @params.values_at(:person).first.permitted?
- assert @params[:person].values_at(:name).first.permitted?
+ assert_predicate @params.values_at(:person).first, :permitted?
+ assert_predicate @params[:person].values_at(:name).first, :permitted?
end
test "values_at retains unpermitted status" do
- assert_not @params.values_at(:person).first.permitted?
- assert_not @params[:person].values_at(:name).first.permitted?
+ assert_not_predicate @params.values_at(:person).first, :permitted?
+ assert_not_predicate @params[:person].values_at(:name).first, :permitted?
+ end
+
+ test "is equal to Parameters instance with same params" do
+ params1 = ActionController::Parameters.new(a: 1, b: 2)
+ params2 = ActionController::Parameters.new(a: 1, b: 2)
+ assert(params1 == params2)
+ end
+
+ test "is equal to Parameters instance with same permitted params" do
+ params1 = ActionController::Parameters.new(a: 1, b: 2).permit(:a)
+ params2 = ActionController::Parameters.new(a: 1, b: 2).permit(:a)
+ assert(params1 == params2)
+ end
+
+ test "is equal to Parameters instance with same different source params, but same permitted params" do
+ params1 = ActionController::Parameters.new(a: 1, b: 2).permit(:a)
+ params2 = ActionController::Parameters.new(a: 1, c: 3).permit(:a)
+ assert(params1 == params2)
+ assert(params2 == params1)
+ end
+
+ test "is not equal to an unpermitted Parameters instance with same params" do
+ params1 = ActionController::Parameters.new(a: 1).permit(:a)
+ params2 = ActionController::Parameters.new(a: 1)
+ assert(params1 != params2)
+ assert(params2 != params1)
+ end
+
+ test "is not equal to Parameters instance with different permitted params" do
+ params1 = ActionController::Parameters.new(a: 1, b: 2).permit(:a, :b)
+ params2 = ActionController::Parameters.new(a: 1, b: 2).permit(:a)
+ assert(params1 != params2)
+ assert(params2 != params1)
+ end
+
+ test "equality with simple types works" do
+ assert(@params != "Hello")
+ assert(@params != 42)
+ assert(@params != false)
+ end
+
+ test "inspect shows both class name, parameters and permitted flag" do
+ assert_equal(
+ '<ActionController::Parameters {"person"=>{"age"=>"32", '\
+ '"name"=>{"first"=>"David", "last"=>"Heinemeier Hansson"}, ' \
+ '"addresses"=>[{"city"=>"Chicago", "state"=>"Illinois"}]}} permitted: false>',
+ @params.inspect
+ )
+ end
+
+ test "inspect prints updated permitted flag in the output" do
+ assert_match(/permitted: false/, @params.inspect)
+
+ @params.permit!
+
+ assert_match(/permitted: true/, @params.inspect)
+ end
+
+ test "#dig delegates the dig method to its values" do
+ assert_equal "David", @params.dig(:person, :name, :first)
+ assert_equal "Chicago", @params.dig(:person, :addresses, 0, :city)
+ end
+
+ test "#dig converts hashes to parameters" do
+ assert_kind_of ActionController::Parameters, @params.dig(:person)
+ assert_kind_of ActionController::Parameters, @params.dig(:person, :addresses, 0)
+ assert @params.dig(:person, :addresses).all? do |value|
+ value.is_a?(ActionController::Parameters)
+ end
+ end
+
+ test "mutating #dig return value mutates underlying parameters" do
+ @params.dig(:person, :name)[:first] = "Bill"
+ assert_equal "Bill", @params.dig(:person, :name, :first)
+
+ @params.dig(:person, :addresses)[0] = { city: "Boston", state: "Massachusetts" }
+ assert_equal "Boston", @params.dig(:person, :addresses, 0, :city)
end
end
diff --git a/actionpack/test/controller/parameters/always_permitted_parameters_test.rb b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb
index efaf8a96c3..974612fb7b 100644
--- a/actionpack/test/controller/parameters/always_permitted_parameters_test.rb
+++ b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class AlwaysPermittedParametersTest < ActiveSupport::TestCase
def setup
@@ -12,24 +14,17 @@ class AlwaysPermittedParametersTest < ActiveSupport::TestCase
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 "returns super on missing constant other than NEVER_UNPERMITTED_PARAMS" do
ActionController::Parameters.superclass.stub :const_missing, "super" do
assert_equal "super", ActionController::Parameters::NON_EXISTING_CONSTANT
end
end
- test "permits parameters that are whitelisted" do
- params = ActionController::Parameters.new({
+ test "allows both explicitly listed and always-permitted parameters" do
+ params = ActionController::Parameters.new(
book: { pages: 65 },
- format: "json"
- })
+ format: "json")
permitted = params.permit book: [:pages]
- assert permitted.permitted?
+ assert_predicate permitted, :permitted?
end
end
diff --git a/actionpack/test/controller/parameters/dup_test.rb b/actionpack/test/controller/parameters/dup_test.rb
new file mode 100644
index 0000000000..5403fc6d93
--- /dev/null
+++ b/actionpack/test/controller/parameters/dup_test.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
+require "active_support/core_ext/object/deep_dup"
+
+class ParametersDupTest < ActiveSupport::TestCase
+ setup do
+ ActionController::Parameters.permit_all_parameters = false
+
+ @params = ActionController::Parameters.new(
+ person: {
+ age: "32",
+ name: {
+ first: "David",
+ last: "Heinemeier Hansson"
+ },
+ addresses: [{ city: "Chicago", state: "Illinois" }]
+ }
+ )
+ end
+
+ test "a duplicate maintains the original's permitted status" do
+ @params.permit!
+ dupped_params = @params.dup
+ assert_predicate dupped_params, :permitted?
+ end
+
+ test "a duplicate maintains the original's parameters" do
+ @params.permit!
+ dupped_params = @params.dup
+ assert_equal @params.to_h, dupped_params.to_h
+ end
+
+ test "changes to a duplicate's parameters do not affect the original" do
+ dupped_params = @params.dup
+ dupped_params.delete(:person)
+ assert_not_equal @params, dupped_params
+ end
+
+ test "changes to a duplicate's permitted status do not affect the original" do
+ dupped_params = @params.dup
+ dupped_params.permit!
+ assert_not_equal @params, dupped_params
+ end
+
+ test "deep_dup content" do
+ dupped_params = @params.deep_dup
+ dupped_params[:person][:age] = "45"
+ dupped_params[:person][:addresses].clear
+
+ assert_not_equal @params[:person][:age], dupped_params[:person][:age]
+ assert_not_equal @params[:person][:addresses], dupped_params[:person][:addresses]
+ end
+
+ test "deep_dup @permitted" do
+ dupped_params = @params.deep_dup
+ dupped_params.permit!
+
+ assert_not_predicate @params, :permitted?
+ end
+
+ test "deep_dup @permitted is being copied" do
+ @params.permit!
+ assert_predicate @params.deep_dup, :permitted?
+ end
+end
diff --git a/actionpack/test/controller/parameters/log_on_unpermitted_params_test.rb b/actionpack/test/controller/parameters/log_on_unpermitted_params_test.rb
index 9ce04b9aeb..fc9229ca1d 100644
--- a/actionpack/test/controller/parameters/log_on_unpermitted_params_test.rb
+++ b/actionpack/test/controller/parameters/log_on_unpermitted_params_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class LogOnUnpermittedParamsTest < ActiveSupport::TestCase
def setup
@@ -11,62 +13,58 @@ class LogOnUnpermittedParamsTest < ActiveSupport::TestCase
end
test "logs on unexpected param" do
- params = ActionController::Parameters.new({
+ params = ActionController::Parameters.new(
book: { pages: 65 },
- fishing: "Turnips"
- })
+ fishing: "Turnips")
- assert_logged("Unpermitted parameter: fishing") do
+ assert_logged("Unpermitted parameter: :fishing") do
params.permit(book: [:pages])
end
end
test "logs on unexpected params" do
- params = ActionController::Parameters.new({
+ params = ActionController::Parameters.new(
book: { pages: 65 },
fishing: "Turnips",
- car: "Mersedes"
- })
+ car: "Mersedes")
- assert_logged("Unpermitted parameters: fishing, car") do
+ assert_logged("Unpermitted parameters: :fishing, :car") do
params.permit(book: [:pages])
end
end
test "logs on unexpected nested param" do
- params = ActionController::Parameters.new({
- book: { pages: 65, title: "Green Cats and where to find then." }
- })
+ params = ActionController::Parameters.new(
+ book: { pages: 65, title: "Green Cats and where to find then." })
- assert_logged("Unpermitted parameter: title") do
+ assert_logged("Unpermitted parameter: :title") do
params.permit(book: [:pages])
end
end
test "logs on unexpected nested params" do
- params = ActionController::Parameters.new({
- book: { pages: 65, title: "Green Cats and where to find then.", author: "G. A. Dog" }
- })
+ params = ActionController::Parameters.new(
+ book: { pages: 65, title: "Green Cats and where to find then.", author: "G. A. Dog" })
- assert_logged("Unpermitted parameters: title, author") do
+ assert_logged("Unpermitted parameters: :title, :author") do
params.permit(book: [:pages])
end
end
private
- def assert_logged(message)
- old_logger = ActionController::Base.logger
- log = StringIO.new
- ActionController::Base.logger = Logger.new(log)
+ def assert_logged(message)
+ old_logger = ActionController::Base.logger
+ log = StringIO.new
+ ActionController::Base.logger = Logger.new(log)
- begin
- yield
+ begin
+ yield
- log.rewind
- assert_match message, log.read
- ensure
- ActionController::Base.logger = old_logger
+ log.rewind
+ assert_match message, log.read
+ ensure
+ ActionController::Base.logger = old_logger
+ end
end
- end
end
diff --git a/actionpack/test/controller/parameters/multi_parameter_attributes_test.rb b/actionpack/test/controller/parameters/multi_parameter_attributes_test.rb
index 15338059bc..c890839727 100644
--- a/actionpack/test/controller/parameters/multi_parameter_attributes_test.rb
+++ b/actionpack/test/controller/parameters/multi_parameter_attributes_test.rb
@@ -1,9 +1,11 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class MultiParameterAttributesTest < ActiveSupport::TestCase
test "permitted multi-parameter attribute keys" do
- params = ActionController::Parameters.new({
+ params = ActionController::Parameters.new(
book: {
"shipped_at(1i)" => "2012",
"shipped_at(2i)" => "3",
@@ -15,12 +17,11 @@ class MultiParameterAttributesTest < ActiveSupport::TestCase
"published_at(3i)" => "5",
"price(1)" => "R$",
"price(2f)" => "2.02"
- }
- })
+ })
permitted = params.permit book: [ :shipped_at, :price ]
- assert permitted.permitted?
+ assert_predicate permitted, :permitted?
assert_equal "2012", permitted[:book]["shipped_at(1i)"]
assert_equal "3", permitted[:book]["shipped_at(2i)"]
diff --git a/actionpack/test/controller/parameters/mutators_test.rb b/actionpack/test/controller/parameters/mutators_test.rb
index 744d8664be..312b1e5b27 100644
--- a/actionpack/test/controller/parameters/mutators_test.rb
+++ b/actionpack/test/controller/parameters/mutators_test.rb
@@ -1,99 +1,121 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
-require 'active_support/core_ext/hash/transform_values'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class ParametersMutatorsTest < ActiveSupport::TestCase
setup do
@params = ActionController::Parameters.new(
person: {
- age: '32',
+ age: "32",
name: {
- first: 'David',
- last: 'Heinemeier Hansson'
+ first: "David",
+ last: "Heinemeier Hansson"
},
- addresses: [{city: 'Chicago', state: 'Illinois'}]
+ addresses: [{ city: "Chicago", state: "Illinois" }]
}
)
end
test "delete retains permitted status" do
@params.permit!
- assert @params.delete(:person).permitted?
+ assert_predicate @params.delete(:person), :permitted?
end
test "delete retains unpermitted status" do
- assert_not @params.delete(:person).permitted?
+ assert_not_predicate @params.delete(:person), :permitted?
+ end
+
+ test "delete returns the value when the key is present" do
+ assert_equal "32", @params[:person].delete(:age)
+ end
+
+ test "delete removes the entry when the key present" do
+ @params[:person].delete(:age)
+ assert_not @params[:person].key?(:age)
+ end
+
+ test "delete returns nil when the key is not present" do
+ assert_nil @params[:person].delete(:first_name)
+ end
+
+ test "delete returns the value of the given block when the key is not present" do
+ assert_equal "David", @params[:person].delete(:first_name) { "David" }
+ end
+
+ test "delete yields the key to the given block when the key is not present" do
+ assert_equal "first_name: David", @params[:person].delete(:first_name) { |k| "#{k}: David" }
end
test "delete_if retains permitted status" do
@params.permit!
- assert @params.delete_if { |k| k == "person" }.permitted?
+ assert_predicate @params.delete_if { |k| k == "person" }, :permitted?
end
test "delete_if retains unpermitted status" do
- assert_not @params.delete_if { |k| k == "person" }.permitted?
+ assert_not_predicate @params.delete_if { |k| k == "person" }, :permitted?
end
test "extract! retains permitted status" do
@params.permit!
- assert @params.extract!(:person).permitted?
+ assert_predicate @params.extract!(:person), :permitted?
end
test "extract! retains unpermitted status" do
- assert_not @params.extract!(:person).permitted?
+ assert_not_predicate @params.extract!(:person), :permitted?
end
test "keep_if retains permitted status" do
@params.permit!
- assert @params.keep_if { |k,v| k == "person" }.permitted?
+ assert_predicate @params.keep_if { |k, v| k == "person" }, :permitted?
end
test "keep_if retains unpermitted status" do
- assert_not @params.keep_if { |k,v| k == "person" }.permitted?
+ assert_not_predicate @params.keep_if { |k, v| k == "person" }, :permitted?
end
test "reject! retains permitted status" do
@params.permit!
- assert @params.reject! { |k| k == "person" }.permitted?
+ assert_predicate @params.reject! { |k| k == "person" }, :permitted?
end
test "reject! retains unpermitted status" do
- assert_not @params.reject! { |k| k == "person" }.permitted?
+ assert_not_predicate @params.reject! { |k| k == "person" }, :permitted?
end
test "select! retains permitted status" do
@params.permit!
- assert @params.select! { |k| k != "person" }.permitted?
+ assert_predicate @params.select! { |k| k != "person" }, :permitted?
end
test "select! retains unpermitted status" do
- assert_not @params.select! { |k| k != "person" }.permitted?
+ assert_not_predicate @params.select! { |k| k != "person" }, :permitted?
end
test "slice! retains permitted status" do
@params.permit!
- assert @params.slice!(:person).permitted?
+ assert_predicate @params.slice!(:person), :permitted?
end
test "slice! retains unpermitted status" do
- assert_not @params.slice!(:person).permitted?
+ assert_not_predicate @params.slice!(:person), :permitted?
end
test "transform_keys! retains permitted status" do
@params.permit!
- assert @params.transform_keys! { |k| k }.permitted?
+ assert_predicate @params.transform_keys! { |k| k }, :permitted?
end
test "transform_keys! retains unpermitted status" do
- assert_not @params.transform_keys! { |k| k }.permitted?
+ assert_not_predicate @params.transform_keys! { |k| k }, :permitted?
end
test "transform_values! retains permitted status" do
@params.permit!
- assert @params.transform_values! { |v| v }.permitted?
+ assert_predicate @params.transform_values! { |v| v }, :permitted?
end
test "transform_values! retains unpermitted status" do
- assert_not @params.transform_values! { |v| v }.permitted?
+ assert_not_predicate @params.transform_values! { |v| v }, :permitted?
end
end
diff --git a/actionpack/test/controller/parameters/nested_parameters_permit_test.rb b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb
new file mode 100644
index 0000000000..1403e224c0
--- /dev/null
+++ b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb
@@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
+
+class NestedParametersPermitTest < ActiveSupport::TestCase
+ def assert_filtered_out(params, key)
+ assert_not params.has_key?(key), "key #{key.inspect} has not been filtered out"
+ end
+
+ test "permitted nested parameters" do
+ params = ActionController::Parameters.new(
+ book: {
+ title: "Romeo and Juliet",
+ authors: [{
+ name: "William Shakespeare",
+ born: "1564-04-26"
+ }, {
+ name: "Christopher Marlowe"
+ }, {
+ name: %w(malicious injected names)
+ }],
+ details: {
+ pages: 200,
+ genre: "Tragedy"
+ },
+ id: {
+ isbn: "x"
+ }
+ },
+ magazine: "Mjallo!")
+
+ permitted = params.permit book: [ :title, { authors: [ :name ] }, { details: :pages }, :id ]
+
+ assert_predicate permitted, :permitted?
+ assert_equal "Romeo and Juliet", permitted[:book][:title]
+ assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
+ assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
+ assert_equal 200, permitted[:book][:details][:pages]
+
+ assert_filtered_out permitted, :magazine
+ assert_filtered_out permitted[:book], :id
+ assert_filtered_out permitted[:book][:details], :genre
+ assert_filtered_out permitted[:book][:authors][0], :born
+ assert_filtered_out permitted[:book][:authors][2], :name
+ end
+
+ test "permitted nested parameters with a string or a symbol as a key" do
+ params = ActionController::Parameters.new(
+ book: {
+ "authors" => [
+ { name: "William Shakespeare", born: "1564-04-26" },
+ { name: "Christopher Marlowe" }
+ ]
+ })
+
+ permitted = params.permit book: [ { "authors" => [ :name ] } ]
+
+ assert_equal "William Shakespeare", permitted[:book]["authors"][0][:name]
+ assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
+ assert_equal "Christopher Marlowe", permitted[:book]["authors"][1][:name]
+ assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
+
+ permitted = params.permit book: [ { authors: [ :name ] } ]
+
+ assert_equal "William Shakespeare", permitted[:book]["authors"][0][:name]
+ assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
+ assert_equal "Christopher Marlowe", permitted[:book]["authors"][1][:name]
+ assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
+ end
+
+ test "nested arrays with strings" do
+ params = ActionController::Parameters.new(
+ book: {
+ genres: ["Tragedy"]
+ })
+
+ permitted = params.permit book: { genres: [] }
+ assert_equal ["Tragedy"], permitted[:book][:genres]
+ end
+
+ test "permit may specify symbols or strings" do
+ params = ActionController::Parameters.new(
+ book: {
+ title: "Romeo and Juliet",
+ author: "William Shakespeare"
+ },
+ magazine: "Shakespeare Today")
+
+ permitted = params.permit({ book: ["title", :author] }, "magazine")
+ assert_equal "Romeo and Juliet", permitted[:book][:title]
+ assert_equal "William Shakespeare", permitted[:book][:author]
+ assert_equal "Shakespeare Today", permitted[:magazine]
+ end
+
+ test "nested array with strings that should be hashes" do
+ params = ActionController::Parameters.new(
+ book: {
+ genres: ["Tragedy"]
+ })
+
+ permitted = params.permit book: { genres: :type }
+ assert_empty permitted[:book][:genres]
+ end
+
+ test "nested array with strings that should be hashes and additional values" do
+ params = ActionController::Parameters.new(
+ book: {
+ title: "Romeo and Juliet",
+ genres: ["Tragedy"]
+ })
+
+ permitted = params.permit book: [ :title, { genres: :type } ]
+ assert_equal "Romeo and Juliet", permitted[:book][:title]
+ assert_empty permitted[:book][:genres]
+ end
+
+ test "nested string that should be a hash" do
+ params = ActionController::Parameters.new(
+ book: {
+ genre: "Tragedy"
+ })
+
+ permitted = params.permit book: { genre: :type }
+ assert_nil permitted[:book][:genre]
+ end
+
+ test "fields_for-style nested params" do
+ params = ActionController::Parameters.new(
+ book: {
+ authors_attributes: {
+ '0': { name: "William Shakespeare", age_of_death: "52" },
+ '1': { name: "Unattributed Assistant" },
+ '2': { name: %w(injected names) }
+ }
+ })
+ permitted = params.permit book: { authors_attributes: [ :name ] }
+
+ assert_not_nil permitted[:book][:authors_attributes]["0"]
+ assert_not_nil permitted[:book][:authors_attributes]["1"]
+ assert_empty permitted[:book][:authors_attributes]["2"]
+ assert_equal "William Shakespeare", permitted[:book][:authors_attributes]["0"][:name]
+ assert_equal "Unattributed Assistant", permitted[:book][:authors_attributes]["1"][:name]
+
+ assert_equal(
+ { "book" => { "authors_attributes" => { "0" => { "name" => "William Shakespeare" }, "1" => { "name" => "Unattributed Assistant" }, "2" => {} } } },
+ permitted.to_h
+ )
+
+ assert_filtered_out permitted[:book][:authors_attributes]["0"], :age_of_death
+ end
+
+ test "fields_for-style nested params with negative numbers" do
+ params = ActionController::Parameters.new(
+ book: {
+ authors_attributes: {
+ '-1': { name: "William Shakespeare", age_of_death: "52" },
+ '-2': { name: "Unattributed Assistant" }
+ }
+ })
+ permitted = params.permit book: { authors_attributes: [:name] }
+
+ assert_not_nil permitted[:book][:authors_attributes]["-1"]
+ assert_not_nil permitted[:book][:authors_attributes]["-2"]
+ assert_equal "William Shakespeare", permitted[:book][:authors_attributes]["-1"][:name]
+ assert_equal "Unattributed Assistant", permitted[:book][:authors_attributes]["-2"][:name]
+
+ assert_filtered_out permitted[:book][:authors_attributes]["-1"], :age_of_death
+ end
+
+ test "nested number as key" do
+ params = ActionController::Parameters.new(
+ product: {
+ properties: {
+ "0" => "prop0",
+ "1" => "prop1"
+ }
+ })
+ params = params.require(:product).permit(properties: ["0"])
+ assert_not_nil params[:properties]["0"]
+ assert_nil params[:properties]["1"]
+ assert_equal "prop0", params[:properties]["0"]
+ end
+end
diff --git a/actionpack/test/controller/parameters/nested_parameters_test.rb b/actionpack/test/controller/parameters/nested_parameters_test.rb
deleted file mode 100644
index 7151a8567c..0000000000
--- a/actionpack/test/controller/parameters/nested_parameters_test.rb
+++ /dev/null
@@ -1,187 +0,0 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
-
-class NestedParametersTest < ActiveSupport::TestCase
- def assert_filtered_out(params, key)
- assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
- end
-
- test "permitted nested parameters" do
- params = ActionController::Parameters.new({
- book: {
- title: "Romeo and Juliet",
- authors: [{
- name: "William Shakespeare",
- born: "1564-04-26"
- }, {
- name: "Christopher Marlowe"
- }, {
- name: %w(malicious injected names)
- }],
- details: {
- pages: 200,
- genre: "Tragedy"
- },
- id: {
- isbn: 'x'
- }
- },
- magazine: "Mjallo!"
- })
-
- permitted = params.permit book: [ :title, { authors: [ :name ] }, { details: :pages }, :id ]
-
- assert permitted.permitted?
- assert_equal "Romeo and Juliet", permitted[:book][:title]
- assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
- assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
- assert_equal 200, permitted[:book][:details][:pages]
-
- assert_filtered_out permitted, :magazine
- assert_filtered_out permitted[:book], :id
- assert_filtered_out permitted[:book][:details], :genre
- assert_filtered_out permitted[:book][:authors][0], :born
- assert_filtered_out permitted[:book][:authors][2], :name
- end
-
- test "permitted nested parameters with a string or a symbol as a key" do
- params = ActionController::Parameters.new({
- book: {
- 'authors' => [
- { name: 'William Shakespeare', born: '1564-04-26' },
- { name: 'Christopher Marlowe' }
- ]
- }
- })
-
- permitted = params.permit book: [ { 'authors' => [ :name ] } ]
-
- assert_equal 'William Shakespeare', permitted[:book]['authors'][0][:name]
- assert_equal 'William Shakespeare', permitted[:book][:authors][0][:name]
- assert_equal 'Christopher Marlowe', permitted[:book]['authors'][1][:name]
- assert_equal 'Christopher Marlowe', permitted[:book][:authors][1][:name]
-
- permitted = params.permit book: [ { authors: [ :name ] } ]
-
- assert_equal 'William Shakespeare', permitted[:book]['authors'][0][:name]
- assert_equal 'William Shakespeare', permitted[:book][:authors][0][:name]
- assert_equal 'Christopher Marlowe', permitted[:book]['authors'][1][:name]
- assert_equal 'Christopher Marlowe', permitted[:book][:authors][1][:name]
- end
-
- test "nested arrays with strings" do
- params = ActionController::Parameters.new({
- book: {
- genres: ["Tragedy"]
- }
- })
-
- permitted = params.permit book: {genres: []}
- assert_equal ["Tragedy"], permitted[:book][:genres]
- end
-
- test "permit may specify symbols or strings" do
- params = ActionController::Parameters.new({
- book: {
- title: "Romeo and Juliet",
- author: "William Shakespeare"
- },
- magazine: "Shakespeare Today"
- })
-
- permitted = params.permit({book: ["title", :author]}, "magazine")
- assert_equal "Romeo and Juliet", permitted[:book][:title]
- assert_equal "William Shakespeare", permitted[:book][:author]
- assert_equal "Shakespeare Today", permitted[:magazine]
- end
-
- test "nested array with strings that should be hashes" do
- params = ActionController::Parameters.new({
- book: {
- genres: ["Tragedy"]
- }
- })
-
- permitted = params.permit book: { genres: :type }
- assert_empty permitted[:book][:genres]
- end
-
- test "nested array with strings that should be hashes and additional values" do
- params = ActionController::Parameters.new({
- book: {
- title: "Romeo and Juliet",
- genres: ["Tragedy"]
- }
- })
-
- permitted = params.permit book: [ :title, { genres: :type } ]
- assert_equal "Romeo and Juliet", permitted[:book][:title]
- assert_empty permitted[:book][:genres]
- end
-
- test "nested string that should be a hash" do
- params = ActionController::Parameters.new({
- book: {
- genre: "Tragedy"
- }
- })
-
- permitted = params.permit book: { genre: :type }
- assert_nil permitted[:book][:genre]
- end
-
- test "fields_for-style nested params" do
- params = ActionController::Parameters.new({
- book: {
- authors_attributes: {
- :'0' => { name: 'William Shakespeare', age_of_death: '52' },
- :'1' => { name: 'Unattributed Assistant' },
- :'2' => { name: %w(injected names) }
- }
- }
- })
- permitted = params.permit book: { authors_attributes: [ :name ] }
-
- assert_not_nil permitted[:book][:authors_attributes]['0']
- assert_not_nil permitted[:book][:authors_attributes]['1']
- assert_empty permitted[:book][:authors_attributes]['2']
- assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['0'][:name]
- assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['1'][:name]
-
- assert_filtered_out permitted[:book][:authors_attributes]['0'], :age_of_death
- end
-
- test "fields_for-style nested params with negative numbers" do
- params = ActionController::Parameters.new({
- book: {
- authors_attributes: {
- :'-1' => { name: 'William Shakespeare', age_of_death: '52' },
- :'-2' => { name: 'Unattributed Assistant' }
- }
- }
- })
- permitted = params.permit book: { authors_attributes: [:name] }
-
- assert_not_nil permitted[:book][:authors_attributes]['-1']
- assert_not_nil permitted[:book][:authors_attributes]['-2']
- assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['-1'][:name]
- assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['-2'][:name]
-
- assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death
- end
-
- test "nested number as key" do
- params = ActionController::Parameters.new({
- product: {
- properties: {
- '0' => "prop0",
- '1' => "prop1"
- }
- }
- })
- params = params.require(:product).permit(:properties => ["0"])
- assert_not_nil params[:properties]["0"]
- assert_nil params[:properties]["1"]
- assert_equal "prop0", params[:properties]["0"]
- end
-end
diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb
index 9f7d14e85d..d2fa0aa16e 100644
--- a/actionpack/test/controller/parameters/parameters_permit_test.rb
+++ b/actionpack/test/controller/parameters/parameters_permit_test.rb
@@ -1,42 +1,65 @@
-require 'abstract_unit'
-require 'action_dispatch/http/upload'
-require 'action_controller/metal/strong_parameters'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/http/upload"
+require "action_controller/metal/strong_parameters"
class ParametersPermitTest < ActiveSupport::TestCase
def assert_filtered_out(params, key)
- assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
+ assert_not params.has_key?(key), "key #{key.inspect} has not been filtered out"
end
setup do
@params = ActionController::Parameters.new(
person: {
- age: '32',
+ age: "32",
name: {
- first: 'David',
- last: 'Heinemeier Hansson'
+ first: "David",
+ last: "Heinemeier Hansson"
},
- addresses: [{city: 'Chicago', state: 'Illinois'}]
+ addresses: [{ city: "Chicago", state: "Illinois" }]
}
)
@struct_fields = []
%w(0 1 12).each do |number|
- ['', 'i', 'f'].each do |suffix|
+ ["", "i", "f"].each do |suffix|
@struct_fields << "sf(#{number}#{suffix})"
end
end
end
- test 'if nothing is permitted, the hash becomes empty' do
- params = ActionController::Parameters.new(id: '1234')
+ def walk_permitted(params)
+ params.each do |k, v|
+ case v
+ when ActionController::Parameters
+ walk_permitted v
+ when Array
+ v.each { |x| walk_permitted v }
+ end
+ end
+ end
+
+ test "iteration should not impact permit" do
+ hash = { "foo" => { "bar" => { "0" => { "baz" => "hello", "zot" => "1" } } } }
+ params = ActionController::Parameters.new(hash)
+
+ walk_permitted params
+
+ sanitized = params[:foo].permit(bar: [:baz])
+ assert_equal({ "0" => { "baz" => "hello" } }, sanitized[:bar].to_unsafe_h)
+ end
+
+ test "if nothing is permitted, the hash becomes empty" do
+ params = ActionController::Parameters.new(id: "1234")
permitted = params.permit
- assert permitted.permitted?
- assert permitted.empty?
+ assert_predicate permitted, :permitted?
+ assert_empty permitted
end
- test 'key: permitted scalar values' do
- values = ['a', :a, nil]
- values += [0, 1.0, 2**128, BigDecimal.new(1)]
+ test "key: permitted scalar values" do
+ values = ["a", :a, nil]
+ values += [0, 1.0, 2**128, BigDecimal(1)]
values += [true, false]
values += [Date.today, Time.now, DateTime.now]
values += [STDOUT, StringIO.new, ActionDispatch::Http::UploadedFile.new(tempfile: __FILE__),
@@ -45,25 +68,33 @@ class ParametersPermitTest < ActiveSupport::TestCase
values.each do |value|
params = ActionController::Parameters.new(id: value)
permitted = params.permit(:id)
- assert_equal value, permitted[:id]
+ if value.nil?
+ assert_nil permitted[:id]
+ else
+ assert_equal value, permitted[:id]
+ end
@struct_fields.each do |sf|
params = ActionController::Parameters.new(sf => value)
permitted = params.permit(:sf)
- assert_equal value, permitted[sf]
+ if value.nil?
+ assert_nil permitted[sf]
+ else
+ assert_equal value, permitted[sf]
+ end
end
end
end
- test 'key: unknown keys are filtered out' do
- params = ActionController::Parameters.new(id: '1234', injected: 'injected')
+ test "key: unknown keys are filtered out" do
+ params = ActionController::Parameters.new(id: "1234", injected: "injected")
permitted = params.permit(:id)
- assert_equal '1234', permitted[:id]
+ assert_equal "1234", permitted[:id]
assert_filtered_out permitted, :injected
end
- test 'key: arrays are filtered out' do
- [[], [1], ['1']].each do |array|
+ test "key: arrays are filtered out" do
+ [[], [1], ["1"]].each do |array|
params = ActionController::Parameters.new(id: array)
permitted = params.permit(:id)
assert_filtered_out permitted, :id
@@ -76,8 +107,8 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
end
- test 'key: hashes are filtered out' do
- [{}, {foo: 1}, {foo: 'bar'}].each do |hash|
+ test "key: hashes are filtered out" do
+ [{}, { foo: 1 }, { foo: "bar" }].each do |hash|
params = ActionController::Parameters.new(id: hash)
permitted = params.permit(:id)
assert_filtered_out permitted, :id
@@ -90,7 +121,7 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
end
- test 'key: non-permitted scalar values are filtered out' do
+ test "key: non-permitted scalar values are filtered out" do
params = ActionController::Parameters.new(id: Object.new)
permitted = params.permit(:id)
assert_filtered_out permitted, :id
@@ -102,51 +133,84 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
end
- test 'key: it is not assigned if not present in params' do
- params = ActionController::Parameters.new(name: 'Joe')
+ test "key: it is not assigned if not present in params" do
+ params = ActionController::Parameters.new(name: "Joe")
permitted = params.permit(:id)
- assert !permitted.has_key?(:id)
+ assert_not permitted.has_key?(:id)
end
- test 'key to empty array: empty arrays pass' do
+ test "key to empty array: empty arrays pass" do
params = ActionController::Parameters.new(id: [])
permitted = params.permit(id: [])
assert_equal [], permitted[:id]
end
- test 'do not break params filtering on nil values' do
+ test "do not break params filtering on nil values" do
params = ActionController::Parameters.new(a: 1, b: [1, 2, 3], c: nil)
permitted = params.permit(:a, c: [], b: [])
assert_equal 1, permitted[:a]
assert_equal [1, 2, 3], permitted[:b]
- assert_equal nil, permitted[:c]
+ assert_nil permitted[:c]
end
- test 'key to empty array: arrays of permitted scalars pass' do
- [['foo'], [1], ['foo', 'bar'], [1, 2, 3]].each do |array|
+ test "key to empty array: arrays of permitted scalars pass" do
+ [["foo"], [1], ["foo", "bar"], [1, 2, 3]].each do |array|
params = ActionController::Parameters.new(id: array)
permitted = params.permit(id: [])
assert_equal array, permitted[:id]
end
end
- test 'key to empty array: permitted scalar values do not pass' do
- ['foo', 1].each do |permitted_scalar|
+ test "key to empty array: permitted scalar values do not pass" do
+ ["foo", 1].each do |permitted_scalar|
params = ActionController::Parameters.new(id: permitted_scalar)
permitted = params.permit(id: [])
assert_filtered_out permitted, :id
end
end
- test 'key to empty array: arrays of non-permitted scalar do not pass' do
- [[Object.new], [[]], [[1]], [{}], [{id: '1'}]].each do |non_permitted_scalar|
+ test "key to empty array: arrays of non-permitted scalar do not pass" do
+ [[Object.new], [[]], [[1]], [{}], [{ id: "1" }]].each do |non_permitted_scalar|
params = ActionController::Parameters.new(id: non_permitted_scalar)
permitted = params.permit(id: [])
assert_filtered_out permitted, :id
end
end
+ test "key to empty hash: arbitrary hashes are permitted" do
+ params = ActionController::Parameters.new(
+ username: "fxn",
+ preferences: {
+ scheme: "Marazul",
+ font: {
+ name: "Source Code Pro",
+ size: 12
+ },
+ tabstops: [4, 8, 12, 16],
+ suspicious: [true, Object.new, false, /yo!/],
+ dubious: [{ a: :a, b: /wtf!/ }, { c: :c }],
+ injected: Object.new
+ },
+ hacked: 1 # not a hash
+ )
+
+ permitted = params.permit(:username, preferences: {}, hacked: {})
+
+ assert_equal "fxn", permitted[:username]
+ assert_equal "Marazul", permitted[:preferences][:scheme]
+ assert_equal "Source Code Pro", permitted[:preferences][:font][:name]
+ assert_equal 12, permitted[:preferences][:font][:size]
+ assert_equal [4, 8, 12, 16], permitted[:preferences][:tabstops]
+ assert_equal [true, false], permitted[:preferences][:suspicious]
+ assert_equal :a, permitted[:preferences][:dubious][0][:a]
+ assert_equal :c, permitted[:preferences][:dubious][1][:c]
+
+ assert_filtered_out permitted[:preferences][:dubious][0], :b
+ assert_filtered_out permitted[:preferences], :injected
+ assert_filtered_out permitted, :hacked
+ end
+
test "fetch raises ParameterMissing exception" do
e = assert_raises(ActionController::ParameterMissing) do
@params.fetch :foo
@@ -157,20 +221,20 @@ class ParametersPermitTest < ActiveSupport::TestCase
test "fetch with a default value of a hash does not mutate the object" do
params = ActionController::Parameters.new({})
params.fetch :foo, {}
- assert_equal nil, params[:foo]
+ assert_nil params[:foo]
end
- test 'hashes in array values get wrapped' do
+ test "hashes in array values get wrapped" do
params = ActionController::Parameters.new(foo: [{}, {}])
params[:foo].each do |hash|
- assert !hash.permitted?
+ assert_not_predicate hash, :permitted?
end
end
# Strong params has an optimization to avoid looping every time you read
# a key whose value is an array and building a new object. We check that
# optimization here.
- test 'arrays are converted at most once' do
+ test "arrays are converted at most once" do
params = ActionController::Parameters.new(foo: [{}])
assert_same params[:foo], params[:foo]
end
@@ -181,12 +245,12 @@ class ParametersPermitTest < ActiveSupport::TestCase
# This test checks that if we push a hash to an array (in-place modification)
# the cache does not get fooled, the hash is still wrapped as strong params,
# and not permitted.
- test 'mutated arrays are detected' do
- params = ActionController::Parameters.new(users: [{id: 1}])
+ test "mutated arrays are detected" do
+ params = ActionController::Parameters.new(users: [{ id: 1 }])
permitted = params.permit(users: [:id])
- permitted[:users] << {injected: 1}
- assert_not permitted[:users].last.permitted?
+ permitted[:users] << { injected: 1 }
+ assert_not_predicate permitted[:users].last, :permitted?
end
test "fetch doesnt raise ParameterMissing exception if there is a default" do
@@ -195,11 +259,11 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
test "fetch doesnt raise ParameterMissing exception if there is a default that is nil" do
- assert_equal nil, @params.fetch(:foo, nil)
- assert_equal nil, @params.fetch(:foo) { nil }
+ assert_nil @params.fetch(:foo, nil)
+ assert_nil @params.fetch(:foo) { nil }
end
- test 'KeyError in fetch block should not be covered up' do
+ test "KeyError in fetch block should not be covered up" do
params = ActionController::Parameters.new
e = assert_raises(KeyError) do
params.fetch(:missing_key) { {}.fetch(:also_missing) }
@@ -208,12 +272,77 @@ class ParametersPermitTest < ActiveSupport::TestCase
end
test "not permitted is sticky beyond merges" do
- assert !@params.merge(a: "b").permitted?
+ assert_not_predicate @params.merge(a: "b"), :permitted?
end
test "permitted is sticky beyond merges" do
@params.permit!
- assert @params.merge(a: "b").permitted?
+ assert_predicate @params.merge(a: "b"), :permitted?
+ end
+
+ test "merge with parameters" do
+ other_params = ActionController::Parameters.new(id: "1234").permit!
+ merged_params = @params.merge(other_params)
+
+ assert merged_params[:id]
+ end
+
+ test "not permitted is sticky beyond merge!" do
+ assert_not_predicate @params.merge!(a: "b"), :permitted?
+ end
+
+ test "permitted is sticky beyond merge!" do
+ @params.permit!
+ assert_predicate @params.merge!(a: "b"), :permitted?
+ end
+
+ test "merge! with parameters" do
+ other_params = ActionController::Parameters.new(id: "1234").permit!
+ @params.merge!(other_params)
+
+ assert_equal "1234", @params[:id]
+ assert_equal "32", @params[:person][:age]
+ end
+
+ test "#reverse_merge with parameters" do
+ default_params = ActionController::Parameters.new(id: "1234", person: {}).permit!
+ merged_params = @params.reverse_merge(default_params)
+
+ assert_equal "1234", merged_params[:id]
+ assert_not_predicate merged_params[:person], :empty?
+ end
+
+ test "#with_defaults is an alias of reverse_merge" do
+ default_params = ActionController::Parameters.new(id: "1234", person: {}).permit!
+ merged_params = @params.with_defaults(default_params)
+
+ assert_equal "1234", merged_params[:id]
+ assert_not_predicate merged_params[:person], :empty?
+ end
+
+ test "not permitted is sticky beyond reverse_merge" do
+ assert_not_predicate @params.reverse_merge(a: "b"), :permitted?
+ end
+
+ test "permitted is sticky beyond reverse_merge" do
+ @params.permit!
+ assert_predicate @params.reverse_merge(a: "b"), :permitted?
+ end
+
+ test "#reverse_merge! with parameters" do
+ default_params = ActionController::Parameters.new(id: "1234", person: {}).permit!
+ @params.reverse_merge!(default_params)
+
+ assert_equal "1234", @params[:id]
+ assert_not_predicate @params[:person], :empty?
+ end
+
+ test "#with_defaults! is an alias of reverse_merge!" do
+ default_params = ActionController::Parameters.new(id: "1234", person: {}).permit!
+ @params.with_defaults!(default_params)
+
+ assert_equal "1234", @params[:id]
+ assert_not_predicate @params[:person], :empty?
end
test "modifying the parameters" do
@@ -224,28 +353,26 @@ class ParametersPermitTest < ActiveSupport::TestCase
assert_equal "Jonas", @params[:person][:family][:brother]
end
- test "permit state is kept on a dup" do
- @params.permit!
- assert_equal @params.permitted?, @params.dup.permitted?
- end
-
- test "permit is recursive" do
+ test "permit! is recursive" do
+ @params[:nested_array] = [[{ x: 2, y: 3 }, { x: 21, y: 42 }]]
@params.permit!
- assert @params.permitted?
- assert @params[:person].permitted?
- assert @params[:person][:name].permitted?
- assert @params[:person][:addresses][0].permitted?
+ assert_predicate @params, :permitted?
+ assert_predicate @params[:person], :permitted?
+ assert_predicate @params[:person][:name], :permitted?
+ assert_predicate @params[:person][:addresses][0], :permitted?
+ assert_predicate @params[:nested_array][0][0], :permitted?
+ assert_predicate @params[:nested_array][0][1], :permitted?
end
test "permitted takes a default value when Parameters.permit_all_parameters is set" do
begin
ActionController::Parameters.permit_all_parameters = true
- params = ActionController::Parameters.new({ person: {
+ params = ActionController::Parameters.new(person: {
age: "32", name: { first: "David", last: "Heinemeier Hansson" }
- }})
+ })
- assert params.slice(:person).permitted?
- assert params[:person][:name].permitted?
+ assert_predicate params.slice(:person), :permitted?
+ assert_predicate params[:person][:name], :permitted?
ensure
ActionController::Parameters.permit_all_parameters = false
end
@@ -255,17 +382,17 @@ class ParametersPermitTest < ActiveSupport::TestCase
assert_equal "32", @params[:person].permit([ :age ])[:age]
end
- test "to_h returns empty hash on unpermitted params" do
- assert @params.to_h.is_a? Hash
- assert_not @params.to_h.is_a? ActionController::Parameters
- assert @params.to_h.empty?
+ test "to_h raises UnfilteredParameters on unfiltered params" do
+ assert_raises(ActionController::UnfilteredParameters) do
+ @params.to_h
+ end
end
test "to_h returns converted hash on permitted params" do
@params.permit!
- assert @params.to_h.is_a? Hash
- assert_not @params.to_h.is_a? ActionController::Parameters
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, @params.to_h
+ assert_not_kind_of ActionController::Parameters, @params.to_h
end
test "to_h returns converted hash when .permit_all_parameters is set" do
@@ -273,28 +400,117 @@ class ParametersPermitTest < ActiveSupport::TestCase
ActionController::Parameters.permit_all_parameters = true
params = ActionController::Parameters.new(crab: "Senjougahara Hitagi")
- assert params.to_h.is_a? Hash
- assert_not @params.to_h.is_a? ActionController::Parameters
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, params.to_h
+ assert_not_kind_of ActionController::Parameters, params.to_h
assert_equal({ "crab" => "Senjougahara Hitagi" }, params.to_h)
ensure
ActionController::Parameters.permit_all_parameters = false
end
end
- test "to_h returns always permitted parameter on unpermitted params" do
- params = ActionController::Parameters.new(
- controller: "users",
- action: "create",
- user: {
- name: "Sengoku Nadeko"
- }
- )
+ test "to_hash raises UnfilteredParameters on unfiltered params" do
+ assert_raises(ActionController::UnfilteredParameters) do
+ @params.to_hash
+ end
+ end
+
+ test "to_hash returns converted hash on permitted params" do
+ @params.permit!
+
+ assert_instance_of Hash, @params.to_hash
+ assert_not_kind_of ActionController::Parameters, @params.to_hash
+ end
- assert_equal({ "controller" => "users", "action" => "create" }, params.to_h)
+ test "parameters can be implicit converted to Hash" do
+ params = ActionController::Parameters.new
+ params.permit!
+
+ assert_equal({ a: 1 }, { a: 1 }.merge!(params))
+ end
+
+ test "to_hash returns converted hash when .permit_all_parameters is set" do
+ begin
+ ActionController::Parameters.permit_all_parameters = true
+ params = ActionController::Parameters.new(crab: "Senjougahara Hitagi")
+
+ assert_instance_of Hash, params.to_hash
+ assert_not_kind_of ActionController::Parameters, params.to_hash
+ assert_equal({ "crab" => "Senjougahara Hitagi" }, params.to_hash)
+ assert_equal({ "crab" => "Senjougahara Hitagi" }, params)
+ ensure
+ ActionController::Parameters.permit_all_parameters = false
+ end
end
test "to_unsafe_h returns unfiltered params" do
- assert @params.to_h.is_a? Hash
- assert_not @params.to_h.is_a? ActionController::Parameters
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, @params.to_unsafe_h
+ assert_not_kind_of ActionController::Parameters, @params.to_unsafe_h
+ end
+
+ test "to_unsafe_h returns unfiltered params even after accessing few keys" do
+ params = ActionController::Parameters.new("f" => { "language_facet" => ["Tibetan"] })
+ expected = { "f" => { "language_facet" => ["Tibetan"] } }
+
+ assert_instance_of ActionController::Parameters, params["f"]
+ assert_equal expected, params.to_unsafe_h
+ end
+
+ test "to_unsafe_h does not mutate the parameters" do
+ params = ActionController::Parameters.new("f" => { "language_facet" => ["Tibetan"] })
+ params[:f]
+
+ params.to_unsafe_h
+
+ assert_not_predicate params, :permitted?
+ assert_not_predicate params[:f], :permitted?
+ end
+
+ test "to_h only deep dups Ruby collections" do
+ company = Class.new do
+ attr_reader :dupped
+ def dup; @dupped = true; end
+ end.new
+
+ params = ActionController::Parameters.new(prem: { likes: %i( dancing ) })
+ assert_equal({ "prem" => { "likes" => %i( dancing ) } }, params.permit!.to_h)
+
+ params = ActionController::Parameters.new(companies: [ company, :acme ])
+ assert_equal({ "companies" => [ company, :acme ] }, params.permit!.to_h)
+ assert_not company.dupped
+ end
+
+ test "to_unsafe_h only deep dups Ruby collections" do
+ company = Class.new do
+ attr_reader :dupped
+ def dup; @dupped = true; end
+ end.new
+
+ params = ActionController::Parameters.new(prem: { likes: %i( dancing ) })
+ assert_equal({ "prem" => { "likes" => %i( dancing ) } }, params.to_unsafe_h)
+
+ params = ActionController::Parameters.new(companies: [ company, :acme ])
+ assert_equal({ "companies" => [ company, :acme ] }, params.to_unsafe_h)
+ assert_not company.dupped
+ end
+
+ test "include? returns true when the key is present" do
+ assert @params.include? :person
+ assert @params.include? "person"
+ assert_not @params.include? :gorilla
+ end
+
+ test "scalar values should be filtered when array or hash is specified" do
+ params = ActionController::Parameters.new(foo: "bar")
+
+ assert params.permit(:foo).has_key?(:foo)
+ assert_not params.permit(foo: []).has_key?(:foo)
+ assert_not params.permit(foo: [:bar]).has_key?(:foo)
+ assert_not params.permit(foo: :bar).has_key?(:foo)
+ end
+
+ test "#permitted? is false by default" do
+ params = ActionController::Parameters.new
+
+ assert_equal false, params.permitted?
end
end
diff --git a/actionpack/test/controller/parameters/raise_on_unpermitted_params_test.rb b/actionpack/test/controller/parameters/raise_on_unpermitted_params_test.rb
index f9cc9f96f1..4afd3da593 100644
--- a/actionpack/test/controller/parameters/raise_on_unpermitted_params_test.rb
+++ b/actionpack/test/controller/parameters/raise_on_unpermitted_params_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_controller/metal/strong_parameters'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
class RaiseOnUnpermittedParamsTest < ActiveSupport::TestCase
def setup
@@ -11,10 +13,9 @@ class RaiseOnUnpermittedParamsTest < ActiveSupport::TestCase
end
test "raises on unexpected params" do
- params = ActionController::Parameters.new({
+ params = ActionController::Parameters.new(
book: { pages: 65 },
- fishing: "Turnips"
- })
+ fishing: "Turnips")
assert_raises(ActionController::UnpermittedParameters) do
params.permit(book: [:pages])
@@ -22,9 +23,8 @@ class RaiseOnUnpermittedParamsTest < ActiveSupport::TestCase
end
test "raises on unexpected nested params" do
- params = ActionController::Parameters.new({
- book: { pages: 65, title: "Green Cats and where to find then." }
- })
+ params = ActionController::Parameters.new(
+ book: { pages: 65, title: "Green Cats and where to find then." })
assert_raises(ActionController::UnpermittedParameters) do
params.permit(book: [:pages])
diff --git a/actionpack/test/controller/parameters/serialization_test.rb b/actionpack/test/controller/parameters/serialization_test.rb
new file mode 100644
index 0000000000..7708c8e4fe
--- /dev/null
+++ b/actionpack/test/controller/parameters/serialization_test.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_controller/metal/strong_parameters"
+
+class ParametersSerializationTest < ActiveSupport::TestCase
+ setup do
+ @old_permitted_parameters = ActionController::Parameters.permit_all_parameters
+ ActionController::Parameters.permit_all_parameters = false
+ end
+
+ teardown do
+ ActionController::Parameters.permit_all_parameters = @old_permitted_parameters
+ end
+
+ test "yaml serialization" do
+ params = ActionController::Parameters.new(key: :value)
+ yaml_dump = YAML.dump(params)
+ assert_match("--- !ruby/object:ActionController::Parameters", yaml_dump)
+ assert_match(/parameters: !ruby\/hash:ActiveSupport::HashWithIndifferentAccess\n\s+key: :value/, yaml_dump)
+ assert_match("permitted: false", yaml_dump)
+ end
+
+ test "yaml deserialization" do
+ params = ActionController::Parameters.new(key: :value)
+ roundtripped = YAML.load(YAML.dump(params))
+
+ assert_equal params, roundtripped
+ assert_not_predicate roundtripped, :permitted?
+ end
+
+ test "yaml backwardscompatible with psych 2.0.8 format" do
+ params = YAML.load <<~end_of_yaml
+ --- !ruby/hash:ActionController::Parameters
+ key: :value
+ end_of_yaml
+
+ assert_equal :value, params[:key]
+ assert_not_predicate params, :permitted?
+ end
+
+ test "yaml backwardscompatible with psych 2.0.9+ format" do
+ params = YAML.load(<<~end_of_yaml)
+ --- !ruby/hash-with-ivars:ActionController::Parameters
+ elements:
+ key: :value
+ ivars:
+ :@permitted: false
+ end_of_yaml
+
+ assert_equal :value, params[:key]
+ assert_not_predicate params, :permitted?
+ end
+end
diff --git a/actionpack/test/controller/params_parse_test.rb b/actionpack/test/controller/params_parse_test.rb
new file mode 100644
index 0000000000..440ab06fd7
--- /dev/null
+++ b/actionpack/test/controller/params_parse_test.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class ParamsParseTest < ActionController::TestCase
+ class UsersController < ActionController::Base
+ def create
+ head :ok
+ end
+ end
+
+ tests UsersController
+
+ def test_parse_error_logged_once
+ log_output = capture_log_output do
+ post :create, body: "{", as: :json
+ end
+ assert_equal <<~LOG, log_output
+ Error occurred while parsing request parameters.
+ Contents:
+
+ {
+ LOG
+ end
+
+ private
+
+ def capture_log_output
+ output = StringIO.new
+ request.set_header "action_dispatch.logger", ActiveSupport::Logger.new(output)
+ yield
+ output.string
+ end
+end
diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb
index 7226beed26..c4c74e8f2b 100644
--- a/actionpack/test/controller/params_wrapper_test.rb
+++ b/actionpack/test/controller/params_wrapper_test.rb
@@ -1,10 +1,12 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module Admin; class User; end; end
module ParamsWrapperTestHelp
def with_default_wrapper_options(&block)
- @controller.class._set_wrapper_options({:format => [:json]})
+ @controller.class._set_wrapper_options(format: [:json])
@controller.class.inherited(@controller.class)
yield
end
@@ -32,6 +34,10 @@ class ParamsWrapperTest < ActionController::TestCase
def self.attribute_names
[]
end
+
+ def self.stored_attributes
+ { settings: [:color, :size] }
+ end
end
class Person
@@ -48,17 +54,28 @@ class ParamsWrapperTest < ActionController::TestCase
def test_filtered_parameters
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_equal @request.filtered_parameters, { 'controller' => 'params_wrapper_test/users', 'action' => 'parse', 'username' => 'sikachu', 'user' => { 'username' => 'sikachu' } }
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_equal({ "controller" => "params_wrapper_test/users", "action" => "parse", "username" => "sikachu", "user" => { "username" => "sikachu" } }, @request.filtered_parameters)
end
end
def test_derived_name_from_controller
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({ 'username' => 'sikachu', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu", "user" => { "username" => "sikachu" })
+ end
+ end
+
+ def test_store_accessors_wrapped
+ assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
+ with_default_wrapper_options do
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "color" => "blue", "size" => "large" }
+ assert_parameters("username" => "sikachu", "color" => "blue", "size" => "large",
+ "user" => { "username" => "sikachu", "color" => "blue", "size" => "large" })
+ end
end
end
@@ -66,9 +83,9 @@ class ParamsWrapperTest < ActionController::TestCase
with_default_wrapper_options do
UsersController.wrap_parameters :person
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({ 'username' => 'sikachu', 'person' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu", "person" => { "username" => "sikachu" })
end
end
@@ -76,99 +93,107 @@ class ParamsWrapperTest < ActionController::TestCase
with_default_wrapper_options do
UsersController.wrap_parameters Person
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({ 'username' => 'sikachu', 'person' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu", "person" => { "username" => "sikachu" })
end
end
def test_specify_include_option
with_default_wrapper_options do
- UsersController.wrap_parameters :include => :username
+ UsersController.wrap_parameters include: :username
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
end
end
def test_specify_exclude_option
with_default_wrapper_options do
- UsersController.wrap_parameters :exclude => :title
+ UsersController.wrap_parameters exclude: :title
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
end
end
def test_specify_both_wrapper_name_and_include_option
with_default_wrapper_options do
- UsersController.wrap_parameters :person, :include => :username
+ UsersController.wrap_parameters :person, include: :username
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" })
end
end
def test_not_enabled_format
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/xml'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer' })
+ @request.env["CONTENT_TYPE"] = "application/xml"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer")
end
end
def test_wrap_parameters_false
with_default_wrapper_options do
UsersController.wrap_parameters false
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer' })
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer")
end
end
def test_specify_format
with_default_wrapper_options do
- UsersController.wrap_parameters :format => :xml
+ UsersController.wrap_parameters format: :xml
- @request.env['CONTENT_TYPE'] = 'application/xml'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu', 'title' => 'Developer' }})
+ @request.env["CONTENT_TYPE"] = "application/xml"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" })
end
end
def test_not_wrap_reserved_parameters
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'authenticity_token' => 'pwned', '_method' => 'put', 'utf8' => '&#9731;', 'username' => 'sikachu' }
- assert_parameters({ 'authenticity_token' => 'pwned', '_method' => 'put', 'utf8' => '&#9731;', 'username' => 'sikachu', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu" }
+ assert_parameters("authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu", "user" => { "username" => "sikachu" })
end
end
def test_no_double_wrap_if_key_exists
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'user' => { 'username' => 'sikachu' }}
- assert_parameters({ 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "user" => { "username" => "sikachu" } }
+ assert_parameters("user" => { "username" => "sikachu" })
+ end
+ end
+
+ def test_no_double_wrap_if_key_exists_and_value_is_nil
+ with_default_wrapper_options do
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "user" => nil }
+ assert_parameters("user" => nil)
end
end
def test_nested_params
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'person' => { 'username' => 'sikachu' }}
- assert_parameters({ 'person' => { 'username' => 'sikachu' }, 'user' => {'person' => { 'username' => 'sikachu' }}})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "person" => { "username" => "sikachu" } }
+ assert_parameters("person" => { "username" => "sikachu" }, "user" => { "person" => { "username" => "sikachu" } })
end
end
def test_derived_wrapped_keys_from_matching_model
assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
end
end
end
@@ -178,40 +203,72 @@ class ParamsWrapperTest < ActionController::TestCase
assert_called(Person, :attribute_names, times: 2, returns: ["username"]) do
UsersController.wrap_parameters Person
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" })
end
end
end
def test_not_wrapping_abstract_model
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu', 'title' => 'Developer' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" })
end
end
def test_preserves_query_string_params
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- get :parse, params: { 'user' => { 'username' => 'nixon' } }
+ @request.env["CONTENT_TYPE"] = "application/json"
+ get :parse, params: { "user" => { "username" => "nixon" } }
assert_parameters(
- {'user' => { 'username' => 'nixon' } }
+ "user" => { "username" => "nixon" }
)
end
end
+ def test_preserves_query_string_params_in_filtered_params
+ with_default_wrapper_options do
+ @request.env["CONTENT_TYPE"] = "application/json"
+ get :parse, params: { "user" => { "username" => "nixon" } }
+ assert_equal({ "controller" => "params_wrapper_test/users", "action" => "parse", "user" => { "username" => "nixon" } }, @request.filtered_parameters)
+ end
+ end
+
def test_empty_parameter_set
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
+ @request.env["CONTENT_TYPE"] = "application/json"
post :parse, params: {}
assert_parameters(
- {'user' => { } }
+ "user" => {}
)
end
end
+
+ def test_handles_empty_content_type
+ with_default_wrapper_options do
+ @request.env["CONTENT_TYPE"] = nil
+ _controller_class.dispatch(:parse, @request, @response)
+
+ assert_equal 200, @response.status
+ assert_equal "", @response.body
+ end
+ end
+
+ def test_derived_wrapped_keys_from_nested_attributes
+ def User.nested_attributes_options
+ { person: {} }
+ end
+
+ assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
+ with_default_wrapper_options do
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "person_attributes" => { "title" => "Developer" } }
+ assert_parameters("username" => "sikachu", "person_attributes" => { "title" => "Developer" }, "user" => { "username" => "sikachu", "person_attributes" => { "title" => "Developer" } })
+ end
+ end
+ end
end
class NamespacedParamsWrapperTest < ActionController::TestCase
@@ -219,7 +276,7 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
module Admin
module Users
- class UsersController < ActionController::Base;
+ class UsersController < ActionController::Base
class << self
attr_accessor :last_parameters
end
@@ -252,9 +309,9 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
def test_derived_name_from_controller
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({'username' => 'sikachu', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu", "user" => { "username" => "sikachu" })
end
end
@@ -262,9 +319,9 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
Admin.const_set(:User, Class.new(SampleOne))
begin
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
end
ensure
Admin.send :remove_const, :User
@@ -275,15 +332,14 @@ class NamespacedParamsWrapperTest < ActionController::TestCase
Object.const_set(:User, Class.new(SampleTwo))
begin
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'title' => 'Developer' }
- assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'title' => 'Developer' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "title" => "Developer" }
+ assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "title" => "Developer" })
end
ensure
Object.send :remove_const, :User
end
end
-
end
class AnonymousControllerParamsWrapperTest < ActionController::TestCase
@@ -302,18 +358,18 @@ class AnonymousControllerParamsWrapperTest < ActionController::TestCase
def test_does_not_implicitly_wrap_params
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({ 'username' => 'sikachu' })
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu")
end
end
def test_does_wrap_params_if_name_provided
with_default_wrapper_options do
- @controller.class.wrap_parameters(:name => "guest")
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu' }
- assert_parameters({ 'username' => 'sikachu', 'guest' => { 'username' => 'sikachu' }})
+ @controller.class.wrap_parameters(name: "guest")
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu" }
+ assert_parameters("username" => "sikachu", "guest" => { "username" => "sikachu" })
end
end
end
@@ -323,7 +379,7 @@ class IrregularInflectionParamsWrapperTest < ActionController::TestCase
class ParamswrappernewsItem
def self.attribute_names
- ['test_attr']
+ ["test_attr"]
end
end
@@ -343,24 +399,24 @@ class IrregularInflectionParamsWrapperTest < ActionController::TestCase
def test_uses_model_attribute_names_with_irregular_inflection
with_dup do
ActiveSupport::Inflector.inflections do |inflect|
- inflect.irregular 'paramswrappernews_item', 'paramswrappernews'
+ inflect.irregular "paramswrappernews_item", "paramswrappernews"
end
with_default_wrapper_options do
- @request.env['CONTENT_TYPE'] = 'application/json'
- post :parse, params: { 'username' => 'sikachu', 'test_attr' => 'test_value' }
- assert_parameters({ 'username' => 'sikachu', 'test_attr' => 'test_value', 'paramswrappernews_item' => { 'test_attr' => 'test_value' }})
+ @request.env["CONTENT_TYPE"] = "application/json"
+ post :parse, params: { "username" => "sikachu", "test_attr" => "test_value" }
+ assert_parameters("username" => "sikachu", "test_attr" => "test_value", "paramswrappernews_item" => { "test_attr" => "test_value" })
end
end
end
private
- def with_dup
- original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)[:en]
- ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original.dup)
- yield
- ensure
- ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original)
- end
+ def with_dup
+ original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)[:en]
+ ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original.dup)
+ yield
+ ensure
+ ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original)
+ end
end
diff --git a/actionpack/test/controller/permitted_params_test.rb b/actionpack/test/controller/permitted_params_test.rb
index 7c753a45a5..caac88ffb2 100644
--- a/actionpack/test/controller/permitted_params_test.rb
+++ b/actionpack/test/controller/permitted_params_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class PeopleController < ActionController::Base
def create
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index 631ff7d02a..998498e1b2 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -1,53 +1,83 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class Workshop
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ OUT_OF_SCOPE_BLOCK = proc do
+ raise "Not executed in controller's context" unless RedirectController === self
+ request.original_url
+ end
+
+ attr_accessor :id
+
+ def initialize(id)
+ @id = id
+ end
+
+ def persisted?
+ id.present?
+ end
+
+ def to_s
+ id.to_s
+ end
+end
class RedirectController < ActionController::Base
# empty method not used anywhere to ensure methods like
# `status` and `location` aren't called on `redirect_to` calls
- def status; render plain: 'called status'; end
- def location; render plain: 'called location'; end
+ def status; raise "Should not be called!"; end
+ def location; raise "Should not be called!"; end
def simple_redirect
- redirect_to :action => "hello_world"
+ redirect_to action: "hello_world"
end
def redirect_with_status
- redirect_to({:action => "hello_world", :status => 301})
+ redirect_to(action: "hello_world", status: 301)
end
def redirect_with_status_hash
- redirect_to({:action => "hello_world"}, {:status => 301})
+ redirect_to({ action: "hello_world" }, { status: 301 })
end
def redirect_with_protocol
- redirect_to :action => "hello_world", :protocol => "https"
+ redirect_to action: "hello_world", protocol: "https"
end
def url_redirect_with_status
- redirect_to("http://www.example.com", :status => :moved_permanently)
+ redirect_to("http://www.example.com", status: :moved_permanently)
end
def url_redirect_with_status_hash
- redirect_to("http://www.example.com", {:status => 301})
+ redirect_to("http://www.example.com", status: 301)
end
def relative_url_redirect_with_status
- redirect_to("/things/stuff", :status => :found)
+ redirect_to("/things/stuff", status: :found)
end
def relative_url_redirect_with_status_hash
- redirect_to("/things/stuff", {:status => 301})
+ redirect_to("/things/stuff", status: 301)
+ end
+
+ def redirect_back_with_status
+ redirect_back(fallback_location: "/things/stuff", status: 307)
end
- def redirect_to_back_with_status
- redirect_to :back, :status => 307
+ def safe_redirect_back_with_status
+ redirect_back(fallback_location: "/things/stuff", status: 307, allow_other_host: false)
end
def host_redirect
- redirect_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ redirect_to action: "other_host", only_path: false, host: "other.test.host"
end
def module_redirect
- redirect_to :controller => 'module_test/module_redirect', :action => "hello_world"
+ redirect_to controller: "module_test/module_redirect", action: "hello_world"
end
def redirect_to_url
@@ -66,10 +96,6 @@ class RedirectController < ActionController::Base
redirect_to "//www.rubyonrails.org/"
end
- def redirect_to_back
- redirect_to :back
- end
-
def redirect_to_existing_record
redirect_to Workshop.new(5)
end
@@ -83,7 +109,7 @@ class RedirectController < ActionController::Base
end
def redirect_to_params
- redirect_to ActionController::Parameters.new(status: 200, protocol: 'javascript', f: '%0Aeval(name)')
+ redirect_to ActionController::Parameters.new(status: 200, protocol: "javascript", f: "%0Aeval(name)")
end
def redirect_to_with_block
@@ -96,7 +122,11 @@ class RedirectController < ActionController::Base
end
def redirect_to_with_block_and_options
- redirect_to proc { {:action => "hello_world"} }
+ redirect_to proc { { action: "hello_world" } }
+ end
+
+ def redirect_to_out_of_scope_block
+ redirect_to Workshop::OUT_OF_SCOPE_BLOCK
end
def redirect_with_header_break
@@ -109,9 +139,9 @@ class RedirectController < ActionController::Base
def rescue_errors(e) raise e end
- protected
+ private
def dashbord_url(id, message)
- url_for :action => "dashboard", :params => { "id" => id, "message" => message }
+ url_for action: "dashboard", params: { "id" => id, "message" => message }
end
end
@@ -172,7 +202,6 @@ class RedirectTest < ActionController::TestCase
assert_equal "http://www.example.com", redirect_to_url
end
-
def test_relative_url_redirect_with_status
get :relative_url_redirect_with_status
assert_response 302
@@ -185,17 +214,17 @@ class RedirectTest < ActionController::TestCase
assert_equal "http://test.host/things/stuff", redirect_to_url
end
- def test_redirect_to_back_with_status
- @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from"
- get :redirect_to_back_with_status
- assert_response 307
- assert_equal "http://www.example.com/coming/from", redirect_to_url
+ def test_relative_url_redirect_host_with_port
+ request.host = "test.host:1234"
+ get :relative_url_redirect_with_status
+ assert_response 302
+ assert_equal "http://test.host:1234/things/stuff", redirect_to_url
end
def test_simple_redirect_using_options
get :host_redirect
assert_response :redirect
- assert_redirected_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ assert_redirected_to action: "other_host", only_path: false, host: "other.test.host"
end
def test_module_redirect
@@ -207,7 +236,7 @@ class RedirectTest < ActionController::TestCase
def test_module_redirect_using_options
get :module_redirect
assert_response :redirect
- assert_redirected_to :controller => 'module_test/module_redirect', :action => 'hello_world'
+ assert_redirected_to controller: "module_test/module_redirect", action: "hello_world"
end
def test_redirect_to_url
@@ -234,25 +263,48 @@ class RedirectTest < ActionController::TestCase
assert_equal "//www.rubyonrails.org/", redirect_to_url
end
- def test_redirect_to_back
- @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from"
- get :redirect_to_back
- assert_response :redirect
- assert_equal "http://www.example.com/coming/from", redirect_to_url
+ def test_redirect_back
+ referer = "http://www.example.com/coming/from"
+ @request.env["HTTP_REFERER"] = referer
+
+ get :redirect_back_with_status
+
+ assert_response 307
+ assert_equal referer, redirect_to_url
end
- def test_redirect_to_back_with_no_referer
- assert_raise(ActionController::RedirectBackError) {
- @request.env["HTTP_REFERER"] = nil
- get :redirect_to_back
- }
+ def test_redirect_back_with_no_referer
+ get :redirect_back_with_status
+
+ assert_response 307
+ assert_equal "http://test.host/things/stuff", redirect_to_url
+ end
+
+ def test_safe_redirect_back_from_other_host
+ @request.env["HTTP_REFERER"] = "http://another.host/coming/from"
+ get :safe_redirect_back_with_status
+
+ assert_response 307
+ assert_equal "http://test.host/things/stuff", redirect_to_url
+ end
+
+ def test_safe_redirect_back_from_the_same_host
+ referer = "http://test.host/coming/from"
+ @request.env["HTTP_REFERER"] = referer
+ get :safe_redirect_back_with_status
+
+ assert_response 307
+ assert_equal referer, redirect_to_url
end
def test_redirect_to_record
with_routing do |set|
set.draw do
resources :workshops
- get ':controller/:action'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :redirect_to_existing_record
@@ -273,10 +325,10 @@ class RedirectTest < ActionController::TestCase
end
def test_redirect_to_params
- error = assert_raise(ActionController::ActionControllerError) do
+ error = assert_raise(ActionController::UnfilteredParameters) do
get :redirect_to_params
end
- assert_equal "Cannot redirect to a parameter hash!", error.message
+ assert_equal "unable to convert unpermitted parameters to hash", error.message
end
def test_redirect_to_with_block
@@ -291,10 +343,18 @@ class RedirectTest < ActionController::TestCase
assert_redirected_to "http://www.rubyonrails.org/"
end
+ def test_redirect_to_out_of_scope_block
+ get :redirect_to_out_of_scope_block
+ assert_response :redirect
+ assert_redirected_to "http://test.host/redirect/redirect_to_out_of_scope_block"
+ end
+
def test_redirect_to_with_block_and_accepted_options
with_routing do |set|
set.draw do
- get ':controller/:action'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :redirect_to_with_block_and_options
@@ -308,7 +368,7 @@ end
module ModuleTest
class ModuleRedirectController < ::RedirectController
def module_redirect
- redirect_to :controller => '/redirect', :action => "hello_world"
+ redirect_to controller: "/redirect", action: "hello_world"
end
end
@@ -324,7 +384,7 @@ module ModuleTest
def test_simple_redirect_using_options
get :host_redirect
assert_response :redirect
- assert_redirected_to :action => "other_host", :only_path => false, :host => 'other.test.host'
+ assert_redirected_to action: "other_host", only_path: false, host: "other.test.host"
end
def test_module_redirect
@@ -336,7 +396,7 @@ module ModuleTest
def test_module_redirect_using_options
get :module_redirect
assert_response :redirect
- assert_redirected_to :controller => '/redirect', :action => "hello_world"
+ assert_redirected_to controller: "/redirect", action: "hello_world"
end
end
end
diff --git a/actionpack/test/controller/render_js_test.rb b/actionpack/test/controller/render_js_test.rb
index 6b661de064..1efc0b9de1 100644
--- a/actionpack/test/controller/render_js_test.rb
+++ b/actionpack/test/controller/render_js_test.rb
@@ -1,21 +1,23 @@
-require 'abstract_unit'
-require 'controller/fake_models'
-require 'pathname'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_models"
+require "pathname"
class RenderJSTest < ActionController::TestCase
class TestController < ActionController::Base
protect_from_forgery
def self.controller_path
- 'test'
+ "test"
end
def render_vanilla_js_hello
- render :js => "alert('hello')"
+ render js: "alert('hello')"
end
def show_partial
- render :partial => 'partial'
+ render partial: "partial"
end
end
@@ -28,7 +30,7 @@ class RenderJSTest < ActionController::TestCase
end
def test_should_render_js_partial
- get :show_partial, format: 'js', xhr: true
- assert_equal 'partial js', @response.body
+ get :show_partial, format: "js", xhr: true
+ assert_equal "partial js", @response.body
end
end
diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb
index 3773900cc4..82c1ba26cb 100644
--- a/actionpack/test/controller/render_json_test.rb
+++ b/actionpack/test/controller/render_json_test.rb
@@ -1,18 +1,20 @@
-require 'abstract_unit'
-require 'controller/fake_models'
-require 'active_support/logger'
-require 'pathname'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_models"
+require "active_support/logger"
+require "pathname"
class RenderJsonTest < ActionController::TestCase
class JsonRenderable
- def as_json(options={})
- hash = { :a => :b, :c => :d, :e => :f }
+ def as_json(options = {})
+ hash = { a: :b, c: :d, e: :f }
hash.except!(*options[:except]) if options[:except]
hash
end
def to_json(options = {})
- super :except => [:c, :e]
+ super except: [:c, :e]
end
end
@@ -20,47 +22,47 @@ class RenderJsonTest < ActionController::TestCase
protect_from_forgery
def self.controller_path
- 'test'
+ "test"
end
def render_json_nil
- render :json => nil
+ render json: nil
end
def render_json_render_to_string
- render plain: render_to_string(json: '[]')
+ render plain: render_to_string(json: "[]")
end
def render_json_hello_world
- render :json => ActiveSupport::JSON.encode(:hello => 'world')
+ render json: ActiveSupport::JSON.encode(hello: "world")
end
def render_json_hello_world_with_status
- render :json => ActiveSupport::JSON.encode(:hello => 'world'), :status => 401
+ render json: ActiveSupport::JSON.encode(hello: "world"), status: 401
end
def render_json_hello_world_with_callback
- render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
+ render json: ActiveSupport::JSON.encode(hello: "world"), callback: "alert"
end
def render_json_with_custom_content_type
- render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
+ render json: ActiveSupport::JSON.encode(hello: "world"), content_type: "text/javascript"
end
def render_symbol_json
- render :json => ActiveSupport::JSON.encode(:hello => 'world')
+ render json: ActiveSupport::JSON.encode(hello: "world")
end
def render_json_with_render_to_string
- render :json => {:hello => render_to_string(:partial => 'partial')}
+ render json: { hello: render_to_string(partial: "partial") }
end
def render_json_with_extra_options
- render :json => JsonRenderable.new, :except => [:c, :e]
+ render json: JsonRenderable.new, except: [:c, :e]
end
def render_json_without_options
- render :json => JsonRenderable.new
+ render json: JsonRenderable.new
end
end
@@ -77,20 +79,19 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json_nil
get :render_json_nil
- assert_equal 'null', @response.body
- assert_equal 'application/json', @response.content_type
+ assert_equal "null", @response.body
+ assert_equal "application/json", @response.content_type
end
def test_render_json_render_to_string
get :render_json_render_to_string
- assert_equal '[]', @response.body
+ assert_equal "[]", @response.body
end
-
def test_render_json
get :render_json_hello_world
assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
+ assert_equal "application/json", @response.content_type
end
def test_render_json_with_status
@@ -102,31 +103,31 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json_with_callback
get :render_json_hello_world_with_callback, xhr: true
assert_equal '/**/alert({"hello":"world"})', @response.body
- assert_equal 'text/javascript', @response.content_type
+ assert_equal "text/javascript", @response.content_type
end
def test_render_json_with_custom_content_type
get :render_json_with_custom_content_type, xhr: true
assert_equal '{"hello":"world"}', @response.body
- assert_equal 'text/javascript', @response.content_type
+ assert_equal "text/javascript", @response.content_type
end
def test_render_symbol_json
get :render_symbol_json
assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
+ assert_equal "application/json", @response.content_type
end
def test_render_json_with_render_to_string
get :render_json_with_render_to_string
assert_equal '{"hello":"partial html"}', @response.body
- assert_equal 'application/json', @response.content_type
+ assert_equal "application/json", @response.content_type
end
def test_render_json_forwards_extra_options
get :render_json_with_extra_options
assert_equal '{"a":"b"}', @response.body
- assert_equal 'application/json', @response.content_type
+ assert_equal "application/json", @response.content_type
end
def test_render_json_calls_to_json_from_object
diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb
deleted file mode 100644
index 1f5215ac55..0000000000
--- a/actionpack/test/controller/render_other_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'abstract_unit'
-
-
-class RenderOtherTest < ActionController::TestCase
- class TestController < ActionController::Base
- def render_simon_says
- render :simon => "foo"
- end
- end
-
- tests TestController
-
- def test_using_custom_render_option
- ActionController.add_renderer :simon do |says, options|
- self.content_type = Mime[:text]
- self.response_body = "Simon says: #{says}"
- end
-
- get :render_simon_says
- assert_equal "Simon says: foo", @response.body
- ensure
- ActionController.remove_renderer :simon
- end
-end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 256ebf6a07..306b245bd1 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1,31 +1,55 @@
-require 'abstract_unit'
-require 'controller/fake_models'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_models"
class TestControllerWithExtraEtags < ActionController::Base
+ def self.controller_name; "test"; end
+ def self.controller_path; "test"; end
+
etag { nil }
- etag { 'ab' }
+ etag { "ab" }
etag { :cde }
etag { [:f] }
etag { nil }
def fresh
- render plain: "stale" if stale?(etag: '123', template: false)
+ render plain: "stale" if stale?(etag: "123", template: false)
end
def array
render plain: "stale" if stale?(etag: %w(1 2 3), template: false)
end
+ def strong
+ render plain: "stale" if stale?(strong_etag: "strong", template: false)
+ end
+
def with_template
- if stale? template: 'test/hello_world'
- render plain: 'stale'
+ if stale? template: "test/hello_world"
+ render plain: "stale"
end
end
+
+ def with_implicit_template
+ fresh_when(etag: "123")
+ end
end
class ImplicitRenderTestController < ActionController::Base
def empty_action
end
+
+ def empty_action_with_template
+ end
+end
+
+module Namespaced
+ class ImplicitRenderTestController < ActionController::Base
+ def hello_world
+ fresh_when(etag: "abc")
+ end
+ end
end
class TestController < ActionController::Base
@@ -49,8 +73,8 @@ class TestController < ActionController::Base
end
def conditional_hello
- if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123])
- render :action => 'hello_world'
+ if stale?(last_modified: Time.now.utc.beginning_of_day, etag: [:foo, 123])
+ render action: "hello_world"
end
end
@@ -58,10 +82,24 @@ class TestController < ActionController::Base
record = Struct.new(:updated_at, :cache_key).new(Time.now.utc.beginning_of_day, "foo/123")
if stale?(record)
- render :action => 'hello_world'
+ render action: "hello_world"
end
end
+ def dynamic_render
+ render params[:id] # => String, AC::Params
+ end
+
+ def dynamic_render_permit
+ render params[:id].permit(:file)
+ end
+
+ def dynamic_render_with_file
+ # This is extremely bad, but should be possible to do.
+ file = params[:id] # => String, AC::Params
+ render file: file
+ end
+
class Collection
def initialize(records)
@records = records
@@ -79,70 +117,79 @@ class TestController < ActionController::Base
old_record = Struct.new(:updated_at, :cache_key).new(ts - 1.day, "bar/123")
if stale?(Collection.new([record, old_record]))
- render action: 'hello_world'
+ render action: "hello_world"
end
end
def conditional_hello_with_expires_in
expires_in 60.1.seconds
- render :action => 'hello_world'
+ render action: "hello_world"
end
def conditional_hello_with_expires_in_with_public
- expires_in 1.minute, :public => true
- render :action => 'hello_world'
+ expires_in 1.minute, public: true
+ render action: "hello_world"
end
def conditional_hello_with_expires_in_with_must_revalidate
- expires_in 1.minute, :must_revalidate => true
- render :action => 'hello_world'
+ expires_in 1.minute, must_revalidate: true
+ render action: "hello_world"
end
def conditional_hello_with_expires_in_with_public_and_must_revalidate
- expires_in 1.minute, :public => true, :must_revalidate => true
- render :action => 'hello_world'
+ expires_in 1.minute, public: true, must_revalidate: true
+ render action: "hello_world"
+ end
+
+ def conditional_hello_with_expires_in_with_stale_while_revalidate
+ expires_in 1.minute, public: true, stale_while_revalidate: 5.minutes
+ render action: "hello_world"
+ end
+
+ def conditional_hello_with_expires_in_with_stale_if_error
+ expires_in 1.minute, public: true, stale_if_error: 5.minutes
+ render action: "hello_world"
end
def conditional_hello_with_expires_in_with_public_with_more_keys
- expires_in 1.minute, :public => true, 's-maxage' => 5.hours
- render :action => 'hello_world'
+ expires_in 1.minute, :public => true, "s-maxage" => 5.hours
+ render action: "hello_world"
end
def conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
- expires_in 1.minute, :public => true, :private => nil, 's-maxage' => 5.hours
- render :action => 'hello_world'
+ expires_in 1.minute, :public => true, :private => nil, "s-maxage" => 5.hours
+ render action: "hello_world"
end
def conditional_hello_with_expires_now
expires_now
- render :action => 'hello_world'
+ render action: "hello_world"
end
def conditional_hello_with_cache_control_headers
- response.headers['Cache-Control'] = 'no-transform'
+ response.headers["Cache-Control"] = "no-transform"
expires_now
- render :action => 'hello_world'
- end
-
- def respond_with_empty_body
- render nothing: true
+ render action: "hello_world"
end
- def conditional_hello_with_bangs
- render :action => 'hello_world'
+ def conditional_hello_with_expires_and_confliciting_cache_control_headers
+ response.headers["Cache-Control"] = "no-cache, must-revalidate"
+ expires_now
+ render action: "hello_world"
end
- before_action :handle_last_modified_and_etags, :only=>:conditional_hello_with_bangs
- def handle_last_modified_and_etags
- fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ])
+ def conditional_hello_without_expires_and_confliciting_cache_control_headers
+ response.headers["Cache-Control"] = "no-cache, must-revalidate"
+ render action: "hello_world"
end
- def head_with_status_hash
- head status: :created
+ def conditional_hello_with_bangs
+ render action: "hello_world"
end
+ before_action :handle_last_modified_and_etags, only: :conditional_hello_with_bangs
- def head_with_hash_does_not_include_status
- head warning: :deprecated
+ def handle_last_modified_and_etags
+ fresh_when(last_modified: Time.now.utc.beginning_of_day, etag: [ :foo, 123 ])
end
def head_created
@@ -150,19 +197,19 @@ class TestController < ActionController::Base
end
def head_created_with_application_json_content_type
- head :created, :content_type => "application/json"
+ head :created, content_type: "application/json"
end
def head_ok_with_image_png_content_type
- head :ok, :content_type => "image/png"
+ head :ok, content_type: "image/png"
end
def head_with_location_header
- head :ok, :location => "/foo"
+ head :ok, location: "/foo"
end
def head_with_location_object
- head :ok, :location => Customer.new("david", 1)
+ head :ok, location: Customer.new("david", 1)
end
def head_with_symbolic_status
@@ -178,20 +225,20 @@ class TestController < ActionController::Base
end
def head_with_custom_header
- head :ok, :x_custom_header => "something"
+ head :ok, x_custom_header: "something"
end
def head_with_www_authenticate_header
- head :ok, 'WWW-Authenticate' => 'something'
+ head :ok, "WWW-Authenticate" => "something"
end
def head_with_status_code_first
- head :forbidden, :x_custom_header => "something"
+ head :forbidden, x_custom_header: "something"
end
def head_and_return
- head :ok and return
- raise 'should not reach this line'
+ head(:ok) && return
+ raise "should not reach this line"
end
def head_with_no_content
@@ -203,6 +250,15 @@ class TestController < ActionController::Base
head 204
end
+ def head_default_content_type
+ # simulating path like "/1.foobar"
+ request.formats = []
+
+ respond_to do |format|
+ format.any { head 200 }
+ end
+ end
+
private
def set_variable_for_layout
@@ -211,7 +267,7 @@ class TestController < ActionController::Base
def determine_layout
case action_name
- when "hello_world", "layout_test", "rendering_without_layout",
+ when "hello_world", "layout_test", "rendering_without_layout",
"rendering_nothing_on_layout", "render_text_hello_world",
"render_text_hello_world_with_layout",
"hello_world_with_layout_false",
@@ -221,28 +277,86 @@ class TestController < ActionController::Base
"render_with_explicit_string_template",
"update_page", "update_page_with_instance_variables"
- "layouts/standard"
- when "action_talk_to_layout", "layout_overriding_layout"
- "layouts/talk_from_action"
- when "render_implicit_html_template_from_xhr_request"
- (request.xhr? ? 'layouts/xhr' : 'layouts/standard')
+ "layouts/standard"
+ when "action_talk_to_layout", "layout_overriding_layout"
+ "layouts/talk_from_action"
+ when "render_implicit_html_template_from_xhr_request"
+ (request.xhr? ? "layouts/xhr" : "layouts/standard")
end
end
end
+module TemplateModificationHelper
+ private
+ def modify_template(name)
+ path = File.expand_path("../fixtures/#{name}.erb", __dir__)
+ original = File.read(path)
+ File.write(path, "#{original} Modified!")
+ ActionView::LookupContext::DetailsKey.clear
+ yield
+ ensure
+ File.write(path, original)
+ end
+end
+
class MetalTestController < ActionController::Metal
include AbstractController::Rendering
include ActionView::Rendering
include ActionController::Rendering
def accessing_logger_in_template
- render :inline => "<%= logger.class %>"
+ render inline: "<%= logger.class %>"
end
end
class ExpiresInRenderTest < ActionController::TestCase
tests TestController
+ def setup
+ super
+ ActionController::Base.view_paths.paths.each(&:clear_cache)
+ end
+
+ def test_dynamic_render_with_file
+ # This is extremely bad, but should be possible to do.
+ assert File.exist?(File.expand_path("../../test/abstract_unit.rb", __dir__))
+ response = get :dynamic_render_with_file, params: { id: '../\\../test/abstract_unit.rb' }
+ assert_equal File.read(File.expand_path("../../test/abstract_unit.rb", __dir__)),
+ response.body
+ end
+
+ def test_dynamic_render_with_absolute_path
+ file = Tempfile.new("name")
+ file.write "secrets!"
+ file.flush
+ assert_raises ActionView::MissingTemplate do
+ get :dynamic_render, params: { id: file.path }
+ end
+ ensure
+ file.close
+ file.unlink
+ end
+
+ def test_dynamic_render
+ assert File.exist?(File.expand_path("../../test/abstract_unit.rb", __dir__))
+ assert_raises ActionView::MissingTemplate do
+ get :dynamic_render, params: { id: '../\\../test/abstract_unit.rb' }
+ end
+ end
+
+ def test_permitted_dynamic_render_file_hash
+ assert File.exist?(File.expand_path("../../test/abstract_unit.rb", __dir__))
+ response = get :dynamic_render_permit, params: { id: { file: '../\\../test/abstract_unit.rb' } }
+ assert_equal File.read(File.expand_path("../../test/abstract_unit.rb", __dir__)),
+ response.body
+ end
+
+ def test_dynamic_render_file_hash
+ assert_raises ArgumentError do
+ get :dynamic_render, params: { id: { file: '../\\../test/abstract_unit.rb' } }
+ end
+ end
+
def test_expires_in_header
get :conditional_hello_with_expires_in
assert_equal "max-age=60, private", @response.headers["Cache-Control"]
@@ -263,6 +377,16 @@ class ExpiresInRenderTest < ActionController::TestCase
assert_equal "max-age=60, public, must-revalidate", @response.headers["Cache-Control"]
end
+ def test_expires_in_header_with_stale_while_revalidate
+ get :conditional_hello_with_expires_in_with_stale_while_revalidate
+ assert_equal "max-age=60, public, stale-while-revalidate=300", @response.headers["Cache-Control"]
+ end
+
+ def test_expires_in_header_with_stale_if_error
+ get :conditional_hello_with_expires_in_with_stale_if_error
+ assert_equal "max-age=60, public, stale-if-error=300", @response.headers["Cache-Control"]
+ end
+
def test_expires_in_header_with_additional_headers
get :conditional_hello_with_expires_in_with_public_with_more_keys
assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"]
@@ -284,14 +408,18 @@ class ExpiresInRenderTest < ActionController::TestCase
assert_match(/no-transform/, @response.headers["Cache-Control"])
end
- def test_render_nothing_deprecated
- assert_deprecated do
- get :respond_with_empty_body
- end
+ def test_expires_now_with_conflicting_cache_control_headers
+ get :conditional_hello_with_expires_and_confliciting_cache_control_headers
+ assert_equal "no-cache", @response.headers["Cache-Control"]
+ end
+
+ def test_no_expires_now_with_conflicting_cache_control_headers
+ get :conditional_hello_without_expires_and_confliciting_cache_control_headers
+ assert_equal "no-cache", @response.headers["Cache-Control"]
end
def test_date_header_when_expires_in
- time = Time.mktime(2011,10,30)
+ time = Time.mktime(2011, 10, 30)
Time.stub :now, time do
get :conditional_hello_with_expires_in
assert_equal Time.now.httpdate, @response.headers["Date"]
@@ -309,92 +437,92 @@ class LastModifiedRenderTest < ActionController::TestCase
def test_responds_with_last_modified
get :conditional_hello
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified
@request.if_modified_since = @last_modified
get :conditional_hello
assert_equal 304, @response.status.to_i
- assert @response.body.blank?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :blank?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified_but_etag_differs
@request.if_modified_since = @last_modified
- @request.if_none_match = "234"
+ @request.if_none_match = '"234"'
get :conditional_hello
assert_response :success
end
def test_request_modified
- @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
+ @request.if_modified_since = "Thu, 16 Jul 2008 00:00:00 GMT"
get :conditional_hello
assert_equal 200, @response.status.to_i
- assert @response.body.present?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :present?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_responds_with_last_modified_with_record
get :conditional_hello_with_record
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified_with_record
@request.if_modified_since = @last_modified
get :conditional_hello_with_record
assert_equal 304, @response.status.to_i
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_not_nil @response.etag
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified_but_etag_differs_with_record
@request.if_modified_since = @last_modified
- @request.if_none_match = "234"
+ @request.if_none_match = '"234"'
get :conditional_hello_with_record
assert_response :success
end
def test_request_modified_with_record
- @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
+ @request.if_modified_since = "Thu, 16 Jul 2008 00:00:00 GMT"
get :conditional_hello_with_record
assert_equal 200, @response.status.to_i
- assert @response.body.present?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :present?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_responds_with_last_modified_with_collection_of_records
get :conditional_hello_with_collection_of_records
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified_with_collection_of_records
@request.if_modified_since = @last_modified
get :conditional_hello_with_collection_of_records
assert_equal 304, @response.status.to_i
- assert @response.body.blank?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :blank?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_not_modified_but_etag_differs_with_collection_of_records
@request.if_modified_since = @last_modified
- @request.if_none_match = "234"
+ @request.if_none_match = '"234"'
get :conditional_hello_with_collection_of_records
assert_response :success
end
def test_request_modified_with_collection_of_records
- @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
+ @request.if_modified_since = "Thu, 16 Jul 2008 00:00:00 GMT"
get :conditional_hello_with_collection_of_records
assert_equal 200, @response.status.to_i
- assert @response.body.present?
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_predicate @response.body, :present?
+ assert_equal @last_modified, @response.headers["Last-Modified"]
end
def test_request_with_bang_gets_last_modified
get :conditional_hello_with_bangs
- assert_equal @last_modified, @response.headers['Last-Modified']
+ assert_equal @last_modified, @response.headers["Last-Modified"]
assert_response :success
end
@@ -413,9 +541,28 @@ end
class EtagRenderTest < ActionController::TestCase
tests TestControllerWithExtraEtags
+ include TemplateModificationHelper
+
+ def test_strong_etag
+ @request.if_none_match = strong_etag(["strong", "ab", :cde, [:f]])
+ get :strong
+ assert_response :not_modified
+
+ @request.if_none_match = "*"
+ get :strong
+ assert_response :not_modified
+
+ @request.if_none_match = '"strong"'
+ get :strong
+ assert_response :ok
+
+ @request.if_none_match = weak_etag(["strong", "ab", :cde, [:f]])
+ get :strong
+ assert_response :ok
+ end
def test_multiple_etags
- @request.if_none_match = etag(["123", 'ab', :cde, [:f]])
+ @request.if_none_match = weak_etag(["123", "ab", :cde, [:f]])
get :fresh
assert_response :not_modified
@@ -425,7 +572,7 @@ class EtagRenderTest < ActionController::TestCase
end
def test_array
- @request.if_none_match = etag([%w(1 2 3), 'ab', :cde, [:f]])
+ @request.if_none_match = weak_etag([%w(1 2 3), "ab", :cde, [:f]])
get :array
assert_response :not_modified
@@ -443,25 +590,60 @@ class EtagRenderTest < ActionController::TestCase
get :with_template
assert_response :not_modified
- # Modify the template digest
- path = File.expand_path('../../fixtures/test/hello_world.erb', __FILE__)
- old = File.read(path)
+ modify_template("test/hello_world") do
+ request.if_none_match = etag
+ get :with_template
+ assert_response :ok
+ assert_not_equal etag, @response.etag
+ end
+ end
- begin
- File.write path, 'foo'
- ActionView::Digestor.cache.clear
+ def test_etag_reflects_implicit_template_digest
+ get :with_implicit_template
+ assert_response :ok
+ assert_not_nil etag = @response.etag
+
+ request.if_none_match = etag
+ get :with_implicit_template
+ assert_response :not_modified
+ modify_template("test/with_implicit_template") do
request.if_none_match = etag
- get :with_template
+ get :with_implicit_template
assert_response :ok
assert_not_equal etag, @response.etag
- ensure
- File.write path, old
end
end
- def etag(record)
- Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(record)).inspect
+ private
+ def weak_etag(record)
+ "W/#{strong_etag record}"
+ end
+
+ def strong_etag(record)
+ %("#{ActiveSupport::Digest.hexdigest(ActiveSupport::Cache.expand_cache_key(record))}")
+ end
+end
+
+class NamespacedEtagRenderTest < ActionController::TestCase
+ tests Namespaced::ImplicitRenderTestController
+ include TemplateModificationHelper
+
+ def test_etag_reflects_template_digest
+ get :hello_world
+ assert_response :ok
+ assert_not_nil etag = @response.etag
+
+ request.if_none_match = etag
+ get :hello_world
+ assert_response :not_modified
+
+ modify_template("namespaced/implicit_render_test/hello_world") do
+ request.if_none_match = etag
+ get :hello_world
+ assert_response :ok
+ assert_not_equal etag, @response.etag
+ end
end
end
@@ -474,13 +656,50 @@ class MetalRenderTest < ActionController::TestCase
end
end
+class ActionControllerRenderTest < ActionController::TestCase
+ class MinimalController < ActionController::Metal
+ include AbstractController::Rendering
+ include ActionController::Rendering
+ end
+
+ def test_direct_render_to_string_with_body
+ mc = MinimalController.new
+ assert_equal "Hello world!", mc.render_to_string(body: ["Hello world!"])
+ end
+end
+
+class ActionControllerBaseRenderTest < ActionController::TestCase
+ def test_direct_render_to_string
+ ac = ActionController::Base.new()
+ assert_equal "Hello world!", ac.render_to_string(template: "test/hello_world")
+ end
+end
+
class ImplicitRenderTest < ActionController::TestCase
tests ImplicitRenderTestController
- def test_implicit_no_content_response
- get :empty_action
+ def test_implicit_no_content_response_as_browser
+ assert_raises(ActionController::MissingExactTemplate) do
+ get :empty_action
+ end
+ end
+
+ def test_implicit_no_content_response_as_xhr
+ get :empty_action, xhr: true
assert_response :no_content
end
+
+ def test_implicit_success_response_with_right_format
+ get :empty_action_with_template
+ assert_equal "<h1>Empty action rendered this implicitly.</h1>\n", @response.body
+ assert_response :success
+ end
+
+ def test_implicit_unknown_format_response
+ assert_raises(ActionController::UnknownFormat) do
+ get :empty_action_with_template, format: "json"
+ end
+ end
end
class HeadRenderTest < ActionController::TestCase
@@ -492,40 +711,27 @@ class HeadRenderTest < ActionController::TestCase
def test_head_created
post :head_created
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_response :created
end
- def test_passing_hash_to_head_as_first_parameter_deprecated
- assert_deprecated do
- get :head_with_status_hash
- end
- end
-
- def test_head_with_default_value_is_deprecated
- assert_deprecated do
- get :head_with_hash_does_not_include_status
- assert_response :ok
- end
- end
-
def test_head_created_with_application_json_content_type
post :head_created_with_application_json_content_type
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "application/json", @response.header["Content-Type"]
assert_response :created
end
def test_head_ok_with_image_png_content_type
post :head_ok_with_image_png_content_type
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "image/png", @response.header["Content-Type"]
assert_response :ok
end
def test_head_with_location_header
get :head_with_location_header
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "/foo", @response.headers["Location"]
assert_response :ok
end
@@ -534,11 +740,14 @@ class HeadRenderTest < ActionController::TestCase
with_routing do |set|
set.draw do
resources :customers
- get ':controller/:action'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :head_with_location_object
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
assert_response :ok
end
@@ -546,14 +755,14 @@ class HeadRenderTest < ActionController::TestCase
def test_head_with_custom_header
get :head_with_custom_header
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "something", @response.headers["X-Custom-Header"]
assert_response :ok
end
def test_head_with_www_authenticate_header
get :head_with_www_authenticate_header
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
assert_equal "something", @response.headers["WWW-Authenticate"]
assert_response :ok
end
@@ -569,7 +778,7 @@ class HeadRenderTest < ActionController::TestCase
get :head_with_symbolic_status, params: { status: "no_content" }
assert_equal 204, @response.status
- assert !@response.headers.include?('Content-Length')
+ assert_not_includes @response.headers, "Content-Length"
assert_response :no_content
Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |status, code|
@@ -614,13 +823,18 @@ class HeadRenderTest < ActionController::TestCase
get :head_and_return
end
end
+
+ def test_head_default_content_type
+ post :head_default_content_type
+ assert_equal "text/html", @response.header["Content-Type"]
+ end
end
class HttpCacheForeverTest < ActionController::TestCase
class HttpCacheForeverController < ActionController::Base
def cache_me_forever
- http_cache_forever(public: params[:public], version: params[:version] || 'v1') do
- render plain: 'hello'
+ http_cache_forever(public: params[:public]) do
+ render plain: "hello"
end
end
end
@@ -628,43 +842,36 @@ class HttpCacheForeverTest < ActionController::TestCase
tests HttpCacheForeverController
def test_cache_with_public
- get :cache_me_forever, params: {public: true}
+ get :cache_me_forever, params: { public: true }
+ assert_response :ok
assert_equal "max-age=#{100.years}, public", @response.headers["Cache-Control"]
assert_not_nil @response.etag
+ assert_predicate @response, :weak_etag?
end
def test_cache_with_private
get :cache_me_forever
+ assert_response :ok
assert_equal "max-age=#{100.years}, private", @response.headers["Cache-Control"]
assert_not_nil @response.etag
- assert_response :success
+ assert_predicate @response, :weak_etag?
end
def test_cache_response_code_with_if_modified_since
get :cache_me_forever
- assert_response :success
- @request.if_modified_since = @response.headers['Last-Modified']
+ assert_response :ok
+
+ @request.if_modified_since = @response.headers["Last-Modified"]
get :cache_me_forever
assert_response :not_modified
end
def test_cache_response_code_with_etag
get :cache_me_forever
- assert_response :success
- @request.if_modified_since = @response.headers['Last-Modified']
- @request.if_none_match = @response.etag
-
- get :cache_me_forever
- assert_response :not_modified
- @request.if_modified_since = @response.headers['Last-Modified']
- @request.if_none_match = @response.etag
+ assert_response :ok
- get :cache_me_forever, params: {version: 'v2'}
- assert_response :success
- @request.if_modified_since = @response.headers['Last-Modified']
@request.if_none_match = @response.etag
-
- get :cache_me_forever, params: {version: 'v2'}
+ get :cache_me_forever
assert_response :not_modified
end
end
diff --git a/actionpack/test/controller/render_xml_test.rb b/actionpack/test/controller/render_xml_test.rb
index f0fd7ddc5e..a72d14e4bb 100644
--- a/actionpack/test/controller/render_xml_test.rb
+++ b/actionpack/test/controller/render_xml_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'controller/fake_models'
-require 'pathname'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_models"
+require "pathname"
class RenderXmlTest < ActionController::TestCase
class XmlRenderable
@@ -14,31 +16,31 @@ class RenderXmlTest < ActionController::TestCase
protect_from_forgery
def self.controller_path
- 'test'
+ "test"
end
def render_with_location
- render :xml => "<hello/>", :location => "http://example.com", :status => 201
+ render xml: "<hello/>", location: "http://example.com", status: 201
end
def render_with_object_location
customer = Customer.new("Some guy", 1)
- render :xml => "<customer/>", :location => customer, :status => :created
+ render xml: "<customer/>", location: customer, status: :created
end
def render_with_to_xml
- render :xml => XmlRenderable.new
+ render xml: XmlRenderable.new
end
def formatted_xml_erb
end
def render_xml_with_custom_content_type
- render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
+ render xml: "<blah/>", content_type: "application/atomsvc+xml"
end
def render_xml_with_custom_options
- render :xml => XmlRenderable.new, :root => "i-am-THE-xml"
+ render xml: XmlRenderable.new, root: "i-am-THE-xml"
end
end
@@ -72,7 +74,10 @@ class RenderXmlTest < ActionController::TestCase
with_routing do |set|
set.draw do
resources :customers
- get ':controller/:action'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
get :render_with_object_location
@@ -82,7 +87,7 @@ class RenderXmlTest < ActionController::TestCase
def test_should_render_formatted_xml_erb_template
get :formatted_xml_erb, format: :xml
- assert_equal '<test>passed formatted xml erb</test>', @response.body
+ assert_equal "<test>passed formatted xml erb</test>", @response.body
end
def test_should_render_xml_but_keep_custom_content_type
@@ -91,7 +96,7 @@ class RenderXmlTest < ActionController::TestCase
end
def test_should_use_implicit_content_type
- get :implicit_content_type, format: 'atom'
+ get :implicit_content_type, format: "atom"
assert_equal Mime[:atom], @response.content_type
end
end
diff --git a/actionpack/test/controller/renderer_test.rb b/actionpack/test/controller/renderer_test.rb
index 16d24fa82a..ae8330e029 100644
--- a/actionpack/test/controller/renderer_test.rb
+++ b/actionpack/test/controller/renderer_test.rb
@@ -1,92 +1,134 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class RendererTest < ActiveSupport::TestCase
- test 'action controller base has a renderer' do
+ test "action controller base has a renderer" do
assert ActionController::Base.renderer
end
- test 'creating with a controller' do
+ test "creating with a controller" do
controller = CommentsController
renderer = ActionController::Renderer.for controller
assert_equal controller, renderer.controller
end
- test 'creating from a controller' do
+ test "creating from a controller" do
controller = AccountsController
renderer = controller.renderer
assert_equal controller, renderer.controller
end
- test 'rendering with a class renderer' do
+ test "creating with new defaults" do
+ renderer = ApplicationController.renderer
+
+ new_defaults = { https: true }
+ new_renderer = renderer.with_defaults(new_defaults).new
+ content = new_renderer.render(inline: "<%= request.ssl? %>")
+
+ assert_equal "true", content
+ end
+
+ test "rendering with a class renderer" do
renderer = ApplicationController.renderer
- content = renderer.render template: 'ruby_template'
+ content = renderer.render template: "ruby_template"
- assert_equal 'Hello from Ruby code', content
+ assert_equal "Hello from Ruby code", content
end
- test 'rendering with an instance renderer' do
+ test "rendering with an instance renderer" do
renderer = ApplicationController.renderer.new
- content = renderer.render file: 'test/hello_world'
+ content = renderer.render file: "test/hello_world"
- assert_equal 'Hello world!', content
+ assert_equal "Hello world!", content
end
- test 'rendering with a controller class' do
- assert_equal 'Hello world!', ApplicationController.render('test/hello_world')
+ test "rendering with a controller class" do
+ assert_equal "Hello world!", ApplicationController.render("test/hello_world")
end
- test 'rendering with locals' do
+ test "rendering with locals" do
renderer = ApplicationController.renderer
- content = renderer.render template: 'test/render_file_with_locals',
- locals: { secret: 'bar' }
+ content = renderer.render template: "test/render_file_with_locals",
+ locals: { secret: "bar" }
assert_equal "The secret is bar\n", content
end
- test 'rendering with assigns' do
+ test "rendering with assigns" do
renderer = ApplicationController.renderer
- content = renderer.render template: 'test/render_file_with_ivar',
- assigns: { secret: 'foo' }
+ content = renderer.render template: "test/render_file_with_ivar",
+ assigns: { secret: "foo" }
assert_equal "The secret is foo\n", content
end
- test 'rendering with custom env' do
- renderer = ApplicationController.renderer.new method: 'post'
- content = renderer.render inline: '<%= request.post? %>'
+ test "rendering with custom env" do
+ renderer = ApplicationController.renderer.new method: "post"
+ content = renderer.render inline: "<%= request.post? %>"
- assert_equal 'true', content
+ assert_equal "true", content
end
- test 'rendering with defaults' do
+ test "rendering with custom env using a key that is not in RACK_KEY_TRANSLATION" do
+ value = "warden is here"
+ renderer = ApplicationController.renderer.new warden: value
+ content = renderer.render inline: "<%= request.env['warden'] %>"
+
+ assert_equal value, content
+ end
+
+ test "rendering with defaults" do
renderer = ApplicationController.renderer.new https: true
- content = renderer.render inline: '<%= request.ssl? %>'
+ content = renderer.render inline: "<%= request.ssl? %>"
- assert_equal 'true', content
+ assert_equal "true", content
end
- test 'same defaults from the same controller' do
+ test "same defaults from the same controller" do
renderer_defaults = ->(controller) { controller.renderer.defaults }
assert_equal renderer_defaults[AccountsController], renderer_defaults[AccountsController]
assert_equal renderer_defaults[AccountsController], renderer_defaults[CommentsController]
end
- test 'rendering with different formats' do
- html = 'Hello world!'
+ test "rendering with different formats" do
+ html = "Hello world!"
xml = "<p>Hello world!</p>\n"
- assert_equal html, render['respond_to/using_defaults']
- assert_equal xml, render['respond_to/using_defaults.xml.builder']
- assert_equal xml, render['respond_to/using_defaults', formats: :xml]
+ assert_equal html, render["respond_to/using_defaults"]
+ assert_equal xml, render["respond_to/using_defaults.xml.builder"]
+ assert_equal xml, render["respond_to/using_defaults", formats: :xml]
end
- test 'rendering with helpers' do
+ test "rendering with helpers" do
assert_equal "<p>1\n<br />2</p>", render[inline: '<%= simple_format "1\n2" %>']
end
+ test "rendering with user specified defaults" do
+ ApplicationController.renderer.defaults.merge!(hello: "hello", https: true)
+ renderer = ApplicationController.renderer.new
+ content = renderer.render inline: "<%= request.ssl? %>"
+
+ assert_equal "true", content
+ end
+
+ test "return valid asset url with defaults" do
+ renderer = ApplicationController.renderer
+ content = renderer.render inline: "<%= asset_url 'asset.jpg' %>"
+
+ assert_equal "http://example.org/asset.jpg", content
+ end
+
+ test "return valid asset url when https is true" do
+ renderer = ApplicationController.renderer.new https: true
+ content = renderer.render inline: "<%= asset_url 'asset.jpg' %>"
+
+ assert_equal "https://example.org/asset.jpg", content
+ end
+
private
def render
@render ||= ApplicationController.renderer.method(:render)
diff --git a/actionpack/test/controller/renderers_test.rb b/actionpack/test/controller/renderers_test.rb
new file mode 100644
index 0000000000..d92de6f5d5
--- /dev/null
+++ b/actionpack/test/controller/renderers_test.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_models"
+require "active_support/logger"
+
+class RenderersTest < ActionController::TestCase
+ class XmlRenderable
+ def to_xml(options)
+ options[:root] ||= "i-am-xml"
+ "<#{options[:root]}/>"
+ end
+ end
+ class JsonRenderable
+ def as_json(options = {})
+ hash = { a: :b, c: :d, e: :f }
+ hash.except!(*options[:except]) if options[:except]
+ hash
+ end
+
+ def to_json(options = {})
+ super except: [:c, :e]
+ end
+ end
+ class CsvRenderable
+ def to_csv
+ "c,s,v"
+ end
+ end
+ class TestController < ActionController::Base
+ def render_simon_says
+ render simon: "foo"
+ end
+
+ def respond_to_mime
+ respond_to do |type|
+ type.json do
+ render json: JsonRenderable.new
+ end
+ type.js { render json: "JS", callback: "alert" }
+ type.csv { render csv: CsvRenderable.new }
+ type.xml { render xml: XmlRenderable.new }
+ type.html { render body: "HTML" }
+ type.rss { render body: "RSS" }
+ type.all { render body: "Nothing" }
+ type.any(:js, :xml) { render body: "Either JS or XML" }
+ end
+ end
+ end
+
+ tests TestController
+
+ def setup
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+ # a more accurate simulation of what happens in "real life".
+ super
+ @controller.logger = ActiveSupport::Logger.new(nil)
+ end
+
+ def test_using_custom_render_option
+ ActionController.add_renderer :simon do |says, options|
+ self.content_type = Mime[:text]
+ self.response_body = "Simon says: #{says}"
+ end
+
+ get :render_simon_says
+ assert_equal "Simon says: foo", @response.body
+ ensure
+ ActionController.remove_renderer :simon
+ end
+
+ def test_raises_missing_template_no_renderer
+ assert_raise ActionView::MissingTemplate do
+ get :respond_to_mime, format: "csv"
+ end
+ assert_equal Mime[:csv], @response.content_type
+ assert_equal "", @response.body
+ end
+
+ def test_adding_csv_rendering_via_renderers_add
+ ActionController::Renderers.add :csv do |value, options|
+ send_data value.to_csv, type: Mime[:csv]
+ end
+ @request.accept = "text/csv"
+ get :respond_to_mime, format: "csv"
+ assert_equal Mime[:csv], @response.content_type
+ assert_equal "c,s,v", @response.body
+ ensure
+ ActionController::Renderers.remove :csv
+ end
+end
diff --git a/actionpack/test/controller/request/test_request_test.rb b/actionpack/test/controller/request/test_request_test.rb
index e5d698d5c2..b8d86696de 100644
--- a/actionpack/test/controller/request/test_request_test.rb
+++ b/actionpack/test/controller/request/test_request_test.rb
@@ -1,23 +1,42 @@
-require 'abstract_unit'
-require 'stringio'
+# frozen_string_literal: true
-class ActionController::TestRequestTest < ActionController::TestCase
+require "abstract_unit"
+require "stringio"
+class ActionController::TestRequestTest < ActionController::TestCase
def test_test_request_has_session_options_initialized
assert @request.session_options
end
- ActionDispatch::Session::AbstractStore::DEFAULT_OPTIONS.each_key do |option|
- test "rack default session options #{option} exists in session options and is default" do
- assert_equal(ActionDispatch::Session::AbstractStore::DEFAULT_OPTIONS[option],
- @request.session_options[option],
- "Missing rack session default option #{option} in request.session_options")
+ def test_mutating_session_options_does_not_affect_default_options
+ @request.session_options[:myparam] = 123
+ assert_nil ActionController::TestSession::DEFAULT_OPTIONS[:myparam]
+ end
+
+ def test_content_length_has_bytes_count_value
+ non_ascii_parameters = { data: { content: "Latin + Кириллица" } }
+ @request.set_header "REQUEST_METHOD", "POST"
+ @request.set_header "CONTENT_TYPE", "application/json"
+ @request.assign_parameters(@routes, "test", "create", non_ascii_parameters,
+ "/test", [:data, :controller, :action])
+ assert_equal(StringIO.new(non_ascii_parameters.to_json).length.to_s,
+ @request.get_header("CONTENT_LENGTH"))
+ end
+
+ ActionDispatch::Session::AbstractStore::DEFAULT_OPTIONS.each_pair do |key, value|
+ test "rack default session options #{key} exists in session options and is default" do
+ if value.nil?
+ assert_nil(@request.session_options[key],
+ "Missing rack session default option #{key} in request.session_options")
+ else
+ assert_equal(value, @request.session_options[key],
+ "Missing rack session default option #{key} in request.session_options")
+ end
end
- test "rack default session options #{option} exists in session options" do
- assert(@request.session_options.has_key?(option),
- "Missing rack session option #{option} in request.session_options")
+ test "rack default session options #{key} exists in session options" do
+ assert(@request.session_options.has_key?(key),
+ "Missing rack session option #{key} in request.session_options")
end
end
-
end
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 87a8ed3dc9..ea94a3e048 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -1,42 +1,61 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
require "active_support/log_subscriber/test_helper"
+require "active_support/messages/rotation_configuration"
# common controller actions
module RequestForgeryProtectionActions
def index
- render :inline => "<%= form_tag('/') {} %>"
+ render inline: "<%= form_tag('/') {} %>"
end
def show_button
- render :inline => "<%= button_to('New', '/') %>"
+ render inline: "<%= button_to('New', '/') %>"
end
def unsafe
- render plain: 'pwn'
+ render plain: "pwn"
end
def meta
- render :inline => "<%= csrf_meta_tags %>"
+ render inline: "<%= csrf_meta_tags %>"
end
def form_for_remote
- render :inline => "<%= form_for(:some_resource, :remote => true ) {} %>"
+ render inline: "<%= form_for(:some_resource, :remote => true ) {} %>"
end
def form_for_remote_with_token
- render :inline => "<%= form_for(:some_resource, :remote => true, :authenticity_token => true ) {} %>"
+ render inline: "<%= form_for(:some_resource, :remote => true, :authenticity_token => true ) {} %>"
end
def form_for_with_token
- render :inline => "<%= form_for(:some_resource, :authenticity_token => true ) {} %>"
+ render inline: "<%= form_for(:some_resource, :authenticity_token => true ) {} %>"
end
def form_for_remote_with_external_token
- render :inline => "<%= form_for(:some_resource, :remote => true, :authenticity_token => 'external_token') {} %>"
+ render inline: "<%= form_for(:some_resource, :remote => true, :authenticity_token => 'external_token') {} %>"
+ end
+
+ def form_with_remote
+ render inline: "<%= form_with(scope: :some_resource) {} %>"
+ end
+
+ def form_with_remote_with_token
+ render inline: "<%= form_with(scope: :some_resource, authenticity_token: true) {} %>"
+ end
+
+ def form_with_local_with_token
+ render inline: "<%= form_with(scope: :some_resource, local: true, authenticity_token: true) {} %>"
+ end
+
+ def form_with_remote_with_external_token
+ render inline: "<%= form_with(scope: :some_resource, authenticity_token: 'external_token') {} %>"
end
def same_origin_js
- render js: 'foo();'
+ render js: "foo();"
end
def negotiate_same_origin
@@ -52,30 +71,29 @@ module RequestForgeryProtectionActions
def negotiate_cross_origin
negotiate_same_origin
end
-
end
# sample controllers
class RequestForgeryProtectionControllerUsingResetSession < ActionController::Base
include RequestForgeryProtectionActions
- protect_from_forgery :only => %w(index meta same_origin_js negotiate_same_origin), :with => :reset_session
+ protect_from_forgery only: %w(index meta same_origin_js negotiate_same_origin), with: :reset_session
end
class RequestForgeryProtectionControllerUsingException < ActionController::Base
include RequestForgeryProtectionActions
- protect_from_forgery :only => %w(index meta same_origin_js negotiate_same_origin), :with => :exception
+ protect_from_forgery only: %w(index meta same_origin_js negotiate_same_origin), with: :exception
end
class RequestForgeryProtectionControllerUsingNullSession < ActionController::Base
- protect_from_forgery :with => :null_session
+ protect_from_forgery with: :null_session
def signed
- cookies.signed[:foo] = 'bar'
+ cookies.signed[:foo] = "bar"
head :ok
end
def encrypted
- cookies.encrypted[:foo] = 'bar'
+ cookies.encrypted[:foo] = "bar"
head :ok
end
@@ -90,48 +108,75 @@ class PrependProtectForgeryBaseController < ActionController::Base
attr_accessor :called_callbacks
def index
- render inline: 'OK'
+ render inline: "OK"
end
- protected
-
- def add_called_callback(name)
- @called_callbacks ||= []
- @called_callbacks << name
- end
+ private
+ def add_called_callback(name)
+ @called_callbacks ||= []
+ @called_callbacks << name
+ end
- def custom_action
- add_called_callback("custom_action")
- end
+ def custom_action
+ add_called_callback("custom_action")
+ end
- def verify_authenticity_token
- add_called_callback("verify_authenticity_token")
- end
+ def verify_authenticity_token
+ add_called_callback("verify_authenticity_token")
+ end
end
class FreeCookieController < RequestForgeryProtectionControllerUsingResetSession
self.allow_forgery_protection = false
def index
- render :inline => "<%= form_tag('/') {} %>"
+ render inline: "<%= form_tag('/') {} %>"
end
def show_button
- render :inline => "<%= button_to('New', '/') %>"
+ render inline: "<%= button_to('New', '/') %>"
end
end
class CustomAuthenticityParamController < RequestForgeryProtectionControllerUsingResetSession
def form_authenticity_param
- 'foobar'
+ "foobar"
+ end
+end
+
+class PerFormTokensController < ActionController::Base
+ protect_from_forgery with: :exception
+ self.per_form_csrf_tokens = true
+
+ def index
+ render inline: "<%= form_tag (params[:form_path] || '/per_form_tokens/post_one'), method: params[:form_method] %>"
+ end
+
+ def button_to
+ render inline: "<%= button_to 'Button', (params[:form_path] || '/per_form_tokens/post_one'), method: params[:form_method] %>"
+ end
+
+ def post_one
+ render plain: ""
+ end
+
+ def post_two
+ render plain: ""
end
end
+class SkipProtectionController < ActionController::Base
+ include RequestForgeryProtectionActions
+ protect_from_forgery with: :exception
+ skip_forgery_protection if: :skip_requested
+ attr_accessor :skip_requested
+end
+
# common test methods
module RequestForgeryProtectionTests
def setup
- @token = Base64.strict_encode64('railstestrailstestrailstestrails')
+ @token = Base64.strict_encode64("railstestrailstestrailstestrails")
@old_request_forgery_protection_token = ActionController::Base.request_forgery_protection_token
ActionController::Base.request_forgery_protection_token = :custom_authenticity_token
end
@@ -145,7 +190,7 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :index
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', @token
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
end
end
@@ -154,7 +199,7 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :show_button
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', @token
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
end
end
@@ -185,7 +230,7 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :form_for_remote_with_external_token
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', 'external_token'
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", "external_token"
ensure
ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = original
end
@@ -195,7 +240,7 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :form_for_remote_with_external_token
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', 'external_token'
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", "external_token"
end
def test_should_render_form_with_token_tag_if_remote_and_authenticity_token_requested
@@ -203,7 +248,7 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :form_for_remote_with_token
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', @token
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
end
end
@@ -212,7 +257,81 @@ module RequestForgeryProtectionTests
assert_not_blocked do
get :form_for_with_token
end
- assert_select 'form>input[name=?][value=?]', 'custom_authenticity_token', @token
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
+ end
+ end
+
+ def test_should_render_form_with_with_token_tag_if_remote
+ assert_not_blocked do
+ get :form_with_remote
+ end
+ assert_match(/authenticity_token/, response.body)
+ end
+
+ def test_should_render_form_with_without_token_tag_if_remote_and_embedding_token_is_off
+ original = ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms
+ begin
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = false
+ assert_not_blocked do
+ get :form_with_remote
+ end
+ assert_no_match(/authenticity_token/, response.body)
+ ensure
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = original
+ end
+ end
+
+ def test_should_render_form_with_with_token_tag_if_remote_and_external_authenticity_token_requested_and_embedding_is_on
+ original = ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms
+ begin
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = true
+ assert_not_blocked do
+ get :form_with_remote_with_external_token
+ end
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", "external_token"
+ ensure
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = original
+ end
+ end
+
+ def test_should_render_form_with_with_token_tag_if_remote_and_external_authenticity_token_requested
+ assert_not_blocked do
+ get :form_with_remote_with_external_token
+ end
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", "external_token"
+ end
+
+ def test_should_render_form_with_with_token_tag_if_remote_and_authenticity_token_requested
+ @controller.stub :form_authenticity_token, @token do
+ assert_not_blocked do
+ get :form_with_remote_with_token
+ end
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
+ end
+ end
+
+ def test_should_render_form_with_with_token_tag_with_authenticity_token_requested
+ @controller.stub :form_authenticity_token, @token do
+ assert_not_blocked do
+ get :form_with_local_with_token
+ end
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
+ end
+ end
+
+ def test_should_render_form_with_with_token_tag_if_remote_and_embedding_token_is_on
+ original = ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms
+ begin
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = true
+
+ @controller.stub :form_authenticity_token, @token do
+ assert_not_blocked do
+ get :form_with_remote
+ end
+ end
+ assert_select "form>input[name=?][value=?]", "custom_authenticity_token", @token
+ ensure
+ ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms = original
end
end
@@ -233,7 +352,7 @@ module RequestForgeryProtectionTests
end
def test_should_not_allow_post_without_token_irrespective_of_format
- assert_blocked { post :index, format: 'xml' }
+ assert_blocked { post :index, format: "xml" }
end
def test_should_not_allow_patch_without_token
@@ -282,25 +401,25 @@ module RequestForgeryProtectionTests
def test_should_allow_post_with_token_in_header
session[:_csrf_token] = @token
- @request.env['HTTP_X_CSRF_TOKEN'] = @token
+ @request.env["HTTP_X_CSRF_TOKEN"] = @token
assert_not_blocked { post :index }
end
def test_should_allow_delete_with_token_in_header
session[:_csrf_token] = @token
- @request.env['HTTP_X_CSRF_TOKEN'] = @token
+ @request.env["HTTP_X_CSRF_TOKEN"] = @token
assert_not_blocked { delete :index }
end
def test_should_allow_patch_with_token_in_header
session[:_csrf_token] = @token
- @request.env['HTTP_X_CSRF_TOKEN'] = @token
+ @request.env["HTTP_X_CSRF_TOKEN"] = @token
assert_not_blocked { patch :index }
end
def test_should_allow_put_with_token_in_header
session[:_csrf_token] = @token
- @request.env['HTTP_X_CSRF_TOKEN'] = @token
+ @request.env["HTTP_X_CSRF_TOKEN"] = @token
assert_not_blocked { put :index }
end
@@ -309,7 +428,7 @@ module RequestForgeryProtectionTests
session[:_csrf_token] = @token
@controller.stub :form_authenticity_token, @token do
assert_not_blocked do
- @request.set_header 'HTTP_ORIGIN', 'http://test.host'
+ @request.set_header "HTTP_ORIGIN", "http://test.host"
post :index, params: { custom_authenticity_token: @token }
end
end
@@ -327,16 +446,40 @@ module RequestForgeryProtectionTests
end
end
+ def test_should_raise_for_post_with_null_origin
+ forgery_protection_origin_check do
+ session[:_csrf_token] = @token
+ @controller.stub :form_authenticity_token, @token do
+ exception = assert_raises(ActionController::InvalidAuthenticityToken) do
+ @request.set_header "HTTP_ORIGIN", "null"
+ post :index, params: { custom_authenticity_token: @token }
+ end
+ assert_match "The browser returned a 'null' origin for a request", exception.message
+ end
+ end
+ end
+
def test_should_block_post_with_origin_checking_and_wrong_origin
+ old_logger = ActionController::Base.logger
+ logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
+ ActionController::Base.logger = logger
+
forgery_protection_origin_check do
session[:_csrf_token] = @token
@controller.stub :form_authenticity_token, @token do
assert_blocked do
- @request.set_header 'HTTP_ORIGIN', 'http://bad.host'
+ @request.set_header "HTTP_ORIGIN", "http://bad.host"
post :index, params: { custom_authenticity_token: @token }
end
end
end
+
+ assert_match(
+ "HTTP Origin header (http://bad.host) didn't match request.base_url (http://test.host)",
+ logger.logged(:warn).last
+ )
+ ensure
+ ActionController::Base.logger = old_logger
end
def test_should_warn_on_missing_csrf_token
@@ -372,50 +515,86 @@ module RequestForgeryProtectionTests
def test_should_only_allow_same_origin_js_get_with_xhr_header
assert_cross_origin_blocked { get :same_origin_js }
- assert_cross_origin_blocked { get :same_origin_js, format: 'js' }
+ assert_cross_origin_blocked { get :same_origin_js, format: "js" }
+ assert_cross_origin_blocked do
+ @request.accept = "text/javascript"
+ get :negotiate_same_origin
+ end
+
assert_cross_origin_blocked do
- @request.accept = 'text/javascript'
+ @request.accept = "application/javascript"
get :negotiate_same_origin
end
assert_cross_origin_not_blocked { get :same_origin_js, xhr: true }
- assert_cross_origin_not_blocked { get :same_origin_js, xhr: true, format: 'js'}
+ assert_cross_origin_not_blocked { get :same_origin_js, xhr: true, format: "js" }
assert_cross_origin_not_blocked do
- @request.accept = 'text/javascript'
+ @request.accept = "text/javascript"
get :negotiate_same_origin, xhr: true
end
end
+ def test_should_warn_on_not_same_origin_js
+ old_logger = ActionController::Base.logger
+ logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
+ ActionController::Base.logger = logger
+
+ begin
+ assert_cross_origin_blocked { get :same_origin_js }
+
+ assert_equal 1, logger.logged(:warn).size
+ assert_match(/<script> tag on another site requested protected JavaScript/, logger.logged(:warn).last)
+ ensure
+ ActionController::Base.logger = old_logger
+ end
+ end
+
+ def test_should_not_warn_if_csrf_logging_disabled_and_not_same_origin_js
+ old_logger = ActionController::Base.logger
+ logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
+ ActionController::Base.logger = logger
+ ActionController::Base.log_warning_on_csrf_failure = false
+
+ begin
+ assert_cross_origin_blocked { get :same_origin_js }
+
+ assert_equal 0, logger.logged(:warn).size
+ ensure
+ ActionController::Base.logger = old_logger
+ ActionController::Base.log_warning_on_csrf_failure = true
+ end
+ end
+
# Allow non-GET requests since GET is all a remote <script> tag can muster.
def test_should_allow_non_get_js_without_xhr_header
session[:_csrf_token] = @token
assert_cross_origin_not_blocked { post :same_origin_js, params: { custom_authenticity_token: @token } }
- assert_cross_origin_not_blocked { post :same_origin_js, params: { format: 'js', custom_authenticity_token: @token } }
+ assert_cross_origin_not_blocked { post :same_origin_js, params: { format: "js", custom_authenticity_token: @token } }
assert_cross_origin_not_blocked do
- @request.accept = 'text/javascript'
- post :negotiate_same_origin, params: { custom_authenticity_token: @token}
+ @request.accept = "text/javascript"
+ post :negotiate_same_origin, params: { custom_authenticity_token: @token }
end
end
def test_should_only_allow_cross_origin_js_get_without_xhr_header_if_protection_disabled
assert_cross_origin_not_blocked { get :cross_origin_js }
- assert_cross_origin_not_blocked { get :cross_origin_js, format: 'js' }
+ assert_cross_origin_not_blocked { get :cross_origin_js, format: "js" }
assert_cross_origin_not_blocked do
- @request.accept = 'text/javascript'
+ @request.accept = "text/javascript"
get :negotiate_cross_origin
end
assert_cross_origin_not_blocked { get :cross_origin_js, xhr: true }
- assert_cross_origin_not_blocked { get :cross_origin_js, xhr: true, format: 'js' }
+ assert_cross_origin_not_blocked { get :cross_origin_js, xhr: true, format: "js" }
assert_cross_origin_not_blocked do
- @request.accept = 'text/javascript'
+ @request.accept = "text/javascript"
get :negotiate_cross_origin, xhr: true
end
end
def test_should_not_raise_error_if_token_is_not_a_string
assert_blocked do
- patch :index, params: { custom_authenticity_token: { foo: 'bar' } }
+ patch :index, params: { custom_authenticity_token: { foo: "bar" } }
end
end
@@ -457,20 +636,11 @@ end
class RequestForgeryProtectionControllerUsingResetSessionTest < ActionController::TestCase
include RequestForgeryProtectionTests
- setup do
- @old_request_forgery_protection_token = ActionController::Base.request_forgery_protection_token
- ActionController::Base.request_forgery_protection_token = :custom_authenticity_token
- end
-
- teardown do
- ActionController::Base.request_forgery_protection_token = @old_request_forgery_protection_token
- end
-
- test 'should emit a csrf-param meta tag and a csrf-token meta tag' do
- @controller.stub :form_authenticity_token, @token + '<=?' do
+ test "should emit a csrf-param meta tag and a csrf-token meta tag" do
+ @controller.stub :form_authenticity_token, @token + "<=?" do
get :meta
- assert_select 'meta[name=?][content=?]', 'csrf-param', 'custom_authenticity_token'
- assert_select 'meta[name=?]', 'csrf-token'
+ assert_select "meta[name=?][content=?]", "csrf-param", "custom_authenticity_token"
+ assert_select "meta[name=?]", "csrf-token"
regexp = "#{@token}&lt;=\?"
assert_match(/#{regexp}/, @response.body)
end
@@ -479,26 +649,27 @@ end
class RequestForgeryProtectionControllerUsingNullSessionTest < ActionController::TestCase
class NullSessionDummyKeyGenerator
- def generate_key(secret)
- '03312270731a2ed0d11ed091c2338a06'
+ def generate_key(secret, length = nil)
+ "03312270731a2ed0d11ed091c2338a06"
end
end
def setup
@request.env[ActionDispatch::Cookies::GENERATOR_KEY] = NullSessionDummyKeyGenerator.new
+ @request.env[ActionDispatch::Cookies::COOKIES_ROTATIONS] = ActiveSupport::Messages::RotationConfiguration.new
end
- test 'should allow to set signed cookies' do
+ test "should allow to set signed cookies" do
post :signed
assert_response :ok
end
- test 'should allow to set encrypted cookies' do
+ test "should allow to set encrypted cookies" do
post :encrypted
assert_response :ok
end
- test 'should allow reset_session' do
+ test "should allow reset_session" do
post :try_to_reset_session
assert_response :ok
end
@@ -558,29 +729,29 @@ class FreeCookieControllerTest < ActionController::TestCase
def test_should_not_render_form_with_token_tag
SecureRandom.stub :base64, @token do
get :index
- assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
+ assert_select "form>div>input[name=?][value=?]", "authenticity_token", @token, false
end
end
def test_should_not_render_button_to_with_token_tag
SecureRandom.stub :base64, @token do
get :show_button
- assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false
+ assert_select "form>div>input[name=?][value=?]", "authenticity_token", @token, false
end
end
def test_should_allow_all_methods_without_token
SecureRandom.stub :base64, @token do
[:post, :patch, :put, :delete].each do |method|
- assert_nothing_raised { send(method, :index)}
+ assert_nothing_raised { send(method, :index) }
end
end
end
- test 'should not emit a csrf-token meta tag' do
+ test "should not emit a csrf-token meta tag" do
SecureRandom.stub :base64, @token do
get :meta
- assert @response.body.blank?
+ assert_predicate @response.body, :blank?
end
end
end
@@ -604,7 +775,7 @@ class CustomAuthenticityParamControllerTest < ActionController::TestCase
ActionController::Base.logger = @logger
begin
@controller.stub :valid_authenticity_token?, :true do
- post :index, params: { custom_token_name: 'foobar' }
+ post :index, params: { custom_token_name: "foobar" }
assert_equal 0, @logger.logged(:warn).size
end
ensure
@@ -616,10 +787,232 @@ class CustomAuthenticityParamControllerTest < ActionController::TestCase
ActionController::Base.logger = @logger
begin
- post :index, params: { custom_token_name: 'bazqux' }
+ post :index, params: { custom_token_name: "bazqux" }
assert_equal 1, @logger.logged(:warn).size
ensure
ActionController::Base.logger = @old_logger
end
end
end
+
+class PerFormTokensControllerTest < ActionController::TestCase
+ def setup
+ @old_request_forgery_protection_token = ActionController::Base.request_forgery_protection_token
+ ActionController::Base.request_forgery_protection_token = :custom_authenticity_token
+ end
+
+ def teardown
+ ActionController::Base.request_forgery_protection_token = @old_request_forgery_protection_token
+ end
+
+ def test_per_form_token_is_same_size_as_global_token
+ get :index
+ expected = ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH
+ actual = @controller.send(:per_form_csrf_token, session, "/path", "post").size
+ assert_equal expected, actual
+ end
+
+ def test_accepts_token_for_correct_path_and_method
+ get :index
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ assert_response :success
+ end
+
+ def test_rejects_token_for_incorrect_path
+ get :index
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_two"
+ assert_raises(ActionController::InvalidAuthenticityToken) do
+ post :post_two, params: { custom_authenticity_token: form_token }
+ end
+ end
+
+ def test_rejects_token_for_incorrect_method
+ get :index
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_raises(ActionController::InvalidAuthenticityToken) do
+ patch :post_one, params: { custom_authenticity_token: form_token }
+ end
+ end
+
+ def test_rejects_token_for_incorrect_method_button_to
+ get :button_to, params: { form_method: "delete" }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token, "delete"
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_raises(ActionController::InvalidAuthenticityToken) do
+ patch :post_one, params: { custom_authenticity_token: form_token }
+ end
+ end
+
+ test "Accepts proper token for implicit post method on button_to tag" do
+ get :button_to
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token, "post"
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ end
+
+ %w{delete post patch}.each do |verb|
+ test "Accepts proper token for #{verb} method on button_to tag" do
+ get :button_to, params: { form_method: verb }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token, verb
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ send verb, :post_one, params: { custom_authenticity_token: form_token }
+ end
+ end
+ end
+
+ def test_accepts_global_csrf_token
+ get :index
+
+ token = @controller.send(:form_authenticity_token)
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: token }
+ end
+ assert_response :success
+ end
+
+ def test_ignores_params
+ get :index, params: { form_path: "/per_form_tokens/post_one?foo=bar" }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ assert_matches_session_token_on_server form_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one?foo=baz"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token, baz: "foo" }
+ end
+ assert_response :success
+ end
+
+ def test_ignores_trailing_slash_during_generation
+ get :index, params: { form_path: "/per_form_tokens/post_one/" }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ assert_response :success
+ end
+
+ def test_ignores_origin_during_generation
+ get :index, params: { form_path: "https://example.com/per_form_tokens/post_one/" }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ assert_response :success
+ end
+
+ def test_ignores_trailing_slash_during_validation
+ get :index
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one/"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ assert_response :success
+ end
+
+ def test_method_is_case_insensitive
+ get :index, params: { form_method: "POST" }
+
+ form_token = assert_presence_and_fetch_form_csrf_token
+ # This is required because PATH_INFO isn't reset between requests.
+ @request.env["PATH_INFO"] = "/per_form_tokens/post_one/"
+ assert_nothing_raised do
+ post :post_one, params: { custom_authenticity_token: form_token }
+ end
+ assert_response :success
+ end
+
+ private
+ def assert_presence_and_fetch_form_csrf_token
+ assert_select 'input[name="custom_authenticity_token"]' do |input|
+ form_csrf_token = input.first["value"]
+ assert_not_nil form_csrf_token
+ return form_csrf_token
+ end
+ end
+
+ def assert_matches_session_token_on_server(form_token, method = "post")
+ actual = @controller.send(:unmask_token, Base64.strict_decode64(form_token))
+ expected = @controller.send(:per_form_csrf_token, session, "/per_form_tokens/post_one", method)
+ assert_equal expected, actual
+ end
+end
+
+class SkipProtectionControllerTest < ActionController::TestCase
+ def test_should_not_allow_post_without_token_when_not_skipping
+ @controller.skip_requested = false
+ assert_blocked { post :index }
+ end
+
+ def test_should_allow_post_without_token_when_skipping
+ @controller.skip_requested = true
+ assert_not_blocked { post :index }
+ end
+
+ def assert_blocked
+ assert_raises(ActionController::InvalidAuthenticityToken) do
+ yield
+ end
+ end
+
+ def assert_not_blocked
+ assert_nothing_raised { yield }
+ assert_response :success
+ end
+end
diff --git a/actionpack/test/controller/required_params_test.rb b/actionpack/test/controller/required_params_test.rb
index 168f64ce41..4a83d07e7d 100644
--- a/actionpack/test/controller/required_params_test.rb
+++ b/actionpack/test/controller/required_params_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class BooksController < ActionController::Base
def create
@@ -32,7 +34,6 @@ class ActionControllerRequiredParamsTest < ActionController::TestCase
end
class ParametersRequireTest < ActiveSupport::TestCase
-
test "required parameters should accept and return false value" do
assert_equal(false, ActionController::Parameters.new(person: false).require(:person))
end
@@ -50,19 +51,50 @@ class ParametersRequireTest < ActiveSupport::TestCase
end
test "require array when all required params are present" do
- safe_params = ActionController::Parameters.new(person: {first_name: 'Gaurish', title: 'Mjallo', city: 'Barcelona'})
+ safe_params = ActionController::Parameters.new(person: { first_name: "Gaurish", title: "Mjallo", city: "Barcelona" })
.require(:person)
.require([:first_name, :title])
assert_kind_of Array, safe_params
- assert_equal ['Gaurish', 'Mjallo'], safe_params
+ assert_equal ["Gaurish", "Mjallo"], safe_params
end
test "require array when a required param is missing" do
assert_raises(ActionController::ParameterMissing) do
- ActionController::Parameters.new(person: {first_name: 'Gaurish', title: nil})
+ ActionController::Parameters.new(person: { first_name: "Gaurish", title: nil })
.require(:person)
.require([:first_name, :title])
end
end
+
+ test "value params" do
+ params = ActionController::Parameters.new(foo: "bar", dog: "cinco")
+ assert_equal ["bar", "cinco"], params.values
+ assert params.has_value?("cinco")
+ assert params.value?("cinco")
+ end
+
+ test "to_param works like in a Hash" do
+ params = ActionController::Parameters.new(nested: { key: "value" }).permit!
+ assert_equal({ nested: { key: "value" } }.to_param, params.to_param)
+
+ params = { root: ActionController::Parameters.new(nested: { key: "value" }).permit! }
+ assert_equal({ root: { nested: { key: "value" } } }.to_param, params.to_param)
+
+ assert_raise(ActionController::UnfilteredParameters) do
+ ActionController::Parameters.new(nested: { key: "value" }).to_param
+ end
+ end
+
+ test "to_query works like in a Hash" do
+ params = ActionController::Parameters.new(nested: { key: "value" }).permit!
+ assert_equal({ nested: { key: "value" } }.to_query, params.to_query)
+
+ params = { root: ActionController::Parameters.new(nested: { key: "value" }).permit! }
+ assert_equal({ root: { nested: { key: "value" } } }.to_query, params.to_query)
+
+ assert_raise(ActionController::UnfilteredParameters) do
+ ActionController::Parameters.new(nested: { key: "value" }).to_query
+ end
+ end
end
diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb
index f42bef883f..3c39373e55 100644
--- a/actionpack/test/controller/rescue_test.rb
+++ b/actionpack/test/controller/rescue_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class RescueController < ActionController::Base
class NotAuthorized < StandardError
@@ -31,50 +33,54 @@ class RescueController < ActionController::Base
class ResourceUnavailableToRescueAsString < StandardError
end
- # We use a fully-qualified name in some strings, and a relative constant
+ # We use a fully qualified name in some strings, and a relative constant
# name in some other to test correct handling of both cases.
- rescue_from NotAuthorized, :with => :deny_access
- rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access
+ rescue_from NotAuthorized, with: :deny_access
+ rescue_from "RescueController::NotAuthorizedToRescueAsString", with: :deny_access
- rescue_from RecordInvalid, :with => :show_errors
- rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors
+ rescue_from RecordInvalid, with: :show_errors
+ rescue_from "RescueController::RecordInvalidToRescueAsString", with: :show_errors
- rescue_from NotAllowed, :with => proc { head :forbidden }
- rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden }
+ rescue_from NotAllowed, with: proc { head :forbidden }
+ rescue_from "RescueController::NotAllowedToRescueAsString", with: proc { head :forbidden }
rescue_from InvalidRequest, with: proc { |exception| render plain: exception.message }
- rescue_from 'InvalidRequestToRescueAsString', with: proc { |exception| render plain: exception.message }
+ rescue_from "InvalidRequestToRescueAsString", with: proc { |exception| render plain: exception.message }
rescue_from BadGateway do
head 502
end
- rescue_from 'BadGatewayToRescueAsString' do
+ rescue_from "BadGatewayToRescueAsString" do
head 502
end
rescue_from ResourceUnavailable do |exception|
render plain: exception.message
end
- rescue_from 'ResourceUnavailableToRescueAsString' do |exception|
+ rescue_from "ResourceUnavailableToRescueAsString" do |exception|
render plain: exception.message
end
rescue_from ActionView::TemplateError do
- render plain: 'action_view templater error'
+ render plain: "action_view templater error"
end
rescue_from IOError do
- render plain: 'io error'
+ render plain: "io error"
+ end
+
+ rescue_from ActionDispatch::Http::Parameters::ParseError do
+ render plain: "parse error", status: :bad_request
end
- before_action(only: :before_action_raises) { raise 'umm nice' }
+ before_action(only: :before_action_raises) { raise "umm nice" }
def before_action_raises
end
def raises
- render plain: 'already rendered'
+ render plain: "already rendered"
raise "don't panic!"
end
@@ -128,26 +134,33 @@ class RescueController < ActionController::Base
raise ResourceUnavailableToRescueAsString
end
+ def arbitrary_action
+ params
+ render plain: "arbitrary action"
+ end
+
def missing_template
end
- def io_error_in_view
- begin
- raise IOError.new('this is io error')
- rescue
- raise ActionView::TemplateError.new(nil)
- end
+ def exception_with_more_specific_handler_for_wrapper
+ raise RecordInvalid
+ rescue
+ raise NotAuthorized
end
- def zero_division_error_in_view
- begin
- raise ZeroDivisionError.new('this is zero division error')
- rescue
- raise ActionView::TemplateError.new(nil)
- end
+ def exception_with_more_specific_handler_for_cause
+ raise NotAuthorized
+ rescue
+ raise RecordInvalid
end
- protected
+ def exception_with_no_handler_for_wrapper
+ raise RecordInvalid
+ rescue
+ raise RangeError
+ end
+
+ private
def deny_access
head :forbidden
end
@@ -158,7 +171,6 @@ class RescueController < ActionController::Base
end
class ExceptionInheritanceRescueController < ActionController::Base
-
class ParentException < StandardError
end
@@ -168,9 +180,9 @@ class ExceptionInheritanceRescueController < ActionController::Base
class GrandchildException < ChildException
end
- rescue_from ChildException, :with => lambda { head :ok }
- rescue_from ParentException, :with => lambda { head :created }
- rescue_from GrandchildException, :with => lambda { head :no_content }
+ rescue_from ChildException, with: lambda { head :ok }
+ rescue_from ParentException, with: lambda { head :created }
+ rescue_from GrandchildException, with: lambda { head :no_content }
def raise_parent_exception
raise ParentException
@@ -204,7 +216,7 @@ class ControllerInheritanceRescueController < ExceptionInheritanceRescueControll
class SecondExceptionInChildController < StandardError
end
- rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone }
+ rescue_from FirstExceptionInChildController, "SecondExceptionInChildController", with: lambda { head :gone }
def raise_first_exception_in_child_controller
raise FirstExceptionInChildController
@@ -233,17 +245,6 @@ class ControllerInheritanceRescueControllerTest < ActionController::TestCase
end
class RescueControllerTest < ActionController::TestCase
-
- def test_io_error_in_view
- get :io_error_in_view
- assert_equal 'io error', @response.body
- end
-
- def test_zero_division_error_in_view
- get :zero_division_error_in_view
- assert_equal 'action_view templater error', @response.body
- end
-
def test_rescue_handler
get :not_authorized
assert_response :forbidden
@@ -258,7 +259,6 @@ class RescueControllerTest < ActionController::TestCase
get :record_invalid
end
end
-
def test_rescue_handler_with_argument_as_string
assert_called_with @controller, :show_errors, [Exception] do
get :record_invalid_raise_as_string
@@ -296,21 +296,52 @@ class RescueControllerTest < ActionController::TestCase
get :resource_unavailable
assert_equal "RescueController::ResourceUnavailable", @response.body
end
-
def test_block_rescue_handler_with_argument_as_string
get :resource_unavailable_raise_as_string
assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
end
+
+ test "rescue when wrapper has more specific handler than cause" do
+ get :exception_with_more_specific_handler_for_wrapper
+ assert_response :forbidden
+ end
+
+ test "rescue when cause has more specific handler than wrapper" do
+ get :exception_with_more_specific_handler_for_cause
+ assert_response :unprocessable_entity
+ end
+
+ test "rescue when cause has handler, but wrapper doesnt" do
+ get :exception_with_no_handler_for_wrapper
+ assert_response :unprocessable_entity
+ end
+
+ test "can rescue a ParseError" do
+ capture_log_output do
+ post :arbitrary_action, body: "{", as: :json
+ end
+ assert_response :bad_request
+ assert_equal "parse error", response.body
+ end
+
+ private
+
+ def capture_log_output
+ output = StringIO.new
+ request.set_header "action_dispatch.logger", ActiveSupport::Logger.new(output)
+ yield
+ output.string
+ end
end
class RescueTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
class RecordInvalid < StandardError
def message
- 'invalid'
+ "invalid"
end
end
- rescue_from RecordInvalid, :with => :show_errors
+ rescue_from RecordInvalid, with: :show_errors
def foo
render plain: "foo"
@@ -321,26 +352,26 @@ class RescueTest < ActionDispatch::IntegrationTest
end
def b00m
- raise 'b00m'
+ raise "b00m"
end
- protected
+ private
def show_errors(exception)
render plain: exception.message
end
end
- test 'normal request' do
+ test "normal request" do
with_test_routing do
- get '/foo'
- assert_equal 'foo', response.body
+ get "/foo"
+ assert_equal "foo", response.body
end
end
- test 'rescue exceptions inside controller' do
+ test "rescue exceptions inside controller" do
with_test_routing do
- get '/invalid'
- assert_equal 'invalid', response.body
+ get "/invalid"
+ assert_equal "invalid", response.body
end
end
@@ -349,9 +380,9 @@ class RescueTest < ActionDispatch::IntegrationTest
def with_test_routing
with_routing do |set|
set.draw do
- get 'foo', :to => ::RescueTest::TestController.action(:foo)
- get 'invalid', :to => ::RescueTest::TestController.action(:invalid)
- get 'b00m', :to => ::RescueTest::TestController.action(:b00m)
+ get "foo", to: ::RescueTest::TestController.action(:foo)
+ get "invalid", to: ::RescueTest::TestController.action(:invalid)
+ get "b00m", to: ::RescueTest::TestController.action(:b00m)
end
yield
end
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 4490abf7b2..d2146f12a5 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -1,10 +1,26 @@
-require 'abstract_unit'
-require 'active_support/core_ext/object/try'
-require 'active_support/core_ext/object/with_options'
-require 'active_support/core_ext/array/extract_options'
+# frozen_string_literal: true
-class ResourcesTest < ActionController::TestCase
+require "abstract_unit"
+require "active_support/core_ext/object/try"
+require "active_support/core_ext/object/with_options"
+require "active_support/core_ext/array/extract_options"
+
+class AdminController < ResourcesController; end
+class MessagesController < ResourcesController; end
+class ProductsController < ResourcesController; end
+class ThreadsController < ResourcesController; end
+
+module Backoffice
+ class ProductsController < ResourcesController; end
+ class ImagesController < ResourcesController; end
+
+ module Admin
+ class ProductsController < ResourcesController; end
+ class ImagesController < ResourcesController; end
+ end
+end
+class ResourcesTest < ActionController::TestCase
def test_default_restful_routes
with_restful_routing :messages do
assert_simply_restful_for :messages
@@ -12,45 +28,44 @@ class ResourcesTest < ActionController::TestCase
end
def test_override_paths_for_member_and_collection_methods
- collection_methods = { :rss => :get, :reorder => :post, :csv => :post }
- member_methods = { :rss => :get, :atom => :get, :upload => :post, :fix => :post }
- path_names = {:new => 'nuevo', :rss => 'canal', :fix => 'corrigir' }
+ collection_methods = { rss: :get, reorder: :post, csv: :post }
+ member_methods = { rss: :get, atom: :get, upload: :post, fix: :post }
+ path_names = { new: "nuevo", rss: "canal", fix: "corrigir" }
with_restful_routing :messages,
- :collection => collection_methods,
- :member => member_methods,
- :path_names => path_names do
+ collection: collection_methods,
+ member: member_methods,
+ path_names: path_names do
assert_restful_routes_for :messages,
- :collection => collection_methods,
- :member => member_methods,
- :path_names => path_names do |options|
+ collection: collection_methods,
+ member: member_methods,
+ path_names: path_names do |options|
member_methods.each do |action, method|
- assert_recognizes(options.merge(:action => action.to_s, :id => '1'),
- :path => "/messages/1/#{path_names[action] || action}",
- :method => method)
+ assert_recognizes(options.merge(action: action.to_s, id: "1"),
+ path: "/messages/1/#{path_names[action] || action}",
+ method: method)
end
collection_methods.each do |action, method|
- assert_recognizes(options.merge(:action => action.to_s),
- :path => "/messages/#{path_names[action] || action}",
- :method => method)
+ assert_recognizes(options.merge(action: action.to_s),
+ path: "/messages/#{path_names[action] || action}",
+ method: method)
end
end
assert_restful_named_routes_for :messages,
- :collection => collection_methods,
- :member => member_methods,
- :path_names => path_names do |options|
+ collection: collection_methods,
+ member: member_methods,
+ path_names: path_names do |options|
collection_methods.each_key do |action|
- assert_named_route "/messages/#{path_names[action] || action}", "#{action}_messages_path", :action => action
+ assert_named_route "/messages/#{path_names[action] || action}", "#{action}_messages_path", action: action
end
member_methods.each_key do |action|
- assert_named_route "/messages/1/#{path_names[action] || action}", "#{action}_message_path", :action => action, :id => "1"
+ assert_named_route "/messages/1/#{path_names[action] || action}", "#{action}_message_path", action: action, id: "1"
end
-
end
end
end
@@ -63,182 +78,182 @@ class ResourcesTest < ActionController::TestCase
end
def test_multiple_resources_with_options
- expected_options = {:controller => 'threads', :action => 'index'}
+ expected_options = { controller: "threads", action: "index" }
with_restful_routing :messages, :comments, expected_options.slice(:controller) do
- assert_recognizes(expected_options, :path => 'comments')
- assert_recognizes(expected_options, :path => 'messages')
+ assert_recognizes(expected_options, path: "comments")
+ assert_recognizes(expected_options, path: "messages")
end
end
def test_with_custom_conditions
- with_restful_routing :messages, :conditions => { :subdomain => 'app' } do
- assert @routes.recognize_path("/messages", :method => :get, :subdomain => 'app')
+ with_restful_routing :messages, conditions: { subdomain: "app" } do
+ assert @routes.recognize_path("/messages", method: :get, subdomain: "app")
end
end
def test_irregular_id_with_no_constraints_should_raise_error
- expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'}
+ expected_options = { controller: "messages", action: "show", id: "1.1.1" }
with_restful_routing :messages do
assert_raise(Assertion) do
- assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get)
+ assert_recognizes(expected_options, path: "messages/1.1.1", method: :get)
end
end
end
def test_irregular_id_with_constraints_should_pass
- expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'}
+ expected_options = { controller: "messages", action: "show", id: "1.1.1" }
- with_restful_routing(:messages, :constraints => {:id => /[0-9]\.[0-9]\.[0-9]/}) do
- assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get)
+ with_restful_routing(:messages, constraints: { id: /[0-9]\.[0-9]\.[0-9]/ }) do
+ assert_recognizes(expected_options, path: "messages/1.1.1", method: :get)
end
end
def test_with_path_prefix_constraints
- expected_options = {:controller => 'messages', :action => 'show', :thread_id => '1.1.1', :id => '1'}
- with_restful_routing :messages, :path_prefix => '/thread/:thread_id', :constraints => {:thread_id => /[0-9]\.[0-9]\.[0-9]/} do
- assert_recognizes(expected_options, :path => 'thread/1.1.1/messages/1', :method => :get)
+ expected_options = { controller: "messages", action: "show", thread_id: "1.1.1", id: "1" }
+ with_restful_routing :messages, path_prefix: "/thread/:thread_id", constraints: { thread_id: /[0-9]\.[0-9]\.[0-9]/ } do
+ assert_recognizes(expected_options, path: "thread/1.1.1/messages/1", method: :get)
end
end
def test_irregular_id_constraints_should_get_passed_to_member_actions
- expected_options = {:controller => 'messages', :action => 'custom', :id => '1.1.1'}
+ expected_options = { controller: "messages", action: "custom", id: "1.1.1" }
- with_restful_routing(:messages, :member => {:custom => :get}, :constraints => {:id => /[0-9]\.[0-9]\.[0-9]/}) do
- assert_recognizes(expected_options, :path => 'messages/1.1.1/custom', :method => :get)
+ with_restful_routing(:messages, member: { custom: :get }, constraints: { id: /[0-9]\.[0-9]\.[0-9]/ }) do
+ assert_recognizes(expected_options, path: "messages/1.1.1/custom", method: :get)
end
end
def test_with_path_prefix
- with_restful_routing :messages, :path_prefix => '/thread/:thread_id' do
- assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
+ with_restful_routing :messages, path_prefix: "/thread/:thread_id" do
+ assert_simply_restful_for :messages, path_prefix: "thread/5/", options: { thread_id: "5" }
end
end
def test_multiple_with_path_prefix
- with_restful_routing :messages, :comments, :path_prefix => '/thread/:thread_id' do
- assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
- assert_simply_restful_for :comments, :path_prefix => 'thread/5/', :options => { :thread_id => '5' }
+ with_restful_routing :messages, :comments, path_prefix: "/thread/:thread_id" do
+ assert_simply_restful_for :messages, path_prefix: "thread/5/", options: { thread_id: "5" }
+ assert_simply_restful_for :comments, path_prefix: "thread/5/", options: { thread_id: "5" }
end
end
def test_with_name_prefix
- with_restful_routing :messages, :as => 'post_messages' do
- assert_simply_restful_for :messages, :name_prefix => 'post_'
+ with_restful_routing :messages, as: "post_messages" do
+ assert_simply_restful_for :messages, name_prefix: "post_"
end
end
def test_with_collection_actions
- actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete, 'e' => :patch }
+ actions = { "a" => :get, "b" => :put, "c" => :post, "d" => :delete, "e" => :patch }
with_routing do |set|
set.draw do
resources :messages do
- get :a, :on => :collection
- put :b, :on => :collection
- post :c, :on => :collection
- delete :d, :on => :collection
- patch :e, :on => :collection
+ get :a, on: :collection
+ put :b, on: :collection
+ post :c, on: :collection
+ delete :d, on: :collection
+ patch :e, on: :collection
end
end
assert_restful_routes_for :messages do |options|
actions.each do |action, method|
- assert_recognizes(options.merge(:action => action), :path => "/messages/#{action}", :method => method)
+ assert_recognizes(options.merge(action: action), path: "/messages/#{action}", method: method)
end
end
assert_restful_named_routes_for :messages do
actions.each_key do |action|
- assert_named_route "/messages/#{action}", "#{action}_messages_path", :action => action
+ assert_named_route "/messages/#{action}", "#{action}_messages_path", action: action
end
end
end
end
def test_with_collection_actions_and_name_prefix
- actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete, 'e' => :patch }
+ actions = { "a" => :get, "b" => :put, "c" => :post, "d" => :delete, "e" => :patch }
with_routing do |set|
set.draw do
- scope '/threads/:thread_id' do
- resources :messages, :as => 'thread_messages' do
- get :a, :on => :collection
- put :b, :on => :collection
- post :c, :on => :collection
- delete :d, :on => :collection
- patch :e, :on => :collection
+ scope "/threads/:thread_id" do
+ resources :messages, as: "thread_messages" do
+ get :a, on: :collection
+ put :b, on: :collection
+ post :c, on: :collection
+ delete :d, on: :collection
+ patch :e, on: :collection
end
end
end
- assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
+ assert_restful_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do |options|
actions.each do |action, method|
- assert_recognizes(options.merge(:action => action), :path => "/threads/1/messages/#{action}", :method => method)
+ assert_recognizes(options.merge(action: action), path: "/threads/1/messages/#{action}", method: method)
end
end
- assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do
+ assert_restful_named_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do
actions.each_key do |action|
- assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", :action => action
+ assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", action: action
end
end
end
end
def test_with_collection_actions_and_name_prefix_and_member_action_with_same_name
- actions = { 'a' => :get }
+ actions = { "a" => :get }
with_routing do |set|
set.draw do
- scope '/threads/:thread_id' do
- resources :messages, :as => 'thread_messages' do
- get :a, :on => :collection
- get :a, :on => :member
+ scope "/threads/:thread_id" do
+ resources :messages, as: "thread_messages" do
+ get :a, on: :collection
+ get :a, on: :member
end
end
end
- assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
+ assert_restful_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do |options|
actions.each do |action, method|
- assert_recognizes(options.merge(:action => action), :path => "/threads/1/messages/#{action}", :method => method)
+ assert_recognizes(options.merge(action: action), path: "/threads/1/messages/#{action}", method: method)
end
end
- assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do
+ assert_restful_named_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do
actions.each_key do |action|
- assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", :action => action
+ assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", action: action
end
end
end
end
def test_with_collection_action_and_name_prefix_and_formatted
- actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete, 'e' => :patch }
+ actions = { "a" => :get, "b" => :put, "c" => :post, "d" => :delete, "e" => :patch }
with_routing do |set|
set.draw do
- scope '/threads/:thread_id' do
- resources :messages, :as => 'thread_messages' do
- get :a, :on => :collection
- put :b, :on => :collection
- post :c, :on => :collection
- delete :d, :on => :collection
- patch :e, :on => :collection
+ scope "/threads/:thread_id" do
+ resources :messages, as: "thread_messages" do
+ get :a, on: :collection
+ put :b, on: :collection
+ post :c, on: :collection
+ delete :d, on: :collection
+ patch :e, on: :collection
end
end
end
- assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
+ assert_restful_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do |options|
actions.each do |action, method|
- assert_recognizes(options.merge(:action => action, :format => 'xml'), :path => "/threads/1/messages/#{action}.xml", :method => method)
+ assert_recognizes(options.merge(action: action, format: "xml"), path: "/threads/1/messages/#{action}.xml", method: method)
end
end
- assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do
+ assert_restful_named_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do
actions.each_key do |action|
- assert_named_route "/threads/1/messages/#{action}.xml", "#{action}_thread_messages_path", :action => action, :format => 'xml'
+ assert_named_route "/threads/1/messages/#{action}.xml", "#{action}_thread_messages_path", action: action, format: "xml"
end
end
end
@@ -246,11 +261,11 @@ class ResourcesTest < ActionController::TestCase
def test_with_member_action
[:patch, :put, :post].each do |method|
- with_restful_routing :messages, :member => { :mark => method } do
- mark_options = {:action => 'mark', :id => '1'}
+ with_restful_routing :messages, member: { mark: method } do
+ mark_options = { action: "mark", id: "1" }
mark_path = "/messages/1/mark"
assert_restful_routes_for :messages do |options|
- assert_recognizes(options.merge(mark_options), :path => mark_path, :method => method)
+ assert_recognizes(options.merge(mark_options), path: mark_path, method: method)
end
assert_restful_named_routes_for :messages do
@@ -261,24 +276,24 @@ class ResourcesTest < ActionController::TestCase
end
def test_with_member_action_and_requirement
- expected_options = {:controller => 'messages', :action => 'mark', :id => '1.1.1'}
+ expected_options = { controller: "messages", action: "mark", id: "1.1.1" }
- with_restful_routing(:messages, :constraints => {:id => /[0-9]\.[0-9]\.[0-9]/}, :member => { :mark => :get }) do
- assert_recognizes(expected_options, :path => 'messages/1.1.1/mark', :method => :get)
+ with_restful_routing(:messages, constraints: { id: /[0-9]\.[0-9]\.[0-9]/ }, member: { mark: :get }) do
+ assert_recognizes(expected_options, path: "messages/1.1.1/mark", method: :get)
end
end
def test_member_when_override_paths_for_default_restful_actions_with
[:patch, :put, :post].each do |method|
- with_restful_routing :messages, :member => { :mark => method }, :path_names => {:new => 'nuevo'} do
- mark_options = {:action => 'mark', :id => '1', :controller => "messages"}
+ with_restful_routing :messages, member: { mark: method }, path_names: { new: "nuevo" } do
+ mark_options = { action: "mark", id: "1", controller: "messages" }
mark_path = "/messages/1/mark"
- assert_restful_routes_for :messages, :path_names => {:new => 'nuevo'} do |options|
- assert_recognizes(options.merge(mark_options), :path => mark_path, :method => method)
+ assert_restful_routes_for :messages, path_names: { new: "nuevo" } do |options|
+ assert_recognizes(options.merge(mark_options), path: mark_path, method: method)
end
- assert_restful_named_routes_for :messages, :path_names => {:new => 'nuevo'} do
+ assert_restful_named_routes_for :messages, path_names: { new: "nuevo" } do
assert_named_route mark_path, :mark_message_path, mark_options
end
end
@@ -291,17 +306,17 @@ class ResourcesTest < ActionController::TestCase
set.draw do
resources :messages do
member do
- match :mark , :via => method
- match :unmark, :via => method
+ match :mark, via: method
+ match :unmark, via: method
end
end
end
%w(mark unmark).each do |action|
- action_options = {:action => action, :id => '1'}
+ action_options = { action: action, id: "1" }
action_path = "/messages/1/#{action}"
assert_restful_routes_for :messages do |options|
- assert_recognizes(options.merge(action_options), :path => action_path, :method => method)
+ assert_recognizes(options.merge(action_options), path: action_path, method: method)
end
assert_restful_named_routes_for :messages do
@@ -317,21 +332,21 @@ class ResourcesTest < ActionController::TestCase
set.draw do
resources :messages do
collection do
- match :search, :via => [:post, :get]
+ match :search, via: [:post, :get]
end
member do
- match :toggle, :via => [:post, :get]
+ match :toggle, via: [:post, :get]
end
end
end
assert_restful_routes_for :messages do |options|
[:get, :post].each do |method|
- assert_recognizes(options.merge(:action => 'search'), :path => "/messages/search", :method => method)
+ assert_recognizes(options.merge(action: "search"), path: "/messages/search", method: method)
end
[:get, :post].each do |method|
- assert_recognizes(options.merge(:action => 'toggle', :id => '1'), :path => '/messages/1/toggle', :method => method)
+ assert_recognizes(options.merge(action: "toggle", id: "1"), path: "/messages/1/toggle", method: method)
end
end
end
@@ -341,14 +356,14 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
resources :messages do
- post :preview, :on => :new
+ post :preview, on: :new
end
end
- preview_options = {:action => 'preview'}
+ preview_options = { action: "preview" }
preview_path = "/messages/new/preview"
assert_restful_routes_for :messages do |options|
- assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ assert_recognizes(options.merge(preview_options), path: preview_path, method: :post)
end
assert_restful_named_routes_for :messages do
@@ -360,20 +375,20 @@ class ResourcesTest < ActionController::TestCase
def test_with_new_action_with_name_prefix
with_routing do |set|
set.draw do
- scope('/threads/:thread_id') do
- resources :messages, :as => "thread_messages" do
- post :preview, :on => :new
+ scope("/threads/:thread_id") do
+ resources :messages, as: "thread_messages" do
+ post :preview, on: :new
end
end
end
- preview_options = {:action => 'preview', :thread_id => '1'}
+ preview_options = { action: "preview", thread_id: "1" }
preview_path = "/threads/1/messages/new/preview"
- assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
- assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ assert_restful_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do |options|
+ assert_recognizes(options.merge(preview_options), path: preview_path, method: :post)
end
- assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do
+ assert_restful_named_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do
assert_named_route preview_path, :preview_new_thread_message_path, preview_options
end
end
@@ -382,20 +397,20 @@ class ResourcesTest < ActionController::TestCase
def test_with_formatted_new_action_with_name_prefix
with_routing do |set|
set.draw do
- scope('/threads/:thread_id') do
- resources :messages, :as => "thread_messages" do
- post :preview, :on => :new
+ scope("/threads/:thread_id") do
+ resources :messages, as: "thread_messages" do
+ post :preview, on: :new
end
end
end
- preview_options = {:action => 'preview', :thread_id => '1', :format => 'xml'}
+ preview_options = { action: "preview", thread_id: "1", format: "xml" }
preview_path = "/threads/1/messages/new/preview.xml"
- assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options|
- assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post)
+ assert_restful_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do |options|
+ assert_recognizes(options.merge(preview_options), path: preview_path, method: :post)
end
- assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do
+ assert_restful_named_routes_for :messages, path_prefix: "threads/1/", name_prefix: "thread_", options: { thread_id: "1" } do
assert_named_route preview_path, :preview_new_thread_message_path, preview_options
end
end
@@ -404,9 +419,9 @@ class ResourcesTest < ActionController::TestCase
def test_override_new_method
with_restful_routing :messages do
assert_restful_routes_for :messages do |options|
- assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get)
+ assert_recognizes(options.merge(action: "new"), path: "/messages/new", method: :get)
assert_raise(ActionController::RoutingError) do
- @routes.recognize_path("/messages/new", :method => :post)
+ @routes.recognize_path("/messages/new", method: :post)
end
end
end
@@ -414,13 +429,13 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
resources :messages do
- match :new, :via => [:post, :get], :on => :new
+ match :new, via: [:post, :get], on: :new
end
end
assert_restful_routes_for :messages do |options|
- assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :post)
- assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get)
+ assert_recognizes(options.merge(action: "new"), path: "/messages/new", method: :post)
+ assert_recognizes(options.merge(action: "new"), path: "/messages/new", method: :get)
end
end
end
@@ -437,20 +452,20 @@ class ResourcesTest < ActionController::TestCase
assert_simply_restful_for :threads
assert_simply_restful_for :messages,
- :name_prefix => 'thread_',
- :path_prefix => 'threads/1/',
- :options => { :thread_id => '1' }
+ name_prefix: "thread_",
+ path_prefix: "threads/1/",
+ options: { thread_id: "1" }
assert_simply_restful_for :comments,
- :name_prefix => 'thread_message_',
- :path_prefix => 'threads/1/messages/2/',
- :options => { :thread_id => '1', :message_id => '2' }
+ name_prefix: "thread_message_",
+ path_prefix: "threads/1/messages/2/",
+ options: { thread_id: "1", message_id: "2" }
end
end
def test_shallow_nested_restful_routes
with_routing do |set|
set.draw do
- resources :threads, :shallow => true do
+ resources :threads, shallow: true do
resources :messages do
resources :comments
end
@@ -458,17 +473,17 @@ class ResourcesTest < ActionController::TestCase
end
assert_simply_restful_for :threads,
- :shallow => true
+ shallow: true
assert_simply_restful_for :messages,
- :name_prefix => 'thread_',
- :path_prefix => 'threads/1/',
- :shallow => true,
- :options => { :thread_id => '1' }
+ name_prefix: "thread_",
+ path_prefix: "threads/1/",
+ shallow: true,
+ options: { thread_id: "1" }
assert_simply_restful_for :comments,
- :name_prefix => 'message_',
- :path_prefix => 'messages/2/',
- :shallow => true,
- :options => { :message_id => '2' }
+ name_prefix: "message_",
+ path_prefix: "messages/2/",
+ shallow: true,
+ options: { message_id: "2" }
end
end
@@ -477,7 +492,7 @@ class ResourcesTest < ActionController::TestCase
set.draw do
namespace :backoffice do
namespace :admin do
- resources :products, :shallow => true do
+ resources :products, shallow: true do
resources :images
end
end
@@ -485,18 +500,18 @@ class ResourcesTest < ActionController::TestCase
end
assert_simply_restful_for :products,
- :controller => 'backoffice/admin/products',
- :namespace => 'backoffice/admin/',
- :name_prefix => 'backoffice_admin_',
- :path_prefix => 'backoffice/admin/',
- :shallow => true
+ controller: "backoffice/admin/products",
+ namespace: "backoffice/admin/",
+ name_prefix: "backoffice_admin_",
+ path_prefix: "backoffice/admin/",
+ shallow: true
assert_simply_restful_for :images,
- :controller => 'backoffice/admin/images',
- :namespace => 'backoffice/admin/',
- :name_prefix => 'backoffice_admin_product_',
- :path_prefix => 'backoffice/admin/products/1/',
- :shallow => true,
- :options => { :product_id => '1' }
+ controller: "backoffice/admin/images",
+ namespace: "backoffice/admin/",
+ name_prefix: "backoffice_admin_product_",
+ path_prefix: "backoffice/admin/products/1/",
+ shallow: true,
+ options: { product_id: "1" }
end
end
@@ -528,13 +543,13 @@ class ResourcesTest < ActionController::TestCase
def test_should_create_nested_singleton_resource_routes
with_routing do |set|
set.draw do
- resource :admin, :controller => 'admin' do
+ resource :admin, controller: "admin" do
resource :account
end
end
- assert_singleton_restful_for :admin, :controller => 'admin'
- assert_singleton_restful_for :account, :name_prefix => "admin_", :path_prefix => 'admin/'
+ assert_singleton_restful_for :admin, controller: "admin"
+ assert_singleton_restful_for :account, name_prefix: "admin_", path_prefix: "admin/"
end
end
@@ -543,14 +558,14 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
resource :account do
- match :reset, :on => :member, :via => method
+ match :reset, on: :member, via: method
end
end
- reset_options = {:action => 'reset'}
+ reset_options = { action: "reset" }
reset_path = "/account/reset"
assert_singleton_routes_for :account do |options|
- assert_recognizes(options.merge(reset_options), :path => reset_path, :method => method)
+ assert_recognizes(options.merge(reset_options), path: reset_path, method: method)
end
assert_singleton_named_routes_for :account do
@@ -565,16 +580,16 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
resource :account do
- match :reset, :on => :member, :via => method
- match :disable, :on => :member, :via => method
+ match :reset, on: :member, via: method
+ match :disable, on: :member, via: method
end
end
%w(reset disable).each do |action|
- action_options = {:action => action}
+ action_options = { action: action }
action_path = "/account/#{action}"
assert_singleton_routes_for :account do |options|
- assert_recognizes(options.merge(action_options), :path => action_path, :method => method)
+ assert_recognizes(options.merge(action_options), path: action_path, method: method)
end
assert_singleton_named_routes_for :account do
@@ -594,22 +609,22 @@ class ResourcesTest < ActionController::TestCase
end
assert_singleton_restful_for :account
- assert_simply_restful_for :messages, :name_prefix => "account_", :path_prefix => 'account/'
+ assert_simply_restful_for :messages, name_prefix: "account_", path_prefix: "account/"
end
end
def test_should_nest_resources_in_singleton_resource_with_path_scope
with_routing do |set|
set.draw do
- scope ':site_id' do
+ scope ":site_id" do
resource(:account) do
resources :messages
end
end
end
- assert_singleton_restful_for :account, :path_prefix => '7/', :options => { :site_id => '7' }
- assert_simply_restful_for :messages, :name_prefix => "account_", :path_prefix => '7/account/', :options => { :site_id => '7' }
+ assert_singleton_restful_for :account, path_prefix: "7/", options: { site_id: "7" }
+ assert_simply_restful_for :messages, name_prefix: "account_", path_prefix: "7/account/", options: { site_id: "7" }
end
end
@@ -617,31 +632,31 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
resources :threads do
- resource :admin, :controller => 'admin'
+ resource :admin, controller: "admin"
end
end
assert_simply_restful_for :threads
- assert_singleton_restful_for :admin, :controller => 'admin', :name_prefix => 'thread_', :path_prefix => 'threads/5/', :options => { :thread_id => '5' }
+ assert_singleton_restful_for :admin, controller: "admin", name_prefix: "thread_", path_prefix: "threads/5/", options: { thread_id: "5" }
end
end
def test_should_not_allow_delete_or_patch_or_put_on_collection_path
controller_name = :messages
with_restful_routing controller_name do
- options = { :controller => controller_name.to_s }
+ options = { controller: controller_name.to_s }
collection_path = "/#{controller_name}"
assert_raise(Assertion) do
- assert_recognizes(options.merge(:action => 'update'), :path => collection_path, :method => :patch)
+ assert_recognizes(options.merge(action: "update"), path: collection_path, method: :patch)
end
assert_raise(Assertion) do
- assert_recognizes(options.merge(:action => 'update'), :path => collection_path, :method => :put)
+ assert_recognizes(options.merge(action: "update"), path: collection_path, method: :put)
end
assert_raise(Assertion) do
- assert_recognizes(options.merge(:action => 'destroy'), :path => collection_path, :method => :delete)
+ assert_recognizes(options.merge(action: "destroy"), path: collection_path, method: :delete)
end
end
end
@@ -649,15 +664,15 @@ class ResourcesTest < ActionController::TestCase
def test_new_style_named_routes_for_resource
with_routing do |set|
set.draw do
- scope '/threads/:thread_id' do
- resources :messages, :as => 'thread_messages' do
- get :search, :on => :collection
- get :preview, :on => :new
+ scope "/threads/:thread_id" do
+ resources :messages, as: "thread_messages" do
+ get :search, on: :collection
+ get :preview, on: :new
end
end
end
- assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' }
+ assert_simply_restful_for :messages, name_prefix: "thread_", path_prefix: "threads/1/", options: { thread_id: "1" }
assert_named_route "/threads/1/messages/search", "search_thread_messages_path", {}
assert_named_route "/threads/1/messages/new", "new_thread_message_path", {}
assert_named_route "/threads/1/messages/new/preview", "preview_new_thread_message_path", {}
@@ -667,14 +682,14 @@ class ResourcesTest < ActionController::TestCase
def test_new_style_named_routes_for_singleton_resource
with_routing do |set|
set.draw do
- scope '/admin' do
- resource :account, :as => :admin_account do
- get :login, :on => :member
- get :preview, :on => :new
+ scope "/admin" do
+ resource :account, as: :admin_account do
+ get :login, on: :member
+ get :preview, on: :new
end
end
end
- assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/'
+ assert_singleton_restful_for :account, name_prefix: "admin_", path_prefix: "admin/"
assert_named_route "/admin/account/login", "login_admin_account_path", {}
assert_named_route "/admin/account/new", "new_admin_account_path", {}
assert_named_route "/admin/account/new/preview", "preview_new_admin_account_path", {}
@@ -689,7 +704,7 @@ class ResourcesTest < ActionController::TestCase
end
end
- assert_simply_restful_for :products, :controller => "backoffice/products", :name_prefix => 'backoffice_', :path_prefix => 'backoffice/'
+ assert_simply_restful_for :products, controller: "backoffice/products", name_prefix: "backoffice_", path_prefix: "backoffice/"
end
end
@@ -703,19 +718,19 @@ class ResourcesTest < ActionController::TestCase
end
end
- assert_simply_restful_for :products, :controller => "backoffice/admin/products", :name_prefix => 'backoffice_admin_', :path_prefix => 'backoffice/admin/'
+ assert_simply_restful_for :products, controller: "backoffice/admin/products", name_prefix: "backoffice_admin_", path_prefix: "backoffice/admin/"
end
end
def test_resources_using_namespace
with_routing do |set|
set.draw do
- namespace :backoffice, :path => nil, :as => nil do
+ namespace :backoffice, path: nil, as: nil do
resources :products
end
end
- assert_simply_restful_for :products, :controller => "backoffice/products"
+ assert_simply_restful_for :products, controller: "backoffice/products"
end
end
@@ -729,7 +744,7 @@ class ResourcesTest < ActionController::TestCase
end
end
- assert_simply_restful_for :images, :controller => "backoffice/images", :name_prefix => 'backoffice_product_', :path_prefix => 'backoffice/products/1/', :options => {:product_id => '1'}
+ assert_simply_restful_for :images, controller: "backoffice/images", name_prefix: "backoffice_product_", path_prefix: "backoffice/products/1/", options: { product_id: "1" }
end
end
@@ -745,107 +760,129 @@ class ResourcesTest < ActionController::TestCase
end
end
- assert_simply_restful_for :images, :controller => "backoffice/admin/images", :name_prefix => 'backoffice_admin_product_', :path_prefix => 'backoffice/admin/products/1/', :options => {:product_id => '1'}
+ assert_simply_restful_for :images, controller: "backoffice/admin/images", name_prefix: "backoffice_admin_product_", path_prefix: "backoffice/admin/products/1/", options: { product_id: "1" }
end
end
def test_with_path_segment
with_restful_routing :messages do
assert_simply_restful_for :messages
- assert_recognizes({:controller => "messages", :action => "index"}, "/messages")
- assert_recognizes({:controller => "messages", :action => "index"}, "/messages/")
+ assert_recognizes({ controller: "messages", action: "index" }, "/messages")
+ assert_recognizes({ controller: "messages", action: "index" }, "/messages/")
end
- with_routing do |set|
- set.draw do
- resources :messages, :path => 'reviews'
- end
- assert_simply_restful_for :messages, :as => 'reviews'
- assert_recognizes({:controller => "messages", :action => "index"}, "/reviews")
- assert_recognizes({:controller => "messages", :action => "index"}, "/reviews/")
- end
+ with_routing do |set|
+ set.draw do
+ resources :messages, path: "reviews"
+ end
+ assert_simply_restful_for :messages, as: "reviews"
+ assert_recognizes({ controller: "messages", action: "index" }, "/reviews")
+ assert_recognizes({ controller: "messages", action: "index" }, "/reviews/")
+ end
end
def test_multiple_with_path_segment_and_controller
with_routing do |set|
set.draw do
- resources :products do
- resources :product_reviews, :path => 'reviews', :controller => 'messages'
- end
- resources :tutors do
- resources :tutor_reviews, :path => 'reviews', :controller => 'comments'
- end
+ resources :products do
+ resources :product_reviews, path: "reviews", controller: "messages"
+ end
+ resources :tutors do
+ resources :tutor_reviews, path: "reviews", controller: "comments"
+ end
end
- assert_simply_restful_for :product_reviews, :controller=>'messages', :as => 'reviews', :name_prefix => 'product_', :path_prefix => 'products/1/', :options => {:product_id => '1'}
- assert_simply_restful_for :tutor_reviews,:controller=>'comments', :as => 'reviews', :name_prefix => 'tutor_', :path_prefix => 'tutors/1/', :options => {:tutor_id => '1'}
+ assert_simply_restful_for :product_reviews, controller: "messages", as: "reviews", name_prefix: "product_", path_prefix: "products/1/", options: { product_id: "1" }
+ assert_simply_restful_for :tutor_reviews, controller: "comments", as: "reviews", name_prefix: "tutor_", path_prefix: "tutors/1/", options: { tutor_id: "1" }
end
end
def test_with_path_segment_path_prefix_constraints
- expected_options = {:controller => 'messages', :action => 'show', :thread_id => '1.1.1', :id => '1'}
+ expected_options = { controller: "messages", action: "show", thread_id: "1.1.1", id: "1" }
with_routing do |set|
set.draw do
- scope '/thread/:thread_id', :constraints => { :thread_id => /[0-9]\.[0-9]\.[0-9]/ } do
- resources :messages, :path => 'comments'
+ scope "/thread/:thread_id", constraints: { thread_id: /[0-9]\.[0-9]\.[0-9]/ } do
+ resources :messages, path: "comments"
end
end
- assert_recognizes(expected_options, :path => 'thread/1.1.1/comments/1', :method => :get)
+ assert_recognizes(expected_options, path: "thread/1.1.1/comments/1", method: :get)
end
end
def test_resource_has_only_show_action
with_routing do |set|
set.draw do
- resources :products, :only => :show
+ resources :products, only: :show
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, :show, [:index, :new, :create, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, :show, [:index, :new, :create, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, :show, [:index, :new, :create, :edit, :update, :destroy])
end
end
def test_singleton_resource_has_only_show_action
with_routing do |set|
set.draw do
- resource :account, :only => :show
+ resource :account, only: :show
end
- assert_singleton_resource_allowed_routes('accounts', {}, :show, [:index, :new, :create, :edit, :update, :destroy])
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, :show, [:index, :new, :create, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", {}, :show, [:index, :new, :create, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, :show, [:index, :new, :create, :edit, :update, :destroy])
end
end
def test_resource_does_not_have_destroy_action
with_routing do |set|
set.draw do
- resources :products, :except => :destroy
+ resources :products, except: :destroy
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, [:index, :new, :create, :show, :edit, :update], :destroy)
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, [:index, :new, :create, :show, :edit, :update], :destroy)
+ assert_resource_allowed_routes("products", {}, { id: "1" }, [:index, :new, :create, :show, :edit, :update], :destroy)
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, [:index, :new, :create, :show, :edit, :update], :destroy)
end
end
def test_singleton_resource_does_not_have_destroy_action
with_routing do |set|
set.draw do
- resource :account, :except => :destroy
+ resource :account, except: :destroy
+ end
+
+ assert_singleton_resource_allowed_routes("accounts", {}, [:new, :create, :show, :edit, :update], :destroy)
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, [:new, :create, :show, :edit, :update], :destroy)
+ end
+ end
+
+ def test_resource_has_show_action_but_does_not_have_destroy_action
+ with_routing do |set|
+ set.draw do
+ resources :products, only: [:show, :destroy], except: :destroy
+ end
+
+ assert_resource_allowed_routes("products", {}, { id: "1" }, :show, [:index, :new, :create, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, :show, [:index, :new, :create, :edit, :update, :destroy])
+ end
+ end
+
+ def test_singleton_resource_has_show_action_but_does_not_have_destroy_action
+ with_routing do |set|
+ set.draw do
+ resource :account, only: [:show, :destroy], except: :destroy
end
- assert_singleton_resource_allowed_routes('accounts', {}, [:new, :create, :show, :edit, :update], :destroy)
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, [:new, :create, :show, :edit, :update], :destroy)
+ assert_singleton_resource_allowed_routes("accounts", {}, :show, [:new, :create, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, :show, [:new, :create, :edit, :update, :destroy])
end
end
def test_resource_has_only_create_action_and_named_route
with_routing do |set|
set.draw do
- resources :products, :only => :create
+ resources :products, only: :create
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, :create, [:index, :new, :show, :edit, :update, :destroy])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, :create, [:index, :new, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, :create, [:index, :new, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, :create, [:index, :new, :show, :edit, :update, :destroy])
assert_not_nil set.named_routes[:products]
end
@@ -854,11 +891,11 @@ class ResourcesTest < ActionController::TestCase
def test_resource_has_only_update_action_and_named_route
with_routing do |set|
set.draw do
- resources :products, :only => :update
+ resources :products, only: :update
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, :update, [:index, :new, :create, :show, :edit, :destroy])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, :update, [:index, :new, :create, :show, :edit, :destroy])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, :update, [:index, :new, :create, :show, :edit, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, :update, [:index, :new, :create, :show, :edit, :destroy])
assert_not_nil set.named_routes[:product]
end
@@ -867,11 +904,11 @@ class ResourcesTest < ActionController::TestCase
def test_resource_has_only_destroy_action_and_named_route
with_routing do |set|
set.draw do
- resources :products, :only => :destroy
+ resources :products, only: :destroy
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, :destroy, [:index, :new, :create, :show, :edit, :update])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, :destroy, [:index, :new, :create, :show, :edit, :update])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, :destroy, [:index, :new, :create, :show, :edit, :update])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, :destroy, [:index, :new, :create, :show, :edit, :update])
assert_not_nil set.named_routes[:product]
end
@@ -880,11 +917,11 @@ class ResourcesTest < ActionController::TestCase
def test_singleton_resource_has_only_create_action_and_named_route
with_routing do |set|
set.draw do
- resource :account, :only => :create
+ resource :account, only: :create
end
- assert_singleton_resource_allowed_routes('accounts', {}, :create, [:new, :show, :edit, :update, :destroy])
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, :create, [:new, :show, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", {}, :create, [:new, :show, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, :create, [:new, :show, :edit, :update, :destroy])
assert_not_nil set.named_routes[:account]
end
@@ -893,11 +930,11 @@ class ResourcesTest < ActionController::TestCase
def test_singleton_resource_has_only_update_action_and_named_route
with_routing do |set|
set.draw do
- resource :account, :only => :update
+ resource :account, only: :update
end
- assert_singleton_resource_allowed_routes('accounts', {}, :update, [:new, :create, :show, :edit, :destroy])
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, :update, [:new, :create, :show, :edit, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", {}, :update, [:new, :create, :show, :edit, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, :update, [:new, :create, :show, :edit, :destroy])
assert_not_nil set.named_routes[:account]
end
@@ -906,11 +943,11 @@ class ResourcesTest < ActionController::TestCase
def test_singleton_resource_has_only_destroy_action_and_named_route
with_routing do |set|
set.draw do
- resource :account, :only => :destroy
+ resource :account, only: :destroy
end
- assert_singleton_resource_allowed_routes('accounts', {}, :destroy, [:new, :create, :show, :edit, :update])
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, :destroy, [:new, :create, :show, :edit, :update])
+ assert_singleton_resource_allowed_routes("accounts", {}, :destroy, [:new, :create, :show, :edit, :update])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, :destroy, [:new, :create, :show, :edit, :update])
assert_not_nil set.named_routes[:account]
end
@@ -919,120 +956,120 @@ class ResourcesTest < ActionController::TestCase
def test_resource_has_only_collection_action
with_routing do |set|
set.draw do
- resources :products, :only => [] do
- get :sale, :on => :collection
+ resources :products, only: [] do
+ get :sale, on: :collection
end
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ :controller => 'products', :action => 'sale' }, :path => 'products/sale', :method => :get)
- assert_recognizes({ :controller => 'products', :action => 'sale', :format => 'xml' }, :path => 'products/sale.xml', :method => :get)
+ assert_recognizes({ controller: "products", action: "sale" }, { path: "products/sale", method: :get })
+ assert_recognizes({ controller: "products", action: "sale", format: "xml" }, { path: "products/sale.xml", method: :get })
end
end
def test_resource_has_only_member_action
with_routing do |set|
set.draw do
- resources :products, :only => [] do
- get :preview, :on => :member
+ resources :products, only: [] do
+ get :preview, on: :member
end
end
- assert_resource_allowed_routes('products', {}, { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_resource_allowed_routes('products', { :format => 'xml' }, { :id => '1' }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", {}, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
+ assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ :controller => 'products', :action => 'preview', :id => '1' }, :path => 'products/1/preview', :method => :get)
- assert_recognizes({ :controller => 'products', :action => 'preview', :id => '1', :format => 'xml' }, :path => 'products/1/preview.xml', :method => :get)
+ assert_recognizes({ controller: "products", action: "preview", id: "1" }, { path: "products/1/preview", method: :get })
+ assert_recognizes({ controller: "products", action: "preview", id: "1", format: "xml" }, { path: "products/1/preview.xml", method: :get })
end
end
def test_singleton_resource_has_only_member_action
with_routing do |set|
set.draw do
- resource :account, :only => [] do
+ resource :account, only: [] do
member do
get :signup
end
end
end
- assert_singleton_resource_allowed_routes('accounts', {}, [], [:new, :create, :show, :edit, :update, :destroy])
- assert_singleton_resource_allowed_routes('accounts', { :format => 'xml' }, [], [:new, :create, :show, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", {}, [], [:new, :create, :show, :edit, :update, :destroy])
+ assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, [], [:new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ :controller => 'accounts', :action => 'signup' }, :path => 'account/signup', :method => :get)
- assert_recognizes({ :controller => 'accounts', :action => 'signup', :format => 'xml' }, :path => 'account/signup.xml', :method => :get)
+ assert_recognizes({ controller: "accounts", action: "signup" }, { path: "account/signup", method: :get })
+ assert_recognizes({ controller: "accounts", action: "signup", format: "xml" }, { path: "account/signup.xml", method: :get })
end
end
def test_nested_resource_has_only_show_and_member_action
with_routing do |set|
set.draw do
- resources :products, :only => [:index, :show] do
- resources :images, :only => :show do
- get :thumbnail, :on => :member
+ resources :products, only: [:index, :show] do
+ resources :images, only: :show do
+ get :thumbnail, on: :member
end
end
end
- assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
- assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, :show, [:index, :new, :create, :edit, :update, :destroy], 'products/1/images')
+ assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, :show, [:index, :new, :create, :edit, :update, :destroy], "products/1/images")
+ assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, :show, [:index, :new, :create, :edit, :update, :destroy], "products/1/images")
- assert_recognizes({ :controller => 'images', :action => 'thumbnail', :product_id => '1', :id => '2' }, :path => 'products/1/images/2/thumbnail', :method => :get)
- assert_recognizes({ :controller => 'images', :action => 'thumbnail', :product_id => '1', :id => '2', :format => 'jpg' }, :path => 'products/1/images/2/thumbnail.jpg', :method => :get)
+ assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2" }, { path: "products/1/images/2/thumbnail", method: :get })
+ assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2", format: "jpg" }, { path: "products/1/images/2/thumbnail.jpg", method: :get })
end
end
def test_nested_resource_does_not_inherit_only_option
with_routing do |set|
set.draw do
- resources :products, :only => :show do
- resources :images, :except => :destroy
+ resources :products, only: :show do
+ resources :images, except: :destroy
end
end
- assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update], :destroy, 'products/1/images')
- assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update], :destroy, 'products/1/images')
+ assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update], :destroy, "products/1/images")
+ assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update], :destroy, "products/1/images")
end
end
def test_nested_resource_does_not_inherit_only_option_by_default
with_routing do |set|
set.draw do
- resources :products, :only => :show do
+ resources :products, only: :show do
resources :images
end
end
- assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
- assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
+ assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update, :destroy], [], "products/1/images")
+ assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update, :destroy], [], "products/1/images")
end
end
def test_nested_resource_does_not_inherit_except_option
with_routing do |set|
set.draw do
- resources :products, :except => :show do
- resources :images, :only => :destroy
+ resources :products, except: :show do
+ resources :images, only: :destroy
end
end
- assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, :destroy, [:index, :new, :create, :show, :edit, :update], 'products/1/images')
- assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, :destroy, [:index, :new, :create, :show, :edit, :update], 'products/1/images')
+ assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, :destroy, [:index, :new, :create, :show, :edit, :update], "products/1/images")
+ assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, :destroy, [:index, :new, :create, :show, :edit, :update], "products/1/images")
end
end
def test_nested_resource_does_not_inherit_except_option_by_default
with_routing do |set|
set.draw do
- resources :products, :except => :show do
+ resources :products, except: :show do
resources :images
end
end
- assert_resource_allowed_routes('images', { :product_id => '1' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
- assert_resource_allowed_routes('images', { :product_id => '1', :format => 'xml' }, { :id => '2' }, [:index, :new, :create, :show, :edit, :update, :destroy], [], 'products/1/images')
+ assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update, :destroy], [], "products/1/images")
+ assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, [:index, :new, :create, :show, :edit, :update, :destroy], [], "products/1/images")
end
end
@@ -1042,8 +1079,8 @@ class ResourcesTest < ActionController::TestCase
resource :product
end
- assert_routing '/product', :controller => 'products', :action => 'show'
- assert set.recognize_path("/product", :method => :get)
+ assert_routing "/product", controller: "products", action: "show"
+ assert set.recognize_path("/product", method: :get)
end
end
@@ -1075,7 +1112,7 @@ class ResourcesTest < ActionController::TestCase
end
end
- protected
+ private
def with_restful_routing(*args)
options = args.extract_options!
collection_methods = options.delete(:collection)
@@ -1085,7 +1122,7 @@ class ResourcesTest < ActionController::TestCase
with_routing do |set|
set.draw do
- scope(path_prefix || '') do
+ scope(path_prefix || "") do
resources(*args) do
if collection_methods
collection do
@@ -1111,7 +1148,7 @@ class ResourcesTest < ActionController::TestCase
def with_singleton_resources(*args)
with_routing do |set|
- set.draw {resource(*args) }
+ set.draw { resource(*args) }
yield
end
end
@@ -1155,34 +1192,34 @@ class ResourcesTest < ActionController::TestCase
formatted_edit_member_path = "#{member_path}/#{edit_action}.xml"
with_options(route_options) do |controller|
- controller.assert_routing collection_path, :action => 'index'
- controller.assert_routing new_path, :action => 'new'
- controller.assert_routing "#{collection_path}.xml", :action => 'index', :format => 'xml'
- controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
+ controller.assert_routing collection_path, action: "index"
+ controller.assert_routing new_path, action: "new"
+ controller.assert_routing "#{collection_path}.xml", action: "index", format: "xml"
+ controller.assert_routing "#{new_path}.xml", action: "new", format: "xml"
end
with_options(options[:shallow_options]) do |controller|
- controller.assert_routing member_path, :action => 'show', :id => '1'
- controller.assert_routing edit_member_path, :action => 'edit', :id => '1'
- controller.assert_routing "#{member_path}.xml", :action => 'show', :id => '1', :format => 'xml'
- controller.assert_routing formatted_edit_member_path, :action => 'edit', :id => '1', :format => 'xml'
- end
-
- assert_recognizes(route_options.merge(:action => 'index'), :path => collection_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'new'), :path => new_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'create'), :path => collection_path, :method => :post)
- assert_recognizes(options[:shallow_options].merge(:action => 'show', :id => '1'), :path => member_path, :method => :get)
- assert_recognizes(options[:shallow_options].merge(:action => 'edit', :id => '1'), :path => edit_member_path, :method => :get)
- assert_recognizes(options[:shallow_options].merge(:action => 'update', :id => '1'), :path => member_path, :method => :put)
- assert_recognizes(options[:shallow_options].merge(:action => 'destroy', :id => '1'), :path => member_path, :method => :delete)
-
- assert_recognizes(route_options.merge(:action => 'index', :format => 'xml'), :path => "#{collection_path}.xml", :method => :get)
- assert_recognizes(route_options.merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
- assert_recognizes(route_options.merge(:action => 'create', :format => 'xml'), :path => "#{collection_path}.xml", :method => :post)
- assert_recognizes(options[:shallow_options].merge(:action => 'show', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :get)
- assert_recognizes(options[:shallow_options].merge(:action => 'edit', :id => '1', :format => 'xml'), :path => formatted_edit_member_path, :method => :get)
- assert_recognizes(options[:shallow_options].merge(:action => 'update', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :put)
- assert_recognizes(options[:shallow_options].merge(:action => 'destroy', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :delete)
+ controller.assert_routing member_path, action: "show", id: "1"
+ controller.assert_routing edit_member_path, action: "edit", id: "1"
+ controller.assert_routing "#{member_path}.xml", action: "show", id: "1", format: "xml"
+ controller.assert_routing formatted_edit_member_path, action: "edit", id: "1", format: "xml"
+ end
+
+ assert_recognizes(route_options.merge(action: "index"), path: collection_path, method: :get)
+ assert_recognizes(route_options.merge(action: "new"), path: new_path, method: :get)
+ assert_recognizes(route_options.merge(action: "create"), path: collection_path, method: :post)
+ assert_recognizes(options[:shallow_options].merge(action: "show", id: "1"), path: member_path, method: :get)
+ assert_recognizes(options[:shallow_options].merge(action: "edit", id: "1"), path: edit_member_path, method: :get)
+ assert_recognizes(options[:shallow_options].merge(action: "update", id: "1"), path: member_path, method: :put)
+ assert_recognizes(options[:shallow_options].merge(action: "destroy", id: "1"), path: member_path, method: :delete)
+
+ assert_recognizes(route_options.merge(action: "index", format: "xml"), path: "#{collection_path}.xml", method: :get)
+ assert_recognizes(route_options.merge(action: "new", format: "xml"), path: "#{new_path}.xml", method: :get)
+ assert_recognizes(route_options.merge(action: "create", format: "xml"), path: "#{collection_path}.xml", method: :post)
+ assert_recognizes(options[:shallow_options].merge(action: "show", id: "1", format: "xml"), path: "#{member_path}.xml", method: :get)
+ assert_recognizes(options[:shallow_options].merge(action: "edit", id: "1", format: "xml"), path: formatted_edit_member_path, method: :get)
+ assert_recognizes(options[:shallow_options].merge(action: "update", id: "1", format: "xml"), path: "#{member_path}.xml", method: :put)
+ assert_recognizes(options[:shallow_options].merge(action: "destroy", id: "1", format: "xml"), path: "#{member_path}.xml", method: :delete)
yield route_options if block_given?
end
@@ -1214,7 +1251,7 @@ class ResourcesTest < ActionController::TestCase
shallow_path = "/#{options[:shallow] ? options[:namespace] : options[:path_prefix]}#{path}"
full_path = "/#{options[:path_prefix]}#{path}"
name_prefix = options[:name_prefix]
- shallow_prefix = options[:shallow] ? options[:namespace].try(:gsub, /\//, '_') : options[:name_prefix]
+ shallow_prefix = options[:shallow] ? options[:namespace].try(:gsub, /\//, "_") : options[:name_prefix]
new_action = "new"
edit_action = "edit"
@@ -1224,14 +1261,14 @@ class ResourcesTest < ActionController::TestCase
end
assert_named_route "#{full_path}", "#{name_prefix}#{controller_name}_path", route_options
- assert_named_route "#{full_path}.xml", "#{name_prefix}#{controller_name}_path", route_options.merge(:format => 'xml')
- assert_named_route "#{shallow_path}/1", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1')
- assert_named_route "#{shallow_path}/1.xml", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
+ assert_named_route "#{full_path}.xml", "#{name_prefix}#{controller_name}_path", route_options.merge(format: "xml")
+ assert_named_route "#{shallow_path}/1", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(id: "1")
+ assert_named_route "#{shallow_path}/1.xml", "#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(id: "1", format: "xml")
assert_named_route "#{full_path}/#{new_action}", "new_#{name_prefix}#{singular_name}_path", route_options
- assert_named_route "#{full_path}/#{new_action}.xml", "new_#{name_prefix}#{singular_name}_path", route_options.merge(:format => 'xml')
- assert_named_route "#{shallow_path}/1/#{edit_action}", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1')
- assert_named_route "#{shallow_path}/1/#{edit_action}.xml", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(:id => '1', :format => 'xml')
+ assert_named_route "#{full_path}/#{new_action}.xml", "new_#{name_prefix}#{singular_name}_path", route_options.merge(format: "xml")
+ assert_named_route "#{shallow_path}/1/#{edit_action}", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(id: "1")
+ assert_named_route "#{shallow_path}/1/#{edit_action}.xml", "edit_#{shallow_prefix}#{singular_name}_path", options[:shallow_options].merge(id: "1", format: "xml")
yield route_options if block_given?
end
@@ -1246,27 +1283,27 @@ class ResourcesTest < ActionController::TestCase
formatted_edit_path = "#{full_path}/edit.xml"
with_options route_options do |controller|
- controller.assert_routing full_path, :action => 'show'
- controller.assert_routing new_path, :action => 'new'
- controller.assert_routing edit_path, :action => 'edit'
- controller.assert_routing "#{full_path}.xml", :action => 'show', :format => 'xml'
- controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
- controller.assert_routing formatted_edit_path, :action => 'edit', :format => 'xml'
- end
-
- assert_recognizes(route_options.merge(:action => 'show'), :path => full_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'new'), :path => new_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'edit'), :path => edit_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'create'), :path => full_path, :method => :post)
- assert_recognizes(route_options.merge(:action => 'update'), :path => full_path, :method => :put)
- assert_recognizes(route_options.merge(:action => 'destroy'), :path => full_path, :method => :delete)
-
- assert_recognizes(route_options.merge(:action => 'show', :format => 'xml'), :path => "#{full_path}.xml", :method => :get)
- assert_recognizes(route_options.merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
- assert_recognizes(route_options.merge(:action => 'edit', :format => 'xml'), :path => formatted_edit_path, :method => :get)
- assert_recognizes(route_options.merge(:action => 'create', :format => 'xml'), :path => "#{full_path}.xml", :method => :post)
- assert_recognizes(route_options.merge(:action => 'update', :format => 'xml'), :path => "#{full_path}.xml", :method => :put)
- assert_recognizes(route_options.merge(:action => 'destroy', :format => 'xml'), :path => "#{full_path}.xml", :method => :delete)
+ controller.assert_routing full_path, action: "show"
+ controller.assert_routing new_path, action: "new"
+ controller.assert_routing edit_path, action: "edit"
+ controller.assert_routing "#{full_path}.xml", action: "show", format: "xml"
+ controller.assert_routing "#{new_path}.xml", action: "new", format: "xml"
+ controller.assert_routing formatted_edit_path, action: "edit", format: "xml"
+ end
+
+ assert_recognizes(route_options.merge(action: "show"), path: full_path, method: :get)
+ assert_recognizes(route_options.merge(action: "new"), path: new_path, method: :get)
+ assert_recognizes(route_options.merge(action: "edit"), path: edit_path, method: :get)
+ assert_recognizes(route_options.merge(action: "create"), path: full_path, method: :post)
+ assert_recognizes(route_options.merge(action: "update"), path: full_path, method: :put)
+ assert_recognizes(route_options.merge(action: "destroy"), path: full_path, method: :delete)
+
+ assert_recognizes(route_options.merge(action: "show", format: "xml"), path: "#{full_path}.xml", method: :get)
+ assert_recognizes(route_options.merge(action: "new", format: "xml"), path: "#{new_path}.xml", method: :get)
+ assert_recognizes(route_options.merge(action: "edit", format: "xml"), path: formatted_edit_path, method: :get)
+ assert_recognizes(route_options.merge(action: "create", format: "xml"), path: "#{full_path}.xml", method: :post)
+ assert_recognizes(route_options.merge(action: "update", format: "xml"), path: "#{full_path}.xml", method: :put)
+ assert_recognizes(route_options.merge(action: "destroy", format: "xml"), path: "#{full_path}.xml", method: :delete)
yield route_options if block_given?
end
@@ -1283,23 +1320,23 @@ class ResourcesTest < ActionController::TestCase
name_prefix = options[:name_prefix]
assert_named_route "#{full_path}", "#{name_prefix}#{singleton_name}_path", route_options
- assert_named_route "#{full_path}.xml", "#{name_prefix}#{singleton_name}_path", route_options.merge(:format => 'xml')
+ assert_named_route "#{full_path}.xml", "#{name_prefix}#{singleton_name}_path", route_options.merge(format: "xml")
assert_named_route "#{full_path}/new", "new_#{name_prefix}#{singleton_name}_path", route_options
- assert_named_route "#{full_path}/new.xml", "new_#{name_prefix}#{singleton_name}_path", route_options.merge(:format => 'xml')
+ assert_named_route "#{full_path}/new.xml", "new_#{name_prefix}#{singleton_name}_path", route_options.merge(format: "xml")
assert_named_route "#{full_path}/edit", "edit_#{name_prefix}#{singleton_name}_path", route_options
- assert_named_route "#{full_path}/edit.xml", "edit_#{name_prefix}#{singleton_name}_path", route_options.merge(:format => 'xml')
+ assert_named_route "#{full_path}/edit.xml", "edit_#{name_prefix}#{singleton_name}_path", route_options.merge(format: "xml")
end
def assert_named_route(expected, route, options)
- actual = @controller.send(route, options) rescue $!.class.name
+ actual = @controller.send(route, options) rescue $!.class.name
assert_equal expected, actual, "Error on route: #{route}(#{options.inspect})"
end
def assert_resource_methods(expected, resource, action_method, method)
assert_equal expected.length, resource.send("#{action_method}_methods")[method].size, "#{resource.send("#{action_method}_methods")[method].inspect}"
expected.each do |action|
- assert resource.send("#{action_method}_methods")[method].include?(action)
+ assert_includes resource.send("#{action_method}_methods")[method], action,
"#{method} not in #{action_method} methods: #{resource.send("#{action_method}_methods")[method].inspect}"
end
end
@@ -1307,41 +1344,41 @@ class ResourcesTest < ActionController::TestCase
def assert_resource_allowed_routes(controller, options, shallow_options, allowed, not_allowed, path = controller)
shallow_path = "#{path}/#{shallow_options[:id]}"
format = options[:format] && ".#{options[:format]}"
- options.merge!(:controller => controller)
+ options[:controller] = controller
shallow_options.merge!(options)
- assert_whether_allowed(allowed, not_allowed, options, 'index', "#{path}#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, options, 'new', "#{path}/new#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, options, 'create', "#{path}#{format}", :post)
- assert_whether_allowed(allowed, not_allowed, shallow_options, 'show', "#{shallow_path}#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, shallow_options, 'edit', "#{shallow_path}/edit#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, shallow_options, 'update', "#{shallow_path}#{format}", :put)
- assert_whether_allowed(allowed, not_allowed, shallow_options, 'destroy', "#{shallow_path}#{format}", :delete)
+ assert_whether_allowed(allowed, not_allowed, options, "index", "#{path}#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, options, "new", "#{path}/new#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, options, "create", "#{path}#{format}", :post)
+ assert_whether_allowed(allowed, not_allowed, shallow_options, "show", "#{shallow_path}#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, shallow_options, "edit", "#{shallow_path}/edit#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, shallow_options, "update", "#{shallow_path}#{format}", :put)
+ assert_whether_allowed(allowed, not_allowed, shallow_options, "destroy", "#{shallow_path}#{format}", :delete)
end
def assert_singleton_resource_allowed_routes(controller, options, allowed, not_allowed, path = controller.singularize)
format = options[:format] && ".#{options[:format]}"
- options.merge!(:controller => controller)
+ options[:controller] = controller
- assert_whether_allowed(allowed, not_allowed, options, 'new', "#{path}/new#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, options, 'create', "#{path}#{format}", :post)
- assert_whether_allowed(allowed, not_allowed, options, 'show', "#{path}#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, options, 'edit', "#{path}/edit#{format}", :get)
- assert_whether_allowed(allowed, not_allowed, options, 'update', "#{path}#{format}", :put)
- assert_whether_allowed(allowed, not_allowed, options, 'destroy', "#{path}#{format}", :delete)
+ assert_whether_allowed(allowed, not_allowed, options, "new", "#{path}/new#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, options, "create", "#{path}#{format}", :post)
+ assert_whether_allowed(allowed, not_allowed, options, "show", "#{path}#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, options, "edit", "#{path}/edit#{format}", :get)
+ assert_whether_allowed(allowed, not_allowed, options, "update", "#{path}#{format}", :put)
+ assert_whether_allowed(allowed, not_allowed, options, "destroy", "#{path}#{format}", :delete)
end
def assert_whether_allowed(allowed, not_allowed, options, action, path, method)
action = action.to_sym
- options = options.merge(:action => action.to_s)
- path_options = { :path => path, :method => method }
+ options = options.merge(action: action.to_s)
+ path_options = { path: path, method: method }
if Array(allowed).include?(action)
assert_recognizes options, path_options
elsif Array(not_allowed).include?(action)
assert_not_recognizes options, path_options
else
- raise Assertion, 'Invalid Action has passed'
+ raise Assertion, "Invalid Action has passed"
end
end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index a39fede5b9..30f2a23b33 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -1,7 +1,9 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
-require 'active_support/core_ext/object/with_options'
-require 'active_support/core_ext/object/json'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
+require "active_support/core_ext/object/with_options"
+require "active_support/core_ext/object/json"
class MilestonesController < ActionController::Base
def index() head :ok end
@@ -15,42 +17,42 @@ class UriReservedCharactersRoutingTest < ActiveSupport::TestCase
def setup
@set = ActionDispatch::Routing::RouteSet.new
@set.draw do
- get ':controller/:action/:variable/*additional'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:variable/*additional"
+ end
end
safe, unsafe = %w(: @ & = + $ , ;), %w(^ ? # [ ])
- hex = unsafe.map { |char| '%' + char.unpack('H2').first.upcase }
+ hex = unsafe.map { |char| "%" + char.unpack1("H2").upcase }
- @segment = "#{safe.join}#{unsafe.join}".freeze
- @escaped = "#{safe.join}#{hex.join}".freeze
+ @segment = "#{safe.join}#{unsafe.join}"
+ @escaped = "#{safe.join}#{hex.join}"
end
def test_route_generation_escapes_unsafe_path_characters
assert_equal "/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2",
- url_for(@set, {
- :controller => "content",
- :action => "act#{@segment}ion",
- :variable => "var#{@segment}iable",
- :additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"]
- })
+ url_for(@set,
+ controller: "content",
+ action: "act#{@segment}ion",
+ variable: "var#{@segment}iable",
+ additional: ["add#{@segment}itional-1", "add#{@segment}itional-2"])
end
def test_route_recognition_unescapes_path_components
- options = { :controller => "content",
- :action => "act#{@segment}ion",
- :variable => "var#{@segment}iable",
- :additional => "add#{@segment}itional-1/add#{@segment}itional-2" }
+ options = { controller: "content",
+ action: "act#{@segment}ion",
+ variable: "var#{@segment}iable",
+ additional: "add#{@segment}itional-1/add#{@segment}itional-2" }
assert_equal options, @set.recognize_path("/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2")
end
def test_route_generation_allows_passing_non_string_values_to_generated_helper
assert_equal "/content/action/variable/1/2",
- url_for(@set, {
- :controller => "content",
- :action => "action",
- :variable => "variable",
- :additional => [1, 2]
- })
+ url_for(@set,
+ controller: "content",
+ action: "action",
+ variable: "variable",
+ additional: [1, 2])
end
end
@@ -84,106 +86,122 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_symbols_with_dashes
rs.draw do
- get '/:artist/:song-omg', :to => lambda { |env|
+ get "/:artist/:song-omg", to: lambda { |env|
resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters
[200, {}, [resp]]
}
end
- hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/faithfully-omg'))
- assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/faithfully-omg"))
+ assert_equal({ "artist" => "journey", "song" => "faithfully" }, hash)
+ end
+
+ def test_id_encoding
+ rs.draw do
+ get "/journey/:id", to: lambda { |env|
+ param = ActionDispatch::Request.new(env).path_parameters
+ resp = ActiveSupport::JSON.encode param
+ [200, {}, [resp]]
+ }
+ end
+
+ # The encoding of the URL in production is *binary*, so we add a
+ # .b here.
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/%E5%A4%AA%E9%83%8E".b))
+ assert_equal({ "id" => "太郎" }, hash)
+ assert_equal ::Encoding::UTF_8, hash["id"].encoding
end
def test_id_with_dash
rs.draw do
- get '/journey/:id', :to => lambda { |env|
+ get "/journey/:id", to: lambda { |env|
resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters
[200, {}, [resp]]
}
end
- hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/faithfully-omg'))
- assert_equal({"id"=>"faithfully-omg"}, hash)
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/faithfully-omg"))
+ assert_equal({ "id" => "faithfully-omg" }, hash)
end
def test_dash_with_custom_regexp
rs.draw do
- get '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env|
+ get "/:artist/:song-omg", constraints: { song: /\d+/ }, to: lambda { |env|
resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters
[200, {}, [resp]]
}
end
- hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/123-omg'))
- assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
- assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg'))
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/123-omg"))
+ assert_equal({ "artist" => "journey", "song" => "123" }, hash)
+ assert_equal "Not Found", get(URI("http://example.org/journey/faithfully-omg"))
end
def test_pre_dash
rs.draw do
- get '/:artist/omg-:song', :to => lambda { |env|
+ get "/:artist/omg-:song", to: lambda { |env|
resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters
[200, {}, [resp]]
}
end
- hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/omg-faithfully'))
- assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/omg-faithfully"))
+ assert_equal({ "artist" => "journey", "song" => "faithfully" }, hash)
end
def test_pre_dash_with_custom_regexp
rs.draw do
- get '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env|
+ get "/:artist/omg-:song", constraints: { song: /\d+/ }, to: lambda { |env|
resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters
[200, {}, [resp]]
}
end
- hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/omg-123'))
- assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
- assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully'))
+ hash = ActiveSupport::JSON.decode get(URI("http://example.org/journey/omg-123"))
+ assert_equal({ "artist" => "journey", "song" => "123" }, hash)
+ assert_equal "Not Found", get(URI("http://example.org/journey/omg-faithfully"))
end
def test_star_paths_are_greedy
rs.draw do
- get "/*path", :to => lambda { |env|
+ get "/*path", to: lambda { |env|
x = env["action_dispatch.request.path_parameters"][:path]
[200, {}, [x]]
- }, :format => false
+ }, format: false
end
- u = URI('http://example.org/foo/bar.html')
- assert_equal u.path.sub(/^\//, ''), get(u)
+ u = URI("http://example.org/foo/bar.html")
+ assert_equal u.path.sub(/^\//, ""), get(u)
end
def test_star_paths_are_greedy_but_not_too_much
rs.draw do
- get "/*path", :to => lambda { |env|
+ get "/*path", to: lambda { |env|
x = ActiveSupport::JSON.encode env["action_dispatch.request.path_parameters"]
[200, {}, [x]]
}
end
expected = { "path" => "foo/bar", "format" => "html" }
- u = URI('http://example.org/foo/bar.html')
+ u = URI("http://example.org/foo/bar.html")
assert_equal expected, ActiveSupport::JSON.decode(get(u))
end
def test_optional_star_paths_are_greedy
rs.draw do
- get "/(*filters)", :to => lambda { |env|
+ get "/(*filters)", to: lambda { |env|
x = env["action_dispatch.request.path_parameters"][:filters]
[200, {}, [x]]
- }, :format => false
+ }, format: false
end
- u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
- assert_equal u.path.sub(/^\//, ''), get(u)
+ u = URI("http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794")
+ assert_equal u.path.sub(/^\//, ""), get(u)
end
def test_optional_star_paths_are_greedy_but_not_too_much
rs.draw do
- get "/(*filters)", :to => lambda { |env|
+ get "/(*filters)", to: lambda { |env|
x = ActiveSupport::JSON.encode env["action_dispatch.request.path_parameters"]
[200, {}, [x]]
}
@@ -191,65 +209,65 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
expected = { "filters" => "ne_27.065938,-80.6092/sw_25.489856,-82",
"format" => "542794" }
- u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
+ u = URI("http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794")
assert_equal expected, ActiveSupport::JSON.decode(get(u))
end
- def test_regexp_precidence
+ def test_regexp_precedence
rs.draw do
- get '/whois/:domain', :constraints => {
- :domain => /\w+\.[\w\.]+/ },
- :to => lambda { |env| [200, {}, %w{regexp}] }
+ get "/whois/:domain", constraints: {
+ domain: /\w+\.[\w\.]+/ },
+ to: lambda { |env| [200, {}, %w{regexp}] }
- get '/whois/:id', :to => lambda { |env| [200, {}, %w{id}] }
+ get "/whois/:id", to: lambda { |env| [200, {}, %w{id}] }
end
- assert_equal 'regexp', get(URI('http://example.org/whois/example.org'))
- assert_equal 'id', get(URI('http://example.org/whois/123'))
+ assert_equal "regexp", get(URI("http://example.org/whois/example.org"))
+ assert_equal "id", get(URI("http://example.org/whois/123"))
end
def test_class_and_lambda_constraints
subdomain = Class.new {
- def matches? request
- request.subdomain.present? and request.subdomain != 'clients'
+ def matches?(request)
+ request.subdomain.present? && request.subdomain != "clients"
end
}
rs.draw do
- get '/', :constraints => subdomain.new,
- :to => lambda { |env| [200, {}, %w{default}] }
- get '/', :constraints => { :subdomain => 'clients' },
- :to => lambda { |env| [200, {}, %w{clients}] }
+ get "/", constraints: subdomain.new,
+ to: lambda { |env| [200, {}, %w{default}] }
+ get "/", constraints: { subdomain: "clients" },
+ to: lambda { |env| [200, {}, %w{clients}] }
end
- assert_equal 'default', get(URI('http://www.example.org/'))
- assert_equal 'clients', get(URI('http://clients.example.org/'))
+ assert_equal "default", get(URI("http://www.example.org/"))
+ assert_equal "clients", get(URI("http://clients.example.org/"))
end
def test_lambda_constraints
rs.draw do
- get '/', :constraints => lambda { |req|
- req.subdomain.present? and req.subdomain != "clients" },
- :to => lambda { |env| [200, {}, %w{default}] }
+ get "/", constraints: lambda { |req|
+ req.subdomain.present? && req.subdomain != "clients" },
+ to: lambda { |env| [200, {}, %w{default}] }
- get '/', :constraints => lambda { |req|
+ get "/", constraints: lambda { |req|
req.subdomain.present? && req.subdomain == "clients" },
- :to => lambda { |env| [200, {}, %w{clients}] }
+ to: lambda { |env| [200, {}, %w{clients}] }
end
- assert_equal 'default', get(URI('http://www.example.org/'))
- assert_equal 'clients', get(URI('http://clients.example.org/'))
+ assert_equal "default", get(URI("http://www.example.org/"))
+ assert_equal "clients", get(URI("http://clients.example.org/"))
end
def test_scoped_lambda
scope_called = false
rs.draw do
- scope '/foo', :constraints => lambda { |req| scope_called = true } do
- get '/', :to => lambda { |env| [200, {}, %w{default}] }
+ scope "/foo", constraints: lambda { |req| scope_called = true } do
+ get "/", to: lambda { |env| [200, {}, %w{default}] }
end
end
- assert_equal 'default', get(URI('http://www.example.org/foo/'))
+ assert_equal "default", get(URI("http://www.example.org/foo/"))
assert scope_called, "scope constraint should be called"
end
@@ -257,165 +275,174 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
inner_called = false
rs.draw do
- scope '/foo', :constraints => lambda { |req| flunk "should not be called" } do
- get '/', :constraints => lambda { |req| inner_called = true },
- :to => lambda { |env| [200, {}, %w{default}] }
+ scope "/foo", constraints: lambda { |req| flunk "should not be called" } do
+ get "/", constraints: lambda { |req| inner_called = true },
+ to: lambda { |env| [200, {}, %w{default}] }
end
end
- assert_equal 'default', get(URI('http://www.example.org/foo/'))
+ assert_equal "default", get(URI("http://www.example.org/foo/"))
assert inner_called, "inner constraint should be called"
end
def test_empty_string_match
rs.draw do
- get '/:username', :constraints => { :username => /[^\/]+/ },
- :to => lambda { |e| [200, {}, ['foo']] }
+ get "/:username", constraints: { username: /[^\/]+/ },
+ to: lambda { |e| [200, {}, ["foo"]] }
end
- assert_equal 'Not Found', get(URI('http://example.org/'))
- assert_equal 'foo', get(URI('http://example.org/hello'))
+ assert_equal "Not Found", get(URI("http://example.org/"))
+ assert_equal "foo", get(URI("http://example.org/hello"))
end
def test_non_greedy_glob_regexp
params = nil
rs.draw do
- get '/posts/:id(/*filters)', :constraints => { :filters => /.+?/ },
- :to => lambda { |e|
+ get "/posts/:id(/*filters)", constraints: { filters: /.+?/ },
+ to: lambda { |e|
params = e["action_dispatch.request.path_parameters"]
- [200, {}, ['foo']]
+ [200, {}, ["foo"]]
}
end
- assert_equal 'foo', get(URI('http://example.org/posts/1/foo.js'))
- assert_equal({:id=>"1", :filters=>"foo", :format=>"js"}, params)
+ assert_equal "foo", get(URI("http://example.org/posts/1/foo.js"))
+ assert_equal({ id: "1", filters: "foo", format: "js" }, params)
end
def test_specific_controller_action_failure
rs.draw do
- mount lambda {} => "/foo"
+ mount lambda { } => "/foo"
end
assert_raises(ActionController::UrlGenerationError) do
- url_for(rs, :controller => "omg", :action => "lol")
+ url_for(rs, controller: "omg", action: "lol")
end
end
def test_default_setup
- rs.draw { get '/:controller(/:action(/:id))' }
- assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
- assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
- assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
+ rs.draw { ActiveSupport::Deprecation.silence { get "/:controller(/:action(/:id))" } }
+ assert_equal({ controller: "content", action: "index" }, rs.recognize_path("/content"))
+ assert_equal({ controller: "content", action: "list" }, rs.recognize_path("/content/list"))
+ assert_equal({ controller: "content", action: "show", id: "10" }, rs.recognize_path("/content/show/10"))
- assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
+ assert_equal({ controller: "admin/user", action: "show", id: "10" }, rs.recognize_path("/admin/user/show/10"))
- assert_equal '/admin/user/show/10', url_for(rs, { :controller => 'admin/user', :action => 'show', :id => 10 })
+ assert_equal "/admin/user/show/10", url_for(rs, controller: "admin/user", action: "show", id: 10)
- get URI('http://test.host/admin/user/list/10')
+ get URI("http://test.host/admin/user/list/10")
- assert_equal({ :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/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 })
+ 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_route_with_colon_first
rs.draw do
- get '/:controller/:action/:id', action: 'index', id: nil
- get ':url', controller: 'content', action: 'translate'
+ ActiveSupport::Deprecation.silence do
+ get "/:controller/:action/:id", action: "index", id: nil
+ end
+
+ get ":url", controller: "content", action: "translate"
end
- assert_equal({controller: 'content', action: 'translate', url: 'example'}, rs.recognize_path('/example'))
+ assert_equal({ controller: "content", action: "translate", url: "example" }, rs.recognize_path("/example"))
end
def test_route_with_regexp_for_action
- rs.draw { get '/:controller/:action', action: /auth[-|_].+/ }
+ rs.draw { ActiveSupport::Deprecation.silence { get "/:controller/:action", action: /auth[-|_].+/ } }
- assert_equal({ action: 'auth_google', controller: 'content' }, rs.recognize_path('/content/auth_google'))
- assert_equal({ action: 'auth-facebook', controller: 'content' }, rs.recognize_path('/content/auth-facebook'))
+ assert_equal({ action: "auth_google", controller: "content" }, rs.recognize_path("/content/auth_google"))
+ assert_equal({ action: "auth-facebook", controller: "content" }, rs.recognize_path("/content/auth-facebook"))
- assert_equal '/content/auth_google', url_for(rs, { controller: "content", action: "auth_google" })
- assert_equal '/content/auth-facebook', url_for(rs, { controller: "content", action: "auth-facebook" })
+ assert_equal "/content/auth_google", url_for(rs, controller: "content", action: "auth_google")
+ assert_equal "/content/auth-facebook", url_for(rs, controller: "content", action: "auth-facebook")
end
def test_route_with_regexp_for_controller
rs.draw do
- get ':controller/:admintoken(/:action(/:id))', :controller => /admin\/.+/
- get '/:controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:admintoken(/:action(/:id))", controller: /admin\/.+/
+ get "/:controller(/:action(/:id))"
+ end
end
- assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
+ assert_equal({ controller: "admin/user", admintoken: "foo", action: "index" },
rs.recognize_path("/admin/user/foo"))
- assert_equal({:controller => "content", :action => "foo"},
+ assert_equal({ controller: "content", action: "foo" },
rs.recognize_path("/content/foo"))
- assert_equal '/admin/user/foo', url_for(rs, { :controller => "admin/user", :admintoken => "foo", :action => "index" })
- assert_equal '/content/foo', url_for(rs, { :controller => "content", :action => "foo" })
+ assert_equal "/admin/user/foo", url_for(rs, controller: "admin/user", admintoken: "foo", action: "index")
+ assert_equal "/content/foo", url_for(rs, controller: "content", action: "foo")
end
def test_route_with_regexp_and_captures_for_controller
rs.draw do
- get '/:controller(/:action(/:id))', :controller => /admin\/(accounts|users)/
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action(/:id))", controller: /admin\/(accounts|users)/
+ end
end
- assert_equal({:controller => "admin/accounts", :action => "index"}, rs.recognize_path("/admin/accounts"))
- assert_equal({:controller => "admin/users", :action => "index"}, rs.recognize_path("/admin/users"))
+ assert_equal({ controller: "admin/accounts", action: "index" }, rs.recognize_path("/admin/accounts"))
+ assert_equal({ controller: "admin/users", action: "index" }, rs.recognize_path("/admin/users"))
assert_raise(ActionController::RoutingError) { rs.recognize_path("/admin/products") }
end
def test_route_with_regexp_and_dot
rs.draw do
- get ':controller/:action/:file',
- :controller => /admin|user/,
- :action => /upload|download/,
- :defaults => {:file => nil},
- :constraints => {:file => %r{[^/]+(\.[^/]+)?}}
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:file",
+ controller: /admin|user/,
+ action: /upload|download/,
+ defaults: { file: nil },
+ constraints: { file: %r{[^/]+(\.[^/]+)?} }
+ end
end
# Without a file extension
- assert_equal '/user/download/file',
- url_for(rs, { :controller => "user", :action => "download", :file => "file" })
+ assert_equal "/user/download/file",
+ url_for(rs, controller: "user", action: "download", file: "file")
- assert_equal({:controller => "user", :action => "download", :file => "file"},
+ assert_equal({ controller: "user", action: "download", file: "file" },
rs.recognize_path("/user/download/file"))
# Now, let's try a file with an extension, really a dot (.)
- assert_equal '/user/download/file.jpg',
- url_for(rs, { :controller => "user", :action => "download", :file => "file.jpg" })
+ assert_equal "/user/download/file.jpg",
+ url_for(rs, controller: "user", action: "download", file: "file.jpg")
- assert_equal({:controller => "user", :action => "download", :file => "file.jpg"},
+ assert_equal({ controller: "user", action: "download", file: "file.jpg" },
rs.recognize_path("/user/download/file.jpg"))
end
def test_basic_named_route
rs.draw do
- root :to => 'content#list', :as => 'home'
+ root to: "content#list", as: "home"
end
assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
end
def test_named_route_with_option
rs.draw do
- get 'page/:title' => 'content#show_page', :as => 'page'
+ get "page/:title" => "content#show_page", :as => "page"
end
assert_equal("http://test.host/page/new%20stuff",
- setup_for_named_route.send(:page_url, :title => 'new stuff'))
+ setup_for_named_route.send(:page_url, title: "new stuff"))
end
def test_named_route_with_default
rs.draw do
- get 'page/:title' => 'content#show_page', :title => 'AboutPage', :as => 'page'
+ get "page/:title" => "content#show_page", :title => "AboutPage", :as => "page"
end
assert_equal("http://test.host/page/AboutRails",
- setup_for_named_route.send(:page_url, :title => "AboutRails"))
+ setup_for_named_route.send(:page_url, title: "AboutRails"))
end
def test_named_route_with_path_prefix
rs.draw do
scope "my" do
- get 'page' => 'content#show_page', :as => 'page'
+ get "page" => "content#show_page", :as => "page"
end
end
@@ -426,7 +453,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_named_route_with_blank_path_prefix
rs.draw do
scope "" do
- get 'page' => 'content#show_page', :as => 'page'
+ get "page" => "content#show_page", :as => "page"
end
end
@@ -436,7 +463,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_named_route_with_nested_controller
rs.draw do
- get 'admin/user' => 'admin/user#index', :as => "users"
+ get "admin/user" => "admin/user#index", :as => "users"
end
assert_equal("http://test.host/admin/user",
@@ -445,7 +472,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_optimised_named_route_with_host
rs.draw do
- get 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com'
+ get "page" => "content#show_page", :as => "pages", :host => "foo.com"
end
routes = setup_for_named_route
assert_equal "http://foo.com/page", routes.pages_url
@@ -457,13 +484,15 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_named_route_without_hash
rs.draw do
- get ':controller/:action/:id', :as => 'normal'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id", as: "normal"
+ end
end
end
def test_named_route_root
rs.draw do
- root :to => "hello#index"
+ root to: "hello#index"
end
routes = setup_for_named_route
assert_equal("http://test.host/", routes.send(:root_url))
@@ -507,224 +536,249 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_named_route_with_regexps
rs.draw do
- get 'page/:year/:month/:day/:title' => 'page#show', :as => 'article',
+ get "page/:year/:month/:day/:title" => "page#show", :as => "article",
:year => /\d+/, :month => /\d+/, :day => /\d+/
- get ':controller/:action/:id'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
routes = setup_for_named_route
assert_equal "http://test.host/page/2005/6/10/hi",
- routes.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
+ routes.send(:article_url, title: "hi", day: 10, year: 2005, month: 6)
end
def test_changing_controller
- rs.draw { get ':controller/:action/:id' }
+ rs.draw { ActiveSupport::Deprecation.silence { get ":controller/:action/:id" } }
- get URI('http://test.host/admin/user/index/10')
+ get URI("http://test.host/admin/user/index/10")
- assert_equal '/admin/stuff/show/10',
- controller.url_for({:controller => 'stuff', :action => 'show', :id => 10, :only_path => true})
+ assert_equal "/admin/stuff/show/10",
+ controller.url_for(controller: "stuff", action: "show", id: 10, only_path: true)
end
def test_paths_escaped
rs.draw do
- get 'file/*path' => 'content#show_file', :as => 'path'
- get ':controller/:action/:id'
+ get "file/*path" => "content#show_file", :as => "path"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
# No + to space in URI escaping, only for query params.
results = rs.recognize_path "/file/hello+world/how+are+you%3F"
assert results, "Recognition should have succeeded"
- assert_equal 'hello+world/how+are+you?', results[:path]
+ assert_equal "hello+world/how+are+you?", results[:path]
# Use %20 for space instead.
results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
assert results, "Recognition should have succeeded"
- assert_equal 'hello world/how are you?', results[:path]
+ assert_equal "hello world/how are you?", results[:path]
end
def test_paths_slashes_unescaped_with_ordered_parameters
rs.draw do
- get '/file/*path' => 'content#index', :as => 'path'
+ get "/file/*path" => "content#index", :as => "path"
end
# No / to %2F in URI, only for query params.
- assert_equal("/file/hello/world", setup_for_named_route.send(:path_path, ['hello', 'world']))
+ assert_equal("/file/hello/world", setup_for_named_route.send(:path_path, ["hello", "world"]))
end
def test_non_controllers_cannot_be_matched
rs.draw do
- get ':controller/:action/:id'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
assert_raise(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
end
def test_should_list_options_diff_when_routing_constraints_dont_match
rs.draw do
- get 'post/:id' => 'post#show', :constraints => { :id => /\d+/ }, :as => 'post'
+ get "post/:id" => "post#show", :constraints => { id: /\d+/ }, :as => "post"
end
assert_raise(ActionController::UrlGenerationError) do
- url_for(rs, { :controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post" })
+ url_for(rs, controller: "post", action: "show", bad_param: "foo", use_route: "post")
end
end
def test_dynamic_path_allowed
rs.draw do
- get '*path' => 'content#show_file'
+ get "*path" => "content#show_file"
end
- assert_equal '/pages/boo',
- url_for(rs, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
+ assert_equal "/pages/boo",
+ url_for(rs, controller: "content", action: "show_file", path: %w(pages boo))
end
def test_dynamic_recall_paths_allowed
rs.draw do
- get '*path' => 'content#show_file'
+ get "*path" => "content#show_file"
end
- get URI('http://test.host/pages/boo')
- assert_equal({:controller=>"content", :action=>"show_file", :path=>"pages/boo"},
+ 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',
- controller.url_for(:only_path => true)
+ assert_equal "/pages/boo",
+ controller.url_for(only_path: true)
end
def test_backwards
rs.draw do
- get 'page/:id(/:action)' => 'pages#show'
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get "page/:id(/:action)" => "pages#show"
+ get ":controller(/:action(/:id))"
+ end
end
- 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' })
+ 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
- def test_route_with_fixnum_default
+ def test_route_with_integer_default
rs.draw do
- get 'page(/:id)' => 'content#show_page', :id => 1
- get ':controller/:action/:id'
+ get "page(/:id)" => "content#show_page", :id => 1
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page' })
- assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 1 })
- assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => '1' })
- assert_equal '/page/10', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 10 })
+ assert_equal "/page", url_for(rs, controller: "content", action: "show_page")
+ assert_equal "/page", url_for(rs, controller: "content", action: "show_page", id: 1)
+ assert_equal "/page", url_for(rs, controller: "content", action: "show_page", id: "1")
+ assert_equal "/page/10", url_for(rs, controller: "content", action: "show_page", id: 10)
- assert_equal({:controller => "content", :action => 'show_page', :id => 1 }, rs.recognize_path("/page"))
- assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
- assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
+ assert_equal({ controller: "content", action: "show_page", id: 1 }, rs.recognize_path("/page"))
+ assert_equal({ controller: "content", action: "show_page", id: "1" }, rs.recognize_path("/page/1"))
+ assert_equal({ controller: "content", action: "show_page", id: "10" }, rs.recognize_path("/page/10"))
end
# For newer revision
def test_route_with_text_default
rs.draw do
- get 'page/:id' => 'content#show_page', :id => 1
- get ':controller/:action/:id'
+ get "page/:id" => "content#show_page", :id => 1
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/page/foo', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 'foo' })
- assert_equal({ :controller => "content", :action => 'show_page', :id => 'foo' }, rs.recognize_path("/page/foo"))
+ assert_equal "/page/foo", url_for(rs, controller: "content", action: "show_page", id: "foo")
+ assert_equal({ controller: "content", action: "show_page", id: "foo" }, rs.recognize_path("/page/foo"))
- token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in Russian
+ token = +"\321\202\320\265\320\272\321\201\321\202" # 'text' in Russian
token.force_encoding(Encoding::BINARY)
- escaped_token = CGI::escape(token)
+ escaped_token = CGI.escape(token)
- assert_equal '/page/' + escaped_token, url_for(rs, { :controller => 'content', :action => 'show_page', :id => token })
- assert_equal({ :controller => "content", :action => 'show_page', :id => token }, rs.recognize_path("/page/#{escaped_token}"))
+ assert_equal "/page/" + escaped_token, url_for(rs, controller: "content", action: "show_page", id: token)
+ assert_equal({ controller: "content", action: "show_page", id: token }, rs.recognize_path("/page/#{escaped_token}"))
end
def test_action_expiry
- rs.draw { get ':controller(/:action(/:id))' }
- get URI('http://test.host/content/show')
- assert_equal '/content', controller.url_for(:controller => 'content', :only_path => true)
+ rs.draw { ActiveSupport::Deprecation.silence { get ":controller(/:action(/:id))" } }
+ 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
rs.draw do
- get 'post/:id' => 'post#show', :constraints => {:id => /\d+/}, :as => 'post'
+ get "post/:id" => "post#show", :constraints => { id: /\d+/ }, :as => "post"
end
- assert_equal '/post/10', url_for(rs, { :controller => 'post', :action => 'show', :id => 10 })
+ assert_equal "/post/10", url_for(rs, controller: "post", action: "show", id: 10)
assert_raise(ActionController::UrlGenerationError) do
- url_for(rs, { :controller => 'post', :action => 'show' })
+ url_for(rs, controller: "post", action: "show")
end
end
def test_both_requirement_and_optional
rs.draw do
- get('test(/:year)' => 'post#show', :as => 'blog',
- :defaults => { :year => nil },
- :constraints => { :year => /\d{4}/ }
+ get("test(/:year)" => "post#show", :as => "blog",
+ :defaults => { year: nil },
+ :constraints => { year: /\d{4}/ }
)
- get ':controller/:action/:id'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show' })
- assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show', :year => nil })
+ assert_equal "/test", url_for(rs, controller: "post", action: "show")
+ assert_equal "/test", url_for(rs, controller: "post", action: "show", year: nil)
assert_equal("http://test.host/test", setup_for_named_route.send(:blog_url))
end
def test_set_to_nil_forgets
rs.draw do
- get 'pages(/:year(/:month(/:day)))' => 'content#list_pages', :month => nil, :day => nil
- get ':controller/:action/:id'
+ get "pages(/:year(/:month(/:day)))" => "content#list_pages", :month => nil, :day => nil
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/pages/2005',
- url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005 })
- assert_equal '/pages/2005/6',
- url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6 })
- assert_equal '/pages/2005/6/12',
- url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12 })
+ assert_equal "/pages/2005",
+ url_for(rs, controller: "content", action: "list_pages", year: 2005)
+ assert_equal "/pages/2005/6",
+ url_for(rs, controller: "content", action: "list_pages", year: 2005, month: 6)
+ 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' },
+ 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',
- controller.url_for({ :day => 4, :only_path => true })
+ assert_equal "/pages/2005/6/4",
+ controller.url_for(day: 4, only_path: true)
- assert_equal '/pages/2005/6',
- controller.url_for({ :day => nil, :only_path => true })
+ assert_equal "/pages/2005/6",
+ controller.url_for(day: nil, only_path: true)
- assert_equal '/pages/2005',
- controller.url_for({ :day => nil, :month => nil, :only_path => true })
+ assert_equal "/pages/2005",
+ controller.url_for(day: nil, month: nil, only_path: true)
end
def test_root_url_generation_with_controller_and_action
rs.draw do
- root :to => "content#index"
+ root to: "content#index"
end
- assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
- assert_equal '/', url_for(rs, { :controller => 'content' })
+ assert_equal "/", url_for(rs, controller: "content", action: "index")
+ assert_equal "/", url_for(rs, controller: "content")
end
def test_named_root_url_generation_with_controller_and_action
rs.draw do
- root :to => "content#index", :as => 'home'
+ root to: "content#index", as: "home"
end
- assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
- assert_equal '/', url_for(rs, { :controller => 'content' })
+ assert_equal "/", url_for(rs, controller: "content", action: "index")
+ assert_equal "/", url_for(rs, controller: "content")
assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
end
def test_named_route_method
rs.draw do
- get 'categories' => 'content#categories', :as => 'categories'
- get ':controller(/:action(/:id))'
+ get "categories" => "content#categories", :as => "categories"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
- assert_equal '/categories', url_for(rs, { :controller => 'content', :action => 'categories' })
- assert_equal '/content/hi', url_for(rs, { :controller => 'content', :action => 'hi' })
+ assert_equal "/categories", url_for(rs, controller: "content", action: "categories")
+ assert_equal "/content/hi", url_for(rs, controller: "content", action: "hi")
end
def test_named_routes_array
@@ -734,52 +788,56 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_nil_defaults
rs.draw do
- get 'journal' => 'content#list_journal',
+ get "journal" => "content#list_journal",
:date => nil, :user_id => nil
- get ':controller/:action/:id'
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/journal', url_for(rs, {
- :controller => 'content',
- :action => 'list_journal',
- :date => nil,
- :user_id => nil
- })
+ assert_equal "/journal", url_for(rs,
+ controller: "content",
+ action: "list_journal",
+ date: nil,
+ user_id: nil)
end
def setup_request_method_routes_for(method)
rs.draw do
- match '/match' => "books##{method}", :via => method.to_sym
+ match "/match" => "books##{method}", :via => method.to_sym
end
end
%w(GET PATCH POST PUT DELETE).each do |request_method|
define_method("test_request_method_recognized_with_#{request_method}") do
setup_request_method_routes_for(request_method.downcase)
- params = rs.recognize_path("/match", :method => request_method)
+ params = rs.recognize_path("/match", method: request_method)
assert_equal request_method.downcase, params[:action]
end
end
def test_recognize_array_of_methods
rs.draw do
- match '/match' => 'books#get_or_post', :via => [:get, :post]
- put '/match' => 'books#not_get_or_post'
+ match "/match" => "books#get_or_post", :via => [:get, :post]
+ put "/match" => "books#not_get_or_post"
end
- params = rs.recognize_path("/match", :method => :post)
- assert_equal 'get_or_post', params[:action]
+ params = rs.recognize_path("/match", method: :post)
+ assert_equal "get_or_post", params[:action]
- params = rs.recognize_path("/match", :method => :put)
- assert_equal 'not_get_or_post', params[:action]
+ params = rs.recognize_path("/match", method: :put)
+ assert_equal "not_get_or_post", params[:action]
end
def test_subpath_recognized
rs.draw do
- get '/books/:id/edit' => 'subpath_books#edit'
- get '/items/:id/:action' => 'subpath_books'
- get '/posts/new/:action' => 'subpath_books'
- get '/posts/:id' => 'subpath_books#show'
+ ActiveSupport::Deprecation.silence do
+ get "/books/:id/edit" => "subpath_books#edit"
+ get "/items/:id/:action" => "subpath_books"
+ get "/posts/new/:action" => "subpath_books"
+ get "/posts/:id" => "subpath_books#show"
+ end
end
hash = rs.recognize_path "/books/17/edit"
@@ -801,19 +859,21 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_subpath_generated
rs.draw do
- get '/books/:id/edit' => 'subpath_books#edit'
- get '/items/:id/:action' => 'subpath_books'
- get '/posts/new/:action' => 'subpath_books'
+ ActiveSupport::Deprecation.silence do
+ get "/books/:id/edit" => "subpath_books#edit"
+ get "/items/:id/:action" => "subpath_books"
+ get "/posts/new/:action" => "subpath_books"
+ end
end
- assert_equal "/books/7/edit", url_for(rs, { :controller => "subpath_books", :id => 7, :action => "edit" })
- assert_equal "/items/15/complete", url_for(rs, { :controller => "subpath_books", :id => 15, :action => "complete" })
- assert_equal "/posts/new/preview", url_for(rs, { :controller => "subpath_books", :action => "preview" })
+ assert_equal "/books/7/edit", url_for(rs, controller: "subpath_books", id: 7, action: "edit")
+ assert_equal "/items/15/complete", url_for(rs, controller: "subpath_books", id: 15, action: "complete")
+ assert_equal "/posts/new/preview", url_for(rs, controller: "subpath_books", action: "preview")
end
def test_failed_constraints_raises_exception_with_violated_constraints
rs.draw do
- get 'foos/:id' => 'foos#show', :as => 'foo_with_requirement', :constraints => { :id => /\d+/ }
+ get "foos/:id" => "foos#show", :as => "foo_with_requirement", :constraints => { id: /\d+/ }
end
assert_raise(ActionController::UrlGenerationError) do
@@ -824,11 +884,14 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
def test_routes_changed_correctly_after_clear
rs = ::ActionDispatch::Routing::RouteSet.new
rs.draw do
- get 'ca' => 'ca#aa'
- get 'cb' => 'cb#ab'
- get 'cc' => 'cc#ac'
- get ':controller/:action/:id'
- get ':controller/:action/:id.:format'
+ get "ca" => "ca#aa"
+ get "cb" => "cb#ab"
+ get "cc" => "cc#ac"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ get ":controller/:action/:id.:format"
+ end
end
hash = rs.recognize_path "/cc"
@@ -837,10 +900,13 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
assert_equal %w(cc ac), [hash[:controller], hash[:action]]
rs.draw do
- get 'cb' => 'cb#ab'
- get 'cc' => 'cc#ac'
- get ':controller/:action/:id'
- get ':controller/:action/:id.:format'
+ get "cb" => "cb#ab"
+ get "cc" => "cc#ac"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ get ":controller/:action/:id.:format"
+ end
end
hash = rs.recognize_path "/cc"
@@ -871,57 +937,65 @@ class RouteSetTest < ActiveSupport::TestCase
@default_route_set ||= begin
set = ActionDispatch::Routing::RouteSet.new
set.draw do
- get '/:controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action(/:id))"
+ end
end
set
end
end
def test_generate_extras
- set.draw { get ':controller/(:action(/:id))' }
- path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller/(:action(/:id))" } }
+ path, extras = set.generate_extras(controller: "foo", action: "bar", id: 15, this: "hello", that: "world")
assert_equal "/foo/bar/15", path
assert_equal %w(that this), extras.map(&:to_s).sort
end
def test_extra_keys
- set.draw { get ':controller/:action/:id' }
- extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller/:action/:id" } }
+ extras = set.extra_keys(controller: "foo", action: "bar", id: 15, this: "hello", that: "world")
assert_equal %w(that this), extras.map(&:to_s).sort
end
def test_generate_extras_not_first
set.draw do
- get ':controller/:action/:id.:format'
- get ':controller/:action/:id'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id.:format"
+ get ":controller/:action/:id"
+ end
end
- path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ path, extras = set.generate_extras(controller: "foo", action: "bar", id: 15, this: "hello", that: "world")
assert_equal "/foo/bar/15", path
assert_equal %w(that this), extras.map(&:to_s).sort
end
def test_generate_not_first
set.draw do
- get ':controller/:action/:id.:format'
- get ':controller/:action/:id'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id.:format"
+ get ":controller/:action/:id"
+ end
end
assert_equal "/foo/bar/15?this=hello",
- url_for(set, { :controller => "foo", :action => "bar", :id => 15, :this => "hello" })
+ url_for(set, controller: "foo", action: "bar", id: 15, this: "hello")
end
def test_extra_keys_not_first
set.draw do
- get ':controller/:action/:id.:format'
- get ':controller/:action/:id'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id.:format"
+ get ":controller/:action/:id"
+ end
end
- extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
+ extras = set.extra_keys(controller: "foo", action: "bar", id: 15, this: "hello", that: "world")
assert_equal %w(that this), extras.map(&:to_s).sort
end
def test_draw
assert_equal 0, set.routes.size
set.draw do
- get '/hello/world' => 'a#b'
+ get "/hello/world" => "a#b"
end
assert_equal 1, set.routes.size
end
@@ -929,16 +1003,16 @@ class RouteSetTest < ActiveSupport::TestCase
def test_draw_symbol_controller_name
assert_equal 0, set.routes.size
set.draw do
- get '/users/index' => 'users#index'
+ get "/users/index" => "users#index"
end
- set.recognize_path('/users/index', :method => :get)
+ set.recognize_path("/users/index", method: :get)
assert_equal 1, set.routes.size
end
def test_named_draw
assert_equal 0, set.routes.size
set.draw do
- get '/hello/world' => 'a#b', :as => 'hello'
+ get "/hello/world" => "a#b", :as => "hello"
end
assert_equal 1, set.routes.size
assert_equal set.routes.first, set.named_routes[:hello]
@@ -947,57 +1021,57 @@ class RouteSetTest < ActiveSupport::TestCase
def test_duplicate_named_route_raises_rather_than_pick_precedence
assert_raise ArgumentError do
set.draw do
- get '/hello/world' => 'a#b', :as => 'hello'
- get '/hello' => 'a#b', :as => 'hello'
+ get "/hello/world" => "a#b", :as => "hello"
+ get "/hello" => "a#b", :as => "hello"
end
end
end
def setup_named_route_test
set.draw do
- get '/people(/:id)' => 'people#show', :as => 'show'
- get '/people' => 'people#index', :as => 'index'
- get '/people/go/:foo/:bar/joe(/:id)' => 'people#multi', :as => 'multi'
- get '/admin/users' => 'admin/users#index', :as => "users"
+ get "/people(/:id)" => "people#show", :as => "show"
+ get "/people" => "people#index", :as => "index"
+ get "/people/go/:foo/:bar/joe(/:id)" => "people#multi", :as => "multi"
+ get "/admin/users" => "admin/users#index", :as => "users"
end
- get URI('http://test.host/people')
+ get URI("http://test.host/people")
controller
end
def test_named_route_url_method
controller = setup_named_route_test
- assert_equal "http://test.host/people/5", controller.send(:show_url, :id => 5)
- assert_equal "/people/5", controller.send(:show_path, :id => 5)
+ assert_equal "http://test.host/people/5", controller.send(:show_url, id: 5)
+ assert_equal "/people/5", controller.send(:show_path, id: 5)
assert_equal "http://test.host/people", controller.send(:index_url)
assert_equal "/people", controller.send(:index_path)
assert_equal "http://test.host/admin/users", controller.send(:users_url)
- assert_equal '/admin/users', controller.send(:users_path)
+ assert_equal "/admin/users", controller.send(:users_path)
end
def test_named_route_url_method_with_anchor
controller = setup_named_route_test
- assert_equal "http://test.host/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
- assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
+ assert_equal "http://test.host/people/5#location", controller.send(:show_url, id: 5, anchor: "location")
+ assert_equal "/people/5#location", controller.send(:show_path, id: 5, anchor: "location")
- assert_equal "http://test.host/people#location", controller.send(:index_url, :anchor => 'location')
- assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
+ assert_equal "http://test.host/people#location", controller.send(:index_url, anchor: "location")
+ assert_equal "/people#location", controller.send(:index_path, anchor: "location")
- assert_equal "http://test.host/admin/users#location", controller.send(:users_url, :anchor => 'location')
- assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
+ assert_equal "http://test.host/admin/users#location", controller.send(:users_url, anchor: "location")
+ assert_equal "/admin/users#location", controller.send(:users_path, anchor: "location")
assert_equal "http://test.host/people/go/7/hello/joe/5#location",
- controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
+ controller.send(:multi_url, 7, "hello", 5, anchor: "location")
assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar#location",
- controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
+ controller.send(:multi_url, 7, "hello", 5, baz: "bar", anchor: "location")
assert_equal "http://test.host/people?baz=bar#location",
- controller.send(:index_url, :baz => "bar", :anchor => 'location')
+ controller.send(:index_url, baz: "bar", anchor: "location")
assert_equal "http://test.host/people", controller.send(:index_url, anchor: nil)
assert_equal "http://test.host/people", controller.send(:index_url, anchor: false)
@@ -1005,17 +1079,17 @@ class RouteSetTest < ActiveSupport::TestCase
def test_named_route_url_method_with_port
controller = setup_named_route_test
- assert_equal "http://test.host:8080/people/5", controller.send(:show_url, 5, :port=>8080)
+ assert_equal "http://test.host:8080/people/5", controller.send(:show_url, 5, port: 8080)
end
def test_named_route_url_method_with_host
controller = setup_named_route_test
- assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
+ assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, host: "some.example.com")
end
def test_named_route_url_method_with_protocol
controller = setup_named_route_test
- assert_equal "https://test.host/people/5", controller.send(:show_url, 5, :protocol => "https")
+ assert_equal "https://test.host/people/5", controller.send(:show_url, 5, protocol: "https")
end
def test_named_route_url_method_with_ordered_parameters
@@ -1027,7 +1101,7 @@ class RouteSetTest < ActiveSupport::TestCase
def test_named_route_url_method_with_ordered_parameters_and_hash
controller = setup_named_route_test
assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar",
- controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
+ controller.send(:multi_url, 7, "hello", 5, baz: "bar")
end
def test_named_route_url_method_with_ordered_parameters_and_empty_hash
@@ -1039,41 +1113,46 @@ class RouteSetTest < ActiveSupport::TestCase
def test_named_route_url_method_with_no_positional_arguments
controller = setup_named_route_test
assert_equal "http://test.host/people?baz=bar",
- controller.send(:index_url, :baz => "bar")
+ controller.send(:index_url, baz: "bar")
end
def test_draw_default_route
set.draw do
- get '/:controller/:action/:id'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
assert_equal 1, set.routes.size
- assert_equal '/users/show/10', url_for(set, { :controller => 'users', :action => 'show', :id => 10 })
- assert_equal '/users/index/10', url_for(set, { :controller => 'users', :id => 10 })
+ assert_equal "/users/show/10", url_for(set, controller: "users", action: "show", id: 10)
+ assert_equal "/users/index/10", url_for(set, controller: "users", id: 10)
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
+ assert_equal({ controller: "users", action: "index", id: "10" }, set.recognize_path("/users/index/10"))
+ assert_equal({ controller: "users", action: "index", id: "10" }, set.recognize_path("/users/index/10/"))
end
def test_route_with_parameter_shell
set.draw do
- get 'page/:id' => 'pages#show', :id => /\d+/
- get '/:controller(/:action(/:id))'
+ get "page/:id" => "pages#show", :id => /\d+/
+
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action(/:id))"
+ end
end
- 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: "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'}, request_path_params('/pages/show/10'))
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/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
assert_nothing_raised do
set.draw do
- get 'page/:id' => 'pages#show', :constraints => { :host => /^foo$/ }
+ get "page/:id" => "pages#show", :constraints => { host: /^foo$/ }
end
end
end
@@ -1081,27 +1160,27 @@ class RouteSetTest < ActiveSupport::TestCase
def test_route_constraints_with_anchor_chars_are_invalid
assert_raise ArgumentError do
set.draw do
- get 'page/:id' => 'pages#show', :id => /^\d+/
+ get "page/:id" => "pages#show", :id => /^\d+/
end
end
assert_raise ArgumentError do
set.draw do
- get 'page/:id' => 'pages#show', :id => /\A\d+/
+ get "page/:id" => "pages#show", :id => /\A\d+/
end
end
assert_raise ArgumentError do
set.draw do
- get 'page/:id' => 'pages#show', :id => /\d+$/
+ get "page/:id" => "pages#show", :id => /\d+$/
end
end
assert_raise ArgumentError do
set.draw do
- get 'page/:id' => 'pages#show', :id => /\d+\Z/
+ get "page/:id" => "pages#show", :id => /\d+\Z/
end
end
assert_raise ArgumentError do
set.draw do
- get 'page/:id' => 'pages#show', :id => /\d+\z/
+ get "page/:id" => "pages#show", :id => /\d+\z/
end
end
end
@@ -1109,7 +1188,7 @@ class RouteSetTest < ActiveSupport::TestCase
def test_route_constraints_with_options_method_condition_is_valid
assert_nothing_raised do
set.draw do
- match 'valid/route' => 'pages#show', :via => :options
+ match "valid/route" => "pages#show", :via => :options
end
end
end
@@ -1119,16 +1198,16 @@ class RouteSetTest < ActiveSupport::TestCase
get "/people" => "missing#index"
end
- assert_raises(ActionController::RoutingError) { request_path_params '/people' }
+ assert_raises(ActionController::RoutingError) { request_path_params "/people" }
end
def test_recognize_with_encoded_id_and_regex
set.draw do
- get 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/
+ get "page/:id" => "pages#show", :id => /[a-zA-Z0-9\+]+/
end
- 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'))
+ 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
@@ -1141,65 +1220,65 @@ class RouteSetTest < ActiveSupport::TestCase
delete "/people/:id" => "people#destroy"
end
- params = request_path_params("/people", :method => :get)
+ params = request_path_params("/people", method: :get)
assert_equal("index", params[:action])
- params = request_path_params("/people", :method => :post)
+ params = request_path_params("/people", method: :post)
assert_equal("create", params[:action])
- params = request_path_params("/people/5", :method => :put)
+ params = request_path_params("/people/5", method: :put)
assert_equal("update", params[:action])
- params = request_path_params("/people/5", :method => :patch)
+ params = request_path_params("/people/5", method: :patch)
assert_equal("update", params[:action])
assert_raise(ActionController::UnknownHttpMethod) {
- request_path_params("/people", :method => :bacon)
+ request_path_params("/people", method: :bacon)
}
- params = request_path_params("/people/5", :method => :get)
+ params = request_path_params("/people/5", method: :get)
assert_equal("show", params[:action])
assert_equal("5", params[:id])
- params = request_path_params("/people/5", :method => :put)
+ params = request_path_params("/people/5", method: :put)
assert_equal("update", params[:action])
assert_equal("5", params[:id])
- params = request_path_params("/people/5", :method => :patch)
+ params = request_path_params("/people/5", method: :patch)
assert_equal("update", params[:action])
assert_equal("5", params[:id])
- params = request_path_params("/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) {
- request_path_params("/people/5", :method => :post)
+ request_path_params("/people/5", method: :post)
}
end
def test_recognize_with_alias_in_conditions
set.draw do
- match "/people" => 'people#index', :as => 'people', :via => :get
- root :to => "people#index"
+ match "/people" => "people#index", :as => "people", :via => :get
+ root to: "people#index"
end
- params = request_path_params("/people", :method => :get)
+ params = request_path_params("/people", method: :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
- params = request_path_params("/", :method => :get)
+ params = request_path_params("/", method: :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
end
def test_typo_recognition
set.draw do
- get 'articles/:year/:month/:day/:title' => 'articles#permalink',
+ get "articles/:year/:month/:day/:title" => "articles#permalink",
:year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
end
- params = request_path_params("/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])
@@ -1208,14 +1287,14 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_routing_traversal_does_not_load_extra_classes
- assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
+ assert_not Object.const_defined?("Profiler__"), "Profiler should not be loaded"
set.draw do
- get '/profile' => 'profile#index'
+ get "/profile" => "profile#index"
end
request_path_params("/profile") rescue nil
- assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
+ assert_not Object.const_defined?("Profiler__"), "Profiler should not be loaded"
end
def test_recognize_with_conditions_and_format
@@ -1226,17 +1305,17 @@ class RouteSetTest < ActiveSupport::TestCase
get "people/:id(.:format)" => "people#show"
end
- params = request_path_params("/people/5", :method => :get)
+ params = request_path_params("/people/5", method: :get)
assert_equal("show", params[:action])
assert_equal("5", params[:id])
- params = request_path_params("/people/5", :method => :put)
+ params = request_path_params("/people/5", method: :put)
assert_equal("update", params[:action])
- params = request_path_params("/people/5", :method => :patch)
+ params = request_path_params("/people/5", method: :patch)
assert_equal("update", params[:action])
- params = request_path_params("/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])
@@ -1244,68 +1323,66 @@ class RouteSetTest < ActiveSupport::TestCase
def test_generate_with_default_action
set.draw do
- get "/people", :controller => "people", :action => "index"
- get "/people/list", :controller => "people", :action => "list"
+ get "/people", controller: "people", action: "index"
+ get "/people/list", controller: "people", action: "list"
end
- url = url_for(set, { :controller => "people", :action => "list" })
+ url = url_for(set, controller: "people", action: "list")
assert_equal "/people/list", url
end
def test_root_map
- set.draw { root :to => 'people#index' }
+ set.draw { root to: "people#index" }
- params = request_path_params("", :method => :get)
+ params = request_path_params("", method: :get)
assert_equal("people", params[:controller])
assert_equal("index", params[:action])
end
def test_namespace
set.draw do
-
- namespace 'api' do
- get 'inventory' => 'products#inventory'
+ namespace "api" do
+ get "inventory" => "products#inventory"
end
-
end
- params = request_path_params("/api/inventory", :method => :get)
+ params = request_path_params("/api/inventory", method: :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
def test_namespaced_root_map
set.draw do
- namespace 'api' do
- root :to => 'products#index'
+ namespace "api" do
+ root to: "products#index"
end
end
- params = request_path_params("/api", :method => :get)
+ params = request_path_params("/api", method: :get)
assert_equal("api/products", params[:controller])
assert_equal("index", params[:action])
end
def test_namespace_with_path_prefix
set.draw do
- scope :module => "api", :path => "prefix" do
- get 'inventory' => 'products#inventory'
+ scope module: "api", path: "prefix" do
+ get "inventory" => "products#inventory"
end
end
- params = request_path_params("/prefix/inventory", :method => :get)
+ params = request_path_params("/prefix/inventory", method: :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
def test_namespace_with_blank_path_prefix
set.draw do
- scope :module => "api", :path => "" do
- get 'inventory' => 'products#inventory'
+ scope module: "api", path: "" do
+ get "inventory" => "products#inventory"
end
end
- params = request_path_params("/inventory", :method => :get)
+ params = request_path_params("/inventory", method: :get)
assert_equal("api/products", params[:controller])
assert_equal("inventory", params[:action])
end
@@ -1314,33 +1391,38 @@ class RouteSetTest < ActiveSupport::TestCase
@set = make_set false
set.draw do
- get ':controller/:id/:action'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:id/:action"
+ end
end
- get URI('http://test.host/people/7/show')
+ get URI("http://test.host/people/7/show")
- assert_equal "/people/7/destroy", controller.url_for(:action => 'destroy', :only_path => true)
+ 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'
+ get "about" => "welcome#about"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:id/:action"
+ end
end
- get URI('http://test.host/welcom/get/7')
+ get URI("http://test.host/welcom/get/7")
- assert_equal "/about", controller.url_for(:controller => 'welcome',
- :action => 'about',
- :only_path => true)
+ assert_equal "/about", controller.url_for(controller: "welcome",
+ action: "about",
+ only_path: true)
end
def test_generate
- set.draw { get ':controller/:action/:id' }
+ set.draw { ActiveSupport::Deprecation.silence { get ":controller/:action/:id" } }
- args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
+ args = { controller: "foo", action: "bar", id: "7", x: "y" }
assert_equal "/foo/bar/7?x=y", url_for(set, args)
assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
assert_equal [:x], set.extra_keys(args)
@@ -1349,22 +1431,26 @@ class RouteSetTest < ActiveSupport::TestCase
def test_generate_with_path_prefix
set.draw do
scope "my" do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
- args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
+ args = { controller: "foo", action: "bar", id: "7", x: "y" }
assert_equal "/my/foo/bar/7?x=y", url_for(set, args)
end
def test_generate_with_blank_path_prefix
set.draw do
scope "" do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
- args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
+ args = { controller: "foo", action: "bar", id: "7", x: "y" }
assert_equal "/foo/bar/7?x=y", url_for(set, args)
end
@@ -1372,19 +1458,21 @@ class RouteSetTest < ActiveSupport::TestCase
@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'
+ ActiveSupport::Deprecation.silence do
+ get "/connection/manage(/:action)" => "connection/manage#index"
+ get "/connection/connection" => "connection/connection#index"
+ get "/connection" => "connection#index", :as => "family_connection"
+ end
end
- assert_equal({ :controller => 'connection/manage',
- :action => 'index', }, request_path_params('/connection/manage'))
+ assert_equal({ controller: "connection/manage",
+ action: "index", }, request_path_params("/connection/manage"))
- url = controller.url_for({ :controller => "connection", :only_path => true })
+ url = controller.url_for(controller: "connection", only_path: true)
assert_equal "/connection/connection", url
- url = controller.url_for({ :use_route => "family_connection",
- :controller => "connection", :only_path => true })
+ url = controller.url_for(use_route: "family_connection",
+ controller: "connection", only_path: true)
assert_equal "/connection", url
end
@@ -1392,71 +1480,76 @@ class RouteSetTest < ActiveSupport::TestCase
@set = make_set false
set.draw do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
- get URI('http://test.host/books/show/10')
+ get URI("http://test.host/books/show/10")
- assert_equal '/books', controller.url_for(:controller => 'books',
- :only_path => true,
- :action => 'index')
+ 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))'
+ get "show_weblog/:parameter" => "weblog#show"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
- get URI('http://test.host/weblog/show/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})
+ assert_equal "/weblog/edit?parameter=1", controller.url_for(
+ action: "edit", parameter: 1, only_path: true)
end
def test_format_is_not_inherit
set.draw do
- get '/posts(.:format)' => 'posts#index'
+ get "/posts(.:format)" => "posts#index"
end
- get URI('http://test.host/posts.xml')
- assert_equal({: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", controller.url_for(
+ controller: "posts", only_path: true)
- assert_equal '/posts.xml', controller.url_for(
- {:controller => 'posts', :format => 'xml', :only_path => true})
+ 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' }
+ set.draw { ActiveSupport::Deprecation.silence { get "projects/:project_id/:controller/:action" } }
- get URI('http://test.host/projects/1/weblog/show')
+ get URI("http://test.host/projects/1/weblog/show")
assert_equal(
- { :controller => 'weblog', :action => 'show', :project_id => '1' },
+ { 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 })
+ 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
set.draw do
resources :projects do
member do
- get 'milestones' => 'milestones#index', :as => 'milestones'
+ get "milestones" => "milestones#index", :as => "milestones"
end
end
end
- params = set.recognize_path("/projects/1/milestones", :method => :get)
+ params = set.recognize_path("/projects/1/milestones", method: :get)
assert_equal("milestones", params[:controller])
assert_equal("index", params[:action])
end
@@ -1465,7 +1558,7 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised do
set.draw do
namespace :admin do
- root :to => "home#index"
+ root to: "home#index"
end
end
end
@@ -1474,8 +1567,8 @@ class RouteSetTest < ActiveSupport::TestCase
def test_setting_root_in_namespace_using_string
assert_nothing_raised do
set.draw do
- namespace 'admin' do
- root :to => "home#index"
+ namespace "admin" do
+ root to: "home#index"
end
end
end
@@ -1484,8 +1577,8 @@ class RouteSetTest < ActiveSupport::TestCase
def test_route_constraints_with_unsupported_regexp_options_must_error
assert_raise ArgumentError do
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => { :name => /(david|jamis)/m }
+ get "page/:name" => "pages#show",
+ :constraints => { name: /(david|jamis)/m }
end
end
end
@@ -1493,14 +1586,14 @@ class RouteSetTest < ActiveSupport::TestCase
def test_route_constraints_with_supported_options_must_not_error
assert_nothing_raised do
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => { :name => /(david|jamis)/i }
+ get "page/:name" => "pages#show",
+ :constraints => { name: /(david|jamis)/i }
end
end
assert_nothing_raised do
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => { :name => / # Desperately overcommented regexp
+ get "page/:name" => "pages#show",
+ :constraints => { name: / # Desperately overcommented regexp
( #Either
david #The Creator
| #Or
@@ -1513,235 +1606,243 @@ class RouteSetTest < ActiveSupport::TestCase
def test_route_with_subdomain_and_constraints_must_receive_params
name_param = nil
set.draw do
- get 'page/:name' => 'pages#show', :constraints => lambda {|request|
+ get "page/:name" => "pages#show", :constraints => lambda { |request|
name_param = request.params[:name]
return true
}
end
- assert_equal({:controller => 'pages', :action => 'show', :name => 'mypage'},
- set.recognize_path('http://subdomain.example.org/page/mypage'))
- assert_equal(name_param, 'mypage')
+ assert_equal({ controller: "pages", action: "show", name: "mypage" },
+ set.recognize_path("http://subdomain.example.org/page/mypage"))
+ assert_equal(name_param, "mypage")
end
def test_route_requirement_recognize_with_ignore_case
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => {:name => /(david|jamis)/i}
+ get "page/:name" => "pages#show",
+ :constraints => { name: /(david|jamis)/i }
end
- assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
+ assert_equal({ controller: "pages", action: "show", name: "jamis" }, set.recognize_path("/page/jamis"))
assert_raise ActionController::RoutingError do
- set.recognize_path('/page/davidjamis')
+ set.recognize_path("/page/davidjamis")
end
- assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID'))
+ assert_equal({ controller: "pages", action: "show", name: "DAVID" }, set.recognize_path("/page/DAVID"))
end
def test_route_requirement_generate_with_ignore_case
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => {:name => /(david|jamis)/i}
+ get "page/:name" => "pages#show",
+ :constraints => { name: /(david|jamis)/i }
end
- url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'david' })
+ url = url_for(set, controller: "pages", action: "show", name: "david")
assert_equal "/page/david", url
assert_raise(ActionController::UrlGenerationError) do
- url_for(set, { :controller => 'pages', :action => 'show', :name => 'davidjamis' })
+ url_for(set, controller: "pages", action: "show", name: "davidjamis")
end
- url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'JAMIS' })
+ url = url_for(set, controller: "pages", action: "show", name: "JAMIS")
assert_equal "/page/JAMIS", url
end
def test_route_requirement_recognize_with_extended_syntax
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => {:name => / # Desperately overcommented regexp
+ get "page/:name" => "pages#show",
+ :constraints => { name: / # Desperately overcommented regexp
( #Either
david #The Creator
| #Or
jamis #The Deployer
- )/x}
+ )/x }
end
- assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
- assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david'))
+ assert_equal({ controller: "pages", action: "show", name: "jamis" }, set.recognize_path("/page/jamis"))
+ assert_equal({ controller: "pages", action: "show", name: "david" }, set.recognize_path("/page/david"))
assert_raise ActionController::RoutingError do
- set.recognize_path('/page/david #The Creator')
+ set.recognize_path("/page/david #The Creator")
end
assert_raise ActionController::RoutingError do
- set.recognize_path('/page/David')
+ set.recognize_path("/page/David")
end
end
def test_route_requirement_with_xi_modifiers
set.draw do
- get 'page/:name' => 'pages#show',
- :constraints => {:name => / # Desperately overcommented regexp
+ get "page/:name" => "pages#show",
+ :constraints => { name: / # Desperately overcommented regexp
( #Either
david #The Creator
| #Or
jamis #The Deployer
- )/xi}
+ )/xi }
end
- assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'},
- set.recognize_path('/page/JAMIS'))
+ assert_equal({ controller: "pages", action: "show", name: "JAMIS" },
+ set.recognize_path("/page/JAMIS"))
assert_equal "/page/JAMIS",
- url_for(set, { :controller => 'pages', :action => 'show', :name => 'JAMIS' })
+ url_for(set, controller: "pages", action: "show", name: "JAMIS")
end
def test_routes_with_symbols
set.draw do
- get 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol
- get 'named' , :controller => :pages, :action => :show, :name => :as_symbol, :as => :named
+ get "unnamed", controller: :pages, action: :show, name: :as_symbol
+ get "named", controller: :pages, action: :show, name: :as_symbol, as: :named
end
- assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/unnamed'))
- assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named'))
+ assert_equal({ controller: "pages", action: "show", name: :as_symbol }, set.recognize_path("/unnamed"))
+ assert_equal({ controller: "pages", action: "show", name: :as_symbol }, set.recognize_path("/named"))
end
def test_regexp_chunk_should_add_question_mark_for_optionals
set.draw do
- get '/' => 'foo#index'
- get '/hello' => 'bar#index'
+ get "/" => "foo#index"
+ get "/hello" => "bar#index"
end
- assert_equal '/', url_for(set, { :controller => 'foo' })
- assert_equal '/hello', url_for(set, { :controller => 'bar' })
+ assert_equal "/", url_for(set, controller: "foo")
+ assert_equal "/hello", url_for(set, controller: "bar")
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/'))
- assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello'))
+ assert_equal({ controller: "foo", action: "index" }, set.recognize_path("/"))
+ assert_equal({ controller: "bar", action: "index" }, set.recognize_path("/hello"))
end
def test_assign_route_options_with_anchor_chars
set.draw do
- get '/cars/:action/:person/:car/', :controller => 'cars'
+ ActiveSupport::Deprecation.silence do
+ get "/cars/:action/:person/:car/", controller: "cars"
+ end
end
- assert_equal '/cars/buy/1/2', url_for(set, { :controller => 'cars', :action => 'buy', :person => '1', :car => '2' })
+ assert_equal "/cars/buy/1/2", url_for(set, controller: "cars", action: "buy", person: "1", car: "2")
- assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2'))
+ assert_equal({ controller: "cars", action: "buy", person: "1", car: "2" }, set.recognize_path("/cars/buy/1/2"))
end
def test_segmentation_of_dot_path
set.draw do
- get '/books/:action.rss', :controller => 'books'
+ ActiveSupport::Deprecation.silence do
+ get "/books/:action.rss", controller: "books"
+ end
end
- assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list' })
+ assert_equal "/books/list.rss", url_for(set, controller: "books", action: "list")
- assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss'))
+ assert_equal({ controller: "books", action: "list" }, set.recognize_path("/books/list.rss"))
end
def test_segmentation_of_dynamic_dot_path
set.draw do
- get '/books(/:action(.:format))', :controller => 'books'
+ ActiveSupport::Deprecation.silence do
+ get "/books(/:action(.:format))", controller: "books"
+ end
end
- assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list', :format => 'rss' })
- assert_equal '/books/list.xml', url_for(set, { :controller => 'books', :action => 'list', :format => 'xml' })
- assert_equal '/books/list', url_for(set, { :controller => 'books', :action => 'list' })
- assert_equal '/books', url_for(set, { :controller => 'books', :action => 'index' })
+ assert_equal "/books/list.rss", url_for(set, controller: "books", action: "list", format: "rss")
+ assert_equal "/books/list.xml", url_for(set, controller: "books", action: "list", format: "xml")
+ assert_equal "/books/list", url_for(set, controller: "books", action: "list")
+ assert_equal "/books", url_for(set, controller: "books", action: "index")
- assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss'))
- assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml'))
- assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list'))
- assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books'))
+ assert_equal({ controller: "books", action: "list", format: "rss" }, set.recognize_path("/books/list.rss"))
+ assert_equal({ controller: "books", action: "list", format: "xml" }, set.recognize_path("/books/list.xml"))
+ assert_equal({ controller: "books", action: "list" }, set.recognize_path("/books/list"))
+ assert_equal({ controller: "books", action: "index" }, set.recognize_path("/books"))
end
def test_slashes_are_implied
- set.draw { get("/:controller(/:action(/:id))") }
+ set.draw { ActiveSupport::Deprecation.silence { get("/:controller(/:action(/:id))") } }
- assert_equal '/content', url_for(set, { :controller => 'content', :action => 'index' })
- assert_equal '/content/list', url_for(set, { :controller => 'content', :action => 'list' })
- assert_equal '/content/show/1', url_for(set, { :controller => 'content', :action => 'show', :id => '1' })
+ assert_equal "/content", url_for(set, controller: "content", action: "index")
+ assert_equal "/content/list", url_for(set, controller: "content", action: "list")
+ assert_equal "/content/show/1", url_for(set, controller: "content", action: "show", id: "1")
- assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content'))
- assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content/index'))
- assert_equal({:controller => "content", :action => "list"}, set.recognize_path('/content/list'))
- assert_equal({:controller => "content", :action => "show", :id => "1"}, set.recognize_path('/content/show/1'))
+ assert_equal({ controller: "content", action: "index" }, set.recognize_path("/content"))
+ assert_equal({ controller: "content", action: "index" }, set.recognize_path("/content/index"))
+ assert_equal({ controller: "content", action: "list" }, set.recognize_path("/content/list"))
+ assert_equal({ controller: "content", action: "show", id: "1" }, set.recognize_path("/content/show/1"))
end
def test_default_route_recognition
- expected = {:controller => 'pages', :action => 'show', :id => '10'}
- assert_equal expected, default_route_set.recognize_path('/pages/show/10')
- assert_equal expected, default_route_set.recognize_path('/pages/show/10/')
+ expected = { controller: "pages", action: "show", id: "10" }
+ assert_equal expected, default_route_set.recognize_path("/pages/show/10")
+ assert_equal expected, default_route_set.recognize_path("/pages/show/10/")
- expected[:id] = 'jamis'
- assert_equal expected, default_route_set.recognize_path('/pages/show/jamis/')
+ expected[:id] = "jamis"
+ assert_equal expected, default_route_set.recognize_path("/pages/show/jamis/")
expected.delete :id
- assert_equal expected, default_route_set.recognize_path('/pages/show')
- assert_equal expected, default_route_set.recognize_path('/pages/show/')
+ assert_equal expected, default_route_set.recognize_path("/pages/show")
+ assert_equal expected, default_route_set.recognize_path("/pages/show/")
- expected[:action] = 'index'
- assert_equal expected, default_route_set.recognize_path('/pages/')
- assert_equal expected, default_route_set.recognize_path('/pages')
+ expected[:action] = "index"
+ assert_equal expected, default_route_set.recognize_path("/pages/")
+ assert_equal expected, default_route_set.recognize_path("/pages")
- assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/') }
- assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/pages/how/goood/it/is/to/be/free') }
+ assert_raise(ActionController::RoutingError) { default_route_set.recognize_path("/") }
+ assert_raise(ActionController::RoutingError) { default_route_set.recognize_path("/pages/how/goood/it/is/to/be/free") }
end
def test_default_route_should_omit_default_action
- assert_equal '/accounts', url_for(default_route_set, { :controller => 'accounts', :action => 'index' })
+ assert_equal "/accounts", url_for(default_route_set, controller: "accounts", action: "index")
end
def test_default_route_should_include_default_action_when_id_present
- assert_equal '/accounts/index/20', url_for(default_route_set, { :controller => 'accounts', :action => 'index', :id => '20' })
+ assert_equal "/accounts/index/20", url_for(default_route_set, controller: "accounts", action: "index", id: "20")
end
def test_default_route_should_work_with_action_but_no_id
- assert_equal '/accounts/list_all', url_for(default_route_set, { :controller => 'accounts', :action => 'list_all' })
+ assert_equal "/accounts/list_all", url_for(default_route_set, controller: "accounts", action: "list_all")
end
def test_default_route_should_uri_escape_pluses
- expected = { :controller => 'pages', :action => 'show', :id => 'hello world' }
- assert_equal expected, default_route_set.recognize_path('/pages/show/hello%20world')
- assert_equal '/pages/show/hello%20world', url_for(default_route_set, expected)
+ expected = { controller: "pages", action: "show", id: "hello world" }
+ assert_equal expected, default_route_set.recognize_path("/pages/show/hello%20world")
+ assert_equal "/pages/show/hello%20world", url_for(default_route_set, expected)
- expected[:id] = 'hello+world'
- assert_equal expected, default_route_set.recognize_path('/pages/show/hello+world')
- assert_equal expected, default_route_set.recognize_path('/pages/show/hello%2Bworld')
- assert_equal '/pages/show/hello+world', url_for(default_route_set, expected)
+ expected[:id] = "hello+world"
+ assert_equal expected, default_route_set.recognize_path("/pages/show/hello+world")
+ assert_equal expected, default_route_set.recognize_path("/pages/show/hello%2Bworld")
+ assert_equal "/pages/show/hello+world", url_for(default_route_set, expected)
end
def test_build_empty_query_string
- assert_uri_equal '/foo', url_for(default_route_set, { :controller => 'foo' })
+ assert_uri_equal "/foo", url_for(default_route_set, controller: "foo")
end
def test_build_query_string_with_nil_value
- assert_uri_equal '/foo', url_for(default_route_set, { :controller => 'foo', :x => nil })
+ assert_uri_equal "/foo", url_for(default_route_set, controller: "foo", x: nil)
end
def test_simple_build_query_string
- assert_uri_equal '/foo?x=1&y=2', url_for(default_route_set, { :controller => 'foo', :x => '1', :y => '2' })
+ assert_uri_equal "/foo?x=1&y=2", url_for(default_route_set, controller: "foo", x: "1", y: "2")
end
def test_convert_ints_build_query_string
- assert_uri_equal '/foo?x=1&y=2', url_for(default_route_set, { :controller => 'foo', :x => 1, :y => 2 })
+ assert_uri_equal "/foo?x=1&y=2", url_for(default_route_set, controller: "foo", x: 1, y: 2)
end
def test_escape_spaces_build_query_string
- assert_uri_equal '/foo?x=hello+world&y=goodbye+world', url_for(default_route_set, { :controller => 'foo', :x => 'hello world', :y => 'goodbye world' })
+ assert_uri_equal "/foo?x=hello+world&y=goodbye+world", url_for(default_route_set, controller: "foo", x: "hello world", y: "goodbye world")
end
def test_expand_array_build_query_string
- assert_uri_equal '/foo?x%5B%5D=1&x%5B%5D=2', url_for(default_route_set, { :controller => 'foo', :x => [1, 2] })
+ assert_uri_equal "/foo?x%5B%5D=1&x%5B%5D=2", url_for(default_route_set, controller: "foo", x: [1, 2])
end
def test_escape_spaces_build_query_string_selected_keys
- assert_uri_equal '/foo?x=hello+world', url_for(default_route_set, { :controller => 'foo', :x => 'hello world' })
+ assert_uri_equal "/foo?x=hello+world", url_for(default_route_set, controller: "foo", x: "hello world")
end
def test_generate_with_default_params
set.draw do
- get 'dummy/page/:page' => 'dummy#show'
- get 'dummy/dots/page.:page' => 'dummy#dots'
- get 'ibocorp(/:page)' => 'ibocorp#show',
- :constraints => { :page => /\d+/ },
- :defaults => { :page => 1 }
-
- get ':controller/:action/:id'
+ get "dummy/page/:page" => "dummy#show"
+ get "dummy/dots/page.:page" => "dummy#dots"
+ get "ibocorp(/:page)" => "ibocorp#show",
+ :constraints => { page: /\d+/ },
+ :defaults => { page: 1 }
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
- assert_equal '/ibocorp', url_for(set, { :controller => 'ibocorp', :action => "show", :page => 1 })
+ assert_equal "/ibocorp", url_for(set, controller: "ibocorp", action: "show", page: 1)
end
include ActionDispatch::RoutingVerbs
@@ -1752,17 +1853,21 @@ class RouteSetTest < ActiveSupport::TestCase
@set = make_set false
set.draw do
- get "blog/", :controller => "blog", :action => "index"
+ get "blog/", controller: "blog", action: "index"
get "blog(/:year(/:month(/:day)))",
- :controller => "blog",
- :action => "show_date",
- :constraints => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/ },
- :day => nil, :month => nil
+ controller: "blog",
+ action: "show_date",
+ constraints: { year: /(19|20)\d\d/, month: /[01]?\d/, day: /[0-3]?\d/ },
+ day: nil, month: nil
- get "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/
- get "blog/:controller/:action(/:id)"
- get "*anything", :controller => "blog", :action => "unknown_request"
+ get "blog/show/:id", controller: "blog", action: "show", id: /\d+/
+
+ ActiveSupport::Deprecation.silence do
+ get "blog/:controller/:action(/:id)"
+ end
+
+ get "*anything", controller: "blog", action: "unknown_request"
end
recognize_path = ->(path) {
@@ -1770,24 +1875,24 @@ class RouteSetTest < ActiveSupport::TestCase
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"))
+ 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')
+ get URI("http://example.org/blog/2006/07/28")
- 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 }))
+ 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
@@ -1796,8 +1901,8 @@ class RouteSetTest < ActiveSupport::TestCase
end
def sort_query_string_params(uri)
- path, qs = uri.split('?')
- qs = qs.split('&').sort.join('&') if qs
+ path, qs = uri.split("?")
+ qs = qs.split("&").sort.join("&") if qs
qs ? "#{path}?#{qs}" : path
end
end
@@ -1812,52 +1917,59 @@ class RackMountIntegrationTests < ActiveSupport::TestCase
resources :users, :posts
end
- namespace 'api' do
- root :to => 'users#index'
+ namespace "api" do
+ root to: "users#index"
end
- get '/blog(/:year(/:month(/:day)))' => 'posts#show_date',
+ get "/blog(/:year(/:month(/:day)))" => "posts#show_date",
:constraints => {
- :year => /(19|20)\d\d/,
- :month => /[01]?\d/,
- :day => /[0-3]?\d/
+ year: /(19|20)\d\d/,
+ month: /[01]?\d/,
+ day: /[0-3]?\d/
},
:day => nil,
:month => nil
- get 'archive/:year', :controller => 'archive', :action => 'index',
- :defaults => { :year => nil },
- :constraints => { :year => /\d{4}/ },
- :as => "blog"
+ get "archive/:year", controller: "archive", action: "index",
+ defaults: { year: nil },
+ constraints: { year: /\d{4}/ },
+ as: "blog"
resources :people
- get 'legacy/people' => "people#index", :legacy => "true"
-
- get 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol
- get 'id_default(/:id)' => "foo#id_default", :id => 1
- match 'get_or_post' => "foo#get_or_post", :via => [:get, :post]
- get 'optional/:optional' => "posts#index"
- get 'projects/:project_id' => "project#index", :as => "project"
- get 'clients' => "projects#index"
-
- get 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i
- get 'extended/geocode/:postalcode' => 'geocode#show',:constraints => {
- :postalcode => /# Postcode format
+ get "legacy/people" => "people#index", :legacy => "true"
+
+ get "symbols", controller: :symbols, action: :show, name: :as_symbol
+ get "id_default(/:id)" => "foo#id_default", :id => 1
+ match "get_or_post" => "foo#get_or_post", :via => [:get, :post]
+ get "optional/:optional" => "posts#index"
+ get "projects/:project_id" => "project#index", :as => "project"
+ get "clients" => "projects#index"
+
+ get "ignorecase/geocode/:postalcode" => "geocode#show", :postalcode => /hx\d\d-\d[a-z]{2}/i
+ get "extended/geocode/:postalcode" => "geocode#show", :constraints => {
+ postalcode: /# Postcode format
\d{5} #Prefix
(-\d{4})? #Suffix
/x
}, :as => "geocode"
- get 'news(.:format)' => "news#index"
+ get "news(.:format)" => "news#index"
+
+ ActiveSupport::Deprecation.silence do
+ get "comment/:id(/:action)" => "comments#show"
+ get "ws/:controller(/:action(/:id))", ws: true
+ get "account(/:action)" => "account#subscription"
+ get "pages/:page_id/:controller(/:action(/:id))"
+ get ":controller/ping", action: "ping"
+ end
+
+ get "こんにちは/世界", controller: "news", action: "index"
+
+ ActiveSupport::Deprecation.silence do
+ match ":controller(/:action(/:id))(.:format)", via: :all
+ end
- get 'comment/:id(/:action)' => "comments#show"
- get 'ws/:controller(/:action(/:id))', :ws => true
- get 'account(/:action)' => "account#subscription"
- get 'pages/:page_id/:controller(/:action(/:id))'
- get ':controller/ping', :action => 'ping'
- get 'こんにちは/世界', :controller => 'news', :action => 'index'
- match ':controller(/:action(/:id))(.:format)', :via => :all
- root :to => "news#index"
+ root to: "news#index"
}
attr_reader :routes
@@ -1869,118 +1981,118 @@ class RackMountIntegrationTests < ActiveSupport::TestCase
end
def test_recognize_path
- assert_equal({:controller => 'admin/users', :action => 'index'}, @routes.recognize_path('/admin/users', :method => :get))
- assert_equal({:controller => 'admin/users', :action => 'create'}, @routes.recognize_path('/admin/users', :method => :post))
- assert_equal({:controller => 'admin/users', :action => 'new'}, @routes.recognize_path('/admin/users/new', :method => :get))
- assert_equal({:controller => 'admin/users', :action => 'show', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :get))
- assert_equal({:controller => 'admin/users', :action => 'update', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :put))
- assert_equal({:controller => 'admin/users', :action => 'destroy', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :delete))
- assert_equal({:controller => 'admin/users', :action => 'edit', :id => '1'}, @routes.recognize_path('/admin/users/1/edit', :method => :get))
-
- assert_equal({:controller => 'admin/posts', :action => 'index'}, @routes.recognize_path('/admin/posts', :method => :get))
- assert_equal({:controller => 'admin/posts', :action => 'new'}, @routes.recognize_path('/admin/posts/new', :method => :get))
-
- assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api', :method => :get))
- assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api/', :method => :get))
-
- assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => nil, :day => nil }, @routes.recognize_path('/blog/2009', :method => :get))
- assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => nil }, @routes.recognize_path('/blog/2009/01', :method => :get))
- assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => '01'}, @routes.recognize_path('/blog/2009/01/01', :method => :get))
-
- assert_equal({:controller => 'archive', :action => 'index', :year => '2010'}, @routes.recognize_path('/archive/2010'))
- assert_equal({:controller => 'archive', :action => 'index'}, @routes.recognize_path('/archive'))
-
- assert_equal({:controller => 'people', :action => 'index'}, @routes.recognize_path('/people', :method => :get))
- assert_equal({:controller => 'people', :action => 'index', :format => 'xml'}, @routes.recognize_path('/people.xml', :method => :get))
- assert_equal({:controller => 'people', :action => 'create'}, @routes.recognize_path('/people', :method => :post))
- assert_equal({:controller => 'people', :action => 'new'}, @routes.recognize_path('/people/new', :method => :get))
- assert_equal({:controller => 'people', :action => 'show', :id => '1'}, @routes.recognize_path('/people/1', :method => :get))
- assert_equal({:controller => 'people', :action => 'show', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1.xml', :method => :get))
- assert_equal({:controller => 'people', :action => 'update', :id => '1'}, @routes.recognize_path('/people/1', :method => :put))
- assert_equal({:controller => 'people', :action => 'destroy', :id => '1'}, @routes.recognize_path('/people/1', :method => :delete))
- assert_equal({:controller => 'people', :action => 'edit', :id => '1'}, @routes.recognize_path('/people/1/edit', :method => :get))
- assert_equal({:controller => 'people', :action => 'edit', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1/edit.xml', :method => :get))
-
- assert_equal({:controller => 'symbols', :action => 'show', :name => :as_symbol}, @routes.recognize_path('/symbols'))
- assert_equal({:controller => 'foo', :action => 'id_default', :id => '1'}, @routes.recognize_path('/id_default/1'))
- assert_equal({:controller => 'foo', :action => 'id_default', :id => '2'}, @routes.recognize_path('/id_default/2'))
- assert_equal({:controller => 'foo', :action => 'id_default', :id => 1 }, @routes.recognize_path('/id_default'))
- assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :get))
- assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :post))
- assert_raise(ActionController::RoutingError) { @routes.recognize_path('/get_or_post', :method => :put) }
- assert_raise(ActionController::RoutingError) { @routes.recognize_path('/get_or_post', :method => :delete) }
-
- assert_equal({:controller => 'posts', :action => 'index', :optional => 'bar'}, @routes.recognize_path('/optional/bar'))
- assert_raise(ActionController::RoutingError) { @routes.recognize_path('/optional') }
-
- assert_equal({:controller => 'posts', :action => 'show', :id => '1', :ws => true}, @routes.recognize_path('/ws/posts/show/1', :method => :get))
- assert_equal({:controller => 'posts', :action => 'list', :ws => true}, @routes.recognize_path('/ws/posts/list', :method => :get))
- assert_equal({:controller => 'posts', :action => 'index', :ws => true}, @routes.recognize_path('/ws/posts', :method => :get))
-
- assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account', :method => :get))
- assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account/subscription', :method => :get))
- assert_equal({:controller => 'account', :action => 'billing'}, @routes.recognize_path('/account/billing', :method => :get))
-
- assert_equal({:page_id => '1', :controller => 'notes', :action => 'index'}, @routes.recognize_path('/pages/1/notes', :method => :get))
- assert_equal({:page_id => '1', :controller => 'notes', :action => 'list'}, @routes.recognize_path('/pages/1/notes/list', :method => :get))
- assert_equal({:page_id => '1', :controller => 'notes', :action => 'show', :id => '2'}, @routes.recognize_path('/pages/1/notes/show/2', :method => :get))
-
- assert_equal({:controller => 'posts', :action => 'ping'}, @routes.recognize_path('/posts/ping', :method => :get))
- assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts', :method => :get))
- assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts/index', :method => :get))
- assert_equal({:controller => 'posts', :action => 'show'}, @routes.recognize_path('/posts/show', :method => :get))
- assert_equal({:controller => 'posts', :action => 'show', :id => '1'}, @routes.recognize_path('/posts/show/1', :method => :get))
- assert_equal({:controller => 'posts', :action => 'create'}, @routes.recognize_path('/posts/create', :method => :post))
-
- assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1az'}, @routes.recognize_path('/ignorecase/geocode/hx12-1az'))
- assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1AZ'}, @routes.recognize_path('/ignorecase/geocode/hx12-1AZ'))
- assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345-1234'}, @routes.recognize_path('/extended/geocode/12345-1234'))
- assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345'}, @routes.recognize_path('/extended/geocode/12345'))
-
- assert_equal({:controller => 'news', :action => 'index' }, @routes.recognize_path('/', :method => :get))
- assert_equal({:controller => 'news', :action => 'index', :format => 'rss'}, @routes.recognize_path('/news.rss', :method => :get))
-
- assert_raise(ActionController::RoutingError) { @routes.recognize_path('/none', :method => :get) }
+ assert_equal({ controller: "admin/users", action: "index" }, @routes.recognize_path("/admin/users", method: :get))
+ assert_equal({ controller: "admin/users", action: "create" }, @routes.recognize_path("/admin/users", method: :post))
+ assert_equal({ controller: "admin/users", action: "new" }, @routes.recognize_path("/admin/users/new", method: :get))
+ assert_equal({ controller: "admin/users", action: "show", id: "1" }, @routes.recognize_path("/admin/users/1", method: :get))
+ assert_equal({ controller: "admin/users", action: "update", id: "1" }, @routes.recognize_path("/admin/users/1", method: :put))
+ assert_equal({ controller: "admin/users", action: "destroy", id: "1" }, @routes.recognize_path("/admin/users/1", method: :delete))
+ assert_equal({ controller: "admin/users", action: "edit", id: "1" }, @routes.recognize_path("/admin/users/1/edit", method: :get))
+
+ assert_equal({ controller: "admin/posts", action: "index" }, @routes.recognize_path("/admin/posts", method: :get))
+ assert_equal({ controller: "admin/posts", action: "new" }, @routes.recognize_path("/admin/posts/new", method: :get))
+
+ assert_equal({ controller: "api/users", action: "index" }, @routes.recognize_path("/api", method: :get))
+ assert_equal({ controller: "api/users", action: "index" }, @routes.recognize_path("/api/", method: :get))
+
+ assert_equal({ controller: "posts", action: "show_date", year: "2009", month: nil, day: nil }, @routes.recognize_path("/blog/2009", method: :get))
+ assert_equal({ controller: "posts", action: "show_date", year: "2009", month: "01", day: nil }, @routes.recognize_path("/blog/2009/01", method: :get))
+ assert_equal({ controller: "posts", action: "show_date", year: "2009", month: "01", day: "01" }, @routes.recognize_path("/blog/2009/01/01", method: :get))
+
+ assert_equal({ controller: "archive", action: "index", year: "2010" }, @routes.recognize_path("/archive/2010"))
+ assert_equal({ controller: "archive", action: "index" }, @routes.recognize_path("/archive"))
+
+ assert_equal({ controller: "people", action: "index" }, @routes.recognize_path("/people", method: :get))
+ assert_equal({ controller: "people", action: "index", format: "xml" }, @routes.recognize_path("/people.xml", method: :get))
+ assert_equal({ controller: "people", action: "create" }, @routes.recognize_path("/people", method: :post))
+ assert_equal({ controller: "people", action: "new" }, @routes.recognize_path("/people/new", method: :get))
+ assert_equal({ controller: "people", action: "show", id: "1" }, @routes.recognize_path("/people/1", method: :get))
+ assert_equal({ controller: "people", action: "show", id: "1", format: "xml" }, @routes.recognize_path("/people/1.xml", method: :get))
+ assert_equal({ controller: "people", action: "update", id: "1" }, @routes.recognize_path("/people/1", method: :put))
+ assert_equal({ controller: "people", action: "destroy", id: "1" }, @routes.recognize_path("/people/1", method: :delete))
+ assert_equal({ controller: "people", action: "edit", id: "1" }, @routes.recognize_path("/people/1/edit", method: :get))
+ assert_equal({ controller: "people", action: "edit", id: "1", format: "xml" }, @routes.recognize_path("/people/1/edit.xml", method: :get))
+
+ assert_equal({ controller: "symbols", action: "show", name: :as_symbol }, @routes.recognize_path("/symbols"))
+ assert_equal({ controller: "foo", action: "id_default", id: "1" }, @routes.recognize_path("/id_default/1"))
+ assert_equal({ controller: "foo", action: "id_default", id: "2" }, @routes.recognize_path("/id_default/2"))
+ assert_equal({ controller: "foo", action: "id_default", id: 1 }, @routes.recognize_path("/id_default"))
+ assert_equal({ controller: "foo", action: "get_or_post" }, @routes.recognize_path("/get_or_post", method: :get))
+ assert_equal({ controller: "foo", action: "get_or_post" }, @routes.recognize_path("/get_or_post", method: :post))
+ assert_raise(ActionController::RoutingError) { @routes.recognize_path("/get_or_post", method: :put) }
+ assert_raise(ActionController::RoutingError) { @routes.recognize_path("/get_or_post", method: :delete) }
+
+ assert_equal({ controller: "posts", action: "index", optional: "bar" }, @routes.recognize_path("/optional/bar"))
+ assert_raise(ActionController::RoutingError) { @routes.recognize_path("/optional") }
+
+ assert_equal({ controller: "posts", action: "show", id: "1", ws: true }, @routes.recognize_path("/ws/posts/show/1", method: :get))
+ assert_equal({ controller: "posts", action: "list", ws: true }, @routes.recognize_path("/ws/posts/list", method: :get))
+ assert_equal({ controller: "posts", action: "index", ws: true }, @routes.recognize_path("/ws/posts", method: :get))
+
+ assert_equal({ controller: "account", action: "subscription" }, @routes.recognize_path("/account", method: :get))
+ assert_equal({ controller: "account", action: "subscription" }, @routes.recognize_path("/account/subscription", method: :get))
+ assert_equal({ controller: "account", action: "billing" }, @routes.recognize_path("/account/billing", method: :get))
+
+ assert_equal({ page_id: "1", controller: "notes", action: "index" }, @routes.recognize_path("/pages/1/notes", method: :get))
+ assert_equal({ page_id: "1", controller: "notes", action: "list" }, @routes.recognize_path("/pages/1/notes/list", method: :get))
+ assert_equal({ page_id: "1", controller: "notes", action: "show", id: "2" }, @routes.recognize_path("/pages/1/notes/show/2", method: :get))
+
+ assert_equal({ controller: "posts", action: "ping" }, @routes.recognize_path("/posts/ping", method: :get))
+ assert_equal({ controller: "posts", action: "index" }, @routes.recognize_path("/posts", method: :get))
+ assert_equal({ controller: "posts", action: "index" }, @routes.recognize_path("/posts/index", method: :get))
+ assert_equal({ controller: "posts", action: "show" }, @routes.recognize_path("/posts/show", method: :get))
+ assert_equal({ controller: "posts", action: "show", id: "1" }, @routes.recognize_path("/posts/show/1", method: :get))
+ assert_equal({ controller: "posts", action: "create" }, @routes.recognize_path("/posts/create", method: :post))
+
+ assert_equal({ controller: "geocode", action: "show", postalcode: "hx12-1az" }, @routes.recognize_path("/ignorecase/geocode/hx12-1az"))
+ assert_equal({ controller: "geocode", action: "show", postalcode: "hx12-1AZ" }, @routes.recognize_path("/ignorecase/geocode/hx12-1AZ"))
+ assert_equal({ controller: "geocode", action: "show", postalcode: "12345-1234" }, @routes.recognize_path("/extended/geocode/12345-1234"))
+ assert_equal({ controller: "geocode", action: "show", postalcode: "12345" }, @routes.recognize_path("/extended/geocode/12345"))
+
+ assert_equal({ controller: "news", action: "index" }, @routes.recognize_path("/", method: :get))
+ assert_equal({ controller: "news", action: "index", format: "rss" }, @routes.recognize_path("/news.rss", method: :get))
+
+ assert_raise(ActionController::RoutingError) { @routes.recognize_path("/none", method: :get) }
end
def test_generate_extras
- assert_equal ['/people', []], @routes.generate_extras(:controller => 'people')
- assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :foo => 'bar')
- assert_equal ['/people', []], @routes.generate_extras(:controller => 'people', :action => 'index')
- assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'index', :foo => 'bar')
- assert_equal ['/people/new', []], @routes.generate_extras(:controller => 'people', :action => 'new')
- assert_equal ['/people/new', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'new', :foo => 'bar')
- assert_equal ['/people/1', []], @routes.generate_extras(:controller => 'people', :action => 'show', :id => '1')
- assert_equal ['/people/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'people', :action => 'show', :id => '1', :foo => '2', :bar => '3'))
- assert_equal ['/people', [:person]], @routes.generate_extras(:controller => 'people', :action => 'create', :person => { :first_name => 'Josh', :last_name => 'Peek' })
- assert_equal ['/people', [:people]], @routes.generate_extras(:controller => 'people', :action => 'create', :people => ['Josh', 'Dave'])
-
- assert_equal ['/posts/show/1', []], @routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1')
- assert_equal ['/posts/show/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1', :foo => '2', :bar => '3'))
- assert_equal ['/posts', []], @routes.generate_extras(:controller => 'posts', :action => 'index')
- assert_equal ['/posts', [:foo]], @routes.generate_extras(:controller => 'posts', :action => 'index', :foo => 'bar')
+ assert_equal ["/people", []], @routes.generate_extras(controller: "people")
+ assert_equal ["/people", [:foo]], @routes.generate_extras(controller: "people", foo: "bar")
+ assert_equal ["/people", []], @routes.generate_extras(controller: "people", action: "index")
+ assert_equal ["/people", [:foo]], @routes.generate_extras(controller: "people", action: "index", foo: "bar")
+ assert_equal ["/people/new", []], @routes.generate_extras(controller: "people", action: "new")
+ assert_equal ["/people/new", [:foo]], @routes.generate_extras(controller: "people", action: "new", foo: "bar")
+ assert_equal ["/people/1", []], @routes.generate_extras(controller: "people", action: "show", id: "1")
+ assert_equal ["/people/1", [:bar, :foo]], sort_extras!(@routes.generate_extras(controller: "people", action: "show", id: "1", foo: "2", bar: "3"))
+ assert_equal ["/people", [:person]], @routes.generate_extras(controller: "people", action: "create", person: { first_name: "Josh", last_name: "Peek" })
+ assert_equal ["/people", [:people]], @routes.generate_extras(controller: "people", action: "create", people: ["Josh", "Dave"])
+
+ assert_equal ["/posts/show/1", []], @routes.generate_extras(controller: "posts", action: "show", id: "1")
+ assert_equal ["/posts/show/1", [:bar, :foo]], sort_extras!(@routes.generate_extras(controller: "posts", action: "show", id: "1", foo: "2", bar: "3"))
+ assert_equal ["/posts", []], @routes.generate_extras(controller: "posts", action: "index")
+ assert_equal ["/posts", [:foo]], @routes.generate_extras(controller: "posts", action: "index", foo: "bar")
end
def test_extras
- params = {:controller => 'people'}
+ params = { controller: "people" }
assert_equal [], @routes.extra_keys(params)
- assert_equal({:controller => 'people'}, params)
+ assert_equal({ controller: "people", action: "index" }, params)
- params = {:controller => 'people', :foo => 'bar'}
+ params = { controller: "people", foo: "bar" }
assert_equal [:foo], @routes.extra_keys(params)
- assert_equal({:controller => 'people', :foo => 'bar'}, params)
+ assert_equal({ controller: "people", action: "index", foo: "bar" }, params)
- params = {:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}
+ params = { controller: "people", action: "create", person: { name: "Josh" } }
assert_equal [:person], @routes.extra_keys(params)
- assert_equal({:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}, params)
+ assert_equal({ controller: "people", action: "create", person: { name: "Josh" } }, params)
end
def test_unicode_path
- assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界'), :method => :get))
+ assert_equal({ controller: "news", action: "index" }, @routes.recognize_path(URI.parser.escape("こんにちは/世界"), method: :get))
end
def test_downcased_unicode_path
- assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界').downcase, :method => :get))
+ assert_equal({ controller: "news", action: "index" }, @routes.recognize_path(URI.parser.escape("こんにちは/世界").downcase, method: :get))
end
private
diff --git a/actionpack/test/controller/runner_test.rb b/actionpack/test/controller/runner_test.rb
index 3e9383abb2..1709ab5f6d 100644
--- a/actionpack/test/controller/runner_test.rb
+++ b/actionpack/test/controller/runner_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_dispatch/testing/integration'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/testing/integration"
module ActionDispatch
class RunnerTest < ActiveSupport::TestCase
@@ -15,8 +17,8 @@ module ActionDispatch
def test_respond_to?
runner = MyRunner.new(Class.new { def x; end }.new)
- assert runner.respond_to?(:hi)
- assert runner.respond_to?(:x)
+ assert_respond_to runner, :hi
+ assert_respond_to runner, :x
end
end
end
diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb
index 2820425c31..c917cdf761 100644
--- a/actionpack/test/controller/send_file_test.rb
+++ b/actionpack/test/controller/send_file_test.rb
@@ -1,9 +1,11 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module TestFileUtils
def file_name() File.basename(__FILE__) end
- def file_path() File.expand_path(__FILE__) end
- def file_data() @data ||= File.open(file_path, 'rb') { |f| f.read } end
+ def file_path() __FILE__ end
+ def file_data() @data ||= File.open(file_path, "rb") { |f| f.read } end
end
class SendFileController < ActionController::Base
@@ -11,6 +13,8 @@ class SendFileController < ActionController::Base
include ActionController::Testing
layout "layouts/standard" # to make sure layouts don't interfere
+ before_action :file, only: :file_from_before_action
+
attr_writer :options
def options
@options ||= {}
@@ -20,11 +24,15 @@ class SendFileController < ActionController::Base
send_file(file_path, options)
end
+ def file_from_before_action
+ raise "No file sent from before action."
+ end
+
def test_send_file_headers_bang
options = {
- :type => Mime[:png],
- :disposition => 'disposition',
- :filename => 'filename'
+ type: Mime[:png],
+ disposition: "disposition",
+ filename: "filename"
}
send_data "foo", options
@@ -32,32 +40,32 @@ class SendFileController < ActionController::Base
def test_send_file_headers_with_disposition_as_a_symbol
options = {
- :type => Mime[:png],
- :disposition => :disposition,
- :filename => 'filename'
+ type: Mime[:png],
+ disposition: :disposition,
+ filename: "filename"
}
send_data "foo", options
end
def test_send_file_headers_with_mime_lookup_with_symbol
- options = { :type => :png }
+ options = { type: :png }
send_data "foo", options
end
def test_send_file_headers_with_bad_symbol
- options = { :type => :this_type_is_not_registered }
+ options = { type: :this_type_is_not_registered }
send_data "foo", options
end
def test_send_file_headers_with_nil_content_type
- options = { :type => nil }
+ options = { type: nil }
send_data "foo", options
end
def test_send_file_headers_guess_type_from_extension
- options = { :filename => params[:filename] }
+ options = { filename: params[:filename] }
send_data "foo", options
end
@@ -78,9 +86,9 @@ class SendFileTest < ActionController::TestCase
end
def test_file_nostream
- @controller.options = { :stream => false }
+ @controller.options = { stream: false }
response = nil
- assert_nothing_raised { response = process('file') }
+ assert_nothing_raised { response = process("file") }
assert_not_nil response
body = response.body
assert_kind_of String, body
@@ -89,12 +97,12 @@ class SendFileTest < ActionController::TestCase
def test_file_stream
response = nil
- assert_nothing_raised { response = process('file') }
+ assert_nothing_raised { response = process("file") }
assert_not_nil response
assert_respond_to response.stream, :each
assert_respond_to response.stream, :to_path
- require 'stringio'
+ require "stringio"
output = StringIO.new
output.binmode
output.string.force_encoding(file_data.encoding)
@@ -103,16 +111,16 @@ class SendFileTest < ActionController::TestCase
end
def test_file_url_based_filename
- @controller.options = { :url_based_filename => true }
+ @controller.options = { url_based_filename: true }
response = nil
- assert_nothing_raised { response = process('file') }
+ assert_nothing_raised { response = process("file") }
assert_not_nil response
assert_equal "attachment", response.headers["Content-Disposition"]
end
def test_data
response = nil
- assert_nothing_raised { response = process('data') }
+ assert_nothing_raised { response = process("data") }
assert_not_nil response
assert_kind_of String, response.body
@@ -120,10 +128,10 @@ class SendFileTest < ActionController::TestCase
end
def test_headers_after_send_shouldnt_include_charset
- response = process('data')
+ response = process("data")
assert_equal "application/octet-stream", response.headers["Content-Type"]
- response = process('file')
+ response = process("file")
assert_equal "application/octet-stream", response.headers["Content-Type"]
end
@@ -135,25 +143,24 @@ class SendFileTest < ActionController::TestCase
5.times do
get :test_send_file_headers_bang
- assert_equal 'image/png', response.content_type
- assert_equal 'disposition; filename="filename"', response.get_header('Content-Disposition')
- assert_equal 'binary', response.get_header('Content-Transfer-Encoding')
- assert_equal 'private', response.get_header('Cache-Control')
+ assert_equal "image/png", response.content_type
+ assert_equal %(disposition; filename="filename"; filename*=UTF-8''filename), response.get_header("Content-Disposition")
+ assert_equal "binary", response.get_header("Content-Transfer-Encoding")
+ assert_equal "private", response.get_header("Cache-Control")
end
end
def test_send_file_headers_with_disposition_as_a_symbol
get :test_send_file_headers_with_disposition_as_a_symbol
- assert_equal 'disposition; filename="filename"', response.get_header('Content-Disposition')
+ assert_equal %(disposition; filename="filename"; filename*=UTF-8''filename), response.get_header("Content-Disposition")
end
def test_send_file_headers_with_mime_lookup_with_symbol
get __method__
- assert_equal 'image/png', response.content_type
+ assert_equal "image/png", response.content_type
end
-
def test_send_file_headers_with_bad_symbol
error = assert_raise(ArgumentError) { get __method__ }
assert_equal "Unknown MIME type this_type_is_not_registered", error.message
@@ -166,47 +173,56 @@ class SendFileTest < ActionController::TestCase
def test_send_file_headers_guess_type_from_extension
{
- 'image.png' => 'image/png',
- 'image.jpeg' => 'image/jpeg',
- 'image.jpg' => 'image/jpeg',
- 'image.tif' => 'image/tiff',
- 'image.gif' => 'image/gif',
- 'movie.mpg' => 'video/mpeg',
- 'file.zip' => 'application/zip',
- 'file.unk' => 'application/octet-stream',
- 'zip' => 'application/octet-stream'
- }.each do |filename,expected_type|
+ "image.png" => "image/png",
+ "image.jpeg" => "image/jpeg",
+ "image.jpg" => "image/jpeg",
+ "image.tif" => "image/tiff",
+ "image.gif" => "image/gif",
+ "movie.mp4" => "video/mp4",
+ "file.zip" => "application/zip",
+ "file.unk" => "application/octet-stream",
+ "zip" => "application/octet-stream"
+ }.each do |filename, expected_type|
get __method__, params: { filename: filename }
assert_equal expected_type, response.content_type
end
end
def test_send_file_with_default_content_disposition_header
- process('data')
- assert_equal 'attachment', @controller.headers['Content-Disposition']
+ process("data")
+ assert_equal "attachment", @controller.headers["Content-Disposition"]
end
def test_send_file_without_content_disposition_header
- @controller.options = {:disposition => nil}
- process('data')
- assert_nil @controller.headers['Content-Disposition']
+ @controller.options = { disposition: nil }
+ process("data")
+ assert_nil @controller.headers["Content-Disposition"]
+ end
+
+ def test_send_file_from_before_action
+ response = nil
+ assert_nothing_raised { response = process("file_from_before_action") }
+ assert_not_nil response
+
+ assert_kind_of String, response.body
+ assert_equal file_data, response.body
end
%w(file data).each do |method|
define_method "test_send_#{method}_status" do
- @controller.options = { :stream => false, :status => 500 }
+ @controller.options = { stream: false, status: 500 }
assert_not_nil process(method)
assert_equal 500, @response.status
end
define_method "test_send_#{method}_content_type" do
- @controller.options = { :stream => false, :content_type => "application/x-ruby" }
+ @controller.options = { stream: false, content_type: "application/x-ruby" }
assert_nothing_raised { assert_not_nil process(method) }
assert_equal "application/x-ruby", @response.content_type
end
define_method "test_default_send_#{method}_status" do
- @controller.options = { :stream => false }
+ @controller.options = { stream: false }
assert_nothing_raised { assert_not_nil process(method) }
assert_equal 200, @response.status
end
@@ -214,9 +230,30 @@ class SendFileTest < ActionController::TestCase
def test_send_file_with_action_controller_live
@controller = SendFileWithActionControllerLive.new
- @controller.options = { :content_type => "application/x-ruby" }
+ @controller.options = { content_type: "application/x-ruby" }
- response = process('file')
+ response = process("file")
assert_equal 200, response.status
end
+
+ def test_send_file_charset_with_type_options_key
+ @controller = SendFileWithActionControllerLive.new
+ @controller.options = { type: "text/calendar; charset=utf-8" }
+ response = process("file")
+ assert_equal "text/calendar; charset=utf-8", response.headers["Content-Type"]
+ end
+
+ def test_send_file_charset_with_type_options_key_without_charset
+ @controller = SendFileWithActionControllerLive.new
+ @controller.options = { type: "image/png" }
+ response = process("file")
+ assert_equal "image/png", response.headers["Content-Type"]
+ end
+
+ def test_send_file_charset_with_content_type_options_key
+ @controller = SendFileWithActionControllerLive.new
+ @controller.options = { content_type: "text/calendar" }
+ response = process("file")
+ assert_equal "text/calendar", response.headers["Content-Type"]
+ end
end
diff --git a/actionpack/test/controller/show_exceptions_test.rb b/actionpack/test/controller/show_exceptions_test.rb
index 786dc15444..2094aa1aed 100644
--- a/actionpack/test/controller/show_exceptions_test.rb
+++ b/actionpack/test/controller/show_exceptions_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ShowExceptions
class ShowExceptionsController < ActionController::Base
@@ -10,11 +12,11 @@ module ShowExceptions
end
def boom
- raise 'boom!'
+ raise "boom!"
end
def another_boom
- raise 'boom!'
+ raise "boom!"
end
def show_detailed_exceptions?
@@ -23,26 +25,26 @@ module ShowExceptions
end
class ShowExceptionsTest < ActionDispatch::IntegrationTest
- test 'show error page from a remote ip' do
+ test "show error page from a remote ip" do
@app = ShowExceptionsController.action(:boom)
- self.remote_addr = '208.77.188.166'
- get '/'
+ self.remote_addr = "208.77.188.166"
+ get "/"
assert_equal "500 error fixture\n", body
end
- test 'show diagnostics from a local ip if show_detailed_exceptions? is set to request.local?' do
+ test "show diagnostics from a local ip if show_detailed_exceptions? is set to request.local?" do
@app = ShowExceptionsController.action(:boom)
- ['127.0.0.1', '127.0.0.127', '127.12.1.1', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
+ ["127.0.0.1", "127.0.0.127", "127.12.1.1", "::1", "0:0:0:0:0:0:0:1", "0:0:0:0:0:0:0:1%0"].each do |ip_address|
self.remote_addr = ip_address
- get '/'
+ get "/"
assert_match(/boom/, body)
end
end
- test 'show diagnostics from a remote ip when env is already set' do
+ test "show diagnostics from a remote ip when env is already set" do
@app = ShowExceptionsController.action(:another_boom)
- self.remote_addr = '208.77.188.166'
- get '/'
+ self.remote_addr = "208.77.188.166"
+ get "/"
assert_match(/boom/, body)
end
end
@@ -50,21 +52,21 @@ module ShowExceptions
class ShowExceptionsOverriddenController < ShowExceptionsController
private
- def show_detailed_exceptions?
- params['detailed'] == '1'
- end
+ def show_detailed_exceptions?
+ params["detailed"] == "1"
+ end
end
class ShowExceptionsOverriddenTest < ActionDispatch::IntegrationTest
- test 'show error page' do
+ test "show error page" do
@app = ShowExceptionsOverriddenController.action(:boom)
- get '/', params: { 'detailed' => '0' }
+ get "/", params: { "detailed" => "0" }
assert_equal "500 error fixture\n", body
end
- test 'show diagnostics message' do
+ test "show diagnostics message" do
@app = ShowExceptionsOverriddenController.action(:boom)
- get '/', params: { 'detailed' => '1' }
+ get "/", params: { "detailed" => "1" }
assert_match(/boom/, body)
end
end
@@ -72,25 +74,25 @@ module ShowExceptions
class ShowExceptionsFormatsTest < ActionDispatch::IntegrationTest
def test_render_json_exception
@app = ShowExceptionsOverriddenController.action(:boom)
- get "/", headers: { 'HTTP_ACCEPT' => 'application/json' }
+ get "/", headers: { "HTTP_ACCEPT" => "application/json" }
assert_response :internal_server_error
- assert_equal 'application/json', response.content_type.to_s
- assert_equal({ :status => 500, :error => 'Internal Server Error' }.to_json, response.body)
+ assert_equal "application/json", response.content_type.to_s
+ assert_equal({ status: 500, error: "Internal Server Error" }.to_json, response.body)
end
def test_render_xml_exception
@app = ShowExceptionsOverriddenController.action(:boom)
- get "/", headers: { 'HTTP_ACCEPT' => 'application/xml' }
+ get "/", headers: { "HTTP_ACCEPT" => "application/xml" }
assert_response :internal_server_error
- assert_equal 'application/xml', response.content_type.to_s
- assert_equal({ :status => 500, :error => 'Internal Server Error' }.to_xml, response.body)
+ assert_equal "application/xml", response.content_type.to_s
+ assert_equal({ status: 500, error: "Internal Server Error" }.to_xml, response.body)
end
def test_render_fallback_exception
@app = ShowExceptionsOverriddenController.action(:boom)
- get "/", headers: { 'HTTP_ACCEPT' => 'text/csv' }
+ get "/", headers: { "HTTP_ACCEPT" => "text/csv" }
assert_response :internal_server_error
- assert_equal 'text/html', response.content_type.to_s
+ assert_equal "text/html", response.content_type.to_s
end
end
@@ -101,9 +103,9 @@ module ShowExceptions
@app.instance_variable_set(:@exceptions_app, nil)
$stderr = StringIO.new
- get '/', headers: { 'HTTP_ACCEPT' => 'text/json' }
+ get "/", headers: { "HTTP_ACCEPT" => "text/json" }
assert_response :internal_server_error
- assert_equal 'text/plain', response.content_type.to_s
+ assert_equal "text/plain", response.content_type.to_s
ensure
@app.instance_variable_set(:@exceptions_app, @exceptions_app)
$stderr = STDERR
diff --git a/actionpack/test/controller/streaming_test.rb b/actionpack/test/controller/streaming_test.rb
index 6ee6444065..5a42e2ae6d 100644
--- a/actionpack/test/controller/streaming_test.rb
+++ b/actionpack/test/controller/streaming_test.rb
@@ -1,10 +1,12 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionController
class StreamingResponseTest < ActionController::TestCase
class TestController < ActionController::Base
def self.controller_path
- 'test'
+ "test"
end
def basic_stream
diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb
index e50373a0cc..6fc70d6248 100644
--- a/actionpack/test/controller/test_case_test.rb
+++ b/actionpack/test/controller/test_case_test.rb
@@ -1,40 +1,42 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
-require 'active_support/json/decoding'
-require 'rails/engine'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
+require "active_support/json/decoding"
+require "rails/engine"
class TestCaseTest < ActionController::TestCase
- def self.fixture_path; end;
+ def self.fixture_path; end
class TestController < ActionController::Base
def no_op
- render plain: 'dummy'
+ render plain: "dummy"
end
def set_flash
flash["test"] = ">#{flash["test"]}<"
- render plain: 'ignore me'
+ render plain: "ignore me"
end
def delete_flash
flash.delete("test")
- render plain: 'ignore me'
+ render plain: "ignore me"
end
def set_flash_now
flash.now["test_now"] = ">#{flash["test_now"]}<"
- render plain: 'ignore me'
+ render plain: "ignore me"
end
def set_session
- session['string'] = 'A wonder'
- session[:symbol] = 'it works'
- render plain: 'Success'
+ session["string"] = "A wonder"
+ session[:symbol] = "it works"
+ render plain: "Success"
end
def reset_the_session
reset_session
- render plain: 'ignore me'
+ render plain: "ignore me"
end
def render_raw_post
@@ -100,11 +102,11 @@ HTML
end
def test_xml_output
- response.content_type = "application/xml"
+ response.content_type = params[:response_as]
render plain: <<XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
- <area>area is an empty tag in HTML, raising an error if not in xml mode</area>
+ <area><p>area is an empty tag in HTML, so it won't contain this content</p></area>
</root>
XML
end
@@ -122,24 +124,28 @@ XML
end
def test_send_file
- send_file(File.expand_path(__FILE__))
+ send_file(__FILE__)
end
def redirect_to_same_controller
- redirect_to controller: 'test', action: 'test_uri', id: 5
+ redirect_to controller: "test", action: "test_uri", id: 5
end
def redirect_to_different_controller
- redirect_to controller: 'fail', id: 5
+ redirect_to controller: "fail", id: 5
end
def create
- head :created, location: 'created resource'
+ head :created, location: "/resource"
+ end
+
+ def render_cookie
+ render plain: cookies["foo"]
end
def delete_cookie
cookies.delete("foo")
- render plain: 'ok'
+ render plain: "ok"
end
def test_without_body
@@ -150,6 +156,10 @@ XML
render html: '<body class="foo"></body>'.html_safe
end
+ def boom
+ raise "boom!"
+ end
+
private
def generate_url(opts)
@@ -160,19 +170,21 @@ XML
def setup
super
@controller = TestController.new
- @request.delete_header 'PATH_INFO'
+ @request.delete_header "PATH_INFO"
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
r.draw do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
end
class DefaultUrlOptionsCachingController < ActionController::Base
- before_action { @dynamic_opt = 'opt' }
+ before_action { @dynamic_opt = "opt" }
def test_url_options_reset
- render plain: url_for(params)
+ render plain: url_for
end
def default_url_options
@@ -187,49 +199,62 @@ XML
def test_assert_select_without_body
get :test_without_body
- assert_select 'body', 0
- assert_select 'div.foo'
+ assert_select "body", 0
+ assert_select "div.foo"
end
def test_assert_select_with_body
get :test_with_body
- assert_select 'body.foo'
+ assert_select "body.foo"
end
def test_url_options_reset
@controller = DefaultUrlOptionsCachingController.new
get :test_url_options_reset
- assert_nil @request.params['dynamic_opt']
+ assert_nil @request.params["dynamic_opt"]
assert_match(/dynamic_opt=opt/, @response.body)
end
def test_raw_post_handling
- params = Hash[:page, { name: 'page name' }, 'some key', 123]
+ params = Hash[:page, { name: "page name" }, "some key", 123]
post :render_raw_post, params: params.dup
assert_equal params.to_query, @response.body
end
- def test_body_stream
- params = Hash[:page, { name: 'page name' }, 'some key', 123]
+ def test_params_round_trip
+ params = { "foo" => { "contents" => [{ "name" => "gorby", "id" => "123" }, { "name" => "puff", "d" => "true" }] } }
+ post :test_params, params: params.dup
- post :render_body, params: params.dup
+ controller_info = { "controller" => "test_case_test/test", "action" => "test_params" }
+ assert_equal params.merge(controller_info), JSON.parse(@response.body)
+ end
- assert_equal params.to_query, @response.body
+ def test_handle_to_params
+ klass = Class.new do
+ def to_param
+ "bar"
+ end
+ end
+
+ post :test_params, params: { foo: klass.new }
+
+ assert_equal JSON.parse(@response.body)["foo"], "bar"
end
- def test_deprecated_body_stream
- params = Hash[:page, { name: 'page name' }, 'some key', 123]
- assert_deprecated { post :render_body, params.dup }
+ def test_body_stream
+ params = Hash[:page, { name: "page name" }, "some key", 123]
+
+ post :render_body, params: params.dup
assert_equal params.to_query, @response.body
end
def test_document_body_and_params_with_post
post :test_params, params: { id: 1 }
- assert_equal({"id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params"}, ::JSON.parse(@response.body))
+ assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
end
def test_document_body_with_post
@@ -237,21 +262,11 @@ XML
assert_equal "document body", @response.body
end
- def test_deprecated_document_body_with_post
- assert_deprecated { post :render_body, "document body" }
- assert_equal "document body", @response.body
- end
-
def test_document_body_with_put
put :render_body, body: "document body"
assert_equal "document body", @response.body
end
- def test_deprecated_document_body_with_put
- assert_deprecated { put :render_body, "document body" }
- assert_equal "document body", @response.body
- end
-
def test_head
head :test_params
assert_equal 200, @response.status
@@ -259,31 +274,21 @@ XML
def test_process_without_flash
process :set_flash
- assert_equal '><', flash['test']
- end
-
- def test_deprecated_process_with_flash
- assert_deprecated { process :set_flash, "GET", nil, nil, { "test" => "value" } }
- assert_equal '>value<', flash['test']
+ assert_equal "><", flash["test"]
end
def test_process_with_flash
process :set_flash,
method: "GET",
flash: { "test" => "value" }
- assert_equal '>value<', flash['test']
- end
-
- def test_deprecated_process_with_flash_now
- assert_deprecated { process :set_flash_now, "GET", nil, nil, { "test_now" => "value_now" } }
- assert_equal '>value_now<', flash['test_now']
+ assert_equal ">value<", flash["test"]
end
def test_process_with_flash_now
process :set_flash_now,
method: "GET",
flash: { "test_now" => "value_now" }
- assert_equal '>value_now<', flash['test_now']
+ assert_equal ">value_now<", flash["test_now"]
end
def test_process_delete_flash
@@ -295,64 +300,38 @@ XML
def test_process_with_session
process :set_session
- assert_equal 'A wonder', session['string'], "A value stored in the session should be available by string key"
- assert_equal 'A wonder', session[:string], "Test session hash should allow indifferent access"
- assert_equal 'it works', session['symbol'], "Test session hash should allow indifferent access"
- assert_equal 'it works', session[:symbol], "Test session hash should allow indifferent access"
- end
-
- def test_process_with_session_arg
- assert_deprecated { process :no_op, "GET", nil, { 'string' => 'value1', symbol: 'value2' } }
- assert_equal 'value1', session['string']
- assert_equal 'value1', session[:string]
- assert_equal 'value2', session['symbol']
- assert_equal 'value2', session[:symbol]
+ assert_equal "A wonder", session["string"], "A value stored in the session should be available by string key"
+ assert_equal "A wonder", session[:string], "Test session hash should allow indifferent access"
+ assert_equal "it works", session["symbol"], "Test session hash should allow indifferent access"
+ assert_equal "it works", session[:symbol], "Test session hash should allow indifferent access"
end
def test_process_with_session_kwarg
- process :no_op, method: "GET", session: { 'string' => 'value1', symbol: 'value2' }
- assert_equal 'value1', session['string']
- assert_equal 'value1', session[:string]
- assert_equal 'value2', session['symbol']
- assert_equal 'value2', session[:symbol]
- end
-
- def test_deprecated_process_merges_session_arg
- session[:foo] = 'bar'
- assert_deprecated {
- get :no_op, nil, { bar: 'baz' }
- }
- assert_equal 'bar', session[:foo]
- assert_equal 'baz', session[:bar]
+ process :no_op, method: "GET", session: { "string" => "value1", symbol: "value2" }
+ assert_equal "value1", session["string"]
+ assert_equal "value1", session[:string]
+ assert_equal "value2", session["symbol"]
+ assert_equal "value2", session[:symbol]
end
def test_process_merges_session_arg
- session[:foo] = 'bar'
- get :no_op, session: { bar: 'baz' }
- assert_equal 'bar', session[:foo]
- assert_equal 'baz', session[:bar]
- end
-
- def test_deprecated_merged_session_arg_is_retained_across_requests
- assert_deprecated {
- get :no_op, nil, { foo: 'bar' }
- }
- assert_equal 'bar', session[:foo]
- get :no_op
- assert_equal 'bar', session[:foo]
+ session[:foo] = "bar"
+ get :no_op, session: { bar: "baz" }
+ assert_equal "bar", session[:foo]
+ assert_equal "baz", session[:bar]
end
def test_merged_session_arg_is_retained_across_requests
- get :no_op, session: { foo: 'bar' }
- assert_equal 'bar', session[:foo]
+ get :no_op, session: { foo: "bar" }
+ assert_equal "bar", session[:foo]
get :no_op
- assert_equal 'bar', session[:foo]
+ assert_equal "bar", session[:foo]
end
def test_process_overwrites_existing_session_arg
- session[:foo] = 'bar'
- get :no_op, session: { foo: 'baz' }
- assert_equal 'baz', session[:foo]
+ session[:foo] = "bar"
+ get :no_op, session: { foo: "baz" }
+ assert_equal "baz", session[:foo]
end
def test_session_is_cleared_from_controller_after_reset_session
@@ -383,11 +362,6 @@ XML
assert_equal "/test_case_test/test/test_uri", @response.body
end
- def test_deprecated_process_with_request_uri_with_params
- assert_deprecated { process :test_uri, "GET", id: 7 }
- assert_equal "/test_case_test/test/test_uri/7", @response.body
- end
-
def test_process_with_request_uri_with_params
process :test_uri,
method: "GET",
@@ -396,14 +370,8 @@ XML
assert_equal "/test_case_test/test/test_uri/7", @response.body
end
- def test_deprecated_process_with_request_uri_with_params_with_explicit_uri
- @request.env['PATH_INFO'] = "/explicit/uri"
- assert_deprecated { process :test_uri, "GET", id: 7 }
- assert_equal "/explicit/uri", @response.body
- end
-
def test_process_with_request_uri_with_params_with_explicit_uri
- @request.env['PATH_INFO'] = "/explicit/uri"
+ @request.env["PATH_INFO"] = "/explicit/uri"
process :test_uri, method: "GET", params: { id: 7 }
assert_equal "/explicit/uri", @response.body
end
@@ -411,13 +379,13 @@ XML
def test_process_with_query_string
process :test_query_string,
method: "GET",
- params: { q: 'test' }
+ params: { q: "test" }
assert_equal "q=test", @response.body
end
def test_process_with_query_string_with_explicit_uri
- @request.env['PATH_INFO'] = '/explicit/uri'
- @request.env['QUERY_STRING'] = 'q=test?extra=question'
+ @request.env["PATH_INFO"] = "/explicit/uri"
+ @request.env["QUERY_STRING"] = "q=test?extra=question"
process :test_query_string
assert_equal "q=test?extra=question", @response.body
end
@@ -429,36 +397,42 @@ XML
assert_equal "OK", @response.body
end
- def test_should_not_impose_childless_html_tags_in_xml
- process :test_xml_output
+ def test_should_impose_childless_html_tags_in_html
+ process :test_xml_output, params: { response_as: "text/html" }
- begin
- $stderr = StringIO.new
- assert_select 'area' #This will cause a warning if content is processed as HTML
- $stderr.rewind && err = $stderr.read
- ensure
- $stderr = STDERR
+ # <area> auto-closes, so the <p> becomes a sibling
+ if defined?(JRUBY_VERSION)
+ # https://github.com/sparklemotion/nokogiri/issues/1653
+ # HTML parser "fixes" "broken" markup in slightly different ways
+ assert_select "root > map > area + p"
+ else
+ assert_select "root > area + p"
end
+ end
+
+ def test_should_not_impose_childless_html_tags_in_xml
+ process :test_xml_output, params: { response_as: "application/xml" }
- assert err.empty?
+ # <area> is not special, so the <p> is its child
+ assert_select "root > area > p"
end
def test_assert_generates
- assert_generates 'controller/action/5', controller: 'controller', action: 'action', id: '5'
- assert_generates 'controller/action/7', { id: "7" }, { controller: "controller", action: "action" }
- assert_generates 'controller/action/5', { controller: "controller", action: "action", id: "5", name: "bob" }, {}, { name: "bob" }
- assert_generates 'controller/action/7', { id: "7", name: "bob" }, { controller: "controller", action: "action" }, { name: "bob" }
- assert_generates 'controller/action/7', { id: "7" }, { controller: "controller", action: "action", name: "bob" }, {}
+ assert_generates "controller/action/5", controller: "controller", action: "action", id: "5"
+ assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action" }
+ assert_generates "controller/action/5", { controller: "controller", action: "action", id: "5", name: "bob" }, {}, { name: "bob" }
+ assert_generates "controller/action/7", { id: "7", name: "bob" }, { controller: "controller", action: "action" }, { name: "bob" }
+ assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action", name: "bob" }, {}
end
def test_assert_routing
- assert_routing 'content', controller: 'content', action: 'index'
+ assert_routing "content", controller: "content", action: "index"
end
def test_assert_routing_with_method
with_routing do |set|
set.draw { resources(:content) }
- assert_routing({ method: 'post', path: 'content' }, { controller: 'content', action: 'create' })
+ assert_routing({ method: "post", path: "content" }, { controller: "content", action: "create" })
end
end
@@ -466,125 +440,101 @@ XML
with_routing do |set|
set.draw do
namespace :admin do
- get 'user' => 'user#index'
+ get "user" => "user#index"
end
end
- assert_routing 'admin/user', controller: 'admin/user', action: 'index'
+ assert_routing "admin/user", controller: "admin/user", action: "index"
end
end
def test_assert_routing_with_glob
with_routing do |set|
- set.draw { get('*path' => "pages#show") }
- assert_routing('/company/about', { controller: 'pages', action: 'show', path: 'company/about' })
+ set.draw { get("*path" => "pages#show") }
+ assert_routing("/company/about", controller: "pages", action: "show", path: "company/about")
end
end
- def test_deprecated_params_passing
- assert_deprecated {
- get :test_params, page: { name: "Page name", month: '4', year: '2004', day: '6' }
- }
- parsed_params = ::JSON.parse(@response.body)
- assert_equal(
- {
- 'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'page' => { 'name' => "Page name", 'month' => '4', 'year' => '2004', 'day' => '6' }
- },
- parsed_params
- )
- end
-
def test_params_passing
get :test_params, params: {
page: {
name: "Page name",
- month: '4',
- year: '2004',
- day: '6'
+ month: "4",
+ year: "2004",
+ day: "6"
}
}
parsed_params = ::JSON.parse(@response.body)
assert_equal(
{
- 'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'page' => { 'name' => "Page name", 'month' => '4', 'year' => '2004', 'day' => '6' }
+ "controller" => "test_case_test/test", "action" => "test_params",
+ "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" }
},
parsed_params
)
end
def test_query_param_named_action
- get :test_query_parameters, params: {action: 'foobar'}
+ get :test_query_parameters, params: { action: "foobar" }
parsed_params = JSON.parse(@response.body)
- assert_equal({'action' => 'foobar'}, parsed_params)
+ assert_equal({ "action" => "foobar" }, parsed_params)
end
def test_request_param_named_action
- post :test_request_parameters, params: {action: 'foobar'}
+ post :test_request_parameters, params: { action: "foobar" }
parsed_params = eval(@response.body)
- assert_equal({'action' => 'foobar'}, parsed_params)
+ assert_equal({ "action" => "foobar" }, parsed_params)
end
def test_kwarg_params_passing_with_session_and_flash
get :test_params, params: {
page: {
name: "Page name",
- month: '4',
- year: '2004',
- day: '6'
+ month: "4",
+ year: "2004",
+ day: "6"
}
- }, session: { 'foo' => 'bar' }, flash: { notice: 'created' }
+ }, session: { "foo" => "bar" }, flash: { notice: "created" }
parsed_params = ::JSON.parse(@response.body)
assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'page' => {'name' => "Page name", 'month' => '4', 'year' => '2004', 'day' => '6'}},
+ { "controller" => "test_case_test/test", "action" => "test_params",
+ "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
parsed_params
)
- assert_equal 'bar', session[:foo]
- assert_equal 'created', flash[:notice]
+ assert_equal "bar", session[:foo]
+ assert_equal "created", flash[:notice]
end
- def test_params_passing_with_fixnums
+ def test_params_passing_with_integer
get :test_params, params: {
page: { name: "Page name", month: 4, year: 2004, day: 6 }
}
parsed_params = ::JSON.parse(@response.body)
assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'page' => {'name' => "Page name", 'month' => '4', 'year' => '2004', 'day' => '6'}},
+ { "controller" => "test_case_test/test", "action" => "test_params",
+ "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
parsed_params
)
end
- def test_params_passing_with_fixnums_when_not_html_request
- get :test_params, params: { format: 'json', count: 999 }
+ def test_params_passing_with_integers_when_not_html_request
+ get :test_params, params: { format: "json", count: 999 }
parsed_params = ::JSON.parse(@response.body)
assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'format' => 'json', 'count' => '999' },
+ { "controller" => "test_case_test/test", "action" => "test_params",
+ "format" => "json", "count" => "999" },
parsed_params
)
end
def test_params_passing_path_parameter_is_string_when_not_html_request
- get :test_params, params: { format: 'json', id: 1 }
- parsed_params = ::JSON.parse(@response.body)
- assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'format' => 'json', 'id' => '1' },
- parsed_params
- )
- end
-
- def test_deprecated_params_passing_path_parameter_is_string_when_not_html_request
- assert_deprecated { get :test_params, format: 'json', id: 1 }
+ get :test_params, params: { format: "json", id: 1 }
parsed_params = ::JSON.parse(@response.body)
assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'format' => 'json', 'id' => '1' },
+ { "controller" => "test_case_test/test", "action" => "test_params",
+ "format" => "json", "id" => "1" },
parsed_params
)
end
@@ -592,13 +542,13 @@ XML
def test_params_passing_with_frozen_values
assert_nothing_raised do
get :test_params, params: {
- frozen: 'icy'.freeze, frozens: ['icy'.freeze].freeze, deepfreeze: { frozen: 'icy'.freeze }.freeze
+ frozen: -"icy", frozens: [-"icy"].freeze, deepfreeze: { frozen: -"icy" }.freeze
}
end
parsed_params = ::JSON.parse(@response.body)
assert_equal(
- {'controller' => 'test_case_test/test', 'action' => 'test_params',
- 'frozen' => 'icy', 'frozens' => ['icy'], 'deepfreeze' => { 'frozen' => 'icy' }},
+ { "controller" => "test_case_test/test", "action" => "test_params",
+ "frozen" => "icy", "frozens" => ["icy"], "deepfreeze" => { "frozen" => "icy" } },
parsed_params
)
end
@@ -610,8 +560,8 @@ XML
end
test "set additional HTTP headers" do
- @request.headers['Referer'] = "http://nohost.com/home"
- @request.headers['Content-Type'] = "application/rss+xml"
+ @request.headers["Referer"] = "http://nohost.com/home"
+ @request.headers["Content-Type"] = "application/rss+xml"
get :test_headers
parsed_env = ActiveSupport::JSON.decode(@response.body)
assert_equal "http://nohost.com/home", parsed_env["HTTP_REFERER"]
@@ -619,36 +569,50 @@ XML
end
test "set additional env variables" do
- @request.headers['HTTP_REFERER'] = "http://example.com/about"
- @request.headers['CONTENT_TYPE'] = "application/json"
+ @request.headers["HTTP_REFERER"] = "http://example.com/about"
+ @request.headers["CONTENT_TYPE"] = "application/json"
get :test_headers
parsed_env = ActiveSupport::JSON.decode(@response.body)
assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"]
assert_equal "application/json", parsed_env["CONTENT_TYPE"]
end
+ def test_using_as_json_sets_request_content_type_to_json
+ post :render_body, params: { bool_value: true, str_value: "string", num_value: 2 }, as: :json
+
+ assert_equal "application/json", @request.headers["CONTENT_TYPE"]
+ assert_equal true, @request.request_parameters[:bool_value]
+ assert_equal "string", @request.request_parameters[:str_value]
+ assert_equal 2, @request.request_parameters[:num_value]
+ end
+
+ def test_using_as_json_sets_format_json
+ post :render_body, params: { bool_value: true, str_value: "string", num_value: 2 }, as: :json
+ assert_equal "json", @request.format
+ end
+
def test_mutating_content_type_headers_for_plain_text_files_sets_the_header
- @request.headers['Content-Type'] = 'text/plain'
- post :render_body, params: { name: 'foo.txt' }
+ @request.headers["Content-Type"] = "text/plain"
+ post :render_body, params: { name: "foo.txt" }
- assert_equal 'text/plain', @request.headers['Content-type']
- assert_equal 'foo.txt', @request.request_parameters[:name]
- assert_equal 'render_body', @request.path_parameters[:action]
+ assert_equal "text/plain", @request.headers["Content-type"]
+ assert_equal "foo.txt", @request.request_parameters[:name]
+ assert_equal "render_body", @request.path_parameters[:action]
end
def test_mutating_content_type_headers_for_html_files_sets_the_header
- @request.headers['Content-Type'] = 'text/html'
- post :render_body, params: { name: 'foo.html' }
+ @request.headers["Content-Type"] = "text/html"
+ post :render_body, params: { name: "foo.html" }
- assert_equal 'text/html', @request.headers['Content-type']
- assert_equal 'foo.html', @request.request_parameters[:name]
- assert_equal 'render_body', @request.path_parameters[:action]
+ assert_equal "text/html", @request.headers["Content-type"]
+ assert_equal "foo.html", @request.request_parameters[:name]
+ assert_equal "render_body", @request.path_parameters[:action]
end
def test_mutating_content_type_headers_for_non_registered_mime_type_raises_an_error
assert_raises(RuntimeError) do
- @request.headers['Content-Type'] = 'type/fake'
- post :render_body, params: { name: 'foo.fake' }
+ @request.headers["Content-Type"] = "type/fake"
+ post :render_body, params: { name: "foo.fake" }
end
end
@@ -659,21 +623,19 @@ XML
assert_kind_of String, @request.path_parameters[:id]
end
- def test_deprecared_id_converted_to_string
- assert_deprecated { get :test_params, id: 20, foo: Object.new}
- assert_kind_of String, @request.path_parameters[:id]
- end
-
def test_array_path_parameter_handled_properly
with_routing do |set|
set.draw do
- get 'file/*path', to: 'test_case_test/test#test_params'
- get ':controller/:action'
+ get "file/*path", to: "test_case_test/test#test_params"
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
- get :test_params, params: { path: ['hello', 'world'] }
- assert_equal ['hello', 'world'], @request.path_parameters[:path]
- assert_equal 'hello/world', @request.path_parameters[:path].to_param
+ get :test_params, params: { path: ["hello", "world"] }
+ assert_equal ["hello", "world"], @request.path_parameters[:path]
+ assert_equal "hello/world", @request.path_parameters[:path].to_param
end
end
@@ -691,8 +653,8 @@ XML
routes_id = @routes.object_id
begin
- with_routing { raise 'fail' }
- fail 'Should not be here.'
+ with_routing { raise "fail" }
+ fail "Should not be here."
rescue RuntimeError
end
@@ -711,46 +673,23 @@ XML
def test_header_properly_reset_after_remote_http_request
get :test_params, xhr: true
- assert_nil @request.env['HTTP_X_REQUESTED_WITH']
- assert_nil @request.env['HTTP_ACCEPT']
- end
-
- def test_deprecated_xhr_with_params
- assert_deprecated { xhr :get, :test_params, params: { id: 1 } }
-
- assert_equal({"id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params"}, ::JSON.parse(@response.body))
+ assert_nil @request.env["HTTP_X_REQUESTED_WITH"]
+ assert_nil @request.env["HTTP_ACCEPT"]
end
def test_xhr_with_params
get :test_params, params: { id: 1 }, xhr: true
- assert_equal({"id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params"}, ::JSON.parse(@response.body))
+ assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
end
def test_xhr_with_session
get :set_session, xhr: true
- assert_equal 'A wonder', session['string'], "A value stored in the session should be available by string key"
- assert_equal 'A wonder', session[:string], "Test session hash should allow indifferent access"
- assert_equal 'it works', session['symbol'], "Test session hash should allow indifferent access"
- assert_equal 'it works', session[:symbol], "Test session hash should allow indifferent access"
- end
-
- def test_deprecated_xhr_with_session
- assert_deprecated { xhr :get, :set_session }
-
- assert_equal 'A wonder', session['string'], "A value stored in the session should be available by string key"
- assert_equal 'A wonder', session[:string], "Test session hash should allow indifferent access"
- assert_equal 'it works', session['symbol'], "Test session hash should allow indifferent access"
- assert_equal 'it works', session[:symbol], "Test session hash should allow indifferent access"
- end
-
- def test_deprecated_params_reset_between_post_requests
- assert_deprecated { post :no_op, foo: "bar" }
- assert_equal "bar", @request.params[:foo]
-
- post :no_op
- assert @request.params[:foo].blank?
+ assert_equal "A wonder", session["string"], "A value stored in the session should be available by string key"
+ assert_equal "A wonder", session[:string], "Test session hash should allow indifferent access"
+ assert_equal "it works", session["symbol"], "Test session hash should allow indifferent access"
+ assert_equal "it works", session[:symbol], "Test session hash should allow indifferent access"
end
def test_params_reset_between_post_requests
@@ -758,7 +697,7 @@ XML
assert_equal "bar", @request.params[:foo]
post :no_op
- assert @request.params[:foo].blank?
+ assert_predicate @request.params[:foo], :blank?
end
def test_filtered_parameters_reset_between_requests
@@ -769,6 +708,27 @@ XML
assert_equal "baz", @request.filtered_parameters[:foo]
end
+ def test_raw_post_reset_between_post_requests
+ post :no_op, params: { foo: "bar" }
+ assert_equal "foo=bar", @request.raw_post
+
+ post :no_op, params: { foo: "baz" }
+ assert_equal "foo=baz", @request.raw_post
+ end
+
+ def test_content_length_reset_after_post_request
+ post :no_op, params: { foo: "bar" }
+ assert_not_equal 0, @request.content_length
+
+ get :no_op
+ assert_equal 0, @request.content_length
+ end
+
+ def test_path_is_kept_after_the_request
+ get :test_params, params: { id: "foo" }
+ assert_equal "/test_case_test/test/test_params/foo", @request.path
+ end
+
def test_path_params_reset_between_request
get :test_params, params: { id: "foo" }
assert_equal "foo", @request.path_parameters[:id]
@@ -791,48 +751,70 @@ XML
end
def test_request_format
- get :test_format, params: { format: 'html' }
- assert_equal 'text/html', @response.body
+ get :test_format, params: { format: "html" }
+ assert_equal "text/html", @response.body
- get :test_format, params: { format: 'json' }
- assert_equal 'application/json', @response.body
+ get :test_format, params: { format: "json" }
+ assert_equal "application/json", @response.body
- get :test_format, params: { format: 'xml' }
- assert_equal 'application/xml', @response.body
+ get :test_format, params: { format: "xml" }
+ assert_equal "application/xml", @response.body
get :test_format
- assert_equal 'text/html', @response.body
+ assert_equal "text/html", @response.body
end
def test_request_format_kwarg
- get :test_format, format: 'html'
- assert_equal 'text/html', @response.body
+ get :test_format, format: "html"
+ assert_equal "text/html", @response.body
- get :test_format, format: 'json'
- assert_equal 'application/json', @response.body
+ get :test_format, format: "json"
+ assert_equal "application/json", @response.body
- get :test_format, format: 'xml'
- assert_equal 'application/xml', @response.body
+ get :test_format, format: "xml"
+ assert_equal "application/xml", @response.body
get :test_format
- assert_equal 'text/html', @response.body
+ assert_equal "text/html", @response.body
end
def test_request_format_kwarg_overrides_params
- get :test_format, format: 'json', params: { format: 'html' }
- assert_equal 'application/json', @response.body
+ get :test_format, format: "json", params: { format: "html" }
+ assert_equal "application/json", @response.body
+ end
+
+ def test_request_format_kwarg_doesnt_mutate_params
+ params = { foo: "bar" }.freeze
+
+ assert_nothing_raised do
+ get :test_format, format: "json", params: params
+ end
end
def test_should_have_knowledge_of_client_side_cookie_state_even_if_they_are_not_set
- cookies['foo'] = 'bar'
+ cookies["foo"] = "bar"
get :no_op
- assert_equal 'bar', cookies['foo']
+ assert_equal "bar", cookies["foo"]
+ end
+
+ def test_cookies_should_be_escaped_properly
+ cookies["foo"] = "+"
+ get :render_cookie
+ assert_equal "+", @response.body
end
def test_should_detect_if_cookie_is_deleted
- cookies['foo'] = 'bar'
+ cookies["foo"] = "bar"
get :delete_cookie
- assert_nil cookies['foo']
+ assert_nil cookies["foo"]
+ end
+
+ def test_multiple_mixed_method_process_should_scrub_rack_input
+ post :test_params, params: { id: 1, foo: "an foo" }
+ assert_equal({ "id" => "1", "foo" => "an foo", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
+
+ get :test_params, params: { bar: "an bar" }
+ assert_equal({ "bar" => "an bar", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
end
%w(controller response request).each do |variable|
@@ -851,15 +833,15 @@ XML
end
end
- FILES_DIR = File.dirname(__FILE__) + '/../fixtures/multipart'
+ FILES_DIR = File.expand_path("../fixtures/multipart", __dir__)
- READ_BINARY = 'rb:binary'
- READ_PLAIN = 'r:binary'
+ READ_BINARY = "rb:binary"
+ READ_PLAIN = "r:binary"
def test_test_uploaded_file
- filename = 'mona_lisa.jpg'
+ filename = "ruby_on_rails.jpg"
path = "#{FILES_DIR}/#{filename}"
- content_type = 'image/png'
+ content_type = "image/png"
expected = File.read(path)
expected.force_encoding(Encoding::BINARY)
@@ -872,20 +854,19 @@ XML
new_content_type = "new content_type"
file.content_type = new_content_type
assert_equal new_content_type, file.content_type
-
end
def test_fixture_path_is_accessed_from_self_instead_of_active_support_test_case
TestCaseTest.stub :fixture_path, FILES_DIR do
- uploaded_file = fixture_file_upload('/mona_lisa.jpg', 'image/png')
- assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
+ uploaded_file = fixture_file_upload("/ruby_on_rails.jpg", "image/png")
+ assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
end
end
def test_test_uploaded_file_with_binary
- filename = 'mona_lisa.jpg'
+ filename = "ruby_on_rails.jpg"
path = "#{FILES_DIR}/#{filename}"
- content_type = 'image/png'
+ content_type = "image/png"
binary_uploaded_file = Rack::Test::UploadedFile.new(path, content_type, :binary)
assert_equal File.open(path, READ_BINARY).read, binary_uploaded_file.read
@@ -895,9 +876,9 @@ XML
end
def test_fixture_file_upload_with_binary
- filename = 'mona_lisa.jpg'
+ filename = "ruby_on_rails.jpg"
path = "#{FILES_DIR}/#{filename}"
- content_type = 'image/jpg'
+ content_type = "image/jpg"
binary_file_upload = fixture_file_upload(path, content_type, :binary)
assert_equal File.open(path, READ_BINARY).read, binary_file_upload.read
@@ -907,50 +888,48 @@ XML
end
def test_fixture_file_upload_should_be_able_access_to_tempfile
- file = fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
- assert file.respond_to?(:tempfile), "expected tempfile should respond on fixture file object, got nothing"
+ file = fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg")
+ assert_respond_to file, :tempfile
end
def test_fixture_file_upload
post :test_file_upload,
params: {
- file: fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
+ file: fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg")
}
- assert_equal '159528', @response.body
+ assert_equal "45142", @response.body
end
def test_fixture_file_upload_relative_to_fixture_path
TestCaseTest.stub :fixture_path, FILES_DIR do
- uploaded_file = fixture_file_upload("mona_lisa.jpg", "image/jpg")
- assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
+ uploaded_file = fixture_file_upload("ruby_on_rails.jpg", "image/jpg")
+ assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
end
end
- def test_fixture_file_upload_ignores_nil_fixture_path
- uploaded_file = fixture_file_upload("#{FILES_DIR}/mona_lisa.jpg", "image/jpg")
- assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
+ def test_fixture_file_upload_ignores_fixture_path_given_full_path
+ TestCaseTest.stub :fixture_path, __dir__ do
+ uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg")
+ assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
+ end
end
- def test_deprecated_action_dispatch_uploaded_file_upload
- filename = 'mona_lisa.jpg'
- path = "#{FILES_DIR}/#{filename}"
- assert_deprecated {
- post :test_file_upload, file: Rack::Test::UploadedFile.new(path, "image/jpg", true)
- }
- assert_equal '159528', @response.body
+ def test_fixture_file_upload_ignores_nil_fixture_path
+ uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg")
+ assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
end
def test_action_dispatch_uploaded_file_upload
- filename = 'mona_lisa.jpg'
+ filename = "ruby_on_rails.jpg"
path = "#{FILES_DIR}/#{filename}"
post :test_file_upload, params: {
file: Rack::Test::UploadedFile.new(path, "image/jpg", true)
}
- assert_equal '159528', @response.body
+ assert_equal "45142", @response.body
end
def test_test_uploaded_file_exception_when_file_doesnt_exist
- assert_raise(RuntimeError) { Rack::Test::UploadedFile.new('non_existent_file') }
+ assert_raise(RuntimeError) { Rack::Test::UploadedFile.new("non_existent_file") }
end
def test_redirect_url_only_cares_about_location_header
@@ -958,21 +937,41 @@ XML
assert_response :created
# Redirect url doesn't care that it wasn't a :redirect response.
- assert_equal 'created resource', @response.redirect_url
+ assert_equal "/resource", @response.redirect_url
assert_equal @response.redirect_url, redirect_to_url
# Must be a :redirect response.
assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_redirected_to 'created resource'
+ assert_redirected_to "/resource"
+ end
+ end
+
+ def test_exception_in_action_reaches_test
+ assert_raise(RuntimeError) do
+ process :boom, method: "GET"
end
end
+
+ def test_request_state_is_cleared_after_exception
+ assert_raise(RuntimeError) do
+ process :boom,
+ method: "GET",
+ params: { q: "test1" }
+ end
+
+ process :test_query_string,
+ method: "GET",
+ params: { q: "test2" }
+
+ assert_equal "q=test2", @response.body
+ end
end
class ResponseDefaultHeadersTest < ActionController::TestCase
class TestController < ActionController::Base
def remove_header
headers.delete params[:header]
- head :ok, 'C' => '3'
+ head :ok, "C" => "3"
end
# Render a head response, but don't touch default headers
@@ -983,7 +982,7 @@ class ResponseDefaultHeadersTest < ActionController::TestCase
def before_setup
@original = ActionDispatch::Response.default_headers
- @defaults = { 'A' => '1', 'B' => '2' }
+ @defaults = { "A" => "1", "B" => "2" }
ActionDispatch::Response.default_headers = @defaults
super
end
@@ -995,10 +994,12 @@ class ResponseDefaultHeadersTest < ActionController::TestCase
def setup
super
@controller = TestController.new
- @request.env['PATH_INFO'] = nil
+ @request.env["PATH_INFO"] = nil
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
r.draw do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
end
@@ -1007,18 +1008,18 @@ class ResponseDefaultHeadersTest < ActionController::TestCase
get :leave_alone
# Response headers start out with the defaults
- assert_equal @defaults.merge('Content-Type' => 'text/html'), response.headers
+ assert_equal @defaults.merge("Content-Type" => "text/html"), response.headers
end
test "response deletes a default header" do
- get :remove_header, params: { header: 'A' }
+ get :remove_header, params: { header: "A" }
assert_response :ok
# After a request, the response in the test case doesn't have the
# defaults merged on top again.
- assert_not_includes response.headers, 'A'
- assert_includes response.headers, 'B'
- assert_includes response.headers, 'C'
+ assert_not_includes response.headers, "A"
+ assert_includes response.headers, "B"
+ assert_includes response.headers, "C"
end
end
@@ -1027,13 +1028,13 @@ module EngineControllerTests
isolate_namespace EngineControllerTests
routes.draw do
- get '/' => 'bar#index'
+ get "/" => "bar#index"
end
end
class BarController < ActionController::Base
def index
- render plain: 'bar'
+ render plain: "bar"
end
end
@@ -1042,7 +1043,7 @@ module EngineControllerTests
def test_engine_controller_route
get :index
- assert_equal @response.body, 'bar'
+ assert_equal @response.body, "bar"
end
end
@@ -1055,7 +1056,7 @@ module EngineControllerTests
def test_engine_controller_route
get :index
- assert_equal @response.body, 'bar'
+ assert_equal @response.body, "bar"
end
end
end
@@ -1096,7 +1097,7 @@ class CrazySymbolNameTest < ActionController::TestCase
end
class CrazyStringNameTest < ActionController::TestCase
- tests 'content'
+ tests "content"
def test_set_controller_class_using_string
assert_equal ContentController, self.class.controller_class
@@ -1109,8 +1110,8 @@ class NamedRoutesControllerTest < ActionController::TestCase
def test_should_be_able_to_use_named_routes_before_a_request_is_done
with_routing do |set|
set.draw { resources :contents }
- assert_equal 'http://test.host/contents/new', new_content_url
- assert_equal 'http://test.host/contents/1', content_url(id: 1)
+ assert_equal "http://test.host/contents/new", new_content_url
+ assert_equal "http://test.host/contents/1", content_url(id: 1)
end
end
end
@@ -1125,14 +1126,16 @@ class AnonymousControllerTest < ActionController::TestCase
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
r.draw do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
end
def test_controller_name
get :index
- assert_equal 'anonymous', @response.body
+ assert_equal "anonymous", @response.body
end
end
@@ -1150,19 +1153,19 @@ class RoutingDefaultsTest < ActionController::TestCase
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
r.draw do
- get '/posts/:id', to: 'anonymous#post', bucket_type: 'post'
- get '/projects/:id', to: 'anonymous#project', defaults: { bucket_type: 'project' }
+ get "/posts/:id", to: "anonymous#post", bucket_type: "post"
+ get "/projects/:id", to: "anonymous#project", defaults: { bucket_type: "project" }
end
end
end
def test_route_option_can_be_passed_via_process
- get :post, params: { id: 1, bucket_type: 'post'}
- assert_equal '/posts/1', @response.body
+ get :post, params: { id: 1, bucket_type: "post" }
+ assert_equal "/posts/1", @response.body
end
def test_route_default_is_not_required_for_building_request_uri
get :project, params: { id: 2 }
- assert_equal '/projects/2', @response.body
+ assert_equal "/projects/2", @response.body
end
end
diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb
index dfc2712e3e..a1521da702 100644
--- a/actionpack/test/controller/url_for_integration_test.rb
+++ b/actionpack/test/controller/url_for_integration_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
-require 'active_support/core_ext/object/with_options'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
+require "active_support/core_ext/object/with_options"
module ActionPack
class URLForIntegrationTest < ActiveSupport::TestCase
@@ -14,51 +16,53 @@ module ActionPack
resources :users, :posts
end
- namespace 'api' do
- root :to => 'users#index'
+ namespace "api" do
+ root to: "users#index"
end
- get '/blog(/:year(/:month(/:day)))' => 'posts#show_date',
+ get "/blog(/:year(/:month(/:day)))" => "posts#show_date",
:constraints => {
- :year => /(19|20)\d\d/,
- :month => /[01]?\d/,
- :day => /[0-3]?\d/
+ year: /(19|20)\d\d/,
+ month: /[01]?\d/,
+ day: /[0-3]?\d/
},
:day => nil,
:month => nil
- get 'archive/:year', :controller => 'archive', :action => 'index',
- :defaults => { :year => nil },
- :constraints => { :year => /\d{4}/ },
- :as => "blog"
+ get "archive/:year", controller: "archive", action: "index",
+ defaults: { year: nil },
+ constraints: { year: /\d{4}/ },
+ as: "blog"
resources :people
- #match 'legacy/people' => "people#index", :legacy => "true"
-
- get 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol
- get 'id_default(/:id)' => "foo#id_default", :id => 1
- match 'get_or_post' => "foo#get_or_post", :via => [:get, :post]
- get 'optional/:optional' => "posts#index"
- get 'projects/:project_id' => "project#index", :as => "project"
- get 'clients' => "projects#index"
-
- get 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i
- get 'extended/geocode/:postalcode' => 'geocode#show',:constraints => {
- :postalcode => /# Postcode format
+
+ get "symbols", controller: :symbols, action: :show, name: :as_symbol
+ get "id_default(/:id)" => "foo#id_default", :id => 1
+ match "get_or_post" => "foo#get_or_post", :via => [:get, :post]
+ get "optional/:optional" => "posts#index"
+ get "projects/:project_id" => "project#index", :as => "project"
+ get "clients" => "projects#index"
+
+ get "ignorecase/geocode/:postalcode" => "geocode#show", :postalcode => /hx\d\d-\d[a-z]{2}/i
+ get "extended/geocode/:postalcode" => "geocode#show", :constraints => {
+ postalcode: /# Postcode format
\d{5} #Prefix
(-\d{4})? #Suffix
/x
}, :as => "geocode"
- get 'news(.:format)' => "news#index"
+ get "news(.:format)" => "news#index"
+
+ ActiveSupport::Deprecation.silence {
+ get "comment/:id(/:action)" => "comments#show"
+ get "ws/:controller(/:action(/:id))", ws: true
+ get "account(/:action)" => "account#subscription"
+ get "pages/:page_id/:controller(/:action(/:id))"
+ get ":controller/ping", action: "ping"
+ get ":controller(/:action(/:id))(.:format)"
+ }
- get 'comment/:id(/:action)' => "comments#show"
- get 'ws/:controller(/:action(/:id))', :ws => true
- get 'account(/:action)' => "account#subscription"
- get 'pages/:page_id/:controller(/:action(/:id))'
- get ':controller/ping', :action => 'ping'
- get ':controller(/:action(/:id))(.:format)'
- root :to => "news#index"
+ root to: "news#index"
}
attr_reader :routes
@@ -70,111 +74,111 @@ module ActionPack
end
[
- ['/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', :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' }]],
-
- ['/blog/2009',[ { :controller => 'posts', :action => 'show_date', :year => 2009 }]],
- ['/blog/2009/1',[ { :controller => 'posts', :action => 'show_date', :year => 2009, :month => 1 }]],
- ['/blog/2009/1/1',[ { :controller => 'posts', :action => 'show_date', :year => 2009, :month => 1, :day => 1 }]],
-
- ['/archive/2010',[ { :controller => 'archive', :action => 'index', :year => '2010' }]],
- ['/archive',[ { :controller => 'archive', :action => 'index' }]],
- ['/archive?year=january',[ { :controller => 'archive', :action => 'index', :year => 'january' }]],
-
- ['/people',[ { :controller => 'people', :action => 'index' }]],
- ['/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' }]],
- ['/people/1',[ { :controller => 'people', :action => 'show', :id => '1' }]],
- ['/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']],
- ['/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' }]],
- ['/people/1?legacy=true',[ { :controller => 'people', :action => 'show', :id => '1', :legacy => 'true' }]],
- ['/people?legacy=true',[ { :controller => 'people', :action => 'index', :legacy => 'true' }]],
-
- ['/id_default/2',[ { :controller => 'foo', :action => 'id_default', :id => '2' }]],
- ['/id_default',[ { :controller => 'foo', :action => 'id_default', :id => '1' }]],
- ['/id_default',[ { :controller => 'foo', :action => 'id_default', :id => 1 }]],
- ['/id_default',[ { :controller => 'foo', :action => 'id_default' }]],
- ['/optional/bar',[ { :controller => 'posts', :action => 'index', :optional => 'bar' }]],
- ['/posts',[ { :controller => 'posts', :action => 'index' }]],
-
- ['/project',[ { :controller => 'project', :action => 'index' }]],
- ['/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' }, { :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', :controller => 'project', :action => 'index' }, '/projects/1']],
-
- ['/comment/20',[ { :id => 20 }, { :controller => 'comments', :action => 'show' }, '/comments/show']],
- ['/comment/20',[ { :controller => 'comments', :id => 20, :action => 'show' }]],
- ['/comments/boo',[ { :controller => 'comments', :action => 'boo' }]],
-
- ['/ws/posts/show/1',[ { :controller => 'posts', :action => 'show', :id => '1', :ws => true }]],
- ['/ws/posts',[ { :controller => 'posts', :action => 'index', :ws => true }]],
-
- ['/account',[ { :controller => 'account', :action => 'subscription' }]],
- ['/account/billing',[ { :controller => 'account', :action => 'billing' }]],
-
- ['/pages/1/notes/show/1',[ { :page_id => '1', :controller => 'notes', :action => 'show', :id => '1' }]],
- ['/pages/1/notes/list',[ { :page_id => '1', :controller => 'notes', :action => 'list' }]],
- ['/pages/1/notes',[ { :page_id => '1', :controller => 'notes', :action => 'index' }]],
- ['/pages/1/notes',[ { :page_id => '1', :controller => 'notes' }]],
- ['/notes',[ { :page_id => nil, :controller => 'notes' }]],
- ['/notes',[ { :controller => 'notes' }]],
- ['/notes/print',[ { :controller => 'notes', :action => 'print' }]],
- ['/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/show/1',[ { :controller => 'posts', :action => 'show', :id => '1', :format => '' }]],
- ['/posts',[ { :controller => 'posts' }]],
- ['/posts',[ { :controller => 'posts', :action => 'index' }]],
- ['/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 }]],
- ['/posts?q%5Bfoo%5D%5Ba%5D=b', [{ :controller => 'posts', :q => { :foo => { :a => 'b'}} }]],
-
- ['/news.rss', [{ :controller => 'news', :action => 'index', :format => 'rss' }]],
+ ["/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", 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" }]],
+
+ ["/blog/2009", [ { controller: "posts", action: "show_date", year: 2009 }]],
+ ["/blog/2009/1", [ { controller: "posts", action: "show_date", year: 2009, month: 1 }]],
+ ["/blog/2009/1/1", [ { controller: "posts", action: "show_date", year: 2009, month: 1, day: 1 }]],
+
+ ["/archive/2010", [ { controller: "archive", action: "index", year: "2010" }]],
+ ["/archive", [ { controller: "archive", action: "index" }]],
+ ["/archive?year=january", [ { controller: "archive", action: "index", year: "january" }]],
+
+ ["/people", [ { controller: "people", action: "index" }]],
+ ["/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" }]],
+ ["/people/1", [ { controller: "people", action: "show", id: "1" }]],
+ ["/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"]],
+ ["/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" }]],
+ ["/people/1?legacy=true", [ { controller: "people", action: "show", id: "1", legacy: "true" }]],
+ ["/people?legacy=true", [ { controller: "people", action: "index", legacy: "true" }]],
+
+ ["/id_default/2", [ { controller: "foo", action: "id_default", id: "2" }]],
+ ["/id_default", [ { controller: "foo", action: "id_default", id: "1" }]],
+ ["/id_default", [ { controller: "foo", action: "id_default", id: 1 }]],
+ ["/id_default", [ { controller: "foo", action: "id_default" }]],
+ ["/optional/bar", [ { controller: "posts", action: "index", optional: "bar" }]],
+ ["/posts", [ { controller: "posts", action: "index" }]],
+
+ ["/project", [ { controller: "project", action: "index" }]],
+ ["/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" }, { 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", controller: "project", action: "index" }, "/projects/1"]],
+
+ ["/comment/20", [ { id: 20 }, { controller: "comments", action: "show" }, "/comments/show"]],
+ ["/comment/20", [ { controller: "comments", id: 20, action: "show" }]],
+ ["/comments/boo", [ { controller: "comments", action: "boo" }]],
+
+ ["/ws/posts/show/1", [ { controller: "posts", action: "show", id: "1", ws: true }]],
+ ["/ws/posts", [ { controller: "posts", action: "index", ws: true }]],
+
+ ["/account", [ { controller: "account", action: "subscription" }]],
+ ["/account/billing", [ { controller: "account", action: "billing" }]],
+
+ ["/pages/1/notes/show/1", [ { page_id: "1", controller: "notes", action: "show", id: "1" }]],
+ ["/pages/1/notes/list", [ { page_id: "1", controller: "notes", action: "list" }]],
+ ["/pages/1/notes", [ { page_id: "1", controller: "notes", action: "index" }]],
+ ["/pages/1/notes", [ { page_id: "1", controller: "notes" }]],
+ ["/notes", [ { page_id: nil, controller: "notes" }]],
+ ["/notes", [ { controller: "notes" }]],
+ ["/notes/print", [ { controller: "notes", action: "print" }]],
+ ["/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/show/1", [ { controller: "posts", action: "show", id: "1", format: "" }]],
+ ["/posts", [ { controller: "posts" }]],
+ ["/posts", [ { controller: "posts", action: "index" }]],
+ ["/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 }]],
+ ["/posts?q%5Bfoo%5D%5Ba%5D=b", [{ controller: "posts", q: { foo: { a: "b" } } }]],
+
+ ["/news.rss", [{ controller: "news", action: "index", format: "rss" }]],
].each_with_index do |(url, params), i|
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)
+ 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
diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb
index 78e883f134..e381abee36 100644
--- a/actionpack/test/controller/url_for_test.rb
+++ b/actionpack/test/controller/url_for_test.rb
@@ -1,10 +1,18 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module AbstractController
module Testing
class UrlForTest < ActionController::TestCase
class W
- include ActionDispatch::Routing::RouteSet.new.tap { |r| r.draw { get ':controller(/:action(/:id(.:format)))' } }.url_helpers
+ include ActionDispatch::Routing::RouteSet.new.tap { |r|
+ r.draw {
+ ActiveSupport::Deprecation.silence {
+ get ":controller(/:action(/:id(.:format)))"
+ }
+ }
+ }.url_helpers
end
def teardown
@@ -15,23 +23,23 @@ module AbstractController
klass = Class.new {
include ActionDispatch::Routing::RouteSet.new.tap { |r|
r.draw {
- get "/foo/(:bar/(:baz))/:zot", :as => 'fun',
- :controller => :articles,
- :action => :index
+ get "/foo/(:bar/(:baz))/:zot", as: "fun",
+ controller: :articles,
+ action: :index
}
}.url_helpers
- self.default_url_options[:host] = 'example.com'
+ default_url_options[:host] = "example.com"
}
- path = klass.new.fun_path({:controller => :articles,
- :baz => "baz",
- :zot => "zot"})
+ path = klass.new.fun_path(controller: :articles,
+ baz: "baz",
+ zot: "zot")
# :bar key isn't provided
- assert_equal '/foo/zot', path
+ assert_equal "/foo/zot", path
end
def add_host!(app = W)
- app.default_url_options[:host] = 'www.basecamphq.com'
+ app.default_url_options[:host] = "www.basecamphq.com"
end
def add_port!
@@ -39,166 +47,166 @@ module AbstractController
end
def add_numeric_host!
- W.default_url_options[:host] = '127.0.0.1'
+ W.default_url_options[:host] = "127.0.0.1"
end
def test_exception_is_thrown_without_host
assert_raise ArgumentError do
- W.new.url_for :controller => 'c', :action => 'a', :id => 'i'
+ W.new.url_for controller: "c", action: "a", id: "i"
end
end
def test_anchor
- assert_equal('/c/a#anchor',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => 'anchor')
+ assert_equal("/c/a#anchor",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: "anchor")
)
end
def test_nil_anchor
assert_equal(
- '/c/a',
- W.new.url_for(only_path: true, controller: 'c', action: 'a', anchor: nil)
+ "/c/a",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: nil)
)
end
def test_false_anchor
assert_equal(
- '/c/a',
- W.new.url_for(only_path: true, controller: 'c', action: 'a', anchor: false)
+ "/c/a",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: false)
)
end
def test_anchor_should_call_to_param
- assert_equal('/c/a#anchor',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anchor'))
+ assert_equal("/c/a#anchor",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: Struct.new(:to_param).new("anchor"))
)
end
def test_anchor_should_escape_unsafe_pchar
- assert_equal('/c/a#%23anchor',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('#anchor'))
+ assert_equal("/c/a#%23anchor",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: Struct.new(:to_param).new("#anchor"))
)
end
def test_anchor_should_not_escape_safe_pchar
- assert_equal('/c/a#name=user&email=user@domain.com',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('name=user&email=user@domain.com'))
+ assert_equal("/c/a#name=user&email=user@domain.com",
+ W.new.url_for(only_path: true, controller: "c", action: "a", anchor: Struct.new(:to_param).new("name=user&email=user@domain.com"))
)
end
def test_default_host
add_host!
- assert_equal('http://www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i")
)
end
def test_host_may_be_overridden
add_host!
- assert_equal('http://37signals.basecamphq.com/c/a/i',
- W.new.url_for(:host => '37signals.basecamphq.com', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://37signals.basecamphq.com/c/a/i",
+ W.new.url_for(host: "37signals.basecamphq.com", controller: "c", action: "a", id: "i")
)
end
def test_subdomain_may_be_changed
add_host!
- assert_equal('http://api.basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => 'api', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://api.basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: "api", controller: "c", action: "a", id: "i")
)
end
def test_subdomain_may_be_object
- model = Class.new { def self.to_param; 'api'; end }
+ model = Class.new { def self.to_param; "api"; end }
add_host!
- assert_equal('http://api.basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => model, :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://api.basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: model, controller: "c", action: "a", id: "i")
)
end
def test_subdomain_may_be_removed
add_host!
- assert_equal('http://basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => false, :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: false, controller: "c", action: "a", id: "i")
)
end
def test_subdomain_may_be_removed_with_blank_string
- W.default_url_options[:host] = 'api.basecamphq.com'
- assert_equal('http://basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => '', :controller => 'c', :action => 'a', :id => 'i')
+ W.default_url_options[:host] = "api.basecamphq.com"
+ assert_equal("http://basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: "", controller: "c", action: "a", id: "i")
)
end
def test_multiple_subdomains_may_be_removed
- W.default_url_options[:host] = 'mobile.www.api.basecamphq.com'
- assert_equal('http://basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => false, :controller => 'c', :action => 'a', :id => 'i')
+ W.default_url_options[:host] = "mobile.www.api.basecamphq.com"
+ assert_equal("http://basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: false, controller: "c", action: "a", id: "i")
)
end
def test_subdomain_may_be_accepted_with_numeric_host
add_numeric_host!
- assert_equal('http://127.0.0.1/c/a/i',
- W.new.url_for(:subdomain => 'api', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://127.0.0.1/c/a/i",
+ W.new.url_for(subdomain: "api", controller: "c", action: "a", id: "i")
)
end
def test_domain_may_be_changed
add_host!
- assert_equal('http://www.37signals.com/c/a/i',
- W.new.url_for(:domain => '37signals.com', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://www.37signals.com/c/a/i",
+ W.new.url_for(domain: "37signals.com", controller: "c", action: "a", id: "i")
)
end
def test_tld_length_may_be_changed
add_host!
- assert_equal('http://mobile.www.basecamphq.com/c/a/i',
- W.new.url_for(:subdomain => 'mobile', :tld_length => 2, :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://mobile.www.basecamphq.com/c/a/i",
+ W.new.url_for(subdomain: "mobile", tld_length: 2, controller: "c", action: "a", id: "i")
)
end
def test_port
add_host!
- assert_equal('http://www.basecamphq.com:3000/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :port => 3000)
+ assert_equal("http://www.basecamphq.com:3000/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", port: 3000)
)
end
def test_default_port
add_host!
add_port!
- assert_equal('http://www.basecamphq.com:3000/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("http://www.basecamphq.com:3000/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i")
)
end
def test_protocol
add_host!
- assert_equal('https://www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https')
+ assert_equal("https://www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https")
)
end
def test_protocol_with_and_without_separators
add_host!
- assert_equal('https://www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https')
+ assert_equal("https://www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https")
)
- assert_equal('https://www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https:')
+ assert_equal("https://www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https:")
)
- assert_equal('https://www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https://')
+ assert_equal("https://www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https://")
)
end
def test_without_protocol
add_host!
- assert_equal('//www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => '//')
+ assert_equal("//www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "//")
)
- assert_equal('//www.basecamphq.com/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => false)
+ assert_equal("//www.basecamphq.com/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: false)
)
end
@@ -206,192 +214,202 @@ module AbstractController
add_host!
add_port!
- assert_equal('//www.basecamphq.com:3000/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => '//')
+ assert_equal("//www.basecamphq.com:3000/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "//")
)
- assert_equal('//www.basecamphq.com:3000/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => false)
+ assert_equal("//www.basecamphq.com:3000/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: false)
)
end
def test_trailing_slash
add_host!
- options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'}
- assert_equal('http://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) )
+ options = { controller: "foo", trailing_slash: true, action: "bar", id: "33" }
+ assert_equal("http://www.basecamphq.com/foo/bar/33/", W.new.url_for(options))
end
def test_trailing_slash_with_protocol
add_host!
- options = { :trailing_slash => true,:protocol => 'https', :controller => 'foo', :action => 'bar', :id => '33'}
- assert_equal('https://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) )
- assert_equal 'https://www.basecamphq.com/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string'}))
+ options = { trailing_slash: true, protocol: "https", controller: "foo", action: "bar", id: "33" }
+ assert_equal("https://www.basecamphq.com/foo/bar/33/", W.new.url_for(options))
+ assert_equal "https://www.basecamphq.com/foo/bar/33/?query=string", W.new.url_for(options.merge(query: "string"))
end
def test_trailing_slash_with_only_path
- options = {:controller => 'foo', :trailing_slash => true}
- assert_equal '/foo/', W.new.url_for(options.merge({:only_path => true}))
- options.update({:action => 'bar', :id => '33'})
- assert_equal '/foo/bar/33/', W.new.url_for(options.merge({:only_path => true}))
- assert_equal '/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string',:only_path => true}))
+ options = { controller: "foo", trailing_slash: true }
+ assert_equal "/foo/", W.new.url_for(options.merge(only_path: true))
+ options.update(action: "bar", id: "33")
+ assert_equal "/foo/bar/33/", W.new.url_for(options.merge(only_path: true))
+ assert_equal "/foo/bar/33/?query=string", W.new.url_for(options.merge(query: "string", only_path: true))
end
def test_trailing_slash_with_anchor
- options = {:trailing_slash => true, :controller => 'foo', :action => 'bar', :id => '33', :only_path => true, :anchor=> 'chapter7'}
- assert_equal '/foo/bar/33/#chapter7', W.new.url_for(options)
- assert_equal '/foo/bar/33/?query=string#chapter7', W.new.url_for(options.merge({:query => 'string'}))
+ options = { trailing_slash: true, controller: "foo", action: "bar", id: "33", only_path: true, anchor: "chapter7" }
+ assert_equal "/foo/bar/33/#chapter7", W.new.url_for(options)
+ assert_equal "/foo/bar/33/?query=string#chapter7", W.new.url_for(options.merge(query: "string"))
end
def test_trailing_slash_with_params
- url = W.new.url_for(:trailing_slash => true, :only_path => true, :controller => 'cont', :action => 'act', :p1 => 'cafe', :p2 => 'link')
+ url = W.new.url_for(trailing_slash: true, only_path: true, controller: "cont", action: "act", p1: "cafe", p2: "link")
params = extract_params(url)
- assert_equal({p1: 'cafe'}.to_query, params[0])
- assert_equal({p2: 'link'}.to_query, params[1])
+ assert_equal({ p1: "cafe" }.to_query, params[0])
+ assert_equal({ p2: "link" }.to_query, params[1])
end
def test_relative_url_root_is_respected
add_host!
- assert_equal('https://www.basecamphq.com/subdir/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :script_name => '/subdir')
+ assert_equal("https://www.basecamphq.com/subdir/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https", script_name: "/subdir")
)
end
def test_relative_url_root_is_respected_with_environment_variable
# `config.relative_url_root` is set by ENV['RAILS_RELATIVE_URL_ROOT']
w = Class.new {
- config = ActionDispatch::Routing::RouteSet::Config.new '/subdir'
+ config = ActionDispatch::Routing::RouteSet::Config.new "/subdir"
r = ActionDispatch::Routing::RouteSet.new(config)
- r.draw { get ':controller(/:action(/:id(.:format)))' }
+ r.draw { ActiveSupport::Deprecation.silence { get ":controller(/:action(/:id(.:format)))" } }
include r.url_helpers
}
add_host!(w)
- assert_equal('https://www.basecamphq.com/subdir/c/a/i',
- w.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https')
+ assert_equal("https://www.basecamphq.com/subdir/c/a/i",
+ w.new.url_for(controller: "c", action: "a", id: "i", protocol: "https")
)
end
def test_named_routes
with_routing do |set|
set.draw do
- get 'this/is/verbose', :to => 'home#index', :as => :no_args
- get 'home/sweet/home/:user', :to => 'home#index', :as => :home
+ get "this/is/verbose", to: "home#index", as: :no_args
+ get "home/sweet/home/:user", to: "home#index", as: :home
end
# 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_equal 'http://www.basecamphq.com/home/sweet/home/again',
- controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again')
+ assert_respond_to controller, :home_url
+ assert_equal "http://www.basecamphq.com/home/sweet/home/again",
+ controller.send(:home_url, host: "www.basecamphq.com", user: "again")
- assert_equal("/home/sweet/home/alabama", controller.send(:home_path, :user => 'alabama', :host => 'unused'))
- assert_equal("http://www.basecamphq.com/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'www.basecamphq.com'))
- assert_equal("http://www.basecamphq.com/this/is/verbose", controller.send(:no_args_url, :host=>'www.basecamphq.com'))
+ assert_equal("/home/sweet/home/alabama", controller.send(:home_path, user: "alabama", host: "unused"))
+ assert_equal("http://www.basecamphq.com/home/sweet/home/alabama", controller.send(:home_url, user: "alabama", host: "www.basecamphq.com"))
+ assert_equal("http://www.basecamphq.com/this/is/verbose", controller.send(:no_args_url, host: "www.basecamphq.com"))
end
end
def test_relative_url_root_is_respected_for_named_routes
with_routing do |set|
set.draw do
- get '/home/sweet/home/:user', :to => 'home#index', :as => :home
+ get "/home/sweet/home/:user", to: "home#index", as: :home
end
kls = Class.new { include set.url_helpers }
controller = kls.new
- assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again',
- controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :script_name => "/subdir")
+ assert_equal "http://www.basecamphq.com/subdir/home/sweet/home/again",
+ controller.send(:home_url, host: "www.basecamphq.com", user: "again", script_name: "/subdir")
end
end
def test_using_nil_script_name_properly_concats_with_original_script_name
add_host!
- assert_equal('https://www.basecamphq.com/subdir/c/a/i',
- W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :script_name => nil, :original_script_name => '/subdir')
+ assert_equal("https://www.basecamphq.com/subdir/c/a/i",
+ W.new.url_for(controller: "c", action: "a", id: "i", protocol: "https", script_name: nil, original_script_name: "/subdir")
)
end
def test_only_path
with_routing do |set|
set.draw do
- get 'home/sweet/home/:user', :to => 'home#index', :as => :home
- get ':controller/:action/:id'
+ get "home/sweet/home/:user", to: "home#index", as: :home
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/:id"
+ end
end
# 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_respond_to controller, :home_url
- assert_equal '/brave/new/world',
- controller.url_for(:controller => 'brave', :action => 'new', :id => 'world', :only_path => true)
+ assert_equal "/brave/new/world",
+ controller.url_for(controller: "brave", action: "new", id: "world", only_path: true)
- assert_equal("/home/sweet/home/alabama", controller.home_path(:user => 'alabama', :host => 'unused'))
- assert_equal("/home/sweet/home/alabama", controller.home_path('alabama'))
+ assert_equal("/home/sweet/home/alabama", controller.home_path(user: "alabama", host: "unused"))
+ assert_equal("/home/sweet/home/alabama", controller.home_path("alabama"))
end
end
def test_one_parameter
- assert_equal('/c/a?param=val',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val')
+ assert_equal("/c/a?param=val",
+ W.new.url_for(only_path: true, controller: "c", action: "a", param: "val")
)
end
def test_two_parameters
- url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2')
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", p1: "X1", p2: "Y2")
params = extract_params(url)
- assert_equal({p1: 'X1'}.to_query, params[0])
- assert_equal({p2: 'Y2'}.to_query, params[1])
+ assert_equal({ p1: "X1" }.to_query, params[0])
+ assert_equal({ p2: "Y2" }.to_query, params[1])
end
def test_hash_parameter
- url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'})
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", query: { name: "Bob", category: "prof" })
params = extract_params(url)
- assert_equal({'query[category]' => 'prof'}.to_query, params[0])
- assert_equal({'query[name]' => 'Bob'}.to_query, params[1])
+ assert_equal({ "query[category]" => "prof" }.to_query, params[0])
+ assert_equal({ "query[name]" => "Bob" }.to_query, params[1])
end
def test_array_parameter
- url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof'])
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", query: ["Bob", "prof"])
params = extract_params(url)
- assert_equal({'query[]' => 'Bob'}.to_query, params[0])
- assert_equal({'query[]' => 'prof'}.to_query, params[1])
+ assert_equal({ "query[]" => "Bob" }.to_query, params[0])
+ assert_equal({ "query[]" => "prof" }.to_query, params[1])
end
def test_hash_recursive_parameters
- url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'})
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", query: { person: { name: "Bob", position: "prof" }, hobby: "piercing" })
params = extract_params(url)
- assert_equal({'query[hobby]' => 'piercing'}.to_query, params[0])
- assert_equal({'query[person][name]' => 'Bob' }.to_query, params[1])
- assert_equal({'query[person][position]' => 'prof' }.to_query, params[2])
+ assert_equal({ "query[hobby]" => "piercing" }.to_query, params[0])
+ assert_equal({ "query[person][name]" => "Bob" }.to_query, params[1])
+ assert_equal({ "query[person][position]" => "prof" }.to_query, params[2])
end
def test_hash_recursive_and_array_parameters
- url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'})
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", id: 101, query: { person: { name: "Bob", position: ["prof", "art director"] }, hobby: "piercing" })
assert_match(%r(^/c/a/101), url)
params = extract_params(url)
- assert_equal({'query[hobby]' => 'piercing' }.to_query, params[0])
- assert_equal({'query[person][name]' => 'Bob' }.to_query, params[1])
- assert_equal({'query[person][position][]' => 'art director'}.to_query, params[2])
- assert_equal({'query[person][position][]' => 'prof' }.to_query, params[3])
+ assert_equal({ "query[hobby]" => "piercing" }.to_query, params[0])
+ assert_equal({ "query[person][name]" => "Bob" }.to_query, params[1])
+ assert_equal({ "query[person][position][]" => "art director" }.to_query, params[2])
+ assert_equal({ "query[person][position][]" => "prof" }.to_query, params[3])
+ end
+
+ def test_url_action_controller_parameters
+ add_host!
+ assert_raise(ActionController::UnfilteredParameters) do
+ W.new.url_for(ActionController::Parameters.new(controller: "c", action: "a", protocol: "javascript", f: "%0Aeval(name)"))
+ end
end
def test_path_generation_for_symbol_parameter_keys
- assert_generates("/image", :controller=> :image)
+ assert_generates("/image", controller: :image)
end
def test_named_routes_with_nil_keys
with_routing do |set|
set.draw do
- get 'posts.:format', :to => 'posts#index', :as => :posts
- get '/', :to => 'posts#index', :as => :main
+ get "posts.:format", to: "posts#index", as: :posts
+ get "/", to: "posts#index", as: :main
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include set.url_helpers }
- kls.default_url_options[:host] = 'www.basecamphq.com'
+ kls.default_url_options[:host] = "www.basecamphq.com"
controller = kls.new
- params = {:action => :index, :controller => :posts, :format => :xml}
+ params = { action: :index, controller: :posts, format: :xml }
assert_equal("http://www.basecamphq.com/posts.xml", controller.send(:url_for, params))
params[:format] = nil
assert_equal("http://www.basecamphq.com/", controller.send(:url_for, params))
@@ -402,35 +420,35 @@ module AbstractController
first_class = Class.new { include ActionController::UrlFor }
second_class = Class.new { include ActionController::UrlFor }
- first_host, second_host = 'firsthost.com', 'secondhost.com'
+ first_host, second_host = "firsthost.com", "secondhost.com"
first_class.default_url_options[:host] = first_host
second_class.default_url_options[:host] = second_host
- assert_equal first_host, first_class.default_url_options[:host]
+ assert_equal first_host, first_class.default_url_options[:host]
assert_equal second_host, second_class.default_url_options[:host]
end
def test_with_stringified_keys
- assert_equal("/c", W.new.url_for('controller' => 'c', 'only_path' => true))
- assert_equal("/c/a", W.new.url_for('controller' => 'c', 'action' => 'a', 'only_path' => true))
+ assert_equal("/c", W.new.url_for("controller" => "c", "only_path" => true))
+ assert_equal("/c/a", W.new.url_for("controller" => "c", "action" => "a", "only_path" => true))
end
def test_with_hash_with_indifferent_access
- W.default_url_options[:controller] = 'd'
+ W.default_url_options[:controller] = "d"
W.default_url_options[:only_path] = false
- assert_equal("/c", W.new.url_for(ActiveSupport::HashWithIndifferentAccess.new('controller' => 'c', 'only_path' => true)))
+ assert_equal("/c", W.new.url_for(ActiveSupport::HashWithIndifferentAccess.new("controller" => "c", "only_path" => true)))
- W.default_url_options[:action] = 'b'
- assert_equal("/c/a", W.new.url_for(ActiveSupport::HashWithIndifferentAccess.new('controller' => 'c', 'action' => 'a', 'only_path' => true)))
+ W.default_url_options[:action] = "b"
+ assert_equal("/c/a", W.new.url_for(ActiveSupport::HashWithIndifferentAccess.new("controller" => "c", "action" => "a", "only_path" => true)))
end
def test_url_params_with_nil_to_param_are_not_in_url
- assert_equal("/c/a", W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => Struct.new(:to_param).new(nil)))
+ assert_equal("/c/a", W.new.url_for(only_path: true, controller: "c", action: "a", id: Struct.new(:to_param).new(nil)))
end
def test_false_url_params_are_included_in_query
- assert_equal("/c/a?show=false", W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :show => false))
+ assert_equal("/c/a?show=false", W.new.url_for(only_path: true, controller: "c", action: "a", show: false))
end
def test_url_generation_with_array_and_hash
@@ -442,11 +460,11 @@ module AbstractController
end
kls = Class.new { include set.url_helpers }
- kls.default_url_options[:host] = 'www.basecamphq.com'
+ kls.default_url_options[:host] = "www.basecamphq.com"
controller = kls.new
assert_equal("http://www.basecamphq.com/admin/posts/new?param=value",
- controller.send(:url_for, [:new, :admin, :post, { param: 'value' }])
+ controller.send(:url_for, [:new, :admin, :post, { param: "value" }])
)
end
end
@@ -460,9 +478,9 @@ module AbstractController
end
kls = Class.new { include set.url_helpers }
- kls.default_url_options[:host] = 'www.basecamphq.com'
+ kls.default_url_options[:host] = "www.basecamphq.com"
- original_components = [:new, :admin, :post, { param: 'value' }]
+ original_components = [:new, :admin, :post, { param: "value" }]
components = original_components.dup
kls.new.url_for(components)
@@ -471,9 +489,30 @@ module AbstractController
end
end
+ def test_default_params_first_empty
+ with_routing do |set|
+ set.draw do
+ get "(:param1)/test(/:param2)" => "index#index",
+ defaults: {
+ param1: 1,
+ param2: 2
+ },
+ constraints: {
+ param1: /\d*/,
+ param2: /\d+/
+ }
+ end
+
+ kls = Class.new { include set.url_helpers }
+ kls.default_url_options[:host] = "www.basecamphq.com"
+
+ assert_equal "http://www.basecamphq.com/test", kls.new.url_for(controller: "index", param1: "1")
+ end
+ end
+
private
def extract_params(url)
- url.split('?', 2).last.split('&').sort
+ url.split("?", 2).last.split("&").sort
end
end
end
diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb
index 5f2abc9606..ca83b850d5 100644
--- a/actionpack/test/controller/url_rewriter_test.rb
+++ b/actionpack/test/controller/url_rewriter_test.rb
@@ -1,12 +1,14 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
class UrlRewriterTests < ActionController::TestCase
class Rewriter
def initialize(request)
@options = {
- :host => request.host_with_port,
- :protocol => request.protocol
+ host: request.host_with_port,
+ protocol: request.protocol
}
end
@@ -17,73 +19,74 @@ class UrlRewriterTests < ActionController::TestCase
def setup
@params = {}
- @rewriter = Rewriter.new(@request) #.new(@request, @params)
+ @rewriter = Rewriter.new(@request)
@routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
r.draw do
- get ':controller(/:action(/:id))'
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))"
+ end
end
end
end
def test_port
- assert_equal('http://test.host:1271/c/a/i',
- @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :port => 1271)
+ assert_equal("http://test.host:1271/c/a/i",
+ @rewriter.rewrite(@routes, controller: "c", action: "a", id: "i", port: 1271)
)
end
def test_protocol_with_and_without_separator
- assert_equal('https://test.host/c/a/i',
- @rewriter.rewrite(@routes, :protocol => 'https', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("https://test.host/c/a/i",
+ @rewriter.rewrite(@routes, protocol: "https", controller: "c", action: "a", id: "i")
)
- assert_equal('https://test.host/c/a/i',
- @rewriter.rewrite(@routes, :protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i')
+ assert_equal("https://test.host/c/a/i",
+ @rewriter.rewrite(@routes, protocol: "https://", controller: "c", action: "a", id: "i")
)
end
def test_user_name_and_password
assert_equal(
- 'http://david:secret@test.host/c/a/i',
- @rewriter.rewrite(@routes, :user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i')
+ "http://david:secret@test.host/c/a/i",
+ @rewriter.rewrite(@routes, user: "david", password: "secret", controller: "c", action: "a", id: "i")
)
end
def test_user_name_and_password_with_escape_codes
assert_equal(
- 'http://openid.aol.com%2Fnextangler:one+two%3F@test.host/c/a/i',
- @rewriter.rewrite(@routes, :user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i')
+ "http://openid.aol.com%2Fnextangler:one+two%3F@test.host/c/a/i",
+ @rewriter.rewrite(@routes, user: "openid.aol.com/nextangler", password: "one two?", controller: "c", action: "a", id: "i")
)
end
def test_anchor
assert_equal(
- 'http://test.host/c/a/i#anchor',
- @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor')
+ "http://test.host/c/a/i#anchor",
+ @rewriter.rewrite(@routes, controller: "c", action: "a", id: "i", anchor: "anchor")
)
end
def test_anchor_should_call_to_param
assert_equal(
- 'http://test.host/c/a/i#anchor',
- @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor'))
+ "http://test.host/c/a/i#anchor",
+ @rewriter.rewrite(@routes, controller: "c", action: "a", id: "i", anchor: Struct.new(:to_param).new("anchor"))
)
end
def test_anchor_should_be_uri_escaped
assert_equal(
- 'http://test.host/c/a/i#anc/hor',
- @rewriter.rewrite(@routes, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor'))
+ "http://test.host/c/a/i#anc/hor",
+ @rewriter.rewrite(@routes, controller: "c", action: "a", id: "i", anchor: Struct.new(:to_param).new("anc/hor"))
)
end
def test_trailing_slash
- options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true}
- assert_equal '/foo/bar/3', @rewriter.rewrite(@routes, options)
- assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(@routes, options.merge({:query => 'string'}))
- options.update({:trailing_slash => true})
- assert_equal '/foo/bar/3/', @rewriter.rewrite(@routes, options)
- options.update({:query => 'string'})
- assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(@routes, options)
+ options = { controller: "foo", action: "bar", id: "3", only_path: true }
+ assert_equal "/foo/bar/3", @rewriter.rewrite(@routes, options)
+ assert_equal "/foo/bar/3?query=string", @rewriter.rewrite(@routes, options.merge(query: "string"))
+ options.update(trailing_slash: true)
+ assert_equal "/foo/bar/3/", @rewriter.rewrite(@routes, options)
+ options.update(query: "string")
+ assert_equal "/foo/bar/3/?query=string", @rewriter.rewrite(@routes, options)
end
end
-
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 6d377c4691..4a10637b54 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'active_support/json/decoding'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/json/decoding"
class WebServiceTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -7,7 +9,7 @@ class WebServiceTest < ActionDispatch::IntegrationTest
if params[:full]
render plain: dump_params_keys
else
- render plain: (params.keys - ['controller', 'action']).sort.join(", ")
+ render plain: (params.keys - ["controller", "action"]).sort.join(", ")
end
end
@@ -21,8 +23,8 @@ class WebServiceTest < ActionDispatch::IntegrationTest
value = ""
end
- s << ", " unless s.empty?
- s << "#{k}#{value}"
+ s += ", " unless s.empty?
+ s += "#{k}#{value}"
end
end
end
@@ -35,7 +37,7 @@ class WebServiceTest < ActionDispatch::IntegrationTest
def test_check_parameters
with_test_route_set do
get "/"
- assert_equal '', @controller.response.body
+ assert_equal "", @controller.response.body
end
end
@@ -43,11 +45,11 @@ class WebServiceTest < ActionDispatch::IntegrationTest
with_test_route_set do
post "/",
params: '{"entry":{"summary":"content..."}}',
- headers: { 'CONTENT_TYPE' => 'application/json' }
+ headers: { "CONTENT_TYPE" => "application/json" }
- assert_equal 'entry', @controller.response.body
+ assert_equal "entry", @controller.response.body
assert @controller.params.has_key?(:entry)
- assert_equal 'content...', @controller.params["entry"]['summary']
+ assert_equal "content...", @controller.params["entry"]["summary"]
end
end
@@ -55,34 +57,34 @@ class WebServiceTest < ActionDispatch::IntegrationTest
with_test_route_set do
put "/",
params: '{"entry":{"summary":"content..."}}',
- headers: { 'CONTENT_TYPE' => 'application/json' }
+ headers: { "CONTENT_TYPE" => "application/json" }
- assert_equal 'entry', @controller.response.body
+ assert_equal "entry", @controller.response.body
assert @controller.params.has_key?(:entry)
- assert_equal 'content...', @controller.params["entry"]['summary']
+ assert_equal "content...", @controller.params["entry"]["summary"]
end
end
def test_register_and_use_json_simple
with_test_route_set do
- with_params_parsers Mime[:json] => Proc.new { |data| ActiveSupport::JSON.decode(data)['request'].with_indifferent_access } do
+ with_params_parsers Mime[:json] => Proc.new { |data| ActiveSupport::JSON.decode(data)["request"].with_indifferent_access } do
post "/",
params: '{"request":{"summary":"content...","title":"JSON"}}',
- headers: { 'CONTENT_TYPE' => 'application/json' }
+ headers: { "CONTENT_TYPE" => "application/json" }
- assert_equal 'summary, title', @controller.response.body
+ assert_equal "summary, title", @controller.response.body
assert @controller.params.has_key?(:summary)
assert @controller.params.has_key?(:title)
- assert_equal 'content...', @controller.params["summary"]
- assert_equal 'JSON', @controller.params["title"]
+ assert_equal "content...", @controller.params["summary"]
+ assert_equal "JSON", @controller.params["title"]
end
end
end
def test_use_json_with_empty_request
with_test_route_set do
- assert_nothing_raised { post "/", headers: { 'CONTENT_TYPE' => 'application/json' } }
- assert_equal '', @controller.response.body
+ assert_nothing_raised { post "/", headers: { "CONTENT_TYPE" => "application/json" } }
+ assert_equal "", @controller.response.body
end
end
@@ -90,20 +92,20 @@ class WebServiceTest < ActionDispatch::IntegrationTest
with_test_route_set do
post "/?full=1",
params: '{"first-key":{"sub-key":"..."}}',
- headers: { 'CONTENT_TYPE' => 'application/json' }
- assert_equal 'action, controller, first-key(sub-key), full', @controller.response.body
- assert_equal "...", @controller.params['first-key']['sub-key']
+ headers: { "CONTENT_TYPE" => "application/json" }
+ assert_equal "action, controller, first-key(sub-key), full", @controller.response.body
+ assert_equal "...", @controller.params["first-key"]["sub-key"]
end
end
def test_parsing_json_doesnot_rescue_exception
req = Class.new(ActionDispatch::Request) do
def params_parsers
- { Mime[:json] => Proc.new { |data| raise Interrupt } }
+ { json: Proc.new { |data| raise Interrupt } }
end
- def content_length; get_header('rack.input').length; end
- end.new({ 'rack.input' => StringIO.new('{"title":"JSON"}}'), 'CONTENT_TYPE' => 'application/json' })
+ def content_length; get_header("rack.input").length; end
+ end.new("rack.input" => StringIO.new('{"title":"JSON"}}'), "CONTENT_TYPE" => "application/json")
assert_raises(Interrupt) do
req.request_parameters
@@ -125,7 +127,7 @@ class WebServiceTest < ActionDispatch::IntegrationTest
def with_test_route_set
with_routing do |set|
set.draw do
- match '/', :to => 'web_service_test/test#assign_parameters', :via => :all
+ match "/", to: "web_service_test/test#assign_parameters", via: :all
end
yield
end
diff --git a/actionpack/test/dispatch/callbacks_test.rb b/actionpack/test/dispatch/callbacks_test.rb
index 5ba76d9ab9..fc80191c02 100644
--- a/actionpack/test/dispatch/callbacks_test.rb
+++ b/actionpack/test/dispatch/callbacks_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class DispatcherTest < ActiveSupport::TestCase
class Foo
@@ -7,7 +9,7 @@ class DispatcherTest < ActiveSupport::TestCase
class DummyApp
def call(env)
- [200, {}, 'response']
+ [200, {}, "response"]
end
end
@@ -35,24 +37,11 @@ class DispatcherTest < ActiveSupport::TestCase
assert_equal 6, Foo.b
end
- def test_to_prepare_and_cleanup_delegation
- prepared = cleaned = false
- ActionDispatch::Callbacks.to_prepare { prepared = true }
- ActionDispatch::Callbacks.to_prepare { cleaned = true }
-
- ActionDispatch::Reloader.prepare!
- assert prepared
-
- ActionDispatch::Reloader.cleanup!
- assert cleaned
- end
-
private
def dispatch(&block)
ActionDispatch::Callbacks.new(block || DummyApp.new).call(
- {'rack.input' => StringIO.new('')}
+ "rack.input" => StringIO.new("")
)
end
-
end
diff --git a/actionpack/test/dispatch/content_disposition_test.rb b/actionpack/test/dispatch/content_disposition_test.rb
new file mode 100644
index 0000000000..3f5959da6e
--- /dev/null
+++ b/actionpack/test/dispatch/content_disposition_test.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+module ActionDispatch
+ class ContentDispositionTest < ActiveSupport::TestCase
+ test "encoding a Latin filename" do
+ disposition = Http::ContentDisposition.new(disposition: :inline, filename: "racecar.jpg")
+
+ assert_equal %(filename="racecar.jpg"), disposition.ascii_filename
+ assert_equal "filename*=UTF-8''racecar.jpg", disposition.utf8_filename
+ assert_equal "inline; #{disposition.ascii_filename}; #{disposition.utf8_filename}", disposition.to_s
+ end
+
+ test "encoding a Latin filename with accented characters" do
+ disposition = Http::ContentDisposition.new(disposition: :inline, filename: "råcëçâr.jpg")
+
+ assert_equal %(filename="racecar.jpg"), disposition.ascii_filename
+ assert_equal "filename*=UTF-8''r%C3%A5c%C3%AB%C3%A7%C3%A2r.jpg", disposition.utf8_filename
+ assert_equal "inline; #{disposition.ascii_filename}; #{disposition.utf8_filename}", disposition.to_s
+ end
+
+ test "encoding a non-Latin filename" do
+ disposition = Http::ContentDisposition.new(disposition: :inline, filename: "автомобиль.jpg")
+
+ assert_equal %(filename="%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F.jpg"), disposition.ascii_filename
+ assert_equal "filename*=UTF-8''%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D0%B1%D0%B8%D0%BB%D1%8C.jpg", disposition.utf8_filename
+ assert_equal "inline; #{disposition.ascii_filename}; #{disposition.utf8_filename}", disposition.to_s
+ end
+
+ test "without filename" do
+ disposition = Http::ContentDisposition.new(disposition: :inline, filename: nil)
+
+ assert_equal "inline", disposition.to_s
+ end
+ end
+end
diff --git a/actionpack/test/dispatch/content_security_policy_test.rb b/actionpack/test/dispatch/content_security_policy_test.rb
new file mode 100644
index 0000000000..c8c885f35c
--- /dev/null
+++ b/actionpack/test/dispatch/content_security_policy_test.rb
@@ -0,0 +1,546 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class ContentSecurityPolicyTest < ActiveSupport::TestCase
+ def setup
+ @policy = ActionDispatch::ContentSecurityPolicy.new
+ end
+
+ def test_build
+ assert_equal "", @policy.build
+
+ @policy.script_src :self
+ assert_equal "script-src 'self'", @policy.build
+ end
+
+ def test_dup
+ @policy.img_src :self
+ @policy.block_all_mixed_content
+ @policy.upgrade_insecure_requests
+ @policy.sandbox
+ copied = @policy.dup
+ assert_equal copied.build, @policy.build
+ end
+
+ def test_mappings
+ @policy.script_src :data
+ assert_equal "script-src data:", @policy.build
+
+ @policy.script_src :mediastream
+ assert_equal "script-src mediastream:", @policy.build
+
+ @policy.script_src :blob
+ assert_equal "script-src blob:", @policy.build
+
+ @policy.script_src :filesystem
+ assert_equal "script-src filesystem:", @policy.build
+
+ @policy.script_src :self
+ assert_equal "script-src 'self'", @policy.build
+
+ @policy.script_src :unsafe_inline
+ assert_equal "script-src 'unsafe-inline'", @policy.build
+
+ @policy.script_src :unsafe_eval
+ assert_equal "script-src 'unsafe-eval'", @policy.build
+
+ @policy.script_src :none
+ assert_equal "script-src 'none'", @policy.build
+
+ @policy.script_src :strict_dynamic
+ assert_equal "script-src 'strict-dynamic'", @policy.build
+
+ @policy.script_src :ws
+ assert_equal "script-src ws:", @policy.build
+
+ @policy.script_src :wss
+ assert_equal "script-src wss:", @policy.build
+
+ @policy.script_src :none, :report_sample
+ assert_equal "script-src 'none' 'report-sample'", @policy.build
+ end
+
+ def test_fetch_directives
+ @policy.child_src :self
+ assert_match %r{child-src 'self'}, @policy.build
+
+ @policy.child_src false
+ assert_no_match %r{child-src}, @policy.build
+
+ @policy.connect_src :self
+ assert_match %r{connect-src 'self'}, @policy.build
+
+ @policy.connect_src false
+ assert_no_match %r{connect-src}, @policy.build
+
+ @policy.default_src :self
+ assert_match %r{default-src 'self'}, @policy.build
+
+ @policy.default_src false
+ assert_no_match %r{default-src}, @policy.build
+
+ @policy.font_src :self
+ assert_match %r{font-src 'self'}, @policy.build
+
+ @policy.font_src false
+ assert_no_match %r{font-src}, @policy.build
+
+ @policy.frame_src :self
+ assert_match %r{frame-src 'self'}, @policy.build
+
+ @policy.frame_src false
+ assert_no_match %r{frame-src}, @policy.build
+
+ @policy.img_src :self
+ assert_match %r{img-src 'self'}, @policy.build
+
+ @policy.img_src false
+ assert_no_match %r{img-src}, @policy.build
+
+ @policy.manifest_src :self
+ assert_match %r{manifest-src 'self'}, @policy.build
+
+ @policy.manifest_src false
+ assert_no_match %r{manifest-src}, @policy.build
+
+ @policy.media_src :self
+ assert_match %r{media-src 'self'}, @policy.build
+
+ @policy.media_src false
+ assert_no_match %r{media-src}, @policy.build
+
+ @policy.object_src :self
+ assert_match %r{object-src 'self'}, @policy.build
+
+ @policy.object_src false
+ assert_no_match %r{object-src}, @policy.build
+
+ @policy.prefetch_src :self
+ assert_match %r{prefetch-src 'self'}, @policy.build
+
+ @policy.prefetch_src false
+ assert_no_match %r{prefetch-src}, @policy.build
+
+ @policy.script_src :self
+ assert_match %r{script-src 'self'}, @policy.build
+
+ @policy.script_src false
+ assert_no_match %r{script-src}, @policy.build
+
+ @policy.style_src :self
+ assert_match %r{style-src 'self'}, @policy.build
+
+ @policy.style_src false
+ assert_no_match %r{style-src}, @policy.build
+
+ @policy.worker_src :self
+ assert_match %r{worker-src 'self'}, @policy.build
+
+ @policy.worker_src false
+ assert_no_match %r{worker-src}, @policy.build
+ end
+
+ def test_document_directives
+ @policy.base_uri "https://example.com"
+ assert_match %r{base-uri https://example\.com}, @policy.build
+
+ @policy.plugin_types "application/x-shockwave-flash"
+ assert_match %r{plugin-types application/x-shockwave-flash}, @policy.build
+
+ @policy.sandbox
+ assert_match %r{sandbox}, @policy.build
+
+ @policy.sandbox "allow-scripts", "allow-modals"
+ assert_match %r{sandbox allow-scripts allow-modals}, @policy.build
+
+ @policy.sandbox false
+ assert_no_match %r{sandbox}, @policy.build
+ end
+
+ def test_navigation_directives
+ @policy.form_action :self
+ assert_match %r{form-action 'self'}, @policy.build
+
+ @policy.frame_ancestors :self
+ assert_match %r{frame-ancestors 'self'}, @policy.build
+ end
+
+ def test_reporting_directives
+ @policy.report_uri "/violations"
+ assert_match %r{report-uri /violations}, @policy.build
+ end
+
+ def test_other_directives
+ @policy.block_all_mixed_content
+ assert_match %r{block-all-mixed-content}, @policy.build
+
+ @policy.block_all_mixed_content false
+ assert_no_match %r{block-all-mixed-content}, @policy.build
+
+ @policy.require_sri_for :script, :style
+ assert_match %r{require-sri-for script style}, @policy.build
+
+ @policy.require_sri_for "script", "style"
+ assert_match %r{require-sri-for script style}, @policy.build
+
+ @policy.require_sri_for
+ assert_no_match %r{require-sri-for}, @policy.build
+
+ @policy.upgrade_insecure_requests
+ assert_match %r{upgrade-insecure-requests}, @policy.build
+
+ @policy.upgrade_insecure_requests false
+ assert_no_match %r{upgrade-insecure-requests}, @policy.build
+ end
+
+ def test_multiple_sources
+ @policy.script_src :self, :https
+ assert_equal "script-src 'self' https:", @policy.build
+ end
+
+ def test_multiple_directives
+ @policy.script_src :self, :https
+ @policy.style_src :self, :https
+ assert_equal "script-src 'self' https:; style-src 'self' https:", @policy.build
+ end
+
+ def test_dynamic_directives
+ request = ActionDispatch::Request.new("HTTP_HOST" => "www.example.com")
+ controller = Struct.new(:request).new(request)
+
+ @policy.script_src -> { request.host }
+ assert_equal "script-src www.example.com", @policy.build(controller)
+ end
+
+ def test_mixed_static_and_dynamic_directives
+ @policy.script_src :self, -> { "foo.com" }, "bar.com"
+ request = ActionDispatch::Request.new({})
+ controller = Struct.new(:request).new(request)
+ assert_equal "script-src 'self' foo.com bar.com", @policy.build(controller)
+ end
+
+ def test_invalid_directive_source
+ exception = assert_raises(ArgumentError) do
+ @policy.script_src [:self]
+ end
+
+ assert_equal "Invalid content security policy source: [:self]", exception.message
+ end
+
+ def test_missing_context_for_dynamic_source
+ @policy.script_src -> { request.host }
+
+ exception = assert_raises(RuntimeError) do
+ @policy.build
+ end
+
+ assert_match %r{\AMissing context for the dynamic content security policy source:}, exception.message
+ end
+
+ def test_raises_runtime_error_when_unexpected_source
+ @policy.plugin_types [:flash]
+
+ exception = assert_raises(RuntimeError) do
+ @policy.build
+ end
+
+ assert_match %r{\AUnexpected content security policy source:}, exception.message
+ end
+end
+
+class DefaultContentSecurityPolicyIntegrationTest < ActionDispatch::IntegrationTest
+ class PolicyController < ActionController::Base
+ def index
+ head :ok
+ end
+ end
+
+ ROUTES = ActionDispatch::Routing::RouteSet.new
+ ROUTES.draw do
+ scope module: "default_content_security_policy_integration_test" do
+ get "/", to: "policy#index"
+ get "/redirect", to: redirect("/")
+ end
+ end
+
+ POLICY = ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src -> { :self }
+ p.script_src -> { :https }
+ end
+
+ class PolicyConfigMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env["action_dispatch.content_security_policy"] = POLICY
+ env["action_dispatch.content_security_policy_nonce_generator"] = proc { "iyhD0Yc0W+c=" }
+ env["action_dispatch.content_security_policy_report_only"] = false
+ env["action_dispatch.show_exceptions"] = false
+
+ @app.call(env)
+ end
+ end
+
+ APP = build_app(ROUTES) do |middleware|
+ middleware.use PolicyConfigMiddleware
+ middleware.use ActionDispatch::ContentSecurityPolicy::Middleware
+ end
+
+ def app
+ APP
+ end
+
+ def test_adds_nonce_to_script_src_content_security_policy_only_once
+ get "/"
+ get "/"
+ assert_response :success
+ assert_policy "default-src 'self'; script-src https: 'nonce-iyhD0Yc0W+c='"
+ end
+
+ def test_redirect_works_with_dynamic_sources
+ get "/redirect"
+ assert_response :redirect
+ assert_policy "default-src 'self'; script-src https: 'nonce-iyhD0Yc0W+c='"
+ end
+
+ private
+
+ def assert_policy(expected, report_only: false)
+ if report_only
+ expected_header = "Content-Security-Policy-Report-Only"
+ unexpected_header = "Content-Security-Policy"
+ else
+ expected_header = "Content-Security-Policy"
+ unexpected_header = "Content-Security-Policy-Report-Only"
+ end
+
+ assert_nil response.headers[unexpected_header]
+ assert_equal expected, response.headers[expected_header]
+ end
+end
+
+class ContentSecurityPolicyIntegrationTest < ActionDispatch::IntegrationTest
+ class PolicyController < ActionController::Base
+ content_security_policy only: :inline do |p|
+ p.default_src "https://example.com"
+ end
+
+ content_security_policy only: :conditional, if: :condition? do |p|
+ p.default_src "https://true.example.com"
+ end
+
+ content_security_policy only: :conditional, unless: :condition? do |p|
+ p.default_src "https://false.example.com"
+ end
+
+ content_security_policy only: :report_only do |p|
+ p.report_uri "/violations"
+ end
+
+ content_security_policy only: :script_src do |p|
+ p.default_src false
+ p.script_src :self
+ end
+
+ content_security_policy only: :style_src do |p|
+ p.default_src false
+ p.style_src :self
+ end
+
+ content_security_policy(false, only: :no_policy)
+
+ content_security_policy_report_only only: :report_only
+
+ def index
+ head :ok
+ end
+
+ def inline
+ head :ok
+ end
+
+ def conditional
+ head :ok
+ end
+
+ def report_only
+ head :ok
+ end
+
+ def script_src
+ head :ok
+ end
+
+ def style_src
+ head :ok
+ end
+
+ def no_policy
+ head :ok
+ end
+
+ private
+ def condition?
+ params[:condition] == "true"
+ end
+ end
+
+ ROUTES = ActionDispatch::Routing::RouteSet.new
+ ROUTES.draw do
+ scope module: "content_security_policy_integration_test" do
+ get "/", to: "policy#index"
+ get "/inline", to: "policy#inline"
+ get "/conditional", to: "policy#conditional"
+ get "/report-only", to: "policy#report_only"
+ get "/script-src", to: "policy#script_src"
+ get "/style-src", to: "policy#style_src"
+ get "/no-policy", to: "policy#no_policy"
+ end
+ end
+
+ POLICY = ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src :self
+ end
+
+ class PolicyConfigMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env["action_dispatch.content_security_policy"] = POLICY
+ env["action_dispatch.content_security_policy_nonce_generator"] = proc { "iyhD0Yc0W+c=" }
+ env["action_dispatch.content_security_policy_report_only"] = false
+ env["action_dispatch.show_exceptions"] = false
+
+ @app.call(env)
+ end
+ end
+
+ APP = build_app(ROUTES) do |middleware|
+ middleware.use PolicyConfigMiddleware
+ middleware.use ActionDispatch::ContentSecurityPolicy::Middleware
+ end
+
+ def app
+ APP
+ end
+
+ def test_generates_content_security_policy_header
+ get "/"
+ assert_policy "default-src 'self'"
+ end
+
+ def test_generates_inline_content_security_policy
+ get "/inline"
+ assert_policy "default-src https://example.com"
+ end
+
+ def test_generates_conditional_content_security_policy
+ get "/conditional", params: { condition: "true" }
+ assert_policy "default-src https://true.example.com"
+
+ get "/conditional", params: { condition: "false" }
+ assert_policy "default-src https://false.example.com"
+ end
+
+ def test_generates_report_only_content_security_policy
+ get "/report-only"
+ assert_policy "default-src 'self'; report-uri /violations", report_only: true
+ end
+
+ def test_adds_nonce_to_script_src_content_security_policy
+ get "/script-src"
+ assert_policy "script-src 'self' 'nonce-iyhD0Yc0W+c='"
+ end
+
+ def test_adds_nonce_to_style_src_content_security_policy
+ get "/style-src"
+ assert_policy "style-src 'self' 'nonce-iyhD0Yc0W+c='"
+ end
+
+ def test_generates_no_content_security_policy
+ get "/no-policy"
+
+ assert_nil response.headers["Content-Security-Policy"]
+ assert_nil response.headers["Content-Security-Policy-Report-Only"]
+ end
+
+ private
+
+ def assert_policy(expected, report_only: false)
+ assert_response :success
+
+ if report_only
+ expected_header = "Content-Security-Policy-Report-Only"
+ unexpected_header = "Content-Security-Policy"
+ else
+ expected_header = "Content-Security-Policy"
+ unexpected_header = "Content-Security-Policy-Report-Only"
+ end
+
+ assert_nil response.headers[unexpected_header]
+ assert_equal expected, response.headers[expected_header]
+ end
+end
+
+class DisabledContentSecurityPolicyIntegrationTest < ActionDispatch::IntegrationTest
+ class PolicyController < ActionController::Base
+ content_security_policy only: :inline do |p|
+ p.default_src "https://example.com"
+ end
+
+ def index
+ head :ok
+ end
+
+ def inline
+ head :ok
+ end
+ end
+
+ ROUTES = ActionDispatch::Routing::RouteSet.new
+ ROUTES.draw do
+ scope module: "disabled_content_security_policy_integration_test" do
+ get "/", to: "policy#index"
+ get "/inline", to: "policy#inline"
+ end
+ end
+
+ class PolicyConfigMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env["action_dispatch.content_security_policy"] = nil
+ env["action_dispatch.content_security_policy_nonce_generator"] = nil
+ env["action_dispatch.content_security_policy_report_only"] = false
+ env["action_dispatch.show_exceptions"] = false
+
+ @app.call(env)
+ end
+ end
+
+ APP = build_app(ROUTES) do |middleware|
+ middleware.use PolicyConfigMiddleware
+ middleware.use ActionDispatch::ContentSecurityPolicy::Middleware
+ end
+
+ def app
+ APP
+ end
+
+ def test_generates_no_content_security_policy_by_default
+ get "/"
+ assert_nil response.headers["Content-Security-Policy"]
+ end
+
+ def test_generates_content_security_policy_header_when_globally_disabled
+ get "/inline"
+ assert_equal "default-src https://example.com", response.headers["Content-Security-Policy"]
+ end
+end
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index dfcef14344..6637c2cae9 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -1,7 +1,9 @@
-require 'abstract_unit'
-require 'openssl'
-require 'active_support/key_generator'
-require 'active_support/message_verifier'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "openssl"
+require "active_support/key_generator"
+require "active_support/messages/rotation_configuration"
class CookieJarTest < ActiveSupport::TestCase
attr_reader :request
@@ -12,26 +14,32 @@ class CookieJarTest < ActiveSupport::TestCase
def test_fetch
x = Object.new
- assert_not request.cookie_jar.key?('zzzzzz')
- assert_equal x, request.cookie_jar.fetch('zzzzzz', x)
- assert_not request.cookie_jar.key?('zzzzzz')
+ assert_not request.cookie_jar.key?("zzzzzz")
+ assert_equal x, request.cookie_jar.fetch("zzzzzz", x)
+ assert_not request.cookie_jar.key?("zzzzzz")
end
def test_fetch_exists
x = Object.new
- request.cookie_jar['foo'] = 'bar'
- assert_equal 'bar', request.cookie_jar.fetch('foo', x)
+ request.cookie_jar["foo"] = "bar"
+ assert_equal "bar", request.cookie_jar.fetch("foo", x)
end
def test_fetch_block
x = Object.new
- assert_not request.cookie_jar.key?('zzzzzz')
- assert_equal x, request.cookie_jar.fetch('zzzzzz') { x }
+ assert_not request.cookie_jar.key?("zzzzzz")
+ assert_equal x, request.cookie_jar.fetch("zzzzzz") { x }
end
def test_key_is_to_s
- request.cookie_jar['foo'] = 'bar'
- assert_equal 'bar', request.cookie_jar.fetch(:foo)
+ request.cookie_jar["foo"] = "bar"
+ assert_equal "bar", request.cookie_jar.fetch(:foo)
+ end
+
+ def test_to_hash
+ request.cookie_jar["foo"] = "bar"
+ assert_equal({ "foo" => "bar" }, request.cookie_jar.to_hash)
+ assert_equal({ "foo" => "bar" }, request.cookie_jar.to_h)
end
def test_fetch_type_error
@@ -41,24 +49,24 @@ class CookieJarTest < ActiveSupport::TestCase
end
def test_each
- request.cookie_jar['foo'] = :bar
+ request.cookie_jar["foo"] = :bar
list = []
- request.cookie_jar.each do |k,v|
+ request.cookie_jar.each do |k, v|
list << [k, v]
end
- assert_equal [['foo', :bar]], list
+ assert_equal [["foo", :bar]], list
end
def test_enumerable
- request.cookie_jar['foo'] = :bar
- actual = request.cookie_jar.map { |k,v| [k.to_s, v.to_s] }
- assert_equal [['foo', 'bar']], actual
+ request.cookie_jar["foo"] = :bar
+ actual = request.cookie_jar.map { |k, v| [k.to_s, v.to_s] }
+ assert_equal [["foo", "bar"]], actual
end
def test_key_methods
- assert !request.cookie_jar.key?(:foo)
- assert !request.cookie_jar.has_key?("foo")
+ assert_not request.cookie_jar.key?(:foo)
+ assert_not request.cookie_jar.has_key?("foo")
request.cookie_jar[:foo] = :bar
assert request.cookie_jar.key?(:foo)
@@ -68,7 +76,7 @@ class CookieJarTest < ActiveSupport::TestCase
def test_write_doesnt_set_a_nil_header
headers = {}
request.cookie_jar.write(headers)
- assert !headers.include?('Set-Cookie')
+ assert_not_includes headers, "Set-Cookie"
end
end
@@ -95,17 +103,17 @@ class CookiesTest < ActionController::TestCase
end
def authenticate_for_fourteen_days
- cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
+ cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) }
head :ok
end
def authenticate_for_fourteen_days_with_symbols
- cookies[:user_name] = { :value => "david", :expires => Time.utc(2005, 10, 10,5) }
+ cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) }
head :ok
end
def set_multiple_cookies
- cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
+ cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) }
cookies["login"] = "XJ-122"
head :ok
end
@@ -123,17 +131,17 @@ class CookiesTest < ActionController::TestCase
alias delete_cookie logout
def delete_cookie_with_path
- cookies.delete("user_name", :path => '/beaten')
+ cookies.delete("user_name", path: "/beaten")
head :ok
end
def authenticate_with_http_only
- cookies["user_name"] = { :value => "david", :httponly => true }
+ cookies["user_name"] = { value: "david", httponly: true }
head :ok
end
def authenticate_with_secure
- cookies["user_name"] = { :value => "david", :secure => true }
+ cookies["user_name"] = { value: "david", secure: true }
head :ok
end
@@ -153,7 +161,7 @@ class CookiesTest < ActionController::TestCase
end
def set_encrypted_cookie
- cookies.encrypted[:foo] = 'bar'
+ cookies.encrypted[:foo] = "bar"
head :ok
end
@@ -173,7 +181,7 @@ class CookiesTest < ActionController::TestCase
end
def set_wrapped_encrypted_cookie
- cookies.encrypted[:foo] = JSONWrapper.new('bar')
+ cookies.encrypted[:foo] = JSONWrapper.new("bar")
head :ok
end
@@ -183,12 +191,12 @@ class CookiesTest < ActionController::TestCase
end
def set_invalid_encrypted_cookie
- cookies[:invalid_cookie] = 'invalid--9170e00a57cfc27083363b5c75b835e477bd90cf'
+ cookies[:invalid_cookie] = "invalid--9170e00a57cfc27083363b5c75b835e477bd90cf"
head :ok
end
def raise_data_overflow
- cookies.signed[:foo] = 'bye!' * 1024
+ cookies.signed[:foo] = "bye!" * 1024
head :ok
end
@@ -205,47 +213,47 @@ class CookiesTest < ActionController::TestCase
def delete_and_set_cookie
cookies.delete :user_name
- cookies[:user_name] = { :value => "david", :expires => Time.utc(2005, 10, 10,5) }
+ cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) }
head :ok
end
def set_cookie_with_domain
- cookies[:user_name] = {:value => "rizwanreza", :domain => :all}
+ cookies[:user_name] = { value: "rizwanreza", domain: :all }
head :ok
end
def set_cookie_with_domain_all_as_string
- cookies[:user_name] = {:value => "rizwanreza", :domain => 'all'}
+ cookies[:user_name] = { value: "rizwanreza", domain: "all" }
head :ok
end
def delete_cookie_with_domain
- cookies.delete(:user_name, :domain => :all)
+ cookies.delete(:user_name, domain: :all)
head :ok
end
def delete_cookie_with_domain_all_as_string
- cookies.delete(:user_name, :domain => 'all')
+ cookies.delete(:user_name, domain: "all")
head :ok
end
def set_cookie_with_domain_and_tld
- cookies[:user_name] = {:value => "rizwanreza", :domain => :all, :tld_length => 2}
+ cookies[:user_name] = { value: "rizwanreza", domain: :all, tld_length: 2 }
head :ok
end
def delete_cookie_with_domain_and_tld
- cookies.delete(:user_name, :domain => :all, :tld_length => 2)
+ cookies.delete(:user_name, domain: :all, tld_length: 2)
head :ok
end
def set_cookie_with_domains
- cookies[:user_name] = {:value => "rizwanreza", :domain => %w(example1.com example2.com .example3.com)}
+ cookies[:user_name] = { value: "rizwanreza", domain: %w(example1.com example2.com .example3.com) }
head :ok
end
def delete_cookie_with_domains
- cookies.delete(:user_name, :domain => %w(example1.com example2.com .example3.com))
+ cookies.delete(:user_name, domain: %w(example1.com example2.com .example3.com))
head :ok
end
@@ -255,7 +263,7 @@ class CookiesTest < ActionController::TestCase
end
def string_key
- cookies['user_name'] = "dhh"
+ cookies["user_name"] = "dhh"
head :ok
end
@@ -265,27 +273,85 @@ class CookiesTest < ActionController::TestCase
end
def string_key_mock
- cookies['user_name'] = "david" if cookies['user_name'] == "andrew"
+ cookies["user_name"] = "david" if cookies["user_name"] == "andrew"
head :ok
end
def noop
head :ok
end
+
+ def encrypted_cookie
+ cookies.encrypted["foo"]
+ end
+
+ def cookie_expires_in_two_hours
+ cookies[:user_name] = { value: "assain", expires: 2.hours }
+ head :ok
+ end
+
+ def encrypted_discount_and_user_id_cookie
+ cookies.encrypted[:user_id] = { value: 50, expires: 1.hour }
+ cookies.encrypted[:discount_percentage] = 10
+
+ head :ok
+ end
+
+ def signed_discount_and_user_id_cookie
+ cookies.signed[:user_id] = { value: 50, expires: 1.hour }
+ cookies.signed[:discount_percentage] = 10
+
+ head :ok
+ end
+
+ def rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on
+ # cookies.encrypted[:favorite] = { value: "5-2-Stable Chocolate Cookies", expires: 1000.years }
+ cookies[:favorite] = "KvH5lIHvX5vPQkLIK63r/NuIMwzWky8M0Zwk8SZ6DwUv8+srf36geR4nWq5KmhsZIYXA8NRdCZYIfxMKJsOFlz77Gf+Fq8vBBCWJTp95rx39A28TCUTJEyMhCNJO5eie7Skef76Qt5Jo/SCnIADAhzyGQkGBopKRcA==--qXZZFWGbCy6N8AGy--WswoH+xHrNh9MzSXDpB2fA=="
+
+ head :ok
+ end
+
+ def rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off
+ cookies[:favorite] = "Wmg4amgvcVVvWGcwK3c4WjJEbTdRQUgrWXhBdDliUTR0cVNidXpmVTMrc2RjcitwUzVsWWEwZGtuVGtFUjJwNi0tcVhVMTFMOTQ1d0hIVE1FK0pJc05SQT09--8b2a55c375049a50f7a959b9d42b31ef0b2bb594"
+
+ head :ok
+ end
+
+ def rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on
+ # cookies.signed[:favorite] = { value: "5-2-Stable Choco Chip Cookie", expires: 1000.years }
+ cookies[:favorite] = "eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJaUUxTFRJdFUzUmhZbXhsSUVOb2IyTnZJRU5vYVhBZ1EyOXZhMmxsQmpvR1JWUT0iLCJleHAiOiIzMDE4LTA3LTExVDE2OjExOjI2Ljc1M1oiLCJwdXIiOm51bGx9fQ==--7df5d885b78b70a501d6e82140ae91b24060ac00"
+
+ head :ok
+ end
+
+ def rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off
+ cookies[:favorite] = "BAhJIiE1LTItU3RhYmxlIENob2NvIENoaXAgQ29va2llBjoGRVQ=--50bbdbf8d64f5a3ec3e54878f54d4f55b6cb3aff"
+
+ head :ok
+ end
end
tests TestController
- SALT = 'b3c631c314c0bbca50c1b2843150fe33'
+ SECRET_KEY_BASE = "b3c631c314c0bbca50c1b2843150fe33"
+ SIGNED_COOKIE_SALT = "signed cookie"
+ ENCRYPTED_COOKIE_SALT = "encrypted cookie"
+ ENCRYPTED_SIGNED_COOKIE_SALT = "sigend encrypted cookie"
+ AUTHENTICATED_ENCRYPTED_COOKIE_SALT = "authenticated encrypted cookie"
def setup
super
- @request.env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new(SALT, iterations: 2)
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new(SECRET_KEY_BASE, iterations: 2)
+ @request.env["action_dispatch.cookies_rotations"] = ActiveSupport::Messages::RotationConfiguration.new
+
+ @request.env["action_dispatch.secret_key_base"] = SECRET_KEY_BASE
+ @request.env["action_dispatch.use_authenticated_cookie_encryption"] = true
- @request.env["action_dispatch.signed_cookie_salt"] =
- @request.env["action_dispatch.encrypted_cookie_salt"] =
- @request.env["action_dispatch.encrypted_signed_cookie_salt"] = SALT
+ @request.env["action_dispatch.signed_cookie_salt"] = SIGNED_COOKIE_SALT
+ @request.env["action_dispatch.encrypted_cookie_salt"] = ENCRYPTED_COOKIE_SALT
+ @request.env["action_dispatch.encrypted_signed_cookie_salt"] = ENCRYPTED_SIGNED_COOKIE_SALT
+ @request.env["action_dispatch.authenticated_encrypted_cookie_salt"] = AUTHENTICATED_ENCRYPTED_COOKIE_SALT
@request.host = "www.nextangle.com"
end
@@ -293,57 +359,57 @@ class CookiesTest < ActionController::TestCase
def test_setting_cookie
get :authenticate
assert_cookie_header "user_name=david; path=/"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_the_same_value_to_cookie
- request.cookies[:user_name] = 'david'
+ request.cookies[:user_name] = "david"
get :authenticate
- assert_predicate response.cookies, :empty?
+ assert_empty response.cookies
end
def test_setting_the_same_value_to_permanent_cookie
- request.cookies[:user_name] = 'Jamie'
+ request.cookies[:user_name] = "Jamie"
get :set_permanent_cookie
- assert_equal({'user_name' => 'Jamie'}, response.cookies)
+ assert_equal({ "user_name" => "Jamie" }, response.cookies)
end
def test_setting_with_escapable_characters
get :set_with_with_escapable_characters
assert_cookie_header "that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"
- assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
+ assert_equal({ "that & guy" => "foo & bar => baz" }, @response.cookies)
end
def test_setting_cookie_for_fourteen_days
get :authenticate_for_fourteen_days
assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_for_fourteen_days_with_symbols
get :authenticate_for_fourteen_days_with_symbols
assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_with_http_only
get :authenticate_with_http_only
assert_cookie_header "user_name=david; path=/; HttpOnly"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_with_secure
@request.env["HTTPS"] = "on"
get :authenticate_with_secure
assert_cookie_header "user_name=david; path=/; secure"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_setting_cookie_with_secure_when_always_write_cookie_is_true
old_cookie, @request.cookie_jar.always_write_cookie = @request.cookie_jar.always_write_cookie, true
get :authenticate_with_secure
assert_cookie_header "user_name=david; path=/; secure"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
ensure
@request.cookie_jar.always_write_cookie = old_cookie
end
@@ -351,14 +417,14 @@ class CookiesTest < ActionController::TestCase
def test_not_setting_cookie_with_secure
get :authenticate_with_secure
assert_not_cookie_header "user_name=david; path=/; secure"
- assert_not_equal({"user_name" => "david"}, @response.cookies)
+ assert_not_equal({ "user_name" => "david" }, @response.cookies)
end
def test_multiple_cookies
get :set_multiple_cookies
assert_equal 2, @response.cookies.size
assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000\nlogin=XJ-122; path=/"
- assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies)
+ assert_equal({ "login" => "XJ-122", "user_name" => "david" }, @response.cookies)
end
def test_setting_test_cookie
@@ -366,14 +432,14 @@ class CookiesTest < ActionController::TestCase
end
def test_expiring_cookie
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :logout
assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
- assert_equal({"user_name" => nil}, @response.cookies)
+ assert_equal({ "user_name" => nil }, @response.cookies)
end
def test_delete_cookie_with_path
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_cookie_with_path
assert_cookie_header "user_name=; path=/beaten; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
@@ -381,20 +447,20 @@ class CookiesTest < ActionController::TestCase
def test_delete_unexisting_cookie
request.cookies.clear
get :delete_cookie
- assert_predicate @response.cookies, :empty?
+ assert_empty @response.cookies
end
def test_deleted_cookie_predicate
- cookies[:user_name] = 'Joe'
+ cookies[:user_name] = "Joe"
cookies.delete("user_name")
assert cookies.deleted?("user_name")
assert_equal false, cookies.deleted?("another")
end
def test_deleted_cookie_predicate_with_mismatching_options
- cookies[:user_name] = 'Joe'
- cookies.delete("user_name", :path => "/path")
- assert_equal false, cookies.deleted?("user_name", :path => "/different")
+ cookies[:user_name] = "Joe"
+ cookies.delete("user_name", path: "/path")
+ assert_equal false, cookies.deleted?("user_name", path: "/different")
end
def test_cookies_persist_throughout_request
@@ -410,7 +476,7 @@ class CookiesTest < ActionController::TestCase
def test_read_permanent_cookie
get :set_permanent_cookie
- assert_equal 'Jamie', @controller.send(:cookies).permanent[:user_name]
+ assert_equal "Jamie", @controller.send(:cookies).permanent[:user_name]
end
def test_signed_cookie_using_default_digest
@@ -420,28 +486,72 @@ class CookiesTest < ActionController::TestCase
assert_equal 45, cookies.signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
- signed_cookie_salt = @request.env["action_dispatch.signed_cookie_salt"]
- secret = key_generator.generate_key(signed_cookie_salt)
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
- verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: 'SHA1')
+ verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA1")
assert_equal verifier.generate(45), cookies[:user_id]
end
def test_signed_cookie_using_custom_digest
- @request.env["action_dispatch.cookies_digest"] = 'SHA256'
+ @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
+
get :set_signed_cookie
cookies = @controller.send :cookies
assert_not_equal 45, cookies[:user_id]
assert_equal 45, cookies.signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
- signed_cookie_salt = @request.env["action_dispatch.signed_cookie_salt"]
- secret = key_generator.generate_key(signed_cookie_salt)
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
- verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: 'SHA256')
+ verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA256")
assert_equal verifier.generate(45), cookies[:user_id]
end
+ def test_signed_cookie_rotating_secret_and_digest
+ secret = "b3c631c314c0bbca50c1b2843150fe33"
+
+ @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
+ @request.env["action_dispatch.cookies_rotations"].rotate :signed, secret, digest: "SHA1"
+
+ old_message = ActiveSupport::MessageVerifier.new(secret, digest: "SHA1", serializer: Marshal).generate(45)
+ @request.headers["Cookie"] = "user_id=#{old_message}"
+
+ get :get_signed_cookie
+ assert_equal 45, @controller.send(:cookies).signed[:user_id]
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+ verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA256", serializer: Marshal)
+ assert_equal 45, verifier.verify(@response.cookies["user_id"])
+ end
+
+ def test_signed_cookie_with_legacy_secret_scheme
+ @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
+
+ old_message = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", digest: "SHA1", serializer: Marshal).generate(45)
+
+ @request.headers["Cookie"] = "user_id=#{old_message}"
+ get :get_signed_cookie
+ assert_equal 45, @controller.send(:cookies).signed[:user_id]
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+ secret = key_generator.generate_key("signed cookie")
+ verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA1", serializer: Marshal)
+ assert_equal 45, verifier.verify(@response.cookies["user_id"])
+ end
+
+ def test_tampered_with_signed_cookie
+ key_generator = @request.env["action_dispatch.key_generator"]
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+
+ verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA1")
+ message = verifier.generate(45)
+
+ @request.headers["Cookie"] = "user_id=#{Marshal.dump 45}--#{message.split("--").last}"
+ get :get_signed_cookie
+ assert_nil @controller.send(:cookies).signed[:user_id]
+ end
+
def test_signed_cookie_using_default_serializer
get :set_signed_cookie
cookies = @controller.send :cookies
@@ -469,23 +579,22 @@ class CookiesTest < ActionController::TestCase
@request.env["action_dispatch.cookies_serializer"] = :json
get :set_wrapped_signed_cookie
cookies = @controller.send :cookies
- assert_not_equal 'wrapped: 45', cookies[:user_id]
- assert_equal 'wrapped: 45', cookies.signed[:user_id]
+ assert_not_equal "wrapped: 45", cookies[:user_id]
+ assert_equal "wrapped: 45", cookies.signed[:user_id]
end
def test_signed_cookie_using_custom_serializer
@request.env["action_dispatch.cookies_serializer"] = CustomSerializer
get :set_signed_cookie
assert_not_equal 45, cookies[:user_id]
- assert_equal '45 was dumped and loaded', cookies.signed[:user_id]
+ assert_equal "45 was dumped and loaded", cookies.signed[:user_id]
end
def test_signed_cookie_using_hybrid_serializer_can_migrate_marshal_dumped_value_to_json
@request.env["action_dispatch.cookies_serializer"] = :hybrid
key_generator = @request.env["action_dispatch.key_generator"]
- signed_cookie_salt = @request.env["action_dispatch.signed_cookie_salt"]
- secret = key_generator.generate_key(signed_cookie_salt)
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
marshal_value = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal).generate(45)
@request.headers["Cookie"] = "user_id=#{marshal_value}"
@@ -497,15 +606,15 @@ class CookiesTest < ActionController::TestCase
assert_equal 45, cookies.signed[:user_id]
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
- assert_equal 45, verifier.verify(@response.cookies['user_id'])
+ assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_signed_cookie_using_hybrid_serializer_can_read_from_json_dumped_value
@request.env["action_dispatch.cookies_serializer"] = :hybrid
key_generator = @request.env["action_dispatch.key_generator"]
- signed_cookie_salt = @request.env["action_dispatch.signed_cookie_salt"]
- secret = key_generator.generate_key(signed_cookie_salt)
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+
json_value = ActiveSupport::MessageVerifier.new(secret, serializer: JSON).generate(45)
@request.headers["Cookie"] = "user_id=#{json_value}"
@@ -520,91 +629,60 @@ class CookiesTest < ActionController::TestCase
def test_accessing_nonexistent_signed_cookie_should_not_raise_an_invalid_signature
get :set_signed_cookie
- assert_nil @controller.send(:cookies).signed[:non_existant_attribute]
+ assert_nil @controller.send(:cookies).signed[:non_existent_attribute]
end
def test_encrypted_cookie_using_default_serializer
get :set_encrypted_cookie
cookies = @controller.send :cookies
- assert_not_equal 'bar', cookies[:foo]
- assert_raise TypeError do
- cookies.signed[:foo]
- end
- assert_equal 'bar', cookies.encrypted[:foo]
+ assert_not_equal "bar", cookies[:foo]
+ assert_nil cookies.signed[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
end
def test_encrypted_cookie_using_marshal_serializer
@request.env["action_dispatch.cookies_serializer"] = :marshal
get :set_encrypted_cookie
cookies = @controller.send :cookies
- assert_not_equal 'bar', cookies[:foo]
- assert_raises TypeError do
- cookies.signed[:foo]
- end
- assert_equal 'bar', cookies.encrypted[:foo]
+ assert_not_equal "bar", cookies[:foo]
+ assert_nil cookies.signed[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
end
def test_encrypted_cookie_using_json_serializer
@request.env["action_dispatch.cookies_serializer"] = :json
get :set_encrypted_cookie
cookies = @controller.send :cookies
- assert_not_equal 'bar', cookies[:foo]
- assert_raises ::JSON::ParserError do
- cookies.signed[:foo]
- end
- assert_equal 'bar', cookies.encrypted[:foo]
+ assert_not_equal "bar", cookies[:foo]
+ assert_nil cookies.signed[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
end
def test_wrapped_encrypted_cookie_using_json_serializer
@request.env["action_dispatch.cookies_serializer"] = :json
get :set_wrapped_encrypted_cookie
cookies = @controller.send :cookies
- assert_not_equal 'wrapped: bar', cookies[:foo]
- assert_raises ::JSON::ParserError do
- cookies.signed[:foo]
- end
- assert_equal 'wrapped: bar', cookies.encrypted[:foo]
+ assert_not_equal "wrapped: bar", cookies[:foo]
+ assert_nil cookies.signed[:foo]
+ assert_equal "wrapped: bar", cookies.encrypted[:foo]
end
def test_encrypted_cookie_using_custom_serializer
@request.env["action_dispatch.cookies_serializer"] = CustomSerializer
get :set_encrypted_cookie
- assert_not_equal 'bar', cookies.encrypted[:foo]
- assert_equal 'bar was dumped and loaded', cookies.encrypted[:foo]
- end
-
- def test_encrypted_cookie_using_custom_digest
- @request.env["action_dispatch.cookies_digest"] = 'SHA256'
- get :set_encrypted_cookie
- cookies = @controller.send :cookies
- assert_not_equal 'bar', cookies[:foo]
- assert_equal 'bar', cookies.encrypted[:foo]
-
- sign_secret = @request.env["action_dispatch.key_generator"].generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
-
- sha1_verifier = ActiveSupport::MessageVerifier.new(sign_secret, serializer: ActiveSupport::MessageEncryptor::NullSerializer, digest: 'SHA1')
- sha256_verifier = ActiveSupport::MessageVerifier.new(sign_secret, serializer: ActiveSupport::MessageEncryptor::NullSerializer, digest: 'SHA256')
-
- assert_raises(ActiveSupport::MessageVerifier::InvalidSignature) do
- sha1_verifier.verify(cookies[:foo])
- end
-
- assert_nothing_raised do
- sha256_verifier.verify(cookies[:foo])
- end
+ assert_not_equal "bar", cookies.encrypted[:foo]
+ assert_equal "bar was dumped and loaded", cookies.encrypted[:foo]
end
def test_encrypted_cookie_using_hybrid_serializer_can_migrate_marshal_dumped_value_to_json
@request.env["action_dispatch.cookies_serializer"] = :hybrid
key_generator = @request.env["action_dispatch.key_generator"]
- encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
- encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
- secret = key_generator.generate_key(encrypted_cookie_salt)
- sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
+ secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], 32)
- marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: Marshal).encrypt_and_sign("bar")
- @request.headers["Cookie"] = "foo=#{marshal_value}"
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
+ marshal_value = encryptor.encrypt_and_sign("bar")
+ @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape marshal_value}"
get :get_encrypted_cookie
@@ -612,20 +690,20 @@ class CookiesTest < ActionController::TestCase
assert_not_equal "bar", cookies[:foo]
assert_equal "bar", cookies.encrypted[:foo]
- encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
- assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
+ json_encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
+ assert_not_nil @response.cookies["foo"]
+ assert_equal "bar", json_encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_encrypted_cookie_using_hybrid_serializer_can_read_from_json_dumped_value
@request.env["action_dispatch.cookies_serializer"] = :hybrid
key_generator = @request.env["action_dispatch.key_generator"]
- encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
- encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
- secret = key_generator.generate_key(encrypted_cookie_salt)
- sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
- json_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON).encrypt_and_sign("bar")
- @request.headers["Cookie"] = "foo=#{json_value}"
+ secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], 32)
+
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
+ json_value = encryptor.encrypt_and_sign("bar")
+ @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape json_value}"
get :get_encrypted_cookie
@@ -638,7 +716,7 @@ class CookiesTest < ActionController::TestCase
def test_accessing_nonexistent_encrypted_cookie_should_not_raise_invalid_message
get :set_encrypted_cookie
- assert_nil @controller.send(:cookies).encrypted[:non_existant_attribute]
+ assert_nil @controller.send(:cookies).encrypted[:non_existent_attribute]
end
def test_setting_invalid_encrypted_cookie_should_return_nil_when_accessing_it
@@ -653,10 +731,10 @@ class CookiesTest < ActionController::TestCase
end
def test_delete_and_set_cookie
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_and_set_cookie
assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
def test_raise_data_overflow
@@ -687,7 +765,7 @@ class CookiesTest < ActionController::TestCase
get :set_signed_cookie
}
- assert_raise(ArgumentError, ''.inspect) {
+ assert_raise(ArgumentError, "".inspect) {
@request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("")
get :set_signed_cookie
}
@@ -710,65 +788,8 @@ class CookiesTest < ActionController::TestCase
}
end
- def test_signed_uses_signed_cookie_jar_if_only_secret_token_is_set
- @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = nil
- get :set_signed_cookie
- assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed
- end
-
- def test_signed_uses_signed_cookie_jar_if_only_secret_key_base_is_set
- @request.env["action_dispatch.secret_token"] = nil
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :set_signed_cookie
- assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed
- end
-
- def test_signed_uses_upgrade_legacy_signed_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
- @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :set_signed_cookie
- assert_kind_of ActionDispatch::Cookies::UpgradeLegacySignedCookieJar, cookies.signed
- end
-
- def test_signed_or_encrypted_uses_signed_cookie_jar_if_only_secret_token_is_set
- @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = nil
- get :get_encrypted_cookie
- assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed_or_encrypted
- end
-
- def test_signed_or_encrypted_uses_encrypted_cookie_jar_if_only_secret_key_base_is_set
- @request.env["action_dispatch.secret_token"] = nil
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :get_encrypted_cookie
- assert_kind_of ActionDispatch::Cookies::EncryptedCookieJar, cookies.signed_or_encrypted
- end
-
- def test_signed_or_encrypted_uses_upgrade_legacy_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
- @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :get_encrypted_cookie
- assert_kind_of ActionDispatch::Cookies::UpgradeLegacyEncryptedCookieJar, cookies.signed_or_encrypted
- end
-
- def test_encrypted_uses_encrypted_cookie_jar_if_only_secret_key_base_is_set
- @request.env["action_dispatch.secret_token"] = nil
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :get_encrypted_cookie
- assert_kind_of ActionDispatch::Cookies::EncryptedCookieJar, cookies.encrypted
- end
-
- def test_encrypted_uses_upgrade_legacy_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
- @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- get :get_encrypted_cookie
- assert_kind_of ActionDispatch::Cookies::UpgradeLegacyEncryptedCookieJar, cookies.encrypted
- end
-
def test_legacy_signed_cookie_is_read_and_transparently_upgraded_by_signed_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate(45)
@@ -785,28 +806,22 @@ class CookiesTest < ActionController::TestCase
def test_legacy_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- @request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
- @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
- legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate('bar')
+ legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate("bar")
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
- assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
+ assert_equal "bar", @controller.send(:cookies).encrypted[:foo]
- key_generator = @request.env["action_dispatch.key_generator"]
- secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
- sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
- encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
- assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
+ secret = @request.env["action_dispatch.key_generator"].generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], 32)
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@@ -824,28 +839,24 @@ class CookiesTest < ActionController::TestCase
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- @request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
- @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
- legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
+ legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate("bar")
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
- assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
+ assert_equal "bar", @controller.send(:cookies).encrypted[:foo]
- key_generator = @request.env["action_dispatch.key_generator"]
- secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
- sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
- encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
- assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
+ cipher = "aes-256-gcm"
+ salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ secret = @request.env["action_dispatch.key_generator"].generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len(cipher)]
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: cipher, serializer: JSON)
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@@ -863,28 +874,23 @@ class CookiesTest < ActionController::TestCase
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- @request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
- @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
- legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
+ legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate("bar")
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
- assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
+ assert_equal "bar", @controller.send(:cookies).encrypted[:foo]
- key_generator = @request.env["action_dispatch.key_generator"]
- secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
- sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
- encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
- assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
+ salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ secret = @request.env["action_dispatch.key_generator"].generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")]
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_marshal_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate(45)
@@ -901,45 +907,170 @@ class CookiesTest < ActionController::TestCase
def test_legacy_marshal_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
+
+ @request.env["action_dispatch.use_authenticated_cookie_encryption"] = true
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
- @request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
- @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
- legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate('bar')
+ legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate("bar")
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
- assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
+ assert_equal "bar", @controller.send(:cookies).encrypted[:foo]
- key_generator = @request.env["action_dispatch.key_generator"]
- secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
- sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
- encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
- assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
+ salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ secret = @request.env["action_dispatch.key_generator"].generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")]
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.headers["Cookie"] = "user_id=45"
get :get_signed_cookie
- assert_equal nil, @controller.send(:cookies).signed[:user_id]
- assert_equal nil, @response.cookies["user_id"]
+ assert_nil @controller.send(:cookies).signed[:user_id]
+ assert_nil @response.cookies["user_id"]
end
def test_legacy_signed_cookie_is_treated_as_nil_by_encrypted_cookie_jar_if_tampered
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
- @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.headers["Cookie"] = "foo=baz"
get :get_encrypted_cookie
- assert_equal nil, @controller.send(:cookies).encrypted[:foo]
- assert_equal nil, @response.cookies["foo"]
+ assert_nil @controller.send(:cookies).encrypted[:foo]
+ assert_nil @response.cookies["foo"]
+ end
+
+ def test_use_authenticated_cookie_encryption_uses_legacy_hmac_aes_cbc_encryption_when_not_enabled
+ @request.env["action_dispatch.use_authenticated_cookie_encryption"] = nil
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+ encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
+ encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
+ secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
+ sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", digest: "SHA1", serializer: Marshal)
+
+ get :set_encrypted_cookie
+
+ cookies = @controller.send :cookies
+ assert_not_equal "bar", cookies[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
+ end
+
+ def test_rotating_signed_cookies_digest
+ @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
+ @request.env["action_dispatch.cookies_rotations"].rotate :signed, digest: "SHA1"
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+
+ old_secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+ old_value = ActiveSupport::MessageVerifier.new(old_secret).generate(45)
+
+ @request.headers["Cookie"] = "user_id=#{old_value}"
+ get :get_signed_cookie
+
+ assert_equal 45, @controller.send(:cookies).signed[:user_id]
+
+ secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+ verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA256")
+ assert_equal 45, verifier.verify(@response.cookies["user_id"])
+ end
+
+ def test_legacy_hmac_aes_cbc_encrypted_marshal_cookie_is_upgraded_to_authenticated_encrypted_cookie
+ key_generator = @request.env["action_dispatch.key_generator"]
+ encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
+ encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
+ secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
+ sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
+ marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", serializer: Marshal).encrypt_and_sign("bar")
+
+ @request.headers["Cookie"] = "foo=#{marshal_value}"
+
+ get :get_encrypted_cookie
+
+ cookies = @controller.send :cookies
+ assert_not_equal "bar", cookies[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
+
+ aead_salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ aead_secret = key_generator.generate_key(aead_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm"))
+ aead_encryptor = ActiveSupport::MessageEncryptor.new(aead_secret, cipher: "aes-256-gcm", serializer: Marshal)
+
+ assert_equal "bar", aead_encryptor.decrypt_and_verify(@response.cookies["foo"])
+ end
+
+ def test_legacy_hmac_aes_cbc_encrypted_json_cookie_is_upgraded_to_authenticated_encrypted_cookie
+ @request.env["action_dispatch.cookies_serializer"] = :json
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+ encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
+ encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
+ secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
+ sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
+ marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", serializer: JSON).encrypt_and_sign("bar")
+
+ @request.headers["Cookie"] = "foo=#{marshal_value}"
+
+ get :get_encrypted_cookie
+
+ cookies = @controller.send :cookies
+ assert_not_equal "bar", cookies[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
+
+ aead_salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ aead_secret = key_generator.generate_key(aead_salt)[0, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")]
+ aead_encryptor = ActiveSupport::MessageEncryptor.new(aead_secret, cipher: "aes-256-gcm", serializer: JSON)
+
+ assert_equal "bar", aead_encryptor.decrypt_and_verify(@response.cookies["foo"])
+ end
+
+ def test_legacy_hmac_aes_cbc_encrypted_cookie_using_64_byte_key_is_upgraded_to_authenticated_encrypted_cookie
+ @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
+ @request.env["action_dispatch.encrypted_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
+ @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
+
+ # Cookie generated with 64 bytes secret
+ message = ["566d4e75536d686e633246564e6b493062557079626c566d51574d30515430394c53315665564a694e4563786555744f57537454576b396a5a31566a626e52525054303d2d2d34663234333330623130623261306163363562316266323335396164666364613564643134623131"].pack("H*")
+ @request.headers["Cookie"] = "foo=#{message}"
+
+ get :get_encrypted_cookie
+
+ cookies = @controller.send :cookies
+ assert_not_equal "bar", cookies[:foo]
+ assert_equal "bar", cookies.encrypted[:foo]
+
+ salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
+ secret = @request.env["action_dispatch.key_generator"].generate_key(salt, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm"))
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
+
+ assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
+ end
+
+ def test_encrypted_cookie_rotating_secret
+ secret = "b3c631c314c0bbca50c1b2843150fe33"
+
+ @request.env["action_dispatch.encrypted_cookie_cipher"] = "aes-256-gcm"
+ @request.env["action_dispatch.cookies_rotations"].rotate :encrypted, secret
+
+ key_len = ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")
+
+ old_message = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal).encrypt_and_sign(45)
+
+ @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape old_message}"
+
+ get :get_encrypted_cookie
+ assert_equal 45, @controller.send(:cookies).encrypted[:foo]
+
+ key_generator = @request.env["action_dispatch.key_generator"]
+ secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], key_len)
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
+ assert_equal 45, encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_cookie_with_all_domain_option
@@ -998,7 +1129,7 @@ class CookiesTest < ActionController::TestCase
end
def test_deleting_cookie_with_all_domain_option
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_cookie_with_domain
assert_response :success
assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
@@ -1032,7 +1163,7 @@ class CookiesTest < ActionController::TestCase
end
def test_deleting_cookie_with_all_domain_option_and_tld_length
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_cookie_with_domain_and_tld
assert_response :success
assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
@@ -1061,7 +1192,7 @@ class CookiesTest < ActionController::TestCase
def test_deletings_cookie_with_several_preset_domains_using_one_of_these_domains
@request.host = "example2.com"
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_cookie_with_domains
assert_response :success
assert_cookie_header "user_name=; domain=example2.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
@@ -1069,7 +1200,7 @@ class CookiesTest < ActionController::TestCase
def test_deletings_cookie_with_several_preset_domains_using_other_domain
@request.host = "other-domain.com"
- request.cookies[:user_name] = 'Joe'
+ request.cookies[:user_name] = "Joe"
get :delete_cookie_with_domains
assert_response :success
assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
@@ -1078,20 +1209,20 @@ class CookiesTest < ActionController::TestCase
def test_cookies_hash_is_indifferent_access
get :symbol_key
assert_equal "david", cookies[:user_name]
- assert_equal "david", cookies['user_name']
+ assert_equal "david", cookies["user_name"]
get :string_key
assert_equal "dhh", cookies[:user_name]
- assert_equal "dhh", cookies['user_name']
+ assert_equal "dhh", cookies["user_name"]
end
def test_setting_request_cookies_is_indifferent_access
cookies.clear
cookies[:user_name] = "andrew"
get :string_key_mock
- assert_equal "david", cookies['user_name']
+ assert_equal "david", cookies["user_name"]
cookies.clear
- cookies['user_name'] = "andrew"
+ cookies["user_name"] = "andrew"
get :symbol_key_mock
assert_equal "david", cookies[:user_name]
end
@@ -1102,11 +1233,11 @@ class CookiesTest < ActionController::TestCase
assert_equal "david", cookies[:user_name]
get :noop
- assert !@response.headers.include?("Set-Cookie")
+ assert_not_includes @response.headers, "Set-Cookie"
assert_equal "david", cookies[:user_name]
get :noop
- assert !@response.headers.include?("Set-Cookie")
+ assert_not_includes @response.headers, "Set-Cookie"
assert_equal "david", cookies[:user_name]
end
@@ -1123,57 +1254,212 @@ class CookiesTest < ActionController::TestCase
end
def test_can_set_http_cookie_header
- @request.env['HTTP_COOKIE'] = 'user_name=david'
+ @request.env["HTTP_COOKIE"] = "user_name=david"
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
- @request.env['HTTP_COOKIE'] = 'user_name=andrew'
+ @request.env["HTTP_COOKIE"] = "user_name=andrew"
get :noop
- assert_equal 'andrew', cookies['user_name']
- assert_equal 'andrew', cookies[:user_name]
+ assert_equal "andrew", cookies["user_name"]
+ assert_equal "andrew", cookies[:user_name]
end
def test_can_set_request_cookies
- @request.cookies['user_name'] = 'david'
+ @request.cookies["user_name"] = "david"
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
- @request.cookies[:user_name] = 'andrew'
+ @request.cookies[:user_name] = "andrew"
get :noop
- assert_equal 'andrew', cookies['user_name']
- assert_equal 'andrew', cookies[:user_name]
+ assert_equal "andrew", cookies["user_name"]
+ assert_equal "andrew", cookies[:user_name]
end
def test_cookies_precedence_over_http_cookie
- @request.env['HTTP_COOKIE'] = 'user_name=andrew'
+ @request.env["HTTP_COOKIE"] = "user_name=andrew"
get :authenticate
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
end
def test_cookies_precedence_over_request_cookies
- @request.cookies['user_name'] = 'andrew'
+ @request.cookies["user_name"] = "andrew"
get :authenticate
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
+
+ get :noop
+ assert_equal "david", cookies["user_name"]
+ assert_equal "david", cookies[:user_name]
+ end
+ def test_cookies_are_not_cleared
+ cookies.encrypted["foo"] = "bar"
get :noop
- assert_equal 'david', cookies['user_name']
- assert_equal 'david', cookies[:user_name]
+ assert_equal "bar", @controller.encrypted_cookie
+ end
+
+ def test_signed_cookie_with_expires_set_relatively
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ cookies.signed[:user_name] = { value: "assain", expires: 2.hours }
+
+ travel 1.hour
+ assert_equal "assain", cookies.signed[:user_name]
+
+ travel 2.hours
+ assert_nil cookies.signed[:user_name]
+ end
+
+ def test_encrypted_cookie_with_expires_set_relatively
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ cookies.encrypted[:user_name] = { value: "assain", expires: 2.hours }
+
+ travel 1.hour
+ assert_equal "assain", cookies.encrypted[:user_name]
+
+ travel 2.hours
+ assert_nil cookies.encrypted[:user_name]
+ end
+
+ def test_vanilla_cookie_with_expires_set_relatively
+ travel_to Time.utc(2017, 8, 15) do
+ get :cookie_expires_in_two_hours
+ assert_cookie_header "user_name=assain; path=/; expires=Tue, 15 Aug 2017 02:00:00 -0000"
+ end
+ end
+
+ def test_purpose_metadata_for_encrypted_cookies
+ get :encrypted_discount_and_user_id_cookie
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_equal 50, cookies.encrypted[:discount_percentage]
+
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ get :encrypted_discount_and_user_id_cookie
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_nil cookies.encrypted[:discount_percentage]
+ end
+
+ def test_purpose_metadata_for_signed_cookies
+ get :signed_discount_and_user_id_cookie
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_equal 50, cookies.signed[:discount_percentage]
+
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ get :signed_discount_and_user_id_cookie
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_nil cookies.signed[:discount_percentage]
+ end
+
+ def test_switch_off_metadata_for_encrypted_cookies_if_config_is_false
+ request.env["action_dispatch.use_cookies_with_metadata"] = false
+
+ get :encrypted_discount_and_user_id_cookie
+
+ travel 2.hours
+ assert_equal 50, cookies.encrypted[:user_id]
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_not_equal 10, cookies.encrypted[:discount_percentage]
+ assert_equal 50, cookies.encrypted[:discount_percentage]
+ end
+
+ def test_switch_off_metadata_for_signed_cookies_if_config_is_false
+ request.env["action_dispatch.use_cookies_with_metadata"] = false
+
+ get :signed_discount_and_user_id_cookie
+
+ travel 2.hours
+ assert_equal 50, cookies.signed[:user_id]
+
+ cookies[:discount_percentage] = cookies[:user_id]
+ assert_not_equal 10, cookies.signed[:discount_percentage]
+ assert_equal 50, cookies.signed[:discount_percentage]
+ end
+
+ def test_read_rails_5_2_stable_encrypted_cookies_if_config_is_false
+ request.env["action_dispatch.use_cookies_with_metadata"] = false
+
+ get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on
+
+ assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
+
+ travel 1001.years do
+ assert_nil cookies.encrypted[:favorite]
+ end
+
+ get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off
+
+ assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
+ end
+
+ def test_read_rails_5_2_stable_signed_cookies_if_config_is_false
+ request.env["action_dispatch.use_cookies_with_metadata"] = false
+
+ get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on
+
+ assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
+
+ travel 1001.years do
+ assert_nil cookies.signed[:favorite]
+ end
+
+ get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off
+
+ assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
+ end
+
+ def test_read_rails_5_2_stable_encrypted_cookies_if_use_metadata_config_is_true
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on
+
+ assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
+
+ travel 1001.years do
+ assert_nil cookies.encrypted[:favorite]
+ end
+
+ get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off
+
+ assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
+ end
+
+ def test_read_rails_5_2_stable_signed_cookies_if_use_metadata_config_is_true
+ request.env["action_dispatch.use_cookies_with_metadata"] = true
+
+ get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on
+
+ assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
+
+ travel 1001.years do
+ assert_nil cookies.signed[:favorite]
+ end
+
+ get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off
+
+ assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
end
private
diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb
index 30772bd9ed..37399cfd07 100644
--- a/actionpack/test/dispatch/debug_exceptions_test.rb
+++ b/actionpack/test/dispatch/debug_exceptions_test.rb
@@ -1,6 +1,9 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class DebugExceptionsTest < ActionDispatch::IntegrationTest
+ InterceptedErrorInstance = StandardError.new
class Boomer
attr_accessor :closed
@@ -20,46 +23,60 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
end
def method_that_raises
- raise StandardError.new 'error in framework'
+ raise StandardError.new "error in framework"
+ end
+
+ def raise_nested_exceptions
+ begin
+ raise "First error"
+ rescue
+ begin
+ raise "Second error"
+ rescue
+ raise "Third error"
+ end
+ end
end
def call(env)
- env['action_dispatch.show_detailed_exceptions'] = @detailed
+ env["action_dispatch.show_detailed_exceptions"] = @detailed
req = ActionDispatch::Request.new(env)
case req.path
- when "/pass"
+ when %r{/pass}
[404, { "X-Cascade" => "pass" }, self]
- when "/not_found"
+ when %r{/not_found}
raise AbstractController::ActionNotFound
- when "/runtime_error"
+ when %r{/runtime_error}
raise RuntimeError
- when "/method_not_allowed"
+ when %r{/method_not_allowed}
raise ActionController::MethodNotAllowed
- when "/unknown_http_method"
+ when %r{/intercepted_error}
+ raise InterceptedErrorInstance
+ when %r{/unknown_http_method}
raise ActionController::UnknownHttpMethod
- when "/not_implemented"
+ when %r{/not_implemented}
raise ActionController::NotImplemented
- when "/unprocessable_entity"
+ when %r{/unprocessable_entity}
raise ActionController::InvalidAuthenticityToken
- when "/not_found_original_exception"
+ when %r{/not_found_original_exception}
begin
raise AbstractController::ActionNotFound.new
rescue
- raise ActionView::Template::Error.new('template')
+ raise ActionView::Template::Error.new("template")
end
- when "/missing_template"
- raise ActionView::MissingTemplate.new(%w(foo), 'foo/index', %w(foo), false, 'mailer')
- when "/bad_request"
+ when %r{/missing_template}
+ raise ActionView::MissingTemplate.new(%w(foo), "foo/index", %w(foo), false, "mailer")
+ when %r{/bad_request}
raise ActionController::BadRequest
- when "/missing_keys"
+ when %r{/missing_keys}
raise ActionController::UrlGenerationError, "No route matches"
- when "/parameter_missing"
+ when %r{/parameter_missing}
raise ActionController::ParameterMissing, :missing_param_key
- when "/original_syntax_error"
- eval 'broke_syntax =' # `eval` need for raise native SyntaxError at runtime
- when "/syntax_error_into_view"
+ when %r{/original_syntax_error}
+ eval "broke_syntax =" # `eval` need for raise native SyntaxError at runtime
+ when %r{/syntax_error_into_view}
begin
- eval 'broke_syntax ='
+ eval "broke_syntax ="
rescue Exception
template = ActionView::Template.new(File.read(__FILE__),
__FILE__,
@@ -67,97 +84,103 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
{})
raise ActionView::Template::Error.new(template)
end
- when "/framework_raises"
+ when %r{/framework_raises}
method_that_raises
+ when %r{/nested_exceptions}
+ raise_nested_exceptions
else
raise "puke!"
end
end
end
+ Interceptor = proc { |request, exception| request.set_header("int", exception) }
+ BadInterceptor = proc { |request, exception| raise "bad" }
RoutesApp = Struct.new(:routes).new(SharedTestRoutes)
ProductionApp = ActionDispatch::DebugExceptions.new(Boomer.new(false), RoutesApp)
DevelopmentApp = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp)
+ InterceptedApp = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :default, [Interceptor])
+ BadInterceptedApp = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :default, [BadInterceptor])
- test 'skip diagnosis if not showing detailed exceptions' do
+ test "skip diagnosis if not showing detailed exceptions" do
@app = ProductionApp
assert_raise RuntimeError do
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
end
end
- test 'skip diagnosis if not showing exceptions' do
+ test "skip diagnosis if not showing exceptions" do
@app = DevelopmentApp
assert_raise RuntimeError do
- get "/", headers: { 'action_dispatch.show_exceptions' => false }
+ get "/", headers: { "action_dispatch.show_exceptions" => false }
end
end
- test 'raise an exception on cascade pass' do
+ test "raise an exception on cascade pass" do
@app = ProductionApp
assert_raise ActionController::RoutingError do
- get "/pass", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/pass", headers: { "action_dispatch.show_exceptions" => true }
end
end
- test 'closes the response body on cascade pass' do
+ test "closes the response body on cascade pass" do
boomer = Boomer.new(false)
@app = ActionDispatch::DebugExceptions.new(boomer)
assert_raise ActionController::RoutingError do
- get "/pass", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/pass", headers: { "action_dispatch.show_exceptions" => true }
end
assert boomer.closed, "Expected to close the response body"
end
- test 'displays routes in a table when a RoutingError occurs' do
+ test "displays routes in a table when a RoutingError occurs" do
@app = DevelopmentApp
- get "/pass", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/pass", headers: { "action_dispatch.show_exceptions" => true }
routing_table = body[/route_table.*<.table>/m]
- assert_match '/:controller(/:action)(.:format)', routing_table
- assert_match ':controller#:action', routing_table
- assert_no_match '&lt;|&gt;', routing_table, "there should not be escaped html in the output"
+ assert_match "/:controller(/:action)(.:format)", routing_table
+ assert_match ":controller#:action", routing_table
+ assert_no_match "&lt;|&gt;", routing_table, "there should not be escaped html in the output"
end
- test 'displays request and response info when a RoutingError occurs' do
+ test "displays request and response info when a RoutingError occurs" do
@app = DevelopmentApp
- get "/pass", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/pass", headers: { "action_dispatch.show_exceptions" => true }
- assert_select 'h2', /Request/
- assert_select 'h2', /Response/
+ assert_select "h2", /Request/
+ assert_select "h2", /Response/
end
test "rescue with diagnostics message" do
@app = DevelopmentApp
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
assert_response 500
assert_match(/puke/, body)
- get "/not_found", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_match(/#{AbstractController::ActionNotFound.name}/, body)
- get "/method_not_allowed", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/method_not_allowed", headers: { "action_dispatch.show_exceptions" => true }
assert_response 405
assert_match(/ActionController::MethodNotAllowed/, body)
- get "/unknown_http_method", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/unknown_http_method", headers: { "action_dispatch.show_exceptions" => true }
assert_response 405
assert_match(/ActionController::UnknownHttpMethod/, body)
- get "/bad_request", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/bad_request", headers: { "action_dispatch.show_exceptions" => true }
assert_response 400
assert_match(/ActionController::BadRequest/, body)
- get "/parameter_missing", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/parameter_missing", headers: { "action_dispatch.show_exceptions" => true }
assert_response 400
assert_match(/ActionController::ParameterMissing/, body)
end
test "rescue with text error for xhr request" do
@app = DevelopmentApp
- xhr_request_env = {'action_dispatch.show_exceptions' => true, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'}
+ xhr_request_env = { "action_dispatch.show_exceptions" => true, "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest" }
get "/", headers: xhr_request_env
assert_response 500
@@ -166,12 +189,12 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_equal "text/plain", response.content_type
assert_match(/RuntimeError\npuke/, body)
- Rails.stub :root, Pathname.new('.') do
+ Rails.stub :root, Pathname.new(".") do
get "/", headers: xhr_request_env
assert_response 500
- assert_match 'Extracted source (around line #', body
- assert_select 'pre', { count: 0 }, body
+ assert_match "Extracted source (around line #", body
+ assert_select "pre", { count: 0 }, body
end
get "/not_found", headers: xhr_request_env
@@ -205,11 +228,91 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_match(/ActionController::ParameterMissing/, body)
end
+ test "rescue with JSON error for JSON API request" do
+ @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api)
+
+ get "/", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 500
+ assert_no_match(/<header>/, body)
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/RuntimeError: puke/, body)
+
+ get "/not_found", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 404
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/#{AbstractController::ActionNotFound.name}/, body)
+
+ get "/method_not_allowed", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 405
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/ActionController::MethodNotAllowed/, body)
+
+ get "/unknown_http_method", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 405
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/ActionController::UnknownHttpMethod/, body)
+
+ get "/bad_request", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 400
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/ActionController::BadRequest/, body)
+
+ get "/parameter_missing", headers: { "action_dispatch.show_exceptions" => true }, as: :json
+ assert_response 400
+ assert_no_match(/<body>/, body)
+ assert_equal "application/json", response.content_type
+ assert_match(/ActionController::ParameterMissing/, body)
+ end
+
+ test "rescue with HTML format for HTML API request" do
+ @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api)
+
+ get "/index.html", headers: { "action_dispatch.show_exceptions" => true }
+ assert_response 500
+ assert_match(/<header>/, body)
+ assert_match(/<body>/, body)
+ assert_equal "text/html", response.content_type
+ assert_match(/puke/, body)
+ end
+
+ test "rescue with XML format for XML API requests" do
+ @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api)
+
+ get "/index.xml", headers: { "action_dispatch.show_exceptions" => true }
+ assert_response 500
+ assert_equal "application/xml", response.content_type
+ assert_match(/RuntimeError: puke/, body)
+ end
+
+ test "rescue with JSON format as fallback if API request format is not supported" do
+ begin
+ Mime::Type.register "text/wibble", :wibble
+
+ ActionDispatch::IntegrationTest.register_encoder(:wibble,
+ param_encoder: -> params { params })
+
+ @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api)
+
+ get "/index", headers: { "action_dispatch.show_exceptions" => true }, as: :wibble
+ assert_response 500
+ assert_equal "application/json", response.content_type
+ assert_match(/RuntimeError: puke/, body)
+
+ ensure
+ Mime::Type.unregister :wibble
+ end
+ end
+
test "does not show filtered parameters" do
@app = DevelopmentApp
- get "/", params: { "foo"=>"bar" }, headers: { 'action_dispatch.show_exceptions' => true,
- 'action_dispatch.parameter_filter' => [:foo] }
+ get "/", params: { "foo" => "bar" }, headers: { "action_dispatch.show_exceptions" => true,
+ "action_dispatch.parameter_filter" => [:foo] }
assert_response 500
assert_match("&quot;foo&quot;=&gt;&quot;[FILTERED]&quot;", body)
end
@@ -217,7 +320,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
test "show registered original exception for wrapped exceptions" do
@app = DevelopmentApp
- get "/not_found_original_exception", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found_original_exception", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_match(/AbstractController::ActionNotFound/, body)
end
@@ -225,7 +328,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
test "named urls missing keys raise 500 level error" do
@app = DevelopmentApp
- get "/missing_keys", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/missing_keys", headers: { "action_dispatch.show_exceptions" => true }
assert_response 500
assert_match(/ActionController::UrlGenerationError/, body)
@@ -234,11 +337,11 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
test "show the controller name in the diagnostics template when controller name is present" do
@app = DevelopmentApp
get("/runtime_error", headers: {
- 'action_dispatch.show_exceptions' => true,
- 'action_dispatch.request.parameters' => {
- 'action' => 'show',
- 'id' => 'unknown',
- 'controller' => 'featured_tile'
+ "action_dispatch.show_exceptions" => true,
+ "action_dispatch.request.parameters" => {
+ "action" => "show",
+ "id" => "unknown",
+ "controller" => "featured_tile"
}
})
assert_response 500
@@ -249,74 +352,114 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
@app = DevelopmentApp
params = {
- 'id' => 'unknown',
- 'someparam' => {
- 'foo' => 'bar',
- 'abc' => 'goo'
+ "id" => "unknown",
+ "someparam" => {
+ "foo" => "bar",
+ "abc" => "goo"
}
}
get("/runtime_error", headers: {
- 'action_dispatch.show_exceptions' => true,
- 'action_dispatch.request.parameters' => {
- 'action' => 'show',
- 'controller' => 'featured_tile'
+ "action_dispatch.show_exceptions" => true,
+ "action_dispatch.request.parameters" => {
+ "action" => "show",
+ "controller" => "featured_tile"
}.merge(params)
})
assert_response 500
- assert_includes(body, CGI.escapeHTML(PP.pp(params, "", 200)))
+ assert_includes(body, CGI.escapeHTML(PP.pp(params, +"", 200)))
end
test "sets the HTTP charset parameter" do
@app = DevelopmentApp
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
assert_equal "text/html; charset=utf-8", response.headers["Content-Type"]
end
- test 'uses logger from env' do
+ test "uses logger from env" do
@app = DevelopmentApp
output = StringIO.new
- get "/", headers: { 'action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => Logger.new(output) }
+ get "/", headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => Logger.new(output) }
assert_match(/puke/, output.rewind && output.read)
end
- test 'uses backtrace cleaner from env' do
+ test "logs only what is necessary" do
+ @app = DevelopmentApp
+ io = StringIO.new
+ logger = ActiveSupport::Logger.new(io)
+
+ _old, ActionView::Base.logger = ActionView::Base.logger, logger
+ begin
+ get "/", headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => logger }
+ ensure
+ ActionView::Base.logger = _old
+ end
+
+ output = io.rewind && io.read
+ lines = output.lines
+
+ # Other than the first three...
+ assert_equal([" \n", "RuntimeError (puke!):\n", " \n"], lines.slice!(0, 3))
+ lines.each do |line|
+ # .. all the remaining lines should be from the backtrace
+ assert_match(/:\d+:in /, line)
+ end
+ end
+
+ test "logs with non active support loggers" do
+ @app = DevelopmentApp
+ io = StringIO.new
+ logger = Logger.new(io)
+
+ _old, ActionView::Base.logger = ActionView::Base.logger, logger
+ begin
+ assert_nothing_raised do
+ get "/", headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => logger }
+ end
+ ensure
+ ActionView::Base.logger = _old
+ end
+
+ assert_match(/puke/, io.rewind && io.read)
+ end
+
+ test "uses backtrace cleaner from env" do
@app = DevelopmentApp
backtrace_cleaner = ActiveSupport::BacktraceCleaner.new
- backtrace_cleaner.stub :clean, ['passed backtrace cleaner'] do
- get "/", headers: { 'action_dispatch.show_exceptions' => true, 'action_dispatch.backtrace_cleaner' => backtrace_cleaner }
+ backtrace_cleaner.stub :clean, ["passed backtrace cleaner"] do
+ get "/", headers: { "action_dispatch.show_exceptions" => true, "action_dispatch.backtrace_cleaner" => backtrace_cleaner }
assert_match(/passed backtrace cleaner/, body)
end
end
- test 'logs exception backtrace when all lines silenced' do
+ test "logs exception backtrace when all lines silenced" do
output = StringIO.new
backtrace_cleaner = ActiveSupport::BacktraceCleaner.new
backtrace_cleaner.add_silencer { true }
- env = {'action_dispatch.show_exceptions' => true,
- 'action_dispatch.logger' => Logger.new(output),
- 'action_dispatch.backtrace_cleaner' => backtrace_cleaner}
+ env = { "action_dispatch.show_exceptions" => true,
+ "action_dispatch.logger" => Logger.new(output),
+ "action_dispatch.backtrace_cleaner" => backtrace_cleaner }
get "/", headers: env
assert_operator((output.rewind && output.read).lines.count, :>, 10)
end
- test 'display backtrace when error type is SyntaxError' do
+ test "display backtrace when error type is SyntaxError" do
@app = DevelopmentApp
- get '/original_syntax_error', headers: { 'action_dispatch.backtrace_cleaner' => ActiveSupport::BacktraceCleaner.new }
+ get "/original_syntax_error", headers: { "action_dispatch.backtrace_cleaner" => ActiveSupport::BacktraceCleaner.new }
assert_response 500
- assert_select '#Application-Trace' do
- assert_select 'pre code', /syntax error, unexpected/
+ assert_select "#Application-Trace-0" do
+ assert_select "code", /syntax error, unexpected/
end
end
- test 'display backtrace on template missing errors' do
+ test "display backtrace on template missing errors" do
@app = DevelopmentApp
get "/missing_template"
@@ -325,56 +468,107 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_select "#container h2", /^Missing template/
- assert_select '#Application-Trace'
- assert_select '#Framework-Trace'
- assert_select '#Full-Trace'
+ assert_select "#Application-Trace-0"
+ assert_select "#Framework-Trace-0"
+ assert_select "#Full-Trace-0"
- assert_select 'h2', /Request/
+ assert_select "h2", /Request/
end
- test 'display backtrace when error type is SyntaxError wrapped by ActionView::Template::Error' do
+ test "display backtrace when error type is SyntaxError wrapped by ActionView::Template::Error" do
@app = DevelopmentApp
- get '/syntax_error_into_view', headers: { 'action_dispatch.backtrace_cleaner' => ActiveSupport::BacktraceCleaner.new }
+ get "/syntax_error_into_view", headers: { "action_dispatch.backtrace_cleaner" => ActiveSupport::BacktraceCleaner.new }
assert_response 500
- assert_select '#Application-Trace' do
- assert_select 'pre code', /syntax error, unexpected/
+ assert_select "#Application-Trace-0" do
+ assert_select "code", /syntax error, unexpected/
end
end
- test 'debug exceptions app shows user code that caused the error in source view' do
+ test "debug exceptions app shows user code that caused the error in source view" do
@app = DevelopmentApp
- Rails.stub :root, Pathname.new('.') do
+ Rails.stub :root, Pathname.new(".") do
cleaner = ActiveSupport::BacktraceCleaner.new.tap do |bc|
bc.add_silencer { |line| line =~ /method_that_raises/ }
bc.add_silencer { |line| line !~ %r{test/dispatch/debug_exceptions_test.rb} }
end
- get '/framework_raises', headers: { 'action_dispatch.backtrace_cleaner' => cleaner }
+ get "/framework_raises", headers: { "action_dispatch.backtrace_cleaner" => cleaner }
# Assert correct error
assert_response 500
- assert_select 'h2', /error in framework/
+ assert_select "h2", /error in framework/
# assert source view line is the call to method_that_raises
- assert_select 'div.source:not(.hidden)' do
- assert_select 'pre .line.active', /method_that_raises/
+ assert_select "div.source:not(.hidden)" do
+ assert_select "pre .line.active", /method_that_raises/
end
# assert first source view (hidden) that throws the error
- assert_select 'div.source:first' do
- assert_select 'pre .line.active', /raise StandardError\.new/
+ assert_select "div.source:first" do
+ assert_select "pre .line.active", /raise StandardError\.new/
end
# assert application trace refers to line that calls method_that_raises is first
- assert_select '#Application-Trace' do
- assert_select 'pre code a:first', %r{test/dispatch/debug_exceptions_test\.rb:\d+:in `call}
+ assert_select "#Application-Trace-0" do
+ assert_select "code a:first", %r{test/dispatch/debug_exceptions_test\.rb:\d+:in `call}
end
# assert framework trace that threw the error is first
- assert_select '#Framework-Trace' do
- assert_select 'pre code a:first', /method_that_raises/
+ assert_select "#Framework-Trace-0" do
+ assert_select "code a:first", /method_that_raises/
+ end
+ end
+ end
+
+ test "invoke interceptors before rendering" do
+ @app = InterceptedApp
+ get "/intercepted_error", headers: { "action_dispatch.show_exceptions" => true }
+
+ assert_equal InterceptedErrorInstance, request.get_header("int")
+ end
+
+ test "bad interceptors doesn't debug exceptions" do
+ @app = BadInterceptedApp
+
+ get "/puke", headers: { "action_dispatch.show_exceptions" => true }
+
+ assert_response 500
+ assert_match(/puke/, body)
+ end
+
+ test "debug exceptions app shows all the nested exceptions in source view" do
+ @app = DevelopmentApp
+ Rails.stub :root, Pathname.new(".") do
+ cleaner = ActiveSupport::BacktraceCleaner.new.tap do |bc|
+ bc.add_silencer { |line| line !~ %r{test/dispatch/debug_exceptions_test.rb} }
+ end
+
+ get "/nested_exceptions", headers: { "action_dispatch.backtrace_cleaner" => cleaner }
+
+ # Assert correct error
+ assert_response 500
+ assert_select "h2", /Third error/
+
+ # assert source view line shows the last error
+ assert_select "div.source:not(.hidden)" do
+ assert_select "pre .line.active", /raise "Third error"/
+ end
+
+ # assert application trace refers to line that raises the last exception
+ assert_select "#Application-Trace-0" do
+ assert_select "code a:first", %r{in `rescue in rescue in raise_nested_exceptions'}
+ end
+
+ # assert the second application trace refers to the line that raises the second exception
+ assert_select "#Application-Trace-1" do
+ assert_select "code a:first", %r{in `rescue in raise_nested_exceptions'}
+ end
+
+ # assert the third application trace refers to the line that raises the first exception
+ assert_select "#Application-Trace-2" do
+ assert_select "code a:first", %r{in `raise_nested_exceptions'}
end
end
end
diff --git a/actionpack/test/dispatch/debug_locks_test.rb b/actionpack/test/dispatch/debug_locks_test.rb
new file mode 100644
index 0000000000..d69614bd79
--- /dev/null
+++ b/actionpack/test/dispatch/debug_locks_test.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class DebugLocksTest < ActionDispatch::IntegrationTest
+ setup do
+ build_app
+ end
+
+ def test_render_threads_status
+ thread_ready = Concurrent::CountDownLatch.new
+ test_terminated = Concurrent::CountDownLatch.new
+
+ thread = Thread.new do
+ ActiveSupport::Dependencies.interlock.running do
+ thread_ready.count_down
+ test_terminated.wait
+ end
+ end
+
+ thread_ready.wait
+
+ get "/rails/locks"
+
+ test_terminated.count_down
+
+ assert_match(/Thread.*?Sharing/, @response.body)
+ ensure
+ thread.join
+ end
+
+ private
+ def build_app
+ @app = self.class.build_app do |middleware|
+ middleware.use ActionDispatch::DebugLocks
+ end
+ end
+end
diff --git a/actionpack/test/dispatch/exception_wrapper_test.rb b/actionpack/test/dispatch/exception_wrapper_test.rb
index dfbb91c0ca..668469a01d 100644
--- a/actionpack/test/dispatch/exception_wrapper_test.rb
+++ b/actionpack/test/dispatch/exception_wrapper_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
class ExceptionWrapperTest < ActionDispatch::IntegrationTest
@@ -18,46 +20,53 @@ module ActionDispatch
setup do
@cleaner = ActiveSupport::BacktraceCleaner.new
+ @cleaner.remove_filters!
@cleaner.add_silencer { |line| line !~ /^lib/ }
end
- test '#source_extracts fetches source fragments for every backtrace entry' do
+ test "#source_extracts fetches source fragments for every backtrace entry" do
exception = TestError.new("lib/file.rb:42:in `index'")
wrapper = ExceptionWrapper.new(nil, exception)
- assert_called_with(wrapper, :source_fragment, ['lib/file.rb', 42], returns: 'foo') do
- assert_equal [ code: 'foo', line_number: 42 ], wrapper.source_extracts
+ assert_called_with(wrapper, :source_fragment, ["lib/file.rb", 42], returns: "foo") do
+ assert_equal [ code: "foo", line_number: 42 ], wrapper.source_extracts
end
end
- test '#source_extracts works with Windows paths' do
+ test "#source_extracts works with Windows paths" do
exc = TestError.new("c:/path/to/rails/app/controller.rb:27:in 'index':")
wrapper = ExceptionWrapper.new(nil, exc)
- assert_called_with(wrapper, :source_fragment, ['c:/path/to/rails/app/controller.rb', 27], returns: 'nothing') do
- assert_equal [ code: 'nothing', line_number: 27 ], wrapper.source_extracts
+ assert_called_with(wrapper, :source_fragment, ["c:/path/to/rails/app/controller.rb", 27], returns: "nothing") do
+ assert_equal [ code: "nothing", line_number: 27 ], wrapper.source_extracts
end
end
- test '#source_extracts works with non standard backtrace' do
- exc = TestError.new('invalid')
+ test "#source_extracts works with non standard backtrace" do
+ exc = TestError.new("invalid")
wrapper = ExceptionWrapper.new(nil, exc)
- assert_called_with(wrapper, :source_fragment, ['invalid', 0], returns: 'nothing') do
- assert_equal [ code: 'nothing', line_number: 0 ], wrapper.source_extracts
+ assert_called_with(wrapper, :source_fragment, ["invalid", 0], returns: "nothing") do
+ assert_equal [ code: "nothing", line_number: 0 ], wrapper.source_extracts
end
end
- test '#application_trace returns traces only from the application' do
+ test "#application_trace returns traces only from the application" do
exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
wrapper = ExceptionWrapper.new(@cleaner, exception)
assert_equal [ "lib/file.rb:42:in `index'" ], wrapper.application_trace
end
- test '#application_trace cannot be nil' do
+ test "#status_code returns 400 for Rack::Utils::ParameterTypeError" do
+ exception = Rack::Utils::ParameterTypeError.new
+ wrapper = ExceptionWrapper.new(@cleaner, exception)
+ assert_equal 400, wrapper.status_code
+ end
+
+ test "#application_trace cannot be nil" do
nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)
@@ -65,14 +74,14 @@ module ActionDispatch
assert_equal [], nil_cleaner_wrapper.application_trace
end
- test '#framework_trace returns traces outside the application' do
+ test "#framework_trace returns traces outside the application" do
exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
wrapper = ExceptionWrapper.new(@cleaner, exception)
assert_equal caller, wrapper.framework_trace
end
- test '#framework_trace cannot be nil' do
+ test "#framework_trace cannot be nil" do
nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)
@@ -80,14 +89,14 @@ module ActionDispatch
assert_equal [], nil_cleaner_wrapper.framework_trace
end
- test '#full_trace returns application and framework traces' do
+ test "#full_trace returns application and framework traces" do
exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
wrapper = ExceptionWrapper.new(@cleaner, exception)
assert_equal exception.backtrace, wrapper.full_trace
end
- test '#full_trace cannot be nil' do
+ test "#full_trace cannot be nil" do
nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)
@@ -95,16 +104,32 @@ module ActionDispatch
assert_equal [], nil_cleaner_wrapper.full_trace
end
- test '#traces returns every trace by category enumerated with an index' do
+ test "#traces returns every trace by category enumerated with an index" do
exception = TestError.new("lib/file.rb:42:in `index'", "/gems/rack.rb:43:in `index'")
wrapper = ExceptionWrapper.new(@cleaner, exception)
assert_equal({
- 'Application Trace' => [ id: 0, trace: "lib/file.rb:42:in `index'" ],
- 'Framework Trace' => [ id: 1, trace: "/gems/rack.rb:43:in `index'" ],
- 'Full Trace' => [
- { id: 0, trace: "lib/file.rb:42:in `index'" },
- { id: 1, trace: "/gems/rack.rb:43:in `index'" }
+ "Application Trace" => [
+ exception_object_id: exception.object_id,
+ id: 0,
+ trace: "lib/file.rb:42:in `index'"
+ ],
+ "Framework Trace" => [
+ exception_object_id: exception.object_id,
+ id: 1,
+ trace: "/gems/rack.rb:43:in `index'"
+ ],
+ "Full Trace" => [
+ {
+ exception_object_id: exception.object_id,
+ id: 0,
+ trace: "lib/file.rb:42:in `index'"
+ },
+ {
+ exception_object_id: exception.object_id,
+ id: 1,
+ trace: "/gems/rack.rb:43:in `index'"
+ }
]
}, wrapper.traces)
end
diff --git a/actionpack/test/dispatch/executor_test.rb b/actionpack/test/dispatch/executor_test.rb
new file mode 100644
index 0000000000..5b8be39b6d
--- /dev/null
+++ b/actionpack/test/dispatch/executor_test.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class ExecutorTest < ActiveSupport::TestCase
+ class MyBody < Array
+ def initialize(&block)
+ @on_close = block
+ end
+
+ def foo
+ "foo"
+ end
+
+ def bar
+ "bar"
+ end
+
+ def close
+ @on_close.call if @on_close
+ end
+ end
+
+ def test_returned_body_object_always_responds_to_close
+ body = call_and_return_body
+ assert_respond_to body, :close
+ end
+
+ def test_returned_body_object_always_responds_to_close_even_if_called_twice
+ body = call_and_return_body
+ assert_respond_to body, :close
+ body.close
+
+ body = call_and_return_body
+ assert_respond_to body, :close
+ body.close
+ end
+
+ def test_returned_body_object_behaves_like_underlying_object
+ body = call_and_return_body do
+ b = MyBody.new
+ b << "hello"
+ b << "world"
+ [200, { "Content-Type" => "text/html" }, b]
+ end
+ assert_equal 2, body.size
+ assert_equal "hello", body[0]
+ assert_equal "world", body[1]
+ assert_equal "foo", body.foo
+ assert_equal "bar", body.bar
+ end
+
+ def test_it_calls_close_on_underlying_object_when_close_is_called_on_body
+ close_called = false
+ body = call_and_return_body do
+ b = MyBody.new do
+ close_called = true
+ end
+ [200, { "Content-Type" => "text/html" }, b]
+ end
+ body.close
+ assert close_called
+ end
+
+ def test_returned_body_object_responds_to_all_methods_supported_by_underlying_object
+ body = call_and_return_body do
+ [200, { "Content-Type" => "text/html" }, MyBody.new]
+ end
+ assert_respond_to body, :size
+ assert_respond_to body, :each
+ assert_respond_to body, :foo
+ assert_respond_to body, :bar
+ end
+
+ def test_run_callbacks_are_called_before_close
+ running = false
+ executor.to_run { running = true }
+
+ body = call_and_return_body
+ assert running
+
+ running = false
+ body.close
+ assert_not running
+ end
+
+ def test_complete_callbacks_are_called_on_close
+ completed = false
+ executor.to_complete { completed = true }
+
+ body = call_and_return_body
+ assert_not completed
+
+ body.close
+ assert completed
+ end
+
+ def test_complete_callbacks_are_called_on_exceptions
+ completed = false
+ executor.to_complete { completed = true }
+
+ begin
+ call_and_return_body do
+ raise "error"
+ end
+ rescue
+ end
+
+ assert completed
+ end
+
+ def test_callbacks_execute_in_shared_context
+ result = false
+ executor.to_run { @in_shared_context = true }
+ executor.to_complete { result = @in_shared_context }
+
+ call_and_return_body.close
+ assert result
+ assert_not defined?(@in_shared_context) # it's not in the test itself
+ end
+
+ private
+ def call_and_return_body(&block)
+ app = middleware(block || proc { [200, {}, "response"] })
+ _, _, body = app.call("rack.input" => StringIO.new(""))
+ body
+ end
+
+ def middleware(inner_app)
+ ActionDispatch::Executor.new(inner_app, executor)
+ end
+
+ def executor
+ @executor ||= Class.new(ActiveSupport::Executor)
+ end
+end
diff --git a/actionpack/test/dispatch/header_test.rb b/actionpack/test/dispatch/header_test.rb
index 7f1ef121b7..bd2a5b35fb 100644
--- a/actionpack/test/dispatch/header_test.rb
+++ b/actionpack/test/dispatch/header_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "abstract_unit"
class HeaderTest < ActiveSupport::TestCase
@@ -18,14 +20,14 @@ class HeaderTest < ActiveSupport::TestCase
"HTTP_REFERER" => "/some/page",
"Host" => "http://test.com")
- assert_equal({"Content-Type" => "application/json",
+ assert_equal({ "Content-Type" => "application/json",
"HTTP_REFERER" => "/some/page",
- "Host" => "http://test.com"}, headers.env)
+ "Host" => "http://test.com" }, headers.env)
end
test "#env returns the headers as env variables" do
- assert_equal({"CONTENT_TYPE" => "text/plain",
- "HTTP_REFERER" => "/some/page"}, @headers.env)
+ assert_equal({ "CONTENT_TYPE" => "text/plain",
+ "HTTP_REFERER" => "/some/page" }, @headers.env)
end
test "#each iterates through the env variables" do
@@ -44,20 +46,20 @@ class HeaderTest < ActiveSupport::TestCase
test "add to multivalued headers" do
# Sets header when not present
- @headers.add 'Foo', '1'
- assert_equal '1', @headers['Foo']
+ @headers.add "Foo", "1"
+ assert_equal "1", @headers["Foo"]
# Ignores nil values
- @headers.add 'Foo', nil
- assert_equal '1', @headers['Foo']
+ @headers.add "Foo", nil
+ assert_equal "1", @headers["Foo"]
# Converts value to string
- @headers.add 'Foo', 1
- assert_equal '1,1', @headers['Foo']
+ @headers.add "Foo", 1
+ assert_equal "1,1", @headers["Foo"]
# Case-insensitive
- @headers.add 'fOo', 2
- assert_equal '1,1,2', @headers['foO']
+ @headers.add "fOo", 2
+ assert_equal "1,1,2", @headers["foO"]
end
test "headers can contain numbers" do
@@ -76,9 +78,9 @@ class HeaderTest < ActiveSupport::TestCase
test "key?" do
assert @headers.key?("CONTENT_TYPE")
- assert @headers.include?("CONTENT_TYPE")
+ assert_includes @headers, "CONTENT_TYPE"
assert @headers.key?("Content-Type")
- assert @headers.include?("Content-Type")
+ assert_includes @headers, "Content-Type"
end
test "fetch with block" do
@@ -105,28 +107,28 @@ class HeaderTest < ActiveSupport::TestCase
test "#merge! headers with mutation" do
@headers.merge!("Host" => "http://example.test",
"Content-Type" => "text/html")
- assert_equal({"HTTP_HOST" => "http://example.test",
+ assert_equal({ "HTTP_HOST" => "http://example.test",
"CONTENT_TYPE" => "text/html",
- "HTTP_REFERER" => "/some/page"}, @headers.env)
+ "HTTP_REFERER" => "/some/page" }, @headers.env)
end
test "#merge! env with mutation" do
@headers.merge!("HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html")
- assert_equal({"HTTP_HOST" => "http://first.com",
+ assert_equal({ "HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html",
- "HTTP_REFERER" => "/some/page"}, @headers.env)
+ "HTTP_REFERER" => "/some/page" }, @headers.env)
end
test "merge without mutation" do
combined = @headers.merge("HTTP_HOST" => "http://example.com",
"CONTENT_TYPE" => "text/html")
- assert_equal({"HTTP_HOST" => "http://example.com",
+ assert_equal({ "HTTP_HOST" => "http://example.com",
"CONTENT_TYPE" => "text/html",
- "HTTP_REFERER" => "/some/page"}, combined.env)
+ "HTTP_REFERER" => "/some/page" }, combined.env)
- assert_equal({"CONTENT_TYPE" => "text/plain",
- "HTTP_REFERER" => "/some/page"}, @headers.env)
+ assert_equal({ "CONTENT_TYPE" => "text/plain",
+ "HTTP_REFERER" => "/some/page" }, @headers.env)
end
test "env variables with . are not modified" do
@@ -151,11 +153,17 @@ class HeaderTest < ActiveSupport::TestCase
end
test "headers directly modifies the passed environment" do
- env = {"HTTP_REFERER" => "/"}
+ env = { "HTTP_REFERER" => "/" }
headers = make_headers(env)
- headers['Referer'] = "http://example.com/"
- headers.merge! "CONTENT_TYPE" => "text/plain"
- assert_equal({"HTTP_REFERER"=>"http://example.com/",
- "CONTENT_TYPE"=>"text/plain"}, env)
+ headers["Referer"] = "http://example.com/"
+ headers["CONTENT_TYPE"] = "text/plain"
+ assert_equal({ "HTTP_REFERER" => "http://example.com/",
+ "CONTENT_TYPE" => "text/plain" }, env)
+ end
+
+ test "fetch exception" do
+ assert_raises KeyError do
+ @headers.fetch(:some_key_that_doesnt_exist)
+ end
end
end
diff --git a/actionpack/test/dispatch/live_response_test.rb b/actionpack/test/dispatch/live_response_test.rb
index e4475f4233..a9a56f205f 100644
--- a/actionpack/test/dispatch/live_response_test.rb
+++ b/actionpack/test/dispatch/live_response_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'concurrent/atomic/count_down_latch'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "concurrent/atomic/count_down_latch"
module ActionController
module Live
@@ -10,7 +12,7 @@ module ActionController
end
def test_header_merge
- header = @response.header.merge('Foo' => 'Bar')
+ header = @response.header.merge("Foo" => "Bar")
assert_kind_of(ActionController::Live::Response::Header, header)
assert_not_equal header, @response.header
end
@@ -18,7 +20,7 @@ module ActionController
def test_initialize_with_default_headers
r = Class.new(Live::Response) do
def self.default_headers
- { 'omg' => 'g' }
+ { "omg" => "g" }
end
end
@@ -30,53 +32,53 @@ module ActionController
latch = Concurrent::CountDownLatch.new
t = Thread.new {
- @response.stream.write 'foo'
+ @response.stream.write "foo"
latch.wait
@response.stream.close
}
@response.await_commit
@response.each do |part|
- assert_equal 'foo', part
+ assert_equal "foo", part
latch.count_down
end
assert t.join
end
def test_setting_body_populates_buffer
- @response.body = 'omg'
+ @response.body = "omg"
@response.close
- assert_equal ['omg'], @response.body_parts
+ assert_equal ["omg"], @response.body_parts
end
def test_cache_control_is_set
- @response.stream.write 'omg'
- assert_equal 'no-cache', @response.headers['Cache-Control']
+ @response.stream.write "omg"
+ assert_equal "no-cache", @response.headers["Cache-Control"]
end
def test_content_length_is_removed
- @response.headers['Content-Length'] = "1234"
- @response.stream.write 'omg'
- assert_nil @response.headers['Content-Length']
+ @response.headers["Content-Length"] = "1234"
+ @response.stream.write "omg"
+ assert_nil @response.headers["Content-Length"]
end
def test_headers_cannot_be_written_after_webserver_reads
- @response.stream.write 'omg'
+ @response.stream.write "omg"
latch = Concurrent::CountDownLatch.new
t = Thread.new {
- @response.stream.each do
+ @response.each do
latch.count_down
end
}
latch.wait
- assert @response.headers.frozen?
+ assert_predicate @response.headers, :frozen?
e = assert_raises(ActionDispatch::IllegalStateError) do
- @response.headers['Content-Length'] = "zomg"
+ @response.headers["Content-Length"] = "zomg"
end
- assert_equal 'header already sent', e.message
+ assert_equal "header already sent", e.message
@response.stream.close
t.join
end
@@ -87,9 +89,9 @@ module ActionController
@response.each { |x| }
e = assert_raises(ActionDispatch::IllegalStateError) do
- @response.headers['Content-Length'] = "zomg"
+ @response.headers["Content-Length"] = "zomg"
end
- assert_equal 'header already sent', e.message
+ assert_equal "header already sent", e.message
end
end
end
diff --git a/actionpack/test/dispatch/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb
index df27e41997..969a08efed 100644
--- a/actionpack/test/dispatch/mapper_test.rb
+++ b/actionpack/test/dispatch/mapper_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Routing
@@ -50,15 +52,15 @@ module ActionDispatch
fakeset = FakeSet.new
mapper = Mapper.new fakeset
assert_raises(ArgumentError) do
- mapper.match '/', :to => 'posts#index', :as => :main
+ mapper.match "/", to: "posts#index", as: :main
end
end
def test_unscoped_formatted
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/foo', :to => 'posts#index', :as => :main, :format => true
- assert_equal({:controller=>"posts", :action=>"index"},
+ mapper.get "/foo", to: "posts#index", as: :main, format: true
+ assert_equal({ controller: "posts", action: "index" },
fakeset.defaults.first)
assert_equal "/foo.:format", fakeset.asts.first.to_s
end
@@ -67,9 +69,9 @@ module ActionDispatch
fakeset = FakeSet.new
mapper = Mapper.new fakeset
mapper.scope(format: true) do
- mapper.get '/foo', :to => 'posts#index', :as => :main
+ mapper.get "/foo", to: "posts#index", as: :main
end
- assert_equal({:controller=>"posts", :action=>"index"},
+ assert_equal({ controller: "posts", action: "index" },
fakeset.defaults.first)
assert_equal "/foo.:format", fakeset.asts.first.to_s
end
@@ -78,18 +80,18 @@ module ActionDispatch
fakeset = FakeSet.new
mapper = Mapper.new fakeset
mapper.scope(omg: :awesome) do
- mapper.get '/', :to => 'posts#index', :as => :main
+ mapper.get "/", to: "posts#index", as: :main
end
- assert_equal({:omg=>:awesome, :controller=>"posts", :action=>"index"},
+ assert_equal({ omg: :awesome, controller: "posts", action: "index" },
fakeset.defaults.first)
assert_equal("GET", fakeset.routes.first.verb)
end
def test_mapping_requirements
- options = { }
+ options = {}
scope = Mapper::Scope.new({})
- ast = Journey::Parser.parse '/store/:name(*rest)'
- m = Mapper::Mapping.build(scope, FakeSet.new, ast, 'foo', 'bar', nil, [:get], nil, {}, true, options)
+ ast = Journey::Parser.parse "/store/:name(*rest)"
+ m = Mapper::Mapping.build(scope, FakeSet.new, ast, "foo", "bar", nil, [:get], nil, {}, true, options)
assert_equal(/.+?/, m.requirements[:rest])
end
@@ -97,16 +99,28 @@ module ActionDispatch
fakeset = FakeSet.new
mapper = Mapper.new fakeset
mapper.scope(via: :put) do
- mapper.match '/', :to => 'posts#index', :as => :main
+ mapper.match "/", to: "posts#index", as: :main
end
assert_equal("PUT", fakeset.routes.first.verb)
end
+ def test_to_scope
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.scope(to: "posts#index") do
+ mapper.get :all
+ mapper.post :most
+ end
+
+ assert_equal "posts#index", fakeset.routes.to_a[0].defaults[:to]
+ assert_equal "posts#index", fakeset.routes.to_a[1].defaults[:to]
+ end
+
def test_map_slash
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/', :to => 'posts#index', :as => :main
- assert_equal '/', fakeset.asts.first.to_s
+ mapper.get "/", to: "posts#index", as: :main
+ assert_equal "/", fakeset.asts.first.to_s
end
def test_map_more_slashes
@@ -114,31 +128,31 @@ module ActionDispatch
mapper = Mapper.new fakeset
# FIXME: is this a desired behavior?
- mapper.get '/one/two/', :to => 'posts#index', :as => :main
- assert_equal '/one/two(.:format)', fakeset.asts.first.to_s
+ mapper.get "/one/two/", to: "posts#index", as: :main
+ assert_equal "/one/two(.:format)", fakeset.asts.first.to_s
end
def test_map_wildcard
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/*path', :to => 'pages#show'
- assert_equal '/*path(.:format)', fakeset.asts.first.to_s
+ mapper.get "/*path", to: "pages#show"
+ assert_equal "/*path(.:format)", fakeset.asts.first.to_s
assert_equal(/.+?/, fakeset.requirements.first[:path])
end
def test_map_wildcard_with_other_element
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/*path/foo/:bar', :to => 'pages#show'
- assert_equal '/*path/foo/:bar(.:format)', fakeset.asts.first.to_s
+ mapper.get "/*path/foo/:bar", to: "pages#show"
+ assert_equal "/*path/foo/:bar(.:format)", fakeset.asts.first.to_s
assert_equal(/.+?/, fakeset.requirements.first[:path])
end
def test_map_wildcard_with_multiple_wildcard
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/*foo/*bar', :to => 'pages#show'
- assert_equal '/*foo/*bar(.:format)', fakeset.asts.first.to_s
+ mapper.get "/*foo/*bar", to: "pages#show"
+ assert_equal "/*foo/*bar(.:format)", fakeset.asts.first.to_s
assert_equal(/.+?/, fakeset.requirements.first[:foo])
assert_equal(/.+?/, fakeset.requirements.first[:bar])
end
@@ -146,16 +160,16 @@ module ActionDispatch
def test_map_wildcard_with_format_false
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/*path', :to => 'pages#show', :format => false
- assert_equal '/*path', fakeset.asts.first.to_s
+ mapper.get "/*path", to: "pages#show", format: false
+ assert_equal "/*path", fakeset.asts.first.to_s
assert_nil fakeset.requirements.first[:path]
end
def test_map_wildcard_with_format_true
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.get '/*path', :to => 'pages#show', :format => true
- assert_equal '/*path.:format', fakeset.asts.first.to_s
+ mapper.get "/*path", to: "pages#show", format: true
+ assert_equal "/*path.:format", fakeset.asts.first.to_s
end
def test_raising_error_when_path_is_not_passed
@@ -178,6 +192,19 @@ module ActionDispatch
mapper.mount as: "exciting"
end
end
+
+ def test_scope_does_not_destructively_mutate_default_options
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+
+ frozen = { foo: :bar }.freeze
+
+ assert_nothing_raised do
+ mapper.scope(defaults: frozen) do
+ # pass
+ end
+ end
+ end
end
end
end
diff --git a/actionpack/test/dispatch/middleware_stack_test.rb b/actionpack/test/dispatch/middleware_stack_test.rb
index 33aa616474..5f43e5a3c5 100644
--- a/actionpack/test/dispatch/middleware_stack_test.rb
+++ b/actionpack/test/dispatch/middleware_stack_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class MiddlewareStackTest < ActiveSupport::TestCase
class FooMiddleware; end
@@ -18,14 +20,6 @@ class MiddlewareStackTest < ActiveSupport::TestCase
@stack.use BarMiddleware
end
- def test_delete_with_string_is_deprecated
- assert_deprecated do
- assert_difference "@stack.size", -1 do
- @stack.delete FooMiddleware.name
- end
- end
- end
-
def test_delete_works
assert_difference "@stack.size", -1 do
@stack.delete FooMiddleware
@@ -39,34 +33,16 @@ class MiddlewareStackTest < ActiveSupport::TestCase
assert_equal BazMiddleware, @stack.last.klass
end
- test "use should push middleware as a string onto the stack" do
- assert_deprecated do
- assert_difference "@stack.size" do
- @stack.use "MiddlewareStackTest::BazMiddleware"
- end
- assert_equal BazMiddleware, @stack.last.klass
- end
- end
-
- test "use should push middleware as a symbol onto the stack" do
- assert_deprecated do
- assert_difference "@stack.size" do
- @stack.use :"MiddlewareStackTest::BazMiddleware"
- end
- assert_equal BazMiddleware, @stack.last.klass
- end
- end
-
test "use should push middleware class with arguments onto the stack" do
assert_difference "@stack.size" do
- @stack.use BazMiddleware, true, :foo => "bar"
+ @stack.use BazMiddleware, true, foo: "bar"
end
assert_equal BazMiddleware, @stack.last.klass
- assert_equal([true, {:foo => "bar"}], @stack.last.args)
+ assert_equal([true, { foo: "bar" }], @stack.last.args)
end
test "use should push middleware class with block arguments onto the stack" do
- proc = Proc.new {}
+ proc = Proc.new { }
assert_difference "@stack.size" do
@stack.use(BlockMiddleware, &proc)
end
@@ -102,15 +78,13 @@ class MiddlewareStackTest < ActiveSupport::TestCase
test "swaps one middleware out for same middleware class" do
assert_equal FooMiddleware, @stack[0].klass
- @stack.swap(FooMiddleware, FooMiddleware, Proc.new { |env| [500, {}, ['error!']] })
+ @stack.swap(FooMiddleware, FooMiddleware, Proc.new { |env| [500, {}, ["error!"]] })
assert_equal FooMiddleware, @stack[0].klass
end
test "unshift adds a new middleware at the beginning of the stack" do
- assert_deprecated do
- @stack.unshift :"MiddlewareStackTest::BazMiddleware"
- assert_equal BazMiddleware, @stack.first.klass
- end
+ @stack.unshift MiddlewareStackTest::BazMiddleware
+ assert_equal BazMiddleware, @stack.first.klass
end
test "raise an error on invalid index" do
@@ -123,12 +97,19 @@ class MiddlewareStackTest < ActiveSupport::TestCase
end
end
- test "lazy evaluates middleware class" do
- assert_deprecated do
- assert_difference "@stack.size" do
- @stack.use "MiddlewareStackTest::BazMiddleware"
- end
- assert_equal BazMiddleware, @stack.last.klass
- end
+ test "can check if Middleware are equal - Class" do
+ assert_equal @stack.last, BarMiddleware
+ end
+
+ test "includes a class" do
+ assert_equal true, @stack.include?(BarMiddleware)
+ end
+
+ test "can check if Middleware are equal - Middleware" do
+ assert_equal @stack.last, @stack.last
+ end
+
+ test "includes a middleware" do
+ assert_equal true, @stack.include?(ActionDispatch::MiddlewareStack::Middleware.new(BarMiddleware, nil, nil))
end
end
diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb
index 149e37bf3d..fa264417e1 100644
--- a/actionpack/test/dispatch/mime_type_test.rb
+++ b/actionpack/test/dispatch/mime_type_test.rb
@@ -1,9 +1,11 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class MimeTypeTest < ActiveSupport::TestCase
test "parse single" do
Mime::LOOKUP.each_key do |mime_type|
- unless mime_type == 'image/*'
+ unless mime_type == "image/*"
assert_equal [Mime::Type.lookup(mime_type)], Mime::Type.parse(mime_type)
end
end
@@ -15,7 +17,7 @@ class MimeTypeTest < ActiveSupport::TestCase
begin
mime = Mime::Type.register("text/x-mobile", :mobile)
assert_equal mime, Mime[:mobile]
- assert_equal mime, Mime::Type.lookup('text/x-mobile')
+ assert_equal mime, Mime::Type.lookup("text/x-mobile")
assert_equal mime, Mime::Type.lookup_by_extension(:mobile)
Mime::Type.unregister(:mobile)
@@ -28,41 +30,41 @@ class MimeTypeTest < ActiveSupport::TestCase
test "parse text with trailing star at the beginning" do
accept = "text/*, text/html, application/json, multipart/form-data"
- expect = [Mime[:html], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:xml], Mime[:yaml], Mime[:json], Mime[:multipart_form]]
+ expect = [Mime[:html], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:vtt], Mime[:xml], Mime[:yaml], Mime[:json], Mime[:multipart_form]]
parsed = Mime::Type.parse(accept)
- assert_equal expect, parsed
+ assert_equal expect.map(&:to_s), parsed.map(&:to_s)
end
test "parse text with trailing star in the end" do
accept = "text/html, application/json, multipart/form-data, text/*"
- expect = [Mime[:html], Mime[:json], Mime[:multipart_form], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:xml], Mime[:yaml]]
+ expect = [Mime[:html], Mime[:json], Mime[:multipart_form], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:vtt], Mime[:xml], Mime[:yaml]]
parsed = Mime::Type.parse(accept)
- assert_equal expect, parsed
+ assert_equal expect.map(&:to_s), parsed.map(&:to_s)
end
test "parse text with trailing star" do
accept = "text/*"
- expect = [Mime[:html], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:xml], Mime[:yaml], Mime[:json]]
+ expect = [Mime[:html], Mime[:text], Mime[:js], Mime[:css], Mime[:ics], Mime[:csv], Mime[:vcf], Mime[:vtt], Mime[:xml], Mime[:yaml], Mime[:json]]
parsed = Mime::Type.parse(accept)
- assert_equal expect, parsed
+ assert_equal expect.map(&:to_s).sort!, parsed.map(&:to_s).sort!
end
test "parse application with trailing star" do
accept = "application/*"
- expect = [Mime[:html], Mime[:js], Mime[:xml], Mime[:rss], Mime[:atom], Mime[:yaml], Mime[:url_encoded_form], Mime[:json], Mime[:pdf], Mime[:zip]]
+ expect = [Mime[:html], Mime[:js], Mime[:xml], Mime[:rss], Mime[:atom], Mime[:yaml], Mime[:url_encoded_form], Mime[:json], Mime[:pdf], Mime[:zip], Mime[:gzip]]
parsed = Mime::Type.parse(accept)
- assert_equal expect, parsed
+ assert_equal expect.map(&:to_s).sort!, parsed.map(&:to_s).sort!
end
test "parse without q" do
accept = "text/xml,application/xhtml+xml,text/yaml,application/xml,text/html,image/png,text/plain,application/pdf,*/*"
- expect = [Mime[:html], Mime[:xml], Mime[:yaml], Mime[:png], Mime[:text], Mime[:pdf], '*/*']
+ expect = [Mime[:html], Mime[:xml], Mime[:yaml], Mime[:png], Mime[:text], Mime[:pdf], "*/*"]
assert_equal expect.map(&:to_s), Mime::Type.parse(accept).map(&:to_s)
end
test "parse with q" do
accept = "text/xml,application/xhtml+xml,text/yaml; q=0.3,application/xml,text/html; q=0.8,image/png,text/plain; q=0.5,application/pdf,*/*; q=0.2"
- expect = [Mime[:html], Mime[:xml], Mime[:png], Mime[:pdf], Mime[:text], Mime[:yaml], '*/*']
+ expect = [Mime[:html], Mime[:xml], Mime[:png], Mime[:pdf], Mime[:text], Mime[:yaml], "*/*"]
assert_equal expect.map(&:to_s), Mime::Type.parse(accept).map(&:to_s)
end
@@ -81,7 +83,7 @@ class MimeTypeTest < ActiveSupport::TestCase
# Accept header send with user HTTP_USER_AGENT: Sunrise/0.42j (Windows XP)
test "parse broken acceptlines" do
accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/*,,*/*;q=0.5"
- expect = [Mime[:html], Mime[:xml], "image/*", Mime[:text], '*/*']
+ expect = [Mime[:html], Mime[:xml], "image/*", Mime[:text], "*/*"]
assert_equal expect.map(&:to_s), Mime::Type.parse(accept).map(&:to_s)
end
@@ -89,7 +91,7 @@ class MimeTypeTest < ActiveSupport::TestCase
# (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.1)
test "parse other broken acceptlines" do
accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, , pronto/1.00.00, sslvpn/1.00.00.00, */*"
- expect = ['image/gif', 'image/x-xbitmap', 'image/jpeg','image/pjpeg', 'application/x-shockwave-flash', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/msword', 'pronto/1.00.00', 'sslvpn/1.00.00.00', '*/*']
+ expect = ["image/gif", "image/x-xbitmap", "image/jpeg", "image/pjpeg", "application/x-shockwave-flash", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword", "pronto/1.00.00", "sslvpn/1.00.00.00", "*/*"]
assert_equal expect.map(&:to_s), Mime::Type.parse(accept).map(&:to_s)
end
@@ -141,14 +143,14 @@ class MimeTypeTest < ActiveSupport::TestCase
test "register alias" do
begin
Mime::Type.register_alias "application/xhtml+xml", :foobar
- assert_equal Mime[:html], Mime::EXTENSION_LOOKUP['foobar']
+ assert_equal Mime[:html], Mime::EXTENSION_LOOKUP["foobar"]
ensure
Mime::Type.unregister(:foobar)
end
end
test "type should be equal to symbol" do
- assert_equal Mime[:html], 'application/xhtml+xml'
+ assert_equal Mime[:html], "application/xhtml+xml"
assert_equal Mime[:html], :html
end
@@ -157,7 +159,7 @@ class MimeTypeTest < ActiveSupport::TestCase
types.each do |type|
mime = Mime[type]
- assert mime.respond_to?("#{type}?"), "#{mime.inspect} does not respond to #{type}?"
+ assert_respond_to mime, "#{type}?"
assert_equal type, mime.symbol, "#{mime.inspect} is not #{type}?"
invalid_types = types - [type]
invalid_types.delete(:html)
@@ -167,18 +169,6 @@ class MimeTypeTest < ActiveSupport::TestCase
end
end
- test "deprecated lookup" do
- assert_deprecated do
- Mime::HTML
- end
- end
-
- test "deprecated const_defined?" do
- assert_deprecated do
- Mime.const_defined? :HTML
- end
- end
-
test "references gives preference to symbols before strings" do
assert_equal :html, Mime[:html].ref
another = Mime::Type.lookup("foo/bar")
@@ -190,8 +180,8 @@ class MimeTypeTest < ActiveSupport::TestCase
assert Mime[:js] =~ "text/javascript"
assert Mime[:js] =~ "application/javascript"
assert Mime[:js] !~ "text/html"
- assert !(Mime[:js] !~ "text/javascript")
- assert !(Mime[:js] !~ "application/javascript")
- assert Mime[:html] =~ 'application/xhtml+xml'
+ assert_not (Mime[:js] !~ "text/javascript")
+ assert_not (Mime[:js] !~ "application/javascript")
+ assert Mime[:html] =~ "application/xhtml+xml"
end
end
diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb
index d027f09762..f6cf653980 100644
--- a/actionpack/test/dispatch/mount_test.rb
+++ b/actionpack/test/dispatch/mount_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'rails/engine'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rails/engine"
class TestRoutingMount < ActionDispatch::IntegrationTest
Router = ActionDispatch::Routing::RouteSet.new
@@ -15,30 +17,30 @@ class TestRoutingMount < ActionDispatch::IntegrationTest
def self.routes; Object.new; end
def self.call(env)
- [200, {"Content-Type" => "text/html"}, ["OK"]]
+ [200, { "Content-Type" => "text/html" }, ["OK"]]
end
end
Router.draw do
SprocketsApp = lambda { |env|
- [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]]
+ [200, { "Content-Type" => "text/html" }, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]]
}
- mount SprocketsApp, :at => "/sprockets"
+ mount SprocketsApp, at: "/sprockets"
mount SprocketsApp => "/shorthand"
- mount SinatraLikeApp, :at => "/fakeengine", :as => :fake
- mount SinatraLikeApp, :at => "/getfake", :via => :get
+ mount SinatraLikeApp, at: "/fakeengine", as: :fake
+ mount SinatraLikeApp, at: "/getfake", via: :get
scope "/its_a" do
- mount SprocketsApp, :at => "/sprocket"
+ mount SprocketsApp, at: "/sprocket"
end
resources :users do
- mount AppWithRoutes, :at => "/fakeengine", :as => :fake_mounted_at_resource
+ mount AppWithRoutes, at: "/fakeengine", as: :fake_mounted_at_resource
end
- mount SprocketsApp, :at => "/", :via => :get
+ mount SprocketsApp, at: "/", via: :get
end
APP = RoutedRackApp.new Router
@@ -64,7 +66,7 @@ class TestRoutingMount < ActionDispatch::IntegrationTest
end
def test_mounting_works_with_nested_script_name
- get "/foo/sprockets/omg", headers: { 'SCRIPT_NAME' => '/foo', 'PATH_INFO' => '/sprockets/omg' }
+ get "/foo/sprockets/omg", headers: { "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/sprockets/omg" }
assert_equal "/foo/sprockets -- /omg", response.body
end
diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb
index d75e31db62..7a7a201b11 100644
--- a/actionpack/test/dispatch/prefix_generation_test.rb
+++ b/actionpack/test/dispatch/prefix_generation_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'rack/test'
-require 'rails/engine'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rack/test"
+require "rails/engine"
module TestGenerationPrefix
class Post
@@ -11,7 +13,7 @@ module TestGenerationPrefix
end
def self.model_name
- klass = "Post"
+ klass = +"Post"
def klass.name; self end
ActiveModel::Name.new(klass)
@@ -22,46 +24,44 @@ module TestGenerationPrefix
end
class WithMountedEngine < ActionDispatch::IntegrationTest
- include Rack::Test::Methods
-
class BlogEngine < Rails::Engine
routes.draw do
- get "/posts/:id", :to => "inside_engine_generating#show", :as => :post
- get "/posts", :to => "inside_engine_generating#index", :as => :posts
- get "/url_to_application", :to => "inside_engine_generating#url_to_application"
- get "/polymorphic_path_for_engine", :to => "inside_engine_generating#polymorphic_path_for_engine"
- get "/conflicting_url", :to => "inside_engine_generating#conflicting"
- get "/foo", :to => "never#invoked", :as => :named_helper_that_should_be_invoked_only_in_respond_to_test
-
- get "/relative_path_root", :to => redirect("")
- get "/relative_path_redirect", :to => redirect("foo")
- get "/relative_option_root", :to => redirect(:path => "")
- get "/relative_option_redirect", :to => redirect(:path => "foo")
- get "/relative_custom_root", :to => redirect { |params, request| "" }
- get "/relative_custom_redirect", :to => redirect { |params, request| "foo" }
-
- get "/absolute_path_root", :to => redirect("/")
- get "/absolute_path_redirect", :to => redirect("/foo")
- get "/absolute_option_root", :to => redirect(:path => "/")
- get "/absolute_option_redirect", :to => redirect(:path => "/foo")
- get "/absolute_custom_root", :to => redirect { |params, request| "/" }
- get "/absolute_custom_redirect", :to => redirect { |params, request| "/foo" }
+ get "/posts/:id", to: "inside_engine_generating#show", as: :post
+ get "/posts", to: "inside_engine_generating#index", as: :posts
+ get "/url_to_application", to: "inside_engine_generating#url_to_application"
+ get "/polymorphic_path_for_engine", to: "inside_engine_generating#polymorphic_path_for_engine"
+ get "/conflicting_url", to: "inside_engine_generating#conflicting"
+ get "/foo", to: "never#invoked", as: :named_helper_that_should_be_invoked_only_in_respond_to_test
+
+ get "/relative_path_root", to: redirect("")
+ get "/relative_path_redirect", to: redirect("foo")
+ get "/relative_option_root", to: redirect(path: "")
+ get "/relative_option_redirect", to: redirect(path: "foo")
+ get "/relative_custom_root", to: redirect { |params, request| "" }
+ get "/relative_custom_redirect", to: redirect { |params, request| "foo" }
+
+ get "/absolute_path_root", to: redirect("/")
+ get "/absolute_path_redirect", to: redirect("/foo")
+ get "/absolute_option_root", to: redirect(path: "/")
+ get "/absolute_option_redirect", to: redirect(path: "/foo")
+ get "/absolute_custom_root", to: redirect { |params, request| "/" }
+ get "/absolute_custom_redirect", to: redirect { |params, request| "/foo" }
end
end
class RailsApplication < Rails::Engine
routes.draw do
- scope "/:omg", :omg => "awesome" do
+ scope "/:omg", omg: "awesome" do
mount BlogEngine => "/blog", :as => "blog_engine"
end
- get "/posts/:id", :to => "outside_engine_generating#post", :as => :post
- get "/generate", :to => "outside_engine_generating#index"
- get "/polymorphic_path_for_app", :to => "outside_engine_generating#polymorphic_path_for_app"
- get "/polymorphic_path_for_engine", :to => "outside_engine_generating#polymorphic_path_for_engine"
- get "/polymorphic_with_url_for", :to => "outside_engine_generating#polymorphic_with_url_for"
- get "/conflicting_url", :to => "outside_engine_generating#conflicting"
- get "/ivar_usage", :to => "outside_engine_generating#ivar_usage"
- root :to => "outside_engine_generating#index"
+ get "/posts/:id", to: "outside_engine_generating#post", as: :post
+ get "/generate", to: "outside_engine_generating#index"
+ get "/polymorphic_path_for_app", to: "outside_engine_generating#polymorphic_path_for_app"
+ get "/polymorphic_path_for_engine", to: "outside_engine_generating#polymorphic_path_for_engine"
+ get "/polymorphic_with_url_for", to: "outside_engine_generating#polymorphic_with_url_for"
+ get "/conflicting_url", to: "outside_engine_generating#conflicting"
+ get "/ivar_usage", to: "outside_engine_generating#ivar_usage"
+ root to: "outside_engine_generating#index"
end
end
@@ -81,9 +81,9 @@ module TestGenerationPrefix
end
def url_to_application
- path = main_app.url_for(:controller => "outside_engine_generating",
- :action => "index",
- :only_path => true)
+ path = main_app.url_for(controller: "outside_engine_generating",
+ action: "index",
+ only_path: true)
render plain: path
end
@@ -153,114 +153,114 @@ module TestGenerationPrefix
# Inside Engine
test "[ENGINE] generating engine's url use SCRIPT_NAME from request" do
get "/pure-awesomeness/blog/posts/1"
- assert_equal "/pure-awesomeness/blog/posts/1", last_response.body
+ assert_equal "/pure-awesomeness/blog/posts/1", response.body
end
test "[ENGINE] generating application's url never uses SCRIPT_NAME from request" do
get "/pure-awesomeness/blog/url_to_application"
- assert_equal "/generate", last_response.body
+ assert_equal "/generate", response.body
end
test "[ENGINE] generating engine's url with polymorphic path" do
get "/pure-awesomeness/blog/polymorphic_path_for_engine"
- assert_equal "/pure-awesomeness/blog/posts/1", last_response.body
+ assert_equal "/pure-awesomeness/blog/posts/1", response.body
end
- test "[ENGINE] url_helpers from engine have higher priotity than application's url_helpers" do
+ test "[ENGINE] url_helpers from engine have higher priority than application's url_helpers" do
get "/awesome/blog/conflicting_url"
- assert_equal "engine", last_response.body
+ assert_equal "engine", response.body
end
test "[ENGINE] relative path root uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_path_root"
- verify_redirect "http://example.org/awesome/blog"
+ verify_redirect "http://www.example.com/awesome/blog"
end
test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_path_redirect"
- verify_redirect "http://example.org/awesome/blog/foo"
+ verify_redirect "http://www.example.com/awesome/blog/foo"
end
test "[ENGINE] relative option root uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_option_root"
- verify_redirect "http://example.org/awesome/blog"
+ verify_redirect "http://www.example.com/awesome/blog"
end
test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_option_redirect"
- verify_redirect "http://example.org/awesome/blog/foo"
+ verify_redirect "http://www.example.com/awesome/blog/foo"
end
test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_custom_root"
- verify_redirect "http://example.org/awesome/blog"
+ verify_redirect "http://www.example.com/awesome/blog"
end
test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_custom_redirect"
- verify_redirect "http://example.org/awesome/blog/foo"
+ verify_redirect "http://www.example.com/awesome/blog/foo"
end
test "[ENGINE] absolute path root doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_path_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_path_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_option_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_option_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_custom_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_custom_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
# Inside Application
test "[APP] generating engine's route includes prefix" do
get "/generate"
- assert_equal "/awesome/blog/posts/1", last_response.body
+ assert_equal "/awesome/blog/posts/1", response.body
end
test "[APP] generating engine's route includes default_url_options[:script_name]" do
- RailsApplication.routes.default_url_options = {:script_name => "/something"}
+ RailsApplication.routes.default_url_options = { script_name: "/something" }
get "/generate"
- assert_equal "/something/awesome/blog/posts/1", last_response.body
+ assert_equal "/something/awesome/blog/posts/1", response.body
end
test "[APP] generating engine's url with polymorphic path" do
get "/polymorphic_path_for_engine"
- assert_equal "/awesome/blog/posts/1", last_response.body
+ assert_equal "/awesome/blog/posts/1", response.body
end
test "polymorphic_path_for_app" do
get "/polymorphic_path_for_app"
- assert_equal "/posts/1", last_response.body
+ assert_equal "/posts/1", response.body
end
test "[APP] generating engine's url with url_for(@post)" do
get "/polymorphic_with_url_for"
- assert_equal "http://example.org/awesome/blog/posts/1", last_response.body
+ assert_equal "http://www.example.com/awesome/blog/posts/1", response.body
end
test "[APP] instance variable with same name as engine" do
get "/ivar_usage"
- assert_equal "/awesome/blog/posts/1", last_response.body
+ assert_equal "/awesome/blog/posts/1", response.body
end
# Inside any Object
@@ -269,16 +269,16 @@ module TestGenerationPrefix
end
test "[OBJECT] generating engine's route includes prefix" do
- assert_equal "/awesome/blog/posts/1", engine_object.post_path(:id => 1)
+ assert_equal "/awesome/blog/posts/1", engine_object.post_path(id: 1)
end
test "[OBJECT] generating engine's route includes dynamic prefix" do
- assert_equal "/pure-awesomeness/blog/posts/3", engine_object.post_path(:id => 3, :omg => "pure-awesomeness")
+ assert_equal "/pure-awesomeness/blog/posts/3", engine_object.post_path(id: 3, omg: "pure-awesomeness")
end
test "[OBJECT] generating engine's route includes default_url_options[:script_name]" do
- RailsApplication.routes.default_url_options = {:script_name => "/something"}
- assert_equal "/something/pure-awesomeness/blog/posts/3", engine_object.post_path(:id => 3, :omg => "pure-awesomeness")
+ RailsApplication.routes.default_url_options = { script_name: "/something" }
+ assert_equal "/something/pure-awesomeness/blog/posts/3", engine_object.post_path(id: 3, omg: "pure-awesomeness")
end
test "[OBJECT] generating application's route" do
@@ -286,7 +286,7 @@ module TestGenerationPrefix
end
test "[OBJECT] generating application's route includes default_url_options[:script_name]" do
- RailsApplication.routes.default_url_options = {:script_name => "/something"}
+ RailsApplication.routes.default_url_options = { script_name: "/something" }
assert_equal "/something/", app_object.root_path
end
@@ -296,11 +296,11 @@ module TestGenerationPrefix
end
test "[OBJECT] generating engine's route with url_for" do
- path = engine_object.url_for(:controller => "inside_engine_generating",
- :action => "show",
- :only_path => true,
- :omg => "omg",
- :id => 1)
+ path = engine_object.url_for(controller: "inside_engine_generating",
+ action: "show",
+ only_path: true,
+ omg: "omg",
+ id: 1)
assert_equal "/omg/blog/posts/1", path
end
@@ -308,7 +308,7 @@ module TestGenerationPrefix
path = engine_object.posts_path
assert_equal "/awesome/blog/posts", path
- path = engine_object.posts_url(:host => "example.com")
+ path = engine_object.posts_url(host: "example.com")
assert_equal "http://example.com/awesome/blog/posts", path
end
@@ -316,45 +316,43 @@ module TestGenerationPrefix
path = engine_object.polymorphic_path(Post.new)
assert_equal "/awesome/blog/posts/1", path
- path = engine_object.polymorphic_url(Post.new, :host => "www.example.com")
+ path = engine_object.polymorphic_url(Post.new, host: "www.example.com")
assert_equal "http://www.example.com/awesome/blog/posts/1", path
end
-
+
private
def verify_redirect(url, status = 301)
- assert_equal status, last_response.status
- assert_equal url, last_response.headers["Location"]
- assert_equal expected_redirect_body(url), last_response.body
+ assert_equal status, response.status
+ assert_equal url, response.headers["Location"]
+ assert_equal expected_redirect_body(url), response.body
end
-
+
def expected_redirect_body(url)
%(<html><body>You are being <a href="#{url}">redirected</a>.</body></html>)
end
end
class EngineMountedAtRoot < ActionDispatch::IntegrationTest
- include Rack::Test::Methods
-
class BlogEngine
def self.routes
@routes ||= begin
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
- get "/posts/:id", :to => "posts#show", :as => :post
-
- get "/relative_path_root", :to => redirect("")
- get "/relative_path_redirect", :to => redirect("foo")
- get "/relative_option_root", :to => redirect(:path => "")
- get "/relative_option_redirect", :to => redirect(:path => "foo")
- get "/relative_custom_root", :to => redirect { |params, request| "" }
- get "/relative_custom_redirect", :to => redirect { |params, request| "foo" }
-
- get "/absolute_path_root", :to => redirect("/")
- get "/absolute_path_redirect", :to => redirect("/foo")
- get "/absolute_option_root", :to => redirect(:path => "/")
- get "/absolute_option_redirect", :to => redirect(:path => "/foo")
- get "/absolute_custom_root", :to => redirect { |params, request| "/" }
- get "/absolute_custom_redirect", :to => redirect { |params, request| "/foo" }
+ get "/posts/:id", to: "posts#show", as: :post
+
+ get "/relative_path_root", to: redirect("")
+ get "/relative_path_redirect", to: redirect("foo")
+ get "/relative_option_root", to: redirect(path: "")
+ get "/relative_option_redirect", to: redirect(path: "foo")
+ get "/relative_custom_root", to: redirect { |params, request| "" }
+ get "/relative_custom_redirect", to: redirect { |params, request| "foo" }
+
+ get "/absolute_path_root", to: redirect("/")
+ get "/absolute_path_redirect", to: redirect("/foo")
+ get "/absolute_option_root", to: redirect(path: "/")
+ get "/absolute_option_redirect", to: redirect(path: "/foo")
+ get "/absolute_custom_root", to: redirect { |params, request| "/" }
+ get "/absolute_custom_redirect", to: redirect { |params, request| "/foo" }
end
routes
@@ -362,7 +360,7 @@ module TestGenerationPrefix
end
def self.call(env)
- env['action_dispatch.routes'] = routes
+ env["action_dispatch.routes"] = routes
routes.call(env)
end
end
@@ -388,76 +386,76 @@ module TestGenerationPrefix
test "generating path inside engine" do
get "/posts/1"
- assert_equal "/posts/1", last_response.body
+ assert_equal "/posts/1", response.body
end
test "[ENGINE] relative path root uses SCRIPT_NAME from request" do
get "/relative_path_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do
get "/relative_path_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] relative option root uses SCRIPT_NAME from request" do
get "/relative_option_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do
get "/relative_option_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do
get "/relative_custom_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do
get "/relative_custom_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] absolute path root doesn't use SCRIPT_NAME from request" do
get "/absolute_path_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_path_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do
get "/absolute_option_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_option_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do
get "/absolute_custom_root"
- verify_redirect "http://example.org/"
+ verify_redirect "http://www.example.com/"
end
test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_custom_redirect"
- verify_redirect "http://example.org/foo"
+ verify_redirect "http://www.example.com/foo"
end
-
+
private
def verify_redirect(url, status = 301)
- assert_equal status, last_response.status
- assert_equal url, last_response.headers["Location"]
- assert_equal expected_redirect_body(url), last_response.body
+ assert_equal status, response.status
+ assert_equal url, response.headers["Location"]
+ assert_equal expected_redirect_body(url), response.body
end
-
+
def expected_redirect_body(url)
%(<html><body>You are being <a href="#{url}">redirected</a>.</body></html>)
end
diff --git a/actionpack/test/dispatch/rack_cache_test.rb b/actionpack/test/dispatch/rack_cache_test.rb
index 79d8a64d29..86b375a2a8 100644
--- a/actionpack/test/dispatch/rack_cache_test.rb
+++ b/actionpack/test/dispatch/rack_cache_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_dispatch/http/rack_cache'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/http/rack_cache"
class RackCacheMetaStoreTest < ActiveSupport::TestCase
class ReadWriteHash < ::Hash
@@ -12,7 +14,7 @@ class RackCacheMetaStoreTest < ActiveSupport::TestCase
end
test "stuff is deep duped" do
- @store.write(:foo, { :bar => :original })
+ @store.write(:foo, bar: :original)
hash = @store.read(:foo)
hash[:bar] = :changed
hash = @store.read(:foo)
diff --git a/actionpack/test/dispatch/reloader_test.rb b/actionpack/test/dispatch/reloader_test.rb
index 62e8197e20..edc4cd62a3 100644
--- a/actionpack/test/dispatch/reloader_test.rb
+++ b/actionpack/test/dispatch/reloader_test.rb
@@ -1,28 +1,11 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-class ReloaderTest < ActiveSupport::TestCase
- Reloader = ActionDispatch::Reloader
+require "abstract_unit"
+class ReloaderTest < ActiveSupport::TestCase
teardown do
- Reloader.reset_callbacks :prepare
- Reloader.reset_callbacks :cleanup
- end
-
- def test_prepare_callbacks
- a = b = c = nil
- Reloader.to_prepare { |*args| a = b = c = 1 }
- Reloader.to_prepare { |*args| b = c = 2 }
- Reloader.to_prepare { |*args| c = 3 }
-
- # Ensure to_prepare callbacks are not run when defined
- assert_nil a || b || c
-
- # Run callbacks
- call_and_return_body
-
- assert_equal 1, a
- assert_equal 2, b
- assert_equal 3, c
+ ActiveSupport::Reloader.reset_callbacks :prepare
+ ActiveSupport::Reloader.reset_callbacks :complete
end
class MyBody < Array
@@ -43,6 +26,23 @@ class ReloaderTest < ActiveSupport::TestCase
end
end
+ def test_prepare_callbacks
+ a = b = c = nil
+ reloader.to_prepare { |*args| a = b = c = 1 }
+ reloader.to_prepare { |*args| b = c = 2 }
+ reloader.to_prepare { |*args| c = 3 }
+
+ # Ensure to_prepare callbacks are not run when defined
+ assert_nil a || b || c
+
+ # Run callbacks
+ call_and_return_body
+
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
def test_returned_body_object_always_responds_to_close
body = call_and_return_body
assert_respond_to body, :close
@@ -60,9 +60,12 @@ class ReloaderTest < ActiveSupport::TestCase
def test_condition_specifies_when_to_reload
i, j = 0, 0, 0, 0
- Reloader.to_prepare { |*args| i += 1 }
- Reloader.to_cleanup { |*args| j += 1 }
- app = Reloader.new(lambda { |env| [200, {}, []] }, lambda { i < 3 })
+
+ reloader = reloader(lambda { i < 3 })
+ reloader.to_prepare { |*args| i += 1 }
+ reloader.to_complete { |*args| j += 1 }
+
+ app = middleware(lambda { |env| [200, {}, []] }, reloader)
5.times do
resp = app.call({})
resp[2].close
@@ -107,55 +110,31 @@ class ReloaderTest < ActiveSupport::TestCase
assert_respond_to body, :bar
end
- def test_cleanup_callbacks_are_called_when_body_is_closed
- cleaned = false
- Reloader.to_cleanup { cleaned = true }
+ def test_complete_callbacks_are_called_when_body_is_closed
+ completed = false
+ reloader.to_complete { completed = true }
body = call_and_return_body
- assert !cleaned
+ assert_not completed
body.close
- assert cleaned
+ assert completed
end
def test_prepare_callbacks_arent_called_when_body_is_closed
prepared = false
- Reloader.to_prepare { prepared = true }
+ reloader.to_prepare { prepared = true }
body = call_and_return_body
prepared = false
body.close
- assert !prepared
+ assert_not prepared
end
- def test_manual_reloading
- prepared = cleaned = false
- Reloader.to_prepare { prepared = true }
- Reloader.to_cleanup { cleaned = true }
-
- Reloader.prepare!
- assert prepared
- assert !cleaned
-
- prepared = cleaned = false
- Reloader.cleanup!
- assert !prepared
- assert cleaned
- end
-
- def test_prepend_prepare_callback
- i = 10
- Reloader.to_prepare { i += 1 }
- Reloader.to_prepare(:prepend => true) { i = 0 }
-
- Reloader.prepare!
- assert_equal 1, i
- end
-
- def test_cleanup_callbacks_are_called_on_exceptions
- cleaned = false
- Reloader.to_cleanup { cleaned = true }
+ def test_complete_callbacks_are_called_on_exceptions
+ completed = false
+ reloader.to_complete { completed = true }
begin
call_and_return_body do
@@ -164,13 +143,25 @@ class ReloaderTest < ActiveSupport::TestCase
rescue
end
- assert cleaned
+ assert completed
end
private
def call_and_return_body(&block)
- @response ||= 'response'
- @reloader ||= Reloader.new(block || proc {[200, {}, @response]})
- @reloader.call({'rack.input' => StringIO.new('')})[2]
+ app = middleware(block || proc { [200, {}, "response"] })
+ _, _, body = app.call("rack.input" => StringIO.new(""))
+ body
+ end
+
+ def middleware(inner_app, reloader = reloader())
+ ActionDispatch::Reloader.new(inner_app, reloader)
+ end
+
+ def reloader(check = lambda { true })
+ @reloader ||= begin
+ reloader = Class.new(ActiveSupport::Reloader)
+ reloader.check = check
+ reloader
+ end
end
end
diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb
index a3992ad008..beab8e78b5 100644
--- a/actionpack/test/dispatch/request/json_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class JsonParamsParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -18,44 +20,44 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
test "parses json params for application json" do
assert_parses(
- {"person" => {"name" => "David"}},
- "{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/json' }
+ { "person" => { "name" => "David" } },
+ "{\"person\": {\"name\": \"David\"}}", "CONTENT_TYPE" => "application/json"
)
end
test "parses boolean and number json params for application json" do
assert_parses(
- {"item" => {"enabled" => false, "count" => 10}},
- "{\"item\": {\"enabled\": false, \"count\": 10}}", { 'CONTENT_TYPE' => 'application/json' }
+ { "item" => { "enabled" => false, "count" => 10 } },
+ "{\"item\": {\"enabled\": false, \"count\": 10}}", "CONTENT_TYPE" => "application/json"
)
end
test "parses json params for application jsonrequest" do
assert_parses(
- {"person" => {"name" => "David"}},
- "{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/jsonrequest' }
+ { "person" => { "name" => "David" } },
+ "{\"person\": {\"name\": \"David\"}}", "CONTENT_TYPE" => "application/jsonrequest"
)
end
- test "parses json params for application/vnd.api+json" do
+ test "does not parse unregistered media types such as application/vnd.api+json" do
assert_parses(
- {"person" => {"name" => "David"}},
- "{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/vnd.api+json' }
+ {},
+ "{\"person\": {\"name\": \"David\"}}", "CONTENT_TYPE" => "application/vnd.api+json"
)
end
test "nils are stripped from collections" do
assert_parses(
- {"person" => []},
- "{\"person\":[null]}", { 'CONTENT_TYPE' => 'application/json' }
+ { "person" => [] },
+ "{\"person\":[null]}", "CONTENT_TYPE" => "application/json"
)
assert_parses(
- {"person" => ['foo']},
- "{\"person\":[\"foo\",null]}", { 'CONTENT_TYPE' => 'application/json' }
+ { "person" => ["foo"] },
+ "{\"person\":[\"foo\",null]}", "CONTENT_TYPE" => "application/json"
)
assert_parses(
- {"person" => []},
- "{\"person\":[null, null]}", { 'CONTENT_TYPE' => 'application/json' }
+ { "person" => [] },
+ "{\"person\":[null, null]}", "CONTENT_TYPE" => "application/json"
)
end
@@ -63,7 +65,7 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
with_test_routing do
output = StringIO.new
json = "[\"person]\": {\"name\": \"David\"}}"
- post "/parse", params: json, headers: { 'CONTENT_TYPE' => 'application/json', 'action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => ActiveSupport::Logger.new(output) }
+ post "/parse", params: json, headers: { "CONTENT_TYPE" => "application/json", "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => ActiveSupport::Logger.new(output) }
assert_response :bad_request
output.rewind && err = output.read
assert err =~ /Error occurred while parsing request parameters/
@@ -75,7 +77,9 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
begin
$stderr = StringIO.new # suppress the log
json = "[\"person]\": {\"name\": \"David\"}}"
- exception = assert_raise(ActionDispatch::ParamsParser::ParseError) { post "/parse", json, {'CONTENT_TYPE' => 'application/json', 'action_dispatch.show_exceptions' => false} }
+ exception = assert_raise(ActionDispatch::Http::Parameters::ParseError) do
+ post "/parse", params: json, headers: { "CONTENT_TYPE" => "application/json", "action_dispatch.show_exceptions" => false }
+ end
assert_equal JSON::ParserError, exception.cause.class
assert_equal exception.cause.message, exception.message
ensure
@@ -84,9 +88,9 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
end
end
- test 'raw_post is not empty for JSON request' do
+ test "raw_post is not empty for JSON request" do
with_test_routing do
- post '/parse', params: '{"posts": [{"title": "Post Title"}]}', headers: { 'CONTENT_TYPE' => 'application/json' }
+ post "/parse", params: '{"posts": [{"title": "Post Title"}]}', headers: { "CONTENT_TYPE" => "application/json" }
assert_equal '{"posts": [{"title": "Post Title"}]}', request.raw_post
end
end
@@ -103,7 +107,9 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
def with_test_routing
with_routing do |set|
set.draw do
- post ':action', :to => ::JsonParamsParsingTest::TestController
+ ActiveSupport::Deprecation.silence do
+ post ":action", to: ::JsonParamsParsingTest::TestController
+ end
end
yield
end
@@ -112,7 +118,7 @@ end
class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
class UsersController < ActionController::Base
- wrap_parameters :format => :json
+ wrap_parameters format: :json
class << self
attr_accessor :last_request_parameters, :last_parameters
@@ -131,30 +137,51 @@ class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
test "parses json params for application json" do
assert_parses(
- {"user" => {"username" => "sikachu"}, "username" => "sikachu"},
- "{\"username\": \"sikachu\"}", { 'CONTENT_TYPE' => 'application/json' }
+ { "user" => { "username" => "sikachu" }, "username" => "sikachu" },
+ "{\"username\": \"sikachu\"}", "CONTENT_TYPE" => "application/json"
)
end
test "parses json params for application jsonrequest" do
assert_parses(
- {"user" => {"username" => "sikachu"}, "username" => "sikachu"},
- "{\"username\": \"sikachu\"}", { 'CONTENT_TYPE' => 'application/jsonrequest' }
+ { "user" => { "username" => "sikachu" }, "username" => "sikachu" },
+ "{\"username\": \"sikachu\"}", "CONTENT_TYPE" => "application/jsonrequest"
)
end
- test "parses json params for application/vnd.api+json" do
+ test "parses json with non-object JSON content" do
assert_parses(
- {"user" => {"username" => "sikachu"}, "username" => "sikachu"},
- "{\"username\": \"sikachu\"}", { 'CONTENT_TYPE' => 'application/vnd.api+json' }
+ { "user" => { "_json" => "string content" }, "_json" => "string content" },
+ "\"string content\"", "CONTENT_TYPE" => "application/json"
)
end
- test "parses json with non-object JSON content" do
- assert_parses(
- {"user" => {"_json" => "string content" }, "_json" => "string content" },
- "\"string content\"", { 'CONTENT_TYPE' => 'application/json' }
- )
+ test "parses json params after custom json mime type registered" do
+ begin
+ Mime::Type.unregister :json
+ Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
+ assert_parses(
+ { "user" => { "username" => "meinac" }, "username" => "meinac" },
+ "{\"username\": \"meinac\"}", "CONTENT_TYPE" => "application/json"
+ )
+ ensure
+ Mime::Type.unregister :json
+ Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
+ end
+ end
+
+ test "parses json params after custom json mime type registered with synonym" do
+ begin
+ Mime::Type.unregister :json
+ Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
+ assert_parses(
+ { "user" => { "username" => "meinac" }, "username" => "meinac" },
+ "{\"username\": \"meinac\"}", "CONTENT_TYPE" => "application/vnd.rails+json"
+ )
+ ensure
+ Mime::Type.unregister :json
+ Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
+ end
end
private
@@ -163,14 +190,16 @@ class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
post "/parse", params: actual, headers: headers
assert_response :ok
assert_equal(expected, UsersController.last_request_parameters)
- assert_equal(expected.merge({"action" => "parse"}), UsersController.last_parameters)
+ assert_equal(expected.merge("action" => "parse"), UsersController.last_parameters)
end
end
def with_test_routing(controller)
with_routing do |set|
set.draw do
- post ':action', :to => controller
+ ActiveSupport::Deprecation.silence do
+ post ":action", to: controller
+ end
end
yield
end
diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
index b36fbd3c76..da8233c074 100644
--- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -21,136 +23,136 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
end
end
- FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/multipart'
+ FIXTURE_PATH = File.expand_path("../../fixtures/multipart", __dir__)
def teardown
TestController.last_request_parameters = nil
end
test "parses single parameter" do
- assert_equal({ 'foo' => 'bar' }, parse_multipart('single_parameter'))
+ assert_equal({ "foo" => "bar" }, parse_multipart("single_parameter"))
end
test "parses bracketed parameters" do
- assert_equal({ 'foo' => { 'baz' => 'bar'}}, parse_multipart('bracketed_param'))
+ assert_equal({ "foo" => { "baz" => "bar" } }, parse_multipart("bracketed_param"))
end
test "parse single utf8 parameter" do
- assert_equal({ 'Iñtërnâtiônàlizætiøn_name' => 'Iñtërnâtiônàlizætiøn_value'},
- parse_multipart('single_utf8_param'), "request.request_parameters")
+ assert_equal({ "Iñtërnâtiônàlizætiøn_name" => "Iñtërnâtiônàlizætiøn_value" },
+ parse_multipart("single_utf8_param"), "request.request_parameters")
assert_equal(
- 'Iñtërnâtiônàlizætiøn_value',
- TestController.last_parameters['Iñtërnâtiônàlizætiøn_name'], "request.parameters")
+ "Iñtërnâtiônàlizætiøn_value",
+ TestController.last_parameters["Iñtërnâtiônàlizætiøn_name"], "request.parameters")
end
test "parse bracketed utf8 parameter" do
- assert_equal({ 'Iñtërnâtiônàlizætiøn_name' => {
- 'Iñtërnâtiônàlizætiøn_nested_name' => 'Iñtërnâtiônàlizætiøn_value'} },
- parse_multipart('bracketed_utf8_param'), "request.request_parameters")
+ assert_equal({ "Iñtërnâtiônàlizætiøn_name" => {
+ "Iñtërnâtiônàlizætiøn_nested_name" => "Iñtërnâtiônàlizætiøn_value" } },
+ parse_multipart("bracketed_utf8_param"), "request.request_parameters")
assert_equal(
- {'Iñtërnâtiônàlizætiøn_nested_name' => 'Iñtërnâtiônàlizætiøn_value'},
- TestController.last_parameters['Iñtërnâtiônàlizætiøn_name'], "request.parameters")
+ { "Iñtërnâtiônàlizætiøn_nested_name" => "Iñtërnâtiônàlizætiøn_value" },
+ TestController.last_parameters["Iñtërnâtiônàlizætiøn_name"], "request.parameters")
end
test "parses text file" do
- params = parse_multipart('text_file')
+ params = parse_multipart("text_file")
assert_equal %w(file foo), params.keys.sort
- assert_equal 'bar', params['foo']
+ assert_equal "bar", params["foo"]
- file = params['file']
- assert_equal 'file.txt', file.original_filename
+ file = params["file"]
+ assert_equal "file.txt", file.original_filename
assert_equal "text/plain", file.content_type
- assert_equal 'contents', file.read
+ assert_equal "contents", file.read
end
test "parses utf8 filename with percent character" do
- params = parse_multipart('utf8_filename')
+ params = parse_multipart("utf8_filename")
assert_equal %w(file foo), params.keys.sort
- assert_equal 'bar', params['foo']
+ assert_equal "bar", params["foo"]
- file = params['file']
- assert_equal 'ファイル%名.txt', file.original_filename
+ file = params["file"]
+ assert_equal "ファイル%名.txt", file.original_filename
assert_equal "text/plain", file.content_type
- assert_equal 'contents', file.read
+ assert_equal "contents", file.read
end
test "parses boundary problem file" do
- params = parse_multipart('boundary_problem_file')
+ params = parse_multipart("boundary_problem_file")
assert_equal %w(file foo), params.keys.sort
- file = params['file']
- foo = params['foo']
+ file = params["file"]
+ foo = params["foo"]
- assert_equal 'file.txt', file.original_filename
+ assert_equal "file.txt", file.original_filename
assert_equal "text/plain", file.content_type
- assert_equal 'bar', foo
+ assert_equal "bar", foo
end
test "parses large text file" do
- params = parse_multipart('large_text_file')
+ params = parse_multipart("large_text_file")
assert_equal %w(file foo), params.keys.sort
- assert_equal 'bar', params['foo']
+ assert_equal "bar", params["foo"]
- file = params['file']
+ file = params["file"]
- assert_equal 'file.txt', file.original_filename
+ assert_equal "file.txt", file.original_filename
assert_equal "text/plain", file.content_type
- assert_equal(('a' * 20480), file.read)
+ assert_equal(("a" * 20480), file.read)
end
test "parses binary file" do
- params = parse_multipart('binary_file')
+ params = parse_multipart("binary_file")
assert_equal %w(file flowers foo), params.keys.sort
- assert_equal 'bar', params['foo']
+ assert_equal "bar", params["foo"]
- file = params['file']
- assert_equal 'file.csv', file.original_filename
+ file = params["file"]
+ assert_equal "file.csv", file.original_filename
assert_nil file.content_type
- assert_equal 'contents', file.read
+ assert_equal "contents", file.read
- file = params['flowers']
- assert_equal 'flowers.jpg', file.original_filename
+ file = params["flowers"]
+ assert_equal "flowers.jpg", file.original_filename
assert_equal "image/jpeg", file.content_type
assert_equal 19512, file.size
end
test "parses mixed files" do
- params = parse_multipart('mixed_files')
+ params = parse_multipart("mixed_files")
assert_equal %w(files foo), params.keys.sort
- assert_equal 'bar', params['foo']
+ assert_equal "bar", params["foo"]
# Rack doesn't handle multipart/mixed for us.
- files = params['files']
+ files = params["files"]
assert_equal 19756, files.bytesize
end
test "does not create tempfile if no file has been selected" do
- params = parse_multipart('none')
+ params = parse_multipart("none")
assert_equal %w(submit-name), params.keys.sort
- assert_equal 'Larry', params['submit-name']
- assert_equal nil, params['files']
+ assert_equal "Larry", params["submit-name"]
+ assert_nil params["files"]
end
test "parses empty upload file" do
- params = parse_multipart('empty')
+ params = parse_multipart("empty")
assert_equal %w(files submit-name), params.keys.sort
- assert_equal 'Larry', params['submit-name']
- assert params['files']
- assert_equal "", params['files'].read
+ assert_equal "Larry", params["submit-name"]
+ assert params["files"]
+ assert_equal "", params["files"].read
end
test "uploads and reads binary file" do
with_test_routing do
- fixture = FIXTURE_PATH + "/mona_lisa.jpg"
- params = { :uploaded_data => fixture_file_upload(fixture, "image/jpg") }
- post '/read', params: params
+ fixture = FIXTURE_PATH + "/ruby_on_rails.jpg"
+ params = { uploaded_data: fixture_file_upload(fixture, "image/jpg") }
+ post "/read", params: params
end
end
test "uploads and reads file" do
with_test_routing do
- post '/read', params: { uploaded_data: fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain") }
+ post "/read", params: { uploaded_data: fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain") }
assert_equal "File: Hello", response.body
end
end
@@ -159,7 +161,9 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
test "does not raise EOFError on GET request with multipart content-type" do
with_routing do |set|
set.draw do
- get ':action', controller: 'multipart_params_parsing_test/test'
+ ActiveSupport::Deprecation.silence do
+ get ":action", controller: "multipart_params_parsing_test/test"
+ end
end
headers = { "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x" }
get "/parse", headers: headers
@@ -169,7 +173,7 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
private
def fixture(name)
- File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
+ File.open(File.join(FIXTURE_PATH, name), "rb") do |file|
{ "rack.input" => file.read,
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
"CONTENT_LENGTH" => file.stat.size.to_s }
@@ -188,7 +192,9 @@ class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
def with_test_routing
with_routing do |set|
set.draw do
- post ':action', :controller => 'multipart_params_parsing_test/test'
+ ActiveSupport::Deprecation.silence do
+ post ":action", controller: "multipart_params_parsing_test/test"
+ end
end
yield
end
diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb
index bc6716525e..f9ae5ef4e8 100644
--- a/actionpack/test/dispatch/request/query_string_parsing_test.rb
+++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class QueryStringParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -29,92 +31,92 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest
test "query string" do
assert_parses(
- {"action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1" },
"action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
)
end
test "deep query string" do
assert_parses(
- {'x' => {'y' => {'z' => '10'}}},
+ { "x" => { "y" => { "z" => "10" } } },
"x[y][z]=10"
)
end
test "deep query string with array" do
- assert_parses({'x' => {'y' => {'z' => ['10']}}}, 'x[y][z][]=10')
- assert_parses({'x' => {'y' => {'z' => ['10', '5']}}}, 'x[y][z][]=10&x[y][z][]=5')
+ assert_parses({ "x" => { "y" => { "z" => ["10"] } } }, "x[y][z][]=10")
+ assert_parses({ "x" => { "y" => { "z" => ["10", "5"] } } }, "x[y][z][]=10&x[y][z][]=5")
end
test "deep query string with array of hash" do
- assert_parses({'x' => {'y' => [{'z' => '10'}]}}, 'x[y][][z]=10')
- assert_parses({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, 'x[y][][z]=10&x[y][][w]=10')
- assert_parses({'x' => {'y' => [{'z' => '10', 'v' => {'w' => '10'}}]}}, 'x[y][][z]=10&x[y][][v][w]=10')
+ assert_parses({ "x" => { "y" => [{ "z" => "10" }] } }, "x[y][][z]=10")
+ assert_parses({ "x" => { "y" => [{ "z" => "10", "w" => "10" }] } }, "x[y][][z]=10&x[y][][w]=10")
+ assert_parses({ "x" => { "y" => [{ "z" => "10", "v" => { "w" => "10" } }] } }, "x[y][][z]=10&x[y][][v][w]=10")
end
test "deep query string with array of hashes with one pair" do
- assert_parses({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, 'x[y][][z]=10&x[y][][z]=20')
+ assert_parses({ "x" => { "y" => [{ "z" => "10" }, { "z" => "20" }] } }, "x[y][][z]=10&x[y][][z]=20")
end
test "deep query string with array of hashes with multiple pairs" do
assert_parses(
- {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
- 'x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b'
+ { "x" => { "y" => [{ "z" => "10", "w" => "a" }, { "z" => "20", "w" => "b" }] } },
+ "x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b"
)
end
test "query string with nil" do
assert_parses(
- { "action" => "create_customer", "full_name" => ''},
+ { "action" => "create_customer", "full_name" => "" },
"action=create_customer&full_name="
)
end
test "query string with array" do
assert_parses(
- { "action" => "create_customer", "selected" => ["1", "2", "3"]},
+ { "action" => "create_customer", "selected" => ["1", "2", "3"] },
"action=create_customer&selected[]=1&selected[]=2&selected[]=3"
)
end
test "query string with amps" do
assert_parses(
- { "action" => "create_customer", "name" => "Don't & Does"},
+ { "action" => "create_customer", "name" => "Don't & Does" },
"action=create_customer&name=Don%27t+%26+Does"
)
end
test "query string with many equal" do
assert_parses(
- { "action" => "create_customer", "full_name" => "abc=def=ghi"},
+ { "action" => "create_customer", "full_name" => "abc=def=ghi" },
"action=create_customer&full_name=abc=def=ghi"
)
end
test "query string without equal" do
- assert_parses({"action" => nil}, "action")
- assert_parses({"action" => {"foo" => nil}}, "action[foo]")
- assert_parses({"action" => {"foo" => { "bar" => nil }}}, "action[foo][bar]")
- assert_parses({"action" => {"foo" => { "bar" => [] }}}, "action[foo][bar][]")
- assert_parses({"action" => {"foo" => [] }}, "action[foo][]")
- assert_parses({"action"=>{"foo"=>[{"bar"=>nil}]}}, "action[foo][][bar]")
+ assert_parses({ "action" => nil }, "action")
+ assert_parses({ "action" => { "foo" => nil } }, "action[foo]")
+ assert_parses({ "action" => { "foo" => { "bar" => nil } } }, "action[foo][bar]")
+ assert_parses({ "action" => { "foo" => { "bar" => [] } } }, "action[foo][bar][]")
+ assert_parses({ "action" => { "foo" => [] } }, "action[foo][]")
+ assert_parses({ "action" => { "foo" => [{ "bar" => nil }] } }, "action[foo][][bar]")
end
def test_array_parses_without_nil
- assert_parses({"action" => ['1']}, "action[]=1&action[]")
+ assert_parses({ "action" => ["1"] }, "action[]=1&action[]")
end
test "perform_deep_munge" do
old_perform_deep_munge = ActionDispatch::Request::Utils.perform_deep_munge
ActionDispatch::Request::Utils.perform_deep_munge = false
begin
- assert_parses({"action" => nil}, "action")
- assert_parses({"action" => {"foo" => nil}}, "action[foo]")
- assert_parses({"action" => {"foo" => {"bar" => nil}}}, "action[foo][bar]")
- assert_parses({"action" => {"foo" => {"bar" => [nil]}}}, "action[foo][bar][]")
- assert_parses({"action" => {"foo" => [nil]}}, "action[foo][]")
- assert_parses({"action" => {"foo" => [{"bar" => nil}]}}, "action[foo][][bar]")
- assert_parses({"action" => ['1',nil]}, "action[]=1&action[]")
+ assert_parses({ "action" => nil }, "action")
+ assert_parses({ "action" => { "foo" => nil } }, "action[foo]")
+ assert_parses({ "action" => { "foo" => { "bar" => nil } } }, "action[foo][bar]")
+ assert_parses({ "action" => { "foo" => { "bar" => [nil] } } }, "action[foo][bar][]")
+ assert_parses({ "action" => { "foo" => [nil] } }, "action[foo][]")
+ assert_parses({ "action" => { "foo" => [{ "bar" => nil }] } }, "action[foo][][bar]")
+ assert_parses({ "action" => ["1", nil] }, "action[]=1&action[]")
ensure
ActionDispatch::Request::Utils.perform_deep_munge = old_perform_deep_munge
end
@@ -129,14 +131,14 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest
test "query string with many ampersands" do
assert_parses(
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
)
end
test "unbalanced query string with array" do
assert_parses(
- {'location' => ["1", "2"], 'age_group' => ["2"]},
+ { "location" => ["1", "2"], "age_group" => ["2"] },
"location[]=1&location[]=2&age_group[]=2"
)
end
@@ -144,7 +146,9 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest
test "ambiguous query string returns a bad request" do
with_routing do |set|
set.draw do
- get ':action', :to => ::QueryStringParsingTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::QueryStringParsingTest::TestController
+ end
end
get "/parse", headers: { "QUERY_STRING" => "foo[]=bar&foo[4]=bar" }
@@ -156,7 +160,9 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest
def assert_parses(expected, actual)
with_routing do |set|
set.draw do
- get ':action', :to => ::QueryStringParsingTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::QueryStringParsingTest::TestController
+ end
end
@app = self.class.build_app(set) do |middleware|
middleware.use(EarlyParse)
diff --git a/actionpack/test/dispatch/request/session_test.rb b/actionpack/test/dispatch/request/session_test.rb
index 7dcbcc5c21..74da2fe7d3 100644
--- a/actionpack/test/dispatch/request/session_test.rb
+++ b/actionpack/test/dispatch/request/session_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_dispatch/middleware/session/abstract_store'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/middleware/session/abstract_store"
module ActionDispatch
class Request
@@ -17,18 +19,19 @@ module ActionDispatch
def test_to_hash
s = Session.create(store, req, {})
- s['foo'] = 'bar'
- assert_equal 'bar', s['foo']
- assert_equal({'foo' => 'bar'}, s.to_hash)
+ s["foo"] = "bar"
+ assert_equal "bar", s["foo"]
+ assert_equal({ "foo" => "bar" }, s.to_hash)
+ assert_equal({ "foo" => "bar" }, s.to_h)
end
def test_create_merges_old
s = Session.create(store, req, {})
- s['foo'] = 'bar'
+ s["foo"] = "bar"
s1 = Session.create(store, req, {})
assert_not_equal s, s1
- assert_equal 'bar', s1['foo']
+ assert_equal "bar", s1["foo"]
end
def test_find
@@ -40,7 +43,7 @@ module ActionDispatch
def test_destroy
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
+ s["rails"] = "ftw"
s.destroy
@@ -49,22 +52,32 @@ module ActionDispatch
def test_keys
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
- s['adequate'] = 'awesome'
+ s["rails"] = "ftw"
+ s["adequate"] = "awesome"
assert_equal %w[rails adequate], s.keys
end
+ def test_keys_with_deferred_loading
+ s = Session.create(store_with_data, req, {})
+ assert_equal %w[sample_key], s.keys
+ end
+
def test_values
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
- s['adequate'] = 'awesome'
+ s["rails"] = "ftw"
+ s["adequate"] = "awesome"
assert_equal %w[ftw awesome], s.values
end
+ def test_values_with_deferred_loading
+ s = Session.create(store_with_data, req, {})
+ assert_equal %w[sample_value], s.values
+ end
+
def test_clear
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
- s['adequate'] = 'awesome'
+ s["rails"] = "ftw"
+ s["adequate"] = "awesome"
s.clear
assert_empty(s.values)
@@ -72,19 +85,19 @@ module ActionDispatch
def test_update
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
+ s["rails"] = "ftw"
- s.update(:rails => 'awesome')
+ s.update(rails: "awesome")
- assert_equal(['rails'], s.keys)
- assert_equal('awesome', s['rails'])
+ assert_equal(["rails"], s.keys)
+ assert_equal("awesome", s["rails"])
end
def test_delete
s = Session.create(store, req, {})
- s['rails'] = 'ftw'
+ s["rails"] = "ftw"
- s.delete('rails')
+ s.delete("rails")
assert_empty(s.keys)
end
@@ -92,26 +105,72 @@ module ActionDispatch
def test_fetch
session = Session.create(store, req, {})
- session['one'] = '1'
- assert_equal '1', session.fetch(:one)
+ session["one"] = "1"
+ assert_equal "1", session.fetch(:one)
- assert_equal '2', session.fetch(:two, '2')
+ assert_equal "2", session.fetch(:two, "2")
assert_nil session.fetch(:two, nil)
- assert_equal 'three', session.fetch(:three) {|el| el.to_s }
+ assert_equal "three", session.fetch(:three) { |el| el.to_s }
assert_raise KeyError do
session.fetch(:three)
end
end
+ def test_dig
+ session = Session.create(store, req, {})
+ session["one"] = { "two" => "3" }
+
+ assert_equal "3", session.dig("one", "two")
+ assert_equal "3", session.dig(:one, "two")
+
+ assert_nil session.dig("three", "two")
+ assert_nil session.dig("one", "three")
+ assert_nil session.dig("one", :two)
+ end
+
private
- def store
- Class.new {
- def load_session(env); [1, {}]; end
- def session_exists?(env); true; end
- def delete_session(env, id, options); 123; end
- }.new
+ def store
+ Class.new {
+ def load_session(env); [1, {}]; end
+ def session_exists?(env); true; end
+ def delete_session(env, id, options); 123; end
+ }.new
+ end
+
+ def store_with_data
+ Class.new {
+ def load_session(env); [1, { "sample_key" => "sample_value" }]; end
+ def session_exists?(env); true; end
+ def delete_session(env, id, options); 123; end
+ }.new
+ end
+ end
+
+ class SessionIntegrationTest < ActionDispatch::IntegrationTest
+ class MySessionApp
+ def call(env)
+ request = Rack::Request.new(env)
+ request.session["hello"] = "Hello from MySessionApp!"
+ [ 200, {}, ["Hello from MySessionApp!"] ]
+ end
+ end
+
+ Router = ActionDispatch::Routing::RouteSet.new
+ Router.draw do
+ get "/mysessionapp" => MySessionApp.new
+ end
+
+ def app
+ @app ||= RoutedRackApp.new(Router)
+ end
+
+ def test_session_follows_rack_api_contract_1
+ get "/mysessionapp"
+ assert_response :ok
+ assert_equal "Hello from MySessionApp!", @response.body
+ assert_equal "Hello from MySessionApp!", session["hello"]
end
end
end
diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
index 365edf849a..9e55a7242e 100644
--- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -18,7 +20,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
test "parses unbalanced query string with array" do
query = "location[]=1&location[]=2&age_group[]=2"
- expected = { 'location' => ["1", "2"], 'age_group' => ["2"] }
+ expected = { "location" => ["1", "2"], "age_group" => ["2"] }
assert_parses expected, query
end
@@ -55,7 +57,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
"products[second]=Pc",
"=Save"
].join("&")
- expected = {
+ expected = {
"customers" => {
"boston" => {
"first" => {
@@ -107,7 +109,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
query = [
"customers[boston][first][name]=David",
"something_else=blah",
- "logo=#{File.expand_path(__FILE__)}"
+ "logo=#{__FILE__}"
].join("&")
expected = {
"customers" => {
@@ -118,7 +120,7 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
}
},
"something_else" => "blah",
- "logo" => File.expand_path(__FILE__),
+ "logo" => __FILE__,
}
assert_parses expected, query
end
@@ -140,7 +142,9 @@ class UrlEncodedParamsParsingTest < ActionDispatch::IntegrationTest
def with_test_routing
with_routing do |set|
set.draw do
- post ':action', to: ::UrlEncodedParamsParsingTest::TestController
+ ActiveSupport::Deprecation.silence do
+ post ":action", to: ::UrlEncodedParamsParsingTest::TestController
+ end
end
yield
end
diff --git a/actionpack/test/dispatch/request_id_test.rb b/actionpack/test/dispatch/request_id_test.rb
index 00d8caf8f4..9df4712dab 100644
--- a/actionpack/test/dispatch/request_id_test.rb
+++ b/actionpack/test/dispatch/request_id_test.rb
@@ -1,16 +1,23 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class RequestIdTest < ActiveSupport::TestCase
test "passing on the request id from the outside" do
- assert_equal "external-uu-rid", stub_request('HTTP_X_REQUEST_ID' => 'external-uu-rid').request_id
+ assert_equal "external-uu-rid", stub_request("HTTP_X_REQUEST_ID" => "external-uu-rid").request_id
end
test "ensure that only alphanumeric uurids are accepted" do
- assert_equal "X-Hacked-HeaderStuff", stub_request('HTTP_X_REQUEST_ID' => '; X-Hacked-Header: Stuff').request_id
+ assert_equal "X-Hacked-HeaderStuff", stub_request("HTTP_X_REQUEST_ID" => "; X-Hacked-Header: Stuff").request_id
+ end
+
+ test "accept Apache mod_unique_id format" do
+ mod_unique_id = "abcxyz@ABCXYZ-0123456789"
+ assert_equal mod_unique_id, stub_request("HTTP_X_REQUEST_ID" => mod_unique_id).request_id
end
test "ensure that 255 char limit on the request id is being enforced" do
- assert_equal "X" * 255, stub_request('HTTP_X_REQUEST_ID' => 'X' * 500).request_id
+ assert_equal "X" * 255, stub_request("HTTP_X_REQUEST_ID" => "X" * 500).request_id
end
test "generating a request id when none is supplied" do
@@ -18,15 +25,15 @@ class RequestIdTest < ActiveSupport::TestCase
end
test "uuid alias" do
- assert_equal "external-uu-rid", stub_request('HTTP_X_REQUEST_ID' => 'external-uu-rid').uuid
+ assert_equal "external-uu-rid", stub_request("HTTP_X_REQUEST_ID" => "external-uu-rid").uuid
end
private
- def stub_request(env = {})
- ActionDispatch::RequestId.new(lambda { |environment| [ 200, environment, [] ] }).call(env)
- ActionDispatch::Request.new(env)
- end
+ def stub_request(env = {})
+ ActionDispatch::RequestId.new(lambda { |environment| [ 200, environment, [] ] }).call(env)
+ ActionDispatch::Request.new(env)
+ end
end
class RequestIdResponseTest < ActionDispatch::IntegrationTest
@@ -38,32 +45,31 @@ class RequestIdResponseTest < ActionDispatch::IntegrationTest
test "request id is passed all the way to the response" do
with_test_route_set do
- get '/'
+ get "/"
assert_match(/\w+/, @response.headers["X-Request-Id"])
end
end
test "request id given on request is passed all the way to the response" do
with_test_route_set do
- get '/', headers: { 'HTTP_X_REQUEST_ID' => 'X' * 500 }
+ get "/", headers: { "HTTP_X_REQUEST_ID" => "X" * 500 }
assert_equal "X" * 255, @response.headers["X-Request-Id"]
end
end
-
private
- def with_test_route_set
- with_routing do |set|
- set.draw do
- get '/', :to => ::RequestIdResponseTest::TestController.action(:index)
- end
+ def with_test_route_set
+ with_routing do |set|
+ set.draw do
+ get "/", to: ::RequestIdResponseTest::TestController.action(:index)
+ end
- @app = self.class.build_app(set) do |middleware|
- middleware.use ActionDispatch::RequestId
- end
+ @app = self.class.build_app(set) do |middleware|
+ middleware.use ActionDispatch::RequestId
+ end
- yield
+ yield
+ end
end
- end
end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index 7dd9d05e62..9d1246b3a4 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class BaseRequestTest < ActiveSupport::TestCase
def setup
@@ -14,11 +16,11 @@ class BaseRequestTest < ActiveSupport::TestCase
end
def url_for(options = {})
- options = { host: 'www.example.com' }.merge!(options)
+ options = { host: "www.example.com" }.merge!(options)
ActionDispatch::Http::URL.url_for(options)
end
- protected
+ private
def stub_request(env = {})
ip_spoofing_check = env.key?(:ip_spoofing_check) ? env.delete(:ip_spoofing_check) : true
@trusted_proxies ||= nil
@@ -34,141 +36,141 @@ end
class RequestUrlFor < BaseRequestTest
test "url_for class method" do
- e = assert_raise(ArgumentError) { url_for(:host => nil) }
+ e = assert_raise(ArgumentError) { url_for(host: nil) }
assert_match(/Please provide the :host parameter/, e.message)
- assert_equal '/books', url_for(:only_path => true, :path => '/books')
-
- assert_equal 'http://www.example.com/books/?q=code', url_for(trailing_slash: true, path: '/books?q=code')
- assert_equal 'http://www.example.com/books/?spareslashes=////', url_for(trailing_slash: true, path: '/books?spareslashes=////')
-
- assert_equal 'http://www.example.com', url_for
- assert_equal 'http://api.example.com', url_for(:subdomain => 'api')
- assert_equal 'http://example.com', url_for(:subdomain => false)
- assert_equal 'http://www.ror.com', url_for(:domain => 'ror.com')
- assert_equal 'http://api.ror.co.uk', url_for(:host => 'www.ror.co.uk', :subdomain => 'api', :tld_length => 2)
- assert_equal 'http://www.example.com:8080', url_for(:port => 8080)
- assert_equal 'https://www.example.com', url_for(:protocol => 'https')
- assert_equal 'http://www.example.com/docs', url_for(:path => '/docs')
- assert_equal 'http://www.example.com#signup', url_for(:anchor => 'signup')
- assert_equal 'http://www.example.com/', url_for(:trailing_slash => true)
- assert_equal 'http://dhh:supersecret@www.example.com', url_for(:user => 'dhh', :password => 'supersecret')
- assert_equal 'http://www.example.com?search=books', url_for(:params => { :search => 'books' })
- assert_equal 'http://www.example.com?params=', url_for(:params => '')
- assert_equal 'http://www.example.com?params=1', url_for(:params => 1)
+ assert_equal "/books", url_for(only_path: true, path: "/books")
+
+ assert_equal "http://www.example.com/books/?q=code", url_for(trailing_slash: true, path: "/books?q=code")
+ assert_equal "http://www.example.com/books/?spareslashes=////", url_for(trailing_slash: true, path: "/books?spareslashes=////")
+
+ assert_equal "http://www.example.com", url_for
+ assert_equal "http://api.example.com", url_for(subdomain: "api")
+ assert_equal "http://example.com", url_for(subdomain: false)
+ assert_equal "http://www.ror.com", url_for(domain: "ror.com")
+ assert_equal "http://api.ror.co.uk", url_for(host: "www.ror.co.uk", subdomain: "api", tld_length: 2)
+ assert_equal "http://www.example.com:8080", url_for(port: 8080)
+ assert_equal "https://www.example.com", url_for(protocol: "https")
+ assert_equal "http://www.example.com/docs", url_for(path: "/docs")
+ assert_equal "http://www.example.com#signup", url_for(anchor: "signup")
+ assert_equal "http://www.example.com/", url_for(trailing_slash: true)
+ assert_equal "http://dhh:supersecret@www.example.com", url_for(user: "dhh", password: "supersecret")
+ assert_equal "http://www.example.com?search=books", url_for(params: { search: "books" })
+ assert_equal "http://www.example.com?params=", url_for(params: "")
+ assert_equal "http://www.example.com?params=1", url_for(params: 1)
end
end
class RequestIP < BaseRequestTest
test "remote ip" do
- request = stub_request 'REMOTE_ADDR' => '1.2.3.4'
- assert_equal '1.2.3.4', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "1.2.3.4"
+ assert_equal "1.2.3.4", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "1.2.3.4,3.4.5.6"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '1.2.3.4',
- 'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "1.2.3.4",
+ "HTTP_X_FORWARDED_FOR" => "3.4.5.6"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '127.0.0.1',
- 'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "127.0.0.1",
+ "HTTP_X_FORWARDED_FOR" => "3.4.5.6"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,unknown'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,unknown"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,172.16.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,172.16.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,192.168.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,192.168.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,10.0.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,10.0.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6, 10.0.0.1, 10.0.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6, 10.0.0.1, 10.0.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '3.4.5.6,127.0.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,127.0.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,192.168.0.1'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,192.168.0.1"
+ assert_nil request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 172.31.4.4, 10.0.0.1'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "9.9.9.9, 3.4.5.6, 172.31.4.4, 10.0.0.1"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'not_ip_address'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "not_ip_address"
+ assert_nil request.remote_ip
end
test "remote ip spoof detection" do
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1',
- 'HTTP_CLIENT_IP' => '2.2.2.2'
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "1.1.1.1",
+ "HTTP_CLIENT_IP" => "2.2.2.2"
e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) {
request.remote_ip
}
assert_match(/IP spoofing attack/, e.message)
- assert_match(/HTTP_X_FORWARDED_FOR="1.1.1.1"/, e.message)
- assert_match(/HTTP_CLIENT_IP="2.2.2.2"/, e.message)
+ assert_match(/HTTP_X_FORWARDED_FOR="1\.1\.1\.1"/, e.message)
+ assert_match(/HTTP_CLIENT_IP="2\.2\.2\.2"/, e.message)
end
test "remote ip with spoof detection disabled" do
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1',
- 'HTTP_CLIENT_IP' => '2.2.2.2',
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "1.1.1.1",
+ "HTTP_CLIENT_IP" => "2.2.2.2",
:ip_spoofing_check => false
- assert_equal '1.1.1.1', request.remote_ip
+ assert_equal "1.1.1.1", request.remote_ip
end
test "remote ip spoof protection ignores private addresses" do
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '172.17.19.51',
- 'HTTP_CLIENT_IP' => '172.17.19.51',
- 'REMOTE_ADDR' => '1.1.1.1',
- 'HTTP_X_BLUECOAT_VIA' => 'de462e07a2db325e'
- assert_equal '1.1.1.1', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "172.17.19.51",
+ "HTTP_CLIENT_IP" => "172.17.19.51",
+ "REMOTE_ADDR" => "1.1.1.1",
+ "HTTP_X_BLUECOAT_VIA" => "de462e07a2db325e"
+ assert_equal "1.1.1.1", request.remote_ip
end
test "remote ip v6" do
- request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '::1',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "::1",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,unknown'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,unknown"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, ::1'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, ::1"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,::1'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,::1"
+ assert_nil request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, fc00::, fc01::, fdff'
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, fc00::, fc01::, fdff"
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'FE00::, FDFF::'
- assert_equal 'FE00::', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "FE00::, FDFF::"
+ assert_equal "FE00::", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'not_ip_address'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "not_ip_address"
+ assert_nil request.remote_ip
end
test "remote ip v6 spoof detection" do
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329',
- 'HTTP_CLIENT_IP' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329",
+ "HTTP_CLIENT_IP" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) {
request.remote_ip
}
@@ -178,139 +180,139 @@ class RequestIP < BaseRequestTest
end
test "remote ip v6 spoof detection disabled" do
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329',
- 'HTTP_CLIENT_IP' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329",
+ "HTTP_CLIENT_IP" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
:ip_spoofing_check => false
- assert_equal 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329', request.remote_ip
+ assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
end
test "remote ip with user specified trusted proxies String" do
@trusted_proxies = "67.205.106.73"
- request = stub_request 'REMOTE_ADDR' => '3.4.5.6',
- 'HTTP_X_FORWARDED_FOR' => '67.205.106.73'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "3.4.5.6",
+ "HTTP_X_FORWARDED_FOR" => "67.205.106.73"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '172.16.0.1,67.205.106.73',
- 'HTTP_X_FORWARDED_FOR' => '67.205.106.73'
- assert_equal '67.205.106.73', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "172.16.0.1,67.205.106.73",
+ "HTTP_X_FORWARDED_FOR" => "67.205.106.73"
+ assert_equal "67.205.106.73", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => '67.205.106.73,3.4.5.6',
- 'HTTP_X_FORWARDED_FOR' => '67.205.106.73'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "67.205.106.73,3.4.5.6",
+ "HTTP_X_FORWARDED_FOR" => "67.205.106.73"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '67.205.106.73,unknown'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "67.205.106.73,unknown"
+ assert_nil request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 10.0.0.1, 67.205.106.73'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "9.9.9.9, 3.4.5.6, 10.0.0.1, 67.205.106.73"
+ assert_equal "3.4.5.6", request.remote_ip
end
test "remote ip v6 with user specified trusted proxies String" do
- @trusted_proxies = 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
+ @trusted_proxies = "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
- request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
- request = stub_request 'REMOTE_ADDR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal '::1', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "::1", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'unknown,fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal nil, request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_nil request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334'
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334"
assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
end
test "remote ip with user specified trusted proxies Regexp" do
@trusted_proxies = /^67\.205\.106\.73$/i
- request = stub_request 'REMOTE_ADDR' => '67.205.106.73',
- 'HTTP_X_FORWARDED_FOR' => '3.4.5.6'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "67.205.106.73",
+ "HTTP_X_FORWARDED_FOR" => "3.4.5.6"
+ assert_equal "3.4.5.6", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '10.0.0.1, 9.9.9.9, 3.4.5.6, 67.205.106.73'
- assert_equal '3.4.5.6', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "10.0.0.1, 9.9.9.9, 3.4.5.6, 67.205.106.73"
+ assert_equal "3.4.5.6", request.remote_ip
end
test "remote ip v6 with user specified trusted proxies Regexp" do
@trusted_proxies = /^fe80:0000:0000:0000:0202:b3ff:fe1e:8329$/i
- request = stub_request 'REMOTE_ADDR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
- 'HTTP_X_FORWARDED_FOR' => 'fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "REMOTE_ADDR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+ "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
- request = stub_request 'HTTP_X_FORWARDED_FOR' => '2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329'
- assert_equal '2001:0db8:85a3:0000:0000:8a2e:0370:7334', request.remote_ip
+ request = stub_request "HTTP_X_FORWARDED_FOR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
+ assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip
end
test "remote ip middleware not present still returns an IP" do
- request = stub_request('REMOTE_ADDR' => '127.0.0.1')
- assert_equal '127.0.0.1', request.remote_ip
+ request = stub_request("REMOTE_ADDR" => "127.0.0.1")
+ assert_equal "127.0.0.1", request.remote_ip
end
end
class RequestDomain < BaseRequestTest
test "domains" do
- request = stub_request 'HTTP_HOST' => "192.168.1.200"
+ request = stub_request "HTTP_HOST" => "192.168.1.200"
assert_nil request.domain
- request = stub_request 'HTTP_HOST' => "foo.192.168.1.200"
+ request = stub_request "HTTP_HOST" => "foo.192.168.1.200"
assert_nil request.domain
- request = stub_request 'HTTP_HOST' => "192.168.1.200.com"
+ request = stub_request "HTTP_HOST" => "192.168.1.200.com"
assert_equal "200.com", request.domain
- request = stub_request 'HTTP_HOST' => 'www.rubyonrails.org'
+ request = stub_request "HTTP_HOST" => "www.rubyonrails.org"
assert_equal "rubyonrails.org", request.domain
- request = stub_request 'HTTP_HOST' => "www.rubyonrails.co.uk"
+ request = stub_request "HTTP_HOST" => "www.rubyonrails.co.uk"
assert_equal "rubyonrails.co.uk", request.domain(2)
- request = stub_request 'HTTP_HOST' => "www.rubyonrails.co.uk", :tld_length => 2
+ request = stub_request "HTTP_HOST" => "www.rubyonrails.co.uk", :tld_length => 2
assert_equal "rubyonrails.co.uk", request.domain
end
test "subdomains" do
- request = stub_request 'HTTP_HOST' => "foobar.foobar.com"
+ request = stub_request "HTTP_HOST" => "foobar.foobar.com"
assert_equal %w( foobar ), request.subdomains
assert_equal "foobar", request.subdomain
- request = stub_request 'HTTP_HOST' => "192.168.1.200"
+ request = stub_request "HTTP_HOST" => "192.168.1.200"
assert_equal [], request.subdomains
assert_equal "", request.subdomain
- request = stub_request 'HTTP_HOST' => "foo.192.168.1.200"
+ request = stub_request "HTTP_HOST" => "foo.192.168.1.200"
assert_equal [], request.subdomains
assert_equal "", request.subdomain
- request = stub_request 'HTTP_HOST' => "192.168.1.200.com"
+ request = stub_request "HTTP_HOST" => "192.168.1.200.com"
assert_equal %w( 192 168 1 ), request.subdomains
assert_equal "192.168.1", request.subdomain
- request = stub_request 'HTTP_HOST' => nil
+ request = stub_request "HTTP_HOST" => nil
assert_equal [], request.subdomains
assert_equal "", request.subdomain
- request = stub_request 'HTTP_HOST' => "www.rubyonrails.org"
+ request = stub_request "HTTP_HOST" => "www.rubyonrails.org"
assert_equal %w( www ), request.subdomains
assert_equal "www", request.subdomain
- request = stub_request 'HTTP_HOST' => "www.rubyonrails.co.uk"
+ request = stub_request "HTTP_HOST" => "www.rubyonrails.co.uk"
assert_equal %w( www ), request.subdomains(2)
assert_equal "www", request.subdomain(2)
- request = stub_request 'HTTP_HOST' => "dev.www.rubyonrails.co.uk"
+ request = stub_request "HTTP_HOST" => "dev.www.rubyonrails.co.uk"
assert_equal %w( dev www ), request.subdomains(2)
assert_equal "dev.www", request.subdomain(2)
- request = stub_request 'HTTP_HOST' => "dev.www.rubyonrails.co.uk", :tld_length => 2
+ request = stub_request "HTTP_HOST" => "dev.www.rubyonrails.co.uk", :tld_length => 2
assert_equal %w( dev www ), request.subdomains
assert_equal "dev.www", request.subdomain
end
@@ -321,95 +323,106 @@ class RequestPort < BaseRequestTest
request = stub_request
assert_equal 80, request.standard_port
- request = stub_request 'HTTPS' => 'on'
+ request = stub_request "HTTPS" => "on"
assert_equal 443, request.standard_port
end
test "standard_port?" do
request = stub_request
- assert !request.ssl?
- assert request.standard_port?
+ assert_not_predicate request, :ssl?
+ assert_predicate request, :standard_port?
- request = stub_request 'HTTPS' => 'on'
- assert request.ssl?
- assert request.standard_port?
+ request = stub_request "HTTPS" => "on"
+ assert_predicate request, :ssl?
+ assert_predicate request, :standard_port?
- request = stub_request 'HTTP_HOST' => 'www.example.org:8080'
- assert !request.ssl?
- assert !request.standard_port?
+ request = stub_request "HTTP_HOST" => "www.example.org:8080"
+ assert_not_predicate request, :ssl?
+ assert_not_predicate request, :standard_port?
- request = stub_request 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on'
- assert request.ssl?
- assert !request.standard_port?
+ request = stub_request "HTTP_HOST" => "www.example.org:8443", "HTTPS" => "on"
+ assert_predicate request, :ssl?
+ assert_not_predicate request, :standard_port?
end
test "optional port" do
- request = stub_request 'HTTP_HOST' => 'www.example.org:80'
- assert_equal nil, request.optional_port
+ request = stub_request "HTTP_HOST" => "www.example.org:80"
+ assert_nil request.optional_port
- request = stub_request 'HTTP_HOST' => 'www.example.org:8080'
+ request = stub_request "HTTP_HOST" => "www.example.org:8080"
assert_equal 8080, request.optional_port
end
test "port string" do
- request = stub_request 'HTTP_HOST' => 'www.example.org:80'
- assert_equal '', request.port_string
+ request = stub_request "HTTP_HOST" => "www.example.org:80"
+ assert_equal "", request.port_string
+
+ request = stub_request "HTTP_HOST" => "www.example.org:8080"
+ assert_equal ":8080", request.port_string
+ end
- request = stub_request 'HTTP_HOST' => 'www.example.org:8080'
- assert_equal ':8080', request.port_string
+ test "server port" do
+ request = stub_request "SERVER_PORT" => "8080"
+ assert_equal 8080, request.server_port
+
+ request = stub_request "SERVER_PORT" => "80"
+ assert_equal 80, request.server_port
+
+ request = stub_request "SERVER_PORT" => ""
+ assert_equal 0, request.server_port
end
end
class RequestPath < BaseRequestTest
test "full path" do
- request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri', 'QUERY_STRING' => 'mapped=1'
+ request = stub_request "SCRIPT_NAME" => "", "PATH_INFO" => "/path/of/some/uri", "QUERY_STRING" => "mapped=1"
assert_equal "/path/of/some/uri?mapped=1", request.fullpath
assert_equal "/path/of/some/uri", request.path_info
- request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri'
+ request = stub_request "SCRIPT_NAME" => "", "PATH_INFO" => "/path/of/some/uri"
assert_equal "/path/of/some/uri", request.fullpath
assert_equal "/path/of/some/uri", request.path_info
- request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/'
+ request = stub_request "SCRIPT_NAME" => "", "PATH_INFO" => "/"
assert_equal "/", request.fullpath
assert_equal "/", request.path_info
- request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'QUERY_STRING' => 'm=b'
+ request = stub_request "SCRIPT_NAME" => "", "PATH_INFO" => "/", "QUERY_STRING" => "m=b"
assert_equal "/?m=b", request.fullpath
assert_equal "/", request.path_info
- request = stub_request 'SCRIPT_NAME' => '/hieraki', 'PATH_INFO' => '/'
+ request = stub_request "SCRIPT_NAME" => "/hieraki", "PATH_INFO" => "/"
assert_equal "/hieraki/", request.fullpath
assert_equal "/", request.path_info
- request = stub_request 'SCRIPT_NAME' => '/collaboration/hieraki', 'PATH_INFO' => '/books/edit/2'
+ request = stub_request "SCRIPT_NAME" => "/collaboration/hieraki", "PATH_INFO" => "/books/edit/2"
assert_equal "/collaboration/hieraki/books/edit/2", request.fullpath
assert_equal "/books/edit/2", request.path_info
- request = stub_request 'SCRIPT_NAME' => '/path', 'PATH_INFO' => '/of/some/uri', 'QUERY_STRING' => 'mapped=1'
+ request = stub_request "SCRIPT_NAME" => "/path", "PATH_INFO" => "/of/some/uri", "QUERY_STRING" => "mapped=1"
assert_equal "/path/of/some/uri?mapped=1", request.fullpath
assert_equal "/of/some/uri", request.path_info
end
test "original_fullpath returns ORIGINAL_FULLPATH" do
- request = stub_request('ORIGINAL_FULLPATH' => "/foo?bar")
+ request = stub_request("ORIGINAL_FULLPATH" => "/foo?bar")
path = request.original_fullpath
assert_equal "/foo?bar", path
end
test "original_url returns url built using ORIGINAL_FULLPATH" do
- request = stub_request('ORIGINAL_FULLPATH' => "/foo?bar",
- 'HTTP_HOST' => "example.org",
- 'rack.url_scheme' => "http")
+ request = stub_request("ORIGINAL_FULLPATH" => "/foo?bar",
+ "HTTP_HOST" => "example.org",
+ "rack.url_scheme" => "http")
url = request.original_url
assert_equal "http://example.org/foo?bar", url
end
test "original_fullpath returns fullpath if ORIGINAL_FULLPATH is not present" do
- request = stub_request('PATH_INFO' => "/foo",
- 'QUERY_STRING' => "bar")
+ request = stub_request("PATH_INFO" => "/foo",
+ "QUERY_STRING" => "bar")
path = request.original_fullpath
assert_equal "/foo?bar", path
@@ -417,58 +430,78 @@ class RequestPath < BaseRequestTest
end
class RequestHost < BaseRequestTest
+ test "host without specifying port" do
+ request = stub_request "HTTP_HOST" => "rubyonrails.org"
+ assert_equal "rubyonrails.org", request.host_with_port
+ end
+
test "host with default port" do
- request = stub_request 'HTTP_HOST' => 'rubyonrails.org:80'
+ request = stub_request "HTTP_HOST" => "rubyonrails.org:80"
assert_equal "rubyonrails.org", request.host_with_port
end
test "host with non default port" do
- request = stub_request 'HTTP_HOST' => 'rubyonrails.org:81'
+ request = stub_request "HTTP_HOST" => "rubyonrails.org:81"
assert_equal "rubyonrails.org:81", request.host_with_port
end
+ test "raw without specifying port" do
+ request = stub_request "HTTP_HOST" => "rubyonrails.org"
+ assert_equal "rubyonrails.org", request.raw_host_with_port
+ end
+
+ test "raw host with default port" do
+ request = stub_request "HTTP_HOST" => "rubyonrails.org:80"
+ assert_equal "rubyonrails.org:80", request.raw_host_with_port
+ end
+
+ test "raw host with non default port" do
+ request = stub_request "HTTP_HOST" => "rubyonrails.org:81"
+ assert_equal "rubyonrails.org:81", request.raw_host_with_port
+ end
+
test "proxy request" do
- request = stub_request 'HTTP_HOST' => 'glu.ttono.us:80'
+ request = stub_request "HTTP_HOST" => "glu.ttono.us:80"
assert_equal "glu.ttono.us", request.host_with_port
end
test "http host" do
- request = stub_request 'HTTP_HOST' => "rubyonrails.org:8080"
+ request = stub_request "HTTP_HOST" => "rubyonrails.org:8080"
assert_equal "rubyonrails.org", request.host
assert_equal "rubyonrails.org:8080", request.host_with_port
- request = stub_request 'HTTP_X_FORWARDED_HOST' => "www.firsthost.org, www.secondhost.org"
+ request = stub_request "HTTP_X_FORWARDED_HOST" => "www.firsthost.org, www.secondhost.org"
assert_equal "www.secondhost.org", request.host
- request = stub_request 'HTTP_X_FORWARDED_HOST' => "", 'HTTP_HOST' => "rubyonrails.org"
+ request = stub_request "HTTP_X_FORWARDED_HOST" => "", "HTTP_HOST" => "rubyonrails.org"
assert_equal "rubyonrails.org", request.host
end
test "http host with default port overrides server port" do
- request = stub_request 'HTTP_HOST' => "rubyonrails.org"
+ request = stub_request "HTTP_HOST" => "rubyonrails.org"
assert_equal "rubyonrails.org", request.host_with_port
end
test "host with port if http standard port is specified" do
- request = stub_request 'HTTP_X_FORWARDED_HOST' => "glu.ttono.us:80"
+ request = stub_request "HTTP_X_FORWARDED_HOST" => "glu.ttono.us:80"
assert_equal "glu.ttono.us", request.host_with_port
end
test "host with port if https standard port is specified" do
request = stub_request(
- 'HTTP_X_FORWARDED_PROTO' => "https",
- 'HTTP_X_FORWARDED_HOST' => "glu.ttono.us:443"
+ "HTTP_X_FORWARDED_PROTO" => "https",
+ "HTTP_X_FORWARDED_HOST" => "glu.ttono.us:443"
)
assert_equal "glu.ttono.us", request.host_with_port
end
test "host if ipv6 reference" do
- request = stub_request 'HTTP_HOST' => "[2001:1234:5678:9abc:def0::dead:beef]"
+ request = stub_request "HTTP_HOST" => "[2001:1234:5678:9abc:def0::dead:beef]"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", request.host
end
test "host if ipv6 reference with port" do
- request = stub_request 'HTTP_HOST' => "[2001:1234:5678:9abc:def0::dead:beef]:8008"
+ request = stub_request "HTTP_HOST" => "[2001:1234:5678:9abc:def0::dead:beef]:8008"
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", request.host
end
end
@@ -506,7 +539,7 @@ class RequestCGI < BaseRequestTest
assert_equal "Basic", request.auth_type
assert_equal 0, request.content_length
- assert_equal nil, request.content_mime_type
+ assert_nil request.content_mime_type
assert_equal "CGI/1.1", request.gateway_interface
assert_equal "*/*", request.accept
assert_equal "UTF-8", request.accept_charset
@@ -538,7 +571,7 @@ end
class LocalhostTest < BaseRequestTest
test "IPs that match localhost" do
request = stub_request("REMOTE_IP" => "127.1.1.1", "REMOTE_ADDR" => "127.1.1.1")
- assert request.local?
+ assert_predicate request, :local?
end
end
@@ -550,7 +583,7 @@ class RequestCookie < BaseRequestTest
# some Nokia phone browsers omit the space after the semicolon separator.
# some developers have grown accustomed to using comma in cookie values.
- request = stub_request("HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes")
+ request = stub_request("HTTP_COOKIE" => "_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes")
assert_equal "c84ace847", request.cookies["_session_id"], request.cookies.inspect
assert_equal "yes", request.cookies["is_admin"], request.cookies.inspect
end
@@ -559,28 +592,28 @@ end
class RequestParamsParsing < BaseRequestTest
test "doesnt break when content type has charset" do
request = stub_request(
- 'REQUEST_METHOD' => 'POST',
- 'CONTENT_LENGTH' => "flamenco=love".length,
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
- 'rack.input' => StringIO.new("flamenco=love")
+ "REQUEST_METHOD" => "POST",
+ "CONTENT_LENGTH" => "flamenco=love".length,
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded; charset=utf-8",
+ "rack.input" => StringIO.new("flamenco=love")
)
- assert_equal({"flamenco"=> "love"}, request.request_parameters)
+ assert_equal({ "flamenco" => "love" }, request.request_parameters)
end
test "doesnt interpret request uri as query string when missing" do
- request = stub_request('REQUEST_URI' => 'foo')
+ request = stub_request("REQUEST_URI" => "foo")
assert_equal({}, request.query_parameters)
end
end
class RequestRewind < BaseRequestTest
test "body should be rewound" do
- data = 'rewind'
+ data = "rewind"
env = {
- 'rack.input' => StringIO.new(data),
- 'CONTENT_LENGTH' => data.length,
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8'
+ "rack.input" => StringIO.new(data),
+ "CONTENT_LENGTH" => data.length,
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded; charset=utf-8"
}
# Read the request body by parsing params.
@@ -593,55 +626,55 @@ class RequestRewind < BaseRequestTest
test "raw_post rewinds rack.input if RAW_POST_DATA is nil" do
request = stub_request(
- 'rack.input' => StringIO.new("raw"),
- 'CONTENT_LENGTH' => 3
+ "rack.input" => StringIO.new("raw"),
+ "CONTENT_LENGTH" => 3
)
assert_equal "raw", request.raw_post
- assert_equal "raw", request.env['rack.input'].read
+ assert_equal "raw", request.env["rack.input"].read
end
end
class RequestProtocol < BaseRequestTest
test "server software" do
- assert_equal 'lighttpd', stub_request('SERVER_SOFTWARE' => 'lighttpd/1.4.5').server_software
- assert_equal 'apache', stub_request('SERVER_SOFTWARE' => 'Apache3.422').server_software
+ assert_equal "lighttpd", stub_request("SERVER_SOFTWARE" => "lighttpd/1.4.5").server_software
+ assert_equal "apache", stub_request("SERVER_SOFTWARE" => "Apache3.422").server_software
end
test "xml http request" do
request = stub_request
- assert !request.xml_http_request?
- assert !request.xhr?
+ assert_not_predicate request, :xml_http_request?
+ assert_not_predicate request, :xhr?
- request = stub_request 'HTTP_X_REQUESTED_WITH' => 'DefinitelyNotAjax1.0'
- assert !request.xml_http_request?
- assert !request.xhr?
+ request = stub_request "HTTP_X_REQUESTED_WITH" => "DefinitelyNotAjax1.0"
+ assert_not_predicate request, :xml_http_request?
+ assert_not_predicate request, :xhr?
- request = stub_request 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'
- assert request.xml_http_request?
- assert request.xhr?
+ request = stub_request "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
+ assert_predicate request, :xml_http_request?
+ assert_predicate request, :xhr?
end
test "reports ssl" do
- assert !stub_request.ssl?
- assert stub_request('HTTPS' => 'on').ssl?
+ assert_not_predicate stub_request, :ssl?
+ assert_predicate stub_request("HTTPS" => "on"), :ssl?
end
test "reports ssl when proxied via lighttpd" do
- assert stub_request('HTTP_X_FORWARDED_PROTO' => 'https').ssl?
+ assert_predicate stub_request("HTTP_X_FORWARDED_PROTO" => "https"), :ssl?
end
test "scheme returns https when proxied" do
- request = stub_request 'rack.url_scheme' => 'http'
- assert !request.ssl?
- assert_equal 'http', request.scheme
+ request = stub_request "rack.url_scheme" => "http"
+ assert_not_predicate request, :ssl?
+ assert_equal "http", request.scheme
request = stub_request(
- 'rack.url_scheme' => 'http',
- 'HTTP_X_FORWARDED_PROTO' => 'https'
+ "rack.url_scheme" => "http",
+ "HTTP_X_FORWARDED_PROTO" => "https"
)
- assert request.ssl?
- assert_equal 'https', request.scheme
+ assert_predicate request, :ssl?
+ assert_equal "https", request.scheme
end
end
@@ -650,7 +683,7 @@ class RequestMethod < BaseRequestTest
overridden by middleware".squish do
ActionDispatch::Request::HTTP_METHODS.each do |method|
- request = stub_request('REQUEST_METHOD' => method)
+ request = stub_request("REQUEST_METHOD" => method)
assert_equal method, request.method
assert_equal method.underscore.to_sym, request.method_symbol
@@ -658,36 +691,36 @@ class RequestMethod < BaseRequestTest
end
test "allow request method hacking" do
- request = stub_request('REQUEST_METHOD' => 'POST')
+ request = stub_request("REQUEST_METHOD" => "POST")
- assert_equal 'POST', request.request_method
- assert_equal 'POST', request.env["REQUEST_METHOD"]
+ assert_equal "POST", request.request_method
+ assert_equal "POST", request.env["REQUEST_METHOD"]
- request.request_method = 'GET'
+ request.request_method = "GET"
- assert_equal 'GET', request.request_method
- assert_equal 'GET', request.env["REQUEST_METHOD"]
- assert request.get?
+ assert_equal "GET", request.request_method
+ assert_equal "GET", request.env["REQUEST_METHOD"]
+ assert_predicate request, :get?
end
test "invalid http method raises exception" do
assert_raise(ActionController::UnknownHttpMethod) do
- stub_request('REQUEST_METHOD' => 'RANDOM_METHOD').request_method
+ stub_request("REQUEST_METHOD" => "RANDOM_METHOD").request_method
end
end
test "method returns original value of environment request method on POST" do
- request = stub_request('rack.methodoverride.original_method' => 'POST')
- assert_equal 'POST', request.method
+ request = stub_request("rack.methodoverride.original_method" => "POST")
+ assert_equal "POST", request.method
end
test "method raises exception on invalid HTTP method" do
assert_raise(ActionController::UnknownHttpMethod) do
- stub_request('rack.methodoverride.original_method' => '_RANDOM_METHOD').method
+ stub_request("rack.methodoverride.original_method" => "_RANDOM_METHOD").method
end
assert_raise(ActionController::UnknownHttpMethod) do
- stub_request('REQUEST_METHOD' => '_RANDOM_METHOD').method
+ stub_request("REQUEST_METHOD" => "_RANDOM_METHOD").method
end
end
@@ -699,7 +732,7 @@ class RequestMethod < BaseRequestTest
I18n.available_locales = [:nl]
I18n.config.enforce_available_locales = true
assert_raise(ActionController::UnknownHttpMethod) do
- stub_request('REQUEST_METHOD' => '_RANDOM_METHOD').method
+ stub_request("REQUEST_METHOD" => "_RANDOM_METHOD").method
end
ensure
I18n.available_locales = old_locales
@@ -709,28 +742,28 @@ class RequestMethod < BaseRequestTest
test "post masquerading as patch" do
request = stub_request(
- 'REQUEST_METHOD' => 'PATCH',
+ "REQUEST_METHOD" => "PATCH",
"rack.methodoverride.original_method" => "POST"
)
assert_equal "POST", request.method
assert_equal "PATCH", request.request_method
- assert request.patch?
+ assert_predicate request, :patch?
end
test "post masquerading as put" do
request = stub_request(
- 'REQUEST_METHOD' => 'PUT',
+ "REQUEST_METHOD" => "PUT",
"rack.methodoverride.original_method" => "POST"
)
assert_equal "POST", request.method
assert_equal "PUT", request.request_method
- assert request.put?
+ assert_predicate request, :put?
end
test "post uneffected by local inflections" do
- existing_acrnoyms = ActiveSupport::Inflector.inflections.acronyms.dup
- existing_acrnoym_regex = ActiveSupport::Inflector.inflections.acronym_regex.dup
+ existing_acronyms = ActiveSupport::Inflector.inflections.acronyms.dup
+ assert_deprecated { ActiveSupport::Inflector.inflections.acronym_regex.dup }
begin
ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym "POS"
@@ -739,12 +772,12 @@ class RequestMethod < BaseRequestTest
request = stub_request "REQUEST_METHOD" => "POST"
assert_equal :post, ActionDispatch::Request::HTTP_METHOD_LOOKUP["POST"]
assert_equal :post, request.method_symbol
- assert request.post?
+ assert_predicate request, :post?
ensure
# Reset original acronym set
ActiveSupport::Inflector.inflections do |inflect|
- inflect.send(:instance_variable_set,"@acronyms",existing_acrnoyms)
- inflect.send(:instance_variable_set,"@acronym_regex",existing_acrnoym_regex)
+ inflect.send(:instance_variable_set, "@acronyms", existing_acronyms)
+ inflect.send(:define_acronym_regex_patterns)
end
end
end
@@ -752,108 +785,99 @@ end
class RequestFormat < BaseRequestTest
test "xml format" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :xml}) do
- assert_equal Mime[:xml], request.format
- end
+ request = stub_request "QUERY_STRING" => "format=xml"
+
+ assert_equal Mime[:xml], request.format
end
test "xhtml format" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :xhtml}) do
- assert_equal Mime[:html], request.format
- end
+ request = stub_request "QUERY_STRING" => "format=xhtml"
+
+ assert_equal Mime[:html], request.format
end
test "txt format" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :txt}) do
- assert_equal Mime[:text], request.format
- end
+ request = stub_request "QUERY_STRING" => "format=txt"
+
+ assert_equal Mime[:text], request.format
end
test "XMLHttpRequest" do
request = stub_request(
- 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest',
- 'HTTP_ACCEPT' => [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(",")
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
+ "HTTP_ACCEPT" => [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(","),
+ "QUERY_STRING" => ""
)
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert request.xhr?
- assert_equal Mime[:js], request.format
- end
+ assert_predicate request, :xhr?
+ assert_equal Mime[:js], request.format
end
test "can override format with parameter negative" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :txt}) do
- assert !request.format.xml?
- end
+ request = stub_request("QUERY_STRING" => "format=txt")
+
+ assert_not_predicate request.format, :xml?
end
test "can override format with parameter positive" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :xml}) do
- assert request.format.xml?
- end
+ request = stub_request("QUERY_STRING" => "format=xml")
+
+ assert_predicate request.format, :xml?
end
test "formats text/html with accept header" do
- request = stub_request 'HTTP_ACCEPT' => 'text/html'
+ request = stub_request "HTTP_ACCEPT" => "text/html"
assert_equal [Mime[:html]], request.formats
end
test "formats blank with accept header" do
- request = stub_request 'HTTP_ACCEPT' => ''
+ request = stub_request "HTTP_ACCEPT" => ""
assert_equal [Mime[:html]], request.formats
end
test "formats XMLHttpRequest with accept header" do
- request = stub_request 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ request = stub_request "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
assert_equal [Mime[:js]], request.formats
end
test "formats application/xml with accept header" do
- request = stub_request('CONTENT_TYPE' => 'application/xml; charset=UTF-8',
- 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest")
+ request = stub_request("CONTENT_TYPE" => "application/xml; charset=UTF-8",
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
assert_equal [Mime[:xml]], request.formats
end
test "formats format:text with accept header" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :txt}) do
- assert_equal [Mime[:text]], request.formats
- end
+ request = stub_request("QUERY_STRING" => "format=txt")
+
+ assert_equal [Mime[:text]], request.formats
end
test "formats format:unknown with accept header" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :unknown}) do
- assert_instance_of Mime::NullType, request.format
- end
+ request = stub_request("QUERY_STRING" => "format=unknown")
+
+ assert_instance_of Mime::NullType, request.format
end
test "format is not nil with unknown format" do
- request = stub_request
- assert_called(request, :parameters, times: 2, returns: {format: :hello}) do
- assert request.format.nil?
- assert_not request.format.html?
- assert_not request.format.xml?
- assert_not request.format.json?
- end
+ request = stub_request("QUERY_STRING" => "format=hello")
+
+ assert_nil request.format
+ assert_not_predicate request.format, :html?
+ assert_not_predicate request.format, :xml?
+ assert_not_predicate 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?
+ assert_predicate request.format, :html?
end
test "formats with xhr request" do
- request = stub_request 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [Mime[:js]], request.formats
- end
+ request = stub_request "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
+ "QUERY_STRING" => ""
+
+ assert_equal [Mime[:js]], request.formats
end
test "ignore_accept_header" do
@@ -861,80 +885,97 @@ class RequestFormat < BaseRequestTest
ActionDispatch::Request.ignore_accept_header = true
begin
- request = stub_request 'HTTP_ACCEPT' => 'application/xml'
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [ Mime[:html] ], request.formats
- end
+ request = stub_request "HTTP_ACCEPT" => "application/xml",
+ "QUERY_STRING" => ""
- request = stub_request 'HTTP_ACCEPT' => 'koz-asked/something-crazy'
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [ Mime[:html] ], request.formats
- end
+ assert_equal [ Mime[:html] ], request.formats
- request = stub_request 'HTTP_ACCEPT' => '*/*;q=0.1'
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [ Mime[:html] ], request.formats
- end
+ request = stub_request "HTTP_ACCEPT" => "koz-asked/something-crazy",
+ "QUERY_STRING" => ""
- request = stub_request 'HTTP_ACCEPT' => 'application/jxw'
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [ Mime[:html] ], request.formats
- end
+ assert_equal [ Mime[:html] ], request.formats
- request = stub_request 'HTTP_ACCEPT' => 'application/xml',
- 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ request = stub_request "HTTP_ACCEPT" => "*/*;q=0.1",
+ "QUERY_STRING" => ""
- assert_called(request, :parameters, times: 1, returns: {}) do
- assert_equal [ Mime[:js] ], request.formats
- end
+ assert_equal [ Mime[:html] ], request.formats
- request = stub_request 'HTTP_ACCEPT' => 'application/xml',
- 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
- assert_called(request, :parameters, times: 2, returns: {format: :json}) do
- assert_equal [ Mime[:json] ], request.formats
- end
+ request = stub_request "HTTP_ACCEPT" => "application/jxw",
+ "QUERY_STRING" => ""
+
+ assert_equal [ Mime[:html] ], request.formats
+
+ request = stub_request "HTTP_ACCEPT" => "application/xml",
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
+ "QUERY_STRING" => ""
+
+ assert_equal [ Mime[:js] ], request.formats
+
+ request = stub_request "HTTP_ACCEPT" => "application/xml",
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest",
+ "QUERY_STRING" => "format=json"
+
+ assert_equal [ Mime[:json] ], request.formats
ensure
ActionDispatch::Request.ignore_accept_header = old_ignore_accept_header
end
end
+
+ test "format taken from the path extension" do
+ request = stub_request "PATH_INFO" => "/foo.xml", "QUERY_STRING" => ""
+
+ assert_equal [Mime[:xml]], request.formats
+
+ request = stub_request "PATH_INFO" => "/foo.123", "QUERY_STRING" => ""
+
+ assert_equal [Mime[:html]], request.formats
+ end
+
+ test "formats from accept headers have higher precedence than path extension" do
+ request = stub_request "HTTP_ACCEPT" => "application/json",
+ "PATH_INFO" => "/foo.xml",
+ "QUERY_STRING" => ""
+
+ assert_equal [Mime[:json]], request.formats
+ end
end
class RequestMimeType < BaseRequestTest
test "content type" do
- assert_equal Mime[:html], stub_request('CONTENT_TYPE' => 'text/html').content_mime_type
+ assert_equal Mime[:html], stub_request("CONTENT_TYPE" => "text/html").content_mime_type
end
test "no content type" do
- assert_equal nil, stub_request.content_mime_type
+ assert_nil stub_request.content_mime_type
end
test "content type is XML" do
- assert_equal Mime[:xml], stub_request('CONTENT_TYPE' => 'application/xml').content_mime_type
+ assert_equal Mime[:xml], stub_request("CONTENT_TYPE" => "application/xml").content_mime_type
end
test "content type with charset" do
- assert_equal Mime[:xml], stub_request('CONTENT_TYPE' => 'application/xml; charset=UTF-8').content_mime_type
+ assert_equal Mime[:xml], stub_request("CONTENT_TYPE" => "application/xml; charset=UTF-8").content_mime_type
end
test "user agent" do
- assert_equal 'TestAgent', stub_request('HTTP_USER_AGENT' => 'TestAgent').user_agent
+ assert_equal "TestAgent", stub_request("HTTP_USER_AGENT" => "TestAgent").user_agent
end
test "negotiate_mime" do
request = stub_request(
- 'HTTP_ACCEPT' => 'text/html',
- 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ "HTTP_ACCEPT" => "text/html",
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
)
- assert_equal nil, request.negotiate_mime([Mime[:xml], Mime[:json]])
+ assert_nil request.negotiate_mime([Mime[:xml], Mime[:json]])
assert_equal Mime[:html], request.negotiate_mime([Mime[:xml], Mime[:html]])
assert_equal Mime[:html], request.negotiate_mime([Mime[:xml], Mime::ALL])
end
test "negotiate_mime with content_type" do
request = stub_request(
- 'CONTENT_TYPE' => 'application/xml; charset=UTF-8',
- 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ "CONTENT_TYPE" => "application/xml; charset=UTF-8",
+ "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"
)
assert_equal Mime[:xml], request.negotiate_mime([Mime[:xml], Mime[:csv]])
@@ -943,15 +984,14 @@ end
class RequestParameters < BaseRequestTest
test "parameters" do
- request = stub_request
+ request = stub_request "CONTENT_TYPE" => "application/json",
+ "CONTENT_LENGTH" => 9,
+ "RAW_POST_DATA" => '{"foo":1}',
+ "QUERY_STRING" => "bar=2"
- assert_called(request, :request_parameters, times: 2, returns: {"foo" => 1}) do
- assert_called(request, :query_parameters, times: 2, returns: {"bar" => 2}) do
- assert_equal({"foo" => 1, "bar" => 2}, request.parameters)
- assert_equal({"foo" => 1}, request.request_parameters)
- assert_equal({"bar" => 2}, request.query_parameters)
- end
- end
+ assert_equal({ "foo" => 1, "bar" => "2" }, request.parameters)
+ assert_equal({ "foo" => 1 }, request.request_parameters)
+ assert_equal({ "bar" => "2" }, request.query_parameters)
end
test "parameters not accessible after rack parse error" do
@@ -966,17 +1006,14 @@ class RequestParameters < BaseRequestTest
end
test "path parameters with invalid UTF8 encoding" do
- request = stub_request(
- "action_dispatch.request.path_parameters" => { foo: "\xBE" }
- )
+ request = stub_request
err = assert_raises(ActionController::BadRequest) do
- request.check_path_parameters!
+ request.path_parameters = { foo: "\xBE" }
end
- assert_match "Invalid parameter encoding", err.message
- assert_match "foo", err.message
- assert_match "\\xBE", err.message
+ assert_predicate err.message, :valid_encoding?
+ assert_equal "Invalid path parameters: Invalid encoding for parameter: �", err.message
end
test "parameters not accessible after rack parse error of invalid UTF8 character" do
@@ -996,10 +1033,10 @@ class RequestParameters < BaseRequestTest
test "parameters not accessible after rack parse error 1" do
request = stub_request(
- 'REQUEST_METHOD' => 'POST',
- 'CONTENT_LENGTH' => "a%=".length,
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded; charset=utf-8',
- 'rack.input' => StringIO.new("a%=")
+ "REQUEST_METHOD" => "POST",
+ "CONTENT_LENGTH" => "a%=".length,
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded; charset=utf-8",
+ "rack.input" => StringIO.new("a%=")
)
assert_raises(ActionController::BadRequest) do
@@ -1021,44 +1058,21 @@ class RequestParameters < BaseRequestTest
end
end
-
class RequestParameterFilter < BaseRequestTest
- test "process parameter filter" do
- test_hashes = [
- [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'],
- [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'],
- [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
- [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
- [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
- [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
- [{'deep'=>{'cc'=>{'code'=>'bar','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},{'deep'=>{'cc'=>{'code'=>'[FILTERED]','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},%w'deep.cc.code'],
- [{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]]
-
- test_hashes.each do |before_filter, after_filter, filter_words|
- parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words)
- assert_equal after_filter, parameter_filter.filter(before_filter)
-
- filter_words << 'blah'
- filter_words << lambda { |key, value|
- value.reverse! if key =~ /bargain/
- }
-
- parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words)
- before_filter['barg'] = {:bargain=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}}
- after_filter['barg'] = {:bargain=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}}
-
- assert_equal after_filter, parameter_filter.filter(before_filter)
+ test "parameter filter is deprecated" do
+ assert_deprecated do
+ ActionDispatch::Http::ParameterFilter.new(["blah"])
end
end
test "filtered_parameters returns params filtered" do
request = stub_request(
- 'action_dispatch.request.parameters' => {
- 'lifo' => 'Pratik',
- 'amount' => '420',
- 'step' => '1'
+ "action_dispatch.request.parameters" => {
+ "lifo" => "Pratik",
+ "amount" => "420",
+ "step" => "1"
},
- 'action_dispatch.parameter_filter' => [:lifo, :amount]
+ "action_dispatch.parameter_filter" => [:lifo, :amount]
)
params = request.filtered_parameters
@@ -1069,12 +1083,12 @@ class RequestParameterFilter < BaseRequestTest
test "filtered_env filters env as a whole" do
request = stub_request(
- 'action_dispatch.request.parameters' => {
- 'amount' => '420',
- 'step' => '1'
+ "action_dispatch.request.parameters" => {
+ "amount" => "420",
+ "step" => "1"
},
"RAW_POST_DATA" => "yada yada",
- 'action_dispatch.parameter_filter' => [:lifo, :amount]
+ "action_dispatch.parameter_filter" => [:lifo, :amount]
)
request = stub_request(request.filtered_env)
@@ -1086,9 +1100,9 @@ class RequestParameterFilter < BaseRequestTest
test "filtered_path returns path with filtered query string" do
%w(; &).each do |sep|
request = stub_request(
- 'QUERY_STRING' => %w(username=sikachu secret=bd4f21f api_key=b1bc3b3cd352f68d79d7).join(sep),
- 'PATH_INFO' => '/authenticate',
- 'action_dispatch.parameter_filter' => [:secret, :api_key]
+ "QUERY_STRING" => %w(username=sikachu secret=bd4f21f api_key=b1bc3b3cd352f68d79d7).join(sep),
+ "PATH_INFO" => "/authenticate",
+ "action_dispatch.parameter_filter" => [:secret, :api_key]
)
path = request.filtered_path
@@ -1098,9 +1112,9 @@ class RequestParameterFilter < BaseRequestTest
test "filtered_path should not unescape a genuine '[FILTERED]' value" do
request = stub_request(
- 'QUERY_STRING' => "secret=bd4f21f&genuine=%5BFILTERED%5D",
- 'PATH_INFO' => '/authenticate',
- 'action_dispatch.parameter_filter' => [:secret]
+ "QUERY_STRING" => "secret=bd4f21f&genuine=%5BFILTERED%5D",
+ "PATH_INFO" => "/authenticate",
+ "action_dispatch.parameter_filter" => [:secret]
)
path = request.filtered_path
@@ -1109,9 +1123,9 @@ class RequestParameterFilter < BaseRequestTest
test "filtered_path should preserve duplication of keys in query string" do
request = stub_request(
- 'QUERY_STRING' => "username=sikachu&secret=bd4f21f&username=fxn",
- 'PATH_INFO' => '/authenticate',
- 'action_dispatch.parameter_filter' => [:secret]
+ "QUERY_STRING" => "username=sikachu&secret=bd4f21f&username=fxn",
+ "PATH_INFO" => "/authenticate",
+ "action_dispatch.parameter_filter" => [:secret]
)
path = request.filtered_path
@@ -1120,9 +1134,9 @@ class RequestParameterFilter < BaseRequestTest
test "filtered_path should ignore searchparts" do
request = stub_request(
- 'QUERY_STRING' => "secret",
- 'PATH_INFO' => '/authenticate',
- 'action_dispatch.parameter_filter' => [:secret]
+ "QUERY_STRING" => "secret",
+ "PATH_INFO" => "/authenticate",
+ "action_dispatch.parameter_filter" => [:secret]
)
path = request.filtered_path
@@ -1131,37 +1145,42 @@ class RequestParameterFilter < BaseRequestTest
end
class RequestEtag < BaseRequestTest
- test "if_none_match_etags none" do
- request = stub_request
+ test "always matches *" do
+ request = stub_request("HTTP_IF_NONE_MATCH" => "*")
- assert_equal nil, request.if_none_match
- assert_equal [], request.if_none_match_etags
- assert !request.etag_matches?("foo")
- assert !request.etag_matches?(nil)
+ assert_equal "*", request.if_none_match
+ assert_equal ["*"], request.if_none_match_etags
+
+ assert request.etag_matches?('"strong"')
+ assert request.etag_matches?('W/"weak"')
+ assert_not request.etag_matches?(nil)
end
- test "if_none_match_etags single" do
- header = 'the-etag'
- request = stub_request('HTTP_IF_NONE_MATCH' => header)
+ test "doesn't match absent If-None-Match" do
+ request = stub_request
- assert_equal header, request.if_none_match
- assert_equal [header], request.if_none_match_etags
- assert request.etag_matches?("the-etag")
+ assert_nil request.if_none_match
+ assert_equal [], request.if_none_match_etags
+
+ assert_not request.etag_matches?("foo")
+ assert_not request.etag_matches?(nil)
end
- test "if_none_match_etags quoted single" do
+ test "matches opaque ETag validators without unquoting" do
header = '"the-etag"'
- request = stub_request('HTTP_IF_NONE_MATCH' => header)
+ request = stub_request("HTTP_IF_NONE_MATCH" => header)
assert_equal header, request.if_none_match
- assert_equal ['the-etag'], request.if_none_match_etags
- assert request.etag_matches?("the-etag")
+ assert_equal ['"the-etag"'], request.if_none_match_etags
+
+ assert request.etag_matches?('"the-etag"')
+ assert_not request.etag_matches?("the-etag")
end
test "if_none_match_etags multiple" do
header = 'etag1, etag2, "third etag", "etag4"'
- expected = ['etag1', 'etag2', 'third etag', 'etag4']
- request = stub_request('HTTP_IF_NONE_MATCH' => header)
+ expected = ["etag1", "etag2", '"third etag"', '"etag4"']
+ request = stub_request("HTTP_IF_NONE_MATCH" => header)
assert_equal header, request.if_none_match
assert_equal expected, request.if_none_match_etags
@@ -1177,62 +1196,77 @@ class RequestVariant < BaseRequestTest
@request = stub_request
end
- test 'setting variant to a symbol' do
+ test "setting variant to a symbol" do
@request.variant = :phone
- assert @request.variant.phone?
- assert_not @request.variant.tablet?
+ assert_predicate @request.variant, :phone?
+ assert_not_predicate @request.variant, :tablet?
assert @request.variant.any?(:phone, :tablet)
assert_not @request.variant.any?(:tablet, :desktop)
end
- test 'setting variant to an array of symbols' do
+ test "setting variant to an array of symbols" do
@request.variant = [:phone, :tablet]
- assert @request.variant.phone?
- assert @request.variant.tablet?
- assert_not @request.variant.desktop?
+ assert_predicate @request.variant, :phone?
+ assert_predicate @request.variant, :tablet?
+ assert_not_predicate @request.variant, :desktop?
assert @request.variant.any?(:tablet, :desktop)
assert_not @request.variant.any?(:desktop, :watch)
end
- test 'clearing variant' do
+ test "clearing variant" do
@request.variant = nil
- assert @request.variant.empty?
- assert_not @request.variant.phone?
+ assert_empty @request.variant
+ assert_not_predicate @request.variant, :phone?
assert_not @request.variant.any?(:phone, :tablet)
end
- test 'setting variant to a non-symbol value' do
+ test "setting variant to a non-symbol value" do
assert_raise ArgumentError do
- @request.variant = 'phone'
+ @request.variant = "phone"
end
end
- test 'setting variant to an array containing a non-symbol value' do
+ test "setting variant to an array containing a non-symbol value" do
assert_raise ArgumentError do
- @request.variant = [:phone, 'tablet']
+ @request.variant = [:phone, "tablet"]
end
end
end
class RequestFormData < BaseRequestTest
- test 'media_type is from the FORM_DATA_MEDIA_TYPES array' do
- assert stub_request('CONTENT_TYPE' => 'application/x-www-form-urlencoded').form_data?
- assert stub_request('CONTENT_TYPE' => 'multipart/form-data').form_data?
+ test "media_type is from the FORM_DATA_MEDIA_TYPES array" do
+ assert_predicate stub_request("CONTENT_TYPE" => "application/x-www-form-urlencoded"), :form_data?
+ assert_predicate stub_request("CONTENT_TYPE" => "multipart/form-data"), :form_data?
+ end
+
+ test "media_type is not from the FORM_DATA_MEDIA_TYPES array" do
+ assert_not_predicate stub_request("CONTENT_TYPE" => "application/xml"), :form_data?
+ assert_not_predicate stub_request("CONTENT_TYPE" => "multipart/related"), :form_data?
end
- test 'media_type is not from the FORM_DATA_MEDIA_TYPES array' do
- assert !stub_request('CONTENT_TYPE' => 'application/xml').form_data?
- assert !stub_request('CONTENT_TYPE' => 'multipart/related').form_data?
+ test "no Content-Type header is provided and the request_method is POST" do
+ request = stub_request("REQUEST_METHOD" => "POST")
+
+ assert_equal "", request.media_type
+ assert_equal "POST", request.request_method
+ assert_not_predicate request, :form_data?
+ end
+end
+
+class EarlyHintsRequestTest < BaseRequestTest
+ def setup
+ super
+ @env["rack.early_hints"] = lambda { |links| links }
+ @request = stub_request
end
- test 'no Content-Type header is provided and the request_method is POST' do
- request = stub_request('REQUEST_METHOD' => 'POST')
+ test "when early hints is set in the env link headers are sent" do
+ early_hints = @request.send_early_hints("Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload")
+ expected_hints = { "Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload" }
- assert_equal '', request.media_type
- assert_equal 'POST', request.request_method
- assert !request.form_data?
+ assert_equal expected_hints, early_hints
end
end
diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb
index c37679bc5f..0f37d074af 100644
--- a/actionpack/test/dispatch/response_test.rb
+++ b/actionpack/test/dispatch/response_test.rb
@@ -1,6 +1,8 @@
-require 'abstract_unit'
-require 'timeout'
-require 'rack/content_length'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "timeout"
+require "rack/content_length"
class ResponseTest < ActiveSupport::TestCase
def setup
@@ -13,13 +15,13 @@ class ResponseTest < ActiveSupport::TestCase
@response.await_commit
}
@response.commit!
- assert @response.committed?
+ assert_predicate @response, :committed?
assert t.join(0.5)
end
def test_stream_close
@response.stream.close
- assert @response.stream.closed?
+ assert_predicate @response.stream, :closed?
end
def test_stream_write
@@ -37,6 +39,60 @@ class ResponseTest < ActiveSupport::TestCase
assert_equal "closed stream", e.message
end
+ def test_each_isnt_called_if_str_body_is_written
+ # Controller writes and reads response body
+ each_counter = 0
+ @response.body = Object.new.tap { |o| o.singleton_class.send(:define_method, :each) { |&block| each_counter += 1; block.call "foo" } }
+ @response["X-Foo"] = @response.body
+
+ assert_equal 1, each_counter, "#each was not called once"
+
+ # Build response
+ status, headers, body = @response.to_a
+
+ assert_equal 200, status
+ assert_equal "foo", headers["X-Foo"]
+ assert_equal "foo", body.each.to_a.join
+
+ # Show that #each was not called twice
+ assert_equal 1, each_counter, "#each was not called once"
+ end
+
+ def test_set_header_after_read_body_during_action
+ @response.body
+
+ # set header after the action reads back @response.body
+ @response["x-header"] = "Best of all possible worlds."
+
+ # the response can be built.
+ status, headers, body = @response.to_a
+ assert_equal 200, status
+ assert_equal "", body.body
+
+ assert_equal "Best of all possible worlds.", headers["x-header"]
+ end
+
+ def test_read_body_during_action
+ @response.body = "Hello, World!"
+
+ # even though there's no explicitly set content-type,
+ assert_nil @response.content_type
+
+ # after the action reads back @response.body,
+ assert_equal "Hello, World!", @response.body
+
+ # the response can be built.
+ status, headers, body = @response.to_a
+ assert_equal 200, status
+ assert_equal({
+ "Content-Type" => "text/html; charset=utf-8"
+ }, headers)
+
+ parts = []
+ body.each { |part| parts << part }
+ assert_equal ["Hello, World!"], parts
+ end
+
def test_response_body_encoding
body = ["hello".encode(Encoding::UTF_8)]
response = ActionDispatch::Response.new 200, {}, body
@@ -45,15 +101,20 @@ class ResponseTest < ActiveSupport::TestCase
end
def test_response_charset_writer
- @response.charset = 'utf-16'
- assert_equal 'utf-16', @response.charset
+ @response.charset = "utf-16"
+ assert_equal "utf-16", @response.charset
@response.charset = nil
- assert_equal 'utf-8', @response.charset
+ assert_equal "utf-8", @response.charset
end
def test_setting_content_type_header_impacts_content_type_method
- @response.headers['Content-Type'] = "application/aaron"
- assert_equal 'application/aaron', @response.content_type
+ @response.headers["Content-Type"] = "application/aaron"
+ assert_equal "application/aaron", @response.content_type
+ end
+
+ def test_empty_content_type_returns_nil
+ @response.headers["Content-Type"] = ""
+ assert_nil @response.content_type
end
test "simple output" do
@@ -71,14 +132,14 @@ class ResponseTest < ActiveSupport::TestCase
end
test "status handled properly in initialize" do
- assert_equal 200, ActionDispatch::Response.new('200 OK').status
+ assert_equal 200, ActionDispatch::Response.new("200 OK").status
end
def test_only_set_charset_still_defaults_to_text_html
response = ActionDispatch::Response.new
response.charset = "utf-16"
- _,headers,_ = response.to_a
- assert_equal "text/html; charset=utf-16", headers['Content-Type']
+ _, headers, _ = response.to_a
+ assert_equal "text/html; charset=utf-16", headers["Content-Type"]
end
test "utf8 output" do
@@ -91,12 +152,32 @@ class ResponseTest < ActiveSupport::TestCase
}, headers)
end
+ test "content length" do
+ [100, 101, 102, 204].each do |c|
+ @response = ActionDispatch::Response.new
+ @response.status = c.to_s
+ @response.set_header "Content-Length", "0"
+ _, headers, _ = @response.to_a
+ assert_not headers.has_key?("Content-Length"), "#{c} must not have a Content-Length header field"
+ end
+ end
+
+ test "does not contain a message-body" do
+ [100, 101, 102, 204, 304].each do |c|
+ @response = ActionDispatch::Response.new
+ @response.status = c.to_s
+ @response.body = "Body must not be included"
+ _, _, body = @response.to_a
+ assert_empty body, "#{c} must not have a message-body but actually contains #{body}"
+ end
+ end
+
test "content type" do
[204, 304].each do |c|
@response = ActionDispatch::Response.new
@response.status = c.to_s
_, headers, _ = @response.to_a
- assert !headers.has_key?("Content-Type"), "#{c} should not have Content-Type header"
+ assert_not headers.has_key?("Content-Type"), "#{c} should not have Content-Type header"
end
[200, 302, 404, 500].each do |c|
@@ -110,7 +191,7 @@ class ResponseTest < ActiveSupport::TestCase
test "does not include Status header" do
@response.status = "200 OK"
_, headers, _ = @response.to_a
- assert !headers.has_key?('Status')
+ assert_not headers.has_key?("Status")
end
test "response code" do
@@ -147,93 +228,111 @@ class ResponseTest < ActiveSupport::TestCase
end
test "cookies" do
- @response.set_cookie("user_name", :value => "david", :path => "/")
+ @response.set_cookie("user_name", value: "david", path: "/")
_status, headers, _body = @response.to_a
assert_equal "user_name=david; path=/", headers["Set-Cookie"]
- assert_equal({"user_name" => "david"}, @response.cookies)
+ assert_equal({ "user_name" => "david" }, @response.cookies)
end
test "multiple cookies" do
- @response.set_cookie("user_name", :value => "david", :path => "/")
- @response.set_cookie("login", :value => "foo&bar", :path => "/", :expires => Time.utc(2005, 10, 10,5))
+ @response.set_cookie("user_name", value: "david", path: "/")
+ @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10, 5))
_status, headers, _body = @response.to_a
assert_equal "user_name=david; path=/\nlogin=foo%26bar; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000", headers["Set-Cookie"]
- assert_equal({"login" => "foo&bar", "user_name" => "david"}, @response.cookies)
+ assert_equal({ "login" => "foo&bar", "user_name" => "david" }, @response.cookies)
end
test "delete cookies" do
- @response.set_cookie("user_name", :value => "david", :path => "/")
- @response.set_cookie("login", :value => "foo&bar", :path => "/", :expires => Time.utc(2005, 10, 10,5))
+ @response.set_cookie("user_name", value: "david", path: "/")
+ @response.set_cookie("login", value: "foo&bar", path: "/", expires: Time.utc(2005, 10, 10, 5))
@response.delete_cookie("login")
- assert_equal({"user_name" => "david", "login" => nil}, @response.cookies)
+ assert_equal({ "user_name" => "david", "login" => nil }, @response.cookies)
end
- test "read cache control" do
+ test "read ETag and Cache-Control" do
resp = ActionDispatch::Response.new.tap { |response|
response.cache_control[:public] = true
- response.etag = '123'
- response.body = 'Hello'
+ response.etag = "123"
+ response.body = "Hello"
}
resp.to_a
- assert_equal('"202cb962ac59075b964b07152d234b70"', resp.etag)
- assert_equal({:public => true}, resp.cache_control)
+ assert_predicate resp, :etag?
+ assert_predicate resp, :weak_etag?
+ assert_not_predicate resp, :strong_etag?
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', resp.etag)
+ assert_equal({ public: true }, resp.cache_control)
+
+ assert_equal("public", resp.headers["Cache-Control"])
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', resp.headers["ETag"])
+ end
- assert_equal('public', resp.headers['Cache-Control'])
- assert_equal('"202cb962ac59075b964b07152d234b70"', resp.headers['ETag'])
+ test "read strong ETag" do
+ resp = ActionDispatch::Response.new.tap { |response|
+ response.cache_control[:public] = true
+ response.strong_etag = "123"
+ response.body = "Hello"
+ }
+ resp.to_a
+
+ assert_predicate resp, :etag?
+ assert_not_predicate resp, :weak_etag?
+ assert_predicate resp, :strong_etag?
+ assert_equal('"202cb962ac59075b964b07152d234b70"', resp.etag)
end
test "read charset and content type" do
resp = ActionDispatch::Response.new.tap { |response|
- response.charset = 'utf-16'
+ response.charset = "utf-16"
response.content_type = Mime[:xml]
- response.body = 'Hello'
+ response.body = "Hello"
}
resp.to_a
- assert_equal('utf-16', resp.charset)
+ assert_equal("utf-16", resp.charset)
assert_equal(Mime[:xml], resp.content_type)
- assert_equal('application/xml; charset=utf-16', resp.headers['Content-Type'])
+ assert_equal("application/xml; charset=utf-16", resp.headers["Content-Type"])
end
test "read content type with default charset utf-8" do
- original = ActionDispatch::Response.default_charset
- begin
- resp = ActionDispatch::Response.new(200, { "Content-Type" => "text/xml" })
- assert_equal('utf-8', resp.charset)
- ensure
- ActionDispatch::Response.default_charset = original
- end
+ resp = ActionDispatch::Response.new(200, "Content-Type" => "text/xml")
+ assert_equal("utf-8", resp.charset)
end
test "read content type with charset utf-16" do
original = ActionDispatch::Response.default_charset
begin
- ActionDispatch::Response.default_charset = 'utf-16'
- resp = ActionDispatch::Response.new(200, { "Content-Type" => "text/xml" })
- assert_equal('utf-16', resp.charset)
+ ActionDispatch::Response.default_charset = "utf-16"
+ resp = ActionDispatch::Response.new(200, "Content-Type" => "text/xml")
+ assert_equal("utf-16", resp.charset)
ensure
ActionDispatch::Response.default_charset = original
end
end
- test "read x_frame_options, x_content_type_options and x_xss_protection" do
+ test "read x_frame_options, x_content_type_options, x_xss_protection, x_download_options and x_permitted_cross_domain_policies, referrer_policy" do
original_default_headers = ActionDispatch::Response.default_headers
begin
ActionDispatch::Response.default_headers = {
- 'X-Frame-Options' => 'DENY',
- 'X-Content-Type-Options' => 'nosniff',
- 'X-XSS-Protection' => '1;'
+ "X-Frame-Options" => "DENY",
+ "X-Content-Type-Options" => "nosniff",
+ "X-XSS-Protection" => "1;",
+ "X-Download-Options" => "noopen",
+ "X-Permitted-Cross-Domain-Policies" => "none",
+ "Referrer-Policy" => "strict-origin-when-cross-origin"
}
resp = ActionDispatch::Response.create.tap { |response|
- response.body = 'Hello'
+ response.body = "Hello"
}
resp.to_a
- assert_equal('DENY', resp.headers['X-Frame-Options'])
- assert_equal('nosniff', resp.headers['X-Content-Type-Options'])
- assert_equal('1;', resp.headers['X-XSS-Protection'])
+ assert_equal("DENY", resp.headers["X-Frame-Options"])
+ assert_equal("nosniff", resp.headers["X-Content-Type-Options"])
+ assert_equal("1;", resp.headers["X-XSS-Protection"])
+ assert_equal("noopen", resp.headers["X-Download-Options"])
+ assert_equal("none", resp.headers["X-Permitted-Cross-Domain-Policies"])
+ assert_equal("strict-origin-when-cross-origin", resp.headers["Referrer-Policy"])
ensure
ActionDispatch::Response.default_headers = original_default_headers
end
@@ -243,32 +342,32 @@ class ResponseTest < ActiveSupport::TestCase
original_default_headers = ActionDispatch::Response.default_headers
begin
ActionDispatch::Response.default_headers = {
- 'X-XX-XXXX' => 'Here is my phone number'
+ "X-XX-XXXX" => "Here is my phone number"
}
resp = ActionDispatch::Response.create.tap { |response|
- response.body = 'Hello'
+ response.body = "Hello"
}
resp.to_a
- assert_equal('Here is my phone number', resp.headers['X-XX-XXXX'])
+ assert_equal("Here is my phone number", resp.headers["X-XX-XXXX"])
ensure
ActionDispatch::Response.default_headers = original_default_headers
end
end
test "respond_to? accepts include_private" do
- assert_not @response.respond_to?(:method_missing)
+ assert_not_respond_to @response, :method_missing
assert @response.respond_to?(:method_missing, true)
end
test "can be explicitly destructured into status, headers and an enumerable body" do
- response = ActionDispatch::Response.new(404, { 'Content-Type' => 'text/plain' }, ['Not Found'])
+ response = ActionDispatch::Response.new(404, { "Content-Type" => "text/plain" }, ["Not Found"])
response.request = ActionDispatch::Request.empty
status, headers, body = *response
assert_equal 404, status
- assert_equal({ 'Content-Type' => 'text/plain' }, headers)
- assert_equal ['Not Found'], body.each.to_a
+ assert_equal({ "Content-Type" => "text/plain" }, headers)
+ assert_equal ["Not Found"], body.each.to_a
end
test "[response.to_a].flatten does not recurse infinitely" do
@@ -281,74 +380,74 @@ class ResponseTest < ActiveSupport::TestCase
end
test "compatibility with Rack::ContentLength" do
- @response.body = 'Hello'
+ @response.body = "Hello"
app = lambda { |env| @response.to_a }
env = Rack::MockRequest.env_for("/")
- status, headers, body = app.call(env)
- assert_nil headers['Content-Length']
+ _status, headers, _body = app.call(env)
+ assert_nil headers["Content-Length"]
- status, headers, body = Rack::ContentLength.new(app).call(env)
- assert_equal '5', headers['Content-Length']
+ _status, headers, _body = Rack::ContentLength.new(app).call(env)
+ assert_equal "5", headers["Content-Length"]
end
end
class ResponseHeadersTest < ActiveSupport::TestCase
def setup
@response = ActionDispatch::Response.create
- @response.set_header 'Foo', '1'
+ @response.set_header "Foo", "1"
end
- test 'has_header?' do
- assert @response.has_header? 'Foo'
- assert_not @response.has_header? 'foo'
+ test "has_header?" do
+ assert @response.has_header? "Foo"
+ assert_not @response.has_header? "foo"
assert_not @response.has_header? nil
end
- test 'get_header' do
- assert_equal '1', @response.get_header('Foo')
- assert_nil @response.get_header('foo')
+ test "get_header" do
+ assert_equal "1", @response.get_header("Foo")
+ assert_nil @response.get_header("foo")
assert_nil @response.get_header(nil)
end
- test 'set_header' do
- assert_equal '2', @response.set_header('Foo', '2')
- assert @response.has_header?('Foo')
- assert_equal '2', @response.get_header('Foo')
+ test "set_header" do
+ assert_equal "2", @response.set_header("Foo", "2")
+ assert @response.has_header?("Foo")
+ assert_equal "2", @response.get_header("Foo")
- assert_nil @response.set_header('Foo', nil)
- assert @response.has_header?('Foo')
- assert_nil @response.get_header('Foo')
+ assert_nil @response.set_header("Foo", nil)
+ assert @response.has_header?("Foo")
+ assert_nil @response.get_header("Foo")
end
- test 'delete_header' do
+ test "delete_header" do
assert_nil @response.delete_header(nil)
- assert_nil @response.delete_header('foo')
- assert @response.has_header?('Foo')
+ assert_nil @response.delete_header("foo")
+ assert @response.has_header?("Foo")
- assert_equal '1', @response.delete_header('Foo')
- assert_not @response.has_header?('Foo')
+ assert_equal "1", @response.delete_header("Foo")
+ assert_not @response.has_header?("Foo")
end
- test 'add_header' do
+ test "add_header" do
# Add a value to an existing header
- assert_equal '1,2', @response.add_header('Foo', '2')
- assert_equal '1,2', @response.get_header('Foo')
+ assert_equal "1,2", @response.add_header("Foo", "2")
+ assert_equal "1,2", @response.get_header("Foo")
# Add nil to an existing header
- assert_equal '1,2', @response.add_header('Foo', nil)
- assert_equal '1,2', @response.get_header('Foo')
+ assert_equal "1,2", @response.add_header("Foo", nil)
+ assert_equal "1,2", @response.get_header("Foo")
# Add nil to a nonexistent header
- assert_nil @response.add_header('Bar', nil)
- assert_not @response.has_header?('Bar')
- assert_nil @response.get_header('Bar')
+ assert_nil @response.add_header("Bar", nil)
+ assert_not @response.has_header?("Bar")
+ assert_nil @response.get_header("Bar")
# Add a value to a nonexistent header
- assert_equal '1', @response.add_header('Bar', '1')
- assert @response.has_header?('Bar')
- assert_equal '1', @response.get_header('Bar')
+ assert_equal "1", @response.add_header("Bar", "1")
+ assert @response.has_header?("Bar")
+ assert_equal "1", @response.get_header("Bar")
end
end
@@ -357,71 +456,87 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
@app = lambda { |env|
ActionDispatch::Response.new.tap { |resp|
resp.cache_control[:public] = true
- resp.etag = '123'
- resp.body = 'Hello'
+ resp.etag = "123"
+ resp.body = "Hello"
resp.request = ActionDispatch::Request.empty
}.to_a
}
- get '/'
+ get "/"
assert_response :success
- assert_equal('public', @response.headers['Cache-Control'])
- assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers['ETag'])
+ assert_equal("public", @response.headers["Cache-Control"])
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', @response.headers["ETag"])
- assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag)
- assert_equal({:public => true}, @response.cache_control)
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', @response.etag)
+ assert_equal({ public: true }, @response.cache_control)
end
test "response cache control from rackish app" do
@app = lambda { |env|
[200,
- {'ETag' => '"202cb962ac59075b964b07152d234b70"',
- 'Cache-Control' => 'public'}, ['Hello']]
+ { "ETag" => 'W/"202cb962ac59075b964b07152d234b70"',
+ "Cache-Control" => "public" }, ["Hello"]]
}
- get '/'
+ get "/"
assert_response :success
- assert_equal('public', @response.headers['Cache-Control'])
- assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers['ETag'])
+ assert_equal("public", @response.headers["Cache-Control"])
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', @response.headers["ETag"])
- assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag)
- assert_equal({:public => true}, @response.cache_control)
+ assert_equal('W/"202cb962ac59075b964b07152d234b70"', @response.etag)
+ assert_equal({ public: true }, @response.cache_control)
end
test "response charset and content type from railsish app" do
@app = lambda { |env|
ActionDispatch::Response.new.tap { |resp|
- resp.charset = 'utf-16'
+ resp.charset = "utf-16"
resp.content_type = Mime[:xml]
- resp.body = 'Hello'
+ resp.body = "Hello"
resp.request = ActionDispatch::Request.empty
}.to_a
}
- get '/'
+ get "/"
assert_response :success
- assert_equal('utf-16', @response.charset)
+ assert_equal("utf-16", @response.charset)
assert_equal(Mime[:xml], @response.content_type)
- assert_equal('application/xml; charset=utf-16', @response.headers['Content-Type'])
+ assert_equal("application/xml; charset=utf-16", @response.headers["Content-Type"])
end
test "response charset and content type from rackish app" do
@app = lambda { |env|
[200,
- {'Content-Type' => 'application/xml; charset=utf-16'},
- ['Hello']]
+ { "Content-Type" => "application/xml; charset=utf-16" },
+ ["Hello"]]
}
- get '/'
+ get "/"
assert_response :success
- assert_equal('utf-16', @response.charset)
+ assert_equal("utf-16", @response.charset)
assert_equal(Mime[:xml], @response.content_type)
- assert_equal('application/xml; charset=utf-16', @response.headers['Content-Type'])
+ assert_equal("application/xml; charset=utf-16", @response.headers["Content-Type"])
+ end
+
+ test "strong ETag validator" do
+ @app = lambda { |env|
+ ActionDispatch::Response.new.tap { |resp|
+ resp.strong_etag = "123"
+ resp.body = "Hello"
+ resp.request = ActionDispatch::Request.empty
+ }.to_a
+ }
+
+ get "/"
+ assert_response :ok
+
+ assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers["ETag"])
+ assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag)
end
end
diff --git a/actionpack/test/dispatch/routing/concerns_test.rb b/actionpack/test/dispatch/routing/concerns_test.rb
index 7ef513b0c8..503a7ccd56 100644
--- a/actionpack/test/dispatch/routing/concerns_test.rb
+++ b/actionpack/test/dispatch/routing/concerns_test.rb
@@ -1,4 +1,8 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class ReviewsController < ResourcesController; end
class RoutingConcernsTest < ActionDispatch::IntegrationTest
class Reviewable
diff --git a/actionpack/test/dispatch/routing/custom_url_helpers_test.rb b/actionpack/test/dispatch/routing/custom_url_helpers_test.rb
new file mode 100644
index 0000000000..a1a1e79884
--- /dev/null
+++ b/actionpack/test/dispatch/routing/custom_url_helpers_test.rb
@@ -0,0 +1,333 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class TestCustomUrlHelpers < ActionDispatch::IntegrationTest
+ class Linkable
+ attr_reader :id
+
+ def self.name
+ super.demodulize
+ end
+
+ def initialize(id)
+ @id = id
+ end
+
+ def linkable_type
+ self.class.name.underscore
+ end
+ end
+
+ class Category < Linkable; end
+ class Collection < Linkable; end
+ class Product < Linkable; end
+ class Manufacturer < Linkable; end
+
+ class Model
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ attr_reader :id
+
+ def initialize(id = nil)
+ @id = id
+ end
+
+ remove_method :model_name
+ def model_name
+ @_model_name ||= ActiveModel::Name.new(self.class, nil, self.class.name.demodulize)
+ end
+
+ def persisted?
+ false
+ end
+ end
+
+ class Basket < Model; end
+ class User < Model; end
+ class Video < Model; end
+
+ class Article
+ attr_reader :id
+
+ def self.name
+ "Article"
+ end
+
+ def initialize(id)
+ @id = id
+ end
+ end
+
+ class Page
+ attr_reader :id
+
+ def self.name
+ super.demodulize
+ end
+
+ def initialize(id)
+ @id = id
+ end
+ end
+
+ class CategoryPage < Page; end
+ class ProductPage < Page; end
+
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw do
+ default_url_options host: "www.example.com"
+
+ root to: "pages#index"
+ get "/basket", to: "basket#show", as: :basket
+ get "/posts/:id", to: "posts#show", as: :post
+ get "/profile", to: "users#profile", as: :profile
+ get "/media/:id", to: "media#show", as: :media
+ get "/pages/:id", to: "pages#show", as: :page
+
+ resources :categories, :collections, :products, :manufacturers
+
+ namespace :admin do
+ get "/dashboard", to: "dashboard#index"
+ end
+
+ direct(:website) { "http://www.rubyonrails.org" }
+ direct("string") { "http://www.rubyonrails.org" }
+ direct(:helper) { basket_url }
+ direct(:linkable) { |linkable| [:"#{linkable.linkable_type}", { id: linkable.id }] }
+ direct(:nested) { |linkable| route_for(:linkable, linkable) }
+ direct(:params) { |params| params }
+ direct(:symbol) { :basket }
+ direct(:hash) { { controller: "basket", action: "show" } }
+ direct(:array) { [:admin, :dashboard] }
+ direct(:options) { |options| [:products, options] }
+ direct(:defaults, size: 10) { |options| [:products, options] }
+
+ direct(:browse, page: 1, size: 10) do |options|
+ [:products, options.merge(params.permit(:page, :size).to_h.symbolize_keys)]
+ end
+
+ resolve("Article") { |article| [:post, { id: article.id }] }
+ resolve("Basket") { |basket| [:basket] }
+ resolve("Manufacturer") { |manufacturer| route_for(:linkable, manufacturer) }
+ resolve("User", anchor: "details") { |user, options| [:profile, options] }
+ resolve("Video") { |video| [:media, { id: video.id }] }
+ resolve(%w[Page CategoryPage ProductPage]) { |page| [:page, { id: page.id }] }
+ end
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ include Routes.url_helpers
+
+ def setup
+ @category = Category.new("1")
+ @collection = Collection.new("2")
+ @product = Product.new("3")
+ @manufacturer = Manufacturer.new("apple")
+ @basket = Basket.new
+ @user = User.new
+ @video = Video.new("4")
+ @article = Article.new("5")
+ @page = Page.new("6")
+ @category_page = CategoryPage.new("7")
+ @product_page = ProductPage.new("8")
+ @path_params = { "controller" => "pages", "action" => "index" }
+ @unsafe_params = ActionController::Parameters.new(@path_params)
+ @safe_params = ActionController::Parameters.new(@path_params).permit(:controller, :action)
+ end
+
+ def params
+ ActionController::Parameters.new(page: 2, size: 25)
+ end
+
+ def test_direct_paths
+ assert_equal "/", website_path
+ assert_equal "/", Routes.url_helpers.website_path
+
+ assert_equal "/", string_path
+ assert_equal "/", Routes.url_helpers.string_path
+
+ assert_equal "/basket", helper_path
+ assert_equal "/basket", Routes.url_helpers.helper_path
+
+ assert_equal "/categories/1", linkable_path(@category)
+ assert_equal "/categories/1", Routes.url_helpers.linkable_path(@category)
+ assert_equal "/collections/2", linkable_path(@collection)
+ assert_equal "/collections/2", Routes.url_helpers.linkable_path(@collection)
+ assert_equal "/products/3", linkable_path(@product)
+ assert_equal "/products/3", Routes.url_helpers.linkable_path(@product)
+
+ assert_equal "/categories/1", nested_path(@category)
+ assert_equal "/categories/1", Routes.url_helpers.nested_path(@category)
+
+ assert_equal "/", params_path(@safe_params)
+ assert_equal "/", Routes.url_helpers.params_path(@safe_params)
+ assert_raises(ActionController::UnfilteredParameters) { params_path(@unsafe_params) }
+ assert_raises(ActionController::UnfilteredParameters) { Routes.url_helpers.params_path(@unsafe_params) }
+
+ assert_equal "/basket", symbol_path
+ assert_equal "/basket", Routes.url_helpers.symbol_path
+ assert_equal "/basket", hash_path
+ assert_equal "/basket", Routes.url_helpers.hash_path
+ assert_equal "/admin/dashboard", array_path
+ assert_equal "/admin/dashboard", Routes.url_helpers.array_path
+
+ assert_equal "/products?page=2", options_path(page: 2)
+ assert_equal "/products?page=2", Routes.url_helpers.options_path(page: 2)
+ assert_equal "/products?size=10", defaults_path
+ assert_equal "/products?size=10", Routes.url_helpers.defaults_path
+ assert_equal "/products?size=20", defaults_path(size: 20)
+ assert_equal "/products?size=20", Routes.url_helpers.defaults_path(size: 20)
+
+ assert_equal "/products?page=2&size=25", browse_path
+ assert_raises(NameError) { Routes.url_helpers.browse_path }
+ end
+
+ def test_direct_urls
+ assert_equal "http://www.rubyonrails.org", website_url
+ assert_equal "http://www.rubyonrails.org", Routes.url_helpers.website_url
+
+ assert_equal "http://www.rubyonrails.org", string_url
+ assert_equal "http://www.rubyonrails.org", Routes.url_helpers.string_url
+
+ assert_equal "http://www.example.com/basket", helper_url
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.helper_url
+
+ assert_equal "http://www.example.com/categories/1", linkable_url(@category)
+ assert_equal "http://www.example.com/categories/1", Routes.url_helpers.linkable_url(@category)
+ assert_equal "http://www.example.com/collections/2", linkable_url(@collection)
+ assert_equal "http://www.example.com/collections/2", Routes.url_helpers.linkable_url(@collection)
+ assert_equal "http://www.example.com/products/3", linkable_url(@product)
+ assert_equal "http://www.example.com/products/3", Routes.url_helpers.linkable_url(@product)
+
+ assert_equal "http://www.example.com/categories/1", nested_url(@category)
+ assert_equal "http://www.example.com/categories/1", Routes.url_helpers.nested_url(@category)
+
+ assert_equal "http://www.example.com/", params_url(@safe_params)
+ assert_equal "http://www.example.com/", Routes.url_helpers.params_url(@safe_params)
+ assert_raises(ActionController::UnfilteredParameters) { params_url(@unsafe_params) }
+ assert_raises(ActionController::UnfilteredParameters) { Routes.url_helpers.params_url(@unsafe_params) }
+
+ assert_equal "http://www.example.com/basket", symbol_url
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.symbol_url
+ assert_equal "http://www.example.com/basket", hash_url
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.hash_url
+ assert_equal "http://www.example.com/admin/dashboard", array_url
+ assert_equal "http://www.example.com/admin/dashboard", Routes.url_helpers.array_url
+
+ assert_equal "http://www.example.com/products?page=2", options_url(page: 2)
+ assert_equal "http://www.example.com/products?page=2", Routes.url_helpers.options_url(page: 2)
+ assert_equal "http://www.example.com/products?size=10", defaults_url
+ assert_equal "http://www.example.com/products?size=10", Routes.url_helpers.defaults_url
+ assert_equal "http://www.example.com/products?size=20", defaults_url(size: 20)
+ assert_equal "http://www.example.com/products?size=20", Routes.url_helpers.defaults_url(size: 20)
+
+ assert_equal "http://www.example.com/products?page=2&size=25", browse_url
+ assert_raises(NameError) { Routes.url_helpers.browse_url }
+ end
+
+ def test_resolve_paths
+ assert_equal "/basket", polymorphic_path(@basket)
+ assert_equal "/basket", Routes.url_helpers.polymorphic_path(@basket)
+
+ assert_equal "/profile#details", polymorphic_path(@user)
+ assert_equal "/profile#details", Routes.url_helpers.polymorphic_path(@user)
+
+ assert_equal "/profile#password", polymorphic_path(@user, anchor: "password")
+ assert_equal "/profile#password", Routes.url_helpers.polymorphic_path(@user, anchor: "password")
+
+ assert_equal "/media/4", polymorphic_path(@video)
+ assert_equal "/media/4", Routes.url_helpers.polymorphic_path(@video)
+ assert_equal "/media/4", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call(self, @video)
+
+ assert_equal "/posts/5", polymorphic_path(@article)
+ assert_equal "/posts/5", Routes.url_helpers.polymorphic_path(@article)
+ assert_equal "/posts/5", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call(self, @article)
+
+ assert_equal "/pages/6", polymorphic_path(@page)
+ assert_equal "/pages/6", Routes.url_helpers.polymorphic_path(@page)
+ assert_equal "/pages/6", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call(self, @page)
+
+ assert_equal "/pages/7", polymorphic_path(@category_page)
+ assert_equal "/pages/7", Routes.url_helpers.polymorphic_path(@category_page)
+ assert_equal "/pages/7", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call(self, @category_page)
+
+ assert_equal "/pages/8", polymorphic_path(@product_page)
+ assert_equal "/pages/8", Routes.url_helpers.polymorphic_path(@product_page)
+ assert_equal "/pages/8", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call(self, @product_page)
+
+ assert_equal "/manufacturers/apple", polymorphic_path(@manufacturer)
+ assert_equal "/manufacturers/apple", Routes.url_helpers.polymorphic_path(@manufacturer)
+ end
+
+ def test_resolve_urls
+ assert_equal "http://www.example.com/basket", polymorphic_url(@basket)
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.polymorphic_url(@basket)
+ assert_equal "http://www.example.com/basket", polymorphic_url(@basket)
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.polymorphic_url(@basket)
+
+ assert_equal "http://www.example.com/profile#details", polymorphic_url(@user)
+ assert_equal "http://www.example.com/profile#details", Routes.url_helpers.polymorphic_url(@user)
+
+ assert_equal "http://www.example.com/profile#password", polymorphic_url(@user, anchor: "password")
+ assert_equal "http://www.example.com/profile#password", Routes.url_helpers.polymorphic_url(@user, anchor: "password")
+
+ assert_equal "http://www.example.com/media/4", polymorphic_url(@video)
+ assert_equal "http://www.example.com/media/4", Routes.url_helpers.polymorphic_url(@video)
+ assert_equal "http://www.example.com/media/4", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.url.handle_model_call(self, @video)
+
+ assert_equal "http://www.example.com/posts/5", polymorphic_url(@article)
+ assert_equal "http://www.example.com/posts/5", Routes.url_helpers.polymorphic_url(@article)
+ assert_equal "http://www.example.com/posts/5", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.url.handle_model_call(self, @article)
+
+ assert_equal "http://www.example.com/pages/6", polymorphic_url(@page)
+ assert_equal "http://www.example.com/pages/6", Routes.url_helpers.polymorphic_url(@page)
+ assert_equal "http://www.example.com/pages/6", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.url.handle_model_call(self, @page)
+
+ assert_equal "http://www.example.com/pages/7", polymorphic_url(@category_page)
+ assert_equal "http://www.example.com/pages/7", Routes.url_helpers.polymorphic_url(@category_page)
+ assert_equal "http://www.example.com/pages/7", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.url.handle_model_call(self, @category_page)
+
+ assert_equal "http://www.example.com/pages/8", polymorphic_url(@product_page)
+ assert_equal "http://www.example.com/pages/8", Routes.url_helpers.polymorphic_url(@product_page)
+ assert_equal "http://www.example.com/pages/8", ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.url.handle_model_call(self, @product_page)
+
+ assert_equal "http://www.example.com/manufacturers/apple", polymorphic_url(@manufacturer)
+ assert_equal "http://www.example.com/manufacturers/apple", Routes.url_helpers.polymorphic_url(@manufacturer)
+ end
+
+ def test_defining_direct_inside_a_scope_raises_runtime_error
+ routes = ActionDispatch::Routing::RouteSet.new
+
+ assert_raises RuntimeError do
+ routes.draw do
+ namespace :admin do
+ direct(:rubyonrails) { "http://www.rubyonrails.org" }
+ end
+ end
+ end
+ end
+
+ def test_defining_resolve_inside_a_scope_raises_runtime_error
+ routes = ActionDispatch::Routing::RouteSet.new
+
+ assert_raises RuntimeError do
+ routes.draw do
+ namespace :admin do
+ resolve("User") { "/profile" }
+ end
+ end
+ end
+ end
+
+ def test_defining_direct_url_registers_helper_method
+ assert_equal "http://www.example.com/basket", Routes.url_helpers.symbol_url
+ assert_equal true, Routes.named_routes.route_defined?(:symbol_url), "'symbol_url' named helper not found"
+ assert_equal true, Routes.named_routes.route_defined?(:symbol_path), "'symbol_path' named helper not found"
+ end
+end
diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb
index a17d07c40b..fe1f1995d8 100644
--- a/actionpack/test/dispatch/routing/inspector_test.rb
+++ b/actionpack/test/dispatch/routing/inspector_test.rb
@@ -1,25 +1,25 @@
-require 'abstract_unit'
-require 'rails/engine'
-require 'action_dispatch/routing/inspector'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rails/engine"
+require "action_dispatch/routing/inspector"
+require "io/console/size"
class MountedRackApp
def self.call(env)
end
end
+class Rails::DummyController
+end
+
module ActionDispatch
module Routing
class RoutesInspectorTest < ActiveSupport::TestCase
- def setup
+ setup do
@set = ActionDispatch::Routing::RouteSet.new
end
- def draw(options = {}, &block)
- @set.draw(&block)
- inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes)
- inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options[:filter]).split("\n")
- end
-
def test_displaying_routes_for_engines
engine = Class.new(Rails::Engine) do
def self.inspect
@@ -27,11 +27,11 @@ module ActionDispatch
end
end
engine.routes.draw do
- get '/cart', :to => 'cart#show'
+ get "/cart", to: "cart#show"
end
output = draw do
- get '/custom/assets', :to => 'custom_assets#show'
+ get "/custom/assets", to: "custom_assets#show"
mount engine => "/blog", :as => "blog"
end
@@ -68,7 +68,7 @@ module ActionDispatch
def test_cart_inspect
output = draw do
- get '/cart', :to => 'cart#show'
+ get "/cart", to: "cart#show"
end
assert_equal [
@@ -79,7 +79,7 @@ module ActionDispatch
def test_articles_inspect_with_multiple_verbs
output = draw do
- match 'articles/:id', to: 'articles#update', via: [:put, :patch]
+ match "articles/:id", to: "articles#update", via: [:put, :patch]
end
assert_equal [
@@ -90,7 +90,7 @@ module ActionDispatch
def test_inspect_shows_custom_assets
output = draw do
- get '/custom/assets', :to => 'custom_assets#show'
+ get "/custom/assets", to: "custom_assets#show"
end
assert_equal [
@@ -119,7 +119,7 @@ module ActionDispatch
def test_inspect_routes_shows_root_route
output = draw do
- root :to => 'pages#main'
+ root to: "pages#main"
end
assert_equal [
@@ -130,7 +130,9 @@ module ActionDispatch
def test_inspect_routes_shows_dynamic_action_route
output = draw do
- get 'api/:action' => 'api'
+ ActiveSupport::Deprecation.silence do
+ get "api/:action" => "api"
+ end
end
assert_equal [
@@ -141,7 +143,9 @@ module ActionDispatch
def test_inspect_routes_shows_controller_and_action_only_route
output = draw do
- get ':controller/:action'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
end
assert_equal [
@@ -152,7 +156,9 @@ module ActionDispatch
def test_inspect_routes_shows_controller_and_action_route_with_constraints
output = draw do
- get ':controller(/:action(/:id))', :id => /\d+/
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))", id: /\d+/
+ end
end
assert_equal [
@@ -161,20 +167,20 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_route_with_defaults
+ def test_rails_routes_shows_route_with_defaults
output = draw do
- get 'photos/:id' => 'photos#show', :defaults => {:format => 'jpg'}
+ get "photos/:id" => "photos#show", :defaults => { format: "jpg" }
end
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
- %Q[ GET /photos/:id(.:format) photos#show {:format=>"jpg"}]
+ ' GET /photos/:id(.:format) photos#show {:format=>"jpg"}'
], output
end
- def test_rake_routes_shows_route_with_constraints
+ def test_rails_routes_shows_route_with_constraints
output = draw do
- get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
end
assert_equal [
@@ -183,15 +189,15 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_routes_with_dashes
+ def test_rails_routes_shows_routes_with_dashes
output = draw do
- get 'about-us' => 'pages#about_us'
- get 'our-work/latest'
+ get "about-us" => "pages#about_us"
+ get "our-work/latest"
resources :photos, only: [:show] do
- get 'user-favorites', on: :collection
- get 'preview-photo', on: :member
- get 'summary-text'
+ get "user-favorites", on: :collection
+ get "preview-photo", on: :member
+ get "summary-text"
end
end
@@ -206,9 +212,9 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_route_with_rack_app
+ def test_rails_routes_shows_route_with_rack_app
output = draw do
- get 'foo/:id' => MountedRackApp, :id => /[A-Z]\d{5}/
+ get "foo/:id" => MountedRackApp, :id => /[A-Z]\d{5}/
end
assert_equal [
@@ -217,9 +223,9 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_named_route_with_mounted_rack_app
+ def test_rails_routes_shows_named_route_with_mounted_rack_app
output = draw do
- mount MountedRackApp => '/foo'
+ mount MountedRackApp => "/foo"
end
assert_equal [
@@ -228,9 +234,9 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_overridden_named_route_with_mounted_rack_app_with_name
+ def test_rails_routes_shows_overridden_named_route_with_mounted_rack_app_with_name
output = draw do
- mount MountedRackApp => '/foo', as: 'blog'
+ mount MountedRackApp => "/foo", as: "blog"
end
assert_equal [
@@ -239,7 +245,7 @@ module ActionDispatch
], output
end
- def test_rake_routes_shows_route_with_rack_app_nested_with_dynamic_constraints
+ def test_rails_routes_shows_route_with_rack_app_nested_with_dynamic_constraints
constraint = Class.new do
def inspect
"( my custom constraint )"
@@ -247,8 +253,8 @@ module ActionDispatch
end
output = draw do
- scope :constraint => constraint.new do
- mount MountedRackApp => '/foo'
+ scope constraint: constraint.new do
+ mount MountedRackApp => "/foo"
end
end
@@ -258,18 +264,18 @@ module ActionDispatch
], output
end
- def test_rake_routes_dont_show_app_mounted_in_assets_prefix
+ def test_rails_routes_dont_show_app_mounted_in_assets_prefix
output = draw do
- get '/sprockets' => MountedRackApp
+ get "/sprockets" => MountedRackApp
end
assert_no_match(/MountedRackApp/, output.first)
assert_no_match(/\/sprockets/, output.first)
end
- def test_rake_routes_shows_route_defined_in_under_assets_prefix
+ def test_rails_routes_shows_route_defined_in_under_assets_prefix
output = draw do
- scope '/sprockets' do
- get '/foo' => 'foo#bar'
+ scope "/sprockets" do
+ get "/foo" => "foo#bar"
end
end
assert_equal [
@@ -280,9 +286,9 @@ module ActionDispatch
def test_redirect
output = draw do
- get "/foo" => redirect("/foo/bar"), :constraints => { :subdomain => "admin" }
+ get "/foo" => redirect("/foo/bar"), :constraints => { subdomain: "admin" }
get "/bar" => redirect(path: "/foo/bar", status: 307)
- get "/foobar" => redirect{ "/foo/bar" }
+ get "/foobar" => redirect { "/foo/bar" }
end
assert_equal [
@@ -294,7 +300,7 @@ module ActionDispatch
end
def test_routes_can_be_filtered
- output = draw(filter: 'posts') do
+ output = draw(grep: "posts") do
resources :articles
resources :posts
end
@@ -310,20 +316,109 @@ module ActionDispatch
" DELETE /posts/:id(.:format) posts#destroy"], output
end
+ def test_routes_when_expanded
+ previous_console_winsize = IO.console.winsize
+ IO.console.winsize = [0, 23]
+
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ end
+
+ output = draw(formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "/custom/assets", to: "custom_assets#show"
+ get "/custom/furnitures", to: "custom_furnitures#show"
+ mount engine => "/blog", :as => "blog"
+ end
+
+ assert_equal ["--[ Route 1 ]----------",
+ "Prefix | custom_assets",
+ "Verb | GET",
+ "URI | /custom/assets(.:format)",
+ "Controller#Action | custom_assets#show",
+ "--[ Route 2 ]----------",
+ "Prefix | custom_furnitures",
+ "Verb | GET",
+ "URI | /custom/furnitures(.:format)",
+ "Controller#Action | custom_furnitures#show",
+ "--[ Route 3 ]----------",
+ "Prefix | blog",
+ "Verb | ",
+ "URI | /blog",
+ "Controller#Action | Blog::Engine",
+ "",
+ "[ Routes for Blog::Engine ]",
+ "--[ Route 1 ]----------",
+ "Prefix | cart",
+ "Verb | GET",
+ "URI | /cart(.:format)",
+ "Controller#Action | cart#show"], output
+ ensure
+ IO.console.winsize = previous_console_winsize
+ end
+
+ def test_no_routes_matched_filter_when_expanded
+ output = draw(grep: "rails/dummy", formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this grep pattern.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_not_routes_when_expanded
+ output = draw(grep: "rails/dummy", formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) { }
+
+ assert_equal [
+ "You don't have any routes defined!",
+ "",
+ "Please add some routes in config/routes.rb.",
+ "",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_routes_can_be_filtered_with_namespaced_controllers
+ output = draw(grep: "admin/posts") do
+ resources :articles
+ namespace :admin do
+ resources :posts
+ end
+ end
+
+ assert_equal [" Prefix Verb URI Pattern Controller#Action",
+ " admin_posts GET /admin/posts(.:format) admin/posts#index",
+ " POST /admin/posts(.:format) admin/posts#create",
+ " new_admin_post GET /admin/posts/new(.:format) admin/posts#new",
+ "edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit",
+ " admin_post GET /admin/posts/:id(.:format) admin/posts#show",
+ " PATCH /admin/posts/:id(.:format) admin/posts#update",
+ " PUT /admin/posts/:id(.:format) admin/posts#update",
+ " DELETE /admin/posts/:id(.:format) admin/posts#destroy"], output
+ end
+
def test_regression_route_with_controller_regexp
output = draw do
- get ':controller(/:action)', controller: /api\/[^\/]+/, format: false
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action)", controller: /api\/[^\/]+/, format: false
+ end
end
assert_equal ["Prefix Verb URI Pattern Controller#Action",
- " GET /:controller(/:action) (?-mix:api\\/[^\\/]+)#:action"], output
+ " GET /:controller(/:action) :controller#:action"], output
end
def test_inspect_routes_shows_resources_route_when_assets_disabled
@set = ActionDispatch::Routing::RouteSet.new
output = draw do
- get '/cart', to: 'cart#show'
+ get "/cart", to: "cart#show"
end
assert_equal [
@@ -331,6 +426,70 @@ module ActionDispatch
" cart GET /cart(.:format) cart#show"
], output
end
+
+ def test_routes_with_undefined_filter
+ output = draw(controller: "Rails::MissingController") do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this controller.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_no_routes_matched_filter
+ output = draw(grep: "rails/dummy") do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this grep pattern.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_no_routes_were_defined
+ output = draw(grep: "Rails::DummyController") { }
+
+ assert_equal [
+ "You don't have any routes defined!",
+ "",
+ "Please add some routes in config/routes.rb.",
+ "",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_displaying_routes_for_internal_engines
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ post "/cart", to: "cart#create"
+ patch "/cart", to: "cart#update"
+ end
+
+ output = draw do
+ get "/custom/assets", to: "custom_assets#show"
+ mount engine => "/blog", as: "blog", internal: true
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "custom_assets GET /custom/assets(.:format) custom_assets#show",
+ ], output
+ end
+
+ private
+ def draw(formatter: ActionDispatch::Routing::ConsoleFormatter::Sheet.new, **options, &block)
+ @set.draw(&block)
+ inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes)
+ inspector.format(formatter, options).split("\n")
+ end
end
end
end
diff --git a/actionpack/test/dispatch/routing/ipv6_redirect_test.rb b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb
index f1b2e8cfc7..31559bffc7 100644
--- a/actionpack/test/dispatch/routing/ipv6_redirect_test.rb
+++ b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class IPv6IntegrationTest < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new
@@ -7,17 +9,17 @@ class IPv6IntegrationTest < ActionDispatch::IntegrationTest
class ::BadRouteRequestController < ActionController::Base
include Routes.url_helpers
def index
- render :text => foo_path
+ render plain: foo_path
end
def foo
- redirect_to :action => :index
+ redirect_to action: :index
end
end
Routes.draw do
- get "/", :to => 'bad_route_request#index', :as => :index
- get "/foo", :to => "bad_route_request#foo", :as => :foo
+ get "/", to: "bad_route_request#index", as: :index
+ get "/foo", to: "bad_route_request#foo", as: :foo
end
def _routes
@@ -32,14 +34,13 @@ class IPv6IntegrationTest < ActionDispatch::IntegrationTest
test "bad IPv6 redirection" do
# def test_simple_redirect
request_env = {
- 'REMOTE_ADDR' => 'fd07:2fa:6cff:2112:225:90ff:fec7:22aa',
- 'HTTP_HOST' => '[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000',
- 'SERVER_NAME' => '[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]',
- 'SERVER_PORT' => 3000 }
+ "REMOTE_ADDR" => "fd07:2fa:6cff:2112:225:90ff:fec7:22aa",
+ "HTTP_HOST" => "[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000",
+ "SERVER_NAME" => "[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]",
+ "SERVER_PORT" => 3000 }
- get '/foo', env: request_env
+ get "/foo", env: request_env
assert_response :redirect
- assert_equal 'http://[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000/', redirect_to_url
+ assert_equal "http://[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000/", redirect_to_url
end
-
end
diff --git a/actionpack/test/dispatch/routing/route_set_test.rb b/actionpack/test/dispatch/routing/route_set_test.rb
index 9327fe12c6..e61d47b160 100644
--- a/actionpack/test/dispatch/routing/route_set_test.rb
+++ b/actionpack/test/dispatch/routing/route_set_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Routing
@@ -9,7 +11,7 @@ module ActionDispatch
end
def call(env)
- [ 200, { 'Content-Type' => 'text/plain' }, [response] ]
+ [ 200, { "Content-Type" => "text/plain" }, [response] ]
end
end
@@ -21,7 +23,7 @@ module ActionDispatch
assert empty?
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
assert_not empty?
@@ -29,101 +31,101 @@ module ActionDispatch
test "url helpers are added when route is added" do
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
- assert_equal '/foo', url_helpers.foo_path
+ assert_equal "/foo", url_helpers.foo_path
assert_raises NoMethodError do
- assert_equal '/bar', url_helpers.bar_path
+ assert_equal "/bar", url_helpers.bar_path
end
draw do
- get 'foo', to: SimpleApp.new('foo#index')
- get 'bar', to: SimpleApp.new('bar#index')
+ get "foo", to: SimpleApp.new("foo#index")
+ get "bar", to: SimpleApp.new("bar#index")
end
- assert_equal '/foo', url_helpers.foo_path
- assert_equal '/bar', url_helpers.bar_path
+ assert_equal "/foo", url_helpers.foo_path
+ assert_equal "/bar", url_helpers.bar_path
end
test "url helpers are updated when route is updated" do
draw do
- get 'bar', to: SimpleApp.new('bar#index'), as: :bar
+ get "bar", to: SimpleApp.new("bar#index"), as: :bar
end
- assert_equal '/bar', url_helpers.bar_path
+ assert_equal "/bar", url_helpers.bar_path
draw do
- get 'baz', to: SimpleApp.new('baz#index'), as: :bar
+ get "baz", to: SimpleApp.new("baz#index"), as: :bar
end
- assert_equal '/baz', url_helpers.bar_path
+ assert_equal "/baz", url_helpers.bar_path
end
test "url helpers are removed when route is removed" do
draw do
- get 'foo', to: SimpleApp.new('foo#index')
- get 'bar', to: SimpleApp.new('bar#index')
+ get "foo", to: SimpleApp.new("foo#index")
+ get "bar", to: SimpleApp.new("bar#index")
end
- assert_equal '/foo', url_helpers.foo_path
- assert_equal '/bar', url_helpers.bar_path
+ assert_equal "/foo", url_helpers.foo_path
+ assert_equal "/bar", url_helpers.bar_path
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
- assert_equal '/foo', url_helpers.foo_path
+ assert_equal "/foo", url_helpers.foo_path
assert_raises NoMethodError do
- assert_equal '/bar', url_helpers.bar_path
+ assert_equal "/bar", url_helpers.bar_path
end
end
test "only_path: true with *_url and no :host option" do
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
- assert_equal '/foo', url_helpers.foo_url(only_path: true)
+ assert_equal "/foo", url_helpers.foo_url(only_path: true)
end
test "only_path: false with *_url and no :host option" do
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
assert_raises ArgumentError do
- assert_equal 'http://example.com/foo', url_helpers.foo_url(only_path: false)
+ assert_equal "http://example.com/foo", url_helpers.foo_url(only_path: false)
end
end
test "only_path: false with *_url and local :host option" do
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
- assert_equal 'http://example.com/foo', url_helpers.foo_url(only_path: false, host: 'example.com')
+ assert_equal "http://example.com/foo", url_helpers.foo_url(only_path: false, host: "example.com")
end
test "only_path: false with *_url and global :host option" do
- @set.default_url_options = { host: 'example.com' }
+ @set.default_url_options = { host: "example.com" }
draw do
- get 'foo', to: SimpleApp.new('foo#index')
+ get "foo", to: SimpleApp.new("foo#index")
end
- assert_equal 'http://example.com/foo', url_helpers.foo_url(only_path: false)
+ assert_equal "http://example.com/foo", url_helpers.foo_url(only_path: false)
end
test "explicit keys win over implicit keys" do
draw do
resources :foo do
- resources :bar, to: SimpleApp.new('foo#show')
+ resources :bar, to: SimpleApp.new("foo#show")
end
end
- assert_equal '/foo/1/bar/2', url_helpers.foo_bar_path(1, 2)
- assert_equal '/foo/1/bar/2', url_helpers.foo_bar_path(2, foo_id: 1)
+ assert_equal "/foo/1/bar/2", url_helpers.foo_bar_path(1, 2)
+ assert_equal "/foo/1/bar/2", url_helpers.foo_bar_path(2, foo_id: 1)
end
test "having an optional scope with resources" do
@@ -133,9 +135,18 @@ module ActionDispatch
end
end
- assert_equal '/users/1', url_helpers.user_path(1)
- assert_equal '/users/1', url_helpers.user_path(1, foo: nil)
- assert_equal '/a/users/1', url_helpers.user_path(1, foo: 'a')
+ assert_equal "/users/1", url_helpers.user_path(1)
+ assert_equal "/users/1", url_helpers.user_path(1, foo: nil)
+ assert_equal "/a/users/1", url_helpers.user_path(1, foo: "a")
+ end
+
+ test "implicit path components consistently return the same result" do
+ draw do
+ resources :users, to: SimpleApp.new("foo#index")
+ end
+ assert_equal "/users/1.json", url_helpers.user_path(1, :json)
+ assert_equal "/users/1.json", url_helpers.user_path(1, format: :json)
+ assert_equal "/users/1.json", url_helpers.user_path(1, :json)
end
private
diff --git a/actionpack/test/dispatch/routing_assertions_test.rb b/actionpack/test/dispatch/routing_assertions_test.rb
index 56ea644f22..009b6d9bc3 100644
--- a/actionpack/test/dispatch/routing_assertions_test.rb
+++ b/actionpack/test/dispatch/routing_assertions_test.rb
@@ -1,130 +1,208 @@
-require 'abstract_unit'
-require 'controller/fake_controllers'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rails/engine"
+require "controller/fake_controllers"
class SecureArticlesController < ArticlesController; end
class BlockArticlesController < ArticlesController; end
class QueryArticlesController < ArticlesController; end
-class RoutingAssertionsTest < ActionController::TestCase
+class SecureBooksController < BooksController; end
+class BlockBooksController < BooksController; end
+class QueryBooksController < BooksController; end
+class RoutingAssertionsTest < ActionController::TestCase
def setup
+ engine = Class.new(Rails::Engine) do
+ def self.name
+ "blog_engine"
+ end
+ end
+ engine.routes.draw do
+ resources :books
+
+ scope "secure", constraints: { protocol: "https://" } do
+ resources :books, controller: "secure_books"
+ end
+
+ scope "block", constraints: lambda { |r| r.ssl? } do
+ resources :books, controller: "block_books"
+ end
+
+ scope "query", constraints: lambda { |r| r.params[:use_query] == "true" } do
+ resources :books, controller: "query_books"
+ end
+ end
+
@routes = ActionDispatch::Routing::RouteSet.new
@routes.draw do
resources :articles
- scope 'secure', :constraints => { :protocol => 'https://' } do
- resources :articles, :controller => 'secure_articles'
+ scope "secure", constraints: { protocol: "https://" } do
+ resources :articles, controller: "secure_articles"
end
- scope 'block', :constraints => lambda { |r| r.ssl? } do
- resources :articles, :controller => 'block_articles'
+ scope "block", constraints: lambda { |r| r.ssl? } do
+ resources :articles, controller: "block_articles"
end
- scope 'query', :constraints => lambda { |r| r.params[:use_query] == 'true' } do
- resources :articles, :controller => 'query_articles'
+ scope "query", constraints: lambda { |r| r.params[:use_query] == "true" } do
+ resources :articles, controller: "query_articles"
end
+
+ mount engine => "/shelf"
+
+ get "/shelf/foo", controller: "query_articles", action: "index"
end
end
def test_assert_generates
- assert_generates('/articles', { :controller => 'articles', :action => 'index' })
- assert_generates('/articles/1', { :controller => 'articles', :action => 'show', :id => '1' })
+ assert_generates("/articles", controller: "articles", action: "index")
+ assert_generates("/articles/1", controller: "articles", action: "show", id: "1")
end
def test_assert_generates_with_defaults
- assert_generates('/articles/1/edit', { :controller => 'articles', :action => 'edit' }, { :id => '1' })
+ assert_generates("/articles/1/edit", { controller: "articles", action: "edit" }, { id: "1" })
end
def test_assert_generates_with_extras
- assert_generates('/articles', { :controller => 'articles', :action => 'index', :page => '1' }, {}, { :page => '1' })
+ assert_generates("/articles", { controller: "articles", action: "index", page: "1" }, {}, { page: "1" })
end
def test_assert_recognizes
- assert_recognizes({ :controller => 'articles', :action => 'index' }, '/articles')
- assert_recognizes({ :controller => 'articles', :action => 'show', :id => '1' }, '/articles/1')
+ assert_recognizes({ controller: "articles", action: "index" }, "/articles")
+ assert_recognizes({ controller: "articles", action: "show", id: "1" }, "/articles/1")
end
def test_assert_recognizes_with_extras
- assert_recognizes({ :controller => 'articles', :action => 'index', :page => '1' }, '/articles', { :page => '1' })
+ assert_recognizes({ controller: "articles", action: "index", page: "1" }, "/articles", page: "1")
end
def test_assert_recognizes_with_method
- assert_recognizes({ :controller => 'articles', :action => 'create' }, { :path => '/articles', :method => :post })
- assert_recognizes({ :controller => 'articles', :action => 'update', :id => '1' }, { :path => '/articles/1', :method => :put })
+ assert_recognizes({ controller: "articles", action: "create" }, { path: "/articles", method: :post })
+ assert_recognizes({ controller: "articles", action: "update", id: "1" }, { path: "/articles/1", method: :put })
end
def test_assert_recognizes_with_hash_constraint
assert_raise(Assertion) do
- assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'http://test.host/secure/articles')
+ assert_recognizes({ controller: "secure_articles", action: "index" }, "http://test.host/secure/articles")
end
- assert_recognizes({ :controller => 'secure_articles', :action => 'index', :protocol => 'https://' }, 'https://test.host/secure/articles')
+ assert_recognizes({ controller: "secure_articles", action: "index", protocol: "https://" }, "https://test.host/secure/articles")
end
def test_assert_recognizes_with_block_constraint
assert_raise(Assertion) do
- assert_recognizes({ :controller => 'block_articles', :action => 'index' }, 'http://test.host/block/articles')
+ assert_recognizes({ controller: "block_articles", action: "index" }, "http://test.host/block/articles")
end
- assert_recognizes({ :controller => 'block_articles', :action => 'index' }, 'https://test.host/block/articles')
+ assert_recognizes({ controller: "block_articles", action: "index" }, "https://test.host/block/articles")
end
def test_assert_recognizes_with_query_constraint
assert_raise(Assertion) do
- assert_recognizes({ :controller => 'query_articles', :action => 'index', :use_query => 'false' }, '/query/articles', { :use_query => 'false' })
+ assert_recognizes({ controller: "query_articles", action: "index", use_query: "false" }, "/query/articles", use_query: "false")
end
- assert_recognizes({ :controller => 'query_articles', :action => 'index', :use_query => 'true' }, '/query/articles', { :use_query => 'true' })
+ assert_recognizes({ controller: "query_articles", action: "index", use_query: "true" }, "/query/articles", use_query: "true")
end
def test_assert_recognizes_raises_message
err = assert_raise(Assertion) do
- assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'http://test.host/secure/articles', {}, "This is a really bad msg")
+ assert_recognizes({ controller: "secure_articles", action: "index" }, "http://test.host/secure/articles", {}, "This is a really bad msg")
end
assert_match err.message, "This is a really bad msg"
end
+ def test_assert_recognizes_with_engine
+ assert_recognizes({ controller: "books", action: "index" }, "/shelf/books")
+ assert_recognizes({ controller: "books", action: "show", id: "1" }, "/shelf/books/1")
+ end
+
+ def test_assert_recognizes_with_engine_and_extras
+ assert_recognizes({ controller: "books", action: "index", page: "1" }, "/shelf/books", page: "1")
+ end
+
+ def test_assert_recognizes_with_engine_and_method
+ assert_recognizes({ controller: "books", action: "create" }, { path: "/shelf/books", method: :post })
+ assert_recognizes({ controller: "books", action: "update", id: "1" }, { path: "/shelf/books/1", method: :put })
+ end
+
+ def test_assert_recognizes_with_engine_and_hash_constraint
+ assert_raise(Assertion) do
+ assert_recognizes({ controller: "secure_books", action: "index" }, "http://test.host/shelf/secure/books")
+ end
+ assert_recognizes({ controller: "secure_books", action: "index", protocol: "https://" }, "https://test.host/shelf/secure/books")
+ end
+
+ def test_assert_recognizes_with_engine_and_block_constraint
+ assert_raise(Assertion) do
+ assert_recognizes({ controller: "block_books", action: "index" }, "http://test.host/shelf/block/books")
+ end
+ assert_recognizes({ controller: "block_books", action: "index" }, "https://test.host/shelf/block/books")
+ end
+
+ def test_assert_recognizes_with_engine_and_query_constraint
+ assert_raise(Assertion) do
+ assert_recognizes({ controller: "query_books", action: "index", use_query: "false" }, "/shelf/query/books", use_query: "false")
+ end
+ assert_recognizes({ controller: "query_books", action: "index", use_query: "true" }, "/shelf/query/books", use_query: "true")
+ end
+
+ def test_assert_recognizes_raises_message_with_engine
+ err = assert_raise(Assertion) do
+ assert_recognizes({ controller: "secure_books", action: "index" }, "http://test.host/shelf/secure/books", {}, "This is a really bad msg")
+ end
+
+ assert_match err.message, "This is a really bad msg"
+ end
+
+ def test_assert_recognizes_continue_to_recoginize_after_it_tried_engines
+ assert_recognizes({ controller: "query_articles", action: "index" }, "/shelf/foo")
+ end
+
def test_assert_routing
- assert_routing('/articles', :controller => 'articles', :action => 'index')
+ assert_routing("/articles", controller: "articles", action: "index")
end
def test_assert_routing_raises_message
err = assert_raise(Assertion) do
- assert_routing('/thisIsNotARoute', { :controller => 'articles', :action => 'edit', :id => '1' }, { :id => '1' }, {}, "This is a really bad msg")
+ assert_routing("/thisIsNotARoute", { controller: "articles", action: "edit", id: "1" }, { id: "1" }, {}, "This is a really bad msg")
end
assert_match err.message, "This is a really bad msg"
end
def test_assert_routing_with_defaults
- assert_routing('/articles/1/edit', { :controller => 'articles', :action => 'edit', :id => '1' }, { :id => '1' })
+ assert_routing("/articles/1/edit", { controller: "articles", action: "edit", id: "1" }, { id: "1" })
end
def test_assert_routing_with_extras
- assert_routing('/articles', { :controller => 'articles', :action => 'index', :page => '1' }, { }, { :page => '1' })
+ assert_routing("/articles", { controller: "articles", action: "index", page: "1" }, {}, { page: "1" })
end
def test_assert_routing_with_hash_constraint
assert_raise(Assertion) do
- assert_routing('http://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index' })
+ assert_routing("http://test.host/secure/articles", controller: "secure_articles", action: "index")
end
- assert_routing('https://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index', :protocol => 'https://' })
+ assert_routing("https://test.host/secure/articles", controller: "secure_articles", action: "index", protocol: "https://")
end
def test_assert_routing_with_block_constraint
assert_raise(Assertion) do
- assert_routing('http://test.host/block/articles', { :controller => 'block_articles', :action => 'index' })
+ assert_routing("http://test.host/block/articles", controller: "block_articles", action: "index")
end
- assert_routing('https://test.host/block/articles', { :controller => 'block_articles', :action => 'index' })
+ assert_routing("https://test.host/block/articles", controller: "block_articles", action: "index")
end
def test_with_routing
with_routing do |routes|
routes.draw do
- resources :articles, :path => 'artikel'
+ resources :articles, path: "artikel"
end
- assert_routing('/artikel', :controller => 'articles', :action => 'index')
+ assert_routing("/artikel", controller: "articles", action: "index")
assert_raise(Assertion) do
- assert_routing('/articles', { :controller => 'articles', :action => 'index' })
+ assert_routing("/articles", controller: "articles", action: "index")
end
end
end
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 8972f3e74d..affc2d8497 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -1,10 +1,13 @@
-require 'erb'
-require 'abstract_unit'
-require 'controller/fake_controllers'
+# frozen_string_literal: true
+
+require "erb"
+require "abstract_unit"
+require "controller/fake_controllers"
+require "active_support/messages/rotation_configuration"
class TestRoutingMapper < ActionDispatch::IntegrationTest
SprocketsApp = lambda { |env|
- [200, {"Content-Type" => "text/html"}, ["javascripts"]]
+ [200, { "Content-Type" => "text/html" }, ["javascripts"]]
}
class IpRestrictor
@@ -28,95 +31,112 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
def test_logout
draw do
controller :sessions do
- delete 'logout' => :destroy
+ delete "logout" => :destroy
end
end
- delete '/logout'
- assert_equal 'sessions#destroy', @response.body
+ delete "/logout"
+ assert_equal "sessions#destroy", @response.body
- assert_equal '/logout', logout_path
- assert_equal '/logout', url_for(:controller => 'sessions', :action => 'destroy', :only_path => true)
+ assert_equal "/logout", logout_path
+ assert_equal "/logout", url_for(controller: "sessions", action: "destroy", only_path: true)
end
def test_login
draw do
- default_url_options :host => "rubyonrails.org"
+ default_url_options host: "rubyonrails.org"
controller :sessions do
- get 'login' => :new
- post 'login' => :create
+ get "login" => :new
+ post "login" => :create
end
end
- get '/login'
- assert_equal 'sessions#new', @response.body
- assert_equal '/login', login_path
+ get "/login"
+ assert_equal "sessions#new", @response.body
+ assert_equal "/login", login_path
- post '/login'
- assert_equal 'sessions#create', @response.body
+ post "/login"
+ assert_equal "sessions#create", @response.body
- assert_equal '/login', url_for(:controller => 'sessions', :action => 'create', :only_path => true)
- assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true)
+ assert_equal "/login", url_for(controller: "sessions", action: "create", only_path: true)
+ assert_equal "/login", url_for(controller: "sessions", action: "new", only_path: true)
- assert_equal 'http://rubyonrails.org/login', url_for(:controller => 'sessions', :action => 'create')
- assert_equal 'http://rubyonrails.org/login', login_url
+ assert_equal "http://rubyonrails.org/login", url_for(controller: "sessions", action: "create")
+ assert_equal "http://rubyonrails.org/login", login_url
end
def test_login_redirect
draw do
- get 'account/login', :to => redirect("/login")
+ get "account/login", to: redirect("/login")
end
- get '/account/login'
- verify_redirect 'http://www.example.com/login'
+ get "/account/login"
+ verify_redirect "http://www.example.com/login"
end
def test_logout_redirect_without_to
draw do
- get 'account/logout' => redirect("/logout"), :as => :logout_redirect
+ get "account/logout" => redirect("/logout"), :as => :logout_redirect
end
- assert_equal '/account/logout', logout_redirect_path
- get '/account/logout'
- verify_redirect 'http://www.example.com/logout'
+ assert_equal "/account/logout", logout_redirect_path
+ get "/account/logout"
+ verify_redirect "http://www.example.com/logout"
end
def test_namespace_redirect
draw do
namespace :private do
- root :to => redirect('/private/index')
- get "index", :to => 'private#index'
+ root to: redirect("/private/index")
+ get "index", to: "private#index"
end
end
- get '/private'
- verify_redirect 'http://www.example.com/private/index'
+ get "/private"
+ verify_redirect "http://www.example.com/private/index"
end
def test_redirect_with_failing_constraint
draw do
- get 'hi', to: redirect("/foo"), constraints: ::TestRoutingMapper::GrumpyRestrictor
+ get "hi", to: redirect("/foo"), constraints: ::TestRoutingMapper::GrumpyRestrictor
end
- get '/hi'
+ get "/hi"
assert_equal 404, status
end
def test_redirect_with_passing_constraint
draw do
- get 'hi', to: redirect("/foo"), constraints: ->(req) { true }
+ get "hi", to: redirect("/foo"), constraints: ->(req) { true }
end
- get '/hi'
+ get "/hi"
assert_equal 301, status
end
+ def test_accepts_a_constraint_object_responding_to_call
+ constraint = Class.new do
+ def call(*); true; end
+ def matches?(*); false; end
+ end
+
+ draw do
+ get "/", to: "home#show", constraints: constraint.new
+ end
+
+ assert_nothing_raised do
+ get "/"
+ end
+ end
+
def test_namespace_with_controller_segment
assert_raise(ArgumentError) do
draw do
namespace :admin do
- get '/:controller(/:action(/:id(.:format)))'
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action(/:id(.:format)))"
+ end
end
end
end
@@ -125,11 +145,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
def test_namespace_without_controller_segment
draw do
namespace :admin do
- get 'hello/:controllers/:action'
+ ActiveSupport::Deprecation.silence do
+ get "hello/:controllers/:action"
+ end
end
end
- get '/admin/hello/foo/new'
- assert_equal 'foo', @request.params["controllers"]
+ get "/admin/hello/foo/new"
+ assert_equal "foo", @request.params["controllers"]
end
def test_session_singleton_resource
@@ -140,30 +162,30 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/session'
- assert_equal 'sessions#create', @response.body
- assert_equal '/session', session_path
+ get "/session"
+ assert_equal "sessions#create", @response.body
+ assert_equal "/session", session_path
- post '/session'
- assert_equal 'sessions#create', @response.body
+ post "/session"
+ assert_equal "sessions#create", @response.body
- put '/session'
- assert_equal 'sessions#update', @response.body
+ put "/session"
+ assert_equal "sessions#update", @response.body
- delete '/session'
- assert_equal 'sessions#destroy', @response.body
+ delete "/session"
+ assert_equal "sessions#destroy", @response.body
- get '/session/new'
- assert_equal 'sessions#new', @response.body
- assert_equal '/session/new', new_session_path
+ get "/session/new"
+ assert_equal "sessions#new", @response.body
+ assert_equal "/session/new", new_session_path
- get '/session/edit'
- assert_equal 'sessions#edit', @response.body
- assert_equal '/session/edit', edit_session_path
+ get "/session/edit"
+ assert_equal "sessions#edit", @response.body
+ assert_equal "/session/edit", edit_session_path
- post '/session/reset'
- assert_equal 'sessions#reset', @response.body
- assert_equal '/session/reset', reset_session_path
+ post "/session/reset"
+ assert_equal "sessions#reset", @response.body
+ assert_equal "/session/reset", reset_session_path
end
def test_session_singleton_resource_for_api_app
@@ -180,28 +202,28 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
@app = RoutedRackApp.new routes
end
- get '/session'
- assert_equal 'sessions#create', @response.body
- assert_equal '/session', session_path
+ get "/session"
+ assert_equal "sessions#create", @response.body
+ assert_equal "/session", session_path
- post '/session'
- assert_equal 'sessions#create', @response.body
+ post "/session"
+ assert_equal "sessions#create", @response.body
- put '/session'
- assert_equal 'sessions#update', @response.body
+ put "/session"
+ assert_equal "sessions#update", @response.body
- delete '/session'
- assert_equal 'sessions#destroy', @response.body
+ delete "/session"
+ assert_equal "sessions#destroy", @response.body
- post '/session/reset'
- assert_equal 'sessions#reset', @response.body
- assert_equal '/session/reset', reset_session_path
+ post "/session/reset"
+ assert_equal "sessions#reset", @response.body
+ assert_equal "/session/reset", reset_session_path
- get '/session/new'
- assert_equal 'Not Found', @response.body
+ get "/session/new"
+ assert_equal "Not Found", @response.body
- get '/session/edit'
- assert_equal 'Not Found', @response.body
+ get "/session/edit"
+ assert_equal "Not Found", @response.body
end
def test_session_info_nested_singleton_resource
@@ -211,9 +233,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/session/info'
- assert_equal 'infos#show', @response.body
- assert_equal '/session/info', session_info_path
+ get "/session/info"
+ assert_equal "infos#show", @response.body
+ assert_equal "/session/info", session_info_path
end
def test_member_on_resource
@@ -225,236 +247,243 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/session/crush'
- assert_equal 'sessions#crush', @response.body
- assert_equal '/session/crush', crush_session_path
+ get "/session/crush"
+ assert_equal "sessions#crush", @response.body
+ assert_equal "/session/crush", crush_session_path
end
def test_redirect_modulo
draw do
- get 'account/modulo/:name', :to => redirect("/%{name}s")
+ get "account/modulo/:name", to: redirect("/%{name}s")
end
- get '/account/modulo/name'
- verify_redirect 'http://www.example.com/names'
+ get "/account/modulo/name"
+ verify_redirect "http://www.example.com/names"
end
def test_redirect_proc
draw do
- get 'account/proc/:name', :to => redirect {|params, req| "/#{params[:name].pluralize}" }
+ get "account/proc/:name", to: redirect { |params, req| "/#{params[:name].pluralize}" }
end
- get '/account/proc/person'
- verify_redirect 'http://www.example.com/people'
+ get "/account/proc/person"
+ verify_redirect "http://www.example.com/people"
end
def test_redirect_proc_with_request
draw do
- get 'account/proc_req' => redirect {|params, req| "/#{req.method}" }
+ get "account/proc_req" => redirect { |params, req| "/#{req.method}" }
end
- get '/account/proc_req'
- verify_redirect 'http://www.example.com/GET'
+ get "/account/proc_req"
+ verify_redirect "http://www.example.com/GET"
end
def test_redirect_hash_with_subdomain
draw do
- get 'mobile', :to => redirect(:subdomain => 'mobile')
+ get "mobile", to: redirect(subdomain: "mobile")
end
- get '/mobile'
- verify_redirect 'http://mobile.example.com/mobile'
+ get "/mobile"
+ verify_redirect "http://mobile.example.com/mobile"
end
def test_redirect_hash_with_domain_and_path
draw do
- get 'documentation', :to => redirect(:domain => 'example-documentation.com', :path => '')
+ get "documentation", to: redirect(domain: "example-documentation.com", path: "")
end
- get '/documentation'
- verify_redirect 'http://www.example-documentation.com'
+ get "/documentation"
+ verify_redirect "http://www.example-documentation.com"
end
def test_redirect_hash_with_path
draw do
- get 'new_documentation', :to => redirect(:path => '/documentation/new')
+ get "new_documentation", to: redirect(path: "/documentation/new")
end
- get '/new_documentation'
- verify_redirect 'http://www.example.com/documentation/new'
+ get "/new_documentation"
+ verify_redirect "http://www.example.com/documentation/new"
end
def test_redirect_hash_with_host
draw do
- get 'super_new_documentation', :to => redirect(:host => 'super-docs.com')
+ get "super_new_documentation", to: redirect(host: "super-docs.com")
end
- get '/super_new_documentation?section=top'
- verify_redirect 'http://super-docs.com/super_new_documentation?section=top'
+ get "/super_new_documentation?section=top"
+ verify_redirect "http://super-docs.com/super_new_documentation?section=top"
end
def test_redirect_hash_path_substitution
draw do
- get 'stores/:name', :to => redirect(:subdomain => 'stores', :path => '/%{name}')
+ get "stores/:name", to: redirect(subdomain: "stores", path: "/%{name}")
end
- get '/stores/iernest'
- verify_redirect 'http://stores.example.com/iernest'
+ get "/stores/iernest"
+ verify_redirect "http://stores.example.com/iernest"
end
def test_redirect_hash_path_substitution_with_catch_all
draw do
- get 'stores/:name(*rest)', :to => redirect(:subdomain => 'stores', :path => '/%{name}%{rest}')
+ get "stores/:name(*rest)", to: redirect(subdomain: "stores", path: "/%{name}%{rest}")
end
- get '/stores/iernest/products'
- verify_redirect 'http://stores.example.com/iernest/products'
+ get "/stores/iernest/products"
+ verify_redirect "http://stores.example.com/iernest/products"
end
def test_redirect_class
draw do
- get 'youtube_favorites/:youtube_id/:name', :to => redirect(YoutubeFavoritesRedirector)
+ get "youtube_favorites/:youtube_id/:name", to: redirect(YoutubeFavoritesRedirector)
end
- get '/youtube_favorites/oHg5SJYRHA0/rick-rolld'
- verify_redirect 'http://www.youtube.com/watch?v=oHg5SJYRHA0'
+ get "/youtube_favorites/oHg5SJYRHA0/rick-rolld"
+ verify_redirect "http://www.youtube.com/watch?v=oHg5SJYRHA0"
end
def test_openid
draw do
- match 'openid/login', :via => [:get, :post], :to => "openid#login"
+ match "openid/login", via: [:get, :post], to: "openid#login"
end
- get '/openid/login'
- assert_equal 'openid#login', @response.body
+ get "/openid/login"
+ assert_equal "openid#login", @response.body
- post '/openid/login'
- assert_equal 'openid#login', @response.body
+ post "/openid/login"
+ assert_equal "openid#login", @response.body
end
def test_bookmarks
draw do
- scope "bookmark", :controller => "bookmarks", :as => :bookmark do
- get :new, :path => "build"
- post :create, :path => "create", :as => ""
+ scope "bookmark", controller: "bookmarks", as: :bookmark do
+ get :new, path: "build"
+ post :create, path: "create", as: ""
put :update
- get :remove, :action => :destroy, :as => :remove
+ get :remove, action: :destroy, as: :remove
end
end
- get '/bookmark/build'
- assert_equal 'bookmarks#new', @response.body
- assert_equal '/bookmark/build', bookmark_new_path
+ get "/bookmark/build"
+ assert_equal "bookmarks#new", @response.body
+ assert_equal "/bookmark/build", bookmark_new_path
- post '/bookmark/create'
- assert_equal 'bookmarks#create', @response.body
- assert_equal '/bookmark/create', bookmark_path
+ post "/bookmark/create"
+ assert_equal "bookmarks#create", @response.body
+ assert_equal "/bookmark/create", bookmark_path
- put '/bookmark/update'
- assert_equal 'bookmarks#update', @response.body
- assert_equal '/bookmark/update', bookmark_update_path
+ put "/bookmark/update"
+ assert_equal "bookmarks#update", @response.body
+ assert_equal "/bookmark/update", bookmark_update_path
- get '/bookmark/remove'
- assert_equal 'bookmarks#destroy', @response.body
- assert_equal '/bookmark/remove', bookmark_remove_path
+ get "/bookmark/remove"
+ assert_equal "bookmarks#destroy", @response.body
+ assert_equal "/bookmark/remove", bookmark_remove_path
end
def test_pagemarks
- tc = self
draw do
- scope "pagemark", :controller => "pagemarks", :as => :pagemark do
- tc.assert_deprecated do
- get "new", :path => "build"
- end
- post "create", :as => ""
+ scope "pagemark", controller: "pagemarks", as: :pagemark do
+ get "build", action: "new", as: "new"
+ post "create", as: ""
put "update"
- get "remove", :action => :destroy, :as => :remove
+ get "remove", action: :destroy, as: :remove
+ get "", action: :show, as: :show
end
end
- get '/pagemark/build'
- assert_equal 'pagemarks#new', @response.body
- assert_equal '/pagemark/build', pagemark_new_path
+ get "/pagemark/build"
+ assert_equal "pagemarks#new", @response.body
+ assert_equal "/pagemark/build", pagemark_new_path
+
+ post "/pagemark/create"
+ assert_equal "pagemarks#create", @response.body
+ assert_equal "/pagemark/create", pagemark_path
- post '/pagemark/create'
- assert_equal 'pagemarks#create', @response.body
- assert_equal '/pagemark/create', pagemark_path
+ put "/pagemark/update"
+ assert_equal "pagemarks#update", @response.body
+ assert_equal "/pagemark/update", pagemark_update_path
- put '/pagemark/update'
- assert_equal 'pagemarks#update', @response.body
- assert_equal '/pagemark/update', pagemark_update_path
+ get "/pagemark/remove"
+ assert_equal "pagemarks#destroy", @response.body
+ assert_equal "/pagemark/remove", pagemark_remove_path
- get '/pagemark/remove'
- assert_equal 'pagemarks#destroy', @response.body
- assert_equal '/pagemark/remove', pagemark_remove_path
+ get "/pagemark"
+ assert_equal "pagemarks#show", @response.body
+ assert_equal "/pagemark", pagemark_show_path
end
def test_admin
draw do
- constraints(:ip => /192\.168\.1\.\d\d\d/) do
- get 'admin' => "queenbee#index"
+ constraints(ip: /192\.168\.1\.\d\d\d/) do
+ get "admin" => "queenbee#index"
end
constraints ::TestRoutingMapper::IpRestrictor do
- get 'admin/accounts' => "queenbee#accounts"
+ get "admin/accounts" => "queenbee#accounts"
end
- get 'admin/passwords' => "queenbee#passwords", :constraints => ::TestRoutingMapper::IpRestrictor
+ get "admin/passwords" => "queenbee#passwords", :constraints => ::TestRoutingMapper::IpRestrictor
end
- get '/admin', headers: { 'REMOTE_ADDR' => '192.168.1.100' }
- assert_equal 'queenbee#index', @response.body
+ get "/admin", headers: { "REMOTE_ADDR" => "192.168.1.100" }
+ assert_equal "queenbee#index", @response.body
- get '/admin', headers: { 'REMOTE_ADDR' => '10.0.0.100' }
- assert_equal 'pass', @response.headers['X-Cascade']
+ get "/admin", headers: { "REMOTE_ADDR" => "10.0.0.100" }
+ assert_equal "pass", @response.headers["X-Cascade"]
- get '/admin/accounts', headers: { 'REMOTE_ADDR' => '192.168.1.100' }
- assert_equal 'queenbee#accounts', @response.body
+ get "/admin/accounts", headers: { "REMOTE_ADDR" => "192.168.1.100" }
+ assert_equal "queenbee#accounts", @response.body
- get '/admin/accounts', headers: { 'REMOTE_ADDR' => '10.0.0.100' }
- assert_equal 'pass', @response.headers['X-Cascade']
+ get "/admin/accounts", headers: { "REMOTE_ADDR" => "10.0.0.100" }
+ assert_equal "pass", @response.headers["X-Cascade"]
- get '/admin/passwords', headers: { 'REMOTE_ADDR' => '192.168.1.100' }
- assert_equal 'queenbee#passwords', @response.body
+ get "/admin/passwords", headers: { "REMOTE_ADDR" => "192.168.1.100" }
+ assert_equal "queenbee#passwords", @response.body
- get '/admin/passwords', headers: { 'REMOTE_ADDR' => '10.0.0.100' }
- assert_equal 'pass', @response.headers['X-Cascade']
+ get "/admin/passwords", headers: { "REMOTE_ADDR" => "10.0.0.100" }
+ assert_equal "pass", @response.headers["X-Cascade"]
end
def test_global
draw do
controller(:global) do
- get 'global/hide_notice'
- get 'global/export', :action => :export, :as => :export_request
- get '/export/:id/:file', :action => :export, :as => :export_download, :constraints => { :file => /.*/ }
- get 'global/:action'
+ get "global/hide_notice"
+ get "global/export", action: :export, as: :export_request
+ get "/export/:id/:file", action: :export, as: :export_download, constraints: { file: /.*/ }
+
+ ActiveSupport::Deprecation.silence do
+ get "global/:action"
+ end
end
end
- get '/global/dashboard'
- assert_equal 'global#dashboard', @response.body
+ get "/global/dashboard"
+ assert_equal "global#dashboard", @response.body
- get '/global/export'
- assert_equal 'global#export', @response.body
+ get "/global/export"
+ assert_equal "global#export", @response.body
- get '/global/hide_notice'
- assert_equal 'global#hide_notice', @response.body
+ get "/global/hide_notice"
+ assert_equal "global#hide_notice", @response.body
- get '/export/123/foo.txt'
- assert_equal 'global#export', @response.body
+ get "/export/123/foo.txt"
+ assert_equal "global#export", @response.body
- assert_equal '/global/export', export_request_path
- assert_equal '/global/hide_notice', global_hide_notice_path
- assert_equal '/export/123/foo.txt', export_download_path(:id => 123, :file => 'foo.txt')
+ assert_equal "/global/export", export_request_path
+ assert_equal "/global/hide_notice", global_hide_notice_path
+ assert_equal "/export/123/foo.txt", export_download_path(id: 123, file: "foo.txt")
end
def test_local
draw do
- get "/local/:action", :controller => "local"
+ ActiveSupport::Deprecation.silence do
+ get "/local/:action", controller: "local"
+ end
end
- get '/local/dashboard'
- assert_equal 'local#dashboard', @response.body
+ get "/local/dashboard"
+ assert_equal "local#dashboard", @response.body
end
# tests the use of dup in url_for
@@ -464,7 +493,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
# without dup, additional (and possibly unwanted) values will be present in the options (eg. :host)
- original_options = {:controller => 'projects', :action => 'status'}
+ original_options = { controller: "projects", action: "status" }
options = original_options.dup
url_for options
@@ -478,23 +507,23 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "/projects/status(.:format)"
end
- controller = '/projects'
- options = {:controller => controller, :action => 'status', :only_path => true}
+ controller = "/projects"
+ options = { controller: controller, action: "status", only_path: true }
url = url_for(options)
- assert_equal '/projects/status', url
- assert_equal '/projects', controller
+ assert_equal "/projects/status", url
+ assert_equal "/projects", controller
end
# tests the arguments modification free version of define_hash_access
def test_named_route_with_no_side_effects
draw do
resources :customers do
- get "profile", :on => :member
+ get "profile", on: :member
end
end
- original_options = { :host => 'test.host' }
+ original_options = { host: "test.host" }
options = original_options.dup
profile_customer_url("customer_model", options)
@@ -508,45 +537,45 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "/projects/status(.:format)"
end
- assert_equal '/projects/status', url_for(:controller => 'projects', :action => 'status', :only_path => true)
- assert_equal '/projects/status.json', url_for(:controller => 'projects', :action => 'status', :format => 'json', :only_path => true)
+ assert_equal "/projects/status", url_for(controller: "projects", action: "status", only_path: true)
+ assert_equal "/projects/status.json", url_for(controller: "projects", action: "status", format: "json", only_path: true)
end
def test_projects
draw do
- resources :projects, :controller => :project
+ resources :projects, controller: :project
end
- get '/projects'
- assert_equal 'project#index', @response.body
- assert_equal '/projects', projects_path
+ get "/projects"
+ assert_equal "project#index", @response.body
+ assert_equal "/projects", projects_path
- post '/projects'
- assert_equal 'project#create', @response.body
+ post "/projects"
+ assert_equal "project#create", @response.body
- get '/projects.xml'
- assert_equal 'project#index', @response.body
- assert_equal '/projects.xml', projects_path(:format => 'xml')
+ get "/projects.xml"
+ assert_equal "project#index", @response.body
+ assert_equal "/projects.xml", projects_path(format: "xml")
- get '/projects/new'
- assert_equal 'project#new', @response.body
- assert_equal '/projects/new', new_project_path
+ get "/projects/new"
+ assert_equal "project#new", @response.body
+ assert_equal "/projects/new", new_project_path
- get '/projects/new.xml'
- assert_equal 'project#new', @response.body
- assert_equal '/projects/new.xml', new_project_path(:format => 'xml')
+ get "/projects/new.xml"
+ assert_equal "project#new", @response.body
+ assert_equal "/projects/new.xml", new_project_path(format: "xml")
- get '/projects/1'
- assert_equal 'project#show', @response.body
- assert_equal '/projects/1', project_path(:id => '1')
+ get "/projects/1"
+ assert_equal "project#show", @response.body
+ assert_equal "/projects/1", project_path(id: "1")
- get '/projects/1.xml'
- assert_equal 'project#show', @response.body
- assert_equal '/projects/1.xml', project_path(:id => '1', :format => 'xml')
+ get "/projects/1.xml"
+ assert_equal "project#show", @response.body
+ assert_equal "/projects/1.xml", project_path(id: "1", format: "xml")
- get '/projects/1/edit'
- assert_equal 'project#edit', @response.body
- assert_equal '/projects/1/edit', edit_project_path(:id => '1')
+ get "/projects/1/edit"
+ assert_equal "project#edit", @response.body
+ assert_equal "/projects/1/edit", edit_project_path(id: "1")
end
def test_projects_for_api_app
@@ -560,166 +589,166 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
@app = RoutedRackApp.new routes
end
- get '/projects'
- assert_equal 'project#index', @response.body
- assert_equal '/projects', projects_path
+ get "/projects"
+ assert_equal "project#index", @response.body
+ assert_equal "/projects", projects_path
- post '/projects'
- assert_equal 'project#create', @response.body
+ post "/projects"
+ assert_equal "project#create", @response.body
- get '/projects.xml'
- assert_equal 'project#index', @response.body
- assert_equal '/projects.xml', projects_path(format: 'xml')
+ get "/projects.xml"
+ assert_equal "project#index", @response.body
+ assert_equal "/projects.xml", projects_path(format: "xml")
- get '/projects/1'
- assert_equal 'project#show', @response.body
- assert_equal '/projects/1', project_path(id: '1')
+ get "/projects/1"
+ assert_equal "project#show", @response.body
+ assert_equal "/projects/1", project_path(id: "1")
- get '/projects/1.xml'
- assert_equal 'project#show', @response.body
- assert_equal '/projects/1.xml', project_path(id: '1', format: 'xml')
+ get "/projects/1.xml"
+ assert_equal "project#show", @response.body
+ assert_equal "/projects/1.xml", project_path(id: "1", format: "xml")
- get '/projects/1/edit'
- assert_equal 'Not Found', @response.body
+ get "/projects/1/edit"
+ assert_equal "Not Found", @response.body
end
def test_projects_with_post_action_and_new_path_on_collection
draw do
- resources :projects, :controller => :project do
- post 'new', :action => 'new', :on => :collection, :as => :new
+ resources :projects, controller: :project do
+ post "new", action: "new", on: :collection, as: :new
end
end
- post '/projects/new'
+ post "/projects/new"
assert_equal "project#new", @response.body
assert_equal "/projects/new", new_projects_path
end
def test_projects_involvements
draw do
- resources :projects, :controller => :project do
+ resources :projects, controller: :project do
resources :involvements, :attachments
end
end
- get '/projects/1/involvements'
- assert_equal 'involvements#index', @response.body
- assert_equal '/projects/1/involvements', project_involvements_path(:project_id => '1')
+ get "/projects/1/involvements"
+ assert_equal "involvements#index", @response.body
+ assert_equal "/projects/1/involvements", project_involvements_path(project_id: "1")
- get '/projects/1/involvements/new'
- assert_equal 'involvements#new', @response.body
- assert_equal '/projects/1/involvements/new', new_project_involvement_path(:project_id => '1')
+ get "/projects/1/involvements/new"
+ assert_equal "involvements#new", @response.body
+ assert_equal "/projects/1/involvements/new", new_project_involvement_path(project_id: "1")
- get '/projects/1/involvements/1'
- assert_equal 'involvements#show', @response.body
- assert_equal '/projects/1/involvements/1', project_involvement_path(:project_id => '1', :id => '1')
+ get "/projects/1/involvements/1"
+ assert_equal "involvements#show", @response.body
+ assert_equal "/projects/1/involvements/1", project_involvement_path(project_id: "1", id: "1")
- put '/projects/1/involvements/1'
- assert_equal 'involvements#update', @response.body
+ put "/projects/1/involvements/1"
+ assert_equal "involvements#update", @response.body
- delete '/projects/1/involvements/1'
- assert_equal 'involvements#destroy', @response.body
+ delete "/projects/1/involvements/1"
+ assert_equal "involvements#destroy", @response.body
- get '/projects/1/involvements/1/edit'
- assert_equal 'involvements#edit', @response.body
- assert_equal '/projects/1/involvements/1/edit', edit_project_involvement_path(:project_id => '1', :id => '1')
+ get "/projects/1/involvements/1/edit"
+ assert_equal "involvements#edit", @response.body
+ assert_equal "/projects/1/involvements/1/edit", edit_project_involvement_path(project_id: "1", id: "1")
end
def test_projects_attachments
draw do
- resources :projects, :controller => :project do
+ resources :projects, controller: :project do
resources :involvements, :attachments
end
end
- get '/projects/1/attachments'
- assert_equal 'attachments#index', @response.body
- assert_equal '/projects/1/attachments', project_attachments_path(:project_id => '1')
+ get "/projects/1/attachments"
+ assert_equal "attachments#index", @response.body
+ assert_equal "/projects/1/attachments", project_attachments_path(project_id: "1")
end
def test_projects_participants
draw do
- resources :projects, :controller => :project do
+ resources :projects, controller: :project do
resources :participants do
- put :update_all, :on => :collection
+ put :update_all, on: :collection
end
end
end
- get '/projects/1/participants'
- assert_equal 'participants#index', @response.body
- assert_equal '/projects/1/participants', project_participants_path(:project_id => '1')
+ get "/projects/1/participants"
+ assert_equal "participants#index", @response.body
+ assert_equal "/projects/1/participants", project_participants_path(project_id: "1")
- put '/projects/1/participants/update_all'
- assert_equal 'participants#update_all', @response.body
- assert_equal '/projects/1/participants/update_all', update_all_project_participants_path(:project_id => '1')
+ put "/projects/1/participants/update_all"
+ assert_equal "participants#update_all", @response.body
+ assert_equal "/projects/1/participants/update_all", update_all_project_participants_path(project_id: "1")
end
def test_projects_companies
draw do
- resources :projects, :controller => :project do
+ resources :projects, controller: :project do
resources :companies do
resources :people
- resource :avatar, :controller => :avatar
+ resource :avatar, controller: :avatar
end
end
end
- get '/projects/1/companies'
- assert_equal 'companies#index', @response.body
- assert_equal '/projects/1/companies', project_companies_path(:project_id => '1')
+ get "/projects/1/companies"
+ assert_equal "companies#index", @response.body
+ assert_equal "/projects/1/companies", project_companies_path(project_id: "1")
- get '/projects/1/companies/1/people'
- assert_equal 'people#index', @response.body
- assert_equal '/projects/1/companies/1/people', project_company_people_path(:project_id => '1', :company_id => '1')
+ get "/projects/1/companies/1/people"
+ assert_equal "people#index", @response.body
+ assert_equal "/projects/1/companies/1/people", project_company_people_path(project_id: "1", company_id: "1")
- get '/projects/1/companies/1/avatar'
- assert_equal 'avatar#show', @response.body
- assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1')
+ get "/projects/1/companies/1/avatar"
+ assert_equal "avatar#show", @response.body
+ assert_equal "/projects/1/companies/1/avatar", project_company_avatar_path(project_id: "1", company_id: "1")
end
def test_project_manager
draw do
resources :projects do
- resource :manager, :as => :super_manager do
+ resource :manager, as: :super_manager do
post :fire
end
end
end
- get '/projects/1/manager'
- assert_equal 'managers#show', @response.body
- assert_equal '/projects/1/manager', project_super_manager_path(:project_id => '1')
+ get "/projects/1/manager"
+ assert_equal "managers#show", @response.body
+ assert_equal "/projects/1/manager", project_super_manager_path(project_id: "1")
- get '/projects/1/manager/new'
- assert_equal 'managers#new', @response.body
- assert_equal '/projects/1/manager/new', new_project_super_manager_path(:project_id => '1')
+ get "/projects/1/manager/new"
+ assert_equal "managers#new", @response.body
+ assert_equal "/projects/1/manager/new", new_project_super_manager_path(project_id: "1")
- post '/projects/1/manager/fire'
- assert_equal 'managers#fire', @response.body
- assert_equal '/projects/1/manager/fire', fire_project_super_manager_path(:project_id => '1')
+ post "/projects/1/manager/fire"
+ assert_equal "managers#fire", @response.body
+ assert_equal "/projects/1/manager/fire", fire_project_super_manager_path(project_id: "1")
end
def test_project_images
draw do
resources :projects do
- resources :images, :as => :funny_images do
- post :revise, :on => :member
+ resources :images, as: :funny_images do
+ post :revise, on: :member
end
end
end
- get '/projects/1/images'
- assert_equal 'images#index', @response.body
- assert_equal '/projects/1/images', project_funny_images_path(:project_id => '1')
+ get "/projects/1/images"
+ assert_equal "images#index", @response.body
+ assert_equal "/projects/1/images", project_funny_images_path(project_id: "1")
- get '/projects/1/images/new'
- assert_equal 'images#new', @response.body
- assert_equal '/projects/1/images/new', new_project_funny_image_path(:project_id => '1')
+ get "/projects/1/images/new"
+ assert_equal "images#new", @response.body
+ assert_equal "/projects/1/images/new", new_project_funny_image_path(project_id: "1")
- post '/projects/1/images/1/revise'
- assert_equal 'images#revise', @response.body
- assert_equal '/projects/1/images/1/revise', revise_project_funny_image_path(:project_id => '1', :id => '1')
+ post "/projects/1/images/1/revise"
+ assert_equal "images#revise", @response.body
+ assert_equal "/projects/1/images/1/revise", revise_project_funny_image_path(project_id: "1", id: "1")
end
def test_projects_people
@@ -740,181 +769,181 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/projects/1/people'
- assert_equal 'people#index', @response.body
- assert_equal '/projects/1/people', project_people_path(:project_id => '1')
+ get "/projects/1/people"
+ assert_equal "people#index", @response.body
+ assert_equal "/projects/1/people", project_people_path(project_id: "1")
- get '/projects/1/people/1'
- assert_equal 'people#show', @response.body
- assert_equal '/projects/1/people/1', project_person_path(:project_id => '1', :id => '1')
+ get "/projects/1/people/1"
+ assert_equal "people#show", @response.body
+ assert_equal "/projects/1/people/1", project_person_path(project_id: "1", id: "1")
- get '/projects/1/people/1/7a2dec8/avatar'
- assert_equal 'avatars#show', @response.body
- assert_equal '/projects/1/people/1/7a2dec8/avatar', project_person_avatar_path(:project_id => '1', :person_id => '1', :access_token => '7a2dec8')
+ get "/projects/1/people/1/7a2dec8/avatar"
+ assert_equal "avatars#show", @response.body
+ assert_equal "/projects/1/people/1/7a2dec8/avatar", project_person_avatar_path(project_id: "1", person_id: "1", access_token: "7a2dec8")
- put '/projects/1/people/1/accessible_projects'
- assert_equal 'people#accessible_projects', @response.body
- assert_equal '/projects/1/people/1/accessible_projects', accessible_projects_project_person_path(:project_id => '1', :id => '1')
+ put "/projects/1/people/1/accessible_projects"
+ assert_equal "people#accessible_projects", @response.body
+ assert_equal "/projects/1/people/1/accessible_projects", accessible_projects_project_person_path(project_id: "1", id: "1")
- post '/projects/1/people/1/resend'
- assert_equal 'people#resend', @response.body
- assert_equal '/projects/1/people/1/resend', resend_project_person_path(:project_id => '1', :id => '1')
+ post "/projects/1/people/1/resend"
+ assert_equal "people#resend", @response.body
+ assert_equal "/projects/1/people/1/resend", resend_project_person_path(project_id: "1", id: "1")
- post '/projects/1/people/1/generate_new_password'
- assert_equal 'people#generate_new_password', @response.body
- assert_equal '/projects/1/people/1/generate_new_password', generate_new_password_project_person_path(:project_id => '1', :id => '1')
+ post "/projects/1/people/1/generate_new_password"
+ assert_equal "people#generate_new_password", @response.body
+ assert_equal "/projects/1/people/1/generate_new_password", generate_new_password_project_person_path(project_id: "1", id: "1")
end
def test_projects_with_resources_path_names
draw do
- resources_path_names :correlation_indexes => "info_about_correlation_indexes"
+ resources_path_names correlation_indexes: "info_about_correlation_indexes"
resources :projects do
- get :correlation_indexes, :on => :collection
+ get :correlation_indexes, on: :collection
end
end
- get '/projects/info_about_correlation_indexes'
- assert_equal 'projects#correlation_indexes', @response.body
- assert_equal '/projects/info_about_correlation_indexes', correlation_indexes_projects_path
+ get "/projects/info_about_correlation_indexes"
+ assert_equal "projects#correlation_indexes", @response.body
+ assert_equal "/projects/info_about_correlation_indexes", correlation_indexes_projects_path
end
def test_projects_posts
draw do
resources :projects do
resources :posts do
- get :archive, :toggle_view, :on => :collection
- post :preview, :on => :member
+ get :archive, :toggle_view, on: :collection
+ post :preview, on: :member
resource :subscription
resources :comments do
- post :preview, :on => :collection
+ post :preview, on: :collection
end
end
end
end
- get '/projects/1/posts'
- assert_equal 'posts#index', @response.body
- assert_equal '/projects/1/posts', project_posts_path(:project_id => '1')
+ get "/projects/1/posts"
+ assert_equal "posts#index", @response.body
+ assert_equal "/projects/1/posts", project_posts_path(project_id: "1")
- get '/projects/1/posts/archive'
- assert_equal 'posts#archive', @response.body
- assert_equal '/projects/1/posts/archive', archive_project_posts_path(:project_id => '1')
+ get "/projects/1/posts/archive"
+ assert_equal "posts#archive", @response.body
+ assert_equal "/projects/1/posts/archive", archive_project_posts_path(project_id: "1")
- get '/projects/1/posts/toggle_view'
- assert_equal 'posts#toggle_view', @response.body
- assert_equal '/projects/1/posts/toggle_view', toggle_view_project_posts_path(:project_id => '1')
+ get "/projects/1/posts/toggle_view"
+ assert_equal "posts#toggle_view", @response.body
+ assert_equal "/projects/1/posts/toggle_view", toggle_view_project_posts_path(project_id: "1")
- post '/projects/1/posts/1/preview'
- assert_equal 'posts#preview', @response.body
- assert_equal '/projects/1/posts/1/preview', preview_project_post_path(:project_id => '1', :id => '1')
+ post "/projects/1/posts/1/preview"
+ assert_equal "posts#preview", @response.body
+ assert_equal "/projects/1/posts/1/preview", preview_project_post_path(project_id: "1", id: "1")
- get '/projects/1/posts/1/subscription'
- assert_equal 'subscriptions#show', @response.body
- assert_equal '/projects/1/posts/1/subscription', project_post_subscription_path(:project_id => '1', :post_id => '1')
+ get "/projects/1/posts/1/subscription"
+ assert_equal "subscriptions#show", @response.body
+ assert_equal "/projects/1/posts/1/subscription", project_post_subscription_path(project_id: "1", post_id: "1")
- get '/projects/1/posts/1/comments'
- assert_equal 'comments#index', @response.body
- assert_equal '/projects/1/posts/1/comments', project_post_comments_path(:project_id => '1', :post_id => '1')
+ get "/projects/1/posts/1/comments"
+ assert_equal "comments#index", @response.body
+ assert_equal "/projects/1/posts/1/comments", project_post_comments_path(project_id: "1", post_id: "1")
- post '/projects/1/posts/1/comments/preview'
- assert_equal 'comments#preview', @response.body
- assert_equal '/projects/1/posts/1/comments/preview', preview_project_post_comments_path(:project_id => '1', :post_id => '1')
+ post "/projects/1/posts/1/comments/preview"
+ assert_equal "comments#preview", @response.body
+ assert_equal "/projects/1/posts/1/comments/preview", preview_project_post_comments_path(project_id: "1", post_id: "1")
end
def test_replies
draw do
resources :replies do
member do
- put :answer, :action => :mark_as_answer
- delete :answer, :action => :unmark_as_answer
+ put :answer, action: :mark_as_answer
+ delete :answer, action: :unmark_as_answer
end
end
end
- put '/replies/1/answer'
- assert_equal 'replies#mark_as_answer', @response.body
+ put "/replies/1/answer"
+ assert_equal "replies#mark_as_answer", @response.body
- delete '/replies/1/answer'
- assert_equal 'replies#unmark_as_answer', @response.body
+ delete "/replies/1/answer"
+ assert_equal "replies#unmark_as_answer", @response.body
end
def test_resource_routes_with_only_and_except
draw do
- resources :posts, :only => [:index, :show] do
- resources :comments, :except => :destroy
+ resources :posts, only: [:index, :show] do
+ resources :comments, except: :destroy
end
end
- get '/posts'
- assert_equal 'posts#index', @response.body
- assert_equal '/posts', posts_path
+ get "/posts"
+ assert_equal "posts#index", @response.body
+ assert_equal "/posts", posts_path
- get '/posts/1'
- assert_equal 'posts#show', @response.body
- assert_equal '/posts/1', post_path(:id => 1)
+ get "/posts/1"
+ assert_equal "posts#show", @response.body
+ assert_equal "/posts/1", post_path(id: 1)
- get '/posts/1/comments'
- assert_equal 'comments#index', @response.body
- assert_equal '/posts/1/comments', post_comments_path(:post_id => 1)
+ get "/posts/1/comments"
+ assert_equal "comments#index", @response.body
+ assert_equal "/posts/1/comments", post_comments_path(post_id: 1)
- post '/posts'
- assert_equal 'pass', @response.headers['X-Cascade']
- put '/posts/1'
- assert_equal 'pass', @response.headers['X-Cascade']
- delete '/posts/1'
- assert_equal 'pass', @response.headers['X-Cascade']
- delete '/posts/1/comments'
- assert_equal 'pass', @response.headers['X-Cascade']
+ post "/posts"
+ assert_equal "pass", @response.headers["X-Cascade"]
+ put "/posts/1"
+ assert_equal "pass", @response.headers["X-Cascade"]
+ delete "/posts/1"
+ assert_equal "pass", @response.headers["X-Cascade"]
+ delete "/posts/1/comments"
+ assert_equal "pass", @response.headers["X-Cascade"]
end
def test_resource_routes_only_create_update_destroy
draw do
- resource :past, :only => :destroy
- resource :present, :only => :update
- resource :future, :only => :create
+ resource :past, only: :destroy
+ resource :present, only: :update
+ resource :future, only: :create
end
- delete '/past'
- assert_equal 'pasts#destroy', @response.body
- assert_equal '/past', past_path
+ delete "/past"
+ assert_equal "pasts#destroy", @response.body
+ assert_equal "/past", past_path
- patch '/present'
- assert_equal 'presents#update', @response.body
- assert_equal '/present', present_path
+ patch "/present"
+ assert_equal "presents#update", @response.body
+ assert_equal "/present", present_path
- put '/present'
- assert_equal 'presents#update', @response.body
- assert_equal '/present', present_path
+ put "/present"
+ assert_equal "presents#update", @response.body
+ assert_equal "/present", present_path
- post '/future'
- assert_equal 'futures#create', @response.body
- assert_equal '/future', future_path
+ post "/future"
+ assert_equal "futures#create", @response.body
+ assert_equal "/future", future_path
end
def test_resources_routes_only_create_update_destroy
draw do
- resources :relationships, :only => [:create, :destroy]
- resources :friendships, :only => [:update]
+ resources :relationships, only: [:create, :destroy]
+ resources :friendships, only: [:update]
end
- post '/relationships'
- assert_equal 'relationships#create', @response.body
- assert_equal '/relationships', relationships_path
+ post "/relationships"
+ assert_equal "relationships#create", @response.body
+ assert_equal "/relationships", relationships_path
- delete '/relationships/1'
- assert_equal 'relationships#destroy', @response.body
- assert_equal '/relationships/1', relationship_path(1)
+ delete "/relationships/1"
+ assert_equal "relationships#destroy", @response.body
+ assert_equal "/relationships/1", relationship_path(1)
- patch '/friendships/1'
- assert_equal 'friendships#update', @response.body
- assert_equal '/friendships/1', friendship_path(1)
+ patch "/friendships/1"
+ assert_equal "friendships#update", @response.body
+ assert_equal "/friendships/1", friendship_path(1)
- put '/friendships/1'
- assert_equal 'friendships#update', @response.body
- assert_equal '/friendships/1', friendship_path(1)
+ put "/friendships/1"
+ assert_equal "friendships#update", @response.body
+ assert_equal "/friendships/1", friendship_path(1)
end
def test_resource_with_slugs_in_ids
@@ -922,153 +951,153 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resources :posts
end
- get '/posts/rails-rocks'
- assert_equal 'posts#show', @response.body
- assert_equal '/posts/rails-rocks', post_path(:id => 'rails-rocks')
+ get "/posts/rails-rocks"
+ assert_equal "posts#show", @response.body
+ assert_equal "/posts/rails-rocks", post_path(id: "rails-rocks")
end
def test_resources_for_uncountable_names
draw do
resources :sheep do
- get "_it", :on => :member
+ get "_it", on: :member
end
end
- assert_equal '/sheep', sheep_index_path
- assert_equal '/sheep/1', sheep_path(1)
- assert_equal '/sheep/new', new_sheep_path
- assert_equal '/sheep/1/edit', edit_sheep_path(1)
- assert_equal '/sheep/1/_it', _it_sheep_path(1)
+ assert_equal "/sheep", sheep_index_path
+ assert_equal "/sheep/1", sheep_path(1)
+ assert_equal "/sheep/new", new_sheep_path
+ assert_equal "/sheep/1/edit", edit_sheep_path(1)
+ assert_equal "/sheep/1/_it", _it_sheep_path(1)
end
def test_resource_does_not_modify_passed_options
- options = {:id => /.+?/, :format => /json|xml/}
+ options = { id: /.+?/, format: /json|xml/ }
draw { resource :user, options }
- assert_equal({:id => /.+?/, :format => /json|xml/}, options)
+ assert_equal({ id: /.+?/, format: /json|xml/ }, options)
end
def test_resources_does_not_modify_passed_options
- options = {:id => /.+?/, :format => /json|xml/}
+ options = { id: /.+?/, format: /json|xml/ }
draw { resources :users, options }
- assert_equal({:id => /.+?/, :format => /json|xml/}, options)
+ assert_equal({ id: /.+?/, format: /json|xml/ }, options)
end
def test_path_names
draw do
- scope 'pt', :as => 'pt' do
- resources :projects, :path_names => { :edit => 'editar', :new => 'novo' }, :path => 'projetos'
- resource :admin, :path_names => { :new => 'novo', :activate => 'ativar' }, :path => 'administrador' do
- put :activate, :on => :member
+ scope "pt", as: "pt" do
+ resources :projects, path_names: { edit: "editar", new: "novo" }, path: "projetos"
+ resource :admin, path_names: { new: "novo", activate: "ativar" }, path: "administrador" do
+ put :activate, on: :member
end
end
end
- get '/pt/projetos'
- assert_equal 'projects#index', @response.body
- assert_equal '/pt/projetos', pt_projects_path
+ get "/pt/projetos"
+ assert_equal "projects#index", @response.body
+ assert_equal "/pt/projetos", pt_projects_path
- get '/pt/projetos/1/editar'
- assert_equal 'projects#edit', @response.body
- assert_equal '/pt/projetos/1/editar', edit_pt_project_path(1)
+ get "/pt/projetos/1/editar"
+ assert_equal "projects#edit", @response.body
+ assert_equal "/pt/projetos/1/editar", edit_pt_project_path(1)
- get '/pt/administrador'
- assert_equal 'admins#show', @response.body
- assert_equal '/pt/administrador', pt_admin_path
+ get "/pt/administrador"
+ assert_equal "admins#show", @response.body
+ assert_equal "/pt/administrador", pt_admin_path
- get '/pt/administrador/novo'
- assert_equal 'admins#new', @response.body
- assert_equal '/pt/administrador/novo', new_pt_admin_path
+ get "/pt/administrador/novo"
+ assert_equal "admins#new", @response.body
+ assert_equal "/pt/administrador/novo", new_pt_admin_path
- put '/pt/administrador/ativar'
- assert_equal 'admins#activate', @response.body
- assert_equal '/pt/administrador/ativar', activate_pt_admin_path
+ put "/pt/administrador/ativar"
+ assert_equal "admins#activate", @response.body
+ assert_equal "/pt/administrador/ativar", activate_pt_admin_path
end
def test_path_option_override
draw do
- scope 'pt', :as => 'pt' do
- resources :projects, :path_names => { :new => 'novo' }, :path => 'projetos' do
- put :close, :on => :member, :path => 'fechar'
- get :open, :on => :new, :path => 'abrir'
+ scope "pt", as: "pt" do
+ resources :projects, path_names: { new: "novo" }, path: "projetos" do
+ put :close, on: :member, path: "fechar"
+ get :open, on: :new, path: "abrir"
end
end
end
- get '/pt/projetos/novo/abrir'
- assert_equal 'projects#open', @response.body
- assert_equal '/pt/projetos/novo/abrir', open_new_pt_project_path
+ get "/pt/projetos/novo/abrir"
+ assert_equal "projects#open", @response.body
+ assert_equal "/pt/projetos/novo/abrir", open_new_pt_project_path
- put '/pt/projetos/1/fechar'
- assert_equal 'projects#close', @response.body
- assert_equal '/pt/projetos/1/fechar', close_pt_project_path(1)
+ put "/pt/projetos/1/fechar"
+ assert_equal "projects#close", @response.body
+ assert_equal "/pt/projetos/1/fechar", close_pt_project_path(1)
end
def test_sprockets
draw do
- get 'sprockets.js' => ::TestRoutingMapper::SprocketsApp
+ get "sprockets.js" => ::TestRoutingMapper::SprocketsApp
end
- get '/sprockets.js'
- assert_equal 'javascripts', @response.body
+ get "/sprockets.js"
+ assert_equal "javascripts", @response.body
end
def test_update_person_route
draw do
- get 'people/:id/update', :to => 'people#update', :as => :update_person
+ get "people/:id/update", to: "people#update", as: :update_person
end
- get '/people/1/update'
- assert_equal 'people#update', @response.body
+ get "/people/1/update"
+ assert_equal "people#update", @response.body
- assert_equal '/people/1/update', update_person_path(:id => 1)
+ assert_equal "/people/1/update", update_person_path(id: 1)
end
def test_update_project_person
draw do
- get '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person
+ get "/projects/:project_id/people/:id/update", to: "people#update", as: :update_project_person
end
- get '/projects/1/people/2/update'
- assert_equal 'people#update', @response.body
+ get "/projects/1/people/2/update"
+ assert_equal "people#update", @response.body
- assert_equal '/projects/1/people/2/update', update_project_person_path(:project_id => 1, :id => 2)
+ assert_equal "/projects/1/people/2/update", update_project_person_path(project_id: 1, id: 2)
end
def test_forum_products
draw do
namespace :forum do
- resources :products, :path => '' do
+ resources :products, path: "" do
resources :questions
end
end
end
- get '/forum'
- assert_equal 'forum/products#index', @response.body
- assert_equal '/forum', forum_products_path
+ get "/forum"
+ assert_equal "forum/products#index", @response.body
+ assert_equal "/forum", forum_products_path
- get '/forum/basecamp'
- assert_equal 'forum/products#show', @response.body
- assert_equal '/forum/basecamp', forum_product_path(:id => 'basecamp')
+ get "/forum/basecamp"
+ assert_equal "forum/products#show", @response.body
+ assert_equal "/forum/basecamp", forum_product_path(id: "basecamp")
- get '/forum/basecamp/questions'
- assert_equal 'forum/questions#index', @response.body
- assert_equal '/forum/basecamp/questions', forum_product_questions_path(:product_id => 'basecamp')
+ get "/forum/basecamp/questions"
+ assert_equal "forum/questions#index", @response.body
+ assert_equal "/forum/basecamp/questions", forum_product_questions_path(product_id: "basecamp")
- get '/forum/basecamp/questions/1'
- assert_equal 'forum/questions#show', @response.body
- assert_equal '/forum/basecamp/questions/1', forum_product_question_path(:product_id => 'basecamp', :id => 1)
+ get "/forum/basecamp/questions/1"
+ assert_equal "forum/questions#show", @response.body
+ assert_equal "/forum/basecamp/questions/1", forum_product_question_path(product_id: "basecamp", id: 1)
end
def test_articles_perma
draw do
- get 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article
+ get "articles/:year/:month/:day/:title", to: "articles#show", as: :article
end
- get '/articles/2009/08/18/rails-3'
- assert_equal 'articles#show', @response.body
+ get "/articles/2009/08/18/rails-3"
+ assert_equal "articles#show", @response.body
- assert_equal '/articles/2009/8/18/rails-3', article_path(:year => 2009, :month => 8, :day => 18, :title => 'rails-3')
+ assert_equal "/articles/2009/8/18/rails-3", article_path(year: 2009, month: 8, day: 18, title: "rails-3")
end
def test_account_namespace
@@ -1078,17 +1107,17 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/account/subscription'
- assert_equal 'account/subscriptions#show', @response.body
- assert_equal '/account/subscription', account_subscription_path
+ get "/account/subscription"
+ assert_equal "account/subscriptions#show", @response.body
+ assert_equal "/account/subscription", account_subscription_path
- get '/account/credit'
- assert_equal 'account/credits#show', @response.body
- assert_equal '/account/credit', account_credit_path
+ get "/account/credit"
+ assert_equal "account/credits#show", @response.body
+ assert_equal "/account/credit", account_credit_path
- get '/account/credit_card'
- assert_equal 'account/credit_cards#show', @response.body
- assert_equal '/account/credit_card', account_credit_card_path
+ get "/account/credit_card"
+ assert_equal "account/credit_cards#show", @response.body
+ assert_equal "/account/credit_card", account_credit_card_path
end
def test_nested_namespace
@@ -1100,9 +1129,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/account/admin/subscription'
- assert_equal 'account/admin/subscriptions#show', @response.body
- assert_equal '/account/admin/subscription', account_admin_subscription_path
+ get "/account/admin/subscription"
+ assert_equal "account/admin/subscriptions#show", @response.body
+ assert_equal "/account/admin/subscription", account_admin_subscription_path
end
def test_namespace_nested_in_resources
@@ -1118,155 +1147,155 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/clients/1/google/account'
- assert_equal '/clients/1/google/account', client_google_account_path(1)
- assert_equal 'google/accounts#show', @response.body
+ get "/clients/1/google/account"
+ assert_equal "/clients/1/google/account", client_google_account_path(1)
+ assert_equal "google/accounts#show", @response.body
- get '/clients/1/google/account/secret/info'
- assert_equal '/clients/1/google/account/secret/info', client_google_account_secret_info_path(1)
- assert_equal 'google/secret/infos#show', @response.body
+ get "/clients/1/google/account/secret/info"
+ assert_equal "/clients/1/google/account/secret/info", client_google_account_secret_info_path(1)
+ assert_equal "google/secret/infos#show", @response.body
end
def test_namespace_with_options
draw do
- namespace :users, :path => 'usuarios' do
- root :to => 'home#index'
+ namespace :users, path: "usuarios" do
+ root to: "home#index"
end
end
- get '/usuarios'
- assert_equal '/usuarios', users_root_path
- assert_equal 'users/home#index', @response.body
+ get "/usuarios"
+ assert_equal "/usuarios", users_root_path
+ assert_equal "users/home#index", @response.body
end
def test_namespaced_shallow_routes_with_module_option
draw do
- namespace :foo, module: 'bar' do
+ namespace :foo, module: "bar" do
resources :posts, only: [:index, :show] do
resources :comments, only: [:index, :show], shallow: true
end
end
end
- get '/foo/posts'
- assert_equal '/foo/posts', foo_posts_path
- assert_equal 'bar/posts#index', @response.body
+ get "/foo/posts"
+ assert_equal "/foo/posts", foo_posts_path
+ assert_equal "bar/posts#index", @response.body
- get '/foo/posts/1'
- assert_equal '/foo/posts/1', foo_post_path('1')
- assert_equal 'bar/posts#show', @response.body
+ get "/foo/posts/1"
+ assert_equal "/foo/posts/1", foo_post_path("1")
+ assert_equal "bar/posts#show", @response.body
- get '/foo/posts/1/comments'
- assert_equal '/foo/posts/1/comments', foo_post_comments_path('1')
- assert_equal 'bar/comments#index', @response.body
+ get "/foo/posts/1/comments"
+ assert_equal "/foo/posts/1/comments", foo_post_comments_path("1")
+ assert_equal "bar/comments#index", @response.body
- get '/foo/comments/2'
- assert_equal '/foo/comments/2', foo_comment_path('2')
- assert_equal 'bar/comments#show', @response.body
+ get "/foo/comments/2"
+ assert_equal "/foo/comments/2", foo_comment_path("2")
+ assert_equal "bar/comments#show", @response.body
end
def test_namespaced_shallow_routes_with_path_option
draw do
- namespace :foo, path: 'bar' do
+ namespace :foo, path: "bar" do
resources :posts, only: [:index, :show] do
resources :comments, only: [:index, :show], shallow: true
end
end
end
- get '/bar/posts'
- assert_equal '/bar/posts', foo_posts_path
- assert_equal 'foo/posts#index', @response.body
+ get "/bar/posts"
+ assert_equal "/bar/posts", foo_posts_path
+ assert_equal "foo/posts#index", @response.body
- get '/bar/posts/1'
- assert_equal '/bar/posts/1', foo_post_path('1')
- assert_equal 'foo/posts#show', @response.body
+ get "/bar/posts/1"
+ assert_equal "/bar/posts/1", foo_post_path("1")
+ assert_equal "foo/posts#show", @response.body
- get '/bar/posts/1/comments'
- assert_equal '/bar/posts/1/comments', foo_post_comments_path('1')
- assert_equal 'foo/comments#index', @response.body
+ get "/bar/posts/1/comments"
+ assert_equal "/bar/posts/1/comments", foo_post_comments_path("1")
+ assert_equal "foo/comments#index", @response.body
- get '/bar/comments/2'
- assert_equal '/bar/comments/2', foo_comment_path('2')
- assert_equal 'foo/comments#show', @response.body
+ get "/bar/comments/2"
+ assert_equal "/bar/comments/2", foo_comment_path("2")
+ assert_equal "foo/comments#show", @response.body
end
def test_namespaced_shallow_routes_with_as_option
draw do
- namespace :foo, as: 'bar' do
+ namespace :foo, as: "bar" do
resources :posts, only: [:index, :show] do
resources :comments, only: [:index, :show], shallow: true
end
end
end
- get '/foo/posts'
- assert_equal '/foo/posts', bar_posts_path
- assert_equal 'foo/posts#index', @response.body
+ get "/foo/posts"
+ assert_equal "/foo/posts", bar_posts_path
+ assert_equal "foo/posts#index", @response.body
- get '/foo/posts/1'
- assert_equal '/foo/posts/1', bar_post_path('1')
- assert_equal 'foo/posts#show', @response.body
+ get "/foo/posts/1"
+ assert_equal "/foo/posts/1", bar_post_path("1")
+ assert_equal "foo/posts#show", @response.body
- get '/foo/posts/1/comments'
- assert_equal '/foo/posts/1/comments', bar_post_comments_path('1')
- assert_equal 'foo/comments#index', @response.body
+ get "/foo/posts/1/comments"
+ assert_equal "/foo/posts/1/comments", bar_post_comments_path("1")
+ assert_equal "foo/comments#index", @response.body
- get '/foo/comments/2'
- assert_equal '/foo/comments/2', bar_comment_path('2')
- assert_equal 'foo/comments#show', @response.body
+ get "/foo/comments/2"
+ assert_equal "/foo/comments/2", bar_comment_path("2")
+ assert_equal "foo/comments#show", @response.body
end
def test_namespaced_shallow_routes_with_shallow_path_option
draw do
- namespace :foo, shallow_path: 'bar' do
+ namespace :foo, shallow_path: "bar" do
resources :posts, only: [:index, :show] do
resources :comments, only: [:index, :show], shallow: true
end
end
end
- get '/foo/posts'
- assert_equal '/foo/posts', foo_posts_path
- assert_equal 'foo/posts#index', @response.body
+ get "/foo/posts"
+ assert_equal "/foo/posts", foo_posts_path
+ assert_equal "foo/posts#index", @response.body
- get '/foo/posts/1'
- assert_equal '/foo/posts/1', foo_post_path('1')
- assert_equal 'foo/posts#show', @response.body
+ get "/foo/posts/1"
+ assert_equal "/foo/posts/1", foo_post_path("1")
+ assert_equal "foo/posts#show", @response.body
- get '/foo/posts/1/comments'
- assert_equal '/foo/posts/1/comments', foo_post_comments_path('1')
- assert_equal 'foo/comments#index', @response.body
+ get "/foo/posts/1/comments"
+ assert_equal "/foo/posts/1/comments", foo_post_comments_path("1")
+ assert_equal "foo/comments#index", @response.body
- get '/bar/comments/2'
- assert_equal '/bar/comments/2', foo_comment_path('2')
- assert_equal 'foo/comments#show', @response.body
+ get "/bar/comments/2"
+ assert_equal "/bar/comments/2", foo_comment_path("2")
+ assert_equal "foo/comments#show", @response.body
end
def test_namespaced_shallow_routes_with_shallow_prefix_option
draw do
- namespace :foo, shallow_prefix: 'bar' do
+ namespace :foo, shallow_prefix: "bar" do
resources :posts, only: [:index, :show] do
resources :comments, only: [:index, :show], shallow: true
end
end
end
- get '/foo/posts'
- assert_equal '/foo/posts', foo_posts_path
- assert_equal 'foo/posts#index', @response.body
+ get "/foo/posts"
+ assert_equal "/foo/posts", foo_posts_path
+ assert_equal "foo/posts#index", @response.body
- get '/foo/posts/1'
- assert_equal '/foo/posts/1', foo_post_path('1')
- assert_equal 'foo/posts#show', @response.body
+ get "/foo/posts/1"
+ assert_equal "/foo/posts/1", foo_post_path("1")
+ assert_equal "foo/posts#show", @response.body
- get '/foo/posts/1/comments'
- assert_equal '/foo/posts/1/comments', foo_post_comments_path('1')
- assert_equal 'foo/comments#index', @response.body
+ get "/foo/posts/1/comments"
+ assert_equal "/foo/posts/1/comments", foo_post_comments_path("1")
+ assert_equal "foo/comments#index", @response.body
- get '/foo/comments/2'
- assert_equal '/foo/comments/2', bar_comment_path('2')
- assert_equal 'foo/comments#show', @response.body
+ get "/foo/comments/2"
+ assert_equal "/foo/comments/2", bar_comment_path("2")
+ assert_equal "foo/comments#show", @response.body
end
def test_namespace_containing_numbers
@@ -1276,81 +1305,97 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/v2/subscriptions'
- assert_equal 'v2/subscriptions#index', @response.body
- assert_equal '/v2/subscriptions', v2_subscriptions_path
+ get "/v2/subscriptions"
+ assert_equal "v2/subscriptions#index", @response.body
+ assert_equal "/v2/subscriptions", v2_subscriptions_path
end
def test_articles_with_id
draw do
controller :articles do
- scope '/articles', :as => 'article' do
- scope :path => '/:title', :title => /[a-z]+/, :as => :with_title do
- get '/:id', :action => :with_id, :as => ""
+ scope "/articles", as: "article" do
+ scope path: "/:title", title: /[a-z]+/, as: :with_title do
+ get "/:id", action: :with_id, as: ""
end
end
end
end
- get '/articles/rails/1'
- assert_equal 'articles#with_id', @response.body
+ get "/articles/rails/1"
+ assert_equal "articles#with_id", @response.body
- get '/articles/123/1'
- assert_equal 'pass', @response.headers['X-Cascade']
+ get "/articles/123/1"
+ assert_equal "pass", @response.headers["X-Cascade"]
- assert_equal '/articles/rails/1', article_with_title_path(:title => 'rails', :id => 1)
+ assert_equal "/articles/rails/1", article_with_title_path(title: "rails", id: 1)
end
def test_access_token_rooms
draw do
- scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do
+ scope ":access_token", constraints: { access_token: /\w{5,5}/ } do
resources :rooms
end
end
- get '/12345/rooms'
- assert_equal 'rooms#index', @response.body
+ get "/12345/rooms"
+ assert_equal "rooms#index", @response.body
- get '/12345/rooms/1'
- assert_equal 'rooms#show', @response.body
+ get "/12345/rooms/1"
+ assert_equal "rooms#show", @response.body
- get '/12345/rooms/1/edit'
- assert_equal 'rooms#edit', @response.body
+ get "/12345/rooms/1/edit"
+ assert_equal "rooms#edit", @response.body
end
def test_root
draw do
- root :to => 'projects#index'
+ root to: "projects#index"
end
- assert_equal '/', root_path
- get '/'
- assert_equal 'projects#index', @response.body
+ assert_equal "/", root_path
+ get "/"
+ assert_equal "projects#index", @response.body
end
def test_scoped_root
draw do
- scope '(:locale)', :locale => /en|pl/ do
- root :to => 'projects#index'
+ scope "(:locale)", locale: /en|pl/ do
+ root to: "projects#index"
end
end
- assert_equal '/en', root_path(:locale => 'en')
- get '/en'
- assert_equal 'projects#index', @response.body
+ assert_equal "/en", root_path(locale: "en")
+ get "/en"
+ assert_equal "projects#index", @response.body
end
def test_scoped_root_as_name
draw do
- scope '(:locale)', :locale => /en|pl/ do
- root :to => 'projects#index', :as => 'projects'
+ scope "(:locale)", locale: /en|pl/ do
+ root to: "projects#index", as: "projects"
+ end
+ end
+
+ assert_equal "/en", projects_path(locale: "en")
+ assert_equal "/", projects_path
+ get "/en"
+ assert_equal "projects#index", @response.body
+ end
+
+ def test_optionally_scoped_root_unscoped_access
+ draw do
+ scope "(:locale)" do
+ scope "(:platform)" do
+ scope "(:browser)" do
+ root to: "projects#index"
+ end
+ end
end
end
- assert_equal '/en', projects_path(:locale => 'en')
- assert_equal '/', projects_path
- get '/en'
- assert_equal 'projects#index', @response.body
+ assert_equal "/", root_path
+ get "/"
+ assert_equal "projects#index", @response.body
end
def test_scope_with_format_option
@@ -1368,10 +1413,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal "/scoped/index", no_format_scoped_path
assert_equal "/scoped/index?format=html", no_format_scoped_path(format: "html")
- get '/scoped/index'
+ get "/scoped/index"
assert_equal "scoped#index", @response.body
- get '/scoped/index.html'
+ get "/scoped/index.html"
assert_equal "Not Found", @response.body
end
@@ -1406,63 +1451,63 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
def test_index
draw do
- get '/info' => 'projects#info', :as => 'info'
+ get "/info" => "projects#info", :as => "info"
end
- assert_equal '/info', info_path
- get '/info'
- assert_equal 'projects#info', @response.body
+ assert_equal "/info", info_path
+ get "/info"
+ assert_equal "projects#info", @response.body
end
def test_match_with_many_paths_containing_a_slash
draw do
- get 'get/first', 'get/second', 'get/third', :to => 'get#show'
+ get "get/first", "get/second", "get/third", to: "get#show"
end
- get '/get/first'
- assert_equal 'get#show', @response.body
+ get "/get/first"
+ assert_equal "get#show", @response.body
- get '/get/second'
- assert_equal 'get#show', @response.body
+ get "/get/second"
+ assert_equal "get#show", @response.body
- get '/get/third'
- assert_equal 'get#show', @response.body
+ get "/get/third"
+ assert_equal "get#show", @response.body
end
def test_match_shorthand_with_no_scope
draw do
- get 'account/overview'
+ get "account/overview"
end
- assert_equal '/account/overview', account_overview_path
- get '/account/overview'
- assert_equal 'account#overview', @response.body
+ assert_equal "/account/overview", account_overview_path
+ get "/account/overview"
+ assert_equal "account#overview", @response.body
end
def test_match_shorthand_inside_namespace
draw do
namespace :account do
- get 'shorthand'
+ get "shorthand"
end
end
- assert_equal '/account/shorthand', account_shorthand_path
- get '/account/shorthand'
- assert_equal 'account#shorthand', @response.body
+ assert_equal "/account/shorthand", account_shorthand_path
+ get "/account/shorthand"
+ assert_equal "account#shorthand", @response.body
end
def test_match_shorthand_with_multiple_paths_inside_namespace
draw do
namespace :proposals do
- put 'activate', 'inactivate'
+ put "activate", "inactivate"
end
end
- put '/proposals/activate'
- assert_equal 'proposals#activate', @response.body
+ put "/proposals/activate"
+ assert_equal "proposals#activate", @response.body
- put '/proposals/inactivate'
- assert_equal 'proposals#inactivate', @response.body
+ put "/proposals/inactivate"
+ assert_equal "proposals#inactivate", @response.body
end
def test_match_shorthand_inside_namespace_with_controller
@@ -1472,126 +1517,130 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- assert_equal '/api/products/list', api_products_list_path
- get '/api/products/list'
- assert_equal 'api/products#list', @response.body
+ assert_equal "/api/products/list", api_products_list_path
+ get "/api/products/list"
+ assert_equal "api/products#list", @response.body
end
def test_match_shorthand_inside_scope_with_variables_with_controller
draw do
- scope ':locale' do
- match 'questions/new', via: [:get]
+ scope ":locale" do
+ match "questions/new", via: [:get]
end
end
- get '/de/questions/new'
- assert_equal 'questions#new', @response.body
- assert_equal 'de', @request.params[:locale]
+ get "/de/questions/new"
+ assert_equal "questions#new", @response.body
+ assert_equal "de", @request.params[:locale]
end
def test_match_shorthand_inside_nested_namespaces_and_scopes_with_controller
draw do
namespace :api do
namespace :v3 do
- scope ':locale' do
+ scope ":locale" do
get "products/list"
end
end
end
end
- get '/api/v3/en/products/list'
- assert_equal 'api/v3/products#list', @response.body
+ get "/api/v3/en/products/list"
+ assert_equal "api/v3/products#list", @response.body
end
def test_not_matching_shorthand_with_dynamic_parameters
draw do
- get ':controller/:action/admin'
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action/admin"
+ end
end
- get '/finances/overview/admin'
- assert_equal 'finances#overview', @response.body
+ get "/finances/overview/admin"
+ assert_equal "finances#overview", @response.body
end
def test_controller_option_with_nesting_and_leading_slash
draw do
- scope '/job', controller: 'job' do
- scope ':id', action: 'manage_applicant' do
+ scope "/job", controller: "job" do
+ scope ":id", action: "manage_applicant" do
get "/active"
end
end
end
- get '/job/5/active'
- assert_equal 'job#manage_applicant', @response.body
+ get "/job/5/active"
+ assert_equal "job#manage_applicant", @response.body
end
def test_dynamically_generated_helpers_on_collection_do_not_clobber_resources_url_helper
draw do
resources :replies do
collection do
- get 'page/:page' => 'replies#index', :page => %r{\d+}
- get ':page' => 'replies#index', :page => %r{\d+}
+ get "page/:page" => "replies#index", :page => %r{\d+}
+ get ":page" => "replies#index", :page => %r{\d+}
end
end
end
- assert_equal '/replies', replies_path
+ assert_equal "/replies", replies_path
end
def test_scoped_controller_with_namespace_and_action
draw do
namespace :account do
- get ':action/callback', :action => /twitter|github/, :controller => "callbacks", :as => :callback
+ ActiveSupport::Deprecation.silence do
+ get ":action/callback", action: /twitter|github/, controller: "callbacks", as: :callback
+ end
end
end
- assert_equal '/account/twitter/callback', account_callback_path("twitter")
- get '/account/twitter/callback'
- assert_equal 'account/callbacks#twitter', @response.body
+ assert_equal "/account/twitter/callback", account_callback_path("twitter")
+ get "/account/twitter/callback"
+ assert_equal "account/callbacks#twitter", @response.body
- get '/account/whatever/callback'
- assert_equal 'Not Found', @response.body
+ get "/account/whatever/callback"
+ assert_equal "Not Found", @response.body
end
def test_convention_match_nested_and_with_leading_slash
draw do
- get '/account/nested/overview'
+ get "/account/nested/overview"
end
- assert_equal '/account/nested/overview', account_nested_overview_path
- get '/account/nested/overview'
- assert_equal 'account/nested#overview', @response.body
+ assert_equal "/account/nested/overview", account_nested_overview_path
+ get "/account/nested/overview"
+ assert_equal "account/nested#overview", @response.body
end
def test_convention_with_explicit_end
draw do
- get 'sign_in' => "sessions#new"
+ get "sign_in" => "sessions#new"
end
- get '/sign_in'
- assert_equal 'sessions#new', @response.body
- assert_equal '/sign_in', sign_in_path
+ get "/sign_in"
+ assert_equal "sessions#new", @response.body
+ assert_equal "/sign_in", sign_in_path
end
def test_redirect_with_complete_url_and_status
draw do
- get 'account/google' => redirect('http://www.google.com/', :status => 302)
+ get "account/google" => redirect("http://www.google.com/", status: 302)
end
- get '/account/google'
- verify_redirect 'http://www.google.com/', 302
+ get "/account/google"
+ verify_redirect "http://www.google.com/", 302
end
def test_redirect_with_port
draw do
- get 'account/login', :to => redirect("/login")
+ get "account/login", to: redirect("/login")
end
- previous_host, self.host = self.host, 'www.example.com:3000'
+ previous_host, self.host = host, "www.example.com:3000"
- get '/account/login'
- verify_redirect 'http://www.example.com:3000/login'
+ get "/account/login"
+ verify_redirect "http://www.example.com:3000/login"
ensure
self.host = previous_host
end
@@ -1599,270 +1648,310 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
def test_normalize_namespaced_matches
draw do
namespace :account do
- get 'description', :action => :description, :as => "description"
+ get "description", action: :description, as: "description"
end
end
- assert_equal '/account/description', account_description_path
+ assert_equal "/account/description", account_description_path
- get '/account/description'
- assert_equal 'account#description', @response.body
+ get "/account/description"
+ assert_equal "account#description", @response.body
end
def test_namespaced_roots
draw do
namespace :account do
- root :to => "account#index"
+ root to: "account#index"
end
end
- assert_equal '/account', account_root_path
- get '/account'
- assert_equal 'account/account#index', @response.body
+ assert_equal "/account", account_root_path
+ get "/account"
+ assert_equal "account/account#index", @response.body
end
def test_optional_scoped_root
draw do
- scope '(:locale)', :locale => /en|pl/ do
- root :to => 'projects#index'
+ scope "(:locale)", locale: /en|pl/ do
+ root to: "projects#index"
end
end
- assert_equal '/en', root_path("en")
- get '/en'
- assert_equal 'projects#index', @response.body
+ assert_equal "/en", root_path("en")
+ get "/en"
+ assert_equal "projects#index", @response.body
end
def test_optional_scoped_path
draw do
- scope '(:locale)', :locale => /en|pl/ do
+ scope "(:locale)", locale: /en|pl/ do
resources :descriptions
end
end
- assert_equal '/en/descriptions', descriptions_path("en")
- assert_equal '/descriptions', descriptions_path(nil)
- assert_equal '/en/descriptions/1', description_path("en", 1)
- assert_equal '/descriptions/1', description_path(nil, 1)
+ assert_equal "/en/descriptions", descriptions_path("en")
+ assert_equal "/descriptions", descriptions_path(nil)
+ assert_equal "/en/descriptions/1", description_path("en", 1)
+ assert_equal "/descriptions/1", description_path(nil, 1)
- get '/en/descriptions'
- assert_equal 'descriptions#index', @response.body
+ get "/en/descriptions"
+ assert_equal "descriptions#index", @response.body
- get '/descriptions'
- assert_equal 'descriptions#index', @response.body
+ get "/descriptions"
+ assert_equal "descriptions#index", @response.body
- get '/en/descriptions/1'
- assert_equal 'descriptions#show', @response.body
+ get "/en/descriptions/1"
+ assert_equal "descriptions#show", @response.body
- get '/descriptions/1'
- assert_equal 'descriptions#show', @response.body
+ get "/descriptions/1"
+ assert_equal "descriptions#show", @response.body
end
def test_nested_optional_scoped_path
draw do
namespace :admin do
- scope '(:locale)', :locale => /en|pl/ do
+ scope "(:locale)", locale: /en|pl/ do
resources :descriptions
end
end
end
- assert_equal '/admin/en/descriptions', admin_descriptions_path("en")
- assert_equal '/admin/descriptions', admin_descriptions_path(nil)
- assert_equal '/admin/en/descriptions/1', admin_description_path("en", 1)
- assert_equal '/admin/descriptions/1', admin_description_path(nil, 1)
+ assert_equal "/admin/en/descriptions", admin_descriptions_path("en")
+ assert_equal "/admin/descriptions", admin_descriptions_path(nil)
+ assert_equal "/admin/en/descriptions/1", admin_description_path("en", 1)
+ assert_equal "/admin/descriptions/1", admin_description_path(nil, 1)
- get '/admin/en/descriptions'
- assert_equal 'admin/descriptions#index', @response.body
+ get "/admin/en/descriptions"
+ assert_equal "admin/descriptions#index", @response.body
- get '/admin/descriptions'
- assert_equal 'admin/descriptions#index', @response.body
+ get "/admin/descriptions"
+ assert_equal "admin/descriptions#index", @response.body
- get '/admin/en/descriptions/1'
- assert_equal 'admin/descriptions#show', @response.body
+ get "/admin/en/descriptions/1"
+ assert_equal "admin/descriptions#show", @response.body
- get '/admin/descriptions/1'
- assert_equal 'admin/descriptions#show', @response.body
+ get "/admin/descriptions/1"
+ assert_equal "admin/descriptions#show", @response.body
end
def test_nested_optional_path_shorthand
draw do
- scope '(:locale)', :locale => /en|pl/ do
+ scope "(:locale)", locale: /en|pl/ do
get "registrations/new"
end
end
- get '/registrations/new'
+ get "/registrations/new"
assert_nil @request.params[:locale]
- get '/en/registrations/new'
- assert_equal 'en', @request.params[:locale]
+ get "/en/registrations/new"
+ assert_equal "en", @request.params[:locale]
end
def test_default_string_params
draw do
- get 'inline_pages/(:id)', :to => 'pages#show', :id => 'home'
- get 'default_pages/(:id)', :to => 'pages#show', :defaults => { :id => 'home' }
+ get "inline_pages/(:id)", to: "pages#show", id: "home"
+ get "default_pages/(:id)", to: "pages#show", defaults: { id: "home" }
- defaults :id => 'home' do
- get 'scoped_pages/(:id)', :to => 'pages#show'
+ defaults id: "home" do
+ get "scoped_pages/(:id)", to: "pages#show"
end
end
- get '/inline_pages'
- assert_equal 'home', @request.params[:id]
+ get "/inline_pages"
+ assert_equal "home", @request.params[:id]
- get '/default_pages'
- assert_equal 'home', @request.params[:id]
+ get "/default_pages"
+ assert_equal "home", @request.params[:id]
- get '/scoped_pages'
- assert_equal 'home', @request.params[:id]
+ get "/scoped_pages"
+ assert_equal "home", @request.params[:id]
end
def test_default_integer_params
draw do
- get 'inline_pages/(:page)', to: 'pages#show', page: 1
- get 'default_pages/(:page)', to: 'pages#show', defaults: { page: 1 }
+ get "inline_pages/(:page)", to: "pages#show", page: 1
+ get "default_pages/(:page)", to: "pages#show", defaults: { page: 1 }
defaults page: 1 do
- get 'scoped_pages/(:page)', to: 'pages#show'
+ get "scoped_pages/(:page)", to: "pages#show"
end
end
- get '/inline_pages'
+ get "/inline_pages"
assert_equal 1, @request.params[:page]
- get '/default_pages'
+ get "/default_pages"
assert_equal 1, @request.params[:page]
- get '/scoped_pages'
+ get "/scoped_pages"
assert_equal 1, @request.params[:page]
end
+ def test_keyed_default_string_params_with_match
+ draw do
+ match "/", to: "pages#show", via: :get, defaults: { id: "home" }
+ end
+
+ get "/"
+ assert_equal "home", @request.params[:id]
+ end
+
+ def test_default_string_params_with_match
+ draw do
+ match "/", to: "pages#show", via: :get, id: "home"
+ end
+
+ get "/"
+ assert_equal "home", @request.params[:id]
+ end
+
+ def test_keyed_default_string_params_with_root
+ draw do
+ root to: "pages#show", defaults: { id: "home" }
+ end
+
+ get "/"
+ assert_equal "home", @request.params[:id]
+ end
+
+ def test_default_string_params_with_root
+ draw do
+ root to: "pages#show", id: "home"
+ end
+
+ get "/"
+ assert_equal "home", @request.params[:id]
+ end
+
def test_resource_constraints
draw do
- resources :products, :constraints => { :id => /\d{4}/ } do
- root :to => "products#root"
- get :favorite, :on => :collection
+ resources :products, constraints: { id: /\d{4}/ } do
+ root to: "products#root"
+ get :favorite, on: :collection
resources :images
end
- resource :dashboard, :constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
+ resource :dashboard, constraints: { ip: /192\.168\.1\.\d{1,3}/ }
end
- get '/products/1'
- assert_equal 'pass', @response.headers['X-Cascade']
- get '/products'
- assert_equal 'products#root', @response.body
- get '/products/favorite'
- assert_equal 'products#favorite', @response.body
- get '/products/0001'
- assert_equal 'products#show', @response.body
+ get "/products/1"
+ assert_equal "pass", @response.headers["X-Cascade"]
+ get "/products"
+ assert_equal "products#root", @response.body
+ get "/products/favorite"
+ assert_equal "products#favorite", @response.body
+ get "/products/0001"
+ assert_equal "products#show", @response.body
- get '/products/1/images'
- assert_equal 'pass', @response.headers['X-Cascade']
- get '/products/0001/images'
- assert_equal 'images#index', @response.body
- get '/products/0001/images/0001'
- assert_equal 'images#show', @response.body
+ get "/products/1/images"
+ assert_equal "pass", @response.headers["X-Cascade"]
+ get "/products/0001/images"
+ assert_equal "images#index", @response.body
+ get "/products/0001/images/0001"
+ assert_equal "images#show", @response.body
- get '/dashboard', headers: { 'REMOTE_ADDR' => '10.0.0.100' }
- assert_equal 'pass', @response.headers['X-Cascade']
- get '/dashboard', headers: { 'REMOTE_ADDR' => '192.168.1.100' }
- assert_equal 'dashboards#show', @response.body
+ get "/dashboard", headers: { "REMOTE_ADDR" => "10.0.0.100" }
+ assert_equal "pass", @response.headers["X-Cascade"]
+ get "/dashboard", headers: { "REMOTE_ADDR" => "192.168.1.100" }
+ assert_equal "dashboards#show", @response.body
end
def test_root_works_in_the_resources_scope
draw do
resources :products do
- root :to => "products#root"
+ root to: "products#root"
end
end
- get '/products'
- assert_equal 'products#root', @response.body
- assert_equal '/products', products_root_path
+ get "/products"
+ assert_equal "products#root", @response.body
+ assert_equal "/products", products_root_path
end
def test_module_scope
draw do
- resource :token, :module => :api
+ resource :token, module: :api
end
- get '/token'
- assert_equal 'api/tokens#show', @response.body
- assert_equal '/token', token_path
+ get "/token"
+ assert_equal "api/tokens#show", @response.body
+ assert_equal "/token", token_path
end
def test_path_scope
draw do
- scope :path => 'api' do
+ scope path: "api" do
resource :me
- get '/' => 'mes#index'
+ get "/" => "mes#index"
end
end
- get '/api/me'
- assert_equal 'mes#show', @response.body
- assert_equal '/api/me', me_path
+ get "/api/me"
+ assert_equal "mes#show", @response.body
+ assert_equal "/api/me", me_path
- get '/api'
- assert_equal 'mes#index', @response.body
+ get "/api"
+ assert_equal "mes#index", @response.body
end
def test_symbol_scope
draw do
- scope :path => 'api' do
+ scope path: "api" do
scope :v2 do
- resource :me, as: 'v2_me'
- get '/' => 'mes#index'
+ resource :me, as: "v2_me"
+ get "/" => "mes#index"
end
scope :v3, :admin do
- resource :me, as: 'v3_me'
+ resource :me, as: "v3_me"
end
end
end
- get '/api/v2/me'
- assert_equal 'mes#show', @response.body
- assert_equal '/api/v2/me', v2_me_path
+ get "/api/v2/me"
+ assert_equal "mes#show", @response.body
+ assert_equal "/api/v2/me", v2_me_path
- get '/api/v2'
- assert_equal 'mes#index', @response.body
+ get "/api/v2"
+ assert_equal "mes#index", @response.body
- get '/api/v3/admin/me'
- assert_equal 'mes#show', @response.body
+ get "/api/v3/admin/me"
+ assert_equal "mes#show", @response.body
end
def test_url_generator_for_generic_route
draw do
- get "whatever/:controller(/:action(/:id))"
+ ActiveSupport::Deprecation.silence do
+ get "whatever/:controller(/:action(/:id))"
+ end
end
- get '/whatever/foo/bar'
- assert_equal 'foo#bar', @response.body
+ get "/whatever/foo/bar"
+ assert_equal "foo#bar", @response.body
- assert_equal 'http://www.example.com/whatever/foo/bar/1',
- url_for(:controller => "foo", :action => "bar", :id => 1)
+ assert_equal "http://www.example.com/whatever/foo/bar/1",
+ url_for(controller: "foo", action: "bar", id: 1)
end
def test_url_generator_for_namespaced_generic_route
draw do
- get "whatever/:controller(/:action(/:id))", :id => /\d+/
+ ActiveSupport::Deprecation.silence do
+ get "whatever/:controller(/:action(/:id))", id: /\d+/
+ end
end
- get '/whatever/foo/bar/show'
- assert_equal 'foo/bar#show', @response.body
+ get "/whatever/foo/bar/show"
+ assert_equal "foo/bar#show", @response.body
- get '/whatever/foo/bar/show/1'
- assert_equal 'foo/bar#show', @response.body
+ get "/whatever/foo/bar/show/1"
+ assert_equal "foo/bar#show", @response.body
- assert_equal 'http://www.example.com/whatever/foo/bar/show',
- url_for(:controller => "foo/bar", :action => "show")
+ assert_equal "http://www.example.com/whatever/foo/bar/show",
+ url_for(controller: "foo/bar", action: "show")
- assert_equal 'http://www.example.com/whatever/foo/bar/show/1',
- url_for(:controller => "foo/bar", :action => "show", :id => '1')
+ assert_equal "http://www.example.com/whatever/foo/bar/show/1",
+ url_for(controller: "foo/bar", action: "show", id: "1")
end
def test_resource_new_actions
@@ -1873,16 +1962,16 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- scope 'pt', :as => 'pt' do
- resources :projects, :path_names => { :new => 'novo' }, :path => 'projetos' do
- post :preview, :on => :new
+ scope "pt", as: "pt" do
+ resources :projects, path_names: { new: "novo" }, path: "projetos" do
+ post :preview, on: :new
end
- resource :admin, :path_names => { :new => 'novo' }, :path => 'administrador' do
- post :preview, :on => :new
+ resource :admin, path_names: { new: "novo" }, path: "administrador" do
+ post :preview, on: :new
end
- resources :products, :path_names => { :new => 'novo' } do
+ resources :products, path_names: { new: "novo" } do
new do
post :preview
end
@@ -1896,58 +1985,58 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- assert_equal '/replies/new/preview', preview_new_reply_path
- assert_equal '/pt/projetos/novo/preview', preview_new_pt_project_path
- assert_equal '/pt/administrador/novo/preview', preview_new_pt_admin_path
- assert_equal '/pt/products/novo/preview', preview_new_pt_product_path
- assert_equal '/profile/new/preview', preview_new_profile_path
+ assert_equal "/replies/new/preview", preview_new_reply_path
+ assert_equal "/pt/projetos/novo/preview", preview_new_pt_project_path
+ assert_equal "/pt/administrador/novo/preview", preview_new_pt_admin_path
+ assert_equal "/pt/products/novo/preview", preview_new_pt_product_path
+ assert_equal "/profile/new/preview", preview_new_profile_path
- post '/replies/new/preview'
- assert_equal 'replies#preview', @response.body
+ post "/replies/new/preview"
+ assert_equal "replies#preview", @response.body
- post '/pt/projetos/novo/preview'
- assert_equal 'projects#preview', @response.body
+ post "/pt/projetos/novo/preview"
+ assert_equal "projects#preview", @response.body
- post '/pt/administrador/novo/preview'
- assert_equal 'admins#preview', @response.body
+ post "/pt/administrador/novo/preview"
+ assert_equal "admins#preview", @response.body
- post '/pt/products/novo/preview'
- assert_equal 'products#preview', @response.body
+ post "/pt/products/novo/preview"
+ assert_equal "products#preview", @response.body
- post '/profile/new/preview'
- assert_equal 'profiles#preview', @response.body
+ post "/profile/new/preview"
+ assert_equal "profiles#preview", @response.body
end
def test_resource_merges_options_from_scope
draw do
- scope :only => :show do
+ scope only: :show do
resource :account
end
end
assert_raise(NoMethodError) { new_account_path }
- get '/account/new'
+ get "/account/new"
assert_equal 404, status
end
def test_resources_merges_options_from_scope
draw do
- scope :only => [:index, :show] do
+ scope only: [:index, :show] do
resources :products do
resources :images
end
end
end
- assert_raise(NoMethodError) { edit_product_path('1') }
+ assert_raise(NoMethodError) { edit_product_path("1") }
- get '/products/1/edit'
+ get "/products/1/edit"
assert_equal 404, status
- assert_raise(NoMethodError) { edit_product_image_path('1', '2') }
+ assert_raise(NoMethodError) { edit_product_image_path("1", "2") }
- post '/products/1/images/2/edit'
+ post "/products/1/images/2/edit"
assert_equal 404, status
end
@@ -1962,7 +2051,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- resources :threads, :shallow => true do
+ resources :threads, shallow: true do
resource :owner
resources :messages do
resources :comments do
@@ -1974,105 +2063,105 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/api/teams'
- assert_equal 'api/teams#index', @response.body
- assert_equal '/api/teams', api_teams_path
+ get "/api/teams"
+ assert_equal "api/teams#index", @response.body
+ assert_equal "/api/teams", api_teams_path
- get '/api/teams/new'
- assert_equal 'api/teams#new', @response.body
- assert_equal '/api/teams/new', new_api_team_path
+ get "/api/teams/new"
+ assert_equal "api/teams#new", @response.body
+ assert_equal "/api/teams/new", new_api_team_path
- get '/api/teams/1'
- assert_equal 'api/teams#show', @response.body
- assert_equal '/api/teams/1', api_team_path(:id => '1')
+ get "/api/teams/1"
+ assert_equal "api/teams#show", @response.body
+ assert_equal "/api/teams/1", api_team_path(id: "1")
- get '/api/teams/1/edit'
- assert_equal 'api/teams#edit', @response.body
- assert_equal '/api/teams/1/edit', edit_api_team_path(:id => '1')
+ get "/api/teams/1/edit"
+ assert_equal "api/teams#edit", @response.body
+ assert_equal "/api/teams/1/edit", edit_api_team_path(id: "1")
- get '/api/teams/1/players'
- assert_equal 'api/players#index', @response.body
- assert_equal '/api/teams/1/players', api_team_players_path(:team_id => '1')
+ get "/api/teams/1/players"
+ assert_equal "api/players#index", @response.body
+ assert_equal "/api/teams/1/players", api_team_players_path(team_id: "1")
- get '/api/teams/1/players/new'
- assert_equal 'api/players#new', @response.body
- assert_equal '/api/teams/1/players/new', new_api_team_player_path(:team_id => '1')
+ get "/api/teams/1/players/new"
+ assert_equal "api/players#new", @response.body
+ assert_equal "/api/teams/1/players/new", new_api_team_player_path(team_id: "1")
- get '/api/players/2'
- assert_equal 'api/players#show', @response.body
- assert_equal '/api/players/2', api_player_path(:id => '2')
+ get "/api/players/2"
+ assert_equal "api/players#show", @response.body
+ assert_equal "/api/players/2", api_player_path(id: "2")
- get '/api/players/2/edit'
- assert_equal 'api/players#edit', @response.body
- assert_equal '/api/players/2/edit', edit_api_player_path(:id => '2')
+ get "/api/players/2/edit"
+ assert_equal "api/players#edit", @response.body
+ assert_equal "/api/players/2/edit", edit_api_player_path(id: "2")
- get '/api/teams/1/captain'
- assert_equal 'api/captains#show', @response.body
- assert_equal '/api/teams/1/captain', api_team_captain_path(:team_id => '1')
+ get "/api/teams/1/captain"
+ assert_equal "api/captains#show", @response.body
+ assert_equal "/api/teams/1/captain", api_team_captain_path(team_id: "1")
- get '/api/teams/1/captain/new'
- assert_equal 'api/captains#new', @response.body
- assert_equal '/api/teams/1/captain/new', new_api_team_captain_path(:team_id => '1')
+ get "/api/teams/1/captain/new"
+ assert_equal "api/captains#new", @response.body
+ assert_equal "/api/teams/1/captain/new", new_api_team_captain_path(team_id: "1")
- get '/api/teams/1/captain/edit'
- assert_equal 'api/captains#edit', @response.body
- assert_equal '/api/teams/1/captain/edit', edit_api_team_captain_path(:team_id => '1')
+ get "/api/teams/1/captain/edit"
+ assert_equal "api/captains#edit", @response.body
+ assert_equal "/api/teams/1/captain/edit", edit_api_team_captain_path(team_id: "1")
- get '/threads'
- assert_equal 'threads#index', @response.body
- assert_equal '/threads', threads_path
+ get "/threads"
+ assert_equal "threads#index", @response.body
+ assert_equal "/threads", threads_path
- get '/threads/new'
- assert_equal 'threads#new', @response.body
- assert_equal '/threads/new', new_thread_path
+ get "/threads/new"
+ assert_equal "threads#new", @response.body
+ assert_equal "/threads/new", new_thread_path
- get '/threads/1'
- assert_equal 'threads#show', @response.body
- assert_equal '/threads/1', thread_path(:id => '1')
+ get "/threads/1"
+ assert_equal "threads#show", @response.body
+ assert_equal "/threads/1", thread_path(id: "1")
- get '/threads/1/edit'
- assert_equal 'threads#edit', @response.body
- assert_equal '/threads/1/edit', edit_thread_path(:id => '1')
+ get "/threads/1/edit"
+ assert_equal "threads#edit", @response.body
+ assert_equal "/threads/1/edit", edit_thread_path(id: "1")
- get '/threads/1/owner'
- assert_equal 'owners#show', @response.body
- assert_equal '/threads/1/owner', thread_owner_path(:thread_id => '1')
+ get "/threads/1/owner"
+ assert_equal "owners#show", @response.body
+ assert_equal "/threads/1/owner", thread_owner_path(thread_id: "1")
- get '/threads/1/messages'
- assert_equal 'messages#index', @response.body
- assert_equal '/threads/1/messages', thread_messages_path(:thread_id => '1')
+ get "/threads/1/messages"
+ assert_equal "messages#index", @response.body
+ assert_equal "/threads/1/messages", thread_messages_path(thread_id: "1")
- get '/threads/1/messages/new'
- assert_equal 'messages#new', @response.body
- assert_equal '/threads/1/messages/new', new_thread_message_path(:thread_id => '1')
+ get "/threads/1/messages/new"
+ assert_equal "messages#new", @response.body
+ assert_equal "/threads/1/messages/new", new_thread_message_path(thread_id: "1")
- get '/messages/2'
- assert_equal 'messages#show', @response.body
- assert_equal '/messages/2', message_path(:id => '2')
+ get "/messages/2"
+ assert_equal "messages#show", @response.body
+ assert_equal "/messages/2", message_path(id: "2")
- get '/messages/2/edit'
- assert_equal 'messages#edit', @response.body
- assert_equal '/messages/2/edit', edit_message_path(:id => '2')
+ get "/messages/2/edit"
+ assert_equal "messages#edit", @response.body
+ assert_equal "/messages/2/edit", edit_message_path(id: "2")
- get '/messages/2/comments'
- assert_equal 'comments#index', @response.body
- assert_equal '/messages/2/comments', message_comments_path(:message_id => '2')
+ get "/messages/2/comments"
+ assert_equal "comments#index", @response.body
+ assert_equal "/messages/2/comments", message_comments_path(message_id: "2")
- get '/messages/2/comments/new'
- assert_equal 'comments#new', @response.body
- assert_equal '/messages/2/comments/new', new_message_comment_path(:message_id => '2')
+ get "/messages/2/comments/new"
+ assert_equal "comments#new", @response.body
+ assert_equal "/messages/2/comments/new", new_message_comment_path(message_id: "2")
- get '/comments/3'
- assert_equal 'comments#show', @response.body
- assert_equal '/comments/3', comment_path(:id => '3')
+ get "/comments/3"
+ assert_equal "comments#show", @response.body
+ assert_equal "/comments/3", comment_path(id: "3")
- get '/comments/3/edit'
- assert_equal 'comments#edit', @response.body
- assert_equal '/comments/3/edit', edit_comment_path(:id => '3')
+ get "/comments/3/edit"
+ assert_equal "comments#edit", @response.body
+ assert_equal "/comments/3/edit", edit_comment_path(id: "3")
- post '/comments/3/preview'
- assert_equal 'comments#preview', @response.body
- assert_equal '/comments/3/preview', preview_comment_path(:id => '3')
+ post "/comments/3/preview"
+ assert_equal "comments#preview", @response.body
+ assert_equal "/comments/3/preview", preview_comment_path(id: "3")
end
def test_shallow_nested_resources_inside_resource
@@ -2082,33 +2171,33 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/membership/cards'
- assert_equal 'cards#index', @response.body
- assert_equal '/membership/cards', membership_cards_path
+ get "/membership/cards"
+ assert_equal "cards#index", @response.body
+ assert_equal "/membership/cards", membership_cards_path
- get '/membership/cards/new'
- assert_equal 'cards#new', @response.body
- assert_equal '/membership/cards/new', new_membership_card_path
+ get "/membership/cards/new"
+ assert_equal "cards#new", @response.body
+ assert_equal "/membership/cards/new", new_membership_card_path
- post '/membership/cards'
- assert_equal 'cards#create', @response.body
+ post "/membership/cards"
+ assert_equal "cards#create", @response.body
- get '/cards/1'
- assert_equal 'cards#show', @response.body
- assert_equal '/cards/1', card_path('1')
+ get "/cards/1"
+ assert_equal "cards#show", @response.body
+ assert_equal "/cards/1", card_path("1")
- get '/cards/1/edit'
- assert_equal 'cards#edit', @response.body
- assert_equal '/cards/1/edit', edit_card_path('1')
+ get "/cards/1/edit"
+ assert_equal "cards#edit", @response.body
+ assert_equal "/cards/1/edit", edit_card_path("1")
- put '/cards/1'
- assert_equal 'cards#update', @response.body
+ put "/cards/1"
+ assert_equal "cards#update", @response.body
- patch '/cards/1'
- assert_equal 'cards#update', @response.body
+ patch "/cards/1"
+ assert_equal "cards#update", @response.body
- delete '/cards/1'
- assert_equal 'cards#destroy', @response.body
+ delete "/cards/1"
+ assert_equal "cards#destroy", @response.body
end
def test_shallow_deeply_nested_resources
@@ -2120,13 +2209,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/comments/1'
- assert_equal 'comments#show', @response.body
+ get "/comments/1"
+ assert_equal "comments#show", @response.body
- assert_equal '/comments/1', comment_path('1')
- assert_equal '/blogs/new', new_blog_path
- assert_equal '/blogs/1/posts/new', new_blog_post_path(:blog_id => 1)
- assert_equal '/blogs/1/posts/2/comments/new', new_blog_post_comment_path(:blog_id => 1, :post_id => 2)
+ assert_equal "/comments/1", comment_path("1")
+ assert_equal "/blogs/new", new_blog_path
+ assert_equal "/blogs/1/posts/new", new_blog_post_path(blog_id: 1)
+ 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
@@ -2138,22 +2227,22 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- post '/posts/1/comments'
- assert_equal 'comments#create', @response.body
- assert_equal '/posts/1/comments', post_comments_path('1')
+ 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/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')
+ 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
+ scope "/hello" do
shallow do
resources :notes do
resources :trackbacks
@@ -2162,120 +2251,120 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/hello/notes/1/trackbacks'
- assert_equal 'trackbacks#index', @response.body
- assert_equal '/hello/notes/1/trackbacks', note_trackbacks_path(:note_id => 1)
+ get "/hello/notes/1/trackbacks"
+ assert_equal "trackbacks#index", @response.body
+ assert_equal "/hello/notes/1/trackbacks", note_trackbacks_path(note_id: 1)
- get '/hello/notes/1/edit'
- assert_equal 'notes#edit', @response.body
- assert_equal '/hello/notes/1/edit', edit_note_path(:id => '1')
+ get "/hello/notes/1/edit"
+ assert_equal "notes#edit", @response.body
+ assert_equal "/hello/notes/1/edit", edit_note_path(id: "1")
- get '/hello/notes/1/trackbacks/new'
- assert_equal 'trackbacks#new', @response.body
- assert_equal '/hello/notes/1/trackbacks/new', new_note_trackback_path(:note_id => 1)
+ get "/hello/notes/1/trackbacks/new"
+ assert_equal "trackbacks#new", @response.body
+ assert_equal "/hello/notes/1/trackbacks/new", new_note_trackback_path(note_id: 1)
- get '/hello/trackbacks/1'
- assert_equal 'trackbacks#show', @response.body
- assert_equal '/hello/trackbacks/1', trackback_path(:id => '1')
+ get "/hello/trackbacks/1"
+ assert_equal "trackbacks#show", @response.body
+ assert_equal "/hello/trackbacks/1", trackback_path(id: "1")
- get '/hello/trackbacks/1/edit'
- assert_equal 'trackbacks#edit', @response.body
- assert_equal '/hello/trackbacks/1/edit', edit_trackback_path(:id => '1')
+ get "/hello/trackbacks/1/edit"
+ assert_equal "trackbacks#edit", @response.body
+ assert_equal "/hello/trackbacks/1/edit", edit_trackback_path(id: "1")
- put '/hello/trackbacks/1'
- assert_equal 'trackbacks#update', @response.body
+ put "/hello/trackbacks/1"
+ assert_equal "trackbacks#update", @response.body
- post '/hello/notes/1/trackbacks'
- assert_equal 'trackbacks#create', @response.body
+ post "/hello/notes/1/trackbacks"
+ assert_equal "trackbacks#create", @response.body
- delete '/hello/trackbacks/1'
- assert_equal 'trackbacks#destroy', @response.body
+ delete "/hello/trackbacks/1"
+ assert_equal "trackbacks#destroy", @response.body
- get '/hello/notes'
- assert_equal 'notes#index', @response.body
+ get "/hello/notes"
+ assert_equal "notes#index", @response.body
- post '/hello/notes'
- assert_equal 'notes#create', @response.body
+ post "/hello/notes"
+ assert_equal "notes#create", @response.body
- get '/hello/notes/new'
- assert_equal 'notes#new', @response.body
- assert_equal '/hello/notes/new', new_note_path
+ get "/hello/notes/new"
+ assert_equal "notes#new", @response.body
+ assert_equal "/hello/notes/new", new_note_path
- get '/hello/notes/1'
- assert_equal 'notes#show', @response.body
- assert_equal '/hello/notes/1', note_path(:id => 1)
+ get "/hello/notes/1"
+ assert_equal "notes#show", @response.body
+ assert_equal "/hello/notes/1", note_path(id: 1)
- put '/hello/notes/1'
- assert_equal 'notes#update', @response.body
+ put "/hello/notes/1"
+ assert_equal "notes#update", @response.body
- delete '/hello/notes/1'
- assert_equal 'notes#destroy', @response.body
+ delete "/hello/notes/1"
+ assert_equal "notes#destroy", @response.body
end
def test_shallow_option_nested_resources_within_scope
draw do
- scope '/hello' do
- resources :notes, :shallow => true do
+ scope "/hello" do
+ resources :notes, shallow: true do
resources :trackbacks
end
end
end
- get '/hello/notes/1/trackbacks'
- assert_equal 'trackbacks#index', @response.body
- assert_equal '/hello/notes/1/trackbacks', note_trackbacks_path(:note_id => 1)
+ get "/hello/notes/1/trackbacks"
+ assert_equal "trackbacks#index", @response.body
+ assert_equal "/hello/notes/1/trackbacks", note_trackbacks_path(note_id: 1)
- get '/hello/notes/1/edit'
- assert_equal 'notes#edit', @response.body
- assert_equal '/hello/notes/1/edit', edit_note_path(:id => '1')
+ get "/hello/notes/1/edit"
+ assert_equal "notes#edit", @response.body
+ assert_equal "/hello/notes/1/edit", edit_note_path(id: "1")
- get '/hello/notes/1/trackbacks/new'
- assert_equal 'trackbacks#new', @response.body
- assert_equal '/hello/notes/1/trackbacks/new', new_note_trackback_path(:note_id => 1)
+ get "/hello/notes/1/trackbacks/new"
+ assert_equal "trackbacks#new", @response.body
+ assert_equal "/hello/notes/1/trackbacks/new", new_note_trackback_path(note_id: 1)
- get '/hello/trackbacks/1'
- assert_equal 'trackbacks#show', @response.body
- assert_equal '/hello/trackbacks/1', trackback_path(:id => '1')
+ get "/hello/trackbacks/1"
+ assert_equal "trackbacks#show", @response.body
+ assert_equal "/hello/trackbacks/1", trackback_path(id: "1")
- get '/hello/trackbacks/1/edit'
- assert_equal 'trackbacks#edit', @response.body
- assert_equal '/hello/trackbacks/1/edit', edit_trackback_path(:id => '1')
+ get "/hello/trackbacks/1/edit"
+ assert_equal "trackbacks#edit", @response.body
+ assert_equal "/hello/trackbacks/1/edit", edit_trackback_path(id: "1")
- put '/hello/trackbacks/1'
- assert_equal 'trackbacks#update', @response.body
+ put "/hello/trackbacks/1"
+ assert_equal "trackbacks#update", @response.body
- post '/hello/notes/1/trackbacks'
- assert_equal 'trackbacks#create', @response.body
+ post "/hello/notes/1/trackbacks"
+ assert_equal "trackbacks#create", @response.body
- delete '/hello/trackbacks/1'
- assert_equal 'trackbacks#destroy', @response.body
+ delete "/hello/trackbacks/1"
+ assert_equal "trackbacks#destroy", @response.body
- get '/hello/notes'
- assert_equal 'notes#index', @response.body
+ get "/hello/notes"
+ assert_equal "notes#index", @response.body
- post '/hello/notes'
- assert_equal 'notes#create', @response.body
+ post "/hello/notes"
+ assert_equal "notes#create", @response.body
- get '/hello/notes/new'
- assert_equal 'notes#new', @response.body
- assert_equal '/hello/notes/new', new_note_path
+ get "/hello/notes/new"
+ assert_equal "notes#new", @response.body
+ assert_equal "/hello/notes/new", new_note_path
- get '/hello/notes/1'
- assert_equal 'notes#show', @response.body
- assert_equal '/hello/notes/1', note_path(:id => 1)
+ get "/hello/notes/1"
+ assert_equal "notes#show", @response.body
+ assert_equal "/hello/notes/1", note_path(id: 1)
- put '/hello/notes/1'
- assert_equal 'notes#update', @response.body
+ put "/hello/notes/1"
+ assert_equal "notes#update", @response.body
- delete '/hello/notes/1'
- assert_equal 'notes#destroy', @response.body
+ delete "/hello/notes/1"
+ assert_equal "notes#destroy", @response.body
end
def test_custom_resource_routes_are_scoped
draw do
resources :customers do
- get :recent, :on => :collection
- get "profile", :on => :member
+ get :recent, on: :collection
+ get "profile", on: :member
get "secret/profile" => "customers#secret", :on => :member
post "preview" => "customers#preview", :as => :another_preview, :on => :new
resource :avatar do
@@ -2283,11 +2372,11 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
resources :invoices do
get "outstanding" => "invoices#outstanding", :on => :collection
- get "overdue", :action => :overdue, :on => :collection
+ get "overdue", action: :overdue, on: :collection
get "print" => "invoices#print", :as => :print, :on => :member
post "preview" => "invoices#preview", :as => :preview, :on => :new
end
- resources :notes, :shallow => true do
+ resources :notes, shallow: true do
get "preview" => "notes#preview", :as => :preview, :on => :new
get "print" => "notes#print", :as => :print, :on => :member
end
@@ -2302,79 +2391,79 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- assert_equal '/customers/recent', recent_customers_path
- assert_equal '/customers/1/profile', profile_customer_path(:id => '1')
- assert_equal '/customers/1/secret/profile', secret_profile_customer_path(:id => '1')
- assert_equal '/customers/new/preview', another_preview_new_customer_path
- assert_equal '/customers/1/avatar/thumbnail.jpg', thumbnail_customer_avatar_path(:customer_id => '1', :format => :jpg)
- assert_equal '/customers/1/invoices/outstanding', outstanding_customer_invoices_path(:customer_id => '1')
- assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')
- assert_equal '/customers/1/invoices/new/preview', preview_new_customer_invoice_path(:customer_id => '1')
- assert_equal '/customers/1/notes/new/preview', preview_new_customer_note_path(:customer_id => '1')
- assert_equal '/notes/1/print', print_note_path(:id => '1')
- assert_equal '/api/customers/recent', recent_api_customers_path
- assert_equal '/api/customers/1/profile', profile_api_customer_path(:id => '1')
- assert_equal '/api/customers/new/preview', preview_new_api_customer_path
+ assert_equal "/customers/recent", recent_customers_path
+ assert_equal "/customers/1/profile", profile_customer_path(id: "1")
+ assert_equal "/customers/1/secret/profile", secret_profile_customer_path(id: "1")
+ assert_equal "/customers/new/preview", another_preview_new_customer_path
+ assert_equal "/customers/1/avatar/thumbnail.jpg", thumbnail_customer_avatar_path(customer_id: "1", format: :jpg)
+ assert_equal "/customers/1/invoices/outstanding", outstanding_customer_invoices_path(customer_id: "1")
+ assert_equal "/customers/1/invoices/2/print", print_customer_invoice_path(customer_id: "1", id: "2")
+ assert_equal "/customers/1/invoices/new/preview", preview_new_customer_invoice_path(customer_id: "1")
+ assert_equal "/customers/1/notes/new/preview", preview_new_customer_note_path(customer_id: "1")
+ assert_equal "/notes/1/print", print_note_path(id: "1")
+ assert_equal "/api/customers/recent", recent_api_customers_path
+ assert_equal "/api/customers/1/profile", profile_api_customer_path(id: "1")
+ assert_equal "/api/customers/new/preview", preview_new_api_customer_path
- get '/customers/1/invoices/overdue'
- assert_equal 'invoices#overdue', @response.body
+ get "/customers/1/invoices/overdue"
+ assert_equal "invoices#overdue", @response.body
- get '/customers/1/secret/profile'
- assert_equal 'customers#secret', @response.body
+ get "/customers/1/secret/profile"
+ assert_equal "customers#secret", @response.body
end
def test_shallow_nested_routes_ignore_module
draw do
- scope :module => :api do
- resources :errors, :shallow => true do
+ scope module: :api do
+ resources :errors, shallow: true do
resources :notices
end
end
end
- get '/errors/1/notices'
- assert_equal 'api/notices#index', @response.body
- assert_equal '/errors/1/notices', error_notices_path(:error_id => '1')
+ get "/errors/1/notices"
+ assert_equal "api/notices#index", @response.body
+ assert_equal "/errors/1/notices", error_notices_path(error_id: "1")
- get '/notices/1'
- assert_equal 'api/notices#show', @response.body
- assert_equal '/notices/1', notice_path(:id => '1')
+ get "/notices/1"
+ assert_equal "api/notices#show", @response.body
+ assert_equal "/notices/1", notice_path(id: "1")
end
def test_non_greedy_regexp
draw do
namespace :api do
- scope(':version', :version => /.+/) do
- resources :users, :id => /.+?/, :format => /json|xml/
+ scope(":version", version: /.+/) do
+ resources :users, id: /.+?/, format: /json|xml/
end
end
end
- get '/api/1.0/users'
- assert_equal 'api/users#index', @response.body
- assert_equal '/api/1.0/users', api_users_path(:version => '1.0')
+ get "/api/1.0/users"
+ assert_equal "api/users#index", @response.body
+ assert_equal "/api/1.0/users", api_users_path(version: "1.0")
- get '/api/1.0/users.json'
- assert_equal 'api/users#index', @response.body
+ get "/api/1.0/users.json"
+ assert_equal "api/users#index", @response.body
assert_equal true, @request.format.json?
- assert_equal '/api/1.0/users.json', api_users_path(:version => '1.0', :format => :json)
+ assert_equal "/api/1.0/users.json", api_users_path(version: "1.0", format: :json)
- get '/api/1.0/users/first.last'
- assert_equal 'api/users#show', @response.body
- assert_equal 'first.last', @request.params[:id]
- assert_equal '/api/1.0/users/first.last', api_user_path(:version => '1.0', :id => 'first.last')
+ get "/api/1.0/users/first.last"
+ assert_equal "api/users#show", @response.body
+ assert_equal "first.last", @request.params[:id]
+ assert_equal "/api/1.0/users/first.last", api_user_path(version: "1.0", id: "first.last")
- get '/api/1.0/users/first.last.xml'
- assert_equal 'api/users#show', @response.body
- assert_equal 'first.last', @request.params[:id]
+ get "/api/1.0/users/first.last.xml"
+ assert_equal "api/users#show", @response.body
+ assert_equal "first.last", @request.params[:id]
assert_equal true, @request.format.xml?
- assert_equal '/api/1.0/users/first.last.xml', api_user_path(:version => '1.0', :id => 'first.last', :format => :xml)
+ assert_equal "/api/1.0/users/first.last.xml", api_user_path(version: "1.0", id: "first.last", format: :xml)
end
def test_match_without_via
assert_raises(ArgumentError) do
draw do
- match '/foo/bar', :to => 'files#show'
+ match "/foo/bar", to: "files#show"
end
end
end
@@ -2382,17 +2471,17 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
def test_match_with_empty_via
assert_raises(ArgumentError) do
draw do
- match '/foo/bar', :to => 'files#show', :via => []
+ match "/foo/bar", to: "files#show", via: []
end
end
end
def test_glob_parameter_accepts_regexp
draw do
- get '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/
+ get "/:locale/*file.:format", to: "files#show", file: /path\/to\/existing\/file/
end
- get '/en/path/to/existing/file.html'
+ get "/en/path/to/existing/file.html"
assert_equal 200, @response.status
end
@@ -2401,8 +2490,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resources :content
end
- get '/content'
- assert_equal 'content#index', @response.body
+ get "/content"
+ assert_equal "content#index", @response.body
end
def test_url_generator_for_optional_prefix_dynamic_segment
@@ -2410,15 +2499,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "(/:username)/followers" => "followers#index"
end
- get '/bob/followers'
- assert_equal 'followers#index', @response.body
- assert_equal 'http://www.example.com/bob/followers',
- url_for(:controller => "followers", :action => "index", :username => "bob")
+ get "/bob/followers"
+ assert_equal "followers#index", @response.body
+ assert_equal "http://www.example.com/bob/followers",
+ url_for(controller: "followers", action: "index", username: "bob")
- get '/followers'
- assert_equal 'followers#index', @response.body
- assert_equal 'http://www.example.com/followers',
- url_for(:controller => "followers", :action => "index", :username => nil)
+ get "/followers"
+ assert_equal "followers#index", @response.body
+ assert_equal "http://www.example.com/followers",
+ url_for(controller: "followers", action: "index", username: nil)
end
def test_url_generator_for_optional_suffix_static_and_dynamic_segment
@@ -2426,15 +2515,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "/groups(/user/:username)" => "groups#index"
end
- get '/groups/user/bob'
- assert_equal 'groups#index', @response.body
- assert_equal 'http://www.example.com/groups/user/bob',
- url_for(:controller => "groups", :action => "index", :username => "bob")
+ get "/groups/user/bob"
+ assert_equal "groups#index", @response.body
+ assert_equal "http://www.example.com/groups/user/bob",
+ url_for(controller: "groups", action: "index", username: "bob")
- get '/groups'
- assert_equal 'groups#index', @response.body
- assert_equal 'http://www.example.com/groups',
- url_for(:controller => "groups", :action => "index", :username => nil)
+ get "/groups"
+ assert_equal "groups#index", @response.body
+ assert_equal "http://www.example.com/groups",
+ url_for(controller: "groups", action: "index", username: nil)
end
def test_url_generator_for_optional_prefix_static_and_dynamic_segment
@@ -2442,66 +2531,66 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "(/user/:username)/photos" => "photos#index"
end
- get '/user/bob/photos'
- assert_equal 'photos#index', @response.body
- assert_equal 'http://www.example.com/user/bob/photos',
- url_for(:controller => "photos", :action => "index", :username => "bob")
+ get "/user/bob/photos"
+ assert_equal "photos#index", @response.body
+ assert_equal "http://www.example.com/user/bob/photos",
+ url_for(controller: "photos", action: "index", username: "bob")
- get '/photos'
- assert_equal 'photos#index', @response.body
- assert_equal 'http://www.example.com/photos',
- url_for(:controller => "photos", :action => "index", :username => nil)
+ get "/photos"
+ assert_equal "photos#index", @response.body
+ assert_equal "http://www.example.com/photos",
+ url_for(controller: "photos", action: "index", username: nil)
end
def test_url_recognition_for_optional_static_segments
draw do
- scope '(groups)' do
- scope '(discussions)' do
+ scope "(groups)" do
+ scope "(discussions)" do
resources :messages
end
end
end
- get '/groups/discussions/messages'
- assert_equal 'messages#index', @response.body
+ get "/groups/discussions/messages"
+ assert_equal "messages#index", @response.body
- get '/groups/discussions/messages/1'
- assert_equal 'messages#show', @response.body
+ get "/groups/discussions/messages/1"
+ assert_equal "messages#show", @response.body
- get '/groups/messages'
- assert_equal 'messages#index', @response.body
+ get "/groups/messages"
+ assert_equal "messages#index", @response.body
- get '/groups/messages/1'
- assert_equal 'messages#show', @response.body
+ get "/groups/messages/1"
+ assert_equal "messages#show", @response.body
- get '/discussions/messages'
- assert_equal 'messages#index', @response.body
+ get "/discussions/messages"
+ assert_equal "messages#index", @response.body
- get '/discussions/messages/1'
- assert_equal 'messages#show', @response.body
+ get "/discussions/messages/1"
+ assert_equal "messages#show", @response.body
- get '/messages'
- assert_equal 'messages#index', @response.body
+ get "/messages"
+ assert_equal "messages#index", @response.body
- get '/messages/1'
- assert_equal 'messages#show', @response.body
+ get "/messages/1"
+ assert_equal "messages#show", @response.body
end
def test_router_removes_invalid_conditions
draw do
- scope :constraints => { :id => /\d+/ } do
- get '/tickets', :to => 'tickets#index', :as => :tickets
+ scope constraints: { id: /\d+/ } do
+ get "/tickets", to: "tickets#index", as: :tickets
end
end
- get '/tickets'
- assert_equal 'tickets#index', @response.body
- assert_equal '/tickets', tickets_path
+ get "/tickets"
+ assert_equal "tickets#index", @response.body
+ assert_equal "/tickets", tickets_path
end
def test_constraints_are_merged_from_scope
draw do
- scope :constraints => { :id => /\d{4}/ } do
+ scope constraints: { id: /\d{4}/ } do
resources :movies do
resources :reviews
resource :trailer
@@ -2509,42 +2598,42 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/movies/0001'
- assert_equal 'movies#show', @response.body
- assert_equal '/movies/0001', movie_path(:id => '0001')
+ get "/movies/0001"
+ assert_equal "movies#show", @response.body
+ assert_equal "/movies/0001", movie_path(id: "0001")
- get '/movies/00001'
- assert_equal 'Not Found', @response.body
- assert_raises(ActionController::UrlGenerationError){ movie_path(:id => '00001') }
+ get "/movies/00001"
+ assert_equal "Not Found", @response.body
+ assert_raises(ActionController::UrlGenerationError) { movie_path(id: "00001") }
- get '/movies/0001/reviews'
- assert_equal 'reviews#index', @response.body
- assert_equal '/movies/0001/reviews', movie_reviews_path(:movie_id => '0001')
+ get "/movies/0001/reviews"
+ assert_equal "reviews#index", @response.body
+ assert_equal "/movies/0001/reviews", movie_reviews_path(movie_id: "0001")
- get '/movies/00001/reviews'
- assert_equal 'Not Found', @response.body
- assert_raises(ActionController::UrlGenerationError){ movie_reviews_path(:movie_id => '00001') }
+ get "/movies/00001/reviews"
+ assert_equal "Not Found", @response.body
+ assert_raises(ActionController::UrlGenerationError) { movie_reviews_path(movie_id: "00001") }
- get '/movies/0001/reviews/0001'
- assert_equal 'reviews#show', @response.body
- assert_equal '/movies/0001/reviews/0001', movie_review_path(:movie_id => '0001', :id => '0001')
+ get "/movies/0001/reviews/0001"
+ assert_equal "reviews#show", @response.body
+ assert_equal "/movies/0001/reviews/0001", movie_review_path(movie_id: "0001", id: "0001")
- get '/movies/00001/reviews/0001'
- assert_equal 'Not Found', @response.body
- assert_raises(ActionController::UrlGenerationError){ movie_path(:movie_id => '00001', :id => '00001') }
+ get "/movies/00001/reviews/0001"
+ assert_equal "Not Found", @response.body
+ assert_raises(ActionController::UrlGenerationError) { movie_path(movie_id: "00001", id: "00001") }
- get '/movies/0001/trailer'
- assert_equal 'trailers#show', @response.body
- assert_equal '/movies/0001/trailer', movie_trailer_path(:movie_id => '0001')
+ get "/movies/0001/trailer"
+ assert_equal "trailers#show", @response.body
+ assert_equal "/movies/0001/trailer", movie_trailer_path(movie_id: "0001")
- get '/movies/00001/trailer'
- assert_equal 'Not Found', @response.body
- assert_raises(ActionController::UrlGenerationError){ movie_trailer_path(:movie_id => '00001') }
+ get "/movies/00001/trailer"
+ assert_equal "Not Found", @response.body
+ assert_raises(ActionController::UrlGenerationError) { movie_trailer_path(movie_id: "00001") }
end
def test_only_should_be_read_from_scope
draw do
- scope :only => [:index, :show] do
+ scope only: [:index, :show] do
namespace :only do
resources :clubs do
resources :players
@@ -2554,34 +2643,34 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/only/clubs'
- assert_equal 'only/clubs#index', @response.body
- assert_equal '/only/clubs', only_clubs_path
+ get "/only/clubs"
+ assert_equal "only/clubs#index", @response.body
+ assert_equal "/only/clubs", only_clubs_path
- get '/only/clubs/1/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_only_club_path(:id => '1') }
+ get "/only/clubs/1/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_only_club_path(id: "1") }
- get '/only/clubs/1/players'
- assert_equal 'only/players#index', @response.body
- assert_equal '/only/clubs/1/players', only_club_players_path(:club_id => '1')
+ get "/only/clubs/1/players"
+ assert_equal "only/players#index", @response.body
+ assert_equal "/only/clubs/1/players", only_club_players_path(club_id: "1")
- get '/only/clubs/1/players/2/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_only_club_player_path(:club_id => '1', :id => '2') }
+ get "/only/clubs/1/players/2/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_only_club_player_path(club_id: "1", id: "2") }
- get '/only/clubs/1/chairman'
- assert_equal 'only/chairmen#show', @response.body
- assert_equal '/only/clubs/1/chairman', only_club_chairman_path(:club_id => '1')
+ get "/only/clubs/1/chairman"
+ assert_equal "only/chairmen#show", @response.body
+ assert_equal "/only/clubs/1/chairman", only_club_chairman_path(club_id: "1")
- get '/only/clubs/1/chairman/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_only_club_chairman_path(:club_id => '1') }
+ get "/only/clubs/1/chairman/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_only_club_chairman_path(club_id: "1") }
end
def test_except_should_be_read_from_scope
draw do
- scope :except => [:new, :create, :edit, :update, :destroy] do
+ scope except: [:new, :create, :edit, :update, :destroy] do
namespace :except do
resources :clubs do
resources :players
@@ -2591,54 +2680,54 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/except/clubs'
- assert_equal 'except/clubs#index', @response.body
- assert_equal '/except/clubs', except_clubs_path
+ get "/except/clubs"
+ assert_equal "except/clubs#index", @response.body
+ assert_equal "/except/clubs", except_clubs_path
- get '/except/clubs/1/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_except_club_path(:id => '1') }
+ get "/except/clubs/1/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_except_club_path(id: "1") }
- get '/except/clubs/1/players'
- assert_equal 'except/players#index', @response.body
- assert_equal '/except/clubs/1/players', except_club_players_path(:club_id => '1')
+ get "/except/clubs/1/players"
+ assert_equal "except/players#index", @response.body
+ assert_equal "/except/clubs/1/players", except_club_players_path(club_id: "1")
- get '/except/clubs/1/players/2/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_except_club_player_path(:club_id => '1', :id => '2') }
+ get "/except/clubs/1/players/2/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_except_club_player_path(club_id: "1", id: "2") }
- get '/except/clubs/1/chairman'
- assert_equal 'except/chairmen#show', @response.body
- assert_equal '/except/clubs/1/chairman', except_club_chairman_path(:club_id => '1')
+ get "/except/clubs/1/chairman"
+ assert_equal "except/chairmen#show", @response.body
+ assert_equal "/except/clubs/1/chairman", except_club_chairman_path(club_id: "1")
- get '/except/clubs/1/chairman/edit'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { edit_except_club_chairman_path(:club_id => '1') }
+ get "/except/clubs/1/chairman/edit"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { edit_except_club_chairman_path(club_id: "1") }
end
def test_only_option_should_override_scope
draw do
- scope :only => :show do
+ scope only: :show do
namespace :only do
- resources :sectors, :only => :index
+ resources :sectors, only: :index
end
end
end
- get '/only/sectors'
- assert_equal 'only/sectors#index', @response.body
- assert_equal '/only/sectors', only_sectors_path
+ get "/only/sectors"
+ assert_equal "only/sectors#index", @response.body
+ assert_equal "/only/sectors", only_sectors_path
- get '/only/sectors/1'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { only_sector_path(:id => '1') }
+ get "/only/sectors/1"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { only_sector_path(id: "1") }
end
def test_only_option_should_not_inherit
draw do
- scope :only => :show do
+ scope only: :show do
namespace :only do
- resources :sectors, :only => :index do
+ resources :sectors, only: :index do
resources :companies
resource :leader
end
@@ -2646,38 +2735,38 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/only/sectors/1/companies/2'
- assert_equal 'only/companies#show', @response.body
- assert_equal '/only/sectors/1/companies/2', only_sector_company_path(:sector_id => '1', :id => '2')
+ get "/only/sectors/1/companies/2"
+ assert_equal "only/companies#show", @response.body
+ assert_equal "/only/sectors/1/companies/2", only_sector_company_path(sector_id: "1", id: "2")
- get '/only/sectors/1/leader'
- assert_equal 'only/leaders#show', @response.body
- assert_equal '/only/sectors/1/leader', only_sector_leader_path(:sector_id => '1')
+ get "/only/sectors/1/leader"
+ assert_equal "only/leaders#show", @response.body
+ assert_equal "/only/sectors/1/leader", only_sector_leader_path(sector_id: "1")
end
def test_except_option_should_override_scope
draw do
- scope :except => :index do
+ scope except: :index do
namespace :except do
- resources :sectors, :except => [:show, :update, :destroy]
+ resources :sectors, except: [:show, :update, :destroy]
end
end
end
- get '/except/sectors'
- assert_equal 'except/sectors#index', @response.body
- assert_equal '/except/sectors', except_sectors_path
+ get "/except/sectors"
+ assert_equal "except/sectors#index", @response.body
+ assert_equal "/except/sectors", except_sectors_path
- get '/except/sectors/1'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { except_sector_path(:id => '1') }
+ get "/except/sectors/1"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { except_sector_path(id: "1") }
end
def test_except_option_should_not_inherit
draw do
- scope :except => :index do
+ scope except: :index do
namespace :except do
- resources :sectors, :except => [:show, :update, :destroy] do
+ resources :sectors, except: [:show, :update, :destroy] do
resources :companies
resource :leader
end
@@ -2685,62 +2774,62 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/except/sectors/1/companies/2'
- assert_equal 'except/companies#show', @response.body
- assert_equal '/except/sectors/1/companies/2', except_sector_company_path(:sector_id => '1', :id => '2')
+ get "/except/sectors/1/companies/2"
+ assert_equal "except/companies#show", @response.body
+ assert_equal "/except/sectors/1/companies/2", except_sector_company_path(sector_id: "1", id: "2")
- get '/except/sectors/1/leader'
- assert_equal 'except/leaders#show', @response.body
- assert_equal '/except/sectors/1/leader', except_sector_leader_path(:sector_id => '1')
+ get "/except/sectors/1/leader"
+ assert_equal "except/leaders#show", @response.body
+ assert_equal "/except/sectors/1/leader", except_sector_leader_path(sector_id: "1")
end
def test_except_option_should_override_scoped_only
draw do
- scope :only => :show do
+ scope only: :show do
namespace :only do
- resources :sectors, :only => :index do
- resources :managers, :except => [:show, :update, :destroy]
+ resources :sectors, only: :index do
+ resources :managers, except: [:show, :update, :destroy]
end
end
end
end
- get '/only/sectors/1/managers'
- assert_equal 'only/managers#index', @response.body
- assert_equal '/only/sectors/1/managers', only_sector_managers_path(:sector_id => '1')
+ get "/only/sectors/1/managers"
+ assert_equal "only/managers#index", @response.body
+ assert_equal "/only/sectors/1/managers", only_sector_managers_path(sector_id: "1")
- get '/only/sectors/1/managers/2'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { only_sector_manager_path(:sector_id => '1', :id => '2') }
+ get "/only/sectors/1/managers/2"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { only_sector_manager_path(sector_id: "1", id: "2") }
end
def test_only_option_should_override_scoped_except
draw do
- scope :except => :index do
+ scope except: :index do
namespace :except do
- resources :sectors, :except => [:show, :update, :destroy] do
- resources :managers, :only => :index
+ resources :sectors, except: [:show, :update, :destroy] do
+ resources :managers, only: :index
end
end
end
end
- get '/except/sectors/1/managers'
- assert_equal 'except/managers#index', @response.body
- assert_equal '/except/sectors/1/managers', except_sector_managers_path(:sector_id => '1')
+ get "/except/sectors/1/managers"
+ assert_equal "except/managers#index", @response.body
+ assert_equal "/except/sectors/1/managers", except_sector_managers_path(sector_id: "1")
- get '/except/sectors/1/managers/2'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { except_sector_manager_path(:sector_id => '1', :id => '2') }
+ get "/except/sectors/1/managers/2"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { except_sector_manager_path(sector_id: "1", id: "2") }
end
def test_only_scope_should_override_parent_scope
draw do
- scope :only => :show do
+ scope only: :show do
namespace :only do
- resources :sectors, :only => :index do
+ resources :sectors, only: :index do
resources :companies do
- scope :only => :index do
+ scope only: :index do
resources :divisions
end
end
@@ -2749,22 +2838,22 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/only/sectors/1/companies/2/divisions'
- assert_equal 'only/divisions#index', @response.body
- assert_equal '/only/sectors/1/companies/2/divisions', only_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
+ get "/only/sectors/1/companies/2/divisions"
+ assert_equal "only/divisions#index", @response.body
+ assert_equal "/only/sectors/1/companies/2/divisions", only_sector_company_divisions_path(sector_id: "1", company_id: "2")
- get '/only/sectors/1/companies/2/divisions/3'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { only_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ get "/only/sectors/1/companies/2/divisions/3"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { only_sector_company_division_path(sector_id: "1", company_id: "2", id: "3") }
end
def test_except_scope_should_override_parent_scope
draw do
- scope :except => :index do
+ scope except: :index do
namespace :except do
- resources :sectors, :except => [:show, :update, :destroy] do
+ resources :sectors, except: [:show, :update, :destroy] do
resources :companies do
- scope :except => [:show, :update, :destroy] do
+ scope except: [:show, :update, :destroy] do
resources :divisions
end
end
@@ -2773,22 +2862,22 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/except/sectors/1/companies/2/divisions'
- assert_equal 'except/divisions#index', @response.body
- assert_equal '/except/sectors/1/companies/2/divisions', except_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
+ get "/except/sectors/1/companies/2/divisions"
+ assert_equal "except/divisions#index", @response.body
+ assert_equal "/except/sectors/1/companies/2/divisions", except_sector_company_divisions_path(sector_id: "1", company_id: "2")
- get '/except/sectors/1/companies/2/divisions/3'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { except_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ get "/except/sectors/1/companies/2/divisions/3"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { except_sector_company_division_path(sector_id: "1", company_id: "2", id: "3") }
end
def test_except_scope_should_override_parent_only_scope
draw do
- scope :only => :show do
+ scope only: :show do
namespace :only do
- resources :sectors, :only => :index do
+ resources :sectors, only: :index do
resources :companies do
- scope :except => [:show, :update, :destroy] do
+ scope except: [:show, :update, :destroy] do
resources :departments
end
end
@@ -2797,22 +2886,22 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/only/sectors/1/companies/2/departments'
- assert_equal 'only/departments#index', @response.body
- assert_equal '/only/sectors/1/companies/2/departments', only_sector_company_departments_path(:sector_id => '1', :company_id => '2')
+ get "/only/sectors/1/companies/2/departments"
+ assert_equal "only/departments#index", @response.body
+ assert_equal "/only/sectors/1/companies/2/departments", only_sector_company_departments_path(sector_id: "1", company_id: "2")
- get '/only/sectors/1/companies/2/departments/3'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { only_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ get "/only/sectors/1/companies/2/departments/3"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { only_sector_company_department_path(sector_id: "1", company_id: "2", id: "3") }
end
def test_only_scope_should_override_parent_except_scope
draw do
- scope :except => :index do
+ scope except: :index do
namespace :except do
- resources :sectors, :except => [:show, :update, :destroy] do
+ resources :sectors, except: [:show, :update, :destroy] do
resources :companies do
- scope :only => :index do
+ scope only: :index do
resources :departments
end
end
@@ -2821,13 +2910,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/except/sectors/1/companies/2/departments'
- assert_equal 'except/departments#index', @response.body
- assert_equal '/except/sectors/1/companies/2/departments', except_sector_company_departments_path(:sector_id => '1', :company_id => '2')
+ get "/except/sectors/1/companies/2/departments"
+ assert_equal "except/departments#index", @response.body
+ assert_equal "/except/sectors/1/companies/2/departments", except_sector_company_departments_path(sector_id: "1", company_id: "2")
- get '/except/sectors/1/companies/2/departments/3'
- assert_equal 'Not Found', @response.body
- assert_raise(NoMethodError) { except_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ get "/except/sectors/1/companies/2/departments/3"
+ assert_equal "Not Found", @response.body
+ assert_raise(NoMethodError) { except_sector_company_department_path(sector_id: "1", company_id: "2", id: "3") }
end
def test_resources_are_not_pluralized
@@ -2837,30 +2926,30 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/transport/taxis'
- assert_equal 'transport/taxis#index', @response.body
- assert_equal '/transport/taxis', transport_taxis_path
+ get "/transport/taxis"
+ assert_equal "transport/taxis#index", @response.body
+ assert_equal "/transport/taxis", transport_taxis_path
- get '/transport/taxis/new'
- assert_equal 'transport/taxis#new', @response.body
- assert_equal '/transport/taxis/new', new_transport_taxi_path
+ get "/transport/taxis/new"
+ assert_equal "transport/taxis#new", @response.body
+ assert_equal "/transport/taxis/new", new_transport_taxi_path
- post '/transport/taxis'
- assert_equal 'transport/taxis#create', @response.body
+ post "/transport/taxis"
+ assert_equal "transport/taxis#create", @response.body
- get '/transport/taxis/1'
- assert_equal 'transport/taxis#show', @response.body
- assert_equal '/transport/taxis/1', transport_taxi_path(:id => '1')
+ get "/transport/taxis/1"
+ assert_equal "transport/taxis#show", @response.body
+ assert_equal "/transport/taxis/1", transport_taxi_path(id: "1")
- get '/transport/taxis/1/edit'
- assert_equal 'transport/taxis#edit', @response.body
- assert_equal '/transport/taxis/1/edit', edit_transport_taxi_path(:id => '1')
+ get "/transport/taxis/1/edit"
+ assert_equal "transport/taxis#edit", @response.body
+ assert_equal "/transport/taxis/1/edit", edit_transport_taxi_path(id: "1")
- put '/transport/taxis/1'
- assert_equal 'transport/taxis#update', @response.body
+ put "/transport/taxis/1"
+ assert_equal "transport/taxis#update", @response.body
- delete '/transport/taxis/1'
- assert_equal 'transport/taxis#destroy', @response.body
+ delete "/transport/taxis/1"
+ assert_equal "transport/taxis#destroy", @response.body
end
def test_singleton_resources_are_not_singularized
@@ -2870,169 +2959,169 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/medical/taxis/new'
- assert_equal 'medical/taxis#new', @response.body
- assert_equal '/medical/taxis/new', new_medical_taxis_path
+ get "/medical/taxis/new"
+ assert_equal "medical/taxis#new", @response.body
+ assert_equal "/medical/taxis/new", new_medical_taxis_path
- post '/medical/taxis'
- assert_equal 'medical/taxis#create', @response.body
+ post "/medical/taxis"
+ assert_equal "medical/taxis#create", @response.body
- get '/medical/taxis'
- assert_equal 'medical/taxis#show', @response.body
- assert_equal '/medical/taxis', medical_taxis_path
+ get "/medical/taxis"
+ assert_equal "medical/taxis#show", @response.body
+ assert_equal "/medical/taxis", medical_taxis_path
- get '/medical/taxis/edit'
- assert_equal 'medical/taxis#edit', @response.body
- assert_equal '/medical/taxis/edit', edit_medical_taxis_path
+ get "/medical/taxis/edit"
+ assert_equal "medical/taxis#edit", @response.body
+ assert_equal "/medical/taxis/edit", edit_medical_taxis_path
- put '/medical/taxis'
- assert_equal 'medical/taxis#update', @response.body
+ put "/medical/taxis"
+ assert_equal "medical/taxis#update", @response.body
- delete '/medical/taxis'
- assert_equal 'medical/taxis#destroy', @response.body
+ delete "/medical/taxis"
+ assert_equal "medical/taxis#destroy", @response.body
end
def test_greedy_resource_id_regexp_doesnt_match_edit_and_custom_action
draw do
- resources :sections, :id => /.+/ do
- get :preview, :on => :member
+ resources :sections, id: /.+/ do
+ get :preview, on: :member
end
end
- get '/sections/1/edit'
- assert_equal 'sections#edit', @response.body
- assert_equal '/sections/1/edit', edit_section_path(:id => '1')
+ get "/sections/1/edit"
+ assert_equal "sections#edit", @response.body
+ assert_equal "/sections/1/edit", edit_section_path(id: "1")
- get '/sections/1/preview'
- assert_equal 'sections#preview', @response.body
- assert_equal '/sections/1/preview', preview_section_path(:id => '1')
+ get "/sections/1/preview"
+ assert_equal "sections#preview", @response.body
+ assert_equal "/sections/1/preview", preview_section_path(id: "1")
end
def test_resource_constraints_are_pushed_to_scope
draw do
namespace :wiki do
- resources :articles, :id => /[^\/]+/ do
- resources :comments, :only => [:create, :new]
+ resources :articles, id: /[^\/]+/ do
+ resources :comments, only: [:create, :new]
end
end
end
- get '/wiki/articles/Ruby_on_Rails_3.0'
- assert_equal 'wiki/articles#show', @response.body
- assert_equal '/wiki/articles/Ruby_on_Rails_3.0', wiki_article_path(:id => 'Ruby_on_Rails_3.0')
+ get "/wiki/articles/Ruby_on_Rails_3.0"
+ assert_equal "wiki/articles#show", @response.body
+ assert_equal "/wiki/articles/Ruby_on_Rails_3.0", wiki_article_path(id: "Ruby_on_Rails_3.0")
- get '/wiki/articles/Ruby_on_Rails_3.0/comments/new'
- assert_equal 'wiki/comments#new', @response.body
- assert_equal '/wiki/articles/Ruby_on_Rails_3.0/comments/new', new_wiki_article_comment_path(:article_id => 'Ruby_on_Rails_3.0')
+ get "/wiki/articles/Ruby_on_Rails_3.0/comments/new"
+ assert_equal "wiki/comments#new", @response.body
+ assert_equal "/wiki/articles/Ruby_on_Rails_3.0/comments/new", new_wiki_article_comment_path(article_id: "Ruby_on_Rails_3.0")
- post '/wiki/articles/Ruby_on_Rails_3.0/comments'
- assert_equal 'wiki/comments#create', @response.body
- assert_equal '/wiki/articles/Ruby_on_Rails_3.0/comments', wiki_article_comments_path(:article_id => 'Ruby_on_Rails_3.0')
+ post "/wiki/articles/Ruby_on_Rails_3.0/comments"
+ assert_equal "wiki/comments#create", @response.body
+ assert_equal "/wiki/articles/Ruby_on_Rails_3.0/comments", wiki_article_comments_path(article_id: "Ruby_on_Rails_3.0")
end
def test_resources_path_can_be_a_symbol
draw do
- resources :wiki_pages, :path => :pages
- resource :wiki_account, :path => :my_account
+ resources :wiki_pages, path: :pages
+ resource :wiki_account, path: :my_account
end
- get '/pages'
- assert_equal 'wiki_pages#index', @response.body
- assert_equal '/pages', wiki_pages_path
+ get "/pages"
+ assert_equal "wiki_pages#index", @response.body
+ assert_equal "/pages", wiki_pages_path
- get '/pages/Ruby_on_Rails'
- assert_equal 'wiki_pages#show', @response.body
- assert_equal '/pages/Ruby_on_Rails', wiki_page_path(:id => 'Ruby_on_Rails')
+ get "/pages/Ruby_on_Rails"
+ assert_equal "wiki_pages#show", @response.body
+ assert_equal "/pages/Ruby_on_Rails", wiki_page_path(id: "Ruby_on_Rails")
- get '/my_account'
- assert_equal 'wiki_accounts#show', @response.body
- assert_equal '/my_account', wiki_account_path
+ get "/my_account"
+ assert_equal "wiki_accounts#show", @response.body
+ assert_equal "/my_account", wiki_account_path
end
def test_redirect_https
draw do
- get 'secure', :to => redirect("/secure/login")
+ get "secure", to: redirect("/secure/login")
end
with_https do
- get '/secure'
- verify_redirect 'https://www.example.com/secure/login'
+ get "/secure"
+ verify_redirect "https://www.example.com/secure/login"
end
end
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'
- get '/cities', :to => 'countries#cities'
+ scope "/countries/:country", constraints: lambda { |params, req| %w(all France).include?(params[:country]) } do
+ get "/", to: "countries#index"
+ get "/cities", to: "countries#cities"
end
- get '/countries/:country/(*other)', :to => redirect{ |params, req| params[:other] ? "/countries/all/#{params[:other]}" : '/countries/all' }
+ get "/countries/:country/(*other)", to: redirect { |params, req| params[:other] ? "/countries/all/#{params[:other]}" : "/countries/all" }
end
- get '/countries/France'
- assert_equal 'countries#index', @response.body
+ get "/countries/France"
+ assert_equal "countries#index", @response.body
- get '/countries/France/cities'
- assert_equal 'countries#cities', @response.body
+ get "/countries/France/cities"
+ assert_equal "countries#cities", @response.body
- get '/countries/UK'
- verify_redirect 'http://www.example.com/countries/all'
+ get "/countries/UK"
+ verify_redirect "http://www.example.com/countries/all"
- get '/countries/UK/cities'
- verify_redirect 'http://www.example.com/countries/all/cities'
+ get "/countries/UK/cities"
+ verify_redirect "http://www.example.com/countries/all/cities"
end
def test_constraints_block_not_carried_to_following_routes
draw do
- scope '/italians' do
- get '/writers', :to => 'italians#writers', :constraints => ::TestRoutingMapper::IpRestrictor
- get '/sculptors', :to => 'italians#sculptors'
- get '/painters/:painter', :to => 'italians#painters', :constraints => {:painter => /michelangelo/}
+ scope "/italians" do
+ get "/writers", to: "italians#writers", constraints: ::TestRoutingMapper::IpRestrictor
+ get "/sculptors", to: "italians#sculptors"
+ get "/painters/:painter", to: "italians#painters", constraints: { painter: /michelangelo/ }
end
end
- get '/italians/writers'
- assert_equal 'Not Found', @response.body
+ get "/italians/writers"
+ assert_equal "Not Found", @response.body
- get '/italians/sculptors'
- assert_equal 'italians#sculptors', @response.body
+ get "/italians/sculptors"
+ assert_equal "italians#sculptors", @response.body
- get '/italians/painters/botticelli'
- assert_equal 'Not Found', @response.body
+ get "/italians/painters/botticelli"
+ assert_equal "Not Found", @response.body
- get '/italians/painters/michelangelo'
- assert_equal 'italians#painters', @response.body
+ get "/italians/painters/michelangelo"
+ assert_equal "italians#painters", @response.body
end
def test_custom_resource_actions_defined_using_string
draw do
resources :customers do
resources :invoices do
- get "aged/:months", :on => :collection, :action => :aged, :as => :aged
+ get "aged/:months", on: :collection, action: :aged, as: :aged
end
- get "inactive", :on => :collection
- post "deactivate", :on => :member
- get "old", :on => :collection, :as => :stale
+ get "inactive", on: :collection
+ post "deactivate", on: :member
+ get "old", on: :collection, as: :stale
end
end
- get '/customers/inactive'
- assert_equal 'customers#inactive', @response.body
- assert_equal '/customers/inactive', inactive_customers_path
+ get "/customers/inactive"
+ assert_equal "customers#inactive", @response.body
+ assert_equal "/customers/inactive", inactive_customers_path
- post '/customers/1/deactivate'
- assert_equal 'customers#deactivate', @response.body
- assert_equal '/customers/1/deactivate', deactivate_customer_path(:id => '1')
+ post "/customers/1/deactivate"
+ assert_equal "customers#deactivate", @response.body
+ assert_equal "/customers/1/deactivate", deactivate_customer_path(id: "1")
- get '/customers/old'
- assert_equal 'customers#old', @response.body
- assert_equal '/customers/old', stale_customers_path
+ get "/customers/old"
+ assert_equal "customers#old", @response.body
+ assert_equal "/customers/old", stale_customers_path
- get '/customers/1/invoices/aged/3'
- assert_equal 'invoices#aged', @response.body
- assert_equal '/customers/1/invoices/aged/3', aged_customer_invoices_path(:customer_id => '1', :months => '3')
+ get "/customers/1/invoices/aged/3"
+ assert_equal "invoices#aged", @response.body
+ assert_equal "/customers/1/invoices/aged/3", aged_customer_invoices_path(customer_id: "1", months: "3")
end
def test_route_defined_in_resources_scope_level
@@ -3042,43 +3131,43 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/customers/1/export'
- assert_equal 'customers#export', @response.body
- assert_equal '/customers/1/export', customer_export_path(:customer_id => '1')
+ get "/customers/1/export"
+ assert_equal "customers#export", @response.body
+ assert_equal "/customers/1/export", customer_export_path(customer_id: "1")
end
def test_named_character_classes_in_regexp_constraints
draw do
- get '/purchases/:token/:filename',
- :to => 'purchases#fetch',
- :token => /[[:alnum:]]{10}/,
- :filename => /(.+)/,
- :as => :purchase
+ get "/purchases/:token/:filename",
+ to: "purchases#fetch",
+ token: /[[:alnum:]]{10}/,
+ filename: /(.+)/,
+ as: :purchase
end
- get '/purchases/315004be7e/Ruby_on_Rails_3.pdf'
- assert_equal 'purchases#fetch', @response.body
- assert_equal '/purchases/315004be7e/Ruby_on_Rails_3.pdf', purchase_path(:token => '315004be7e', :filename => 'Ruby_on_Rails_3.pdf')
+ get "/purchases/315004be7e/Ruby_on_Rails_3.pdf"
+ assert_equal "purchases#fetch", @response.body
+ assert_equal "/purchases/315004be7e/Ruby_on_Rails_3.pdf", purchase_path(token: "315004be7e", filename: "Ruby_on_Rails_3.pdf")
end
def test_nested_resource_constraints
draw do
- resources :lists, :id => /([A-Za-z0-9]{25})|default/ do
- resources :todos, :id => /\d+/
+ resources :lists, id: /([A-Za-z0-9]{25})|default/ do
+ resources :todos, id: /\d+/
end
end
- get '/lists/01234012340123401234fffff'
- assert_equal 'lists#show', @response.body
- assert_equal '/lists/01234012340123401234fffff', list_path(:id => '01234012340123401234fffff')
+ get "/lists/01234012340123401234fffff"
+ assert_equal "lists#show", @response.body
+ assert_equal "/lists/01234012340123401234fffff", list_path(id: "01234012340123401234fffff")
- get '/lists/01234012340123401234fffff/todos/1'
- assert_equal 'todos#show', @response.body
- assert_equal '/lists/01234012340123401234fffff/todos/1', list_todo_path(:list_id => '01234012340123401234fffff', :id => '1')
+ get "/lists/01234012340123401234fffff/todos/1"
+ assert_equal "todos#show", @response.body
+ assert_equal "/lists/01234012340123401234fffff/todos/1", list_todo_path(list_id: "01234012340123401234fffff", id: "1")
- get '/lists/2/todos/1'
- assert_equal 'Not Found', @response.body
- assert_raises(ActionController::UrlGenerationError){ list_todo_path(:list_id => '2', :id => '1') }
+ get "/lists/2/todos/1"
+ assert_equal "Not Found", @response.body
+ assert_raises(ActionController::UrlGenerationError) { list_todo_path(list_id: "2", id: "1") }
end
def test_redirect_argument_error
@@ -3095,73 +3184,67 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
after = has_named_route?(:hello)
end
- assert !before, "expected to not have named route :hello before route definition"
+ assert_not before, "expected to not have named route :hello before route definition"
assert after, "expected to have named route :hello after route definition"
end
def test_explicitly_avoiding_the_named_route
draw do
- scope :as => "routes" do
- get "/c/:id", :as => :collision, :to => "collision#show"
- get "/collision", :to => "collision#show"
- get "/no_collision", :to => "collision#show", :as => nil
+ scope as: "routes" do
+ get "/c/:id", as: :collision, to: "collision#show"
+ get "/collision", to: "collision#show"
+ get "/no_collision", to: "collision#show", as: nil
end
end
- assert !respond_to?(:routes_no_collision_path)
+ assert_not respond_to?(:routes_no_collision_path)
end
def test_controller_name_with_leading_slash_raise_error
assert_raise(ArgumentError) do
- draw { get '/feeds/:service', :to => '/feeds#show' }
+ draw { get "/feeds/:service", to: "/feeds#show" }
end
assert_raise(ArgumentError) do
- draw { get '/feeds/:service', :controller => '/feeds', :action => 'show' }
+ draw { get "/feeds/:service", controller: "/feeds", action: "show" }
end
assert_raise(ArgumentError) do
- draw { get '/api/feeds/:service', :to => '/api/feeds#show' }
+ draw { get "/api/feeds/:service", to: "/api/feeds#show" }
end
assert_raise(ArgumentError) do
- assert_deprecated do
- draw { controller("/feeds") { get '/feeds/:service', :to => :show } }
- end
- end
-
- assert_raise(ArgumentError) do
- draw { resources :feeds, :controller => '/feeds' }
+ draw { resources :feeds, controller: "/feeds" }
end
end
def test_invalid_route_name_raises_error
assert_raise(ArgumentError) do
- draw { get '/products', :to => 'products#index', :as => 'products ' }
+ draw { get "/products", to: "products#index", as: "products " }
end
assert_raise(ArgumentError) do
- draw { get '/products', :to => 'products#index', :as => ' products' }
+ draw { get "/products", to: "products#index", as: " products" }
end
assert_raise(ArgumentError) do
- draw { get '/products', :to => 'products#index', :as => 'products!' }
+ draw { get "/products", to: "products#index", as: "products!" }
end
assert_raise(ArgumentError) do
- draw { get '/products', :to => 'products#index', :as => 'products index' }
+ draw { get "/products", to: "products#index", as: "products index" }
end
assert_raise(ArgumentError) do
- draw { get '/products', :to => 'products#index', :as => '1products' }
+ draw { get "/products", to: "products#index", as: "1products" }
end
end
def test_duplicate_route_name_raises_error
assert_raise(ArgumentError) do
draw do
- get '/collision', :to => 'collision#show', :as => 'collision'
- get '/duplicate', :to => 'duplicate#show', :as => 'collision'
+ get "/collision", to: "collision#show", as: "collision"
+ get "/duplicate", to: "duplicate#show", as: "collision"
end
end
end
@@ -3170,15 +3253,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_raise(ArgumentError) do
draw do
resources :collisions
- get '/collision', :to => 'collision#show', :as => 'collision'
+ get "/collision", to: "collision#show", as: "collision"
end
end
end
def test_nested_route_in_nested_resource
draw do
- resources :posts, :only => [:index, :show] do
- resources :comments, :except => :destroy do
+ resources :posts, only: [:index, :show] do
+ resources :comments, except: :destroy do
get "views" => "comments#views", :as => :views
end
end
@@ -3186,124 +3269,124 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "/posts/1/comments/2/views"
assert_equal "comments#views", @response.body
- assert_equal "/posts/1/comments/2/views", post_comment_views_path(:post_id => '1', :comment_id => '2')
+ assert_equal "/posts/1/comments/2/views", post_comment_views_path(post_id: "1", comment_id: "2")
end
def test_root_in_deeply_nested_scope
draw do
- resources :posts, :only => [:index, :show] do
+ resources :posts, only: [:index, :show] do
namespace :admin do
- root :to => "index#index"
+ root to: "index#index"
end
end
end
get "/posts/1/admin"
assert_equal "admin/index#index", @response.body
- assert_equal "/posts/1/admin", post_admin_root_path(:post_id => '1')
+ assert_equal "/posts/1/admin", post_admin_root_path(post_id: "1")
end
def test_custom_param
draw do
- resources :profiles, :param => :username do
- get :details, :on => :member
+ resources :profiles, param: :username do
+ get :details, on: :member
resources :messages
end
end
- get '/profiles/bob'
- assert_equal 'profiles#show', @response.body
- assert_equal 'bob', @request.params[:username]
+ get "/profiles/bob"
+ assert_equal "profiles#show", @response.body
+ assert_equal "bob", @request.params[:username]
- get '/profiles/bob/details'
- assert_equal 'bob', @request.params[:username]
+ get "/profiles/bob/details"
+ assert_equal "bob", @request.params[:username]
- get '/profiles/bob/messages/34'
- assert_equal 'bob', @request.params[:profile_username]
- assert_equal '34', @request.params[:id]
+ get "/profiles/bob/messages/34"
+ assert_equal "bob", @request.params[:profile_username]
+ assert_equal "34", @request.params[:id]
end
def test_custom_param_constraint
draw do
- resources :profiles, :param => :username, :username => /[a-z]+/ do
- get :details, :on => :member
+ resources :profiles, param: :username, username: /[a-z]+/ do
+ get :details, on: :member
resources :messages
end
end
- get '/profiles/bob1'
+ get "/profiles/bob1"
assert_equal 404, @response.status
- get '/profiles/bob1/details'
+ get "/profiles/bob1/details"
assert_equal 404, @response.status
- get '/profiles/bob1/messages/34'
+ get "/profiles/bob1/messages/34"
assert_equal 404, @response.status
end
def test_shallow_custom_param
draw do
resources :orders do
- constraints :download => /[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}/ do
- resources :downloads, :param => :download, :shallow => true
+ constraints download: /[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}/ do
+ resources :downloads, param: :download, shallow: true
end
end
end
- get '/downloads/0c0c0b68-d24b-11e1-a861-001ff3fffe6f.zip'
- assert_equal 'downloads#show', @response.body
- assert_equal '0c0c0b68-d24b-11e1-a861-001ff3fffe6f', @request.params[:download]
+ get "/downloads/0c0c0b68-d24b-11e1-a861-001ff3fffe6f.zip"
+ assert_equal "downloads#show", @response.body
+ assert_equal "0c0c0b68-d24b-11e1-a861-001ff3fffe6f", @request.params[:download]
end
def test_action_from_path_is_not_frozen
draw do
- get 'search' => 'search'
+ get "search" => "search"
end
- get '/search'
- assert !@request.params[:action].frozen?
+ get "/search"
+ assert_not_predicate @request.params[:action], :frozen?
end
def test_multiple_positional_args_with_the_same_name
draw do
- get '/downloads/:id/:id.tar' => 'downloads#show', as: :download, format: false
+ get "/downloads/:id/:id.tar" => "downloads#show", as: :download, format: false
end
expected_params = {
- controller: 'downloads',
- action: 'show',
- id: '1'
+ controller: "downloads",
+ action: "show",
+ id: "1"
}
- get '/downloads/1/1.tar'
- assert_equal 'downloads#show', @response.body
+ get "/downloads/1/1.tar"
+ assert_equal "downloads#show", @response.body
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')
+ assert_equal "/downloads/1/1.tar", download_path("1")
+ assert_equal "/downloads/1/1.tar", download_path("1", "1")
end
def test_absolute_controller_namespace
draw do
namespace :foo do
- get '/', to: '/bar#index', as: 'root'
+ get "/", to: "/bar#index", as: "root"
end
end
- get '/foo'
- assert_equal 'bar#index', @response.body
- assert_equal '/foo', foo_root_path
+ get "/foo"
+ assert_equal "bar#index", @response.body
+ assert_equal "/foo", foo_root_path
end
def test_namespace_as_controller
draw do
namespace :foo do
- get '/', to: '/bar#index', as: 'root'
+ get "/", to: "/bar#index", as: "root"
end
end
- get '/foo'
- assert_equal 'bar#index', @response.body
- assert_equal '/foo', foo_root_path
+ get "/foo"
+ assert_equal "bar#index", @response.body
+ assert_equal "/foo", foo_root_path
end
def test_trailing_slash
@@ -3311,63 +3394,63 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resources :streams
end
- get '/streams'
- assert @response.ok?, 'route without trailing slash should work'
+ get "/streams"
+ assert @response.ok?, "route without trailing slash should work"
- get '/streams/'
- assert @response.ok?, 'route with trailing slash should work'
+ get "/streams/"
+ assert @response.ok?, "route with trailing slash should work"
- get '/streams?foobar'
- assert @response.ok?, 'route without trailing slash and with QUERY_STRING should work'
+ get "/streams?foobar"
+ assert @response.ok?, "route without trailing slash and with QUERY_STRING should work"
- get '/streams/?foobar'
- assert @response.ok?, 'route with trailing slash and with QUERY_STRING should work'
+ get "/streams/?foobar"
+ assert @response.ok?, "route with trailing slash and with QUERY_STRING should work"
end
def test_route_with_dashes_in_path
draw do
- get '/contact-us', to: 'pages#contact_us'
+ get "/contact-us", to: "pages#contact_us"
end
- get '/contact-us'
- assert_equal 'pages#contact_us', @response.body
- assert_equal '/contact-us', contact_us_path
+ get "/contact-us"
+ assert_equal "pages#contact_us", @response.body
+ assert_equal "/contact-us", contact_us_path
end
def test_shorthand_route_with_dashes_in_path
draw do
- get '/about-us/index'
+ get "/about-us/index"
end
- get '/about-us/index'
- assert_equal 'about_us#index', @response.body
- assert_equal '/about-us/index', about_us_index_path
+ get "/about-us/index"
+ assert_equal "about_us#index", @response.body
+ assert_equal "/about-us/index", about_us_index_path
end
def test_resource_routes_with_dashes_in_path
draw do
resources :photos, only: [:show] do
- get 'user-favorites', on: :collection
- get 'preview-photo', on: :member
- get 'summary-text'
+ get "user-favorites", on: :collection
+ get "preview-photo", on: :member
+ get "summary-text"
end
end
- get '/photos/user-favorites'
- assert_equal 'photos#user_favorites', @response.body
- assert_equal '/photos/user-favorites', user_favorites_photos_path
+ get "/photos/user-favorites"
+ assert_equal "photos#user_favorites", @response.body
+ assert_equal "/photos/user-favorites", user_favorites_photos_path
- get '/photos/1/preview-photo'
- assert_equal 'photos#preview_photo', @response.body
- assert_equal '/photos/1/preview-photo', preview_photo_photo_path('1')
+ get "/photos/1/preview-photo"
+ assert_equal "photos#preview_photo", @response.body
+ assert_equal "/photos/1/preview-photo", preview_photo_photo_path("1")
- get '/photos/1/summary-text'
- assert_equal 'photos#summary_text', @response.body
- assert_equal '/photos/1/summary-text', photo_summary_text_path('1')
+ get "/photos/1/summary-text"
+ assert_equal "photos#summary_text", @response.body
+ assert_equal "/photos/1/summary-text", photo_summary_text_path("1")
- get '/photos/1'
- assert_equal 'photos#show', @response.body
- assert_equal '/photos/1', photo_path('1')
+ get "/photos/1"
+ assert_equal "photos#show", @response.body
+ assert_equal "/photos/1", photo_path("1")
end
def test_shallow_path_inside_namespace_is_not_added_twice
@@ -3381,208 +3464,305 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- get '/admin/posts/1/comments'
- assert_equal 'admin/comments#index', @response.body
- assert_equal '/admin/posts/1/comments', admin_post_comments_path('1')
+ get "/admin/posts/1/comments"
+ assert_equal "admin/comments#index", @response.body
+ assert_equal "/admin/posts/1/comments", admin_post_comments_path("1")
end
def test_mix_string_to_controller_action
draw do
- get '/projects', controller: 'project_files',
- action: 'index',
- to: 'comments#index'
+ get "/projects", controller: "project_files",
+ action: "index",
+ to: "comments#index"
end
- get '/projects'
- assert_equal 'comments#index', @response.body
+ get "/projects"
+ assert_equal "comments#index", @response.body
end
def test_mix_string_to_controller
draw do
- get '/projects', controller: 'project_files',
- to: 'comments#index'
+ get "/projects", controller: "project_files",
+ to: "comments#index"
end
- get '/projects'
- assert_equal 'comments#index', @response.body
+ get "/projects"
+ assert_equal "comments#index", @response.body
end
def test_mix_string_to_action
draw do
- get '/projects', action: 'index',
- to: 'comments#index'
+ get "/projects", action: "index",
+ to: "comments#index"
end
- get '/projects'
- assert_equal 'comments#index', @response.body
+ get "/projects"
+ assert_equal "comments#index", @response.body
end
def test_shallow_path_and_prefix_are_not_added_to_non_shallow_routes
draw do
- scope shallow_path: 'projects', shallow_prefix: 'project' do
+ scope shallow_path: "projects", shallow_prefix: "project" do
resources :projects do
- resources :files, controller: 'project_files', shallow: true
+ resources :files, controller: "project_files", shallow: true
end
end
end
- get '/projects'
- assert_equal 'projects#index', @response.body
- assert_equal '/projects', projects_path
+ get "/projects"
+ assert_equal "projects#index", @response.body
+ assert_equal "/projects", projects_path
- get '/projects/new'
- assert_equal 'projects#new', @response.body
- assert_equal '/projects/new', new_project_path
+ get "/projects/new"
+ assert_equal "projects#new", @response.body
+ assert_equal "/projects/new", new_project_path
- post '/projects'
- assert_equal 'projects#create', @response.body
+ post "/projects"
+ assert_equal "projects#create", @response.body
- get '/projects/1'
- assert_equal 'projects#show', @response.body
- assert_equal '/projects/1', project_path('1')
+ get "/projects/1"
+ assert_equal "projects#show", @response.body
+ assert_equal "/projects/1", project_path("1")
- get '/projects/1/edit'
- assert_equal 'projects#edit', @response.body
- assert_equal '/projects/1/edit', edit_project_path('1')
+ get "/projects/1/edit"
+ assert_equal "projects#edit", @response.body
+ assert_equal "/projects/1/edit", edit_project_path("1")
- patch '/projects/1'
- assert_equal 'projects#update', @response.body
+ patch "/projects/1"
+ assert_equal "projects#update", @response.body
- delete '/projects/1'
- assert_equal 'projects#destroy', @response.body
+ delete "/projects/1"
+ assert_equal "projects#destroy", @response.body
- get '/projects/1/files'
- assert_equal 'project_files#index', @response.body
- assert_equal '/projects/1/files', project_files_path('1')
+ get "/projects/1/files"
+ assert_equal "project_files#index", @response.body
+ assert_equal "/projects/1/files", project_files_path("1")
- get '/projects/1/files/new'
- assert_equal 'project_files#new', @response.body
- assert_equal '/projects/1/files/new', new_project_file_path('1')
+ get "/projects/1/files/new"
+ assert_equal "project_files#new", @response.body
+ assert_equal "/projects/1/files/new", new_project_file_path("1")
- post '/projects/1/files'
- assert_equal 'project_files#create', @response.body
+ post "/projects/1/files"
+ assert_equal "project_files#create", @response.body
- get '/projects/files/2'
- assert_equal 'project_files#show', @response.body
- assert_equal '/projects/files/2', project_file_path('2')
+ get "/projects/files/2"
+ assert_equal "project_files#show", @response.body
+ assert_equal "/projects/files/2", project_file_path("2")
- get '/projects/files/2/edit'
- assert_equal 'project_files#edit', @response.body
- assert_equal '/projects/files/2/edit', edit_project_file_path('2')
+ get "/projects/files/2/edit"
+ assert_equal "project_files#edit", @response.body
+ assert_equal "/projects/files/2/edit", edit_project_file_path("2")
- patch '/projects/files/2'
- assert_equal 'project_files#update', @response.body
+ patch "/projects/files/2"
+ assert_equal "project_files#update", @response.body
- delete '/projects/files/2'
- assert_equal 'project_files#destroy', @response.body
+ delete "/projects/files/2"
+ assert_equal "project_files#destroy", @response.body
end
def test_scope_path_is_copied_to_shallow_path
draw do
- scope path: 'foo' do
+ scope path: "foo" do
resources :posts do
resources :comments, shallow: true
end
end
end
- assert_equal '/foo/comments/1', comment_path('1')
+ assert_equal "/foo/comments/1", comment_path("1")
end
def test_scope_as_is_copied_to_shallow_prefix
draw do
- scope as: 'foo' do
+ scope as: "foo" do
resources :posts do
resources :comments, shallow: true
end
end
end
- assert_equal '/comments/1', foo_comment_path('1')
+ assert_equal "/comments/1", foo_comment_path("1")
end
def test_scope_shallow_prefix_is_not_overwritten_by_as
draw do
- scope as: 'foo', shallow_prefix: 'bar' do
+ scope as: "foo", shallow_prefix: "bar" do
resources :posts do
resources :comments, shallow: true
end
end
end
- assert_equal '/comments/1', bar_comment_path('1')
+ assert_equal "/comments/1", bar_comment_path("1")
end
def test_scope_shallow_path_is_not_overwritten_by_path
draw do
- scope path: 'foo', shallow_path: 'bar' do
+ scope path: "foo", shallow_path: "bar" do
resources :posts do
resources :comments, shallow: true
end
end
end
- assert_equal '/bar/comments/1', comment_path('1')
+ assert_equal "/bar/comments/1", comment_path("1")
end
def test_resource_where_as_is_empty
draw do
- resource :post, as: ''
+ resource :post, as: ""
- scope 'post', as: 'post' do
- resource :comment, as: ''
+ scope "post", as: "post" do
+ resource :comment, as: ""
end
end
- assert_equal '/post/new', new_path
- assert_equal '/post/comment/new', new_post_path
+ assert_equal "/post/new", new_path
+ assert_equal "/post/comment/new", new_post_path
end
def test_resources_where_as_is_empty
draw do
- resources :posts, as: ''
+ resources :posts, as: ""
- scope 'posts', as: 'posts' do
- resources :comments, as: ''
+ scope "posts", as: "posts" do
+ resources :comments, as: ""
end
end
- assert_equal '/posts/new', new_path
- assert_equal '/posts/comments/new', new_posts_path
+ assert_equal "/posts/new", new_path
+ assert_equal "/posts/comments/new", new_posts_path
end
def test_scope_where_as_is_empty
draw do
- scope 'post', as: '' do
+ scope "post", as: "" do
resource :user
resources :comments
end
end
- assert_equal '/post/user/new', new_user_path
- assert_equal '/post/comments/new', new_comment_path
+ assert_equal "/post/user/new", new_user_path
+ assert_equal "/post/comments/new", new_comment_path
end
def test_head_fetch_with_mount_on_root
draw do
- get '/home' => 'test#index'
- mount lambda { |env| [200, {}, [env['REQUEST_METHOD']]] }, at: '/'
+ get "/home" => "test#index"
+ mount lambda { |env| [200, {}, [env["REQUEST_METHOD"]]] }, at: "/"
end
# HEAD request should match `get /home` rather than the
# lower-precedence Rack app mounted at `/`.
- head '/home'
+ head "/home"
assert_response :ok
- assert_equal 'test#index', @response.body
+ assert_equal "test#index", @response.body
# But the Rack app can still respond to its own HEAD requests.
- head '/foobar'
+ head "/foobar"
assert_response :ok
- assert_equal 'HEAD', @response.body
+ assert_equal "HEAD", @response.body
+ end
+
+ def test_passing_action_parameters_to_url_helpers_raises_error_if_parameters_are_not_permitted
+ draw do
+ root to: "projects#index"
+ end
+ params = ActionController::Parameters.new(id: "1")
+
+ assert_raises ActionController::UnfilteredParameters do
+ root_path(params)
+ end
+ end
+
+ def test_passing_action_parameters_to_url_helpers_is_allowed_if_parameters_are_permitted
+ draw do
+ root to: "projects#index"
+ end
+ params = ActionController::Parameters.new(id: "1")
+ params.permit!
+
+ assert_equal "/?id=1", root_path(params)
+ end
+
+ def test_dynamic_controller_segments_are_deprecated
+ assert_deprecated do
+ draw do
+ get "/:controller", action: "index"
+ end
+ end
+ end
+
+ def test_dynamic_action_segments_are_deprecated
+ assert_deprecated do
+ draw do
+ get "/pages/:action", controller: "pages"
+ end
+ end
+ end
+
+ def test_multiple_roots
+ draw do
+ namespace :foo do
+ root "pages#index", constraints: { host: "www.example.com" }
+ root "admin/pages#index", constraints: { host: "admin.example.com" }
+ end
+
+ root "pages#index", constraints: { host: "www.example.com" }
+ root "admin/pages#index", constraints: { host: "admin.example.com" }
+ end
+
+ get "http://www.example.com/foo"
+ assert_equal "foo/pages#index", @response.body
+
+ get "http://admin.example.com/foo"
+ assert_equal "foo/admin/pages#index", @response.body
+
+ get "http://www.example.com/"
+ assert_equal "pages#index", @response.body
+
+ get "http://admin.example.com/"
+ assert_equal "admin/pages#index", @response.body
+ end
+
+ def test_multiple_namespaced_roots
+ draw do
+ namespace :foo do
+ root "test#index"
+ end
+
+ root "test#index"
+
+ namespace :bar do
+ root "test#index"
+ end
+ end
+
+ assert_equal "/foo", foo_root_path
+ assert_equal "/", root_path
+ assert_equal "/bar", bar_root_path
+ end
+
+ def test_nested_routes_under_format_resource
+ draw do
+ resources :formats do
+ resources :items
+ end
+ end
+
+ get "/formats/1/items.json"
+ assert_equal 200, @response.status
+ assert_equal "items#index", @response.body
+ assert_equal "/formats/1/items.json", format_items_path(1, :json)
+
+ get "/formats/1/items/2.json"
+ assert_equal 200, @response.status
+ assert_equal "items#show", @response.body
+ assert_equal "/formats/1/items/2.json", format_item_path(1, 2, :json)
end
private
def draw(&block)
self.class.stub_controllers do |routes|
- routes.default_url_options = { host: 'www.example.com' }
+ routes.default_url_options = { host: "www.example.com" }
routes.draw(&block)
@app = RoutedRackApp.new routes
end
@@ -3608,9 +3788,9 @@ private
https!(old_https)
end
- def verify_redirect(url, status=301)
+ def verify_redirect(url, status = 301)
assert_equal status, @response.status
- assert_equal url, @response.headers['Location']
+ assert_equal url, @response.headers["Location"]
assert_equal expected_redirect_body(url), @response.body
end
@@ -3647,13 +3827,13 @@ class TestAltApp < ActionDispatch::IntegrationTest
class XHeader
def call(env)
- [200, {"Content-Type" => "text/html"}, ["XHeader"]]
+ [200, { "Content-Type" => "text/html" }, ["XHeader"]]
end
end
class AltApp
def call(env)
- [200, {"Content-Type" => "text/html"}, ["Alternative App"]]
+ [200, { "Content-Type" => "text/html" }, ["Alternative App"]]
end
end
@@ -3663,7 +3843,7 @@ class TestAltApp < ActionDispatch::IntegrationTest
end
}.new
AltRoutes.draw do
- get "/" => TestAltApp::XHeader.new, :constraints => {:x_header => /HEADER/}
+ get "/" => TestAltApp::XHeader.new, :constraints => { x_header: /HEADER/ }
get "/" => TestAltApp::AltApp.new
end
@@ -3691,7 +3871,7 @@ end
class TestAppendingRoutes < ActionDispatch::IntegrationTest
def simple_app(resp)
- lambda { |e| [ 200, { 'Content-Type' => 'text/plain' }, [resp] ] }
+ lambda { |e| [ 200, { "Content-Type" => "text/plain" }, [resp] ] }
end
def setup
@@ -3699,28 +3879,28 @@ class TestAppendingRoutes < ActionDispatch::IntegrationTest
s = self
routes = ActionDispatch::Routing::RouteSet.new
routes.append do
- get '/hello' => s.simple_app('fail')
- get '/goodbye' => s.simple_app('goodbye')
+ get "/hello" => s.simple_app("fail")
+ get "/goodbye" => s.simple_app("goodbye")
end
routes.draw do
- get '/hello' => s.simple_app('hello')
+ get "/hello" => s.simple_app("hello")
end
@app = self.class.build_app routes
end
def test_goodbye_should_be_available
- get '/goodbye'
- assert_equal 'goodbye', @response.body
+ get "/goodbye"
+ assert_equal "goodbye", @response.body
end
def test_hello_should_not_be_overwritten
- get '/hello'
- assert_equal 'hello', @response.body
+ get "/hello"
+ assert_equal "hello", @response.body
end
def test_missing_routes_are_still_missing
- get '/random'
+ get "/random"
assert_equal 404, @response.status
end
end
@@ -3743,7 +3923,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_missing_controller
ex = assert_raises(ArgumentError) {
draw do
- get '/foo/bar', :action => :index
+ get "/foo/bar", action: :index
end
}
assert_match(/Missing :controller/, ex.message)
@@ -3752,7 +3932,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_missing_controller_with_to
ex = assert_raises(ArgumentError) {
draw do
- get '/foo/bar', :to => 'foo'
+ get "/foo/bar", to: "foo"
end
}
assert_match(/Missing :controller/, ex.message)
@@ -3761,7 +3941,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_missing_action_on_hash
ex = assert_raises(ArgumentError) {
draw do
- get '/foo/bar', :to => 'foo#'
+ get "/foo/bar", to: "foo#"
end
}
assert_match(/Missing :action/, ex.message)
@@ -3770,20 +3950,20 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_valid_controller_options_inside_namespace
draw do
namespace :admin do
- resources :storage_files, :controller => "storage_files"
+ resources :storage_files, controller: "storage_files"
end
end
- get '/admin/storage_files'
+ get "/admin/storage_files"
assert_equal "admin/storage_files#index", @response.body
end
def test_resources_with_valid_namespaced_controller_option
draw do
- resources :storage_files, :controller => 'admin/storage_files'
+ resources :storage_files, controller: "admin/storage_files"
end
- get '/storage_files'
+ get "/storage_files"
assert_equal "admin/storage_files#index", @response.body
end
@@ -3791,7 +3971,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
e = assert_raise(ArgumentError) do
draw do
namespace :admin do
- resources :storage_files, :controller => "StorageFiles"
+ resources :storage_files, controller: "StorageFiles"
end
end
end
@@ -3802,7 +3982,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_warn_with_ruby_constant_syntax_namespaced_controller_option
e = assert_raise(ArgumentError) do
draw do
- resources :storage_files, :controller => 'Admin::StorageFiles'
+ resources :storage_files, controller: "Admin::StorageFiles"
end
end
@@ -3812,7 +3992,7 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
def test_warn_with_ruby_constant_syntax_no_colons
e = assert_raise(ArgumentError) do
draw do
- resources :storage_files, :controller => 'Admin'
+ resources :storage_files, controller: "Admin"
end
end
@@ -3830,7 +4010,7 @@ class TestDefaultScope < ActionDispatch::IntegrationTest
end
DefaultScopeRoutes = ActionDispatch::Routing::RouteSet.new
- DefaultScopeRoutes.default_scope = {:module => :blog}
+ DefaultScopeRoutes.default_scope = { module: :blog }
DefaultScopeRoutes.draw do
resources :posts
end
@@ -3844,7 +4024,7 @@ class TestDefaultScope < ActionDispatch::IntegrationTest
include DefaultScopeRoutes.url_helpers
def test_default_scope
- get '/posts'
+ get "/posts"
assert_equal "blog/posts#index", @response.body
end
end
@@ -3860,7 +4040,7 @@ class TestHttpMethods < ActionDispatch::IntegrationTest
RFC5789 = %w(PATCH)
def simple_app(response)
- lambda { |env| [ 200, { 'Content-Type' => 'text/plain' }, [response] ] }
+ lambda { |env| [ 200, { "Content-Type" => "text/plain" }, [response] ] }
end
attr_reader :app
@@ -3872,14 +4052,14 @@ class TestHttpMethods < ActionDispatch::IntegrationTest
routes.draw do
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789).each do |method|
- match '/' => s.simple_app(method), :via => method.underscore.to_sym
+ match "/" => s.simple_app(method), :via => method.underscore.to_sym
end
end
end
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789).each do |method|
test "request method #{method.underscore} can be matched" do
- get '/', headers: { 'REQUEST_METHOD' => method }
+ get "/", headers: { "REQUEST_METHOD" => method }
assert_equal method, @response.body
end
end
@@ -3888,14 +4068,14 @@ end
class TestUriPathEscaping < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- get '/:segment' => lambda { |env|
- path_params = env['action_dispatch.request.path_parameters']
- [200, { 'Content-Type' => 'text/plain' }, [path_params[:segment]]]
+ get "/:segment" => lambda { |env|
+ path_params = env["action_dispatch.request.path_parameters"]
+ [200, { "Content-Type" => "text/plain" }, [path_params[:segment]]]
}, :as => :segment
- get '/*splat' => lambda { |env|
- path_params = env['action_dispatch.request.path_parameters']
- [200, { 'Content-Type' => 'text/plain' }, [path_params[:splat]]]
+ get "/*splat" => lambda { |env|
+ path_params = env["action_dispatch.request.path_parameters"]
+ [200, { "Content-Type" => "text/plain" }, [path_params[:splat]]]
}, :as => :splat
end
end
@@ -3904,22 +4084,22 @@ class TestUriPathEscaping < ActionDispatch::IntegrationTest
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')
+ test "escapes slash in generated path segment" do
+ assert_equal "/a%20b%2Fc+d", segment_path(segment: "a b/c+d")
end
- test 'unescapes recognized path segment' do
- get '/a%20b%2Fc+d'
- assert_equal 'a b/c+d', @response.body
+ test "unescapes recognized path segment" do
+ get "/a%20b%2Fc+d"
+ assert_equal "a b/c+d", @response.body
end
- test 'does not escape slash in generated path splat' do
- assert_equal '/a%20b/c+d', splat_path(:splat => 'a b/c+d')
+ test "does not escape slash in generated path splat" do
+ assert_equal "/a%20b/c+d", splat_path(splat: "a b/c+d")
end
- test 'unescapes recognized path splat' do
- get '/a%20b/c+d'
- assert_equal 'a b/c+d', @response.body
+ test "unescapes recognized path splat" do
+ get "/a%20b/c+d"
+ assert_equal "a b/c+d", @response.body
end
end
@@ -3927,7 +4107,7 @@ class TestUnicodePaths < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
get "/ほげ" => lambda { |env|
- [200, { 'Content-Type' => 'text/plain' }, []]
+ [200, { "Content-Type" => "text/plain" }, []]
}, :as => :unicode_path
end
end
@@ -3936,23 +4116,13 @@ class TestUnicodePaths < ActionDispatch::IntegrationTest
APP = build_app Routes
def app; APP end
- test 'recognizes unicode path' do
+ test "recognizes unicode path" do
get "/#{Rack::Utils.escape("ほげ")}"
assert_equal "200", @response.code
end
end
class TestMultipleNestedController < ActionDispatch::IntegrationTest
- module ::Foo
- module Bar
- class BazController < ActionController::Base
- def index
- render :inline => "<%= url_for :controller => '/pooh', :action => 'index' %>"
- end
- end
- end
- end
-
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
namespace :foo do
@@ -3964,7 +4134,18 @@ class TestMultipleNestedController < ActionDispatch::IntegrationTest
end
end
- include Routes.url_helpers
+ module ::Foo
+ module Bar
+ class BazController < ActionController::Base
+ include Routes.url_helpers
+
+ def index
+ render inline: "<%= url_for :controller => '/pooh', :action => 'index' %>"
+ end
+ end
+ end
+ end
+
APP = build_app Routes
def app; APP end
@@ -3977,7 +4158,7 @@ end
class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
get "/~user" => ok
get "/young-and-fine" => ok
@@ -3988,25 +4169,24 @@ class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest
APP = build_app Routes
def app; APP end
- test 'recognizes tilde path' do
+ test "recognizes tilde path" do
get "/~user"
assert_equal "200", @response.code
end
- test 'recognizes minus path' do
+ test "recognizes minus path" do
get "/young-and-fine"
assert_equal "200", @response.code
end
-
end
class TestRedirectInterpolation < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
get "/foo/:id" => redirect("/foo/bar/%{id}")
- get "/bar/:id" => redirect(:path => "/foo/bar/%{id}")
+ get "/bar/:id" => redirect(path: "/foo/bar/%{id}")
get "/baz/:id" => redirect("/baz?id=%{id}&foo=?&bar=1#id-%{id}")
get "/foo/bar/:id" => ok
get "/baz" => ok
@@ -4035,9 +4215,9 @@ class TestRedirectInterpolation < ActionDispatch::IntegrationTest
end
private
- def verify_redirect(url, status=301)
+ def verify_redirect(url, status = 301)
assert_equal status, @response.status
- assert_equal url, @response.headers['Location']
+ assert_equal url, @response.headers["Location"]
assert_equal expected_redirect_body(url), @response.body
end
@@ -4049,9 +4229,9 @@ end
class TestConstraintsAccessingParameters < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
- get "/:foo" => ok, :constraints => lambda { |r| r.params[:foo] == 'foo' }
+ get "/:foo" => ok, :constraints => lambda { |r| r.params[:foo] == "foo" }
get "/:bar" => ok
end
end
@@ -4061,7 +4241,7 @@ class TestConstraintsAccessingParameters < ActionDispatch::IntegrationTest
test "parameters are reset between constraint checks" do
get "/bar"
- assert_equal nil, @request.params[:foo]
+ assert_nil @request.params[:foo]
assert_equal "bar", @request.params[:bar]
end
end
@@ -4069,21 +4249,21 @@ end
class TestGlobRoutingMapper < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
- get "/*id" => redirect("/not_cars"), :constraints => {id: /dummy/}
+ get "/*id" => redirect("/not_cars"), :constraints => { id: /dummy/ }
get "/cars" => ok
end
end
- #include Routes.url_helpers
+ # include Routes.url_helpers
APP = build_app Routes
def app; APP end
def test_glob_constraint
get "/dummy"
assert_equal "301", @response.code
- assert_equal "/not_cars", @response.header['Location'].match('/[^/]+$')[0]
+ assert_equal "/not_cars", @response.header["Location"].match("/[^/]+$")[0]
end
def test_glob_constraint_skip_route
@@ -4099,13 +4279,17 @@ end
class TestOptimizedNamedRoutes < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
- get '/foo' => ok, as: :foo
- get '/post(/:action(/:id))' => ok, as: :posts
- get '/:foo/:foo_type/bars/:id' => ok, as: :bar
- get '/projects/:id.:format' => ok, as: :project
- get '/pages/:id' => ok, as: :page
- get '/wiki/*page' => ok, as: :wiki
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
+ get "/foo" => ok, as: :foo
+
+ ActiveSupport::Deprecation.silence do
+ get "/post(/:action(/:id))" => ok, as: :posts
+ end
+
+ get "/:foo/:foo_type/bars/:id" => ok, as: :bar
+ get "/projects/:id.:format" => ok, as: :project
+ get "/pages/:id" => ok, as: :page
+ get "/wiki/*page" => ok, as: :wiki
end
end
@@ -4113,51 +4297,51 @@ class TestOptimizedNamedRoutes < ActionDispatch::IntegrationTest
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?
+ test "enabled when not mounted and default_url_options is empty" do
+ assert_predicate Routes.url_helpers, :optimize_routes_generation?
end
- test 'named route called as singleton method' do
- assert_equal '/foo', Routes.url_helpers.foo_path
+ test "named route called as singleton method" do
+ assert_equal "/foo", Routes.url_helpers.foo_path
end
- test 'named route called on included module' do
- assert_equal '/foo', foo_path
+ test "named route called on included module" do
+ assert_equal "/foo", foo_path
end
- test 'nested optional segments are removed' do
- assert_equal '/post', Routes.url_helpers.posts_path
- assert_equal '/post', posts_path
+ test "nested optional segments are removed" do
+ assert_equal "/post", Routes.url_helpers.posts_path
+ assert_equal "/post", posts_path
end
- test 'segments with same prefix are replaced correctly' do
- assert_equal '/foo/baz/bars/1', Routes.url_helpers.bar_path('foo', 'baz', '1')
- assert_equal '/foo/baz/bars/1', bar_path('foo', 'baz', '1')
+ test "segments with same prefix are replaced correctly" do
+ assert_equal "/foo/baz/bars/1", Routes.url_helpers.bar_path("foo", "baz", "1")
+ assert_equal "/foo/baz/bars/1", bar_path("foo", "baz", "1")
end
- test 'segments separated with a period are replaced correctly' do
- assert_equal '/projects/1.json', Routes.url_helpers.project_path(1, :json)
- assert_equal '/projects/1.json', project_path(1, :json)
+ test "segments separated with a period are replaced correctly" do
+ assert_equal "/projects/1.json", Routes.url_helpers.project_path(1, :json)
+ assert_equal "/projects/1.json", project_path(1, :json)
end
- test 'segments with question marks are escaped' do
- assert_equal '/pages/foo%3Fbar', Routes.url_helpers.page_path('foo?bar')
- assert_equal '/pages/foo%3Fbar', page_path('foo?bar')
+ test "segments with question marks are escaped" do
+ assert_equal "/pages/foo%3Fbar", Routes.url_helpers.page_path("foo?bar")
+ assert_equal "/pages/foo%3Fbar", page_path("foo?bar")
end
- test 'segments with slashes are escaped' do
- assert_equal '/pages/foo%2Fbar', Routes.url_helpers.page_path('foo/bar')
- assert_equal '/pages/foo%2Fbar', page_path('foo/bar')
+ test "segments with slashes are escaped" do
+ assert_equal "/pages/foo%2Fbar", Routes.url_helpers.page_path("foo/bar")
+ assert_equal "/pages/foo%2Fbar", page_path("foo/bar")
end
- test 'glob segments with question marks are escaped' do
- assert_equal '/wiki/foo%3Fbar', Routes.url_helpers.wiki_path('foo?bar')
- assert_equal '/wiki/foo%3Fbar', wiki_path('foo?bar')
+ test "glob segments with question marks are escaped" do
+ assert_equal "/wiki/foo%3Fbar", Routes.url_helpers.wiki_path("foo?bar")
+ assert_equal "/wiki/foo%3Fbar", wiki_path("foo?bar")
end
- test 'glob segments with slashes are not escaped' do
- assert_equal '/wiki/foo/bar', Routes.url_helpers.wiki_path('foo/bar')
- assert_equal '/wiki/foo/bar', wiki_path('foo/bar')
+ test "glob segments with slashes are not escaped" do
+ assert_equal "/wiki/foo/bar", Routes.url_helpers.wiki_path("foo/bar")
+ assert_equal "/wiki/foo/bar", wiki_path("foo/bar")
end
end
@@ -4176,9 +4360,9 @@ class TestNamedRouteUrlHelpers < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- scope :module => "test_named_route_url_helpers" do
- get "/categories/:id" => 'categories#show', :as => :category
- get "/products/:id" => 'products#show', :as => :product
+ scope module: "test_named_route_url_helpers" do
+ get "/categories/:id" => "categories#show", :as => :category
+ get "/products/:id" => "products#show", :as => :product
end
end
end
@@ -4200,21 +4384,21 @@ end
class TestUrlConstraints < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
- constraints :subdomain => 'admin' do
- get '/' => ok, :as => :admin_root
+ constraints subdomain: "admin" do
+ get "/" => ok, :as => :admin_root
end
- scope :constraints => { :protocol => 'https://' } do
- get '/' => ok, :as => :secure_root
+ scope constraints: { protocol: "https://" } do
+ get "/" => ok, :as => :secure_root
end
- get '/' => ok, :as => :alternate_root, :constraints => { :port => 8080 }
+ get "/" => ok, :as => :alternate_root, :constraints => { port: 8080 }
- get '/search' => ok, :constraints => { :subdomain => false }
+ get "/search" => ok, :constraints => { subdomain: false }
- get '/logs' => ok, :constraints => { :subdomain => true }
+ get "/logs" => ok, :constraints => { subdomain: true }
end
end
@@ -4223,59 +4407,67 @@ class TestUrlConstraints < ActionDispatch::IntegrationTest
def app; APP end
test "constraints are copied to defaults when using constraints method" do
- assert_equal 'http://admin.example.com/', admin_root_url
+ assert_equal "http://admin.example.com/", admin_root_url
- get 'http://admin.example.com/'
+ get "http://admin.example.com/"
assert_response :success
end
test "constraints are copied to defaults when using scope constraints hash" do
- assert_equal 'https://www.example.com/', secure_root_url
+ assert_equal "https://www.example.com/", secure_root_url
- get 'https://www.example.com/'
+ get "https://www.example.com/"
assert_response :success
end
test "constraints are copied to defaults when using route constraints hash" do
- assert_equal 'http://www.example.com:8080/', alternate_root_url
+ assert_equal "http://www.example.com:8080/", alternate_root_url
- get 'http://www.example.com:8080/'
+ get "http://www.example.com:8080/"
assert_response :success
end
test "false constraint expressions check for absence of values" do
- get 'http://example.com/search'
+ get "http://example.com/search"
assert_response :success
- assert_equal 'http://example.com/search', search_url
+ assert_equal "http://example.com/search", search_url
- get 'http://api.example.com/search'
+ get "http://api.example.com/search"
assert_response :not_found
end
test "true constraint expressions check for presence of values" do
- get 'http://api.example.com/logs'
+ get "http://api.example.com/logs"
assert_response :success
- assert_equal 'http://api.example.com/logs', logs_url
+ assert_equal "http://api.example.com/logs", logs_url
- get 'http://example.com/logs'
+ get "http://example.com/logs"
assert_response :not_found
end
end
class TestInvalidUrls < ActionDispatch::IntegrationTest
class FooController < ActionController::Base
+ def self.binary_params_for?(action)
+ action == "show"
+ end
+
def show
render plain: "foo#show"
end
end
- test "invalid UTF-8 encoding returns a 400 Bad Request" do
+ test "invalid UTF-8 encoding returns a bad request" do
with_routing do |set|
set.draw do
- get "/bar/:id", :to => redirect("/foo/show/%{id}")
- get "/foo/show(/:id)", :to => "test_invalid_urls/foo#show"
- get "/foo(/:action(/:id))", :controller => "test_invalid_urls/foo"
- get "/:controller(/:action(/:id))"
+ get "/bar/:id", to: redirect("/foo/show/%{id}")
+
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
+ get "/foobar/:id", to: ok
+
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action(/:id))"
+ end
end
get "/%E2%EF%BF%BD%A6"
@@ -4284,20 +4476,31 @@ class TestInvalidUrls < ActionDispatch::IntegrationTest
get "/foo/%E2%EF%BF%BD%A6"
assert_response :bad_request
- get "/foo/show/%E2%EF%BF%BD%A6"
+ get "/bar/%E2%EF%BF%BD%A6"
assert_response :bad_request
- get "/bar/%E2%EF%BF%BD%A6"
+ get "/foobar/%E2%EF%BF%BD%A6"
assert_response :bad_request
end
end
+
+ test "params encoded with binary_params_for? are treated as ASCII 8bit" do
+ with_routing do |set|
+ set.draw do
+ get "/foo/show(/:id)", to: "test_invalid_urls/foo#show"
+ end
+
+ get "/foo/show/%E2%EF%BF%BD%A6"
+ assert_response :ok
+ end
+ end
end
class TestOptionalRootSegments < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes
Routes.draw do
- get '/(page/:page)', :to => 'pages#index', :as => :root
+ get "/(page/:page)", to: "pages#index", as: :root
end
end
@@ -4309,27 +4512,27 @@ class TestOptionalRootSegments < ActionDispatch::IntegrationTest
include Routes.url_helpers
def test_optional_root_segments
- get '/'
- assert_equal 'pages#index', @response.body
- assert_equal '/', root_path
+ get "/"
+ assert_equal "pages#index", @response.body
+ assert_equal "/", root_path
- get '/page/1'
- assert_equal 'pages#index', @response.body
- assert_equal '1', @request.params[:page]
- assert_equal '/page/1', root_path('1')
- assert_equal '/page/1', root_path(:page => '1')
+ get "/page/1"
+ assert_equal "pages#index", @response.body
+ assert_equal "1", @request.params[:page]
+ assert_equal "/page/1", root_path("1")
+ assert_equal "/page/1", root_path(page: "1")
end
end
class TestPortConstraints < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
- get '/integer', to: ok, constraints: { :port => 8080 }
- get '/string', to: ok, constraints: { :port => '8080' }
- get '/array', to: ok, constraints: { :port => [8080] }
- get '/regexp', to: ok, constraints: { :port => /8080/ }
+ get "/integer", to: ok, constraints: { port: 8080 }
+ get "/string", to: ok, constraints: { port: "8080" }
+ get "/array/:idx", to: ok, constraints: { port: [8080], idx: %w[first last] }
+ get "/regexp", to: ok, constraints: { port: /8080/ }
end
end
@@ -4338,34 +4541,37 @@ class TestPortConstraints < ActionDispatch::IntegrationTest
def app; APP end
def test_integer_port_constraints
- get 'http://www.example.com/integer'
+ get "http://www.example.com/integer"
assert_response :not_found
- get 'http://www.example.com:8080/integer'
+ get "http://www.example.com:8080/integer"
assert_response :success
end
def test_string_port_constraints
- get 'http://www.example.com/string'
+ get "http://www.example.com/string"
assert_response :not_found
- get 'http://www.example.com:8080/string'
+ get "http://www.example.com:8080/string"
assert_response :success
end
def test_array_port_constraints
- get 'http://www.example.com/array'
+ get "http://www.example.com/array"
+ assert_response :not_found
+
+ get "http://www.example.com:8080/array/middle"
assert_response :not_found
- get 'http://www.example.com:8080/array'
+ get "http://www.example.com:8080/array/first"
assert_response :success
end
def test_regexp_port_constraints
- get 'http://www.example.com/regexp'
+ get "http://www.example.com/regexp"
assert_response :not_found
- get 'http://www.example.com:8080/regexp'
+ get "http://www.example.com:8080/regexp"
assert_response :success
end
end
@@ -4373,12 +4579,12 @@ end
class TestFormatConstraints < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
- get '/string', to: ok, constraints: { format: 'json' }
- get '/regexp', to: ok, constraints: { format: /json/ }
- get '/json_only', to: ok, format: true, constraints: { format: /json/ }
- get '/xml_only', to: ok, format: 'xml'
+ get "/string", to: ok, constraints: { format: "json" }
+ get "/regexp", to: ok, constraints: { format: /json/ }
+ get "/json_only", to: ok, format: true, constraints: { format: /json/ }
+ get "/xml_only", to: ok, format: "xml"
end
end
@@ -4387,46 +4593,46 @@ class TestFormatConstraints < ActionDispatch::IntegrationTest
def app; APP end
def test_string_format_constraints
- get 'http://www.example.com/string'
+ get "http://www.example.com/string"
assert_response :success
- get 'http://www.example.com/string.json'
+ get "http://www.example.com/string.json"
assert_response :success
- get 'http://www.example.com/string.html'
+ get "http://www.example.com/string.html"
assert_response :not_found
end
def test_regexp_format_constraints
- get 'http://www.example.com/regexp'
+ get "http://www.example.com/regexp"
assert_response :success
- get 'http://www.example.com/regexp.json'
+ get "http://www.example.com/regexp.json"
assert_response :success
- get 'http://www.example.com/regexp.html'
+ get "http://www.example.com/regexp.html"
assert_response :not_found
end
def test_enforce_with_format_true_with_constraint
- get 'http://www.example.com/json_only.json'
+ get "http://www.example.com/json_only.json"
assert_response :success
- get 'http://www.example.com/json_only.html'
+ get "http://www.example.com/json_only.html"
assert_response :not_found
- get 'http://www.example.com/json_only'
+ get "http://www.example.com/json_only"
assert_response :not_found
end
def test_enforce_with_string
- get 'http://www.example.com/xml_only.xml'
+ get "http://www.example.com/xml_only.xml"
assert_response :success
- get 'http://www.example.com/xml_only'
+ get "http://www.example.com/xml_only"
assert_response :success
- get 'http://www.example.com/xml_only.json'
+ get "http://www.example.com/xml_only.json"
assert_response :not_found
end
end
@@ -4435,8 +4641,8 @@ class TestCallableConstraintValidation < ActionDispatch::IntegrationTest
def test_constraint_with_object_not_callable
assert_raises(ArgumentError) do
ActionDispatch::Routing::RouteSet.new.draw do
- ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
- get '/test', to: ok, constraints: Object.new
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
+ get "/test", to: ok, constraints: Object.new
end
end
end
@@ -4446,8 +4652,8 @@ class TestRouteDefaults < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes
Routes.draw do
- resources :posts, bucket_type: 'post'
- resources :projects, defaults: { bucket_type: 'project' }
+ resources :posts, bucket_type: "post"
+ resources :projects, defaults: { bucket_type: "project" }
end
end
@@ -4460,14 +4666,14 @@ class TestRouteDefaults < ActionDispatch::IntegrationTest
def test_route_options_are_required_for_url_for
assert_raises(ActionController::UrlGenerationError) do
- assert_equal '/posts/1', url_for(controller: 'posts', action: 'show', id: 1, only_path: true)
+ assert_equal "/posts/1", url_for(controller: "posts", action: "show", id: 1, only_path: true)
end
- assert_equal '/posts/1', url_for(controller: 'posts', action: 'show', id: 1, bucket_type: 'post', only_path: true)
+ assert_equal "/posts/1", url_for(controller: "posts", action: "show", id: 1, bucket_type: "post", only_path: true)
end
def test_route_defaults_are_not_required_for_url_for
- assert_equal '/projects/1', url_for(controller: 'projects', action: 'show', id: 1, only_path: true)
+ assert_equal "/projects/1", url_for(controller: "projects", action: "show", id: 1, only_path: true)
end
end
@@ -4475,9 +4681,9 @@ class TestRackAppRouteGeneration < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes
Routes.draw do
- rack_app = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
- mount rack_app, at: '/account', as: 'account'
- mount rack_app, at: '/:locale/account', as: 'localized_account'
+ rack_app = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
+ mount rack_app, at: "/account", as: "account"
+ mount rack_app, at: "/:locale/account", as: "localized_account"
end
end
@@ -4490,11 +4696,11 @@ class TestRackAppRouteGeneration < ActionDispatch::IntegrationTest
def test_mounted_application_doesnt_match_unnamed_route
assert_raise(ActionController::UrlGenerationError) do
- assert_equal '/account?controller=products', url_for(controller: 'products', action: 'index', only_path: true)
+ assert_equal "/account?controller=products", url_for(controller: "products", action: "index", only_path: true)
end
assert_raise(ActionController::UrlGenerationError) do
- assert_equal '/de/account?controller=products', url_for(controller: 'products', action: 'index', :locale => 'de', only_path: true)
+ assert_equal "/de/account?controller=products", url_for(controller: "products", action: "index", locale: "de", only_path: true)
end
end
end
@@ -4503,8 +4709,8 @@ class TestRedirectRouteGeneration < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes
Routes.draw do
- get '/account', to: redirect('/myaccount'), as: 'account'
- get '/:locale/account', to: redirect('/%{locale}/myaccount'), as: 'localized_account'
+ get "/account", to: redirect("/myaccount"), as: "account"
+ get "/:locale/account", to: redirect("/%{locale}/myaccount"), as: "localized_account"
end
end
@@ -4517,11 +4723,11 @@ class TestRedirectRouteGeneration < ActionDispatch::IntegrationTest
def test_redirect_doesnt_match_unnamed_route
assert_raise(ActionController::UrlGenerationError) do
- assert_equal '/account?controller=products', url_for(controller: 'products', action: 'index', only_path: true)
+ assert_equal "/account?controller=products", url_for(controller: "products", action: "index", only_path: true)
end
assert_raise(ActionController::UrlGenerationError) do
- assert_equal '/de/account?controller=products', url_for(controller: 'products', action: 'index', :locale => 'de', only_path: true)
+ assert_equal "/de/account?controller=products", url_for(controller: "products", action: "index", locale: "de", only_path: true)
end
end
end
@@ -4529,7 +4735,7 @@ end
class TestUrlGenerationErrors < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
- get "/products/:id" => 'products#show', :as => :product
+ get "/products/:id" => "products#show", :as => :product
end
end
@@ -4538,29 +4744,32 @@ class TestUrlGenerationErrors < ActionDispatch::IntegrationTest
include Routes.url_helpers
- test "url helpers raise a helpful error message when generation fails" do
- url, missing = { action: 'show', controller: 'products', id: nil }, [:id]
- message = "No route matches #{url.inspect} missing required keys: #{missing.inspect}"
+ test "url helpers raise a 'missing keys' error for a nil param with optimized helpers" do
+ url, missing = { action: "show", controller: "products", id: nil }, [:id]
+ message = "No route matches #{url.inspect}, missing required keys: #{missing.inspect}"
- # Optimized url helper
- error = assert_raises(ActionController::UrlGenerationError){ product_path(nil) }
+ error = assert_raises(ActionController::UrlGenerationError) { product_path(nil) }
assert_equal message, error.message
+ end
- # Non-optimized url helper
- error = assert_raises(ActionController::UrlGenerationError, message){ product_path(id: nil) }
+ test "url helpers raise a 'constraint failure' error for a nil param with non-optimized helpers" do
+ url, missing = { action: "show", controller: "products", id: nil }, [:id]
+ message = "No route matches #{url.inspect}, possible unmatched constraints: #{missing.inspect}"
+
+ error = assert_raises(ActionController::UrlGenerationError, message) { product_path(id: nil) }
assert_equal message, error.message
end
- test "url helpers raise message with mixed parameters when generation fails " do
- url, missing = { action: 'show', controller: 'products', id: nil, "id"=>"url-tested"}, [:id]
- message = "No route matches #{url.inspect} missing required keys: #{missing.inspect}"
+ test "url helpers raise message with mixed parameters when generation fails" do
+ url, missing = { action: "show", controller: "products", id: nil, "id" => "url-tested" }, [:id]
+ message = "No route matches #{url.inspect}, possible unmatched constraints: #{missing.inspect}"
# Optimized url helper
- error = assert_raises(ActionController::UrlGenerationError){ product_path(nil, 'id'=>'url-tested') }
+ error = assert_raises(ActionController::UrlGenerationError) { product_path(nil, "id" => "url-tested") }
assert_equal message, error.message
# Non-optimized url helper
- error = assert_raises(ActionController::UrlGenerationError, message){ product_path(id: nil, 'id'=>'url-tested') }
+ error = assert_raises(ActionController::UrlGenerationError, message) { product_path(id: nil, "id" => "url-tested") }
assert_equal message, error.message
end
end
@@ -4574,9 +4783,9 @@ class TestDefaultUrlOptions < ActionDispatch::IntegrationTest
Routes = ActionDispatch::Routing::RouteSet.new
Routes.draw do
- default_url_options locale: 'en'
- scope ':locale', format: false do
- get '/posts/:year/:month/:day', to: 'posts#archive', as: 'archived_posts'
+ default_url_options locale: "en"
+ scope ":locale", format: false do
+ get "/posts/:year/:month/:day", to: "posts#archive", as: "archived_posts"
end
end
@@ -4589,6 +4798,333 @@ class TestDefaultUrlOptions < ActionDispatch::IntegrationTest
include Routes.url_helpers
def test_positional_args_with_format_false
- assert_equal '/en/posts/2014/12/13', archived_posts_path(2014, 12, 13)
+ assert_equal "/en/posts/2014/12/13", archived_posts_path(2014, 12, 13)
+ end
+end
+
+class TestErrorsInController < ActionDispatch::IntegrationTest
+ class ::PostsController < ActionController::Base
+ def foo
+ nil.i_do_not_exist
+ end
+
+ def bar
+ NonExistingClass.new
+ end
+ end
+
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get "/:controller(/:action)"
+ end
+ end
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ def test_legit_no_method_errors_are_not_caught
+ get "/posts/foo"
+ assert_equal 500, response.status
+ end
+
+ def test_legit_name_errors_are_not_caught
+ get "/posts/bar"
+ assert_equal 500, response.status
+ end
+
+ def test_legit_routing_not_found_responses
+ get "/posts/baz"
+ assert_equal 404, response.status
+
+ get "/i_do_not_exist"
+ assert_equal 404, response.status
+ end
+end
+
+class TestPartialDynamicPathSegments < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw do
+ ok = lambda { |env| [200, { "Content-Type" => "text/plain" }, []] }
+
+ get "/songs/song-:song", to: ok
+ get "/songs/:song-song", to: ok
+ get "/:artist/song-:song", to: ok
+ get "/:artist/:song-song", to: ok
+
+ get "/optional/songs(/song-:song)", to: ok
+ get "/optional/songs(/:song-song)", to: ok
+ get "/optional/:artist(/song-:song)", to: ok
+ get "/optional/:artist(/:song-song)", to: ok
+ end
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ def test_paths_with_partial_dynamic_segments_are_recognised
+ get "/david-bowie/changes-song"
+ assert_equal 200, response.status
+ assert_params artist: "david-bowie", song: "changes"
+
+ get "/david-bowie/song-changes"
+ assert_equal 200, response.status
+ assert_params artist: "david-bowie", song: "changes"
+
+ get "/songs/song-changes"
+ assert_equal 200, response.status
+ assert_params song: "changes"
+
+ get "/songs/changes-song"
+ assert_equal 200, response.status
+ assert_params song: "changes"
+
+ get "/optional/songs/song-changes"
+ assert_equal 200, response.status
+ assert_params song: "changes"
+
+ get "/optional/songs/changes-song"
+ assert_equal 200, response.status
+ assert_params song: "changes"
+
+ get "/optional/david-bowie/changes-song"
+ assert_equal 200, response.status
+ assert_params artist: "david-bowie", song: "changes"
+
+ get "/optional/david-bowie/song-changes"
+ assert_equal 200, response.status
+ assert_params artist: "david-bowie", song: "changes"
+ end
+
+ private
+
+ def assert_params(params)
+ assert_equal(params, request.path_parameters)
+ end
+end
+
+class TestPathParameters < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ scope module: "test_path_parameters" do
+ scope ":locale", locale: /en|ar/ do
+ root to: "home#index"
+ get "/about", to: "pages#about"
+ end
+ end
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action/(:id))"
+ end
+ end
+ end
+
+ class HomeController < ActionController::Base
+ include Routes.url_helpers
+
+ def index
+ render inline: "<%= root_path %>"
+ end
+ end
+
+ class PagesController < ActionController::Base
+ include Routes.url_helpers
+
+ def about
+ render inline: "<%= root_path(locale: :ar) %> | <%= url_for(locale: :ar) %>"
+ end
+ end
+
+ APP = build_app Routes
+ def app; APP end
+
+ def test_path_parameters_are_not_mutated
+ get "/en/about"
+ assert_equal "/ar | /ar/about", @response.body
+ end
+end
+
+class TestInternalRoutingParams < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ get "/test_internal/:internal" => "internal#internal"
+ end
+ end
+
+ class ::InternalController < ActionController::Base
+ def internal
+ head :ok
+ end
+ end
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ def test_paths_with_partial_dynamic_segments_are_recognised
+ get "/test_internal/123"
+ assert_equal 200, response.status
+
+ assert_equal(
+ { controller: "internal", action: "internal", internal: "123" },
+ request.path_parameters
+ )
+ end
+end
+
+class FlashRedirectTest < ActionDispatch::IntegrationTest
+ SessionKey = "_myapp_session"
+ Generator = ActiveSupport::LegacyKeyGenerator.new("b3c631c314c0bbca50c1b2843150fe33")
+ Rotations = ActiveSupport::Messages::RotationConfiguration.new
+
+ class KeyGeneratorMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env["action_dispatch.key_generator"] ||= Generator
+ env["action_dispatch.cookies_rotations"] ||= Rotations
+
+ @app.call(env)
+ end
+ end
+
+ class FooController < ActionController::Base
+ def bar
+ render plain: (flash[:foo] || "foo")
+ end
+ end
+
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw do
+ get "/foo", to: redirect { |params, req| req.flash[:foo] = "bar"; "/bar" }
+ get "/bar", to: "flash_redirect_test/foo#bar"
+ end
+
+ APP = build_app Routes do |middleware|
+ middleware.use KeyGeneratorMiddleware
+ middleware.use ActionDispatch::Session::CookieStore, key: SessionKey
+ middleware.use ActionDispatch::Flash
+ middleware.delete ActionDispatch::ShowExceptions
+ end
+
+ def app
+ APP
+ end
+
+ include Routes.url_helpers
+
+ def test_block_redirect_commits_flash
+ get "/foo", env: { "action_dispatch.key_generator" => Generator }
+ assert_response :redirect
+
+ follow_redirect!
+ assert_equal "bar", response.body
+ end
+end
+
+class TestRecognizePath < ActionDispatch::IntegrationTest
+ class PageConstraint
+ attr_reader :key, :pattern
+
+ def initialize(key, pattern)
+ @key = key
+ @pattern = pattern
+ end
+
+ def matches?(request)
+ request.path_parameters[key] =~ pattern
+ end
+ end
+
+ stub_controllers do |routes|
+ Routes = routes
+ routes.draw do
+ get "/hash/:foo", to: "pages#show", constraints: { foo: /foo/ }
+ get "/hash/:bar", to: "pages#show", constraints: { bar: /bar/ }
+
+ get "/proc/:foo", to: "pages#show", constraints: proc { |r| r.path_parameters[:foo] =~ /foo/ }
+ get "/proc/:bar", to: "pages#show", constraints: proc { |r| r.path_parameters[:bar] =~ /bar/ }
+
+ get "/class/:foo", to: "pages#show", constraints: PageConstraint.new(:foo, /foo/)
+ get "/class/:bar", to: "pages#show", constraints: PageConstraint.new(:bar, /bar/)
+ end
+ end
+
+ APP = build_app Routes
+ def app
+ APP
+ end
+
+ def test_hash_constraints_dont_leak_between_routes
+ expected_params = { controller: "pages", action: "show", bar: "bar" }
+ actual_params = recognize_path("/hash/bar")
+
+ assert_equal expected_params, actual_params
+ end
+
+ def test_proc_constraints_dont_leak_between_routes
+ expected_params = { controller: "pages", action: "show", bar: "bar" }
+ actual_params = recognize_path("/proc/bar")
+
+ assert_equal expected_params, actual_params
+ end
+
+ def test_class_constraints_dont_leak_between_routes
+ expected_params = { controller: "pages", action: "show", bar: "bar" }
+ actual_params = recognize_path("/class/bar")
+
+ assert_equal expected_params, actual_params
+ end
+
+ private
+
+ def recognize_path(*args)
+ Routes.recognize_path(*args)
+ end
+end
+
+class TestRelativeUrlRootGeneration < ActionDispatch::IntegrationTest
+ config = ActionDispatch::Routing::RouteSet::Config.new("/blog", false)
+
+ stub_controllers(config) do |routes|
+ Routes = routes
+
+ routes.draw do
+ get "/", to: "posts#index", as: :posts
+ get "/:id", to: "posts#show", as: :post
+ end
+ end
+
+ include Routes.url_helpers
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ def test_url_helpers
+ assert_equal "/blog/", posts_path({})
+ assert_equal "/blog/", Routes.url_helpers.posts_path({})
+
+ assert_equal "/blog/1", post_path(id: "1")
+ assert_equal "/blog/1", Routes.url_helpers.post_path(id: "1")
+ end
+
+ def test_optimized_url_helpers
+ assert_equal "/blog/", posts_path
+ assert_equal "/blog/", Routes.url_helpers.posts_path
+
+ assert_equal "/blog/1", post_path("1")
+ assert_equal "/blog/1", Routes.url_helpers.post_path("1")
end
end
diff --git a/actionpack/test/dispatch/runner_test.rb b/actionpack/test/dispatch/runner_test.rb
new file mode 100644
index 0000000000..f16c7963af
--- /dev/null
+++ b/actionpack/test/dispatch/runner_test.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class RunnerTest < ActiveSupport::TestCase
+ test "runner preserves the setting of integration_session" do
+ runner = Class.new do
+ def before_setup
+ end
+ end.new
+
+ runner.extend(ActionDispatch::Integration::Runner)
+ runner.integration_session.host! "lvh.me"
+
+ runner.before_setup
+
+ assert_equal "lvh.me", runner.integration_session.host
+ end
+end
diff --git a/actionpack/test/dispatch/session/abstract_store_test.rb b/actionpack/test/dispatch/session/abstract_store_test.rb
index d38d1bbce6..47616db15a 100644
--- a/actionpack/test/dispatch/session/abstract_store_test.rb
+++ b/actionpack/test/dispatch/session/abstract_store_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'action_dispatch/middleware/session/abstract_store'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/middleware/session/abstract_store"
module ActionDispatch
module Session
@@ -37,7 +39,7 @@ module ActionDispatch
assert @env
session = Request::Session.find ActionDispatch::Request.new @env
- session['foo'] = 'bar'
+ session["foo"] = "bar"
as.call(@env)
session1 = Request::Session.find ActionDispatch::Request.new @env
@@ -47,10 +49,10 @@ module ActionDispatch
end
private
- def app(&block)
- @env = nil
- lambda { |env| @env = env }
- end
+ def app(&block)
+ @env = nil
+ lambda { |env| @env = env }
+ end
end
end
end
diff --git a/actionpack/test/dispatch/session/cache_store_test.rb b/actionpack/test/dispatch/session/cache_store_test.rb
index dbb996973d..06e67fac9f 100644
--- a/actionpack/test/dispatch/session/cache_store_test.rb
+++ b/actionpack/test/dispatch/session/cache_store_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'fixtures/session_autoload_test/session_autoload_test/foo'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "fixtures/session_autoload_test/session_autoload_test/foo"
class CacheStoreTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@@ -35,11 +37,11 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def test_setting_and_getting_session_value
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
assert_equal 'foo: "bar"', response.body
end
@@ -47,56 +49,56 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_nil_session_value
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
end
end
def test_getting_session_value_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_cookie = cookies.send(:hash_for)['_session_id']
+ assert cookies["_session_id"]
+ session_cookie = cookies.send(:hash_for)["_session_id"]
- get '/call_reset_session'
+ get "/call_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal [], headers["Set-Cookie"]
cookies << session_cookie # replace our new session_id with our old, pre-reset session_id
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body, "data for this session should have been obliterated from cache"
+ assert_equal "foo: nil", response.body, "data for this session should have been obliterated from cache"
end
end
def test_getting_from_nonexistent_session
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
- assert_nil cookies['_session_id'], "should only create session on write, not read"
+ assert_equal "foo: nil", response.body
+ assert_nil cookies["_session_id"], "should only create session on write, not read"
end
end
def test_setting_session_value_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_id = cookies['_session_id']
+ assert cookies["_session_id"]
+ session_id = cookies["_session_id"]
- get '/call_reset_session'
+ get "/call_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal [], headers["Set-Cookie"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
assert_not_equal session_id, response.body
end
@@ -104,12 +106,12 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_session_id
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_id = cookies['_session_id']
+ assert cookies["_session_id"]
+ session_id = cookies["_session_id"]
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
assert_equal session_id, response.body, "should be able to read session id without accessing the session hash"
end
@@ -118,16 +120,16 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def test_deserializes_unloaded_class
with_test_route_set do
with_autoload_path "session_autoload_test" do
- get '/set_serialized_session_value'
+ get "/set_serialized_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
end
with_autoload_path "session_autoload_test" do
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
end
with_autoload_path "session_autoload_test" do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
assert_equal 'foo: #<SessionAutoloadTest::Foo bar:"baz">', response.body, "should auto-load unloaded class"
end
@@ -136,27 +138,27 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def test_doesnt_write_session_cookie_if_session_id_is_already_exists
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal nil, headers['Set-Cookie'], "should not resend the cookie again if session_id cookie is already exists"
+ assert_nil headers["Set-Cookie"], "should not resend the cookie again if session_id cookie is already exists"
end
end
def test_prevents_session_fixation
with_test_route_set do
- assert_equal nil, @cache.read('_session_id:0xhax')
+ assert_nil @cache.read("_session_id:0xhax")
- cookies['_session_id'] = '0xhax'
- get '/set_session_value'
+ cookies["_session_id"] = "0xhax"
+ get "/set_session_value"
assert_response :success
- assert_not_equal '0xhax', cookies['_session_id']
- assert_equal nil, @cache.read('_session_id:0xhax')
- assert_equal({'foo' => 'bar'}, @cache.read("_session_id:#{cookies['_session_id']}"))
+ assert_not_equal "0xhax", cookies["_session_id"]
+ assert_nil @cache.read("_session_id:0xhax")
+ assert_equal({ "foo" => "bar" }, @cache.read("_session_id:#{cookies['_session_id']}"))
end
end
@@ -164,12 +166,14 @@ class CacheStoreTest < ActionDispatch::IntegrationTest
def with_test_route_set
with_routing do |set|
set.draw do
- get ':action', :to => ::CacheStoreTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::CacheStoreTest::TestController
+ end
end
@app = self.class.build_app(set) do |middleware|
@cache = ActiveSupport::Cache::MemoryStore.new
- middleware.use ActionDispatch::Session::CacheStore, :key => '_session_id', :cache => @cache
+ middleware.use ActionDispatch::Session::CacheStore, key: "_session_id", cache: @cache
middleware.delete ActionDispatch::ShowExceptions
end
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index f07e215e3a..e34426a471 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -1,14 +1,21 @@
-require 'abstract_unit'
-require 'stringio'
-require 'active_support/key_generator'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "stringio"
+require "active_support/key_generator"
+require "active_support/messages/rotation_configuration"
class CookieStoreTest < ActionDispatch::IntegrationTest
- SessionKey = '_myapp_session'
- SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33'
- Generator = ActiveSupport::LegacyKeyGenerator.new(SessionSecret)
+ SessionKey = "_myapp_session"
+ SessionSecret = "b3c631c314c0bbca50c1b2843150fe33"
+ SessionSalt = "authenticated encrypted cookie"
+
+ Generator = ActiveSupport::KeyGenerator.new(SessionSecret, iterations: 1000)
+ Rotations = ActiveSupport::Messages::RotationConfiguration.new
- Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, :digest => 'SHA1')
- SignedBar = Verifier.generate(:foo => "bar", :session_id => SecureRandom.hex(16))
+ Encryptor = ActiveSupport::MessageEncryptor.new(
+ Generator.generate_key(SessionSalt, 32), cipher: "aes-256-gcm", serializer: Marshal
+ )
class TestController < ActionController::Base
def no_session_access
@@ -21,7 +28,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def set_session_value
session[:foo] = "bar"
- render plain: Rack::Utils.escape(Verifier.generate(session.to_hash))
+ render body: nil
end
def get_session_value
@@ -48,7 +55,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
end
def raise_data_overflow
- session[:foo] = 'bye!' * 1024
+ session[:foo] = "bye!" * 1024
head :ok
end
@@ -63,19 +70,35 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
end
end
+ def parse_cookie_from_header
+ cookie_matches = headers["Set-Cookie"].match(/#{SessionKey}=([^;]+)/)
+ cookie_matches && cookie_matches[1]
+ end
+
+ def assert_session_cookie(cookie_string, contents)
+ assert_includes headers["Set-Cookie"], cookie_string
+
+ session_value = parse_cookie_from_header
+ session_data = Encryptor.decrypt_and_verify(Rack::Utils.unescape(session_value)) rescue nil
+
+ assert_not_nil session_data, "session failed to decrypt"
+ assert_equal session_data.slice(*contents.keys), contents
+ end
+
def test_setting_session_value
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
+
assert_response :success
- assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; HttpOnly", "foo" => "bar"
end
end
def test_getting_session_value
with_test_route_set do
- cookies[SessionKey] = SignedBar
- get '/get_session_value'
+ get "/set_session_value"
+ get "/get_session_value"
+
assert_response :success
assert_equal 'foo: "bar"', response.body
end
@@ -83,13 +106,14 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def test_getting_session_id
with_test_route_set do
- cookies[SessionKey] = SignedBar
- get '/persistent_session_id'
+ get "/set_session_value"
+ get "/persistent_session_id"
+
assert_response :success
assert_equal 32, response.body.size
session_id = response.body
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
assert_equal "id: #{session_id}", response.body, "should be able to read session id without accessing the session hash"
end
@@ -97,51 +121,55 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def test_disregards_tampered_sessions
with_test_route_set do
- cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--123456780"
- get '/get_session_value'
+ encryptor = ActiveSupport::MessageEncryptor.new("A" * 32, cipher: "aes-256-gcm", serializer: Marshal)
+
+ cookies[SessionKey] = encryptor.encrypt_and_sign("foo" => "bar", "session_id" => "abc")
+
+ get "/get_session_value"
+
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
end
end
def test_does_not_set_secure_cookies_over_http
- with_test_route_set(:secure => true) do
- get '/set_session_value'
+ with_test_route_set(secure: true) do
+ get "/set_session_value"
assert_response :success
- assert_equal nil, headers['Set-Cookie']
+ assert_nil headers["Set-Cookie"]
end
end
def test_properly_renew_cookies
with_test_route_set do
- get '/set_session_value'
- get '/persistent_session_id'
+ get "/set_session_value"
+ get "/persistent_session_id"
session_id = response.body
- get '/renew_session_id'
- get '/persistent_session_id'
+ get "/renew_session_id"
+ get "/persistent_session_id"
assert_not_equal response.body, session_id
end
end
def test_does_set_secure_cookies_over_https
- with_test_route_set(:secure => true) do
- get '/set_session_value', headers: { 'HTTPS' => 'on' }
+ with_test_route_set(secure: true) do
+ get "/set_session_value", headers: { "HTTPS" => "on" }
+
assert_response :success
- assert_equal "_myapp_session=#{response.body}; path=/; secure; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; secure; HttpOnly", "foo" => "bar"
end
end
# {:foo=>#<SessionAutoloadTest::Foo bar:"baz">, :session_id=>"ce8b0752a6ab7c7af3cdb8a80e6b9e46"}
- SignedSerializedCookie = "BAh7BzoIZm9vbzodU2Vzc2lvbkF1dG9sb2FkVGVzdDo6Rm9vBjoJQGJhciIIYmF6Og9zZXNzaW9uX2lkIiVjZThiMDc1MmE2YWI3YzdhZjNjZGI4YTgwZTZiOWU0Ng==--2bf3af1ae8bd4e52b9ac2099258ace0c380e601c"
+ EncryptedSerializedCookie = "9RZ2Fij0qLveUwM4s+CCjGqhpjyUC8jiBIf/AiBr9M3TB8xh2vQZtvSOMfN3uf6oYbbpIDHAcOFIEl69FcW1ozQYeSrCLonYCazoh34ZdYskIQfGwCiSYleVXG1OD9Z4jFqeVArw4Ewm0paOOPLbN1rc6A==--I359v/KWdZ1ok0ey--JFFhuPOY7WUo6tB/eP05Aw=="
def test_deserializes_unloaded_classes_on_get_id
with_test_route_set do
with_autoload_path "session_autoload_test" do
- cookies[SessionKey] = SignedSerializedCookie
- get '/get_session_id'
+ cookies[SessionKey] = EncryptedSerializedCookie
+ get "/get_session_id"
assert_response :success
- assert_equal 'id: ce8b0752a6ab7c7af3cdb8a80e6b9e46', response.body, "should auto-load unloaded class"
+ assert_equal "id: ce8b0752a6ab7c7af3cdb8a80e6b9e46", response.body, "should auto-load unloaded class"
end
end
end
@@ -149,8 +177,8 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def test_deserializes_unloaded_classes_on_get_value
with_test_route_set do
with_autoload_path "session_autoload_test" do
- cookies[SessionKey] = SignedSerializedCookie
- get '/get_session_value'
+ cookies[SessionKey] = EncryptedSerializedCookie
+ get "/get_session_value"
assert_response :success
assert_equal 'foo: #<SessionAutoloadTest::Foo bar:"baz">', response.body, "should auto-load unloaded class"
end
@@ -160,107 +188,103 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def test_close_raises_when_data_overflows
with_test_route_set do
assert_raise(ActionDispatch::Cookies::CookieOverflow) {
- get '/raise_data_overflow'
+ get "/raise_data_overflow"
}
end
end
def test_doesnt_write_session_cookie_if_session_is_not_accessed
with_test_route_set do
- get '/no_session_access'
+ get "/no_session_access"
assert_response :success
- assert_equal nil, headers['Set-Cookie']
+ assert_nil headers["Set-Cookie"]
end
end
def test_doesnt_write_session_cookie_if_session_is_unchanged
with_test_route_set do
- cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" +
+ cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" \
"fef868465920f415f2c0652d6910d3af288a0367"
- get '/no_session_access'
+ get "/no_session_access"
assert_response :success
- assert_equal nil, headers['Set-Cookie']
+ assert_nil headers["Set-Cookie"]
end
end
def test_setting_session_value_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
session_payload = response.body
- assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; HttpOnly", "foo" => "bar"
- get '/call_reset_session'
+ get "/call_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal [], headers["Set-Cookie"]
assert_not_nil session_payload
assert_not_equal session_payload, cookies[SessionKey]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
end
end
def test_class_type_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; HttpOnly", "foo" => "bar"
- get '/get_class_after_reset_session'
+ get "/get_class_after_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
- assert_equal 'class: ActionDispatch::Request::Session', response.body
+ assert_not_equal [], headers["Set-Cookie"]
+ assert_equal "class: ActionDispatch::Request::Session", response.body
end
end
def test_getting_from_nonexistent_session
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
- assert_nil headers['Set-Cookie'], "should only create session on write, not read"
+ assert_equal "foo: nil", response.body
+ assert_nil headers["Set-Cookie"], "should only create session on write, not read"
end
end
def test_setting_session_value_after_session_clear
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; HttpOnly", "foo" => "bar"
- get '/call_session_clear'
+ get "/call_session_clear"
assert_response :success
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
end
end
def test_persistent_session_id
with_test_route_set do
- cookies[SessionKey] = SignedBar
- get '/persistent_session_id'
+ get "/set_session_value"
+ get "/persistent_session_id"
assert_response :success
assert_equal 32, response.body.size
session_id = response.body
- get '/persistent_session_id'
+ get "/persistent_session_id"
assert_equal session_id, response.body
reset!
- get '/persistent_session_id'
+ get "/persistent_session_id"
assert_not_equal session_id, response.body
end
end
def test_setting_session_id_to_nil_is_respected
with_test_route_set do
- cookies[SessionKey] = SignedBar
-
+ get "/set_session_value"
get "/get_session_id"
sid = response.body
assert_equal 36, sid.size
@@ -271,64 +295,86 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
end
def test_session_store_with_expire_after
- with_test_route_set(:expire_after => 5.hours) do
+ with_test_route_set(expire_after: 5.hours) do
# First request accesses the session
time = Time.local(2008, 4, 24)
- cookie_body = nil
Time.stub :now, time do
expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")
- cookies[SessionKey] = SignedBar
+ get "/set_session_value"
- get '/set_session_value'
assert_response :success
-
- cookie_body = response.body
- assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly",
- headers['Set-Cookie']
+ assert_session_cookie "path=/; expires=#{expected_expiry}; HttpOnly", "foo" => "bar"
end
# Second request does not access the session
- time = Time.local(2008, 4, 25)
+ time = time + 3.hours
Time.stub :now, time do
expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")
- get '/no_session_access'
+ get "/no_session_access"
+
assert_response :success
+ assert_session_cookie "path=/; expires=#{expected_expiry}; HttpOnly", "foo" => "bar"
+ end
+ end
+ end
+
+ def test_session_store_with_expire_after_does_not_accept_expired_session
+ with_test_route_set(expire_after: 5.hours) do
+ # First request accesses the session
+ time = Time.local(2017, 11, 12)
+
+ Time.stub :now, time do
+ expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")
+
+ get "/set_session_value"
+ get "/get_session_value"
- assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly",
- headers['Set-Cookie']
+ assert_response :success
+ assert_equal 'foo: "bar"', response.body
+ assert_session_cookie "path=/; expires=#{expected_expiry}; HttpOnly", "foo" => "bar"
+ end
+
+ # Second request is beyond the expiry time and the session is invalidated
+ time += 5.hours + 1.minute
+
+ Time.stub :now, time do
+ get "/get_session_value"
+
+ assert_response :success
+ assert_equal "foo: nil", response.body
end
end
end
def test_session_store_with_explicit_domain
- with_test_route_set(:domain => "example.es") do
- get '/set_session_value'
- assert_match(/domain=example\.es/, headers['Set-Cookie'])
- headers['Set-Cookie']
+ with_test_route_set(domain: "example.es") do
+ get "/set_session_value"
+ assert_match(/domain=example\.es/, headers["Set-Cookie"])
+ headers["Set-Cookie"]
end
end
def test_session_store_without_domain
with_test_route_set do
- get '/set_session_value'
- assert_no_match(/domain\=/, headers['Set-Cookie'])
+ get "/set_session_value"
+ assert_no_match(/domain\=/, headers["Set-Cookie"])
end
end
def test_session_store_with_nil_domain
- with_test_route_set(:domain => nil) do
- get '/set_session_value'
- assert_no_match(/domain\=/, headers['Set-Cookie'])
+ with_test_route_set(domain: nil) do
+ get "/set_session_value"
+ assert_no_match(/domain\=/, headers["Set-Cookie"])
end
end
def test_session_store_with_all_domains
- with_test_route_set(:domain => :all) do
- get '/set_session_value'
- assert_match(/domain=\.example\.com/, headers['Set-Cookie'])
+ with_test_route_set(domain: :all) do
+ get "/set_session_value"
+ assert_match(/domain=\.example\.com/, headers["Set-Cookie"])
end
end
@@ -338,17 +384,27 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
def get(path, *args)
args[0] ||= {}
args[0][:headers] ||= {}
- args[0][:headers]["action_dispatch.key_generator"] ||= Generator
+ args[0][:headers].tap do |config|
+ config["action_dispatch.secret_key_base"] = SessionSecret
+ config["action_dispatch.authenticated_encrypted_cookie_salt"] = SessionSalt
+ config["action_dispatch.use_authenticated_cookie_encryption"] = true
+
+ config["action_dispatch.key_generator"] ||= Generator
+ config["action_dispatch.cookies_rotations"] ||= Rotations
+ end
+
super(path, *args)
end
def with_test_route_set(options = {})
with_routing do |set|
set.draw do
- get ':action', :to => ::CookieStoreTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::CookieStoreTest::TestController
+ end
end
- options = { :key => SessionKey }.merge!(options)
+ options = { key: SessionKey }.merge!(options)
@app = self.class.build_app(set) do |middleware|
middleware.use ActionDispatch::Session::CookieStore, options
@@ -358,5 +414,4 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
yield
end
end
-
end
diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb
index 3fed9bad4f..9b51ee1cad 100644
--- a/actionpack/test/dispatch/session/mem_cache_store_test.rb
+++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'securerandom'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "securerandom"
# You need to start a memcached server inorder to run these tests
class MemCacheStoreTest < ActionDispatch::IntegrationTest
@@ -35,17 +37,17 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
end
begin
- require 'dalli'
- ss = Dalli::Client.new('localhost:11211').stats
- raise Dalli::DalliError unless ss['localhost:11211']
+ require "dalli"
+ ss = Dalli::Client.new("localhost:11211").stats
+ raise Dalli::DalliError unless ss["localhost:11211"]
def test_setting_and_getting_session_value
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
assert_equal 'foo: "bar"', response.body
end
@@ -55,9 +57,9 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_nil_session_value
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
end
rescue Dalli::RingError => ex
skip ex.message, ex.backtrace
@@ -65,20 +67,20 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_session_value_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_cookie = cookies.send(:hash_for)['_session_id']
+ assert cookies["_session_id"]
+ session_cookie = cookies.send(:hash_for)["_session_id"]
- get '/call_reset_session'
+ get "/call_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal [], headers["Set-Cookie"]
cookies << session_cookie # replace our new session_id with our old, pre-reset session_id
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body, "data for this session should have been obliterated from memcached"
+ assert_equal "foo: nil", response.body, "data for this session should have been obliterated from memcached"
end
rescue Dalli::RingError => ex
skip ex.message, ex.backtrace
@@ -86,10 +88,10 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_from_nonexistent_session
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
- assert_nil cookies['_session_id'], "should only create session on write, not read"
+ assert_equal "foo: nil", response.body
+ assert_nil cookies["_session_id"], "should only create session on write, not read"
end
rescue Dalli::RingError => ex
skip ex.message, ex.backtrace
@@ -97,20 +99,20 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_setting_session_value_after_session_reset
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_id = cookies['_session_id']
+ assert cookies["_session_id"]
+ session_id = cookies["_session_id"]
- get '/call_reset_session'
+ get "/call_reset_session"
assert_response :success
- assert_not_equal [], headers['Set-Cookie']
+ assert_not_equal [], headers["Set-Cookie"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal "foo: nil", response.body
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
assert_not_equal session_id, response.body
end
@@ -120,12 +122,12 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_getting_session_id
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
- session_id = cookies['_session_id']
+ assert cookies["_session_id"]
+ session_id = cookies["_session_id"]
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
assert_equal session_id, response.body, "should be able to read session id without accessing the session hash"
end
@@ -136,12 +138,12 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_deserializes_unloaded_class
with_test_route_set do
with_autoload_path "session_autoload_test" do
- get '/set_serialized_session_value'
+ get "/set_serialized_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
end
with_autoload_path "session_autoload_test" do
- get '/get_session_id'
+ get "/get_session_id"
assert_response :success
end
end
@@ -151,13 +153,13 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_doesnt_write_session_cookie_if_session_id_is_already_exists
with_test_route_set do
- get '/set_session_value'
+ get "/set_session_value"
assert_response :success
- assert cookies['_session_id']
+ assert cookies["_session_id"]
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal nil, headers['Set-Cookie'], "should not resend the cookie again if session_id cookie is already exists"
+ assert_nil headers["Set-Cookie"], "should not resend the cookie again if session_id cookie is already exists"
end
rescue Dalli::RingError => ex
skip ex.message, ex.backtrace
@@ -165,16 +167,16 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def test_prevents_session_fixation
with_test_route_set do
- get '/get_session_value'
+ get "/get_session_value"
assert_response :success
- assert_equal 'foo: nil', response.body
- session_id = cookies['_session_id']
+ assert_equal "foo: nil", response.body
+ session_id = cookies["_session_id"]
reset!
- get '/set_session_value', params: { _session_id: session_id }
+ get "/set_session_value", params: { _session_id: session_id }
assert_response :success
- assert_not_equal session_id, cookies['_session_id']
+ assert_not_equal session_id, cookies["_session_id"]
end
rescue Dalli::RingError => ex
skip ex.message, ex.backtrace
@@ -187,11 +189,13 @@ class MemCacheStoreTest < ActionDispatch::IntegrationTest
def with_test_route_set
with_routing do |set|
set.draw do
- get ':action', :to => ::MemCacheStoreTest::TestController
+ ActiveSupport::Deprecation.silence do
+ get ":action", to: ::MemCacheStoreTest::TestController
+ end
end
@app = self.class.build_app(set) do |middleware|
- middleware.use ActionDispatch::Session::MemCacheStore, :key => '_session_id', :namespace => "mem_cache_store_test:#{SecureRandom.hex(10)}"
+ middleware.use ActionDispatch::Session::MemCacheStore, key: "_session_id", namespace: "mem_cache_store_test:#{SecureRandom.hex(10)}"
middleware.delete ActionDispatch::ShowExceptions
end
diff --git a/actionpack/test/dispatch/session/test_session_test.rb b/actionpack/test/dispatch/session/test_session_test.rb
index 3e61d123e3..e90162a5fe 100644
--- a/actionpack/test/dispatch/session/test_session_test.rb
+++ b/actionpack/test/dispatch/session/test_session_test.rb
@@ -1,63 +1,65 @@
-require 'abstract_unit'
-require 'stringio'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "stringio"
class ActionController::TestSessionTest < ActiveSupport::TestCase
def test_initialize_with_values
- session = ActionController::TestSession.new(one: 'one', two: 'two')
- assert_equal('one', session[:one])
- assert_equal('two', session[:two])
+ session = ActionController::TestSession.new(one: "one", two: "two")
+ assert_equal("one", session[:one])
+ assert_equal("two", session[:two])
end
def test_setting_session_item_sets_item
session = ActionController::TestSession.new
- session[:key] = 'value'
- assert_equal('value', session[:key])
+ session[:key] = "value"
+ assert_equal("value", session[:key])
end
def test_calling_delete_removes_item_and_returns_its_value
session = ActionController::TestSession.new
- session[:key] = 'value'
- assert_equal('value', session[:key])
- assert_equal('value', session.delete(:key))
+ session[:key] = "value"
+ assert_equal("value", session[:key])
+ assert_equal("value", session.delete(:key))
assert_nil(session[:key])
end
def test_calling_update_with_params_passes_to_attributes
session = ActionController::TestSession.new
- session.update('key' => 'value')
- assert_equal('value', session[:key])
+ session.update("key" => "value")
+ assert_equal("value", session[:key])
end
def test_clear_empties_session
- session = ActionController::TestSession.new(one: 'one', two: 'two')
+ session = ActionController::TestSession.new(one: "one", two: "two")
session.clear
assert_nil(session[:one])
assert_nil(session[:two])
end
def test_keys_and_values
- session = ActionController::TestSession.new(one: '1', two: '2')
+ session = ActionController::TestSession.new(one: "1", two: "2")
assert_equal %w(one two), session.keys
assert_equal %w(1 2), session.values
end
def test_fetch_returns_default
- session = ActionController::TestSession.new(one: '1')
- assert_equal('2', session.fetch(:two, '2'))
+ session = ActionController::TestSession.new(one: "1")
+ assert_equal("2", session.fetch(:two, "2"))
end
def test_fetch_on_symbol_returns_value
- session = ActionController::TestSession.new(one: '1')
- assert_equal('1', session.fetch(:one))
+ session = ActionController::TestSession.new(one: "1")
+ assert_equal("1", session.fetch(:one))
end
def test_fetch_on_string_returns_value
- session = ActionController::TestSession.new(one: '1')
- assert_equal('1', session.fetch('one'))
+ session = ActionController::TestSession.new(one: "1")
+ assert_equal("1", session.fetch("one"))
end
def test_fetch_returns_block_value
- session = ActionController::TestSession.new(one: '1')
- assert_equal(2, session.fetch('2') { |key| key.to_i })
+ session = ActionController::TestSession.new(one: "1")
+ assert_equal(2, session.fetch("2") { |key| key.to_i })
end
end
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index ffdf775836..b69071b44b 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -1,28 +1,29 @@
-require 'abstract_unit'
+# frozen_string_literal: true
-class ShowExceptionsTest < ActionDispatch::IntegrationTest
+require "abstract_unit"
+class ShowExceptionsTest < ActionDispatch::IntegrationTest
class Boomer
def call(env)
req = ActionDispatch::Request.new(env)
case req.path
when "/not_found"
raise AbstractController::ActionNotFound
- when "/bad_params"
+ when "/bad_params", "/bad_params.json"
begin
raise StandardError.new
rescue
- raise ActionDispatch::ParamsParser::ParseError
+ raise ActionDispatch::Http::Parameters::ParseError
end
when "/method_not_allowed"
- raise ActionController::MethodNotAllowed, 'PUT'
+ raise ActionController::MethodNotAllowed, "PUT"
when "/unknown_http_method"
raise ActionController::UnknownHttpMethod
when "/not_found_original_exception"
begin
raise AbstractController::ActionNotFound.new
rescue
- raise ActionView::Template::Error.new('template')
+ raise ActionView::Template::Error.new("template")
end
else
raise "puke!"
@@ -35,30 +36,30 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
test "skip exceptions app if not showing exceptions" do
@app = ProductionApp
assert_raise RuntimeError do
- get "/", headers: { 'action_dispatch.show_exceptions' => false }
+ get "/", headers: { "action_dispatch.show_exceptions" => false }
end
end
test "rescue with error page" do
@app = ProductionApp
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
assert_response 500
assert_equal "500 error fixture\n", body
- get "/bad_params", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/bad_params", headers: { "action_dispatch.show_exceptions" => true }
assert_response 400
assert_equal "400 error fixture\n", body
- get "/not_found", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_equal "404 error fixture\n", body
- get "/method_not_allowed", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/method_not_allowed", headers: { "action_dispatch.show_exceptions" => true }
assert_response 405
assert_equal "", body
- get "/unknown_http_method", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/unknown_http_method", headers: { "action_dispatch.show_exceptions" => true }
assert_response 405
assert_equal "", body
end
@@ -69,11 +70,11 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
begin
@app = ProductionApp
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
assert_response 500
assert_equal "500 localized error fixture\n", body
- get "/not_found", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_equal "404 error fixture\n", body
ensure
@@ -84,14 +85,14 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
test "sets the HTTP charset parameter" do
@app = ProductionApp
- get "/", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/", headers: { "action_dispatch.show_exceptions" => true }
assert_equal "text/html; charset=utf-8", response.headers["Content-Type"]
end
test "show registered original exception for wrapped exceptions" do
@app = ProductionApp
- get "/not_found_original_exception", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found_original_exception", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_match(/404 error/, body)
end
@@ -105,7 +106,7 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
end
@app = ActionDispatch::ShowExceptions.new(Boomer.new, exceptions_app)
- get "/not_found_original_exception", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/not_found_original_exception", headers: { "action_dispatch.show_exceptions" => true }
assert_response 404
assert_equal "YOU FAILED", body
end
@@ -116,8 +117,22 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
end
@app = ActionDispatch::ShowExceptions.new(Boomer.new, exceptions_app)
- get "/method_not_allowed", headers: { 'action_dispatch.show_exceptions' => true }
+ get "/method_not_allowed", headers: { "action_dispatch.show_exceptions" => true }
assert_response 405
assert_equal "", body
end
+
+ test "bad params exception is returned in the correct format" do
+ @app = ProductionApp
+
+ get "/bad_params", headers: { "action_dispatch.show_exceptions" => true }
+ assert_equal "text/html; charset=utf-8", response.headers["Content-Type"]
+ assert_response 400
+ assert_match(/400 error/, body)
+
+ get "/bad_params.json", headers: { "action_dispatch.show_exceptions" => true }
+ assert_equal "application/json; charset=utf-8", response.headers["Content-Type"]
+ assert_response 400
+ assert_equal("{\"status\":400,\"error\":\"Bad Request\"}", body)
+ end
end
diff --git a/actionpack/test/dispatch/ssl_test.rb b/actionpack/test/dispatch/ssl_test.rb
index 7a5b8393dc..baf46e7c7e 100644
--- a/actionpack/test/dispatch/ssl_test.rb
+++ b/actionpack/test/dispatch/ssl_test.rb
@@ -1,142 +1,158 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class SSLTest < ActionDispatch::IntegrationTest
- HEADERS = Rack::Utils::HeaderHash.new 'Content-Type' => 'text/html'
+ HEADERS = Rack::Utils::HeaderHash.new "Content-Type" => "text/html"
attr_accessor :app
def build_app(headers: {}, ssl_options: {})
headers = HEADERS.merge(headers)
- ActionDispatch::SSL.new lambda { |env| [200, headers, []] }, ssl_options
+ ActionDispatch::SSL.new lambda { |env| [200, headers, []] }, ssl_options.reverse_merge(hsts: { subdomains: true })
end
end
class RedirectSSLTest < SSLTest
- def assert_not_redirected(url, headers: {})
- self.app = build_app
+ def assert_not_redirected(url, headers: {}, redirect: {})
+ self.app = build_app ssl_options: { redirect: redirect }
get url, headers: headers
assert_response :ok
end
- def assert_redirected(host: nil, port: nil, status: 301, body: [],
- deprecated_host: nil, deprecated_port: nil,
- from: 'http://a/b?c=d', to: from.sub('http', 'https'))
+ def assert_redirected(redirect: {}, from: "http://a/b?c=d", to: from.sub("http", "https"))
+ redirect = { status: 301, body: [] }.merge(redirect)
- self.app = build_app ssl_options: {
- redirect: { host: host, port: port, status: status, body: body },
- host: deprecated_host, port: deprecated_port
- }
+ self.app = build_app ssl_options: { redirect: redirect }
get from
- assert_response status
+ assert_response redirect[:status] || 301
assert_redirected_to to
- assert_equal body.join, @response.body
+ assert_equal redirect[:body].join, @response.body
+ end
+
+ def assert_post_redirected(redirect: {}, from: "http://a/b?c=d",
+ to: from.sub("http", "https"))
+
+ self.app = build_app ssl_options: { redirect: redirect }
+
+ post from
+ assert_response redirect[:status] || 307
+ assert_redirected_to to
+ end
+
+ test "exclude can avoid redirect" do
+ excluding = { exclude: -> request { request.path =~ /healthcheck/ } }
+
+ assert_not_redirected "http://example.org/healthcheck", redirect: excluding
+ assert_redirected from: "http://example.org/", redirect: excluding
end
- test 'https is not redirected' do
- assert_not_redirected 'https://example.org'
+ test "https is not redirected" do
+ assert_not_redirected "https://example.org"
end
- test 'proxied https is not redirected' do
- assert_not_redirected 'http://example.org', headers: { 'HTTP_X_FORWARDED_PROTO' => 'https' }
+ test "proxied https is not redirected" do
+ assert_not_redirected "http://example.org", headers: { "HTTP_X_FORWARDED_PROTO" => "https" }
end
- test 'http is redirected to https' do
+ test "http is redirected to https" do
assert_redirected
end
- test 'redirect with non-301 status' do
- assert_redirected status: 307
+ test "http POST is redirected to https with status 307" do
+ assert_post_redirected
end
- test 'redirect with custom body' do
- assert_redirected body: ['foo']
+ test "redirect with non-301 status" do
+ assert_redirected redirect: { status: 307 }
end
- test 'redirect to specific host' do
- assert_redirected host: 'ssl', to: 'https://ssl/b?c=d'
+ test "redirect with custom body" do
+ assert_redirected redirect: { body: ["foo"] }
end
- test 'redirect to default port' do
- assert_redirected port: 443
+ test "redirect to specific host" do
+ assert_redirected redirect: { host: "ssl" }, to: "https://ssl/b?c=d"
end
- test 'redirect to non-default port' do
- assert_redirected port: 8443, to: 'https://a:8443/b?c=d'
+ test "redirect to default port" do
+ assert_redirected redirect: { port: 443 }
end
- test 'redirect to different host and non-default port' do
- assert_redirected host: 'ssl', port: 8443, to: 'https://ssl:8443/b?c=d'
+ test "redirect to non-default port" do
+ assert_redirected redirect: { port: 8443 }, to: "https://a:8443/b?c=d"
end
- test 'redirect to different host including port' do
- assert_redirected host: 'ssl:443', to: 'https://ssl:443/b?c=d'
+ test "redirect to different host and non-default port" do
+ assert_redirected redirect: { host: "ssl", port: 8443 }, to: "https://ssl:8443/b?c=d"
end
- test ':host is deprecated, moved within redirect: { host: … }' do
- assert_deprecated do
- assert_redirected deprecated_host: 'foo', to: 'https://foo/b?c=d'
- end
+ test "redirect to different host including port" do
+ assert_redirected redirect: { host: "ssl:443" }, to: "https://ssl:443/b?c=d"
end
- test ':port is deprecated, moved within redirect: { port: … }' do
- assert_deprecated do
- assert_redirected deprecated_port: 1, to: 'https://a:1/b?c=d'
- end
+ test "no redirect with redirect set to false" do
+ assert_not_redirected "http://example.org", redirect: false
end
end
class StrictTransportSecurityTest < SSLTest
- EXPECTED = 'max-age=15552000'
+ EXPECTED = "max-age=31536000"
+ EXPECTED_WITH_SUBDOMAINS = "max-age=31536000; includeSubDomains"
- def assert_hsts(expected, url: 'https://example.org', hsts: {}, headers: {})
+ def assert_hsts(expected, url: "https://example.org", hsts: { subdomains: true }, headers: {})
self.app = build_app ssl_options: { hsts: hsts }, headers: headers
get url
- assert_equal expected, response.headers['Strict-Transport-Security']
+ if expected.nil?
+ assert_nil response.headers["Strict-Transport-Security"]
+ else
+ assert_equal expected, response.headers["Strict-Transport-Security"]
+ end
end
- test 'enabled by default' do
- assert_hsts EXPECTED
+ test "enabled by default" do
+ assert_hsts EXPECTED_WITH_SUBDOMAINS
end
- test 'not sent with http:// responses' do
- assert_hsts nil, url: 'http://example.org'
+ test "not sent with http:// responses" do
+ assert_hsts nil, url: "http://example.org"
end
- test 'defers to app-provided header' do
- assert_hsts 'app-provided', headers: { 'Strict-Transport-Security' => 'app-provided' }
+ test "defers to app-provided header" do
+ assert_hsts "app-provided", headers: { "Strict-Transport-Security" => "app-provided" }
end
- test 'hsts: true enables default settings' do
- assert_hsts EXPECTED, hsts: true
+ test "hsts: true enables default settings" do
+ assert_hsts EXPECTED_WITH_SUBDOMAINS, hsts: true
end
- test 'hsts: false sets max-age to zero, clearing browser HSTS settings' do
- assert_hsts 'max-age=0', hsts: false
+ test "hsts: false sets max-age to zero, clearing browser HSTS settings" do
+ assert_hsts "max-age=0; includeSubDomains", hsts: false
end
- test ':expires sets max-age' do
- assert_hsts 'max-age=500', hsts: { expires: 500 }
+ test ":expires sets max-age" do
+ assert_hsts "max-age=500; includeSubDomains", hsts: { expires: 500 }
end
- test ':expires supports AS::Duration arguments' do
- assert_hsts 'max-age=31557600', hsts: { expires: 1.year }
+ test ":expires supports AS::Duration arguments" do
+ assert_hsts "max-age=31556952; includeSubDomains", hsts: { expires: 1.year }
end
- test 'include subdomains' do
+ test "include subdomains" do
assert_hsts "#{EXPECTED}; includeSubDomains", hsts: { subdomains: true }
end
- test 'exclude subdomains' do
+ test "exclude subdomains" do
assert_hsts EXPECTED, hsts: { subdomains: false }
end
- test 'opt in to browser preload lists' do
- assert_hsts "#{EXPECTED}; preload", hsts: { preload: true }
+ test "opt in to browser preload lists" do
+ assert_hsts "#{EXPECTED_WITH_SUBDOMAINS}; preload", hsts: { preload: true }
end
- test 'opt out of browser preload lists' do
- assert_hsts EXPECTED, hsts: { preload: false }
+ test "opt out of browser preload lists" do
+ assert_hsts EXPECTED_WITH_SUBDOMAINS, hsts: { preload: false }
end
end
@@ -145,55 +161,68 @@ class SecureCookiesTest < SSLTest
def get(**options)
self.app = build_app(**options)
- super 'https://example.org'
+ super "https://example.org"
end
def assert_cookies(*expected)
- assert_equal expected, response.headers['Set-Cookie'].split("\n")
+ assert_equal expected, response.headers["Set-Cookie"].split("\n")
end
def test_flag_cookies_as_secure
- get headers: { 'Set-Cookie' => DEFAULT }
- assert_cookies 'id=1; path=/; secure', 'token=abc; path=/; secure; HttpOnly'
+ get headers: { "Set-Cookie" => DEFAULT }
+ assert_cookies "id=1; path=/; secure", "token=abc; path=/; secure; HttpOnly"
end
def test_flag_cookies_as_secure_at_end_of_line
- get headers: { 'Set-Cookie' => 'problem=def; path=/; HttpOnly; secure' }
- assert_cookies 'problem=def; path=/; HttpOnly; secure'
+ get headers: { "Set-Cookie" => "problem=def; path=/; HttpOnly; secure" }
+ assert_cookies "problem=def; path=/; HttpOnly; secure"
end
def test_flag_cookies_as_secure_with_more_spaces_before
- get headers: { 'Set-Cookie' => 'problem=def; path=/; HttpOnly; secure' }
- assert_cookies 'problem=def; path=/; HttpOnly; secure'
+ get headers: { "Set-Cookie" => "problem=def; path=/; HttpOnly; secure" }
+ assert_cookies "problem=def; path=/; HttpOnly; secure"
end
def test_flag_cookies_as_secure_with_more_spaces_after
- get headers: { 'Set-Cookie' => 'problem=def; path=/; secure; HttpOnly' }
- assert_cookies 'problem=def; path=/; secure; HttpOnly'
+ get headers: { "Set-Cookie" => "problem=def; path=/; secure; HttpOnly" }
+ assert_cookies "problem=def; path=/; secure; HttpOnly"
end
def test_flag_cookies_as_secure_with_has_not_spaces_before
- get headers: { 'Set-Cookie' => 'problem=def; path=/;secure; HttpOnly' }
- assert_cookies 'problem=def; path=/;secure; HttpOnly'
+ get headers: { "Set-Cookie" => "problem=def; path=/;secure; HttpOnly" }
+ assert_cookies "problem=def; path=/;secure; HttpOnly"
end
def test_flag_cookies_as_secure_with_has_not_spaces_after
- get headers: { 'Set-Cookie' => 'problem=def; path=/; secure;HttpOnly' }
- assert_cookies 'problem=def; path=/; secure;HttpOnly'
+ get headers: { "Set-Cookie" => "problem=def; path=/; secure;HttpOnly" }
+ assert_cookies "problem=def; path=/; secure;HttpOnly"
end
def test_flag_cookies_as_secure_with_ignore_case
- get headers: { 'Set-Cookie' => 'problem=def; path=/; Secure; HttpOnly' }
- assert_cookies 'problem=def; path=/; Secure; HttpOnly'
+ get headers: { "Set-Cookie" => "problem=def; path=/; Secure; HttpOnly" }
+ assert_cookies "problem=def; path=/; Secure; HttpOnly"
+ end
+
+ def test_cookies_as_not_secure_with_secure_cookies_disabled
+ get headers: { "Set-Cookie" => DEFAULT }, ssl_options: { secure_cookies: false }
+ assert_cookies(*DEFAULT.split("\n"))
+ end
+
+ def test_cookies_as_not_secure_with_exclude
+ excluding = { exclude: -> request { request.domain =~ /example/ } }
+ get headers: { "Set-Cookie" => DEFAULT }, ssl_options: { redirect: excluding }
+
+ assert_cookies(*DEFAULT.split("\n"))
+ assert_response :ok
end
def test_no_cookies
get
- assert_nil response.headers['Set-Cookie']
+ assert_nil response.headers["Set-Cookie"]
end
def test_keeps_original_headers_behavior
- get headers: { 'Connection' => %w[close] }
- assert_equal 'close', response.headers['Connection']
+ get headers: { "Connection" => %w[close] }
+ assert_equal "close", response.headers["Connection"]
end
end
diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb
index 1da57ab50b..d44aa00122 100644
--- a/actionpack/test/dispatch/static_test.rb
+++ b/actionpack/test/dispatch/static_test.rb
@@ -1,9 +1,11 @@
-require 'abstract_unit'
-require 'zlib'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "zlib"
module StaticTests
DummyApp = lambda { |env|
- [200, {"Content-Type" => "text/plain"}, ["Hello, World!"]]
+ [200, { "Content-Type" => "text/plain" }, ["Hello, World!"]]
}
def setup
@@ -29,7 +31,7 @@ module StaticTests
end
def test_handles_urls_with_ascii_8bit
- assert_equal "Hello, World!", get("/doorkeeper%E3E4".force_encoding('ASCII-8BIT')).body
+ assert_equal "Hello, World!", get((+"/doorkeeper%E3E4").force_encoding("ASCII-8BIT")).body
end
def test_handles_urls_with_ascii_8bit_on_win_31j
@@ -37,17 +39,11 @@ module StaticTests
Encoding.default_internal = "Windows-31J"
Encoding.default_external = "Windows-31J"
end
- assert_equal "Hello, World!", get("/doorkeeper%E3E4".force_encoding('ASCII-8BIT')).body
+ assert_equal "Hello, World!", get((+"/doorkeeper%E3E4").force_encoding("ASCII-8BIT")).body
end
- def test_sets_cache_control
- app = assert_deprecated do
- ActionDispatch::Static.new(DummyApp, @root, "public, max-age=60")
- end
- response = Rack::MockRequest.new(app).request("GET", "/index.html")
-
- assert_html "/index.html", response
- assert_equal "public, max-age=60", response.headers["Cache-Control"]
+ def test_handles_urls_with_null_byte
+ assert_equal "Hello, World!", get("/doorkeeper%00").body
end
def test_serves_static_index_at_root
@@ -75,9 +71,17 @@ module StaticTests
end
def test_served_static_file_with_non_english_filename
- assert_html "means hello in Japanese\n", get("/foo/#{Rack::Utils.escape("こんにちは.html")}")
+ assert_html "means hello in Japanese\n", get("/foo/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.html")
end
+ def test_served_gzipped_static_file_with_non_english_filename
+ response = get("/foo/%E3%81%95%E3%82%88%E3%81%86%E3%81%AA%E3%82%89.html", "HTTP_ACCEPT_ENCODING" => "gzip")
+
+ assert_gzip "/foo/さようなら.html", response
+ assert_equal "text/html", response.headers["Content-Type"]
+ assert_equal "Accept-Encoding", response.headers["Vary"]
+ assert_equal "gzip", response.headers["Content-Encoding"]
+ end
def test_serves_static_file_with_exclamation_mark_in_filename
with_static_file "/foo/foo!bar.html" do |file|
@@ -144,65 +148,74 @@ module StaticTests
def test_serves_gzip_files_when_header_set
file_name = "/gzip/application-a71b3024f80aea3181c09774ca17e712.js"
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => 'gzip')
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "gzip")
assert_gzip file_name, response
- assert_equal 'application/javascript', response.headers['Content-Type']
- assert_equal 'Accept-Encoding', response.headers["Vary"]
- assert_equal 'gzip', response.headers["Content-Encoding"]
+ assert_equal "application/javascript", response.headers["Content-Type"]
+ assert_equal "Accept-Encoding", response.headers["Vary"]
+ assert_equal "gzip", response.headers["Content-Encoding"]
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => 'Gzip')
- assert_gzip file_name, response
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "Gzip")
+ assert_gzip file_name, response
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => 'GZIP')
- assert_gzip file_name, response
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "GZIP")
+ assert_gzip file_name, response
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => '')
- assert_not_equal 'gzip', response.headers["Content-Encoding"]
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "compress;q=0.5, gzip;q=1.0")
+ assert_gzip file_name, response
+
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "")
+ assert_not_equal "gzip", response.headers["Content-Encoding"]
end
def test_does_not_modify_path_info
file_name = "/gzip/application-a71b3024f80aea3181c09774ca17e712.js"
- env = {'PATH_INFO' => file_name, 'HTTP_ACCEPT_ENCODING' => 'gzip', "REQUEST_METHOD" => 'POST'}
+ env = { "PATH_INFO" => file_name, "HTTP_ACCEPT_ENCODING" => "gzip", "REQUEST_METHOD" => "POST" }
@app.call(env)
- assert_equal file_name, env['PATH_INFO']
+ assert_equal file_name, env["PATH_INFO"]
end
- def test_serves_gzip_with_propper_content_type_fallback
+ def test_serves_gzip_with_proper_content_type_fallback
file_name = "/gzip/foo.zoo"
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => 'gzip')
- assert_gzip file_name, response
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "gzip")
+ assert_gzip file_name, response
default_response = get(file_name) # no gzip
- assert_equal default_response.headers['Content-Type'], response.headers['Content-Type']
+ assert_equal default_response.headers["Content-Type"], response.headers["Content-Type"]
end
def test_serves_gzip_files_with_not_modified
file_name = "/gzip/application-a71b3024f80aea3181c09774ca17e712.js"
last_modified = File.mtime(File.join(@root, "#{file_name}.gz"))
- response = get(file_name, 'HTTP_ACCEPT_ENCODING' => 'gzip', 'HTTP_IF_MODIFIED_SINCE' => last_modified.httpdate)
+ response = get(file_name, "HTTP_ACCEPT_ENCODING" => "gzip", "HTTP_IF_MODIFIED_SINCE" => last_modified.httpdate)
assert_equal 304, response.status
- assert_equal nil, response.headers['Content-Type']
- assert_equal nil, response.headers['Content-Encoding']
- assert_equal nil, response.headers['Vary']
+ assert_nil response.headers["Content-Type"]
+ assert_nil response.headers["Content-Encoding"]
+ assert_nil response.headers["Vary"]
end
def test_serves_files_with_headers
headers = {
- "Access-Control-Allow-Origin" => 'http://rubyonrails.org',
- "Cache-Control" => 'public, max-age=60',
+ "Access-Control-Allow-Origin" => "http://rubyonrails.org",
+ "Cache-Control" => "public, max-age=60",
"X-Custom-Header" => "I'm a teapot"
}
app = ActionDispatch::Static.new(DummyApp, @root, headers: headers)
response = Rack::MockRequest.new(app).request("GET", "/foo/bar.html")
- assert_equal 'http://rubyonrails.org', response.headers["Access-Control-Allow-Origin"]
- assert_equal 'public, max-age=60', response.headers["Cache-Control"]
+ assert_equal "http://rubyonrails.org", response.headers["Access-Control-Allow-Origin"]
+ assert_equal "public, max-age=60", response.headers["Cache-Control"]
assert_equal "I'm a teapot", response.headers["X-Custom-Header"]
end
+ def test_ignores_unknown_http_methods
+ app = ActionDispatch::Static.new(DummyApp, @root)
+
+ assert_nothing_raised { Rack::MockRequest.new(app).request("BAD_METHOD", "/foo/bar.html") }
+ end
+
# Windows doesn't allow \ / : * ? " < > | in filenames
- unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
+ unless Gem.win_platform?
def test_serves_static_file_with_colon
with_static_file "/foo/foo:bar.html" do |file|
assert_html file, get("/foo/foo%3Abar.html")
@@ -222,7 +235,7 @@ module StaticTests
def assert_gzip(file_name, response)
expected = File.read("#{FIXTURE_LOAD_PATH}/#{public_path}" + file_name)
- actual = Zlib::GzipReader.new(StringIO.new(response.body)).read
+ actual = ActiveSupport::Gzip.decompress(response.body)
assert_equal expected, actual
end
@@ -254,7 +267,7 @@ class StaticTest < ActiveSupport::TestCase
def setup
super
@root = "#{FIXTURE_LOAD_PATH}/public"
- @app = ActionDispatch::Static.new(DummyApp, @root, headers: {'Cache-Control' => "public, max-age=60"})
+ @app = ActionDispatch::Static.new(DummyApp, @root, headers: { "Cache-Control" => "public, max-age=60" })
end
def public_path
@@ -264,17 +277,17 @@ class StaticTest < ActiveSupport::TestCase
include StaticTests
def test_custom_handler_called_when_file_is_outside_root
- filename = 'shared.html.erb'
- assert File.exist?(File.join(@root, '..', filename))
+ filename = "shared.html.erb"
+ assert File.exist?(File.join(@root, "..", filename))
env = {
- "REQUEST_METHOD"=>"GET",
- "REQUEST_PATH"=>"/..%2F#{filename}",
- "PATH_INFO"=>"/..%2F#{filename}",
- "REQUEST_URI"=>"/..%2F#{filename}",
- "HTTP_VERSION"=>"HTTP/1.1",
- "SERVER_NAME"=>"localhost",
- "SERVER_PORT"=>"8080",
- "QUERY_STRING"=>""
+ "REQUEST_METHOD" => "GET",
+ "REQUEST_PATH" => "/..%2F#{filename}",
+ "PATH_INFO" => "/..%2F#{filename}",
+ "REQUEST_URI" => "/..%2F#{filename}",
+ "HTTP_VERSION" => "HTTP/1.1",
+ "SERVER_NAME" => "localhost",
+ "SERVER_PORT" => "8080",
+ "QUERY_STRING" => ""
}
assert_equal(DummyApp.call(nil), @app.call(env))
end
@@ -290,14 +303,13 @@ class StaticTest < ActiveSupport::TestCase
assert_html "/foo/other-index.html", get("/foo/")
assert_html "/foo/other-index.html", get("/foo")
end
-
end
class StaticEncodingTest < StaticTest
def setup
super
@root = "#{FIXTURE_LOAD_PATH}/公共"
- @app = ActionDispatch::Static.new(DummyApp, @root, headers: {'Cache-Control' => "public, max-age=60"})
+ @app = ActionDispatch::Static.new(DummyApp, @root, headers: { "Cache-Control" => "public, max-age=60" })
end
def public_path
diff --git a/actionpack/test/dispatch/system_testing/driver_test.rb b/actionpack/test/dispatch/system_testing/driver_test.rb
new file mode 100644
index 0000000000..a824ee0c84
--- /dev/null
+++ b/actionpack/test/dispatch/system_testing/driver_test.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/system_testing/driver"
+
+class DriverTest < ActiveSupport::TestCase
+ test "initializing the driver" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:selenium)
+ assert_equal :selenium, driver.instance_variable_get(:@name)
+ end
+
+ test "initializing the driver with a browser" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:selenium, using: :chrome, screen_size: [1400, 1400], options: { url: "http://example.com/wd/hub" })
+ assert_equal :selenium, driver.instance_variable_get(:@name)
+ assert_equal :chrome, driver.instance_variable_get(:@browser).name
+ assert_nil driver.instance_variable_get(:@browser).options
+ assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
+ assert_equal ({ url: "http://example.com/wd/hub" }), driver.instance_variable_get(:@options)
+ end
+
+ test "initializing the driver with a headless chrome" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:selenium, using: :headless_chrome, screen_size: [1400, 1400], options: { url: "http://example.com/wd/hub" })
+ assert_equal :selenium, driver.instance_variable_get(:@name)
+ assert_equal :headless_chrome, driver.instance_variable_get(:@browser).name
+ assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
+ assert_equal ({ url: "http://example.com/wd/hub" }), driver.instance_variable_get(:@options)
+ end
+
+ test "initializing the driver with a headless firefox" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:selenium, using: :headless_firefox, screen_size: [1400, 1400], options: { url: "http://example.com/wd/hub" })
+ assert_equal :selenium, driver.instance_variable_get(:@name)
+ assert_equal :headless_firefox, driver.instance_variable_get(:@browser).name
+ assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
+ assert_equal ({ url: "http://example.com/wd/hub" }), driver.instance_variable_get(:@options)
+ end
+
+ test "initializing the driver with a poltergeist" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:poltergeist, screen_size: [1400, 1400], options: { js_errors: false })
+ assert_equal :poltergeist, driver.instance_variable_get(:@name)
+ assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
+ assert_equal ({ js_errors: false }), driver.instance_variable_get(:@options)
+ end
+
+ test "initializing the driver with a webkit" do
+ driver = ActionDispatch::SystemTesting::Driver.new(:webkit, screen_size: [1400, 1400], options: { skip_image_loading: true })
+ assert_equal :webkit, driver.instance_variable_get(:@name)
+ assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
+ assert_equal ({ skip_image_loading: true }), driver.instance_variable_get(:@options)
+ end
+
+ test "registerable? returns false if driver is rack_test" do
+ assert_not ActionDispatch::SystemTesting::Driver.new(:rack_test).send(:registerable?)
+ end
+end
diff --git a/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb b/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb
new file mode 100644
index 0000000000..de79c05657
--- /dev/null
+++ b/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "action_dispatch/system_testing/test_helpers/screenshot_helper"
+require "capybara/dsl"
+
+class ScreenshotHelperTest < ActiveSupport::TestCase
+ test "image path is saved in tmp directory" do
+ new_test = DrivenBySeleniumWithChrome.new("x")
+
+ Rails.stub :root, Pathname.getwd do
+ assert_equal Rails.root.join("tmp/screenshots/x.png").to_s, new_test.send(:image_path)
+ end
+ end
+
+ test "image path includes failures text if test did not pass" do
+ new_test = DrivenBySeleniumWithChrome.new("x")
+
+ Rails.stub :root, Pathname.getwd do
+ new_test.stub :passed?, false do
+ assert_equal Rails.root.join("tmp/screenshots/failures_x.png").to_s, new_test.send(:image_path)
+ end
+ end
+ end
+
+ test "image path does not include failures text if test skipped" do
+ new_test = DrivenBySeleniumWithChrome.new("x")
+
+ Rails.stub :root, Pathname.getwd do
+ new_test.stub :passed?, false do
+ new_test.stub :skipped?, true do
+ assert_equal Rails.root.join("tmp/screenshots/x.png").to_s, new_test.send(:image_path)
+ end
+ end
+ end
+ end
+
+ test "defaults to simple output for the screenshot" do
+ new_test = DrivenBySeleniumWithChrome.new("x")
+ assert_equal "simple", new_test.send(:output_type)
+ end
+
+ test "display_image return artifact format when specify RAILS_SYSTEM_TESTING_SCREENSHOT environment" do
+ begin
+ original_output_type = ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"]
+ ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] = "artifact"
+
+ new_test = DrivenBySeleniumWithChrome.new("x")
+
+ assert_equal "artifact", new_test.send(:output_type)
+
+ Rails.stub :root, Pathname.getwd do
+ new_test.stub :passed?, false do
+ assert_match %r|url=artifact://.+?tmp/screenshots/failures_x\.png|, new_test.send(:display_image)
+ end
+ end
+ ensure
+ ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] = original_output_type
+ end
+ end
+
+ test "image path returns the absolute path from root" do
+ new_test = DrivenBySeleniumWithChrome.new("x")
+
+ Rails.stub :root, Pathname.getwd.join("..") do
+ assert_equal Rails.root.join("tmp/screenshots/x.png").to_s, new_test.send(:image_path)
+ end
+ end
+end
+
+class RackTestScreenshotsTest < DrivenByRackTest
+ test "rack_test driver does not support screenshot" do
+ assert_not self.send(:supports_screenshot?)
+ end
+end
+
+class SeleniumScreenshotsTest < DrivenBySeleniumWithChrome
+ test "selenium driver supports screenshot" do
+ assert self.send(:supports_screenshot?)
+ end
+end
diff --git a/actionpack/test/dispatch/system_testing/server_test.rb b/actionpack/test/dispatch/system_testing/server_test.rb
new file mode 100644
index 0000000000..740e90a4da
--- /dev/null
+++ b/actionpack/test/dispatch/system_testing/server_test.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "capybara/dsl"
+require "action_dispatch/system_testing/server"
+
+class ServerTest < ActiveSupport::TestCase
+ setup do
+ @old_capybara_server = Capybara.server
+ end
+
+ test "port is always included" do
+ ActionDispatch::SystemTesting::Server.new.run
+ assert Capybara.always_include_port, "expected Capybara.always_include_port to be true"
+ end
+
+ test "server is changed from `default` to `puma`" do
+ Capybara.server = :default
+ ActionDispatch::SystemTesting::Server.new.run
+ assert_not_equal Capybara.server, Capybara.servers[:default]
+ end
+
+ test "server is not changed to `puma` when is different than default" do
+ Capybara.server = :webrick
+ ActionDispatch::SystemTesting::Server.new.run
+ assert_equal Capybara.server, Capybara.servers[:webrick]
+ end
+
+ teardown do
+ Capybara.server = @old_capybara_server
+ end
+end
diff --git a/actionpack/test/dispatch/system_testing/system_test_case_test.rb b/actionpack/test/dispatch/system_testing/system_test_case_test.rb
new file mode 100644
index 0000000000..b078a5abc5
--- /dev/null
+++ b/actionpack/test/dispatch/system_testing/system_test_case_test.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class SetDriverToRackTestTest < DrivenByRackTest
+ test "uses rack_test" do
+ assert_equal :rack_test, Capybara.current_driver
+ end
+end
+
+class OverrideSeleniumSubclassToRackTestTest < DrivenBySeleniumWithChrome
+ driven_by :rack_test
+
+ test "uses rack_test" do
+ assert_equal :rack_test, Capybara.current_driver
+ end
+end
+
+class SetDriverToSeleniumTest < DrivenBySeleniumWithChrome
+ test "uses selenium" do
+ assert_equal :selenium, Capybara.current_driver
+ end
+end
+
+class SetDriverToSeleniumHeadlessChromeTest < DrivenBySeleniumWithHeadlessChrome
+ test "uses selenium headless chrome" do
+ assert_equal :selenium, Capybara.current_driver
+ end
+end
+
+class SetDriverToSeleniumHeadlessFirefoxTest < DrivenBySeleniumWithHeadlessFirefox
+ test "uses selenium headless firefox" do
+ assert_equal :selenium, Capybara.current_driver
+ end
+end
+
+class SetHostTest < DrivenByRackTest
+ test "sets default host" do
+ assert_equal "http://127.0.0.1", Capybara.app_host
+ end
+
+ test "overrides host" do
+ host! "http://example.com"
+
+ assert_equal "http://example.com", Capybara.app_host
+ end
+end
+
+class UndefMethodsTest < DrivenBySeleniumWithChrome
+ test "get" do
+ exception = assert_raise NoMethodError do
+ get "http://example.com"
+ end
+ assert_equal "System tests cannot make direct requests via #get; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information.", exception.message
+ end
+
+ test "post" do
+ exception = assert_raise NoMethodError do
+ post "http://example.com"
+ end
+ assert_equal "System tests cannot make direct requests via #post; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information.", exception.message
+ end
+
+ test "put" do
+ exception = assert_raise NoMethodError do
+ put "http://example.com"
+ end
+ assert_equal "System tests cannot make direct requests via #put; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information.", exception.message
+ end
+
+ test "patch" do
+ exception = assert_raise NoMethodError do
+ patch "http://example.com"
+ end
+ assert_equal "System tests cannot make direct requests via #patch; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information.", exception.message
+ end
+
+ test "delete" do
+ exception = assert_raise NoMethodError do
+ delete "http://example.com"
+ end
+ assert_equal "System tests cannot make direct requests via #delete; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information.", exception.message
+ end
+end
diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb
index 51c469a61a..e56537d80b 100644
--- a/actionpack/test/dispatch/test_request_test.rb
+++ b/actionpack/test/dispatch/test_request_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class TestRequestTest < ActiveSupport::TestCase
test "sane defaults" do
@@ -30,27 +32,27 @@ class TestRequestTest < ActiveSupport::TestCase
req = ActionDispatch::TestRequest.create({})
assert_equal({}, req.cookies)
- assert_equal nil, req.env["HTTP_COOKIE"]
+ assert_nil req.env["HTTP_COOKIE"]
req.cookie_jar["user_name"] = "david"
- assert_cookies({"user_name" => "david"}, req.cookie_jar)
+ assert_cookies({ "user_name" => "david" }, req.cookie_jar)
req.cookie_jar["login"] = "XJ-122"
- assert_cookies({"user_name" => "david", "login" => "XJ-122"}, req.cookie_jar)
+ assert_cookies({ "user_name" => "david", "login" => "XJ-122" }, req.cookie_jar)
assert_nothing_raised do
req.cookie_jar["login"] = nil
- assert_cookies({"user_name" => "david", "login" => nil}, req.cookie_jar)
+ assert_cookies({ "user_name" => "david", "login" => nil }, req.cookie_jar)
end
req.cookie_jar.delete(:login)
- assert_cookies({"user_name" => "david"}, req.cookie_jar)
+ assert_cookies({ "user_name" => "david" }, req.cookie_jar)
req.cookie_jar.clear
assert_cookies({}, req.cookie_jar)
- req.cookie_jar.update(:user_name => "david")
- assert_cookies({"user_name" => "david"}, req.cookie_jar)
+ req.cookie_jar.update(user_name: "david")
+ assert_cookies({ "user_name" => "david" }, req.cookie_jar)
end
test "does not complain when there is no application config" do
@@ -60,32 +62,66 @@ class TestRequestTest < ActiveSupport::TestCase
test "default remote address is 0.0.0.0" do
req = ActionDispatch::TestRequest.create({})
- assert_equal '0.0.0.0', req.remote_addr
+ assert_equal "0.0.0.0", req.remote_addr
end
test "allows remote address to be overridden" do
- req = ActionDispatch::TestRequest.create('REMOTE_ADDR' => '127.0.0.1')
- assert_equal '127.0.0.1', req.remote_addr
+ req = ActionDispatch::TestRequest.create("REMOTE_ADDR" => "127.0.0.1")
+ assert_equal "127.0.0.1", req.remote_addr
end
test "default host is test.host" do
req = ActionDispatch::TestRequest.create({})
- assert_equal 'test.host', req.host
+ assert_equal "test.host", req.host
end
test "allows host to be overridden" do
- req = ActionDispatch::TestRequest.create('HTTP_HOST' => 'www.example.com')
- assert_equal 'www.example.com', req.host
+ req = ActionDispatch::TestRequest.create("HTTP_HOST" => "www.example.com")
+ assert_equal "www.example.com", req.host
end
test "default user agent is 'Rails Testing'" do
req = ActionDispatch::TestRequest.create({})
- assert_equal 'Rails Testing', req.user_agent
+ assert_equal "Rails Testing", req.user_agent
end
test "allows user agent to be overridden" do
- req = ActionDispatch::TestRequest.create('HTTP_USER_AGENT' => 'GoogleBot')
- assert_equal 'GoogleBot', req.user_agent
+ req = ActionDispatch::TestRequest.create("HTTP_USER_AGENT" => "GoogleBot")
+ assert_equal "GoogleBot", req.user_agent
+ end
+
+ test "request_method getter and setter" do
+ req = ActionDispatch::TestRequest.create
+ req.request_method # to reproduce bug caused by memoization
+ req.request_method = "POST"
+ assert_equal "POST", req.request_method
+ end
+
+ test "setter methods" do
+ req = ActionDispatch::TestRequest.create({})
+ get = "GET"
+
+ [
+ "request_method=", "host=", "request_uri=", "path=", "if_modified_since=", "if_none_match=",
+ "remote_addr=", "user_agent=", "accept="
+ ].each do |method|
+ req.send(method, get)
+ end
+
+ req.port = 8080
+ req.accept = "hello goodbye"
+
+ assert_equal(get, req.get_header("REQUEST_METHOD"))
+ assert_equal(get, req.get_header("HTTP_HOST"))
+ assert_equal(8080, req.get_header("SERVER_PORT"))
+ assert_equal(get, req.get_header("REQUEST_URI"))
+ assert_equal(get, req.get_header("PATH_INFO"))
+ assert_equal(get, req.get_header("HTTP_IF_MODIFIED_SINCE"))
+ assert_equal(get, req.get_header("HTTP_IF_NONE_MATCH"))
+ assert_equal(get, req.get_header("REMOTE_ADDR"))
+ assert_equal(get, req.get_header("HTTP_USER_AGENT"))
+ assert_nil(req.get_header("action_dispatch.request.accepts"))
+ assert_equal("hello goodbye", req.get_header("HTTP_ACCEPT"))
end
private
diff --git a/actionpack/test/dispatch/test_response_test.rb b/actionpack/test/dispatch/test_response_test.rb
index a4f9d56a6a..f0b8f7785d 100644
--- a/actionpack/test/dispatch/test_response_test.rb
+++ b/actionpack/test/dispatch/test_response_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
class TestResponseTest < ActiveSupport::TestCase
def assert_response_code_range(range, predicate)
@@ -17,4 +19,19 @@ class TestResponseTest < ActiveSupport::TestCase
assert_response_code_range 500..599, :server_error?
assert_response_code_range 400..499, :client_error?
end
+
+ test "response parsing" do
+ response = ActionDispatch::TestResponse.create(200, {}, "")
+ assert_equal response.body, response.parsed_body
+
+ response = ActionDispatch::TestResponse.create(200, { "Content-Type" => "application/json" }, '{ "foo": "fighters" }')
+ assert_equal({ "foo" => "fighters" }, response.parsed_body)
+ end
+
+ test "response status aliases deprecated" do
+ response = ActionDispatch::TestResponse.create
+ assert_deprecated { response.success? }
+ assert_deprecated { response.missing? }
+ assert_deprecated { response.error? }
+ end
end
diff --git a/actionpack/test/dispatch/uploaded_file_test.rb b/actionpack/test/dispatch/uploaded_file_test.rb
index 55ebbd5143..21169fcb5c 100644
--- a/actionpack/test/dispatch/uploaded_file_test.rb
+++ b/actionpack/test/dispatch/uploaded_file_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
class UploadedFileTest < ActiveSupport::TestCase
@@ -9,81 +11,87 @@ module ActionDispatch
end
def test_original_filename
- uf = Http::UploadedFile.new(:filename => 'foo', :tempfile => Object.new)
- assert_equal 'foo', uf.original_filename
+ uf = Http::UploadedFile.new(filename: "foo", tempfile: Object.new)
+ assert_equal "foo", uf.original_filename
+ end
+
+ def test_filename_is_different_object
+ file_str = "foo"
+ uf = Http::UploadedFile.new(filename: file_str, tempfile: Object.new)
+ assert_not_equal file_str.object_id, uf.original_filename.object_id
end
def test_filename_should_be_in_utf_8
- uf = Http::UploadedFile.new(:filename => 'foo', :tempfile => Object.new)
+ uf = Http::UploadedFile.new(filename: "foo", tempfile: Object.new)
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)
+ 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
+ uf = Http::UploadedFile.new(type: "foo", tempfile: Object.new)
+ assert_equal "foo", uf.content_type
end
def test_headers
- uf = Http::UploadedFile.new(:head => 'foo', :tempfile => Object.new)
- assert_equal 'foo', uf.headers
+ uf = Http::UploadedFile.new(head: "foo", tempfile: Object.new)
+ assert_equal "foo", uf.headers
end
def test_tempfile
- uf = Http::UploadedFile.new(:tempfile => 'foo')
- assert_equal 'foo', uf.tempfile
+ uf = Http::UploadedFile.new(tempfile: "foo")
+ assert_equal "foo", uf.tempfile
end
def test_to_io_returns_the_tempfile
tf = Object.new
- uf = Http::UploadedFile.new(:tempfile => tf)
+ uf = Http::UploadedFile.new(tempfile: tf)
assert_equal tf, uf.to_io
end
def test_delegates_path_to_tempfile
- tf = Class.new { def path; 'thunderhorse' end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert_equal 'thunderhorse', uf.path
+ tf = Class.new { def path; "thunderhorse" end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "thunderhorse", uf.path
end
def test_delegates_open_to_tempfile
- tf = Class.new { def open; 'thunderhorse' end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert_equal 'thunderhorse', uf.open
+ tf = Class.new { def open; "thunderhorse" end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "thunderhorse", uf.open
end
def test_delegates_close_to_tempfile
- tf = Class.new { def close(unlink_now=false); 'thunderhorse' end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert_equal 'thunderhorse', uf.close
+ tf = Class.new { def close(unlink_now = false); "thunderhorse" end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "thunderhorse", uf.close
end
def test_close_accepts_parameter
- tf = Class.new { def close(unlink_now=false); "thunderhorse: #{unlink_now}" end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert_equal 'thunderhorse: true', uf.close(true)
+ tf = Class.new { def close(unlink_now = false); "thunderhorse: #{unlink_now}" end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "thunderhorse: true", uf.close(true)
end
def test_delegates_read_to_tempfile
- tf = Class.new { def read(length=nil, buffer=nil); 'thunderhorse' end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert_equal 'thunderhorse', uf.read
+ tf = Class.new { def read(length = nil, buffer = nil); "thunderhorse" end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "thunderhorse", uf.read
end
def test_delegates_read_to_tempfile_with_params
- tf = Class.new { def read(length=nil, buffer=nil); [length, buffer] end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
+ tf = Class.new { def read(length = nil, buffer = nil); [length, buffer] end }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
assert_equal %w{ thunder horse }, uf.read(*%w{ thunder horse })
end
def test_delegate_respects_respond_to?
tf = Class.new { def read; yield end; private :read }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
+ uf = Http::UploadedFile.new(tempfile: tf.new)
assert_raises(NoMethodError) do
uf.read
end
@@ -91,15 +99,21 @@ module ActionDispatch
def test_delegate_eof_to_tempfile
tf = Class.new { def eof?; true end; }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert uf.eof?
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_predicate uf, :eof?
+ end
+
+ def test_delegate_to_path_to_tempfile
+ tf = Class.new { def to_path; "/any/file/path" end; }
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_equal "/any/file/path", uf.to_path
end
def test_respond_to?
tf = Class.new { def read; yield end }
- uf = Http::UploadedFile.new(:tempfile => tf.new)
- assert uf.respond_to?(:headers), 'responds to headers'
- assert uf.respond_to?(:read), 'responds to read'
+ uf = Http::UploadedFile.new(tempfile: tf.new)
+ assert_respond_to uf, :headers
+ assert_respond_to uf, :read
end
end
end
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index 8c9782bb90..aef9351de1 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module TestUrlGeneration
class WithMountPoint < ActionDispatch::IntegrationTest
@@ -13,11 +15,11 @@ module TestUrlGeneration
end
Routes.draw do
- get "/foo", :to => "my_route_generating#index", :as => :foo
+ get "/foo", to: "my_route_generating#index", as: :foo
resources :bars
- mount MyRouteGeneratingController.action(:index), at: '/bar'
+ mount MyRouteGeneratingController.action(:index), at: "/bar"
end
APP = build_app Routes
@@ -35,22 +37,22 @@ module TestUrlGeneration
end
test "accepting a :script_name option" do
- assert_equal "/bar/foo", foo_path(:script_name => "/bar")
+ assert_equal "/bar/foo", foo_path(script_name: "/bar")
end
test "the request's SCRIPT_NAME takes precedence over the route" do
- get "/foo", headers: { 'SCRIPT_NAME' => "/new", 'action_dispatch.routes' => Routes }
+ get "/foo", headers: { "SCRIPT_NAME" => "/new", "action_dispatch.routes" => Routes }
assert_equal "/new/foo", response.body
end
test "the request's SCRIPT_NAME wraps the mounted app's" do
- get '/new/bar/foo', headers: { 'SCRIPT_NAME' => '/new', 'PATH_INFO' => '/bar/foo', 'action_dispatch.routes' => Routes }
+ get "/new/bar/foo", headers: { "SCRIPT_NAME" => "/new", "PATH_INFO" => "/bar/foo", "action_dispatch.routes" => Routes }
assert_equal "/new/bar/foo", response.body
end
test "handling http protocol with https set" do
https!
- assert_equal "http://www.example.com/foo", foo_url(:protocol => "http")
+ assert_equal "http://www.example.com/foo", foo_url(protocol: "http")
end
test "extracting protocol from host when protocol not present" do
@@ -117,25 +119,23 @@ module TestUrlGeneration
test "generating URLs with trailing slashes" do
assert_equal "/bars.json", bars_path(
trailing_slash: true,
- format: 'json'
+ format: "json"
)
end
test "generating URLS with querystring and trailing slashes" do
assert_equal "/bars.json?a=b", bars_path(
trailing_slash: true,
- a: 'b',
- format: 'json'
+ a: "b",
+ format: "json"
)
end
test "generating URLS with empty querystring" do
assert_equal "/bars.json", bars_path(
a: {},
- format: 'json'
+ format: "json"
)
end
-
end
end
-
diff --git a/actionpack/test/fixtures/alternate_helpers/foo_helper.rb b/actionpack/test/fixtures/alternate_helpers/foo_helper.rb
index 2528584473..c1a995af5f 100644
--- a/actionpack/test/fixtures/alternate_helpers/foo_helper.rb
+++ b/actionpack/test/fixtures/alternate_helpers/foo_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module FooHelper
- redefine_method(:baz) {}
+ redefine_method(:baz) { }
end
diff --git a/actionpack/test/fixtures/collection_cache/index.html.erb b/actionpack/test/fixtures/collection_cache/index.html.erb
index 521b1450df..853e501ab4 100644
--- a/actionpack/test/fixtures/collection_cache/index.html.erb
+++ b/actionpack/test/fixtures/collection_cache/index.html.erb
@@ -1 +1 @@
-<%= render @customers %> \ No newline at end of file
+<%= render partial: 'customers/customer', collection: @customers, cached: true %>
diff --git a/actionpack/test/fixtures/company.rb b/actionpack/test/fixtures/company.rb
index f3ac3642fa..93afdd5472 100644
--- a/actionpack/test/fixtures/company.rb
+++ b/actionpack/test/fixtures/company.rb
@@ -1,9 +1,11 @@
+# frozen_string_literal: true
+
class Company < ActiveRecord::Base
has_one :mascot
self.sequence_name = :companies_nonstd_seq
validates_presence_of :name
def validate
- errors.add('rating', 'rating should not be 2') if rating == 2
+ errors.add("rating", "rating should not be 2") if rating == 2
end
end
diff --git a/actionpack/test/fixtures/functional_caching/_formatted_partial.html.erb b/actionpack/test/fixtures/functional_caching/_formatted_partial.html.erb
new file mode 100644
index 0000000000..aad73c0d6b
--- /dev/null
+++ b/actionpack/test/fixtures/functional_caching/_formatted_partial.html.erb
@@ -0,0 +1 @@
+<p>Hello!</p>
diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
index 9b88fa1f5a..dfcd423978 100644
--- a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
+++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb
@@ -1,3 +1,3 @@
<body>
-<%= cache do %><p>ERB</p><% end %>
+<%= cache("fragment") do %><p>ERB</p><% end %>
</body>
diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder
index efdcc28e0f..6599579740 100644
--- a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder
+++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder
@@ -1,5 +1,5 @@
xml.body do
- cache do
+ cache("fragment") do
xml.p "Builder"
end
end
diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb
index e523b74ae3..abf7017ce6 100644
--- a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb
+++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached_with_variant.html+phone.erb
@@ -1,3 +1,3 @@
<body>
-<%= cache do %><p>PHONE</p><% end %>
+<%= cache("fragment") do %><p>PHONE</p><% end %>
</body>
diff --git a/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
index fa5e6bd318..1148d83ad7 100644
--- a/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
+++ b/actionpack/test/fixtures/functional_caching/fragment_cached.html.erb
@@ -1,3 +1,3 @@
Hello
-<%= cache do %>This bit's fragment cached<% end %>
+<%= cache "fragment" do %>This bit's fragment cached<% end %>
<%= 'Ciao' %>
diff --git a/actionpack/test/fixtures/functional_caching/fragment_cached_with_options.html.erb b/actionpack/test/fixtures/functional_caching/fragment_cached_with_options.html.erb
new file mode 100644
index 0000000000..951c761995
--- /dev/null
+++ b/actionpack/test/fixtures/functional_caching/fragment_cached_with_options.html.erb
@@ -0,0 +1,3 @@
+<body>
+<%= cache 'with_options', skip_digest: true, expires_in: 10 do %><p>ERB</p><% end %>
+</body>
diff --git a/actionpack/test/fixtures/functional_caching/xml_fragment_cached_with_html_partial.xml.builder b/actionpack/test/fixtures/functional_caching/xml_fragment_cached_with_html_partial.xml.builder
new file mode 100644
index 0000000000..2bdda3af18
--- /dev/null
+++ b/actionpack/test/fixtures/functional_caching/xml_fragment_cached_with_html_partial.xml.builder
@@ -0,0 +1,5 @@
+cache do
+ xml.title "Hello!"
+end
+
+xml.body cdata_section(render("formatted_partial"))
diff --git a/actionpack/test/fixtures/helpers/abc_helper.rb b/actionpack/test/fixtures/helpers/abc_helper.rb
index cf2774bb5f..999b9b5c6e 100644
--- a/actionpack/test/fixtures/helpers/abc_helper.rb
+++ b/actionpack/test/fixtures/helpers/abc_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module AbcHelper
def bare_a() end
end
diff --git a/actionpack/test/fixtures/helpers/fun/games_helper.rb b/actionpack/test/fixtures/helpers/fun/games_helper.rb
index 3b7adce086..8b325927f3 100644
--- a/actionpack/test/fixtures/helpers/fun/games_helper.rb
+++ b/actionpack/test/fixtures/helpers/fun/games_helper.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
module Fun
module GamesHelper
def stratego() "Iz guuut!" end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/helpers/fun/pdf_helper.rb b/actionpack/test/fixtures/helpers/fun/pdf_helper.rb
index 0171be8500..7ce6591de3 100644
--- a/actionpack/test/fixtures/helpers/fun/pdf_helper.rb
+++ b/actionpack/test/fixtures/helpers/fun/pdf_helper.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
module Fun
module PdfHelper
- def foobar() 'baz' end
+ def foobar() "baz" end
end
end
diff --git a/actionpack/test/fixtures/helpers/just_me_helper.rb b/actionpack/test/fixtures/helpers/just_me_helper.rb
index b140a7b9b4..bd977a22d9 100644
--- a/actionpack/test/fixtures/helpers/just_me_helper.rb
+++ b/actionpack/test/fixtures/helpers/just_me_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module JustMeHelper
def me() "mine!" end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/helpers/me_too_helper.rb b/actionpack/test/fixtures/helpers/me_too_helper.rb
index ce56042143..c6fc053dee 100644
--- a/actionpack/test/fixtures/helpers/me_too_helper.rb
+++ b/actionpack/test/fixtures/helpers/me_too_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module MeTooHelper
def me() "me too!" end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/helpers1_pack/pack1_helper.rb b/actionpack/test/fixtures/helpers1_pack/pack1_helper.rb
index 9faa427736..cf75b6875e 100644
--- a/actionpack/test/fixtures/helpers1_pack/pack1_helper.rb
+++ b/actionpack/test/fixtures/helpers1_pack/pack1_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Pack1Helper
def conflicting_helper
"pack1"
diff --git a/actionpack/test/fixtures/helpers2_pack/pack2_helper.rb b/actionpack/test/fixtures/helpers2_pack/pack2_helper.rb
index cf56697dfb..c8e51d40a2 100644
--- a/actionpack/test/fixtures/helpers2_pack/pack2_helper.rb
+++ b/actionpack/test/fixtures/helpers2_pack/pack2_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Pack2Helper
def conflicting_helper
"pack2"
diff --git a/actionpack/test/fixtures/helpers_typo/admin/users_helper.rb b/actionpack/test/fixtures/helpers_typo/admin/users_helper.rb
index 7d2326e04d..0455e26b93 100644
--- a/actionpack/test/fixtures/helpers_typo/admin/users_helper.rb
+++ b/actionpack/test/fixtures/helpers_typo/admin/users_helper.rb
@@ -1,5 +1,6 @@
+# frozen_string_literal: true
+
module Admin
module UsersHelpeR
end
end
-
diff --git a/actionpack/test/fixtures/implicit_render_test/empty_action_with_mobile_variant.html+mobile.erb b/actionpack/test/fixtures/implicit_render_test/empty_action_with_mobile_variant.html+mobile.erb
new file mode 100644
index 0000000000..ded99ba52d
--- /dev/null
+++ b/actionpack/test/fixtures/implicit_render_test/empty_action_with_mobile_variant.html+mobile.erb
@@ -0,0 +1 @@
+mobile
diff --git a/actionpack/test/fixtures/implicit_render_test/empty_action_with_template.html.erb b/actionpack/test/fixtures/implicit_render_test/empty_action_with_template.html.erb
new file mode 100644
index 0000000000..dd294f8cf6
--- /dev/null
+++ b/actionpack/test/fixtures/implicit_render_test/empty_action_with_template.html.erb
@@ -0,0 +1 @@
+<h1>Empty action rendered this implicitly.</h1>
diff --git a/actionpack/test/fixtures/layouts/builder.builder b/actionpack/test/fixtures/layouts/builder.builder
index 7c7d4b2dd1..c55488edd0 100644
--- a/actionpack/test/fixtures/layouts/builder.builder
+++ b/actionpack/test/fixtures/layouts/builder.builder
@@ -1,3 +1,3 @@
xml.wrapper do
xml << yield
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/load_me.rb b/actionpack/test/fixtures/load_me.rb
new file mode 100644
index 0000000000..efafe6898f
--- /dev/null
+++ b/actionpack/test/fixtures/load_me.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+class LoadMe
+end
diff --git a/actionpack/test/fixtures/multipart/mona_lisa.jpg b/actionpack/test/fixtures/multipart/mona_lisa.jpg
deleted file mode 100644
index 5cf3bef3d0..0000000000
--- a/actionpack/test/fixtures/multipart/mona_lisa.jpg
+++ /dev/null
Binary files differ
diff --git a/actionpack/test/fixtures/multipart/ruby_on_rails.jpg b/actionpack/test/fixtures/multipart/ruby_on_rails.jpg
new file mode 100644
index 0000000000..ed284ea0ba
--- /dev/null
+++ b/actionpack/test/fixtures/multipart/ruby_on_rails.jpg
Binary files differ
diff --git a/actionpack/test/fixtures/namespaced/implicit_render_test/hello_world.erb b/actionpack/test/fixtures/namespaced/implicit_render_test/hello_world.erb
new file mode 100644
index 0000000000..cd0875583a
--- /dev/null
+++ b/actionpack/test/fixtures/namespaced/implicit_render_test/hello_world.erb
@@ -0,0 +1 @@
+Hello world!
diff --git a/actionpack/test/fixtures/old_content_type/render_default_for_builder.builder b/actionpack/test/fixtures/old_content_type/render_default_for_builder.builder
index 598d62e2fc..15c8a7f5cf 100644
--- a/actionpack/test/fixtures/old_content_type/render_default_for_builder.builder
+++ b/actionpack/test/fixtures/old_content_type/render_default_for_builder.builder
@@ -1 +1 @@
-xml.p "Hello world!" \ No newline at end of file
+xml.p "Hello world!"
diff --git a/actionpack/test/fixtures/public/foo/さようなら.html b/actionpack/test/fixtures/public/foo/さようなら.html
new file mode 100644
index 0000000000..627bb2469f
--- /dev/null
+++ b/actionpack/test/fixtures/public/foo/さようなら.html
@@ -0,0 +1 @@
+means goodbye in Japanese
diff --git a/actionpack/test/fixtures/public/foo/さようなら.html.gz b/actionpack/test/fixtures/public/foo/さようなら.html.gz
new file mode 100644
index 0000000000..4f484cfe86
--- /dev/null
+++ b/actionpack/test/fixtures/public/foo/さようなら.html.gz
Binary files differ
diff --git a/actionpack/test/fixtures/respond_to/using_defaults.xml.builder b/actionpack/test/fixtures/respond_to/using_defaults.xml.builder
index 598d62e2fc..15c8a7f5cf 100644
--- a/actionpack/test/fixtures/respond_to/using_defaults.xml.builder
+++ b/actionpack/test/fixtures/respond_to/using_defaults.xml.builder
@@ -1 +1 @@
-xml.p "Hello world!" \ No newline at end of file
+xml.p "Hello world!"
diff --git a/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder b/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder
index 598d62e2fc..15c8a7f5cf 100644
--- a/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder
+++ b/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder
@@ -1 +1 @@
-xml.p "Hello world!" \ No newline at end of file
+xml.p "Hello world!"
diff --git a/actionpack/test/fixtures/respond_to/variant_with_implicit_rendering.html+mobile.erb b/actionpack/test/fixtures/respond_to/variant_with_implicit_template_rendering.html+mobile.erb
index 317801ad30..317801ad30 100644
--- a/actionpack/test/fixtures/respond_to/variant_with_implicit_rendering.html+mobile.erb
+++ b/actionpack/test/fixtures/respond_to/variant_with_implicit_template_rendering.html+mobile.erb
diff --git a/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb b/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb
index 4ee7a24561..deb81c647d 100644
--- a/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb
+++ b/actionpack/test/fixtures/session_autoload_test/session_autoload_test/foo.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module SessionAutoloadTest
class Foo
- def initialize(bar='baz')
+ def initialize(bar = "baz")
@bar = bar
end
def inspect
diff --git a/actionpack/test/fixtures/test/formatted_xml_erb.builder b/actionpack/test/fixtures/test/formatted_xml_erb.builder
index 14fd3549fb..f98aaa34a5 100644
--- a/actionpack/test/fixtures/test/formatted_xml_erb.builder
+++ b/actionpack/test/fixtures/test/formatted_xml_erb.builder
@@ -1 +1 @@
-xml.test 'failed' \ No newline at end of file
+xml.test "failed"
diff --git a/actionpack/test/fixtures/test/hello_xml_world.builder b/actionpack/test/fixtures/test/hello_xml_world.builder
index e7081b89fe..d16bb6b5cb 100644
--- a/actionpack/test/fixtures/test/hello_xml_world.builder
+++ b/actionpack/test/fixtures/test/hello_xml_world.builder
@@ -8,4 +8,4 @@ xml.html do
xml.p "monks"
xml.p "wiseguys"
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/fixtures/test/with_implicit_template.erb b/actionpack/test/fixtures/test/with_implicit_template.erb
new file mode 100644
index 0000000000..474488cd13
--- /dev/null
+++ b/actionpack/test/fixtures/test/with_implicit_template.erb
@@ -0,0 +1 @@
+Hello explicitly!
diff --git a/actionpack/test/fixtures/公共/foo/さようなら.html b/actionpack/test/fixtures/公共/foo/さようなら.html
new file mode 100644
index 0000000000..627bb2469f
--- /dev/null
+++ b/actionpack/test/fixtures/公共/foo/さようなら.html
@@ -0,0 +1 @@
+means goodbye in Japanese
diff --git a/actionpack/test/fixtures/公共/foo/さようなら.html.gz b/actionpack/test/fixtures/公共/foo/さようなら.html.gz
new file mode 100644
index 0000000000..4f484cfe86
--- /dev/null
+++ b/actionpack/test/fixtures/公共/foo/さようなら.html.gz
Binary files differ
diff --git a/actionpack/test/journey/gtg/builder_test.rb b/actionpack/test/journey/gtg/builder_test.rb
index c1da374007..b92460884d 100644
--- a/actionpack/test/journey/gtg/builder_test.rb
+++ b/actionpack/test/journey/gtg/builder_test.rb
@@ -1,28 +1,30 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
module GTG
class TestBuilder < ActiveSupport::TestCase
def test_following_states_multi
- table = tt ['a|a']
- assert_equal 1, table.move([0], 'a').length
+ table = tt ["a|a"]
+ assert_equal 1, table.move([0], "a").length
end
def test_following_states_multi_regexp
- table = tt [':a|b']
- assert_equal 1, table.move([0], 'fooo').length
- assert_equal 2, table.move([0], 'b').length
+ table = tt [":a|b"]
+ assert_equal 1, table.move([0], "fooo").length
+ assert_equal 2, table.move([0], "b").length
end
def test_multi_path
- table = tt ['/:a/d', '/b/c']
+ table = tt ["/:a/d", "/b/c"]
[
- [1, '/'],
- [2, 'b'],
- [2, '/'],
- [1, 'c'],
+ [1, "/"],
+ [2, "b"],
+ [2, "/"],
+ [1, "c"],
].inject([0]) { |state, (exp, sym)|
new = table.move(state, sym)
assert_equal exp, new.length
@@ -38,9 +40,9 @@ module ActionDispatch
/articles/:id(.:format)
}
- sim = NFA::Simulator.new table
+ sim = NFA::Simulator.new table
- match = sim.match '/articles/new'
+ match = sim.match "/articles/new"
assert_equal 2, match.memos.length
end
@@ -52,27 +54,27 @@ module ActionDispatch
/articles/new(.:format)
}
- sim = NFA::Simulator.new table
+ sim = NFA::Simulator.new table
- match = sim.match '/articles/new'
+ match = sim.match "/articles/new"
assert_equal 2, match.memos.length
end
private
- def ast strings
- parser = Journey::Parser.new
- asts = strings.map { |string|
- memo = Object.new
- ast = parser.parse string
- ast.each { |n| n.memo = memo }
- ast
- }
- Nodes::Or.new asts
- end
+ def ast(strings)
+ parser = Journey::Parser.new
+ asts = strings.map { |string|
+ memo = Object.new
+ ast = parser.parse string
+ ast.each { |n| n.memo = memo }
+ ast
+ }
+ Nodes::Or.new asts
+ end
- def tt strings
- Builder.new(ast(strings)).transition_table
- end
+ def tt(strings)
+ Builder.new(ast(strings)).transition_table
+ end
end
end
end
diff --git a/actionpack/test/journey/gtg/transition_table_test.rb b/actionpack/test/journey/gtg/transition_table_test.rb
index b968780d8d..9044934f05 100644
--- a/actionpack/test/journey/gtg/transition_table_test.rb
+++ b/actionpack/test/journey/gtg/transition_table_test.rb
@@ -1,5 +1,7 @@
-require 'abstract_unit'
-require 'active_support/json/decoding'
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "active_support/json/decoding"
module ActionDispatch
module Journey
@@ -14,12 +16,12 @@ module ActionDispatch
}
json = ActiveSupport::JSON.decode table.to_json
- assert json['regexp_states']
- assert json['string_states']
- assert json['accepting']
+ assert json["regexp_states"]
+ assert json["string_states"]
+ assert json["accepting"]
end
- if system("dot -V 2>/dev/null")
+ if system("dot -V", 2 => File::NULL)
def test_to_svg
table = tt %w{
/articles(.:format)
@@ -34,26 +36,26 @@ module ActionDispatch
end
def test_simulate_gt
- sim = simulator_for ['/foo', '/bar']
- assert_match sim, '/foo'
+ sim = simulator_for ["/foo", "/bar"]
+ assert_match_route sim, "/foo"
end
def test_simulate_gt_regexp
- sim = simulator_for [':foo']
- assert_match sim, 'foo'
+ sim = simulator_for [":foo"]
+ assert_match_route sim, "foo"
end
def test_simulate_gt_regexp_mix
- sim = simulator_for ['/get', '/:method/foo']
- assert_match sim, '/get'
- assert_match sim, '/get/foo'
+ sim = simulator_for ["/get", "/:method/foo"]
+ assert_match_route sim, "/get"
+ assert_match_route sim, "/get/foo"
end
def test_simulate_optional
- sim = simulator_for ['/foo(/bar)']
- assert_match sim, '/foo'
- assert_match sim, '/foo/bar'
- assert_no_match sim, '/foo/'
+ sim = simulator_for ["/foo(/bar)"]
+ assert_match_route sim, "/foo"
+ assert_match_route sim, "/foo/bar"
+ assert_no_match_route sim, "/foo/"
end
def test_match_data
@@ -65,11 +67,11 @@ module ActionDispatch
sim = GTG::Simulator.new tt
- match = sim.match '/get'
- assert_equal [paths.first], match.memos
+ memos = sim.memos "/get"
+ assert_equal [paths.first], memos
- match = sim.match '/get/foo'
- assert_equal [paths.last], match.memos
+ memos = sim.memos "/get/foo"
+ assert_equal [paths.last], memos
end
def test_match_data_ambiguous
@@ -86,29 +88,37 @@ module ActionDispatch
builder = GTG::Builder.new ast
sim = GTG::Simulator.new builder.transition_table
- match = sim.match '/articles/new'
- assert_equal [paths[1], paths[3]], match.memos
+ memos = sim.memos "/articles/new"
+ assert_equal [paths[1], paths[3]], memos
end
private
- def asts paths
- parser = Journey::Parser.new
- paths.map { |x|
- ast = parser.parse x
- ast.each { |n| n.memo = ast}
- ast
- }
- end
+ def asts(paths)
+ parser = Journey::Parser.new
+ paths.map { |x|
+ ast = parser.parse x
+ ast.each { |n| n.memo = ast }
+ ast
+ }
+ end
- def tt paths
- x = asts paths
- builder = GTG::Builder.new Nodes::Or.new x
- builder.transition_table
- end
+ def tt(paths)
+ x = asts paths
+ builder = GTG::Builder.new Nodes::Or.new x
+ builder.transition_table
+ end
- def simulator_for paths
- GTG::Simulator.new tt(paths)
- end
+ def simulator_for(paths)
+ GTG::Simulator.new tt(paths)
+ end
+
+ def assert_match_route(simulator, path)
+ assert simulator.memos(path), "Simulator should match #{path}."
+ end
+
+ def assert_no_match_route(simulator, path)
+ assert_not simulator.memos(path) { nil }, "Simulator should not match #{path}."
+ end
end
end
end
diff --git a/actionpack/test/journey/nfa/simulator_test.rb b/actionpack/test/journey/nfa/simulator_test.rb
index 673a491fe5..6b9f87b452 100644
--- a/actionpack/test/journey/nfa/simulator_test.rb
+++ b/actionpack/test/journey/nfa/simulator_test.rb
@@ -1,47 +1,49 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
module NFA
class TestSimulator < ActiveSupport::TestCase
def test_simulate_simple
- sim = simulator_for ['/foo']
- assert_match sim, '/foo'
+ sim = simulator_for ["/foo"]
+ assert_match sim, "/foo"
end
def test_simulate_simple_no_match
- sim = simulator_for ['/foo']
- assert_no_match sim, 'foo'
+ sim = simulator_for ["/foo"]
+ assert_no_match sim, "foo"
end
def test_simulate_simple_no_match_too_long
- sim = simulator_for ['/foo']
- assert_no_match sim, '/foo/bar'
+ sim = simulator_for ["/foo"]
+ assert_no_match sim, "/foo/bar"
end
def test_simulate_simple_no_match_wrong_string
- sim = simulator_for ['/foo']
- assert_no_match sim, '/bar'
+ sim = simulator_for ["/foo"]
+ assert_no_match sim, "/bar"
end
def test_simulate_regex
- sim = simulator_for ['/:foo/bar']
- assert_match sim, '/bar/bar'
- assert_match sim, '/foo/bar'
+ sim = simulator_for ["/:foo/bar"]
+ assert_match sim, "/bar/bar"
+ assert_match sim, "/foo/bar"
end
def test_simulate_or
- sim = simulator_for ['/foo', '/bar']
- assert_match sim, '/bar'
- assert_match sim, '/foo'
- assert_no_match sim, '/baz'
+ sim = simulator_for ["/foo", "/bar"]
+ assert_match sim, "/bar"
+ assert_match sim, "/foo"
+ assert_no_match sim, "/baz"
end
def test_simulate_optional
- sim = simulator_for ['/foo(/bar)']
- assert_match sim, '/foo'
- assert_match sim, '/foo/bar'
- assert_no_match sim, '/foo/'
+ sim = simulator_for ["/foo(/bar)"]
+ assert_match sim, "/foo"
+ assert_match sim, "/foo/bar"
+ assert_no_match sim, "/foo/"
end
def test_matchdata_has_memos
@@ -49,7 +51,7 @@ module ActionDispatch
parser = Journey::Parser.new
asts = paths.map { |x|
ast = parser.parse x
- ast.each { |n| n.memo = ast}
+ ast.each { |n| n.memo = ast }
ast
}
@@ -59,17 +61,17 @@ module ActionDispatch
sim = Simulator.new builder.transition_table
- md = sim.match '/foo'
+ md = sim.match "/foo"
assert_equal [expected], md.memos
end
def test_matchdata_memos_on_merge
parser = Journey::Parser.new
routes = [
- '/articles(.:format)',
- '/articles/new(.:format)',
- '/articles/:id/edit(.:format)',
- '/articles/:id(.:format)',
+ "/articles(.:format)",
+ "/articles/new(.:format)",
+ "/articles/:id/edit(.:format)",
+ "/articles/:id(.:format)",
].map { |path|
ast = parser.parse path
ast.each { |n| n.memo = ast }
@@ -80,13 +82,13 @@ module ActionDispatch
ast = Nodes::Or.new routes
- nfa = Journey::NFA::Builder.new ast
+ nfa = Journey::NFA::Builder.new ast
sim = Simulator.new nfa.transition_table
- md = sim.match '/articles'
+ md = sim.match "/articles"
assert_equal [asts.first], md.memos
end
- def simulator_for paths
+ def simulator_for(paths)
parser = Journey::Parser.new
asts = paths.map { |x| parser.parse x }
builder = Builder.new Nodes::Or.new asts
diff --git a/actionpack/test/journey/nfa/transition_table_test.rb b/actionpack/test/journey/nfa/transition_table_test.rb
index 1248082c03..c23611e980 100644
--- a/actionpack/test/journey/nfa/transition_table_test.rb
+++ b/actionpack/test/journey/nfa/transition_table_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -9,63 +11,63 @@ module ActionDispatch
end
def test_eclosure
- table = tt '/'
+ table = tt "/"
assert_equal [0], table.eclosure(0)
- table = tt ':a|:b'
+ table = tt ":a|:b"
assert_equal 3, table.eclosure(0).length
- table = tt '(:a|:b)'
+ table = tt "(:a|:b)"
assert_equal 5, table.eclosure(0).length
assert_equal 5, table.eclosure([0]).length
end
def test_following_states_one
- table = tt '/'
+ table = tt "/"
- assert_equal [1], table.following_states(0, '/')
- assert_equal [1], table.following_states([0], '/')
+ assert_equal [1], table.following_states(0, "/")
+ assert_equal [1], table.following_states([0], "/")
end
def test_following_states_group
- table = tt 'a|b'
+ table = tt "a|b"
states = table.eclosure 0
- assert_equal 1, table.following_states(states, 'a').length
- assert_equal 1, table.following_states(states, 'b').length
+ assert_equal 1, table.following_states(states, "a").length
+ assert_equal 1, table.following_states(states, "b").length
end
def test_following_states_multi
- table = tt 'a|a'
+ table = tt "a|a"
states = table.eclosure 0
- assert_equal 2, table.following_states(states, 'a').length
- assert_equal 0, table.following_states(states, 'b').length
+ assert_equal 2, table.following_states(states, "a").length
+ assert_equal 0, table.following_states(states, "b").length
end
def test_following_states_regexp
- table = tt 'a|:a'
+ table = tt "a|:a"
states = table.eclosure 0
- assert_equal 1, table.following_states(states, 'a').length
+ assert_equal 1, table.following_states(states, "a").length
assert_equal 1, table.following_states(states, /[^\.\/\?]+/).length
- assert_equal 0, table.following_states(states, 'b').length
+ assert_equal 0, table.following_states(states, "b").length
end
def test_alphabet
- table = tt 'a|:a'
- assert_equal [/[^\.\/\?]+/, 'a'], table.alphabet
+ table = tt "a|:a"
+ assert_equal [/[^\.\/\?]+/, "a"], table.alphabet
- table = tt 'a|a'
- assert_equal ['a'], table.alphabet
+ table = tt "a|a"
+ assert_equal ["a"], table.alphabet
end
private
- def tt string
- ast = @parser.parse string
- builder = Builder.new ast
- builder.transition_table
- end
+ def tt(string)
+ ast = @parser.parse string
+ builder = Builder.new ast
+ builder.transition_table
+ end
end
end
end
diff --git a/actionpack/test/journey/nodes/symbol_test.rb b/actionpack/test/journey/nodes/symbol_test.rb
index adf85b860c..b0622ac71a 100644
--- a/actionpack/test/journey/nodes/symbol_test.rb
+++ b/actionpack/test/journey/nodes/symbol_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -6,10 +8,10 @@ module ActionDispatch
class TestSymbol < ActiveSupport::TestCase
def test_default_regexp?
sym = Symbol.new "foo"
- assert sym.default_regexp?
+ assert_predicate sym, :default_regexp?
sym.regexp = nil
- assert_not sym.default_regexp?
+ assert_not_predicate sym, :default_regexp?
end
end
end
diff --git a/actionpack/test/journey/path/pattern_test.rb b/actionpack/test/journey/path/pattern_test.rb
index 72858f5eda..3e7aea57f1 100644
--- a/actionpack/test/journey/path/pattern_test.rb
+++ b/actionpack/test/journey/path/pattern_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -8,22 +10,22 @@ module ActionDispatch
x = /.+/
{
- '/:controller(/:action)' => %r{\A/(#{x})(?:/([^/.?]+))?\Z},
- '/:controller/foo' => %r{\A/(#{x})/foo\Z},
- '/:controller/:action' => %r{\A/(#{x})/([^/.?]+)\Z},
- '/:controller' => %r{\A/(#{x})\Z},
- '/:controller(/:action(/:id))' => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z},
- '/:controller/:action.xml' => %r{\A/(#{x})/([^/.?]+)\.xml\Z},
- '/:controller.:format' => %r{\A/(#{x})\.([^/.?]+)\Z},
- '/:controller(.:format)' => %r{\A/(#{x})(?:\.([^/.?]+))?\Z},
- '/:controller/*foo' => %r{\A/(#{x})/(.+)\Z},
- '/:controller/*foo/bar' => %r{\A/(#{x})/(.+)/bar\Z},
- '/:foo|*bar' => %r{\A/(?:([^/.?]+)|(.+))\Z},
+ "/:controller(/:action)" => %r{\A/(#{x})(?:/([^/.?]+))?\Z},
+ "/:controller/foo" => %r{\A/(#{x})/foo\Z},
+ "/:controller/:action" => %r{\A/(#{x})/([^/.?]+)\Z},
+ "/:controller" => %r{\A/(#{x})\Z},
+ "/:controller(/:action(/:id))" => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z},
+ "/:controller/:action.xml" => %r{\A/(#{x})/([^/.?]+)\.xml\Z},
+ "/:controller.:format" => %r{\A/(#{x})\.([^/.?]+)\Z},
+ "/:controller(.:format)" => %r{\A/(#{x})(?:\.([^/.?]+))?\Z},
+ "/:controller/*foo" => %r{\A/(#{x})/(.+)\Z},
+ "/:controller/*foo/bar" => %r{\A/(#{x})/(.+)/bar\Z},
+ "/:foo|*bar" => %r{\A/(?:([^/.?]+)|(.+))\Z},
}.each do |path, expected|
- define_method(:"test_to_regexp_#{path}") do
+ define_method(:"test_to_regexp_#{Regexp.escape(path)}") do
path = Pattern.build(
path,
- { :controller => /.+/ },
+ { controller: /.+/ },
SEPARATORS,
true
)
@@ -32,22 +34,22 @@ module ActionDispatch
end
{
- '/:controller(/:action)' => %r{\A/(#{x})(?:/([^/.?]+))?},
- '/:controller/foo' => %r{\A/(#{x})/foo},
- '/:controller/:action' => %r{\A/(#{x})/([^/.?]+)},
- '/:controller' => %r{\A/(#{x})},
- '/:controller(/:action(/:id))' => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?},
- '/:controller/:action.xml' => %r{\A/(#{x})/([^/.?]+)\.xml},
- '/:controller.:format' => %r{\A/(#{x})\.([^/.?]+)},
- '/:controller(.:format)' => %r{\A/(#{x})(?:\.([^/.?]+))?},
- '/:controller/*foo' => %r{\A/(#{x})/(.+)},
- '/:controller/*foo/bar' => %r{\A/(#{x})/(.+)/bar},
- '/:foo|*bar' => %r{\A/(?:([^/.?]+)|(.+))},
+ "/:controller(/:action)" => %r{\A/(#{x})(?:/([^/.?]+))?},
+ "/:controller/foo" => %r{\A/(#{x})/foo},
+ "/:controller/:action" => %r{\A/(#{x})/([^/.?]+)},
+ "/:controller" => %r{\A/(#{x})},
+ "/:controller(/:action(/:id))" => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?},
+ "/:controller/:action.xml" => %r{\A/(#{x})/([^/.?]+)\.xml},
+ "/:controller.:format" => %r{\A/(#{x})\.([^/.?]+)},
+ "/:controller(.:format)" => %r{\A/(#{x})(?:\.([^/.?]+))?},
+ "/:controller/*foo" => %r{\A/(#{x})/(.+)},
+ "/:controller/*foo/bar" => %r{\A/(#{x})/(.+)/bar},
+ "/:foo|*bar" => %r{\A/(?:([^/.?]+)|(.+))},
}.each do |path, expected|
- define_method(:"test_to_non_anchored_regexp_#{path}") do
+ define_method(:"test_to_non_anchored_regexp_#{Regexp.escape(path)}") do
path = Pattern.build(
path,
- { :controller => /.+/ },
+ { controller: /.+/ },
SEPARATORS,
false
)
@@ -56,21 +58,21 @@ module ActionDispatch
end
{
- '/:controller(/:action)' => %w{ controller action },
- '/:controller/foo' => %w{ controller },
- '/:controller/:action' => %w{ controller action },
- '/:controller' => %w{ controller },
- '/:controller(/:action(/:id))' => %w{ controller action id },
- '/:controller/:action.xml' => %w{ controller action },
- '/:controller.:format' => %w{ controller format },
- '/:controller(.:format)' => %w{ controller format },
- '/:controller/*foo' => %w{ controller foo },
- '/:controller/*foo/bar' => %w{ controller foo },
+ "/:controller(/:action)" => %w{ controller action },
+ "/:controller/foo" => %w{ controller },
+ "/:controller/:action" => %w{ controller action },
+ "/:controller" => %w{ controller },
+ "/:controller(/:action(/:id))" => %w{ controller action id },
+ "/:controller/:action.xml" => %w{ controller action },
+ "/:controller.:format" => %w{ controller format },
+ "/:controller(.:format)" => %w{ controller format },
+ "/:controller/*foo" => %w{ controller foo },
+ "/:controller/*foo/bar" => %w{ controller foo },
}.each do |path, expected|
- define_method(:"test_names_#{path}") do
+ define_method(:"test_names_#{Regexp.escape(path)}") do
path = Pattern.build(
path,
- { :controller => /.+/ },
+ { controller: /.+/ },
SEPARATORS,
true
)
@@ -80,8 +82,8 @@ module ActionDispatch
def test_to_regexp_with_extended_group
path = Pattern.build(
- '/page/:name',
- { :name => /
+ "/page/:name",
+ { name: /
#ROFL
(tender|love
#MAO
@@ -89,16 +91,16 @@ module ActionDispatch
SEPARATORS,
true
)
- assert_match(path, '/page/tender')
- assert_match(path, '/page/love')
- assert_no_match(path, '/page/loving')
+ assert_match(path, "/page/tender")
+ assert_match(path, "/page/love")
+ assert_no_match(path, "/page/loving")
end
def test_optional_names
[
- ['/:foo(/:bar(/:baz))', %w{ bar baz }],
- ['/:foo(/:bar)', %w{ bar }],
- ['/:foo(/:bar)/:lol(/:baz)', %w{ bar baz }],
+ ["/:foo(/:bar(/:baz))", %w{ bar baz }],
+ ["/:foo(/:bar)", %w{ bar }],
+ ["/:foo(/:bar)/:lol(/:baz)", %w{ bar baz }],
].each do |pattern, list|
path = Pattern.from_string pattern
assert_equal list.sort, path.optional_names.sort
@@ -107,31 +109,31 @@ module ActionDispatch
def test_to_regexp_match_non_optional
path = Pattern.build(
- '/:name',
- { :name => /\d+/ },
+ "/:name",
+ { name: /\d+/ },
SEPARATORS,
true
)
- assert_match(path, '/123')
- assert_no_match(path, '/')
+ assert_match(path, "/123")
+ assert_no_match(path, "/")
end
def test_to_regexp_with_group
path = Pattern.build(
- '/page/:name',
- { :name => /(tender|love)/ },
+ "/page/:name",
+ { name: /(tender|love)/ },
SEPARATORS,
true
)
- assert_match(path, '/page/tender')
- assert_match(path, '/page/love')
- assert_no_match(path, '/page/loving')
+ assert_match(path, "/page/tender")
+ assert_match(path, "/page/love")
+ assert_no_match(path, "/page/loving")
end
def test_ast_sets_regular_expressions
- requirements = { :name => /(tender|love)/, :value => /./ }
+ requirements = { name: /(tender|love)/, value: /./ }
path = Pattern.build(
- '/page/:name/:value',
+ "/page/:name/:value",
requirements,
SEPARATORS,
true
@@ -146,26 +148,26 @@ module ActionDispatch
def test_match_data_with_group
path = Pattern.build(
- '/page/:name',
- { :name => /(tender|love)/ },
+ "/page/:name",
+ { name: /(tender|love)/ },
SEPARATORS,
true
)
- match = path.match '/page/tender'
- assert_equal 'tender', match[1]
+ match = path.match "/page/tender"
+ assert_equal "tender", match[1]
assert_equal 2, match.length
end
def test_match_data_with_multi_group
path = Pattern.build(
- '/page/:name/:id',
- { :name => /t(((ender|love)))()/ },
+ "/page/:name/:id",
+ { name: /t(((ender|love)))()/ },
SEPARATORS,
true
)
- match = path.match '/page/tender/10'
- assert_equal 'tender', match[1]
- assert_equal '10', match[2]
+ match = path.match "/page/tender/10"
+ assert_equal "tender", match[1]
+ assert_equal "10", match[2]
assert_equal 3, match.length
assert_equal %w{ tender 10 }, match.captures
end
@@ -173,8 +175,8 @@ module ActionDispatch
def test_star_with_custom_re
z = /\d+/
path = Pattern.build(
- '/page/*foo',
- { :foo => z },
+ "/page/*foo",
+ { foo: z },
SEPARATORS,
true
)
@@ -183,76 +185,76 @@ module ActionDispatch
def test_insensitive_regexp_with_group
path = Pattern.build(
- '/page/:name/aaron',
- { :name => /(tender|love)/i },
+ "/page/:name/aaron",
+ { name: /(tender|love)/i },
SEPARATORS,
true
)
- assert_match(path, '/page/TENDER/aaron')
- assert_match(path, '/page/loVE/aaron')
- assert_no_match(path, '/page/loVE/AAron')
+ assert_match(path, "/page/TENDER/aaron")
+ assert_match(path, "/page/loVE/aaron")
+ assert_no_match(path, "/page/loVE/AAron")
end
def test_to_regexp_with_strexp
- path = Pattern.build('/:controller', { }, SEPARATORS, true)
+ path = Pattern.build("/:controller", {}, SEPARATORS, true)
x = %r{\A/([^/.?]+)\Z}
assert_equal(x.source, path.source)
end
def test_to_regexp_defaults
- path = Pattern.from_string '/:controller(/:action(/:id))'
+ path = Pattern.from_string "/:controller(/:action(/:id))"
expected = %r{\A/([^/.?]+)(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z}
assert_equal expected, path.to_regexp
end
def test_failed_match
- path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
- uri = 'content'
+ path = Pattern.from_string "/:controller(/:action(/:id(.:format)))"
+ uri = "content"
assert_not path =~ uri
end
def test_match_controller
- path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
- uri = '/content'
+ path = Pattern.from_string "/:controller(/:action(/:id(.:format)))"
+ uri = "/content"
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
- assert_equal 'content', match[1]
+ assert_equal "content", match[1]
assert_nil match[2]
assert_nil match[3]
assert_nil match[4]
end
def test_match_controller_action
- path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
- uri = '/content/list'
+ path = Pattern.from_string "/:controller(/:action(/:id(.:format)))"
+ uri = "/content/list"
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
- assert_equal 'content', match[1]
- assert_equal 'list', match[2]
+ assert_equal "content", match[1]
+ assert_equal "list", match[2]
assert_nil match[3]
assert_nil match[4]
end
def test_match_controller_action_id
- path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
- uri = '/content/list/10'
+ path = Pattern.from_string "/:controller(/:action(/:id(.:format)))"
+ uri = "/content/list/10"
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
- assert_equal 'content', match[1]
- assert_equal 'list', match[2]
- assert_equal '10', match[3]
+ assert_equal "content", match[1]
+ assert_equal "list", match[2]
+ assert_equal "10", match[3]
assert_nil match[4]
end
def test_match_literal
path = Path::Pattern.from_string "/books(/:action(.:format))"
- uri = '/books'
+ uri = "/books"
match = path =~ uri
assert_equal %w{ action format }, match.names
assert_nil match[1]
@@ -262,21 +264,21 @@ module ActionDispatch
def test_match_literal_with_action
path = Path::Pattern.from_string "/books(/:action(.:format))"
- uri = '/books/list'
+ uri = "/books/list"
match = path =~ uri
assert_equal %w{ action format }, match.names
- assert_equal 'list', match[1]
+ assert_equal "list", match[1]
assert_nil match[2]
end
def test_match_literal_with_action_and_format
path = Path::Pattern.from_string "/books(/:action(.:format))"
- uri = '/books/list.rss'
+ uri = "/books/list.rss"
match = path =~ uri
assert_equal %w{ action format }, match.names
- assert_equal 'list', match[1]
- assert_equal 'rss', match[2]
+ assert_equal "list", match[1]
+ assert_equal "rss", match[2]
end
end
end
diff --git a/actionpack/test/journey/route/definition/parser_test.rb b/actionpack/test/journey/route/definition/parser_test.rb
index d7d7172a40..39693198b8 100644
--- a/actionpack/test/journey/route/definition/parser_test.rb
+++ b/actionpack/test/journey/route/definition/parser_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -9,88 +11,88 @@ module ActionDispatch
end
def test_slash
- assert_equal :SLASH, @parser.parse('/').type
- assert_round_trip '/'
+ assert_equal :SLASH, @parser.parse("/").type
+ assert_round_trip "/"
end
def test_segment
- assert_round_trip '/foo'
+ assert_round_trip "/foo"
end
def test_segments
- assert_round_trip '/foo/bar'
+ assert_round_trip "/foo/bar"
end
def test_segment_symbol
- assert_round_trip '/foo/:id'
+ assert_round_trip "/foo/:id"
end
def test_symbol
- assert_round_trip '/:foo'
+ assert_round_trip "/:foo"
end
def test_group
- assert_round_trip '(/:foo)'
+ assert_round_trip "(/:foo)"
end
def test_groups
- assert_round_trip '(/:foo)(/:bar)'
+ assert_round_trip "(/:foo)(/:bar)"
end
def test_nested_groups
- assert_round_trip '(/:foo(/:bar))'
+ assert_round_trip "(/:foo(/:bar))"
end
def test_dot_symbol
- assert_round_trip('.:format')
+ assert_round_trip(".:format")
end
def test_dot_literal
- assert_round_trip('.xml')
+ assert_round_trip(".xml")
end
def test_segment_dot
- assert_round_trip('/foo.:bar')
+ assert_round_trip("/foo.:bar")
end
def test_segment_group_dot
- assert_round_trip('/foo(.:bar)')
+ assert_round_trip("/foo(.:bar)")
end
def test_segment_group
- assert_round_trip('/foo(/:action)')
+ assert_round_trip("/foo(/:action)")
end
def test_segment_groups
- assert_round_trip('/foo(/:action)(/:bar)')
+ assert_round_trip("/foo(/:action)(/:bar)")
end
def test_segment_nested_groups
- assert_round_trip('/foo(/:action(/:bar))')
+ assert_round_trip("/foo(/:action(/:bar))")
end
def test_group_followed_by_path
- assert_round_trip('/foo(/:action)/:bar')
+ assert_round_trip("/foo(/:action)/:bar")
end
def test_star
- assert_round_trip('*foo')
- assert_round_trip('/*foo')
- assert_round_trip('/bar/*foo')
- assert_round_trip('/bar/(*foo)')
+ assert_round_trip("*foo")
+ assert_round_trip("/*foo")
+ assert_round_trip("/bar/*foo")
+ assert_round_trip("/bar/(*foo)")
end
def test_or
- assert_round_trip('a|b')
- assert_round_trip('a|b|c')
- assert_round_trip('(a|b)|c')
- assert_round_trip('a|(b|c)')
- assert_round_trip('*a|(b|c)')
- assert_round_trip('*a|:b|c')
+ assert_round_trip("a|b")
+ assert_round_trip("a|b|c")
+ assert_round_trip("(a|b)|c")
+ assert_round_trip("a|(b|c)")
+ assert_round_trip("*a|(b|c)")
+ assert_round_trip("*a|:b|c")
end
def test_arbitrary
- assert_round_trip('/bar/*foo#')
+ assert_round_trip("/bar/*foo#")
end
def test_literal_dot_paren
@@ -101,7 +103,7 @@ module ActionDispatch
assert_round_trip "/(:locale)(.:format)"
end
- def assert_round_trip str
+ def assert_round_trip(str)
assert_equal str, @parser.parse(str).to_s
end
end
diff --git a/actionpack/test/journey/route/definition/scanner_test.rb b/actionpack/test/journey/route/definition/scanner_test.rb
index 7a510f1e07..092177d315 100644
--- a/actionpack/test/journey/route/definition/scanner_test.rb
+++ b/actionpack/test/journey/route/definition/scanner_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -8,61 +10,70 @@ module ActionDispatch
@scanner = Scanner.new
end
- # /page/:id(/:action)(.:format)
- def test_tokens
- [
- ['/', [[:SLASH, '/']]],
- ['*omg', [[:STAR, '*omg']]],
- ['/page', [[:SLASH, '/'], [:LITERAL, 'page']]],
- ['/page!', [[:SLASH, '/'], [:LITERAL, 'page!']]],
- ['/page$', [[:SLASH, '/'], [:LITERAL, 'page$']]],
- ['/page&', [[:SLASH, '/'], [:LITERAL, 'page&']]],
- ["/page'", [[:SLASH, '/'], [:LITERAL, "page'"]]],
- ['/page*', [[:SLASH, '/'], [:LITERAL, 'page*']]],
- ['/page+', [[:SLASH, '/'], [:LITERAL, 'page+']]],
- ['/page,', [[:SLASH, '/'], [:LITERAL, 'page,']]],
- ['/page;', [[:SLASH, '/'], [:LITERAL, 'page;']]],
- ['/page=', [[:SLASH, '/'], [:LITERAL, 'page=']]],
- ['/page@', [[:SLASH, '/'], [:LITERAL, 'page@']]],
- ['/page\:', [[:SLASH, '/'], [:LITERAL, 'page:']]],
- ['/page\(', [[:SLASH, '/'], [:LITERAL, 'page(']]],
- ['/page\)', [[:SLASH, '/'], [:LITERAL, 'page)']]],
- ['/~page', [[:SLASH, '/'], [:LITERAL, '~page']]],
- ['/pa-ge', [[:SLASH, '/'], [:LITERAL, 'pa-ge']]],
- ['/:page', [[:SLASH, '/'], [:SYMBOL, ':page']]],
- ['/(:page)', [
- [:SLASH, '/'],
- [:LPAREN, '('],
- [:SYMBOL, ':page'],
- [:RPAREN, ')'],
- ]],
- ['(/:action)', [
- [:LPAREN, '('],
- [:SLASH, '/'],
- [:SYMBOL, ':action'],
- [:RPAREN, ')'],
- ]],
- ['(())', [[:LPAREN, '('],
- [:LPAREN, '('], [:RPAREN, ')'], [:RPAREN, ')']]],
- ['(.:format)', [
- [:LPAREN, '('],
- [:DOT, '.'],
- [:SYMBOL, ':format'],
- [:RPAREN, ')'],
+ CASES = [
+ ["/", [[:SLASH, "/"]]],
+ ["*omg", [[:STAR, "*omg"]]],
+ ["/page", [[:SLASH, "/"], [:LITERAL, "page"]]],
+ ["/page!", [[:SLASH, "/"], [:LITERAL, "page!"]]],
+ ["/page$", [[:SLASH, "/"], [:LITERAL, "page$"]]],
+ ["/page&", [[:SLASH, "/"], [:LITERAL, "page&"]]],
+ ["/page'", [[:SLASH, "/"], [:LITERAL, "page'"]]],
+ ["/page*", [[:SLASH, "/"], [:LITERAL, "page*"]]],
+ ["/page+", [[:SLASH, "/"], [:LITERAL, "page+"]]],
+ ["/page,", [[:SLASH, "/"], [:LITERAL, "page,"]]],
+ ["/page;", [[:SLASH, "/"], [:LITERAL, "page;"]]],
+ ["/page=", [[:SLASH, "/"], [:LITERAL, "page="]]],
+ ["/page@", [[:SLASH, "/"], [:LITERAL, "page@"]]],
+ ['/page\:', [[:SLASH, "/"], [:LITERAL, "page:"]]],
+ ['/page\(', [[:SLASH, "/"], [:LITERAL, "page("]]],
+ ['/page\)', [[:SLASH, "/"], [:LITERAL, "page)"]]],
+ ["/~page", [[:SLASH, "/"], [:LITERAL, "~page"]]],
+ ["/pa-ge", [[:SLASH, "/"], [:LITERAL, "pa-ge"]]],
+ ["/:page", [[:SLASH, "/"], [:SYMBOL, ":page"]]],
+ ["/:page|*foo", [
+ [:SLASH, "/"],
+ [:SYMBOL, ":page"],
+ [:OR, "|"],
+ [:STAR, "*foo"]
]],
- ].each do |str, expected|
- @scanner.scan_setup str
- assert_tokens expected, @scanner
+ ["/(:page)", [
+ [:SLASH, "/"],
+ [:LPAREN, "("],
+ [:SYMBOL, ":page"],
+ [:RPAREN, ")"],
+ ]],
+ ["(/:action)", [
+ [:LPAREN, "("],
+ [:SLASH, "/"],
+ [:SYMBOL, ":action"],
+ [:RPAREN, ")"],
+ ]],
+ ["(())", [[:LPAREN, "("],
+ [:LPAREN, "("], [:RPAREN, ")"], [:RPAREN, ")"]]],
+ ["(.:format)", [
+ [:LPAREN, "("],
+ [:DOT, "."],
+ [:SYMBOL, ":format"],
+ [:RPAREN, ")"],
+ ]],
+ ]
+
+ CASES.each do |pattern, expected_tokens|
+ test "Scanning `#{pattern}`" do
+ @scanner.scan_setup pattern
+ assert_tokens expected_tokens, @scanner, pattern
end
end
- def assert_tokens tokens, scanner
- toks = []
- while tok = scanner.next_token
- toks << tok
+ private
+
+ def assert_tokens(expected_tokens, scanner, pattern)
+ actual_tokens = []
+ while token = scanner.next_token
+ actual_tokens << token
+ end
+ assert_equal expected_tokens, actual_tokens, "Wrong tokens for `#{pattern}`"
end
- assert_equal tokens, toks
- end
end
end
end
diff --git a/actionpack/test/journey/route_test.rb b/actionpack/test/journey/route_test.rb
index 22c3b8113d..a8bf4a11e2 100644
--- a/actionpack/test/journey/route_test.rb
+++ b/actionpack/test/journey/route_test.rb
@@ -1,11 +1,13 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
class TestRoute < ActiveSupport::TestCase
def test_initialize
app = Object.new
- path = Path::Pattern.from_string '/:controller(/:action(/:id(.:format)))'
+ path = Path::Pattern.from_string "/:controller(/:action(/:id(.:format)))"
defaults = {}
route = Route.build("name", app, path, {}, [], defaults)
@@ -16,7 +18,7 @@ module ActionDispatch
def test_route_adds_itself_as_memo
app = Object.new
- path = Path::Pattern.from_string '/:controller(/:action(/:id(.:format)))'
+ path = Path::Pattern.from_string "/:controller(/:action(/:id(.:format)))"
defaults = {}
route = Route.build("name", app, path, {}, [], defaults)
@@ -26,71 +28,69 @@ module ActionDispatch
end
def test_path_requirements_override_defaults
- path = Path::Pattern.build(':name', { name: /love/ }, '/', true)
- defaults = { name: 'tender' }
- route = Route.build('name', nil, path, {}, [], defaults)
+ path = Path::Pattern.build(":name", { name: /love/ }, "/", true)
+ defaults = { name: "tender" }
+ route = Route.build("name", nil, path, {}, [], defaults)
assert_equal(/love/, route.requirements[:name])
end
def test_ip_address
- path = Path::Pattern.from_string '/messages/:id(.:format)'
- route = Route.build("name", nil, path, {:ip => '192.168.1.1'}, [],
- { :controller => 'foo', :action => 'bar' })
- assert_equal '192.168.1.1', route.ip
+ path = Path::Pattern.from_string "/messages/:id(.:format)"
+ route = Route.build("name", nil, path, { ip: "192.168.1.1" }, [],
+ controller: "foo", action: "bar")
+ assert_equal "192.168.1.1", route.ip
end
def test_default_ip
- path = Path::Pattern.from_string '/messages/:id(.:format)'
+ path = Path::Pattern.from_string "/messages/:id(.:format)"
route = Route.build("name", nil, path, {}, [],
- { :controller => 'foo', :action => 'bar' })
+ controller: "foo", action: "bar")
assert_equal(//, route.ip)
end
def test_format_with_star
- path = Path::Pattern.from_string '/:controller/*extra'
+ path = Path::Pattern.from_string "/:controller/*extra"
route = Route.build("name", nil, path, {}, [],
- { :controller => 'foo', :action => 'bar' })
- assert_equal '/foo/himom', route.format({
- :controller => 'foo',
- :extra => 'himom',
- })
+ controller: "foo", action: "bar")
+ assert_equal "/foo/himom", route.format(
+ controller: "foo",
+ extra: "himom")
end
def test_connects_all_match
- path = Path::Pattern.from_string '/:controller(/:action(/:id(.:format)))'
- route = Route.build("name", nil, path, {:action => 'bar'}, [], { :controller => 'foo' })
-
- assert_equal '/foo/bar/10', route.format({
- :controller => 'foo',
- :action => 'bar',
- :id => 10
- })
+ path = Path::Pattern.from_string "/:controller(/:action(/:id(.:format)))"
+ route = Route.build("name", nil, path, { action: "bar" }, [], controller: "foo")
+
+ assert_equal "/foo/bar/10", route.format(
+ controller: "foo",
+ action: "bar",
+ id: 10)
end
def test_extras_are_not_included_if_optional
- path = Path::Pattern.from_string '/page/:id(/:action)'
- route = Route.build("name", nil, path, { }, [], { :action => 'show' })
+ path = Path::Pattern.from_string "/page/:id(/:action)"
+ route = Route.build("name", nil, path, {}, [], action: "show")
- assert_equal '/page/10', route.format({ :id => 10 })
+ assert_equal "/page/10", route.format(id: 10)
end
def test_extras_are_not_included_if_optional_with_parameter
- path = Path::Pattern.from_string '(/sections/:section)/pages/:id'
- route = Route.build("name", nil, path, { }, [], { :action => 'show' })
+ path = Path::Pattern.from_string "(/sections/:section)/pages/:id"
+ route = Route.build("name", nil, path, {}, [], action: "show")
- assert_equal '/pages/10', route.format({:id => 10})
+ assert_equal "/pages/10", route.format(id: 10)
end
def test_extras_are_not_included_if_optional_parameter_is_nil
- path = Path::Pattern.from_string '(/sections/:section)/pages/:id'
- route = Route.build("name", nil, path, { }, [], { :action => 'show' })
+ path = Path::Pattern.from_string "(/sections/:section)/pages/:id"
+ route = Route.build("name", nil, path, {}, [], action: "show")
- assert_equal '/pages/10', route.format({:id => 10, :section => nil})
+ assert_equal "/pages/10", route.format(id: 10, section: nil)
end
def test_score
constraints = {}
- defaults = {:controller=>"pages", :action=>"show"}
+ defaults = { controller: "pages", action: "show" }
path = Path::Pattern.from_string "/page/:id(/:action)(.:format)"
specific = Route.build "name", nil, path, constraints, [:controller, :action], defaults
@@ -98,7 +98,7 @@ module ActionDispatch
path = Path::Pattern.from_string "/:controller(/:action(/:id))(.:format)"
generic = Route.build "name", nil, path, constraints, [], {}
- knowledge = {:id=>20, :controller=>"pages", :action=>"show"}
+ knowledge = { "id" => true, "controller" => true, "action" => true }
routes = [specific, generic]
diff --git a/actionpack/test/journey/router/utils_test.rb b/actionpack/test/journey/router/utils_test.rb
index 2b505f081e..472f1bf35e 100644
--- a/actionpack/test/journey/router/utils_test.rb
+++ b/actionpack/test/journey/router/utils_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -21,7 +23,7 @@ module ActionDispatch
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))
+ 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
@@ -31,6 +33,15 @@ module ActionDispatch
def test_normalize_path_uppercase
assert_equal "/foo%AAbar%AAbaz", Utils.normalize_path("/foo%aabar%aabaz")
end
+
+ def test_normalize_path_maintains_string_encoding
+ path = "/foo%AAbar%AAbaz".b
+ assert_equal Encoding::ASCII_8BIT, Utils.normalize_path(path).encoding
+ end
+
+ def test_normalize_path_with_nil
+ assert_equal "/", Utils.normalize_path(nil)
+ end
end
end
end
diff --git a/actionpack/test/journey/router_test.rb b/actionpack/test/journey/router_test.rb
index 15d51e5d6c..1f4e14aef6 100644
--- a/actionpack/test/journey/router_test.rb
+++ b/actionpack/test/journey/router_test.rb
@@ -1,13 +1,15 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
class TestRouter < ActiveSupport::TestCase
- attr_reader :routes, :mapper
+ attr_reader :mapper, :routes, :route_set, :router
def setup
- @app = Routing::RouteSet::Dispatcher.new({})
- @route_set = ActionDispatch::Routing::RouteSet.new
+ @app = Routing::RouteSet::Dispatcher.new({})
+ @route_set = ActionDispatch::Routing::RouteSet.new
@routes = @route_set.router.routes
@router = @route_set.router
@formatter = @route_set.formatter
@@ -15,84 +17,83 @@ module ActionDispatch
end
def test_dashes
- mapper.get '/foo-bar-baz', to: 'foo#bar'
+ get "/foo-bar-baz", to: "foo#bar"
- env = rails_env 'PATH_INFO' => '/foo-bar-baz'
+ env = rails_env "PATH_INFO" => "/foo-bar-baz"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
assert called
end
def test_unicode
- mapper.get '/ほげ', to: 'foo#bar'
+ get "/ほげ", to: "foo#bar"
- #match the escaped version of /ほげ
- env = rails_env 'PATH_INFO' => '/%E3%81%BB%E3%81%92'
+ # match the escaped version of /ほげ
+ env = rails_env "PATH_INFO" => "/%E3%81%BB%E3%81%92"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
assert called
end
def test_regexp_first_precedence
- mapper.get "/whois/:domain", :domain => /\w+\.[\w\.]+/, to: "foo#bar"
- mapper.get "/whois/:id(.:format)", to: "foo#baz"
+ get "/whois/:domain", domain: /\w+\.[\w\.]+/, to: "foo#bar"
+ get "/whois/:id(.:format)", to: "foo#baz"
- env = rails_env 'PATH_INFO' => '/whois/example.com'
+ env = rails_env "PATH_INFO" => "/whois/example.com"
list = []
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
list << r
end
assert_equal 2, list.length
r = list.first
- assert_equal '/whois/:domain(.:format)', r.path.spec.to_s
+ assert_equal "/whois/:domain(.:format)", r.path.spec.to_s
end
def test_required_parts_verified_are_anchored
- mapper.get "/foo/:id", :id => /\d/, anchor: false, to: "foo#bar"
+ get "/foo/:id", id: /\d/, anchor: false, to: "foo#bar"
assert_raises(ActionController::UrlGenerationError) do
- @formatter.generate(nil, { :controller => "foo", :action => "bar", :id => '10' }, { })
+ @formatter.generate(nil, { controller: "foo", action: "bar", id: "10" }, {})
end
end
def test_required_parts_are_verified_when_building
- mapper.get "/foo/:id", :id => /\d+/, anchor: false, to: "foo#bar"
+ get "/foo/:id", id: /\d+/, anchor: false, to: "foo#bar"
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar", :id => '10' }, { })
- assert_equal '/foo/10', path
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", id: "10" }, {})
+ assert_equal "/foo/10", path
assert_raises(ActionController::UrlGenerationError) do
- @formatter.generate(nil, { :id => 'aa' }, { })
+ @formatter.generate(nil, { id: "aa" }, {})
end
end
def test_only_required_parts_are_verified
- mapper.get "/foo(/:id)", :id => /\d/, :to => "foo#bar"
+ get "/foo(/:id)", id: /\d/, to: "foo#bar"
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar", :id => '10' }, { })
- assert_equal '/foo/10', path
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", id: "10" }, {})
+ assert_equal "/foo/10", path
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar" }, { })
- assert_equal '/foo', path
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar" }, {})
+ assert_equal "/foo", path
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar", :id => 'aa' }, { })
- assert_equal '/foo/aa', path
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", id: "aa" }, {})
+ assert_equal "/foo/aa", path
end
def test_knows_what_parts_are_missing_from_named_route
route_name = "gorby_thunderhorse"
- mapper = ActionDispatch::Routing::Mapper.new @route_set
- mapper.get "/foo/:id", :as => route_name, :id => /\d+/, :to => "foo#bar"
+ get "/foo/:id", as: route_name, id: /\d+/, to: "foo#bar"
error = assert_raises(ActionController::UrlGenerationError) do
- @formatter.generate(route_name, { }, { })
+ @formatter.generate(route_name, {}, {})
end
assert_match(/missing required keys: \[:id\]/, error.message)
@@ -102,69 +103,66 @@ module ActionDispatch
route_name = "gorby_thunderhorse"
error = assert_raises(ActionController::UrlGenerationError) do
- @formatter.generate(route_name, { }, { })
+ @formatter.generate(route_name, {}, {})
end
assert_no_match(/missing required keys: \[\]/, error.message)
end
def test_X_Cascade
- mapper.get "/messages(.:format)", to: "foo#bar"
- resp = @router.serve(rails_env({ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/lol' }))
- assert_equal ['Not Found'], resp.last
- assert_equal 'pass', resp[1]['X-Cascade']
+ get "/messages(.:format)", to: "foo#bar"
+ resp = router.serve(rails_env("REQUEST_METHOD" => "GET", "PATH_INFO" => "/lol"))
+ assert_equal ["Not Found"], resp.last
+ assert_equal "pass", resp[1]["X-Cascade"]
assert_equal 404, resp.first
end
def test_clear_trailing_slash_from_script_name_on_root_unanchored_routes
- route_set = Routing::RouteSet.new
- mapper = Routing::Mapper.new route_set
-
- app = lambda { |env| [200, {}, ['success!']] }
- mapper.get '/weblog', :to => app
+ app = lambda { |env| [200, {}, ["success!"]] }
+ get "/weblog", to: app
- env = rack_env('SCRIPT_NAME' => '', 'PATH_INFO' => '/weblog')
+ env = rack_env("SCRIPT_NAME" => "", "PATH_INFO" => "/weblog")
resp = route_set.call env
- assert_equal ['success!'], resp.last
- assert_equal '', env['SCRIPT_NAME']
+ assert_equal ["success!"], resp.last
+ assert_equal "", env["SCRIPT_NAME"]
end
def test_defaults_merge_correctly
- mapper.get '/foo(/:id)', to: "foo#bar", id: nil
+ get "/foo(/:id)", to: "foo#bar", id: nil
- env = rails_env 'PATH_INFO' => '/foo/10'
- @router.recognize(env) do |r, params|
- assert_equal({:id => '10', :controller => "foo", :action => "bar"}, params)
+ env = rails_env "PATH_INFO" => "/foo/10"
+ router.recognize(env) do |r, params|
+ assert_equal({ id: "10", controller: "foo", action: "bar" }, params)
end
- env = rails_env 'PATH_INFO' => '/foo'
- @router.recognize(env) do |r, params|
- assert_equal({:id => nil, :controller => "foo", :action => "bar"}, params)
+ env = rails_env "PATH_INFO" => "/foo"
+ router.recognize(env) do |r, params|
+ assert_equal({ id: nil, controller: "foo", action: "bar" }, params)
end
end
def test_recognize_with_unbound_regexp
- mapper.get "/foo", anchor: false, to: "foo#bar"
+ get "/foo", anchor: false, to: "foo#bar"
- env = rails_env 'PATH_INFO' => '/foo/bar'
+ env = rails_env "PATH_INFO" => "/foo/bar"
- @router.recognize(env) { |*_| }
+ router.recognize(env) { |*_| }
- assert_equal '/foo', env.env['SCRIPT_NAME']
- assert_equal '/bar', env.env['PATH_INFO']
+ assert_equal "/foo", env.env["SCRIPT_NAME"]
+ assert_equal "/bar", env.env["PATH_INFO"]
end
def test_bound_regexp_keeps_path_info
- mapper.get "/foo", to: "foo#bar"
+ get "/foo", to: "foo#bar"
- env = rails_env 'PATH_INFO' => '/foo'
+ env = rails_env "PATH_INFO" => "/foo"
- before = env.env['SCRIPT_NAME']
+ before = env.env["SCRIPT_NAME"]
- @router.recognize(env) { |*_| }
+ router.recognize(env) { |*_| }
- assert_equal before, env.env['SCRIPT_NAME']
- assert_equal '/foo', env.env['PATH_INFO']
+ assert_equal before, env.env["SCRIPT_NAME"]
+ assert_equal "/foo", env.env["PATH_INFO"]
end
def test_path_not_found
@@ -174,60 +172,60 @@ module ActionDispatch
"/messages/:id/edit(.:format)",
"/messages/:id(.:format)"
].each do |path|
- mapper.get path, to: "foo#bar"
+ get path, to: "foo#bar"
end
- env = rails_env 'PATH_INFO' => '/messages/unknown/path'
+ env = rails_env "PATH_INFO" => "/messages/unknown/path"
yielded = false
- @router.recognize(env) do |*whatever|
+ router.recognize(env) do |*whatever|
yielded = true
end
assert_not yielded
end
def test_required_part_in_recall
- mapper.get "/messages/:a/:b", to: "foo#bar"
+ get "/messages/:a/:b", to: "foo#bar"
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar", :a => 'a' }, { :b => 'b' })
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", a: "a" }, { b: "b" })
assert_equal "/messages/a/b", path
end
def test_splat_in_recall
- mapper.get "/*path", to: "foo#bar"
+ get "/*path", to: "foo#bar"
- path, _ = @formatter.generate(nil, { :controller => "foo", :action => "bar" }, { :path => 'b' })
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar" }, { path: "b" })
assert_equal "/b", path
end
def test_recall_should_be_used_when_scoring
- mapper.get "/messages/:action(/:id(.:format))", to: 'foo#bar'
- mapper.get "/messages/:id(.:format)", to: 'bar#baz'
+ get "/messages/:action(/:id(.:format))", to: "foo#bar"
+ get "/messages/:id(.:format)", to: "bar#baz"
- path, _ = @formatter.generate(nil, { :controller => "foo", :id => 10 }, { :action => 'index' })
+ path, _ = @formatter.generate(nil, { controller: "foo", id: 10 }, { action: "index" })
assert_equal "/messages/index/10", path
end
def test_nil_path_parts_are_ignored
- mapper.get "/:controller(/:action(.:format))", to: "tasks#lol"
+ get "/:controller(/:action(.:format))", to: "tasks#lol"
- params = { :controller => "tasks", :format => nil }
- extras = { :action => 'lol' }
+ params = { controller: "tasks", format: nil }
+ extras = { action: "lol" }
path, _ = @formatter.generate(nil, params, extras)
- assert_equal '/tasks', path
+ assert_equal "/tasks", path
end
def test_generate_slash
params = [ [:controller, "tasks"],
[:action, "show"] ]
- mapper.get "/", Hash[params]
+ get "/", Hash[params]
path, _ = @formatter.generate(nil, Hash[params], {})
- assert_equal '/', path
+ assert_equal "/", path
end
def test_generate_calls_param_proc
- mapper.get '/:controller(/:action)', to: "foo#bar"
+ get "/:controller(/:action)", to: "foo#bar"
parameterized = []
params = [ [:controller, "tasks"],
@@ -237,71 +235,71 @@ module ActionDispatch
nil,
Hash[params],
{},
- lambda { |k,v| parameterized << [k,v]; v })
+ lambda { |k, v| parameterized << [k, v]; v })
assert_equal params.map(&:to_s).sort, parameterized.map(&:to_s).sort
end
def test_generate_id
- mapper.get '/:controller(/:action)', to: 'foo#bar'
+ get "/:controller(/:action)", to: "foo#bar"
path, params = @formatter.generate(
- nil, {:id=>1, :controller=>"tasks", :action=>"show"}, {})
- assert_equal '/tasks/show', path
- assert_equal({:id => 1}, params)
+ nil, { id: 1, controller: "tasks", action: "show" }, {})
+ assert_equal "/tasks/show", path
+ assert_equal({ id: 1 }, params)
end
def test_generate_escapes
- mapper.get '/:controller(/:action)', to: "foo#bar"
+ get "/:controller(/:action)", to: "foo#bar"
path, _ = @formatter.generate(nil,
- { :controller => "tasks",
- :action => "a/b c+d",
+ { controller: "tasks",
+ action: "a/b c+d",
}, {})
- assert_equal '/tasks/a%2Fb%20c+d', path
+ assert_equal "/tasks/a%2Fb%20c+d", path
end
def test_generate_escapes_with_namespaced_controller
- mapper.get '/:controller(/:action)', to: "foo#bar"
+ get "/:controller(/:action)", to: "foo#bar"
path, _ = @formatter.generate(
- nil, { :controller => "admin/tasks",
- :action => "a/b c+d",
+ nil, { controller: "admin/tasks",
+ action: "a/b c+d",
}, {})
- assert_equal '/admin/tasks/a%2Fb%20c+d', path
+ assert_equal "/admin/tasks/a%2Fb%20c+d", path
end
def test_generate_extra_params
- mapper.get '/:controller(/:action)', to: "foo#bar"
+ get "/:controller(/:action)", to: "foo#bar"
path, params = @formatter.generate(
- nil, { :id => 1,
- :controller => "tasks",
- :action => "show",
- :relative_url_root => nil
+ nil, { id: 1,
+ controller: "tasks",
+ action: "show",
+ relative_url_root: nil
}, {})
- assert_equal '/tasks/show', path
- assert_equal({:id => 1, :relative_url_root => nil}, params)
+ assert_equal "/tasks/show", path
+ assert_equal({ id: 1, relative_url_root: nil }, params)
end
def test_generate_missing_keys_no_matches_different_format_keys
- mapper.get '/:controller/:action/:name', to: "foo#bar"
+ get "/:controller/:action/:name", to: "foo#bar"
primarty_parameters = {
- :id => 1,
- :controller => "tasks",
- :action => "show",
- :relative_url_root => nil
+ id: 1,
+ controller: "tasks",
+ action: "show",
+ relative_url_root: nil
}
redirection_parameters = {
- 'action'=>'show',
+ "action" => "show",
}
- missing_key = 'name'
- missing_parameters ={
+ missing_key = "name"
+ missing_parameters = {
missing_key => "task_1"
}
request_parameters = primarty_parameters.merge(redirection_parameters).merge(missing_parameters)
- message = "No route matches #{Hash[request_parameters.sort_by{|k,v|k.to_s}].inspect} missing required keys: #{[missing_key.to_sym].inspect}"
+ message = "No route matches #{Hash[request_parameters.sort_by { |k, v|k.to_s }].inspect}, missing required keys: #{[missing_key.to_sym].inspect}"
error = assert_raises(ActionController::UrlGenerationError) do
@formatter.generate(
@@ -311,42 +309,42 @@ module ActionDispatch
end
def test_generate_uses_recall_if_needed
- mapper.get '/:controller(/:action(/:id))', to: "foo#bar"
+ get "/:controller(/:action(/:id))", to: "foo#bar"
path, params = @formatter.generate(
nil,
- {:controller =>"tasks", :id => 10},
- {:action =>"index"})
- assert_equal '/tasks/index/10', path
+ { controller: "tasks", id: 10 },
+ { action: "index" })
+ assert_equal "/tasks/index/10", path
assert_equal({}, params)
end
def test_generate_with_name
- mapper.get '/:controller(/:action)', to: 'foo#bar', as: 'tasks'
+ get "/:controller(/:action)", to: "foo#bar", as: "tasks"
path, params = @formatter.generate(
"tasks",
- {:controller=>"tasks"},
- {:controller=>"tasks", :action=>"index"})
- assert_equal '/tasks', path
+ { controller: "tasks" },
+ { controller: "tasks", action: "index" })
+ assert_equal "/tasks", path
assert_equal({}, params)
end
{
- '/content' => { :controller => 'content' },
- '/content/list' => { :controller => 'content', :action => 'list' },
- '/content/show/10' => { :controller => 'content', :action => 'show', :id => "10" },
+ "/content" => { controller: "content" },
+ "/content/list" => { controller: "content", action: "list" },
+ "/content/show/10" => { controller: "content", action: "show", id: "10" },
}.each do |request_path, expected|
define_method("test_recognize_#{expected.keys.map(&:to_s).join('_')}") do
- mapper.get "/:controller(/:action(/:id))", to: 'foo#bar'
+ get "/:controller(/:action(/:id))", to: "foo#bar"
route = @routes.first
- env = rails_env 'PATH_INFO' => request_path
- called = false
+ env = rails_env "PATH_INFO" => request_path
+ called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
assert_equal route, r
- assert_equal({ :action => "bar" }.merge(expected), params)
+ assert_equal({ action: "bar" }.merge(expected), params)
called = true
end
@@ -355,19 +353,19 @@ module ActionDispatch
end
{
- :segment => ['/a%2Fb%20c+d/splat', { :segment => 'a/b c+d', :splat => 'splat' }],
- :splat => ['/segment/a/b%20c+d', { :segment => 'segment', :splat => 'a/b c+d' }]
+ segment: ["/a%2Fb%20c+d/splat", { segment: "a/b c+d", splat: "splat" }],
+ splat: ["/segment/a/b%20c+d", { segment: "segment", splat: "a/b c+d" }]
}.each do |name, (request_path, expected)|
define_method("test_recognize_#{name}") do
- mapper.get '/:segment/*splat', to: 'foo#bar'
+ get "/:segment/*splat", to: "foo#bar"
- env = rails_env 'PATH_INFO' => request_path
- called = false
+ env = rails_env "PATH_INFO" => request_path
+ called = false
route = @routes.first
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
assert_equal route, r
- assert_equal(expected.merge(:controller=>"foo", :action=>"bar"), params)
+ assert_equal(expected.merge(controller: "foo", action: "bar"), params)
called = true
end
@@ -376,18 +374,18 @@ module ActionDispatch
end
def test_namespaced_controller
- mapper.get "/:controller(/:action(/:id))", { :controller => /.+?/ }
+ get "/:controller(/:action(/:id))", controller: /.+?/
route = @routes.first
- env = rails_env 'PATH_INFO' => '/admin/users/show/10'
+ env = rails_env "PATH_INFO" => "/admin/users/show/10"
called = false
expected = {
- :controller => 'admin/users',
- :action => 'show',
- :id => '10'
+ controller: "admin/users",
+ action: "show",
+ id: "10"
}
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
assert_equal route, r
assert_equal(expected, params)
called = true
@@ -396,13 +394,13 @@ module ActionDispatch
end
def test_recognize_literal
- mapper.get "/books(/:action(.:format))", controller: "books"
+ get "/books(/:action(.:format))", controller: "books"
route = @routes.first
- env = rails_env 'PATH_INFO' => '/books/list.rss'
- expected = { :controller => 'books', :action => 'list', :format => 'rss' }
+ env = rails_env "PATH_INFO" => "/books/list.rss"
+ expected = { controller: "books", action: "list", format: "rss" }
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
assert_equal route, r
assert_equal(expected, params)
called = true
@@ -412,15 +410,15 @@ module ActionDispatch
end
def test_recognize_head_route
- mapper.match "/books(/:action(.:format))", via: 'head', to: 'foo#bar'
+ match "/books(/:action(.:format))", via: "head", to: "foo#bar"
env = rails_env(
- 'PATH_INFO' => '/books/list.rss',
- 'REQUEST_METHOD' => 'HEAD'
+ "PATH_INFO" => "/books/list.rss",
+ "REQUEST_METHOD" => "HEAD"
)
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
@@ -428,13 +426,13 @@ module ActionDispatch
end
def test_recognize_head_request_as_get_route
- mapper.get "/books(/:action(.:format))", to: 'foo#bar'
+ get "/books(/:action(.:format))", to: "foo#bar"
- env = rails_env 'PATH_INFO' => '/books/list.rss',
- "REQUEST_METHOD" => "HEAD"
+ env = rails_env "PATH_INFO" => "/books/list.rss",
+ "REQUEST_METHOD" => "HEAD"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
@@ -442,13 +440,13 @@ module ActionDispatch
end
def test_recognize_cares_about_get_verbs
- mapper.match "/books(/:action(.:format))", to: "foo#bar", via: :get
+ match "/books(/:action(.:format))", to: "foo#bar", via: :get
- env = rails_env 'PATH_INFO' => '/books/list.rss',
+ env = rails_env "PATH_INFO" => "/books/list.rss",
"REQUEST_METHOD" => "POST"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
@@ -456,13 +454,13 @@ module ActionDispatch
end
def test_recognize_cares_about_post_verbs
- mapper.match "/books(/:action(.:format))", to: "foo#bar", via: :post
+ match "/books(/:action(.:format))", to: "foo#bar", via: :post
- env = rails_env 'PATH_INFO' => '/books/list.rss',
+ env = rails_env "PATH_INFO" => "/books/list.rss",
"REQUEST_METHOD" => "POST"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
@@ -470,56 +468,77 @@ module ActionDispatch
end
def test_multi_verb_recognition
- mapper.match "/books(/:action(.:format))", to: "foo#bar", via: [:post, :get]
+ match "/books(/:action(.:format))", to: "foo#bar", via: [:post, :get]
%w( POST GET ).each do |verb|
- env = rails_env 'PATH_INFO' => '/books/list.rss',
+ env = rails_env "PATH_INFO" => "/books/list.rss",
"REQUEST_METHOD" => verb
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
assert called
end
- env = rails_env 'PATH_INFO' => '/books/list.rss',
- "REQUEST_METHOD" => 'PUT'
+ env = rails_env "PATH_INFO" => "/books/list.rss",
+ "REQUEST_METHOD" => "PUT"
called = false
- @router.recognize(env) do |r, params|
+ router.recognize(env) do |r, params|
called = true
end
assert_not called
end
- private
+ def test_eager_load_with_routes
+ get "/foo-bar", to: "foo#bar"
+ assert_nil router.eager_load!
+ end
- def rails_env env, klass = ActionDispatch::Request
- klass.new(rack_env(env))
- end
-
- def rack_env env
- {
- "rack.version" => [1, 1],
- "rack.input" => StringIO.new,
- "rack.errors" => StringIO.new,
- "rack.multithread" => true,
- "rack.multiprocess" => true,
- "rack.run_once" => false,
- "REQUEST_METHOD" => "GET",
- "SERVER_NAME" => "example.org",
- "SERVER_PORT" => "80",
- "QUERY_STRING" => "",
- "PATH_INFO" => "/content",
- "rack.url_scheme" => "http",
- "HTTPS" => "off",
- "SCRIPT_NAME" => "",
- "CONTENT_LENGTH" => "0"
- }.merge env
+ def test_eager_load_without_routes
+ assert_nil router.eager_load!
end
+
+ private
+
+ def get(*args)
+ ActiveSupport::Deprecation.silence do
+ mapper.get(*args)
+ end
+ end
+
+ def match(*args)
+ ActiveSupport::Deprecation.silence do
+ mapper.match(*args)
+ end
+ end
+
+ def rails_env(env, klass = ActionDispatch::Request)
+ klass.new(rack_env(env))
+ end
+
+ def rack_env(env)
+ {
+ "rack.version" => [1, 1],
+ "rack.input" => StringIO.new,
+ "rack.errors" => StringIO.new,
+ "rack.multithread" => true,
+ "rack.multiprocess" => true,
+ "rack.run_once" => false,
+ "REQUEST_METHOD" => "GET",
+ "SERVER_NAME" => "example.org",
+ "SERVER_PORT" => "80",
+ "QUERY_STRING" => "",
+ "PATH_INFO" => "/content",
+ "rack.url_scheme" => "http",
+ "HTTPS" => "off",
+ "SCRIPT_NAME" => "",
+ "CONTENT_LENGTH" => "0"
+ }.merge env
+ end
end
end
end
diff --git a/actionpack/test/journey/routes_test.rb b/actionpack/test/journey/routes_test.rb
index f8293dfc5f..d5c81a8421 100644
--- a/actionpack/test/journey/routes_test.rb
+++ b/actionpack/test/journey/routes_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Journey
@@ -6,7 +8,7 @@ module ActionDispatch
attr_reader :routes, :mapper
def setup
- @route_set = ActionDispatch::Routing::RouteSet.new
+ @route_set = ActionDispatch::Routing::RouteSet.new
@routes = @route_set.router.routes
@router = @route_set.router
@mapper = ActionDispatch::Routing::Mapper.new @route_set
@@ -14,45 +16,45 @@ module ActionDispatch
end
def test_clear
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'aaron'
- assert_not_predicate routes, :empty?
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "aaron"
+ assert_not_empty routes
assert_equal 1, routes.length
routes.clear
- assert routes.empty?
+ assert_empty routes
assert_equal 0, routes.length
end
def test_ast
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'aaron'
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "aaron"
ast = routes.ast
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'gorby'
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "gorby"
assert_not_equal ast, routes.ast
end
def test_simulator_changes
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'aaron'
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "aaron"
sim = routes.simulator
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'gorby'
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "gorby"
assert_not_equal sim, routes.simulator
end
def test_partition_route
- mapper.get "/foo(/:id)", to: "foo#bar", as: 'aaron'
+ mapper.get "/foo(/:id)", to: "foo#bar", as: "aaron"
assert_equal 1, @routes.anchored_routes.length
- assert_predicate @routes.custom_routes, :empty?
+ assert_empty @routes.custom_routes
- mapper.get "/hello/:who", to: "foo#bar", as: 'bar', who: /\d/
+ mapper.get "/hello/:who", to: "foo#bar", as: "bar", who: /\d/
assert_equal 1, @routes.custom_routes.length
assert_equal 1, @routes.anchored_routes.length
end
def test_first_name_wins
- mapper.get "/hello", to: "foo#bar", as: 'aaron'
+ mapper.get "/hello", to: "foo#bar", as: "aaron"
assert_raise(ArgumentError) do
- mapper.get "/aaron", to: "foo#bar", as: 'aaron'
+ mapper.get "/aaron", to: "foo#bar", as: "aaron"
end
end
end
diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb
index 1a2863b689..e985716f43 100644
--- a/actionpack/test/lib/controller/fake_controllers.rb
+++ b/actionpack/test/lib/controller/fake_controllers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class ContentController < ActionController::Base; end
module Admin
diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb
index ce9522d12a..01c7ec26ae 100644
--- a/actionpack/test/lib/controller/fake_models.rb
+++ b/actionpack/test/lib/controller/fake_models.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
require "active_model"
-class Customer < Struct.new(:name, :id)
+Customer = Struct.new(:name, :id) do
extend ActiveModel::Naming
include ActiveModel::Conversion
undef_method :to_json
- def to_xml(options={})
+ def to_xml(options = {})
if options[:builder]
options[:builder].name name
else
@@ -14,7 +16,7 @@ class Customer < Struct.new(:name, :id)
end
end
- def to_js(options={})
+ def to_js(options = {})
"name: #{name.inspect}"
end
alias :to_text :to_js
@@ -26,9 +28,13 @@ class Customer < Struct.new(:name, :id)
def persisted?
id.present?
end
+
+ def cache_key
+ "#{name}/#{id}"
+ end
end
-class Post < Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost)
+Post = Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) do
extend ActiveModel::Naming
include ActiveModel::Conversion
extend ActiveModel::Translation
diff --git a/actionpack/test/routing/helper_test.rb b/actionpack/test/routing/helper_test.rb
index 0028aaa629..d13b043b0b 100644
--- a/actionpack/test/routing/helper_test.rb
+++ b/actionpack/test/routing/helper_test.rb
@@ -1,4 +1,6 @@
-require 'abstract_unit'
+# frozen_string_literal: true
+
+require "abstract_unit"
module ActionDispatch
module Routing
diff --git a/actionpack/test/tmp/.gitignore b/actionpack/test/tmp/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/actionpack/test/tmp/.gitignore
+++ /dev/null