diff options
Diffstat (limited to 'actionpack/test/controller')
36 files changed, 958 insertions, 458 deletions
diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index 580604df3a..f07d201563 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -56,13 +56,16 @@ class AssertSelectTest < ActionController::TestCase def setup super + @old_delivery_method = ActionMailer::Base.delivery_method + @old_perform_deliveries = ActionMailer::Base.perform_deliveries ActionMailer::Base.delivery_method = :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] end def teardown super + ActionMailer::Base.delivery_method = @old_delivery_method + ActionMailer::Base.perform_deliveries = @old_perform_deliveries ActionMailer::Base.deliveries.clear end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 58a86ce9af..c0e6a2ebd1 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -227,6 +227,22 @@ CACHED @store.read("views/test.host/functional_caching/inline_fragment_cached/#{template_digest("functional_caching/inline_fragment_cached")}")) end + def test_fragment_cache_instrumentation + payload = nil + + subscriber = proc do |*args| + event = ActiveSupport::Notifications::Event.new(*args) + payload = event.payload + end + + ActiveSupport::Notifications.subscribed(subscriber, "read_fragment.action_controller") do + get :inline_fragment_cached + end + + assert_equal "functional_caching", payload[:controller] + assert_equal "inline_fragment_cached", payload[:action] + end + def test_html_formatted_fragment_caching get :formatted_fragment_cached, :format => "html" assert_response :success diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index 03d5d27cf4..89667df3a4 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -68,12 +68,11 @@ class ContentTypeTest < ActionController::TestCase end def test_render_changed_charset_default - ActionDispatch::Response.default_charset = "utf-16" - get :render_defaults - assert_equal "utf-16", @response.charset - assert_equal Mime::HTML, @response.content_type - ensure - ActionDispatch::Response.default_charset = "utf-8" + with_default_charset "utf-16" do + get :render_defaults + assert_equal "utf-16", @response.charset + assert_equal Mime::HTML, @response.content_type + end end # :ported: @@ -105,12 +104,11 @@ class ContentTypeTest < ActionController::TestCase end def test_nil_default_for_erb - ActionDispatch::Response.default_charset = nil - get :render_default_for_erb - assert_equal Mime::HTML, @response.content_type - assert_nil @response.charset, @response.headers.inspect - ensure - ActionDispatch::Response.default_charset = "utf-8" + with_default_charset nil do + get :render_default_for_erb + assert_equal Mime::HTML, @response.content_type + assert_nil @response.charset, @response.headers.inspect + end end def test_default_for_erb @@ -130,6 +128,16 @@ class ContentTypeTest < ActionController::TestCase assert_equal Mime::HTML, @response.content_type assert_equal "utf-8", @response.charset end + + 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 end class AcceptBasedContentTypeTest < ActionController::TestCase diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index c87494aa64..b2b01b3fa9 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -2,13 +2,13 @@ require 'abstract_unit' class ActionController::Base class << self - %w(append_around_filter prepend_after_filter prepend_around_filter prepend_before_filter skip_after_filter skip_before_filter skip_filter).each do |pending| + %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| define_method(pending) do |*args| $stderr.puts "#{pending} unimplemented: #{args.inspect}" end unless method_defined?(pending) end - def before_filters + def before_actions filters = _process_action_callbacks.select { |c| c.kind == :before } filters.map! { |c| c.raw_filter } end @@ -28,8 +28,8 @@ end class FilterTest < ActionController::TestCase class TestController < ActionController::Base - before_filter :ensure_login - after_filter :clean_up + before_action :ensure_login + after_action :clean_up def show render :inline => "ran action" @@ -42,13 +42,13 @@ class FilterTest < ActionController::TestCase end def clean_up - @ran_after_filter ||= [] - @ran_after_filter << "clean_up" + @ran_after_action ||= [] + @ran_after_action << "clean_up" end end class ChangingTheRequirementsController < TestController - before_filter :ensure_login, :except => [:go_wild] + before_action :ensure_login, :except => [:go_wild] def go_wild render :text => "gobble" @@ -56,9 +56,9 @@ class FilterTest < ActionController::TestCase end class TestMultipleFiltersController < ActionController::Base - before_filter :try_1 - before_filter :try_2 - before_filter :try_3 + before_action :try_1 + before_action :try_2 + before_action :try_3 (1..3).each do |i| define_method "fail_#{i}" do @@ -78,8 +78,8 @@ class FilterTest < ActionController::TestCase end class RenderingController < ActionController::Base - before_filter :before_filter_rendering - after_filter :unreached_after_filter + before_action :before_action_rendering + after_action :unreached_after_action def show @ran_action = true @@ -87,29 +87,29 @@ class FilterTest < ActionController::TestCase end private - def before_filter_rendering + def before_action_rendering @ran_filter ||= [] - @ran_filter << "before_filter_rendering" + @ran_filter << "before_action_rendering" render :inline => "something else" end - def unreached_after_filter - @ran_filter << "unreached_after_filter_after_render" + def unreached_after_action + @ran_filter << "unreached_after_action_after_render" end end - class RenderingForPrependAfterFilterController < RenderingController - prepend_after_filter :unreached_prepend_after_filter + class RenderingForPrependAfterActionController < RenderingController + prepend_after_action :unreached_prepend_after_action private - def unreached_prepend_after_filter - @ran_filter << "unreached_preprend_after_filter_after_render" + def unreached_prepend_after_action + @ran_filter << "unreached_preprend_after_action_after_render" end end - class BeforeFilterRedirectionController < ActionController::Base - before_filter :before_filter_redirects - after_filter :unreached_after_filter + class BeforeActionRedirectionController < ActionController::Base + before_action :before_action_redirects + after_action :unreached_after_action def show @ran_action = true @@ -122,23 +122,23 @@ class FilterTest < ActionController::TestCase end private - def before_filter_redirects + def before_action_redirects @ran_filter ||= [] - @ran_filter << "before_filter_redirects" + @ran_filter << "before_action_redirects" redirect_to(:action => 'target_of_redirection') end - def unreached_after_filter - @ran_filter << "unreached_after_filter_after_redirection" + def unreached_after_action + @ran_filter << "unreached_after_action_after_redirection" end end - class BeforeFilterRedirectionForPrependAfterFilterController < BeforeFilterRedirectionController - prepend_after_filter :unreached_prepend_after_filter_after_redirection + class BeforeActionRedirectionForPrependAfterActionController < BeforeActionRedirectionController + prepend_after_action :unreached_prepend_after_action_after_redirection private - def unreached_prepend_after_filter_after_redirection - @ran_filter << "unreached_prepend_after_filter_after_redirection" + def unreached_prepend_after_action_after_redirection + @ran_filter << "unreached_prepend_after_action_after_redirection" end end @@ -151,8 +151,8 @@ class FilterTest < ActionController::TestCase render :inline => "ran action" end - def show_without_filter - render :inline => "ran action without filter" + def show_without_action + render :inline => "ran action without action" end private @@ -168,70 +168,70 @@ class FilterTest < ActionController::TestCase end class ConditionalCollectionFilterController < ConditionalFilterController - before_filter :ensure_login, :except => [ :show_without_filter, :another_action ] + before_action :ensure_login, :except => [ :show_without_action, :another_action ] end class OnlyConditionSymController < ConditionalFilterController - before_filter :ensure_login, :only => :show + before_action :ensure_login, :only => :show end class ExceptConditionSymController < ConditionalFilterController - before_filter :ensure_login, :except => :show_without_filter + before_action :ensure_login, :except => :show_without_action end class BeforeAndAfterConditionController < ConditionalFilterController - before_filter :ensure_login, :only => :show - after_filter :clean_up_tmp, :only => :show + before_action :ensure_login, :only => :show + after_action :clean_up_tmp, :only => :show end class OnlyConditionProcController < ConditionalFilterController - before_filter(:only => :show) {|c| c.instance_variable_set(:"@ran_proc_filter", true) } + before_action(:only => :show) {|c| c.instance_variable_set(:"@ran_proc_action", true) } end class ExceptConditionProcController < ConditionalFilterController - before_filter(:except => :show_without_filter) {|c| c.instance_variable_set(:"@ran_proc_filter", true) } + before_action(:except => :show_without_action) {|c| c.instance_variable_set(:"@ran_proc_action", true) } end class ConditionalClassFilter - def self.before(controller) controller.instance_variable_set(:"@ran_class_filter", true) end + def self.before(controller) controller.instance_variable_set(:"@ran_class_action", true) end end class OnlyConditionClassController < ConditionalFilterController - before_filter ConditionalClassFilter, :only => :show + before_action ConditionalClassFilter, :only => :show end class ExceptConditionClassController < ConditionalFilterController - before_filter ConditionalClassFilter, :except => :show_without_filter + before_action ConditionalClassFilter, :except => :show_without_action end class AnomolousYetValidConditionController < ConditionalFilterController - before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:"@ran_proc_filter1", true)}, :except => :show_without_filter) { |c| c.instance_variable_set(:"@ran_proc_filter2", 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_filter :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_filter :ensure_login, :if => Proc.new { |c| true } - before_filter :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 - before_filter :ensure_login - before_filter :clean_up_tmp + before_action :ensure_login + before_action :clean_up_tmp - skip_before_filter :ensure_login, if: -> { false } - skip_before_filter :clean_up_tmp, if: -> { true } + skip_before_action :ensure_login, if: -> { false } + skip_before_action :clean_up_tmp, if: -> { true } end class ClassController < ConditionalFilterController - before_filter ConditionalClassFilter + before_action ConditionalClassFilter end class PrependingController < TestController - prepend_before_filter :wonderful_life - # skip_before_filter :fire_flash + prepend_before_action :wonderful_life + # skip_before_action :fire_flash private def wonderful_life @@ -241,8 +241,8 @@ class FilterTest < ActionController::TestCase end class SkippingAndLimitedController < TestController - skip_before_filter :ensure_login - before_filter :ensure_login, :only => :index + skip_before_action :ensure_login + before_action :ensure_login, :only => :index def index render :text => 'ok' @@ -254,9 +254,9 @@ class FilterTest < ActionController::TestCase end class SkippingAndReorderingController < TestController - skip_before_filter :ensure_login - before_filter :find_record - before_filter :ensure_login + skip_before_action :ensure_login + before_action :find_record + before_action :ensure_login def index render :text => 'ok' @@ -270,10 +270,10 @@ class FilterTest < ActionController::TestCase end class ConditionalSkippingController < TestController - skip_before_filter :ensure_login, :only => [ :login ] - skip_after_filter :clean_up, :only => [ :login ] + skip_before_action :ensure_login, :only => [ :login ] + skip_after_action :clean_up, :only => [ :login ] - before_filter :find_user, :only => [ :change_password ] + before_action :find_user, :only => [ :change_password ] def login render :inline => "ran action" @@ -291,8 +291,8 @@ class FilterTest < ActionController::TestCase end class ConditionalParentOfConditionalSkippingController < ConditionalFilterController - before_filter :conditional_in_parent_before, :only => [:show, :another_action] - after_filter :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 @@ -308,20 +308,20 @@ class FilterTest < ActionController::TestCase end class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController - skip_before_filter :conditional_in_parent_before, :only => :another_action - skip_after_filter :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_filter :conditional_in_parent_before, :only => :show + skip_before_action :conditional_in_parent_before, :only => :show end class ProcController < PrependingController - before_filter(proc { |c| c.instance_variable_set(:"@ran_proc_filter", true) }) + before_action(proc { |c| c.instance_variable_set(:"@ran_proc_action", true) }) end class ImplicitProcController < PrependingController - before_filter { |c| c.instance_variable_set(:"@ran_proc_filter", true) } + before_action { |c| c.instance_variable_set(:"@ran_proc_action", true) } end class AuditFilter @@ -367,7 +367,7 @@ class FilterTest < ActionController::TestCase end class AuditController < ActionController::Base - before_filter(AuditFilter) + before_action(AuditFilter) def show render :text => "hello" @@ -375,14 +375,14 @@ class FilterTest < ActionController::TestCase end class AroundFilterController < PrependingController - around_filter AroundFilter.new + around_action AroundFilter.new end class BeforeAfterClassFilterController < PrependingController begin filter = AroundFilter.new - before_filter filter - after_filter filter + before_action filter + after_action filter end end @@ -394,18 +394,18 @@ class FilterTest < ActionController::TestCase super() end - before_filter { |c| c.class.execution_log << " before procfilter " } - prepend_around_filter AroundFilter.new + before_action { |c| c.class.execution_log << " before procfilter " } + prepend_around_action AroundFilter.new - after_filter { |c| c.class.execution_log << " after procfilter " } - append_around_filter AppendedAroundFilter.new + after_action { |c| c.class.execution_log << " after procfilter " } + append_around_action AppendedAroundFilter.new end class MixedSpecializationController < ActionController::Base class OutOfOrder < StandardError; end - before_filter :first - before_filter :second, :only => :foo + before_action :first + before_action :second, :only => :foo def foo render :text => 'foo' @@ -426,7 +426,7 @@ class FilterTest < ActionController::TestCase end class DynamicDispatchController < ActionController::Base - before_filter :choose + before_action :choose %w(foo bar baz).each do |action| define_method(action) { render :text => action } @@ -439,9 +439,9 @@ class FilterTest < ActionController::TestCase end class PrependingBeforeAndAfterController < ActionController::Base - prepend_before_filter :before_all - prepend_after_filter :after_all - before_filter :between_before_all_and_after_all + prepend_before_action :before_all + prepend_after_action :after_all + before_action :between_before_all_and_after_all def before_all @ran_filter ||= [] @@ -473,7 +473,7 @@ class FilterTest < ActionController::TestCase end class RescuedController < ActionController::Base - around_filter RescuingAroundFilterWithBlock.new + around_action RescuingAroundFilterWithBlock.new def show raise ErrorToRescue.new("Something made the bad noise.") @@ -482,10 +482,10 @@ class FilterTest < ActionController::TestCase class NonYieldingAroundFilterController < ActionController::Base - before_filter :filter_one - around_filter :non_yielding_filter - before_filter :filter_two - after_filter :filter_three + before_action :filter_one + around_action :non_yielding_action + before_action :action_two + after_action :action_three def index render :inline => "index" @@ -498,24 +498,24 @@ class FilterTest < ActionController::TestCase @filters << "filter_one" end - def filter_two - @filters << "filter_two" + def action_two + @filters << "action_two" end - def non_yielding_filter + def non_yielding_action @filters << "it didn't yield" @filter_return_value end - def filter_three - @filters << "filter_three" + def action_three + @filters << "action_three" end end class ImplicitActionsController < ActionController::Base - before_filter :find_only, :only => :edit - before_filter :find_except, :except => :edit + before_action :find_only, :only => :edit + before_action :find_except, :except => :edit private @@ -528,7 +528,7 @@ class FilterTest < ActionController::TestCase end end - def test_non_yielding_around_filters_not_returning_false_do_not_raise + def test_non_yielding_around_actions_not_returning_false_do_not_raise controller = NonYieldingAroundFilterController.new controller.instance_variable_set "@filter_return_value", true assert_nothing_raised do @@ -536,7 +536,7 @@ class FilterTest < ActionController::TestCase end end - def test_non_yielding_around_filters_returning_false_do_not_raise + def test_non_yielding_around_actions_returning_false_do_not_raise controller = NonYieldingAroundFilterController.new controller.instance_variable_set "@filter_return_value", false assert_nothing_raised do @@ -544,64 +544,64 @@ class FilterTest < ActionController::TestCase end end - def test_after_filters_are_not_run_if_around_filter_returns_false + def test_after_actions_are_not_run_if_around_action_returns_false controller = NonYieldingAroundFilterController.new controller.instance_variable_set "@filter_return_value", false test_process(controller, "index") assert_equal ["filter_one", "it didn't yield"], controller.assigns['filters'] end - def test_after_filters_are_not_run_if_around_filter_does_not_yield + def test_after_actions_are_not_run_if_around_action_does_not_yield controller = NonYieldingAroundFilterController.new controller.instance_variable_set "@filter_return_value", true test_process(controller, "index") assert_equal ["filter_one", "it didn't yield"], controller.assigns['filters'] end - def test_added_filter_to_inheritance_graph - assert_equal [ :ensure_login ], TestController.before_filters + def test_added_action_to_inheritance_graph + assert_equal [ :ensure_login ], TestController.before_actions end def test_base_class_in_isolation - assert_equal [ ], ActionController::Base.before_filters + assert_equal [ ], ActionController::Base.before_actions end - def test_prepending_filter - assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters + def test_prepending_action + assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_actions end - def test_running_filters + def test_running_actions test_process(PrependingController) assert_equal %w( wonderful_life ensure_login ), assigns["ran_filter"] end - def test_running_filters_with_proc + def test_running_actions_with_proc test_process(ProcController) - assert assigns["ran_proc_filter"] + assert assigns["ran_proc_action"] end - def test_running_filters_with_implicit_proc + def test_running_actions_with_implicit_proc test_process(ImplicitProcController) - assert assigns["ran_proc_filter"] + assert assigns["ran_proc_action"] end - def test_running_filters_with_class + def test_running_actions_with_class test_process(AuditController) assert assigns["was_audited"] end - def test_running_anomolous_yet_valid_condition_filters + def test_running_anomolous_yet_valid_condition_actions test_process(AnomolousYetValidConditionController) assert_equal %w( ensure_login ), assigns["ran_filter"] - assert assigns["ran_class_filter"] - assert assigns["ran_proc_filter1"] - assert assigns["ran_proc_filter2"] + assert assigns["ran_class_action"] + assert assigns["ran_proc_action1"] + assert assigns["ran_proc_action2"] - test_process(AnomolousYetValidConditionController, "show_without_filter") + test_process(AnomolousYetValidConditionController, "show_without_action") assert_nil assigns["ran_filter"] - assert !assigns["ran_class_filter"] - assert !assigns["ran_proc_filter1"] - assert !assigns["ran_proc_filter2"] + assert !assigns["ran_class_action"] + assert !assigns["ran_proc_action1"] + assert !assigns["ran_proc_action2"] end def test_running_conditional_options @@ -614,59 +614,59 @@ class FilterTest < ActionController::TestCase assert_equal %w( ensure_login ), assigns["ran_filter"] end - def test_skipping_class_filters + def test_skipping_class_actions test_process(ClassController) - assert_equal true, assigns["ran_class_filter"] + assert_equal true, assigns["ran_class_action"] skipping_class_controller = Class.new(ClassController) do - skip_before_filter ConditionalClassFilter + skip_before_action ConditionalClassFilter end test_process(skipping_class_controller) - assert_nil assigns['ran_class_filter'] + assert_nil assigns['ran_class_action'] end - def test_running_collection_condition_filters + def test_running_collection_condition_actions test_process(ConditionalCollectionFilterController) assert_equal %w( ensure_login ), assigns["ran_filter"] - test_process(ConditionalCollectionFilterController, "show_without_filter") + test_process(ConditionalCollectionFilterController, "show_without_action") assert_nil assigns["ran_filter"] test_process(ConditionalCollectionFilterController, "another_action") assert_nil assigns["ran_filter"] end - def test_running_only_condition_filters + def test_running_only_condition_actions test_process(OnlyConditionSymController) assert_equal %w( ensure_login ), assigns["ran_filter"] - test_process(OnlyConditionSymController, "show_without_filter") + test_process(OnlyConditionSymController, "show_without_action") assert_nil assigns["ran_filter"] test_process(OnlyConditionProcController) - assert assigns["ran_proc_filter"] - test_process(OnlyConditionProcController, "show_without_filter") - assert !assigns["ran_proc_filter"] + assert assigns["ran_proc_action"] + test_process(OnlyConditionProcController, "show_without_action") + assert !assigns["ran_proc_action"] test_process(OnlyConditionClassController) - assert assigns["ran_class_filter"] - test_process(OnlyConditionClassController, "show_without_filter") - assert !assigns["ran_class_filter"] + assert assigns["ran_class_action"] + test_process(OnlyConditionClassController, "show_without_action") + assert !assigns["ran_class_action"] end - def test_running_except_condition_filters + def test_running_except_condition_actions test_process(ExceptConditionSymController) assert_equal %w( ensure_login ), assigns["ran_filter"] - test_process(ExceptConditionSymController, "show_without_filter") + test_process(ExceptConditionSymController, "show_without_action") assert_nil assigns["ran_filter"] test_process(ExceptConditionProcController) - assert assigns["ran_proc_filter"] - test_process(ExceptConditionProcController, "show_without_filter") - assert !assigns["ran_proc_filter"] + assert assigns["ran_proc_action"] + test_process(ExceptConditionProcController, "show_without_action") + assert !assigns["ran_proc_action"] test_process(ExceptConditionClassController) - assert assigns["ran_class_filter"] - test_process(ExceptConditionClassController, "show_without_filter") - assert !assigns["ran_class_filter"] + assert assigns["ran_class_action"] + test_process(ExceptConditionClassController, "show_without_action") + assert !assigns["ran_class_action"] end def test_running_only_condition_and_conditional_options @@ -674,70 +674,70 @@ class FilterTest < ActionController::TestCase assert_not assigns["ran_conditional_index_proc"] end - def test_running_before_and_after_condition_filters + def test_running_before_and_after_condition_actions test_process(BeforeAndAfterConditionController) assert_equal %w( ensure_login clean_up_tmp), assigns["ran_filter"] - test_process(BeforeAndAfterConditionController, "show_without_filter") + test_process(BeforeAndAfterConditionController, "show_without_action") assert_nil assigns["ran_filter"] end - def test_around_filter + def test_around_action test_process(AroundFilterController) assert assigns["before_ran"] assert assigns["after_ran"] end - def test_before_after_class_filter + def test_before_after_class_action test_process(BeforeAfterClassFilterController) assert assigns["before_ran"] assert assigns["after_ran"] end - def test_having_properties_in_around_filter + def test_having_properties_in_around_action test_process(AroundFilterController) assert_equal "before and after", assigns["execution_log"] end - def test_prepending_and_appending_around_filter + def test_prepending_and_appending_around_action test_process(MixedFilterController) assert_equal " before aroundfilter before procfilter before appended aroundfilter " + " after appended aroundfilter after procfilter after aroundfilter ", MixedFilterController.execution_log end - def test_rendering_breaks_filtering_chain + def test_rendering_breaks_actioning_chain response = test_process(RenderingController) assert_equal "something else", response.body assert !assigns["ran_action"] end - def test_before_filter_rendering_breaks_filtering_chain_for_after_filter + def test_before_action_rendering_breaks_actioning_chain_for_after_action test_process(RenderingController) - assert_equal %w( before_filter_rendering ), assigns["ran_filter"] + assert_equal %w( before_action_rendering ), assigns["ran_filter"] assert !assigns["ran_action"] end - def test_before_filter_redirects_breaks_filtering_chain_for_after_filter - test_process(BeforeFilterRedirectionController) + def test_before_action_redirects_breaks_actioning_chain_for_after_action + test_process(BeforeActionRedirectionController) assert_response :redirect - assert_equal "http://test.host/filter_test/before_filter_redirection/target_of_redirection", redirect_to_url - assert_equal %w( before_filter_redirects ), assigns["ran_filter"] + assert_equal "http://test.host/filter_test/before_action_redirection/target_of_redirection", redirect_to_url + assert_equal %w( before_action_redirects ), assigns["ran_filter"] end - def test_before_filter_rendering_breaks_filtering_chain_for_preprend_after_filter - test_process(RenderingForPrependAfterFilterController) - assert_equal %w( before_filter_rendering ), assigns["ran_filter"] + def test_before_action_rendering_breaks_actioning_chain_for_preprend_after_action + test_process(RenderingForPrependAfterActionController) + assert_equal %w( before_action_rendering ), assigns["ran_filter"] assert !assigns["ran_action"] end - def test_before_filter_redirects_breaks_filtering_chain_for_preprend_after_filter - test_process(BeforeFilterRedirectionForPrependAfterFilterController) + def test_before_action_redirects_breaks_actioning_chain_for_preprend_after_action + test_process(BeforeActionRedirectionForPrependAfterActionController) assert_response :redirect - assert_equal "http://test.host/filter_test/before_filter_redirection_for_prepend_after_filter/target_of_redirection", redirect_to_url - assert_equal %w( before_filter_redirects ), assigns["ran_filter"] + assert_equal "http://test.host/filter_test/before_action_redirection_for_prepend_after_action/target_of_redirection", redirect_to_url + assert_equal %w( before_action_redirects ), assigns["ran_filter"] end - def test_filters_with_mixed_specialization_run_in_order + def test_actions_with_mixed_specialization_run_in_order assert_nothing_raised do response = test_process(MixedSpecializationController, 'bar') assert_equal 'bar', response.body @@ -758,7 +758,7 @@ class FilterTest < ActionController::TestCase end end - def test_running_prepended_before_and_after_filter + def test_running_prepended_before_and_after_action test_process(PrependingBeforeAndAfterController) assert_equal %w( before_all between_before_all_and_after_all after_all ), assigns["ran_filter"] end @@ -775,26 +775,26 @@ class FilterTest < ActionController::TestCase assert_equal %w( find_record ensure_login ), assigns["ran_filter"] end - def test_conditional_skipping_of_filters + def test_conditional_skipping_of_actions test_process(ConditionalSkippingController, "login") assert_nil assigns["ran_filter"] test_process(ConditionalSkippingController, "change_password") assert_equal %w( ensure_login find_user ), assigns["ran_filter"] test_process(ConditionalSkippingController, "login") - assert !@controller.instance_variable_defined?("@ran_after_filter") + assert !@controller.instance_variable_defined?("@ran_after_action") test_process(ConditionalSkippingController, "change_password") - assert_equal %w( clean_up ), @controller.instance_variable_get("@ran_after_filter") + assert_equal %w( clean_up ), @controller.instance_variable_get("@ran_after_action") end - def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional + 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 ), assigns['ran_filter'] test_process(ChildOfConditionalParentController, 'another_action') assert_nil assigns['ran_filter'] end - def test_condition_skipping_of_filters_when_siblings_also_have_conditions + def test_condition_skipping_of_actions_when_siblings_also_have_conditions test_process(ChildOfConditionalParentController) assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter'] test_process(AnotherChildOfConditionalParentController) @@ -808,7 +808,7 @@ class FilterTest < ActionController::TestCase assert_nil assigns['ran_filter'] end - def test_a_rescuing_around_filter + def test_a_rescuing_around_action response = nil assert_nothing_raised do response = test_process(RescuedController) @@ -818,7 +818,7 @@ class FilterTest < ActionController::TestCase assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body) end - def test_filters_obey_only_and_except_for_implicit_actions + def test_actions_obey_only_and_except_for_implicit_actions test_process(ImplicitActionsController, 'show') assert_equal 'Except', assigns(:except) assert_nil assigns(:only) @@ -852,7 +852,7 @@ class PostsController < ActionController::Base include AroundExceptions end - module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n") + module_eval %w(raises_before raises_after raises_both no_raise no_action).map { |action| "def #{action}; default_action end" }.join("\n") private def default_action @@ -861,9 +861,9 @@ class PostsController < ActionController::Base end class ControllerWithSymbolAsFilter < PostsController - around_filter :raise_before, :only => :raises_before - around_filter :raise_after, :only => :raises_after - around_filter :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 @@ -895,7 +895,7 @@ class ControllerWithFilterClass < PostsController end end - around_filter YieldingFilter, :only => :raises_after + around_action YieldingFilter, :only => :raises_after end class ControllerWithFilterInstance < PostsController @@ -906,11 +906,11 @@ class ControllerWithFilterInstance < PostsController end end - around_filter YieldingFilter.new, :only => :raises_after + around_action YieldingFilter.new, :only => :raises_after end class ControllerWithProcFilter < PostsController - around_filter(: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) @@ -918,14 +918,14 @@ class ControllerWithProcFilter < PostsController end class ControllerWithNestedFilters < ControllerWithSymbolAsFilter - around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both + around_action :raise_before, :raise_after, :without_exception, :only => :raises_both end class ControllerWithAllTypesOfFilters < PostsController - before_filter :before - around_filter :around - after_filter :after - around_filter :around_again + before_action :before + around_action :around + after_action :after + around_action :around_again private def before @@ -951,8 +951,8 @@ class ControllerWithAllTypesOfFilters < PostsController end class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters - skip_filter :around_again - skip_filter :after + skip_action_callback :around_again + skip_action_callback :after end class YieldingAroundFiltersTest < ActionController::TestCase @@ -963,7 +963,7 @@ class YieldingAroundFiltersTest < ActionController::TestCase 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_filter') } + assert_nothing_raised { test_process(controller,'no_action') } end def test_with_symbol @@ -992,7 +992,7 @@ class YieldingAroundFiltersTest < ActionController::TestCase assert assigns['after'] end - def test_nested_filters + def test_nested_actions controller = ControllerWithNestedFilters assert_nothing_raised do begin @@ -1008,31 +1008,31 @@ class YieldingAroundFiltersTest < ActionController::TestCase end end - def test_filter_order_with_all_filter_types + 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)', assigns['ran_filter'].join(' ') end - def test_filter_order_with_skip_filter_method + def test_action_order_with_skip_action_method test_process(ControllerWithTwoLessFilters,'no_raise') assert_equal 'before around (before yield) around (after yield)', assigns['ran_filter'].join(' ') end - def test_first_filter_in_multiple_before_filter_chain_halts + def test_first_action_in_multiple_before_action_chain_halts controller = ::FilterTest::TestMultipleFiltersController.new response = test_process(controller, 'fail_1') assert_equal ' ', response.body assert_equal 1, controller.instance_variable_get(:@try) end - def test_second_filter_in_multiple_before_filter_chain_halts + def test_second_action_in_multiple_before_action_chain_halts controller = ::FilterTest::TestMultipleFiltersController.new response = test_process(controller, 'fail_2') assert_equal ' ', response.body assert_equal 2, controller.instance_variable_get(:@try) end - def test_last_filter_in_multiple_before_filter_chain_halts + def test_last_action_in_multiple_before_action_chain_halts controller = ::FilterTest::TestMultipleFiltersController.new response = test_process(controller, 'fail_3') assert_equal ' ', response.body diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb index 3655b90e32..00d4612ac9 100644 --- a/actionpack/test/controller/force_ssl_test.rb +++ b/actionpack/test/controller/force_ssl_test.rb @@ -93,8 +93,6 @@ class RedirectToSSL < ForceSSLController end class ForceSSLControllerLevelTest < ActionController::TestCase - tests ForceSSLControllerLevel - def test_banana_redirects_to_https get :banana assert_response 301 @@ -115,8 +113,6 @@ class ForceSSLControllerLevelTest < ActionController::TestCase end class ForceSSLCustomOptionsTest < ActionController::TestCase - tests ForceSSLCustomOptions - def setup @request.env['HTTP_HOST'] = 'www.example.com:80' end @@ -189,8 +185,6 @@ class ForceSSLCustomOptionsTest < ActionController::TestCase end class ForceSSLOnlyActionTest < ActionController::TestCase - tests ForceSSLOnlyAction - def test_banana_not_redirects_to_https get :banana assert_response 200 @@ -204,8 +198,6 @@ class ForceSSLOnlyActionTest < ActionController::TestCase end class ForceSSLExceptActionTest < ActionController::TestCase - tests ForceSSLExceptAction - def test_banana_not_redirects_to_https get :banana assert_response 200 @@ -219,8 +211,6 @@ class ForceSSLExceptActionTest < ActionController::TestCase end class ForceSSLIfConditionTest < ActionController::TestCase - tests ForceSSLIfCondition - def test_banana_not_redirects_to_https get :banana assert_response 200 @@ -234,8 +224,6 @@ class ForceSSLIfConditionTest < ActionController::TestCase end class ForceSSLFlashTest < ActionController::TestCase - tests ForceSSLFlash - def test_cheeseburger_redirects_to_https get :set_flash assert_response 302 @@ -315,7 +303,6 @@ class ForceSSLOptionalSegmentsTest < ActionController::TestCase end class RedirectToSSLTest < ActionController::TestCase - tests RedirectToSSL def test_banana_redirects_to_https_if_not_https get :banana assert_response 301 @@ -334,4 +321,4 @@ class RedirectToSSLTest < ActionController::TestCase assert_response 200 assert_equal 'ihaz', response.body end -end
\ No newline at end of file +end diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb index 90548d4294..9052fc6962 100644 --- a/actionpack/test/controller/http_basic_authentication_test.rb +++ b/actionpack/test/controller/http_basic_authentication_test.rb @@ -129,6 +129,13 @@ class HttpBasicAuthenticationTest < ActionController::TestCase 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 + get :search + assert_response :unauthorized + end + private def encode_credentials(username, password) diff --git a/actionpack/test/controller/http_token_authentication_test.rb b/actionpack/test/controller/http_token_authentication_test.rb index 86b94652ce..8c6c8a0aa7 100644 --- a/actionpack/test/controller/http_token_authentication_test.rb +++ b/actionpack/test/controller/http_token_authentication_test.rb @@ -132,13 +132,50 @@ class HttpTokenAuthenticationTest < ActionController::TestCase assert_equal(expected, actual) end - private + test "token_and_options returns empty string with empty token" do + token = '' + actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token)).first + expected = token + assert_equal(expected, actual) + end - def sample_request(token) - @sample_request ||= OpenStruct.new authorization: %{Token token="#{token}"} + test "token_and_options returns correct token with nounce option" do + token = "rcHu+HzSFw89Ypyhn/896A=" + nonce_hash = {nonce: "123abc"} + actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token, nonce_hash)) + expected_token = token + expected_nonce = {"nonce" => nonce_hash[:nonce]} + assert_equal(expected_token, actual.first) + assert_equal(expected_nonce, actual.last) end - def encode_credentials(token, options = {}) - ActionController::HttpAuthentication::Token.encode_credentials(token, options) + test "token_and_options returns nil with no value after the equal sign" do + actual = ActionController::HttpAuthentication::Token.token_and_options(malformed_request).first + expected = nil + assert_equal(expected, actual) + end + + test "raw_params returns a tuple of two key value pair strings" do + auth = sample_request("rcHu+HzSFw89Ypyhn/896A=").authorization.to_s + actual = ActionController::HttpAuthentication::Token.raw_params(auth) + expected = ["token=\"rcHu+HzSFw89Ypyhn/896A=\"", "nonce=\"def\""] + assert_equal(expected, actual) end + + private + + def sample_request(token, options = {nonce: "def"}) + authorization = options.inject([%{Token token="#{token}"}]) do |arr, (k, v)| + arr << "#{k}=\"#{v}\"" + end.join(", ") + @sample_request ||= OpenStruct.new authorization: authorization + end + + def malformed_request + @malformed_request ||= OpenStruct.new authorization: %{Token token=} + end + + def encode_credentials(token, options = {}) + ActionController::HttpAuthentication::Token.encode_credentials(token, options) + end end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index e851cc6a63..78cce3aa64 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -1,6 +1,7 @@ require 'abstract_unit' require 'controller/fake_controllers' require 'action_view/vendor/html-scanner' +require 'rails/engine' class SessionTest < ActiveSupport::TestCase StubApp = lambda { |env| @@ -374,6 +375,10 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest follow_redirect! assert_response :success assert_equal "/get", path + + get '/moved' + assert_response :redirect + assert_redirected_to '/method' end end @@ -511,6 +516,8 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end set.draw do + get 'moved' => redirect('/method') + match ':action', :to => controller, :via => [:get, :post], :as => :action get 'get/:action', :to => controller, :as => :get_action end @@ -589,7 +596,7 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest @routes ||= ActionDispatch::Routing::RouteSet.new end - class MountedApp + class MountedApp < Rails::Engine def self.routes @routes ||= ActionDispatch::Routing::RouteSet.new end @@ -769,3 +776,34 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest assert_equal "/foo/1/edit", url_for(:action => 'edit', :only_path => true) end end + +class HeadWithStatusActionIntegrationTest < ActionDispatch::IntegrationTest + class FooController < ActionController::Base + def status + head :ok + end + end + + def self.routes + @routes ||= ActionDispatch::Routing::RouteSet.new + end + + def self.call(env) + routes.call(env) + end + + def app + self.class + end + + routes.draw do + 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' + end + assert_response :ok + end +end diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb index 947f64176b..0500b7c789 100644 --- a/actionpack/test/controller/live_stream_test.rb +++ b/actionpack/test/controller/live_stream_test.rb @@ -39,6 +39,13 @@ module ActionController ensure sse.close end + + def sse_with_multiple_line_message + sse = SSE.new(response.stream) + sse.write("first line.\nsecond line.") + ensure + sse.close + end end tests SSETestController @@ -87,6 +94,15 @@ module ActionController assert_match(/data: {\"name\":\"Ryan\"}/, second_response) assert_match(/id: 2/, second_response) end + + def test_sse_with_multiple_line_message + get :sse_with_multiple_line_message + + wait_for_response_stream_close + first_response, second_response = response.body.split("\n") + assert_match(/data: first line/, first_response) + assert_match(/data: second line/, second_response) + end end class LiveStreamTest < ActionController::TestCase @@ -186,6 +202,39 @@ module ActionController response.stream.write '' response.stream.write params[:widget][:didnt_check_for_nil] end + + def overfill_buffer_and_die + # 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 '.' + end + # .. plus one more, because the #each frees up a slot: + response.stream.write '.' + + latch.release + + # This write will block, and eventually raise + response.stream.write 'x' + + 20.times do + response.stream.write '.' + end + end + + def ignore_client_disconnect + response.stream.ignore_disconnect = true + + response.stream.write '' # commit + + # These writes will be ignored + 15.times do + response.stream.write 'x' + end + + logger.info 'Work complete' + latch.release + end end tests TestController @@ -248,6 +297,62 @@ module ActionController assert t.join(3), 'timeout expired before the thread terminated' end + def test_abort_with_full_buffer + @controller.latch = ActiveSupport::Concurrency::Latch.new + + @request.parameters[:format] = 'plain' + @controller.request = @request + @controller.response = @response + + got_error = ActiveSupport::Concurrency::Latch.new + @response.stream.on_error do + ActionController::Base.logger.warn 'Error while streaming' + got_error.release + end + + t = Thread.new(@response) { |resp| + resp.await_commit + _, _, body = resp.to_a + body.each do |part| + @controller.latch.await + body.close + break + end + } + + capture_log_output do |output| + @controller.process :overfill_buffer_and_die + t.join + got_error.await + assert_match 'Error while streaming', output.rewind && output.read + end + end + + def test_ignore_client_disconnect + @controller.latch = ActiveSupport::Concurrency::Latch.new + + @controller.request = @request + @controller.response = @response + + t = Thread.new(@response) { |resp| + resp.await_commit + _, _, body = resp.to_a + body.each do |part| + body.close + break + end + } + + capture_log_output do |output| + @controller.process :ignore_client_disconnect + t.join + Timeout.timeout(3) do + @controller.latch.await + end + 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 diff --git a/actionpack/test/controller/localized_templates_test.rb b/actionpack/test/controller/localized_templates_test.rb index c95ef8a0c7..27871ef351 100644 --- a/actionpack/test/controller/localized_templates_test.rb +++ b/actionpack/test/controller/localized_templates_test.rb @@ -8,22 +8,24 @@ end class LocalizedTemplatesTest < ActionController::TestCase tests LocalizedController + setup do + @old_locale = I18n.locale + end + + teardown do + I18n.locale = @old_locale + end + def test_localized_template_is_used - old_locale = I18n.locale I18n.locale = :de get :hello_world assert_equal "Gutten Tag", @response.body - ensure - I18n.locale = old_locale end def test_default_locale_template_is_used_when_locale_is_missing - old_locale = I18n.locale I18n.locale = :dk get :hello_world assert_equal "Hello World", @response.body - ensure - I18n.locale = old_locale end def test_use_fallback_locales @@ -36,13 +38,9 @@ class LocalizedTemplatesTest < ActionController::TestCase end def test_localized_template_has_correct_header_with_no_format_in_template_name - old_locale = I18n.locale I18n.locale = :it - get :hello_world assert_equal "Ciao Mondo", @response.body assert_equal "text/html", @response.content_type - ensure - I18n.locale = old_locale end end diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 18037b3d2f..49be7caf38 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -85,7 +85,7 @@ class ACLogSubscriberTest < ActionController::TestCase @old_logger = ActionController::Base.logger - @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) + @cache_path = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('tmp', 'cache') @controller.cache_store = :file_store, @cache_path ActionController::LogSubscriber.attach_to :action_controller end diff --git a/actionpack/test/controller/mime/accept_format_test.rb b/actionpack/test/controller/mime/accept_format_test.rb index c03c7edeb8..811c507af2 100644 --- a/actionpack/test/controller/mime/accept_format_test.rb +++ b/actionpack/test/controller/mime/accept_format_test.rb @@ -9,8 +9,6 @@ class StarStarMimeController < ActionController::Base end class StarStarMimeControllerTest < ActionController::TestCase - tests StarStarMimeController - def test_javascript_with_format @request.accept = "text/javascript" get :index, :format => 'js' diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb index ce6d135d92..1bc7ad3015 100644 --- a/actionpack/test/controller/mime/respond_to_test.rb +++ b/actionpack/test/controller/mime/respond_to_test.rb @@ -128,6 +128,12 @@ class RespondToController < ActionController::Base end end + def json_with_callback + respond_to do |type| + type.json { render :json => 'JS', :callback => 'alert' } + end + end + def iphone_with_html_response_type request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone" @@ -258,8 +264,6 @@ class RespondToController < ActionController::Base end class RespondToControllerTest < ActionController::TestCase - tests RespondToController - def setup super @request.host = "www.example.com" @@ -513,6 +517,13 @@ class RespondToControllerTest < ActionController::TestCase assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body end + def test_json_with_callback_sets_javascript_content_type + @request.accept = 'application/json' + get :json_with_callback + assert_equal '/**/alert(JS)', @response.body + assert_equal 'text/javascript', @response.content_type + end + def test_xhr xhr :get, :js_or_html assert_equal 'JS', @response.body diff --git a/actionpack/test/controller/mime/respond_with_test.rb b/actionpack/test/controller/mime/respond_with_test.rb index a70592fa1b..115f3b2f41 100644 --- a/actionpack/test/controller/mime/respond_with_test.rb +++ b/actionpack/test/controller/mime/respond_with_test.rb @@ -2,6 +2,10 @@ require 'abstract_unit' require 'controller/fake_models' class RespondWithController < ActionController::Base + class CustomerWithJson < Customer + def to_json; super; end + end + respond_to :html, :json, :touch respond_to :xml, :except => :using_resource_with_block respond_to :js, :only => [ :using_resource_with_block, :using_resource, 'using_hash_resource' ] @@ -38,6 +42,10 @@ class RespondWithController < ActionController::Base respond_with(resource, :location => "http://test.host/", :status => :created) end + def using_resource_with_json + respond_with(CustomerWithJson.new("david", request.delete? ? nil : 13)) + end + def using_invalid_resource_with_template respond_with(resource) end @@ -138,8 +146,6 @@ class EmptyRespondWithController < ActionController::Base end class RespondWithControllerTest < ActionController::TestCase - tests RespondWithController - def setup super @request.host = "www.example.com" @@ -382,9 +388,8 @@ class RespondWithControllerTest < ActionController::TestCase end def test_using_resource_for_put_with_json_yields_no_content_on_success - Customer.any_instance.stubs(:to_json).returns('{"name": "David"}') @request.accept = "application/json" - put :using_resource + put :using_resource_with_json assert_equal "application/json", @response.content_type assert_equal 204, @response.status assert_equal "", @response.body @@ -433,10 +438,9 @@ class RespondWithControllerTest < ActionController::TestCase end def test_using_resource_for_delete_with_json_yields_no_content_on_success - Customer.any_instance.stubs(:to_json).returns('{"name": "David"}') Customer.any_instance.stubs(:destroyed?).returns(true) @request.accept = "application/json" - delete :using_resource + delete :using_resource_with_json assert_equal "application/json", @response.content_type assert_equal 204, @response.status assert_equal "", @response.body @@ -645,6 +649,8 @@ class RespondWithControllerTest < ActionController::TestCase get :index, format: 'csv' assert_equal Mime::CSV, @response.content_type assert_equal "c,s,v", @response.body + ensure + ActionController::Renderers.remove :csv end def test_raises_missing_renderer_if_an_api_behavior_with_no_renderer @@ -654,6 +660,23 @@ class RespondWithControllerTest < ActionController::TestCase end end + def test_removing_renderers + ActionController::Renderers.add :csv do |obj, options| + send_data obj.to_csv, type: Mime::CSV + end + @controller = CsvRespondWithController.new + @request.accept = "text/csv" + get :index, format: 'csv' + assert_equal Mime::CSV, @response.content_type + + ActionController::Renderers.remove :csv + assert_raise ActionController::MissingRenderer do + get :index, format: 'csv' + end + ensure + ActionController::Renderers.remove :csv + end + def test_error_is_raised_if_no_respond_to_is_declared_and_respond_with_is_called @controller = EmptyRespondWithController.new @request.accept = "*/*" diff --git a/actionpack/test/controller/new_base/bare_metal_test.rb b/actionpack/test/controller/new_base/bare_metal_test.rb index 7396c850ad..246ba099af 100644 --- a/actionpack/test/controller/new_base/bare_metal_test.rb +++ b/actionpack/test/controller/new_base/bare_metal_test.rb @@ -2,6 +2,8 @@ require "abstract_unit" module BareMetalTest class BareController < ActionController::Metal + include ActionController::RackDelegation + def index self.response_body = "Hello world" end @@ -81,8 +83,8 @@ module BareMetalTest assert_nil headers['Content-Length'] end - test "head :continue (101) does not return a content-type header" do - headers = HeadController.action(:continue).call(Rack::MockRequest.env_for("/")).second + 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'] end diff --git a/actionpack/test/controller/new_base/render_body_test.rb b/actionpack/test/controller/new_base/render_body_test.rb index fad848349a..f4a3db8b41 100644 --- a/actionpack/test/controller/new_base/render_body_test.rb +++ b/actionpack/test/controller/new_base/render_body_test.rb @@ -111,17 +111,17 @@ module RenderBody assert_status 404 end - test "rendering body with nil returns an empty body padded for Safari" do + test "rendering body with nil returns an empty body" do get "/render_body/with_layout/with_nil" - assert_body " " + assert_body "" assert_status 200 end - test "Rendering body with nil and custom status code returns an empty body padded for Safari and the status" do + test "Rendering body with nil and custom status code returns an empty body and the status" do get "/render_body/with_layout/with_nil_and_status" - assert_body " " + assert_body "" assert_status 403 end diff --git a/actionpack/test/controller/new_base/render_html_test.rb b/actionpack/test/controller/new_base/render_html_test.rb index bfe0271df7..fe11501eeb 100644 --- a/actionpack/test/controller/new_base/render_html_test.rb +++ b/actionpack/test/controller/new_base/render_html_test.rb @@ -114,17 +114,17 @@ module RenderHtml assert_status 404 end - test "rendering text with nil returns an empty body padded for Safari" do + test "rendering text with nil returns an empty body" do get "/render_html/with_layout/with_nil" - assert_body " " + assert_body "" assert_status 200 end - test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do + test "Rendering text with nil and custom status code returns an empty body and the status" do get "/render_html/with_layout/with_nil_and_status" - assert_body " " + assert_body "" assert_status 403 end diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb index 1e2191d417..5b4885f7e0 100644 --- a/actionpack/test/controller/new_base/render_implicit_action_test.rb +++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb @@ -6,7 +6,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__))] def hello_world() end end @@ -33,10 +33,25 @@ module RenderImplicitAction assert_status 200 end + test "render does not traverse the file system" do + assert_raises(AbstractController::ActionNotFound) do + action_name = %w(.. .. fixtures shared).join(File::SEPARATOR) + SimpleController.action(action_name).call(Rack::MockRequest.env_for("/")) + end + end + test "available_action? returns true for implicit actions" do assert SimpleController.new.available_action?(:hello_world) assert SimpleController.new.available_action?(:"hyphen-ated") assert SimpleController.new.available_action?(:not_implemented) end + + test "available_action? does not allow File::SEPARATOR on the name" do + action_name = %w(evil .. .. path).join(File::SEPARATOR) + assert_equal false, SimpleController.new.available_action?(action_name.to_sym) + + action_name = %w(evil path).join(File::SEPARATOR) + assert_equal false, SimpleController.new.available_action?(action_name.to_sym) + 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 dba2e9f13e..0e36d36b50 100644 --- a/actionpack/test/controller/new_base/render_plain_test.rb +++ b/actionpack/test/controller/new_base/render_plain_test.rb @@ -106,17 +106,17 @@ module RenderPlain assert_status 404 end - test "rendering text with nil returns an empty body padded for Safari" do + test "rendering text with nil returns an empty body" do get "/render_plain/with_layout/with_nil" - assert_body " " + assert_body "" assert_status 200 end - test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do + test "Rendering text with nil and custom status code returns an empty body and the status" do get "/render_plain/with_layout/with_nil_and_status" - assert_body " " + assert_body "" assert_status 403 end diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb index b7a9cf92f2..e87811776a 100644 --- a/actionpack/test/controller/new_base/render_template_test.rb +++ b/actionpack/test/controller/new_base/render_template_test.rb @@ -9,7 +9,7 @@ module RenderTemplate "locals.html.erb" => "The secret is <%= secret %>", "xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend", "with_raw.html.erb" => "Hello <%=raw '<strong>this is raw</strong>' %>", - "with_implicit_raw.html.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in a html template", + "with_implicit_raw.html.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in an html template", "with_implicit_raw.text.erb" => "Hello <%== '<strong>this is also raw</strong>' %> in a text template", "test/with_json.html.erb" => "<%= render :template => 'test/with_json', :formats => [:json] %>", "test/with_json.json.erb" => "<%= render :template => 'test/final', :formats => [:json] %>", @@ -114,7 +114,7 @@ module RenderTemplate get :with_implicit_raw - assert_body "Hello <strong>this is also raw</strong> in a html template" + assert_body "Hello <strong>this is also raw</strong> in an html template" assert_status 200 get :with_implicit_raw, format: 'text' diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb index abb81d7e71..10bad57cd6 100644 --- a/actionpack/test/controller/new_base/render_text_test.rb +++ b/actionpack/test/controller/new_base/render_text_test.rb @@ -106,17 +106,17 @@ module RenderText assert_status 404 end - test "rendering text with nil returns an empty body padded for Safari" do + test "rendering text with nil returns an empty body" do get "/render_text/with_layout/with_nil" - assert_body " " + assert_body "" assert_status 200 end - test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do + test "Rendering text with nil and custom status code returns an empty body and the status" do get "/render_text/with_layout/with_nil_and_status" - assert_body " " + assert_body "" assert_status 403 end diff --git a/actionpack/test/controller/parameters/always_permitted_parameters_test.rb b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb new file mode 100644 index 0000000000..059f310d49 --- /dev/null +++ b/actionpack/test/controller/parameters/always_permitted_parameters_test.rb @@ -0,0 +1,29 @@ +require 'abstract_unit' +require 'action_controller/metal/strong_parameters' + +class AlwaysPermittedParametersTest < ActiveSupport::TestCase + def setup + ActionController::Parameters.action_on_unpermitted_parameters = :raise + ActionController::Parameters.always_permitted_parameters = %w( controller action format ) + end + + def teardown + ActionController::Parameters.action_on_unpermitted_parameters = false + ActionController::Parameters.always_permitted_parameters = %w( controller action ) + end + + test "shows deprecations warning on NEVER_UNPERMITTED_PARAMS" do + assert_deprecated do + ActionController::Parameters::NEVER_UNPERMITTED_PARAMS + end + end + + test "permits parameters that are whitelisted" do + params = ActionController::Parameters.new({ + book: { pages: 65 }, + format: "json" + }) + permitted = params.permit book: [:pages] + assert permitted.permitted? + end +end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 33a91d72d9..aa894ffa17 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -167,9 +167,26 @@ class ParametersPermitTest < ActiveSupport::TestCase 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 params = ActionController::Parameters.new(foo: [{}]) - assert params[:foo].equal?(params[:foo]) + assert_same params[:foo], params[:foo] + end + + # Strong params has an internal cache to avoid duplicated loops in the most + # common usage pattern. See the docs of the method `converted_arrays`. + # + # 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}]) + + permitted = params.permit(users: [:id]) + permitted[:users] << {injected: 1} + assert_not permitted[:users].last.permitted? end test "fetch doesnt raise ParameterMissing exception if there is a default" do diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb index 11ccb6cf3b..645ecae220 100644 --- a/actionpack/test/controller/params_wrapper_test.rb +++ b/actionpack/test/controller/params_wrapper_test.rb @@ -337,14 +337,26 @@ class IrregularInflectionParamsWrapperTest < ActionController::TestCase tests ParamswrappernewsController def test_uses_model_attribute_names_with_irregular_inflection - ActiveSupport::Inflector.inflections do |inflect| - inflect.irregular 'paramswrappernews_item', 'paramswrappernews' - end + with_dup do + ActiveSupport::Inflector.inflections do |inflect| + inflect.irregular 'paramswrappernews_item', 'paramswrappernews' + end - with_default_wrapper_options do - @request.env['CONTENT_TYPE'] = 'application/json' - post :parse, { 'username' => 'sikachu', 'test_attr' => 'test_value' } - assert_parameters({ 'username' => 'sikachu', 'test_attr' => 'test_value', 'paramswrappernews_item' => { 'test_attr' => 'test_value' }}) + with_default_wrapper_options do + @request.env['CONTENT_TYPE'] = 'application/json' + post :parse, { '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 end diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index 4331333b98..103ca9c776 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -90,6 +90,10 @@ class RedirectController < ActionController::Base redirect_to nil end + def redirect_to_params + redirect_to ActionController::Parameters.new(status: 200, protocol: 'javascript', f: '%0Aeval(name)') + end + def redirect_to_with_block redirect_to proc { "http://www.rubyonrails.org/" } end @@ -281,6 +285,12 @@ class RedirectTest < ActionController::TestCase end end + def test_redirect_to_params + assert_raise(ActionController::ActionControllerError) do + get :redirect_to_params + end + end + def test_redirect_to_with_block get :redirect_to_with_block assert_response :redirect diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb index de8d1cbd9b..ada978aa11 100644 --- a/actionpack/test/controller/render_json_test.rb +++ b/actionpack/test/controller/render_json_test.rb @@ -101,7 +101,7 @@ class RenderJsonTest < ActionController::TestCase def test_render_json_with_callback xhr :get, :render_json_hello_world_with_callback - assert_equal 'alert({"hello":"world"})', @response.body + assert_equal '/**/alert({"hello":"world"})', @response.body assert_equal 'text/javascript', @response.content_type end diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb index b5e74e373d..af50e11261 100644 --- a/actionpack/test/controller/render_other_test.rb +++ b/actionpack/test/controller/render_other_test.rb @@ -1,9 +1,5 @@ require 'abstract_unit' -ActionController.add_renderer :simon do |says, options| - self.content_type = Mime::TEXT - self.response_body = "Simon says: #{says}" -end class RenderOtherTest < ActionController::TestCase class TestController < ActionController::Base @@ -15,7 +11,14 @@ class RenderOtherTest < ActionController::TestCase 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 26806fb03f..9926130c02 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -242,6 +242,8 @@ class MetalTestController < ActionController::Metal include AbstractController::Rendering include ActionView::Rendering include ActionController::Rendering + include ActionController::RackDelegation + def accessing_logger_in_template render :inline => "<%= logger.class %>" @@ -387,10 +389,6 @@ end class EtagRenderTest < ActionController::TestCase tests TestControllerWithExtraEtags - def setup - super - end - def test_multiple_etags @request.if_none_match = etag(["123", 'ab', :cde, [:f]]) get :fresh diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb index 5ab5141966..2a5aad9c0e 100644 --- a/actionpack/test/controller/request_forgery_protection_test.rb +++ b/actionpack/test/controller/request_forgery_protection_test.rb @@ -127,11 +127,12 @@ module RequestForgeryProtectionTests @token = "cf50faa3fe97702ca1ae" SecureRandom.stubs(:base64).returns(@token) + @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 = nil + ActionController::Base.request_forgery_protection_token = @old_request_forgery_protection_token end def test_should_render_form_with_token_tag @@ -376,11 +377,12 @@ class RequestForgeryProtectionControllerUsingResetSessionTest < ActionController 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 = nil + 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 @@ -462,16 +464,38 @@ end class CustomAuthenticityParamControllerTest < ActionController::TestCase def setup super - ActionController::Base.request_forgery_protection_token = :custom_token_name + @old_logger = ActionController::Base.logger + @logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new + @token = "foobar" + @old_request_forgery_protection_token = ActionController::Base.request_forgery_protection_token + ActionController::Base.request_forgery_protection_token = @token end def teardown - ActionController::Base.request_forgery_protection_token = :authenticity_token + ActionController::Base.request_forgery_protection_token = @old_request_forgery_protection_token super end - def test_should_allow_custom_token - post :index, :custom_token_name => 'foobar' - assert_response :ok + def test_should_not_warn_if_form_authenticity_param_matches_form_authenticity_token + ActionController::Base.logger = @logger + SecureRandom.stubs(:base64).returns(@token) + + begin + post :index, :custom_token_name => 'foobar' + assert_equal 0, @logger.logged(:warn).size + ensure + ActionController::Base.logger = @old_logger + end + end + + def test_should_warn_if_form_authenticity_param_does_not_match_form_authenticity_token + ActionController::Base.logger = @logger + + begin + post :index, :custom_token_name => 'bazqux' + assert_equal 1, @logger.logged(:warn).size + ensure + ActionController::Base.logger = @old_logger + end end end diff --git a/actionpack/test/controller/required_params_test.rb b/actionpack/test/controller/required_params_test.rb index 25d0337212..6803dbbb62 100644 --- a/actionpack/test/controller/required_params_test.rb +++ b/actionpack/test/controller/required_params_test.rb @@ -24,10 +24,26 @@ class ActionControllerRequiredParamsTest < ActionController::TestCase post :create, { book: { name: "Mjallo!" } } assert_response :ok end + + test "required parameters with false value will not raise" do + post :create, { book: { name: false } } + assert_response :ok + end end class ParametersRequireTest < ActiveSupport::TestCase - test "required parameters must be present not merely not nil" do + + test "required parameters should accept and return false value" do + assert_equal(false, ActionController::Parameters.new(person: false).require(:person)) + end + + test "required parameters must not be nil" do + assert_raises(ActionController::ParameterMissing) do + ActionController::Parameters.new(person: nil).require(:person) + end + end + + test "required parameters must not be empty" do assert_raises(ActionController::ParameterMissing) do ActionController::Parameters.new(person: {}).require(:person) end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index df453a0251..c18914cc8e 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -77,17 +77,18 @@ class LegacyRouteSetTests < ActiveSupport::TestCase include ActionDispatch::RoutingVerbs attr_reader :rs + attr_accessor :controller alias :routes :rs def setup - @rs = ::ActionDispatch::Routing::RouteSet.new + @rs = make_set @response = nil end def test_symbols_with_dashes rs.draw do get '/:artist/:song-omg', :to => lambda { |env| - resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters [200, {}, [resp]] } end @@ -99,7 +100,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_id_with_dash rs.draw do get '/journey/:id', :to => lambda { |env| - resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters [200, {}, [resp]] } end @@ -111,7 +112,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_dash_with_custom_regexp rs.draw do get '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env| - resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters [200, {}, [resp]] } end @@ -124,7 +125,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_pre_dash rs.draw do get '/:artist/omg-:song', :to => lambda { |env| - resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters [200, {}, [resp]] } end @@ -136,7 +137,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_pre_dash_with_custom_regexp rs.draw do get '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env| - resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + resp = ActiveSupport::JSON.encode ActionDispatch::Request.new(env).path_parameters [200, {}, [resp]] } end @@ -243,6 +244,32 @@ class LegacyRouteSetTests < ActiveSupport::TestCase 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}] } + end + end + + assert_equal 'default', get(URI('http://www.example.org/foo/')) + assert scope_called, "scope constraint should be called" + end + + def test_scoped_lambda_with_get_lambda + 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}] } + end + end + + 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 => /[^\/]+/ }, @@ -291,11 +318,16 @@ class LegacyRouteSetTests < ActiveSupport::TestCase assert_equal '/admin/user/show/10', url_for(rs, { :controller => 'admin/user', :action => 'show', :id => 10 }) - assert_equal '/admin/user/show', url_for(rs, { :action => 'show' }, { :controller => 'admin/user', :action => 'list', :id => '10' }) - assert_equal '/admin/user/list/10', url_for(rs, {}, { :controller => 'admin/user', :action => 'list', :id => '10' }) + get URI('http://test.host/admin/user/list/10') + + assert_equal({ :controller => 'admin/user', :action => 'list', :id => '10' }, + controller.request.path_parameters) - assert_equal '/admin/stuff', url_for(rs, { :controller => 'stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' }) - assert_equal '/stuff', url_for(rs, { :controller => '/stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' }) + assert_equal '/admin/user/show', controller.url_for({ :action => 'show', :only_path => true }) + assert_equal '/admin/user/list/10', controller.url_for({:only_path => true}) + + assert_equal '/admin/stuff', controller.url_for({ :controller => 'stuff', :only_path => true }) + assert_equal '/stuff', controller.url_for({ :controller => '/stuff', :only_path => true }) end def test_ignores_leading_slash @@ -419,14 +451,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase get 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com' end routes = setup_for_named_route - routes.expects(:url_for).with({ - :host => 'foo.com', - :only_path => false, - :controller => 'content', - :action => 'show_page', - :use_route => 'pages' - }).once - routes.send(:pages_url) + assert_equal "http://foo.com/page", routes.pages_url end def setup_for_named_route(options = {}) @@ -499,9 +524,10 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_changing_controller rs.draw { get ':controller/:action/:id' } + get URI('http://test.host/admin/user/index/10') + assert_equal '/admin/stuff/show/10', - url_for(rs, {:controller => 'stuff', :action => 'show', :id => 10}, - {:controller => 'admin/user', :action => 'index'}) + controller.url_for({:controller => 'stuff', :action => 'show', :id => 10, :only_path => true}) end def test_paths_escaped @@ -560,8 +586,12 @@ class LegacyRouteSetTests < ActiveSupport::TestCase get '*path' => 'content#show_file' end + get URI('http://test.host/pages/boo') + assert_equal({:controller=>"content", :action=>"show_file", :path=>"pages/boo"}, + controller.request.path_parameters) + assert_equal '/pages/boo', - url_for(rs, {}, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) }) + controller.url_for(:only_path => true) end def test_backwards @@ -570,7 +600,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase get ':controller(/:action(/:id))' end - assert_equal '/page/20', url_for(rs, { :id => 20 }, { :controller => 'pages', :action => 'show' }) + get URI('http://test.host/pages/show') + assert_equal '/page/20', controller.url_for({ :id => 20, :only_path => true }) assert_equal '/page/20', url_for(rs, { :controller => 'pages', :id => 20, :action => 'show' }) assert_equal '/pages/boo', url_for(rs, { :controller => 'pages', :action => 'boo' }) end @@ -611,7 +642,8 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def test_action_expiry rs.draw { get ':controller(/:action(/:id))' } - assert_equal '/content', url_for(rs, { :controller => 'content' }, { :controller => 'content', :action => 'show' }) + get URI('http://test.host/content/show') + assert_equal '/content', controller.url_for(:controller => 'content', :only_path => true) end def test_requirement_should_prevent_optional_id @@ -654,14 +686,18 @@ class LegacyRouteSetTests < ActiveSupport::TestCase assert_equal '/pages/2005/6/12', url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12 }) + get URI('http://test.host/pages/2005/6/12') + assert_equal({ :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' }, + controller.request.path_parameters) + assert_equal '/pages/2005/6/4', - url_for(rs, { :day => 4 }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' }) + controller.url_for({ :day => 4, :only_path => true }) assert_equal '/pages/2005/6', - url_for(rs, { :day => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' }) + controller.url_for({ :day => nil, :only_path => true }) assert_equal '/pages/2005', - url_for(rs, { :day => nil, :month => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' }) + controller.url_for({ :day => nil, :month => nil, :only_path => true }) end def test_root_url_generation_with_controller_and_action @@ -819,9 +855,15 @@ end class RouteSetTest < ActiveSupport::TestCase include RoutingTestHelpers + include ActionDispatch::RoutingVerbs - def set - @set ||= ROUTING::RouteSet.new + attr_reader :set + alias :routes :set + attr_accessor :controller + + def setup + super + @set = make_set end def request @@ -922,7 +964,8 @@ class RouteSetTest < ActiveSupport::TestCase get '/admin/users' => 'admin/users#index', :as => "users" end - MockController.build(set.url_helpers).new + get URI('http://test.host/people') + controller end def test_named_route_url_method @@ -1019,12 +1062,12 @@ class RouteSetTest < ActiveSupport::TestCase get '/:controller(/:action(/:id))' end - assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages')) - assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index')) - assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list')) + assert_equal({:controller => 'pages', :action => 'index'}, request_path_params('/pages')) + assert_equal({:controller => 'pages', :action => 'index'}, request_path_params('/pages/index')) + assert_equal({:controller => 'pages', :action => 'list'}, request_path_params('/pages/list')) - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10')) - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/pages/show/10')) + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/page/10')) end def test_route_constraints_on_request_object_with_anchors_are_valid @@ -1076,9 +1119,7 @@ class RouteSetTest < ActiveSupport::TestCase get "/people" => "missing#index" end - assert_raise(ActionController::RoutingError) { - set.recognize_path("/people", :method => :get) - } + assert_raises(ActionController::RoutingError) { request_path_params '/people' } end def test_recognize_with_encoded_id_and_regex @@ -1086,8 +1127,8 @@ class RouteSetTest < ActiveSupport::TestCase get 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/ end - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) - assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world')) + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, request_path_params('/page/10')) + assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, request_path_params('/page/hello+world')) end def test_recognize_with_http_methods @@ -1100,40 +1141,40 @@ class RouteSetTest < ActiveSupport::TestCase delete "/people/:id" => "people#destroy" end - params = set.recognize_path("/people", :method => :get) + params = request_path_params("/people", :method => :get) assert_equal("index", params[:action]) - params = set.recognize_path("/people", :method => :post) + params = request_path_params("/people", :method => :post) assert_equal("create", params[:action]) - params = set.recognize_path("/people/5", :method => :put) + params = request_path_params("/people/5", :method => :put) assert_equal("update", params[:action]) - params = set.recognize_path("/people/5", :method => :patch) + params = request_path_params("/people/5", :method => :patch) assert_equal("update", params[:action]) assert_raise(ActionController::UnknownHttpMethod) { - set.recognize_path("/people", :method => :bacon) + request_path_params("/people", :method => :bacon) } - params = set.recognize_path("/people/5", :method => :get) + params = request_path_params("/people/5", :method => :get) assert_equal("show", params[:action]) assert_equal("5", params[:id]) - params = set.recognize_path("/people/5", :method => :put) + params = request_path_params("/people/5", :method => :put) assert_equal("update", params[:action]) assert_equal("5", params[:id]) - params = set.recognize_path("/people/5", :method => :patch) + params = request_path_params("/people/5", :method => :patch) assert_equal("update", params[:action]) assert_equal("5", params[:id]) - params = set.recognize_path("/people/5", :method => :delete) + params = request_path_params("/people/5", :method => :delete) assert_equal("destroy", params[:action]) assert_equal("5", params[:id]) assert_raise(ActionController::RoutingError) { - set.recognize_path("/people/5", :method => :post) + request_path_params("/people/5", :method => :post) } end @@ -1143,11 +1184,11 @@ class RouteSetTest < ActiveSupport::TestCase root :to => "people#index" end - params = set.recognize_path("/people", :method => :get) + params = request_path_params("/people", :method => :get) assert_equal("people", params[:controller]) assert_equal("index", params[:action]) - params = set.recognize_path("/", :method => :get) + params = request_path_params("/", :method => :get) assert_equal("people", params[:controller]) assert_equal("index", params[:action]) end @@ -1158,7 +1199,7 @@ class RouteSetTest < ActiveSupport::TestCase :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/ end - params = set.recognize_path("/articles/2005/11/05/a-very-interesting-article", :method => :get) + params = request_path_params("/articles/2005/11/05/a-very-interesting-article", :method => :get) assert_equal("permalink", params[:action]) assert_equal("2005", params[:year]) assert_equal("11", params[:month]) @@ -1172,7 +1213,7 @@ class RouteSetTest < ActiveSupport::TestCase get '/profile' => 'profile#index' end - set.recognize_path("/profile") rescue nil + request_path_params("/profile") rescue nil assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" end @@ -1185,17 +1226,17 @@ class RouteSetTest < ActiveSupport::TestCase get "people/:id(.:format)" => "people#show" end - params = set.recognize_path("/people/5", :method => :get) + params = request_path_params("/people/5", :method => :get) assert_equal("show", params[:action]) assert_equal("5", params[:id]) - params = set.recognize_path("/people/5", :method => :put) + params = request_path_params("/people/5", :method => :put) assert_equal("update", params[:action]) - params = set.recognize_path("/people/5", :method => :patch) + params = request_path_params("/people/5", :method => :patch) assert_equal("update", params[:action]) - params = set.recognize_path("/people/5.png", :method => :get) + params = request_path_params("/people/5.png", :method => :get) assert_equal("show", params[:action]) assert_equal("5", params[:id]) assert_equal("png", params[:format]) @@ -1214,7 +1255,7 @@ class RouteSetTest < ActiveSupport::TestCase def test_root_map set.draw { root :to => 'people#index' } - params = set.recognize_path("", :method => :get) + params = request_path_params("", :method => :get) assert_equal("people", params[:controller]) assert_equal("index", params[:action]) end @@ -1228,7 +1269,7 @@ class RouteSetTest < ActiveSupport::TestCase end - params = set.recognize_path("/api/inventory", :method => :get) + params = request_path_params("/api/inventory", :method => :get) assert_equal("api/products", params[:controller]) assert_equal("inventory", params[:action]) end @@ -1240,7 +1281,7 @@ class RouteSetTest < ActiveSupport::TestCase end end - params = set.recognize_path("/api", :method => :get) + params = request_path_params("/api", :method => :get) assert_equal("api/products", params[:controller]) assert_equal("index", params[:action]) end @@ -1252,7 +1293,7 @@ class RouteSetTest < ActiveSupport::TestCase end end - params = set.recognize_path("/prefix/inventory", :method => :get) + params = request_path_params("/prefix/inventory", :method => :get) assert_equal("api/products", params[:controller]) assert_equal("inventory", params[:action]) end @@ -1264,38 +1305,36 @@ class RouteSetTest < ActiveSupport::TestCase end end - params = set.recognize_path("/inventory", :method => :get) + params = request_path_params("/inventory", :method => :get) assert_equal("api/products", params[:controller]) assert_equal("inventory", params[:action]) end - def test_generate_changes_controller_module - set.draw { get ':controller/:action/:id' } - current = { :controller => "bling/bloop", :action => "bap", :id => 9 } - - assert_equal "/foo/bar/baz/7", - url_for(set, { :controller => "foo/bar", :action => "baz", :id => 7 }, current) - end - def test_id_is_sticky_when_it_ought_to_be + @set = make_set false + set.draw do get ':controller/:id/:action' end - url = url_for(set, { :action => "destroy" }, { :controller => "people", :action => "show", :id => "7" }) - assert_equal "/people/7/destroy", url + get URI('http://test.host/people/7/show') + + assert_equal "/people/7/destroy", controller.url_for(:action => 'destroy', :only_path => true) end def test_use_static_path_when_possible + @set = make_set false + set.draw do get 'about' => "welcome#about" get ':controller/:action/:id' end - url = url_for(set, { :controller => "welcome", :action => "about" }, - { :controller => "welcome", :action => "get", :id => "7" }) + get URI('http://test.host/welcom/get/7') - assert_equal "/about", url + assert_equal "/about", controller.url_for(:controller => 'welcome', + :action => 'about', + :only_path => true) end def test_generate @@ -1330,38 +1369,51 @@ class RouteSetTest < ActiveSupport::TestCase end def test_named_routes_are_never_relative_to_modules + @set = make_set false + set.draw do get "/connection/manage(/:action)" => 'connection/manage#index' get "/connection/connection" => "connection/connection#index" get '/connection' => 'connection#index', :as => 'family_connection' end - url = url_for(set, { :controller => "connection" }, { :controller => 'connection/manage' }) + assert_equal({ :controller => 'connection/manage', + :action => 'index', }, request_path_params('/connection/manage')) + + url = controller.url_for({ :controller => "connection", :only_path => true }) assert_equal "/connection/connection", url - url = url_for(set, { :use_route => :family_connection, :controller => "connection" }, { :controller => 'connection/manage' }) + url = controller.url_for({ :use_route => :family_connection, + :controller => "connection", :only_path => true }) assert_equal "/connection", url end def test_action_left_off_when_id_is_recalled + @set = make_set false + set.draw do get ':controller(/:action(/:id))' end - assert_equal '/books', url_for(set, - {:controller => 'books', :action => 'index'}, - {:controller => 'books', :action => 'show', :id => '10'} - ) + + get URI('http://test.host/books/show/10') + + assert_equal '/books', controller.url_for(:controller => 'books', + :only_path => true, + :action => 'index') end def test_query_params_will_be_shown_when_recalled + @set = make_set false + set.draw do get 'show_weblog/:parameter' => 'weblog#show' get ':controller(/:action(/:id))' end - assert_equal '/weblog/edit?parameter=1', url_for(set, - {:action => 'edit', :parameter => 1}, - {:controller => 'weblog', :action => 'show', :parameter => 1} - ) + + get URI('http://test.host/weblog/show/1') + + assert_equal '/weblog/edit?parameter=1', controller.url_for( + {:action => 'edit', :parameter => 1, :only_path => true}) end def test_format_is_not_inherit @@ -1369,22 +1421,30 @@ class RouteSetTest < ActiveSupport::TestCase get '/posts(.:format)' => 'posts#index' end - assert_equal '/posts', url_for(set, - {:controller => 'posts'}, - {:controller => 'posts', :action => 'index', :format => 'xml'} - ) + get URI('http://test.host/posts.xml') + assert_equal({:controller => 'posts', :action => 'index', :format => 'xml'}, + controller.request.path_parameters) - assert_equal '/posts.xml', url_for(set, - {:controller => 'posts', :format => 'xml'}, - {:controller => 'posts', :action => 'index', :format => 'xml'} - ) + 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}) end def test_expiry_determination_should_consider_values_with_to_param + @set = make_set false + set.draw { get 'projects/:project_id/:controller/:action' } - assert_equal '/projects/1/weblog/show', url_for(set, - { :action => 'show', :project_id => 1 }, - { :controller => 'weblog', :action => 'show', :project_id => '1' }) + + get URI('http://test.host/projects/1/weblog/show') + + assert_equal( + { :controller => 'weblog', :action => 'show', :project_id => '1' }, + controller.request.path_parameters) + + assert_equal '/projects/1/weblog/show', + controller.url_for({ :action => 'show', :project_id => 1, :only_path => true }) end def test_named_route_in_nested_resource @@ -1587,7 +1647,6 @@ class RouteSetTest < ActiveSupport::TestCase end def test_slashes_are_implied - @set = nil set.draw { get("/:controller(/:action(/:id))") } assert_equal '/content', url_for(set, { :controller => 'content', :action => 'index' }) @@ -1685,7 +1744,43 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal '/ibocorp', url_for(set, { :controller => 'ibocorp', :action => "show", :page => 1 }) end + include ActionDispatch::RoutingVerbs + + class TestSet < ROUTING::RouteSet + def initialize(block) + @block = block + super() + end + + class Dispatcher < ROUTING::RouteSet::Dispatcher + def initialize(defaults, set, block) + super(defaults) + @block = block + @set = set + end + + def controller_reference(controller_param) + block = @block + set = @set + Class.new(ActionController::Base) { + include set.url_helpers + define_method(:process) { |name| block.call(self) } + def to_a; [200, {}, []]; end + } + end + end + + def dispatcher defaults + TestSet::Dispatcher.new defaults, self, @block + end + end + + alias :routes :set + def test_generate_with_optional_params_recalls_last_request + controller = nil + @set = TestSet.new ->(c) { controller = c } + set.draw do get "blog/", :controller => "blog", :action => "index" @@ -1700,23 +1795,29 @@ class RouteSetTest < ActiveSupport::TestCase get "*anything", :controller => "blog", :action => "unknown_request" end - assert_equal({:controller => "blog", :action => "index"}, set.recognize_path("/blog")) - assert_equal({:controller => "blog", :action => "show", :id => "123"}, set.recognize_path("/blog/show/123")) - assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :day => nil, :month => nil }, set.recognize_path("/blog/2004")) - assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => nil }, set.recognize_path("/blog/2004/12")) - assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => "25"}, set.recognize_path("/blog/2004/12/25")) - assert_equal({:controller => "articles", :action => "edit", :id => "123"}, set.recognize_path("/blog/articles/edit/123")) - assert_equal({:controller => "articles", :action => "show_stats"}, set.recognize_path("/blog/articles/show_stats")) - assert_equal({:controller => "blog", :action => "unknown_request", :anything => "blog/wibble"}, set.recognize_path("/blog/wibble")) - assert_equal({:controller => "blog", :action => "unknown_request", :anything => "junk"}, set.recognize_path("/junk")) + recognize_path = ->(path) { + get(URI("http://example.org" + path)) + controller.request.path_parameters + } - last_request = set.recognize_path("/blog/2006/07/28").freeze - assert_equal({:controller => "blog", :action => "show_date", :year => "2006", :month => "07", :day => "28"}, last_request) - assert_equal("/blog/2006/07/25", url_for(set, { :day => 25 }, last_request)) - assert_equal("/blog/2005", url_for(set, { :year => 2005 }, last_request)) - assert_equal("/blog/show/123", url_for(set, { :action => "show" , :id => 123 }, last_request)) - assert_equal("/blog/2006", url_for(set, { :year => 2006 }, last_request)) - assert_equal("/blog/2006", url_for(set, { :year => 2006, :month => nil }, last_request)) + assert_equal({:controller => "blog", :action => "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') + + 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 @@ -1789,6 +1890,9 @@ class RackMountIntegrationTests < ActiveSupport::TestCase root :to => "news#index" } + attr_reader :routes + attr_reader :controller + def setup @routes = ActionDispatch::Routing::RouteSet.new @routes.draw(&Mapping) diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 4df2f8b98d..c002cf4d8f 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -9,6 +9,7 @@ end class SendFileController < ActionController::Base include TestFileUtils + include ActionController::Testing layout "layouts/standard" # to make sure layouts don't interfere attr_writer :options @@ -30,11 +31,8 @@ class SendFileWithActionControllerLive < SendFileController end class SendFileTest < ActionController::TestCase - tests SendFileController include TestFileUtils - Mime::Type.register "image/png", :png unless defined? Mime::PNG - def setup @controller = SendFileController.new @request = ActionController::TestRequest.new @@ -201,8 +199,6 @@ class SendFileTest < ActionController::TestCase end end - tests SendFileWithActionControllerLive - def test_send_file_with_action_controller_live @controller = SendFileWithActionControllerLive.new @controller.options = { :content_type => "application/x-ruby" } diff --git a/actionpack/test/controller/show_exceptions_test.rb b/actionpack/test/controller/show_exceptions_test.rb index ff23b22040..f7eba1ef43 100644 --- a/actionpack/test/controller/show_exceptions_test.rb +++ b/actionpack/test/controller/show_exceptions_test.rb @@ -32,7 +32,7 @@ module ShowExceptions 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', '::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 '/' assert_match(/boom/, body) diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index fbc10baf21..3b3b15c061 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -164,7 +164,7 @@ XML end class DefaultUrlOptionsCachingController < ActionController::Base - before_filter { @dynamic_opt = 'opt' } + before_action { @dynamic_opt = 'opt' } def test_url_options_reset render text: url_for(params) @@ -662,7 +662,7 @@ XML def test_id_converted_to_string get :test_params, :id => 20, :foo => Object.new - assert_kind_of String, @request.path_parameters['id'] + assert_kind_of String, @request.path_parameters[:id] end def test_array_path_parameter_handled_properly @@ -673,17 +673,17 @@ XML end get :test_params, :path => ['hello', 'world'] - assert_equal ['hello', 'world'], @request.path_parameters['path'] - assert_equal 'hello/world', @request.path_parameters['path'].to_param + assert_equal ['hello', 'world'], @request.path_parameters[:path] + assert_equal 'hello/world', @request.path_parameters[:path].to_param end end def test_assert_realistic_path_parameters get :test_params, :id => 20, :foo => Object.new - # All elements of path_parameters should use string keys + # All elements of path_parameters should use Symbol keys @request.path_parameters.keys.each do |key| - assert_kind_of String, key + assert_kind_of Symbol, key end end @@ -737,12 +737,12 @@ XML assert_equal "baz", @request.filtered_parameters[:foo] end - def test_symbolized_path_params_reset_after_request + def test_path_params_reset_after_request get :test_params, :id => "foo" - assert_equal "foo", @request.symbolized_path_parameters[:id] + assert_equal "foo", @request.path_parameters[:id] @request.recycle! get :test_params - assert_nil @request.symbolized_path_parameters[:id] + assert_nil @request.path_parameters[:id] end def test_request_protocol_is_reset_after_request diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb index 6c2311e7a5..24a09222b1 100644 --- a/actionpack/test/controller/url_for_integration_test.rb +++ b/actionpack/test/controller/url_for_integration_test.rb @@ -6,6 +6,7 @@ require 'active_support/core_ext/object/with_options' module ActionPack class URLForIntegrationTest < ActiveSupport::TestCase include RoutingTestHelpers + include ActionDispatch::RoutingVerbs Model = Struct.new(:to_param) @@ -61,8 +62,11 @@ module ActionPack root :to => "news#index" } + attr_reader :routes + attr_accessor :controller + def setup - @routes = ActionDispatch::Routing::RouteSet.new + @routes = make_set false @routes.draw(&Mapping) end @@ -70,9 +74,9 @@ module ActionPack ['/admin/users',[ { :use_route => 'admin_users' }]], ['/admin/users',[ { :controller => 'admin/users' }]], ['/admin/users',[ { :controller => 'admin/users', :action => 'index' }]], - ['/admin/users',[ { :action => 'index' }, { :controller => 'admin/users' }]], - ['/admin/users',[ { :controller => 'users', :action => 'index' }, { :controller => 'admin/accounts' }]], - ['/people',[ { :controller => '/people', :action => 'index' }, { :controller => 'admin/accounts' }]], + ['/admin/users',[ { :action => 'index' }, { :controller => 'admin/users', :action => 'index' }, '/admin/users']], + ['/admin/users',[ { :controller => 'users', :action => 'index' }, { :controller => 'admin/accounts', :action => 'show', :id => '1' }, '/admin/accounts/show/1']], + ['/people',[ { :controller => '/people', :action => 'index' }, {:controller=>"admin/accounts", :action=>"foo", :id=>"bar"}, '/admin/accounts/foo/bar']], ['/admin/posts',[ { :controller => 'admin/posts' }]], ['/admin/posts/new',[ { :controller => 'admin/posts', :action => 'new' }]], @@ -86,11 +90,11 @@ module ActionPack ['/archive?year=january',[ { :controller => 'archive', :action => 'index', :year => 'january' }]], ['/people',[ { :controller => 'people', :action => 'index' }]], - ['/people',[ { :action => 'index' }, { :controller => 'people' }]], - ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]], - ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]], - ['/people',[ {}, { :controller => 'people', :action => 'index' }]], - ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'show', :id => '1' }]], + ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'index' }, '/people']], + ['/people',[ { :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], + ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], + ['/people',[ {}, { :controller => 'people', :action => 'index' }, '/people']], + ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], ['/people/new',[ { :use_route => 'new_person' }]], ['/people/new',[ { :controller => 'people', :action => 'new' }]], ['/people/1',[ { :use_route => 'person', :id => '1' }]], @@ -98,11 +102,11 @@ module ActionPack ['/people/1.xml',[ { :controller => 'people', :action => 'show', :id => '1', :format => 'xml' }]], ['/people/1',[ { :controller => 'people', :action => 'show', :id => 1 }]], ['/people/1',[ { :controller => 'people', :action => 'show', :id => Model.new('1') }]], - ['/people/1',[ { :action => 'show', :id => '1' }, { :controller => 'people', :action => 'index' }]], - ['/people/1',[ { :action => 'show', :id => 1 }, { :controller => 'people', :action => 'show', :id => '1' }]], - ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }]], - ['/people/1',[ {}, { :controller => 'people', :action => 'show', :id => '1' }]], - ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'index', :id => '1' }]], + ['/people/1',[ { :action => 'show', :id => '1' }, { :controller => 'people', :action => 'index' }, '/people']], + ['/people/1',[ { :action => 'show', :id => 1 }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], + ['/people',[ { :controller => 'people', :action => 'index' }, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], + ['/people/1',[ {}, { :controller => 'people', :action => 'show', :id => '1' }, '/people/show/1']], + ['/people/1',[ { :controller => 'people', :action => 'show' }, { :controller => 'people', :action => 'index', :id => '1' }, '/people/index/1']], ['/people/1/edit',[ { :controller => 'people', :action => 'edit', :id => '1' }]], ['/people/1/edit.xml',[ { :controller => 'people', :action => 'edit', :id => '1', :format => 'xml' }]], ['/people/1/edit',[ { :use_route => 'edit_person', :id => '1' }]], @@ -118,16 +122,15 @@ module ActionPack ['/project',[ { :controller => 'project', :action => 'index' }]], ['/projects/1',[ { :controller => 'project', :action => 'index', :project_id => '1' }]], - ['/projects/1',[ { :controller => 'project', :action => 'index'}, {:project_id => '1' }]], + ['/projects/1',[ { :controller => 'project', :action => 'index'}, {:project_id => '1', :controller => 'project', :action => 'index' }, '/projects/1']], ['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index', :project_id => '1' }]], - ['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index' }, { :project_id => '1' }]], + ['/projects/1',[ { :use_route => 'project', :controller => 'project', :action => 'index' }, { :controller => 'project', :action => 'index', :project_id => '1' }, '/projects/1']], ['/clients',[ { :controller => 'projects', :action => 'index' }]], ['/clients?project_id=1',[ { :controller => 'projects', :action => 'index', :project_id => '1' }]], - ['/clients',[ { :controller => 'projects', :action => 'index' }, { :project_id => '1' }]], - ['/clients',[ { :action => 'index' }, { :controller => 'projects', :action => 'index', :project_id => '1' }]], + ['/clients',[ { :controller => 'projects', :action => 'index' }, { :project_id => '1', :controller => 'project', :action => 'index' }, '/projects/1']], - ['/comment/20',[ { :id => 20 }, { :controller => 'comments', :action => 'show' }]], + ['/comment/20',[ { :id => 20 }, { :controller => 'comments', :action => 'show' }, '/comments/show']], ['/comment/20',[ { :controller => 'comments', :id => 20, :action => 'show' }]], ['/comments/boo',[ { :controller => 'comments', :action => 'boo' }]], @@ -144,24 +147,21 @@ module ActionPack ['/notes',[ { :page_id => nil, :controller => 'notes' }]], ['/notes',[ { :controller => 'notes' }]], ['/notes/print',[ { :controller => 'notes', :action => 'print' }]], - ['/notes/print',[ {}, { :controller => 'notes', :action => 'print' }]], - - ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1' }]], - ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1', :foo => 'bar' }]], - ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1' }]], - ['/notes/index/1',[ { :action => 'index' }, { :controller => 'notes', :id => '1' }]], - ['/notes/index/1',[ {}, { :controller => 'notes', :id => '1' }]], - ['/notes/show/1',[ {}, { :controller => 'notes', :action => 'show', :id => '1' }]], - ['/notes/index/1',[ { :controller => 'notes', :id => '1' }, { :foo => 'bar' }]], - ['/posts',[ { :controller => 'posts' }, { :controller => 'notes', :action => 'show', :id => '1' }]], - ['/notes/list',[ { :action => 'list' }, { :controller => 'notes', :action => 'show', :id => '1' }]], + ['/notes/print',[ {}, { :controller => 'notes', :action => 'print' }, '/notes/print']], + + ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :action => 'index', :id => '1' }, '/notes/index/1']], + ['/notes/index/1',[ { :controller => 'notes' }, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']], + ['/notes/index/1',[ { :action => 'index' }, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']], + ['/notes/index/1',[ {}, { :controller => 'notes', :id => '1', :action => 'index' }, '/notes/index/1']], + ['/notes/show/1',[ {}, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']], + ['/posts',[ { :controller => 'posts' }, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']], + ['/notes/list',[ { :action => 'list' }, { :controller => 'notes', :action => 'show', :id => '1' }, '/notes/show/1']], ['/posts/ping',[ { :controller => 'posts', :action => 'ping' }]], ['/posts/show/1',[ { :controller => 'posts', :action => 'show', :id => '1' }]], ['/posts',[ { :controller => 'posts' }]], ['/posts',[ { :controller => 'posts', :action => 'index' }]], - ['/posts',[ { :controller => 'posts' }, { :controller => 'posts', :action => 'index' }]], - ['/posts/create',[ { :action => 'create' }, { :controller => 'posts' }]], + ['/posts/create',[ { :action => 'create' }, {:day=>nil, :month=>nil, :controller=>"posts", :action=>"show_date"}, '/blog']], ['/posts?foo=bar',[ { :controller => 'posts', :foo => 'bar' }]], ['/posts?foo%5B%5D=bar&foo%5B%5D=baz', [{ :controller => 'posts', :foo => ['bar', 'baz'] }]], ['/posts?page=2', [{ :controller => 'posts', :page => 2 }]], @@ -169,9 +169,20 @@ module ActionPack ['/news.rss', [{ :controller => 'news', :action => 'index', :format => 'rss' }]], ].each_with_index do |(url, params), i| - define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do - assert_equal url, url_for(@routes, *params), params.inspect - end + if params.length > 1 + hash, path_params, route = *params + hash[:only_path] = true + + define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do + get URI('http://test.host' + route.to_s) + assert_equal path_params, controller.request.path_parameters + assert_equal url, controller.url_for(hash), params.inspect + end + else + define_method("test_#{url.gsub(/\W/, '_')}_#{i}") do + assert_equal url, url_for(@routes, params.first), params.inspect + end + end end end end diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index a8035e5bd7..9f086af664 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -11,6 +11,26 @@ module AbstractController W.default_url_options.clear end + def test_nested_optional + klass = Class.new { + include ActionDispatch::Routing::RouteSet.new.tap { |r| + r.draw { + get "/foo/(:bar/(:baz))/:zot", :as => 'fun', + :controller => :articles, + :action => :index + } + }.url_helpers + self.default_url_options[:host] = 'example.com' + } + + path = klass.new.fun_path({:controller => :articles, + :baz => "baz", + :zot => "zot", + :only_path => true }) + # :bar key isn't provided + assert_equal '/foo/zot', path + end + def add_host! W.default_url_options[:host] = 'www.basecamphq.com' end @@ -75,7 +95,7 @@ module AbstractController end def test_subdomain_may_be_object - model = mock(:to_param => 'api') + 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') @@ -169,6 +189,18 @@ module AbstractController ) end + def test_without_protocol_and_with_port + 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 => false) + ) + end + def test_trailing_slash add_host! options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'} @@ -255,12 +287,12 @@ module AbstractController # We need to create a new class in order to install the new named route. kls = Class.new { include set.url_helpers } controller = kls.new - assert controller.respond_to?(:home_url) + assert_respond_to controller, :home_url assert_equal '/brave/new/world', - controller.send(:url_for, :controller => 'brave', :action => 'new', :id => 'world', :only_path => true) + controller.url_for(:controller => 'brave', :action => 'new', :id => 'world', :only_path => true) - assert_equal("/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'unused', :only_path => true)) - assert_equal("/home/sweet/home/alabama", controller.send(:home_path, 'alabama')) + assert_equal("/home/sweet/home/alabama", controller.home_path(:user => 'alabama', :host => 'unused', :only_path => true)) + assert_equal("/home/sweet/home/alabama", controller.home_path('alabama')) end end |