aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test/dispatch')
-rw-r--r--actionpack/test/dispatch/cookies_test.rb154
-rw-r--r--actionpack/test/dispatch/debug_exceptions_test.rb6
-rw-r--r--actionpack/test/dispatch/mime_type_test.rb2
-rw-r--r--actionpack/test/dispatch/mount_test.rb2
-rw-r--r--actionpack/test/dispatch/routing_test.rb139
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb3
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb6
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb41
8 files changed, 323 insertions, 30 deletions
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index 5ada5a7603..91ac13e7c6 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -1,6 +1,14 @@
require 'abstract_unit'
-# FIXME remove DummyKeyGenerator and this require in 4.1
+
+begin
+ require 'openssl'
+ OpenSSL::PKCS5
+rescue LoadError, NameError
+ $stderr.puts "Skipping KeyGenerator test: broken OpenSSL install"
+else
+
require 'active_support/key_generator'
+require 'active_support/message_verifier'
class CookiesTest < ActionController::TestCase
class TestController < ActionController::Base
@@ -67,11 +75,21 @@ class CookiesTest < ActionController::TestCase
head :ok
end
+ def get_signed_cookie
+ cookies.signed[:user_id]
+ head :ok
+ end
+
def set_encrypted_cookie
cookies.encrypted[:foo] = 'bar'
head :ok
end
+ def get_encrypted_cookie
+ cookies.encrypted[:foo]
+ head :ok
+ end
+
def set_invalid_encrypted_cookie
cookies[:invalid_cookie] = 'invalid--9170e00a57cfc27083363b5c75b835e477bd90cf'
head :ok
@@ -330,12 +348,17 @@ class CookiesTest < ActionController::TestCase
assert response.headers["Set-Cookie"] =~ /user_name=david/
end
- def test_permanent_cookie
+ def test_set_permanent_cookie
get :set_permanent_cookie
assert_match(/Jamie/, @response.headers["Set-Cookie"])
assert_match(%r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"])
end
+ def test_read_permanent_cookie
+ get :set_permanent_cookie
+ assert_equal 'Jamie', @controller.send(:cookies).permanent[:user_name]
+ end
+
def test_signed_cookie
get :set_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
@@ -394,33 +417,148 @@ class CookiesTest < ActionController::TestCase
def test_raises_argument_error_if_missing_secret
assert_raise(ArgumentError, nil.inspect) {
- @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new(nil)
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new(nil)
get :set_signed_cookie
}
assert_raise(ArgumentError, ''.inspect) {
- @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new("")
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("")
get :set_signed_cookie
}
end
def test_raises_argument_error_if_secret_is_probably_insecure
assert_raise(ArgumentError, "password".inspect) {
- @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new("password")
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("password")
get :set_signed_cookie
}
assert_raise(ArgumentError, "secret".inspect) {
- @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new("secret")
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("secret")
get :set_signed_cookie
}
assert_raise(ArgumentError, "12345678901234567890123456789".inspect) {
- @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new("12345678901234567890123456789")
+ @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("12345678901234567890123456789")
get :set_signed_cookie
}
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)
+
+ @request.headers["Cookie"] = "user_id=#{legacy_value}"
+ 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)
+ assert_equal 45, verifier.verify(@response.cookies["user_id"])
+ end
+
+ 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')
+
+ @request.headers["Cookie"] = "foo=#{legacy_value}"
+ get :get_encrypted_cookie
+
+ 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"])
+ 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"]
+ 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"]
+ end
+
def test_cookie_with_all_domain_option
get :set_cookie_with_domain
assert_response :success
@@ -669,3 +807,5 @@ class CookiesTest < ActionController::TestCase
end
end
end
+
+end
diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb
index 6035f0361e..ff0baccd76 100644
--- a/actionpack/test/dispatch/debug_exceptions_test.rb
+++ b/actionpack/test/dispatch/debug_exceptions_test.rb
@@ -29,6 +29,8 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
raise RuntimeError
when "/method_not_allowed"
raise ActionController::MethodNotAllowed
+ when "/unknown_http_method"
+ raise ActionController::UnknownHttpMethod
when "/not_implemented"
raise ActionController::NotImplemented
when "/unprocessable_entity"
@@ -113,6 +115,10 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_response 405
assert_match(/ActionController::MethodNotAllowed/, body)
+ get "/unknown_http_method", {}, {'action_dispatch.show_exceptions' => true}
+ assert_response 405
+ assert_match(/ActionController::UnknownHttpMethod/, body)
+
get "/bad_request", {}, {'action_dispatch.show_exceptions' => true}
assert_response 400
assert_match(/ActionController::BadRequest/, body)
diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb
index e2a9ba782d..6a2eb7da9f 100644
--- a/actionpack/test/dispatch/mime_type_test.rb
+++ b/actionpack/test/dispatch/mime_type_test.rb
@@ -75,7 +75,7 @@ class MimeTypeTest < ActiveSupport::TestCase
assert_equal expect, Mime::Type.parse(accept)
end
- test "parse arbitarry media type parameters" do
+ test "parse arbitrary media type parameters" do
accept = 'multipart/form-data; boundary="simple boundary"'
expect = [Mime::MULTIPART_FORM]
assert_equal expect, Mime::Type.parse(accept)
diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb
index 3b008fdff0..e5e28c28be 100644
--- a/actionpack/test/dispatch/mount_test.rb
+++ b/actionpack/test/dispatch/mount_test.rb
@@ -21,7 +21,7 @@ class TestRoutingMount < ActionDispatch::IntegrationTest
mount SprocketsApp, :at => "/sprockets"
mount SprocketsApp => "/shorthand"
- mount FakeEngine, :at => "/fakeengine"
+ mount FakeEngine, :at => "/fakeengine", :as => :fake
mount FakeEngine, :at => "/getfake", :via => :get
scope "/its_a" do
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 2bf7056ff7..5b42ca0f21 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -1102,6 +1102,57 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal 'projects#index', @response.body
end
+ def test_scope_with_format_option
+ draw do
+ get "direct/index", as: :no_format_direct, format: false
+
+ scope format: false do
+ get "scoped/index", as: :no_format_scoped
+ end
+ end
+
+ assert_equal "/direct/index", no_format_direct_path
+ assert_equal "/direct/index?format=html", no_format_direct_path(format: "html")
+
+ assert_equal "/scoped/index", no_format_scoped_path
+ assert_equal "/scoped/index?format=html", no_format_scoped_path(format: "html")
+
+ get '/scoped/index'
+ assert_equal "scoped#index", @response.body
+
+ get '/scoped/index.html'
+ assert_equal "Not Found", @response.body
+ end
+
+ def test_resources_with_format_false_from_scope
+ draw do
+ scope format: false do
+ resources :posts
+ resource :user
+ end
+ end
+
+ get "/posts"
+ assert_response :success
+ assert_equal "posts#index", @response.body
+ assert_equal "/posts", posts_path
+
+ get "/posts.html"
+ assert_response :not_found
+ assert_equal "Not Found", @response.body
+ assert_equal "/posts?format=html", posts_path(format: "html")
+
+ get "/user"
+ assert_response :success
+ assert_equal "users#show", @response.body
+ assert_equal "/user", user_path
+
+ get "/user.html"
+ assert_response :not_found
+ assert_equal "Not Found", @response.body
+ assert_equal "/user?format=html", user_path(format: "html")
+ end
+
def test_index
draw do
get '/info' => 'projects#info', :as => 'info'
@@ -1112,6 +1163,21 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
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'
+ end
+
+ get '/get/first'
+ assert_equal 'get#show', @response.body
+
+ get '/get/second'
+ 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'
@@ -1134,6 +1200,20 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal 'account#shorthand', @response.body
end
+ def test_match_shorthand_with_multiple_paths_inside_namespace
+ draw do
+ namespace :proposals do
+ put 'activate', 'inactivate'
+ end
+ end
+
+ put '/proposals/activate'
+ assert_equal 'proposals#activate', @response.body
+
+ put '/proposals/inactivate'
+ assert_equal 'proposals#inactivate', @response.body
+ end
+
def test_match_shorthand_inside_namespace_with_controller
draw do
namespace :api do
@@ -2577,22 +2657,6 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_raises(ActionController::UrlGenerationError){ list_todo_path(:list_id => '2', :id => '1') }
end
- def test_named_routes_collision_is_avoided_unless_explicitly_given_as
- 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
-
- get "/fc/:id", :as => :forced_collision, :to => "forced_collision#show"
- get "/forced_collision", :as => :forced_collision, :to => "forced_collision#show"
- end
- end
-
- assert_equal "/c/1", routes_collision_path(1)
- assert_equal "/fc/1", routes_forced_collision_path(1)
- end
-
def test_redirect_argument_error
routes = Class.new { include ActionDispatch::Routing::Redirection }.new
assert_raises(ArgumentError) { routes.redirect Object.new }
@@ -2604,9 +2668,6 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get "/c/:id", :as => :collision, :to => "collision#show"
get "/collision", :to => "collision#show"
get "/no_collision", :to => "collision#show", :as => nil
-
- get "/fc/:id", :as => :forced_collision, :to => "forced_collision#show"
- get "/forced_collision", :as => :forced_collision, :to => "forced_collision#show"
end
end
@@ -2657,6 +2718,24 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
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'
+ end
+ end
+ end
+
+ def test_duplicate_route_name_via_resources_raises_error
+ assert_raise(ArgumentError) do
+ draw do
+ resources :collisions
+ 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
@@ -3272,6 +3351,10 @@ class TestUrlConstraints < ActionDispatch::IntegrationTest
end
get '/' => ok, :as => :alternate_root, :constraints => { :port => 8080 }
+
+ get '/search' => ok, :constraints => { :subdomain => false }
+
+ get '/logs' => ok, :constraints => { :subdomain => true }
end
end
@@ -3298,6 +3381,24 @@ class TestUrlConstraints < ActionDispatch::IntegrationTest
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'
+ assert_response :success
+ assert_equal 'http://example.com/search', search_url
+
+ 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'
+ assert_response :success
+ assert_equal 'http://api.example.com/logs', logs_url
+
+ get 'http://example.com/logs'
+ assert_response :not_found
+ end
end
class TestInvalidUrls < ActionDispatch::IntegrationTest
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index d8bf22dec8..e99ff46edf 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -1,12 +1,11 @@
require 'abstract_unit'
require 'stringio'
-# FIXME remove DummyKeyGenerator and this require in 4.1
require 'active_support/key_generator'
class CookieStoreTest < ActionDispatch::IntegrationTest
SessionKey = '_myapp_session'
SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33'
- Generator = ActiveSupport::DummyKeyGenerator.new(SessionSecret)
+ Generator = ActiveSupport::LegacyKeyGenerator.new(SessionSecret)
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, :digest => 'SHA1')
SignedBar = Verifier.generate(:foo => "bar", :session_id => SecureRandom.hex(16))
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index 900f45ee5e..38bd234f37 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -12,6 +12,8 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
raise ActionDispatch::ParamsParser::ParseError.new("", StandardError.new)
when "/method_not_allowed"
raise ActionController::MethodNotAllowed
+ when "/unknown_http_method"
+ raise ActionController::UnknownHttpMethod
when "/not_found_original_exception"
raise ActionView::Template::Error.new('template', AbstractController::ActionNotFound.new)
else
@@ -47,6 +49,10 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
get "/method_not_allowed", {}, {'action_dispatch.show_exceptions' => true}
assert_response 405
assert_equal "", body
+
+ get "/unknown_http_method", {}, {'action_dispatch.show_exceptions' => true}
+ assert_response 405
+ assert_equal "", body
end
test "localize rescue error page" do
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index 4123529092..f919592d24 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -56,6 +56,47 @@ module TestUrlGeneration
test "formatting host when protocol is present" do
assert_equal "http://www.example.com/foo", foo_url(host: "httpz://www.example.com", protocol: "http://")
end
+
+ test "default ports are removed from the host" do
+ assert_equal "http://www.example.com/foo", foo_url(host: "www.example.com:80", protocol: "http://")
+ assert_equal "https://www.example.com/foo", foo_url(host: "www.example.com:443", protocol: "https://")
+ end
+
+ test "port is extracted from the host" do
+ assert_equal "http://www.example.com:8080/foo", foo_url(host: "www.example.com:8080", protocol: "http://")
+ end
+
+ test "port option overides the host" do
+ assert_equal "http://www.example.com:8080/foo", foo_url(host: "www.example.com:8443", protocol: "http://", port: 8080)
+ end
+
+ test "port option disables the host when set to nil" do
+ assert_equal "http://www.example.com/foo", foo_url(host: "www.example.com:8443", protocol: "http://", port: nil)
+ end
+
+ test "port option disables the host when set to false" do
+ assert_equal "http://www.example.com/foo", foo_url(host: "www.example.com:8443", protocol: "http://", port: false)
+ end
+
+ test "keep subdomain when key is true" do
+ assert_equal "http://www.example.com/foo", foo_url(subdomain: true)
+ end
+
+ test "keep subdomain when key is missing" do
+ assert_equal "http://www.example.com/foo", foo_url
+ end
+
+ test "omit subdomain when key is nil" do
+ assert_equal "http://example.com/foo", foo_url(subdomain: nil)
+ end
+
+ test "omit subdomain when key is false" do
+ assert_equal "http://example.com/foo", foo_url(subdomain: false)
+ end
+
+ test "omit subdomain when key is blank" do
+ assert_equal "http://example.com/foo", foo_url(subdomain: "")
+ end
end
end