diff options
Diffstat (limited to 'actionpack/test')
33 files changed, 1197 insertions, 541 deletions
diff --git a/actionpack/test/abstract/helper_test.rb b/actionpack/test/abstract/helper_test.rb index 5a363c9aa5..6c28f01fa4 100644 --- a/actionpack/test/abstract/helper_test.rb +++ b/actionpack/test/abstract/helper_test.rb @@ -1,17 +1,17 @@ require 'abstract_unit' +ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers' + module AbstractController module Testing class ControllerWithHelpers < AbstractController::Base include AbstractController::RenderingController include Helpers - - def render(string) - super(:_template_name => string) + + def with_module + render :inline => "Module <%= included_method %>" end - - append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) end module HelperyTest @@ -20,24 +20,61 @@ module AbstractController end end - class MyHelpers1 < ControllerWithHelpers + class AbstractHelpers < ControllerWithHelpers helper(HelperyTest) do def helpery_test "World" end end - - def index - render "helper_test.erb" + + helper :abc + + def with_block + render :inline => "Hello <%= helpery_test %>" + end + + def with_symbol + render :inline => "I respond to bare_a: <%= respond_to?(:bare_a) %>" + end + end + + class AbstractHelpersBlock < ControllerWithHelpers + helper do + include HelperyTest end end - + class TestHelpers < ActiveSupport::TestCase - def test_helpers - controller = MyHelpers1.new - controller.process(:index) - assert_equal "Hello World : Included", controller.response_body + + def setup + @controller = AbstractHelpers.new end + + def test_helpers_with_block + @controller.process(:with_block) + assert_equal "Hello World", @controller.response_body + end + + def test_helpers_with_module + @controller.process(:with_module) + assert_equal "Module Included", @controller.response_body + end + + def test_helpers_with_symbol + @controller.process(:with_symbol) + assert_equal "I respond to bare_a: true", @controller.response_body + end + + def test_declare_missing_helper + assert_raise(MissingSourceFile) { AbstractHelpers.helper :missing } + end + + def test_helpers_with_module_through_block + @controller = AbstractHelpersBlock.new + @controller.process(:with_module) + assert_equal "Module Included", @controller.response_body + end + end end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index 453d31826e..9c29696ad5 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -17,17 +17,6 @@ module AbstractControllerTests "layouts/omg.erb" => "OMGHI2U <%= yield %>", "layouts/with_false_layout.erb" => "False Layout <%= yield %>" )] - - def self.controller_path - @controller_path ||= self.name.sub(/Controller$/, '').underscore - end - - def controller_path() self.class.controller_path end - - def render_to_body(options) - options[:_layout] = _default_layout({}) - super - end end class Blank < Base @@ -44,6 +33,22 @@ module AbstractControllerTests def index render :_template => ActionView::TextTemplate.new("Hello string!") end + + def overwrite_default + render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => :default + end + + def overwrite_false + render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => false + end + + def overwrite_string + render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => "omg" + end + + def overwrite_skip + render :text => "Hello text!" + end end class WithStringChild < WithString @@ -153,7 +158,31 @@ module AbstractControllerTests controller.process(:index) assert_equal "With String Hello string!", controller.response_body end - + + test "when layout is overwriten by :default in render, render default layout" do + controller = WithString.new + controller.process(:overwrite_default) + assert_equal "With String Hello string!", controller.response_body + end + + test "when layout is overwriten by string in render, render new layout" do + controller = WithString.new + controller.process(:overwrite_string) + assert_equal "OMGHI2U Hello string!", controller.response_body + end + + test "when layout is overwriten by false in render, render no layout" do + controller = WithString.new + controller.process(:overwrite_false) + assert_equal "Hello string!", controller.response_body + end + + test "when text is rendered, render no layout" do + controller = WithString.new + controller.process(:overwrite_skip) + assert_equal "Hello text!", controller.response_body + end + test "when layout is specified as a string, but the layout is missing, raise an exception" do assert_raises(ActionView::MissingTemplate) { WithMissingLayout.new.process(:index) } end diff --git a/actionpack/test/abstract/localized_cache_test.rb b/actionpack/test/abstract/localized_cache_test.rb new file mode 100644 index 0000000000..6f9bb693f7 --- /dev/null +++ b/actionpack/test/abstract/localized_cache_test.rb @@ -0,0 +1,57 @@ +require 'abstract_unit' + +module AbstractController + module Testing + + class CachedController < AbstractController::Base + include AbstractController::RenderingController + include AbstractController::LocalizedCache + + self.view_paths = [ActionView::FixtureResolver.new( + "default.erb" => "With Default", + "template.erb" => "With Template", + "some/file.erb" => "With File", + "template_name.erb" => "With Template Name" + )] + end + + class TestLocalizedCache < ActiveSupport::TestCase + + def setup + @controller = CachedController.new + CachedController.clear_template_caches! + end + + def test_templates_are_cached + @controller.render :template => "default.erb" + assert_equal "With Default", @controller.response_body + + cached = @controller.class.template_cache + assert_equal 1, cached.size + assert_kind_of ActionView::Template, cached.values.first["default.erb"] + end + + def test_cache_is_used + CachedController.new.render :template => "default.erb" + + @controller.expects(:find_template).never + @controller.render :template => "default.erb" + + assert_equal 1, @controller.class.template_cache.size + end + + def test_cache_changes_with_locale + CachedController.new.render :template => "default.erb" + + I18n.locale = :es + @controller.render :template => "default.erb" + + assert_equal 2, @controller.class.template_cache.size + ensure + I18n.locale = :en + end + + end + + end +end diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb new file mode 100644 index 0000000000..45a4763fe4 --- /dev/null +++ b/actionpack/test/abstract/render_test.rb @@ -0,0 +1,88 @@ +require 'abstract_unit' + +module AbstractController + module Testing + + class ControllerRenderer < AbstractController::Base + include AbstractController::RenderingController + + self.view_paths = [ActionView::FixtureResolver.new( + "default.erb" => "With Default", + "template.erb" => "With Template", + "some/file.erb" => "With File", + "template_name.erb" => "With Template Name" + )] + + def template + render :template => "template" + end + + def file + render :file => "some/file" + end + + def inline + render :inline => "With <%= :Inline %>" + end + + def text + render :text => "With Text" + end + + def default + render + end + + def template_name + render :_template_name => :template_name + end + + def object + render :_template => ActionView::TextTemplate.new("With Object") + end + end + + class TestRenderer < ActiveSupport::TestCase + + def setup + @controller = ControllerRenderer.new + end + + def test_render_template + @controller.process(:template) + assert_equal "With Template", @controller.response_body + end + + def test_render_file + @controller.process(:file) + assert_equal "With File", @controller.response_body + end + + def test_render_inline + @controller.process(:inline) + assert_equal "With Inline", @controller.response_body + end + + def test_render_text + @controller.process(:text) + assert_equal "With Text", @controller.response_body + end + + def test_render_default + @controller.process(:default) + assert_equal "With Default", @controller.response_body + end + + def test_render_template_name + @controller.process(:template_name) + assert_equal "With Template Name", @controller.response_body + end + + def test_render_object + @controller.process(:object) + assert_equal "With Object", @controller.response_body + end + + end + end +end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index f7a1564f90..214d79cd87 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,13 +1,12 @@ -bundled = "#{File.dirname(__FILE__)}/../vendor/gems/environment" -if File.exist?("#{bundled}.rb") - require bundled -else - $:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib" - $:.unshift "#{File.dirname(__FILE__)}/../../activemodel/lib" +root = File.expand_path('../../..', __FILE__) +begin + require "#{root}/vendor/gems/environment" +rescue LoadError + $:.unshift "#{root}/activesupport/lib" + $:.unshift "#{root}/activemodel/lib" end $:.unshift(File.dirname(__FILE__) + '/../lib') - $:.unshift(File.dirname(__FILE__) + '/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') $:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers') @@ -106,6 +105,26 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase self.app = build_app + class StubDispatcher + def self.new(*args) + lambda { |env| + params = env['action_dispatch.request.path_parameters'] + controller, action = params[:controller], params[:action] + [200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]] + } + end + end + + def self.stub_controllers + old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher + ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher } + ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher } + yield ActionDispatch::Routing::RouteSet.new + ensure + ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher } + ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher } + end + def with_routing(&block) real_routes = ActionController::Routing::Routes ActionController::Routing.module_eval { remove_const :Routes } diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 37f1f6dff8..ad744421db 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -98,14 +98,6 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - def test_formatted_url_helper_is_deprecated - with_test_routes do - assert_deprecated do - formatted_polymorphic_url([@project, :pdf]) - end - end - end - def test_format_option with_test_routes do @project.save @@ -251,6 +243,12 @@ class PolymorphicRoutesTest < ActionController::TestCase end end + def test_with_array_containing_symbols + with_test_routes do + assert_equal "http://example.com/series/new", polymorphic_url([:new, :series]) + end + end + def test_with_hash with_test_routes do @project.save diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index b97ceb4594..b57550a69a 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -10,12 +10,12 @@ module Submodule def public_action render :nothing => true end - + hide_action :hidden_action def hidden_action raise "Noooo!" end - + def another_hidden_action end hide_action :another_hidden_action @@ -30,25 +30,25 @@ class NonEmptyController < ActionController::Base def public_action render :nothing => true end - + hide_action :hidden_action def hidden_action end end class MethodMissingController < ActionController::Base - + hide_action :shouldnt_be_called def shouldnt_be_called raise "NO WAY!" end - + protected - + def method_missing(selector) render :text => selector.to_s end - + end class DefaultUrlOptionsController < ActionController::Base @@ -79,7 +79,7 @@ class ControllerInstanceTests < Test::Unit::TestCase @empty = EmptyController.new @contained = Submodule::ContainedEmptyController.new @empty_controllers = [@empty, @contained, Submodule::SubclassedController.new] - + @non_empty_controllers = [NonEmptyController.new, Submodule::ContainedNonEmptyController.new] end @@ -135,24 +135,24 @@ class PerformActionTest < ActionController::TestCase rescue_action_in_public! end - + def test_get_on_priv_should_show_selector use_controller MethodMissingController get :shouldnt_be_called assert_response :success assert_equal 'shouldnt_be_called', @response.body end - + def test_method_missing_is_not_an_action_name use_controller MethodMissingController assert ! @controller.__send__(:action_method?, 'method_missing') - + get :method_missing assert_response :success assert_equal 'method_missing', @response.body end - + def test_get_on_hidden_should_fail use_controller NonEmptyController assert_raise(ActionController::UnknownAction) { get :hidden_action } diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 495b431307..3ce90b6ccf 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -228,12 +228,16 @@ class ActionCachingMockController @mock_url_for end + def params + request.parameters + end + def request mocked_path = @mock_path Object.new.instance_eval(<<-EVAL) def path; '#{@mock_path}' end def format; 'all' end - def cache_format; nil end + def parameters; {:format => nil}; end self EVAL end @@ -466,7 +470,7 @@ class ActionCacheTest < ActionController::TestCase @mock_controller.mock_url_for = 'http://example.org/' @mock_controller.mock_path = '/' - assert_equal 'example.org/index', @path_class.path_for(@mock_controller, {}) + assert_equal 'example.org/index', @path_class.new(@mock_controller, {}).path end def test_file_extensions @@ -628,20 +632,13 @@ class FragmentCachingTest < ActionController::TestCase def test_fragment_for_logging fragment_computed = false - - listener = [] - ActiveSupport::Orchestra.register listener + ActiveSupport::Notifications.queue.expects(:publish).times(2) buffer = 'generated till now -> ' @controller.fragment_for(buffer, 'expensive') { fragment_computed = true } - assert_equal 1, listener.count { |e| e.name == :fragment_exist? } - assert_equal 1, listener.count { |e| e.name == :write_fragment } - assert fragment_computed assert_equal 'generated till now -> ', buffer - ensure - ActiveSupport::Orchestra.unregister listener end end diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index b429cbf0e6..53d4364576 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -106,7 +106,7 @@ class CookieTest < ActionController::TestCase def test_cookiejar_accessor @request.cookies["user_name"] = "david" @controller.request = @request - jar = ActionController::CookieJar.new(@controller) + jar = ActionController::CookieJar.build(@controller.request, @controller.response) assert_equal "david", jar["user_name"] assert_equal nil, jar["something_else"] end @@ -114,14 +114,14 @@ class CookieTest < ActionController::TestCase def test_cookiejar_accessor_with_array_value @request.cookies["pages"] = %w{1 2 3} @controller.request = @request - jar = ActionController::CookieJar.new(@controller) + jar = ActionController::CookieJar.build(@controller.request, @controller.response) assert_equal %w{1 2 3}, jar["pages"] end def test_cookiejar_delete_removes_item_and_returns_its_value @request.cookies["user_name"] = "david" @controller.response = @response - jar = ActionController::CookieJar.new(@controller) + jar = ActionController::CookieJar.build(@controller.request, @controller.response) assert_equal "david", jar.delete("user_name") end @@ -131,9 +131,8 @@ class CookieTest < ActionController::TestCase end def test_cookies_persist_throughout_request - get :authenticate - cookies = @controller.send(:cookies) - assert_equal 'david', cookies['user_name'] + response = get :authenticate + assert response.headers["Set-Cookie"] =~ /user_name=david/ end private diff --git a/actionpack/test/controller/filter_params_test.rb b/actionpack/test/controller/filter_params_test.rb index 19232c6bc9..43bef34885 100644 --- a/actionpack/test/controller/filter_params_test.rb +++ b/actionpack/test/controller/filter_params_test.rb @@ -19,23 +19,23 @@ class FilterParamTest < ActionController::TestCase def method_missing(method, *args) @logged ||= [] - @logged << args.first + @logged << args.first unless block_given? + @logged << yield if block_given? end end setup :set_logger + def test_filter_parameters_must_have_one_word + assert_raises RuntimeError do + FilterParamController.filter_parameter_logging + end + end + def test_filter_parameters assert FilterParamController.respond_to?(:filter_parameter_logging) - assert !@controller.respond_to?(:filter_parameters) - - FilterParamController.filter_parameter_logging - assert @controller.respond_to?(:filter_parameters) - test_hashes = [[{},{},[]], - [{'foo'=>nil},{'foo'=>nil},[]], - [{'foo'=>'bar'},{'foo'=>'bar'},[]], - [{'foo'=>1},{'foo'=>1},[]], + test_hashes = [ [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'], [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'], [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'], diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 23149fee27..12539739aa 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -57,40 +57,6 @@ class HelperTest < Test::Unit::TestCase assert_equal [], missing_methods end - def test_declare_helper - require 'abc_helper' - self.test_helper = AbcHelper - assert_equal expected_helper_methods, missing_methods - assert_nothing_raised { @controller_class.helper :abc } - assert_equal [], missing_methods - end - - def test_declare_missing_helper - assert_equal expected_helper_methods, missing_methods - assert_raise(MissingSourceFile) { @controller_class.helper :missing } - end - - def test_declare_missing_file_from_helper - require 'broken_helper' - rescue LoadError => e - assert_nil(/\bbroken_helper\b/.match(e.to_s)[1]) - end - - def test_helper_block - assert_nothing_raised { - @controller_class.helper { def block_helper_method; end } - } - assert master_helper_methods.include?('block_helper_method') - end - - def test_helper_block_include - assert_equal expected_helper_methods, missing_methods - assert_nothing_raised { - @controller_class.helper { include HelperTest::TestHelper } - } - assert [], missing_methods - end - def test_helper_method assert_nothing_raised { @controller_class.helper_method :delegate_method } assert master_helper_methods.include?('delegate_method') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index fe95fb5750..d6e2a5a974 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -390,7 +390,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest def with_test_route_set with_routing do |set| set.draw do |map| - map.connect "/:action", :controller => "integration_process_test/integration" + match ':action', :to => IntegrationController end yield end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index a79648396c..b070f925d4 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -760,6 +760,14 @@ class RespondWithControllerTest < ActionController::TestCase assert_equal "Resource name is david", @response.body end + def test_using_resource_with_responder + RespondWithController.responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" } + get :using_resource + assert_equal "Resource name is david", @response.body + ensure + RespondWithController.responder = ActionController::Responder + end + def test_not_acceptable @request.accept = "application/xml" get :using_defaults diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 2db524ca4b..ac8dad7c42 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -73,6 +73,11 @@ class TestController < ActionController::Base render :action => 'hello_world' end + def conditional_hello_with_expires_now + expires_now + render :action => 'hello_world' + end + def conditional_hello_with_bangs render :action => 'hello_world' end @@ -1321,6 +1326,11 @@ class ExpiresInRenderTest < ActionController::TestCase get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax assert_equal "max-age=60, public, max-stale=18000", @response.headers["Cache-Control"] end + + def test_expires_now + get :conditional_hello_with_expires_now + assert_equal "no-cache", @response.headers["Cache-Control"] + end end diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 054a9f2aaf..2b1f532b8d 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -343,9 +343,9 @@ class RescueTest < ActionController::IntegrationTest def with_test_routing with_routing do |set| set.draw do |map| - map.connect 'foo', :controller => "rescue_test/test", :action => 'foo' - map.connect 'invalid', :controller => "rescue_test/test", :action => 'invalid' - map.connect 'b00m', :controller => "rescue_test/test", :action => 'b00m' + match 'foo', :to => TestController.action(:foo) + match 'invalid', :to => TestController.action(:invalid) + match 'b00m', :to => TestController.action(:b00m) end yield end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 5b47de19ae..04e9acf855 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -41,7 +41,7 @@ class ResourcesTest < ActionController::TestCase end def test_should_arrange_actions - resource = ActionController::Resources::Resource.new(:messages, + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, :collection => { :rss => :get, :reorder => :post, :csv => :post }, :member => { :rss => :get, :atom => :get, :upload => :post, :fix => :post }, :new => { :preview => :get, :draft => :get }) @@ -54,18 +54,18 @@ class ResourcesTest < ActionController::TestCase end def test_should_resource_controller_name_equal_resource_name_by_default - resource = ActionController::Resources::Resource.new(:messages, {}) + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, {}) assert_equal 'messages', resource.controller end def test_should_resource_controller_name_equal_controller_option - resource = ActionController::Resources::Resource.new(:messages, :controller => 'posts') + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, :controller => 'posts') assert_equal 'posts', resource.controller end def test_should_all_singleton_paths_be_the_same [ :path, :nesting_path_prefix, :member_path ].each do |method| - resource = ActionController::Resources::SingletonResource.new(:messages, :path_prefix => 'admin') + resource = ActionDispatch::Routing::DeprecatedMapper::SingletonResource.new(:messages, :path_prefix => 'admin') assert_equal 'admin/messages', resource.send(method) end end @@ -121,7 +121,7 @@ class ResourcesTest < ActionController::TestCase end def test_override_paths_for_default_restful_actions - resource = ActionController::Resources::Resource.new(:messages, + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, :path_names => {:new => 'nuevo', :edit => 'editar'}) assert_equal resource.new_path, "#{resource.path}/nuevo" end @@ -135,7 +135,7 @@ class ResourcesTest < ActionController::TestCase def test_with_custom_conditions with_restful_routing :messages, :conditions => { :subdomain => 'app' } do - assert ActionController::Routing::Routes.recognize_path("/messages", :method => :get, :subdomain => 'app') + assert ActionDispatch::Routing::Routes.recognize_path("/messages", :method => :get, :subdomain => 'app') end end @@ -281,7 +281,7 @@ class ResourcesTest < ActionController::TestCase def test_with_member_action_and_requirement expected_options = {:controller => 'messages', :action => 'mark', :id => '1.1.1'} - + with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}, :member => { :mark => :get }) do assert_recognizes(expected_options, :path => 'messages/1.1.1/mark', :method => :get) end @@ -701,8 +701,8 @@ class ResourcesTest < ActionController::TestCase def test_should_not_allow_invalid_head_method_for_member_routes with_routing do |set| - set.draw do |map| - assert_raise(ArgumentError) do + assert_raise(ArgumentError) do + set.draw do |map| map.resources :messages, :member => {:something => :head} end end @@ -711,8 +711,8 @@ class ResourcesTest < ActionController::TestCase def test_should_not_allow_invalid_http_methods_for_member_routes with_routing do |set| - set.draw do |map| - assert_raise(ArgumentError) do + assert_raise(ArgumentError) do + set.draw do |map| map.resources :messages, :member => {:something => :invalid} end end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 7c88520bac..308e2a85b1 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -11,24 +11,15 @@ end ROUTING = ActionController::Routing -class ROUTING::RouteBuilder - attr_reader :warn_output - - def warn(msg) - (@warn_output ||= []) << msg - end -end - # See RFC 3986, section 3.3 for allowed path characters. class UriReservedCharactersRoutingTest < Test::Unit::TestCase def setup - ActionController::Routing.use_controllers! ['controller'] @set = ActionController::Routing::RouteSet.new @set.draw do |map| map.connect ':controller/:action/:variable/*additional' end - safe, unsafe = %w(: @ & = + $ , ;), %w(^ / ? # [ ]) + safe, unsafe = %w(: @ & = + $ , ;), %w(^ ? # [ ]) hex = unsafe.map { |char| '%' + char.unpack('H2').first.upcase } @segment = "#{safe.join}#{unsafe.join}".freeze @@ -36,8 +27,9 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase end def test_route_generation_escapes_unsafe_path_characters - assert_equal "/contr#{@segment}oller/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2", - @set.generate(:controller => "contr#{@segment}oller", + @set.generate(:controller => "content", :action => "act#{@segment}ion", :variable => "variable", :additional => "foo") + assert_equal "/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2", + @set.generate(:controller => "content", :action => "act#{@segment}ion", :variable => "var#{@segment}iable", :additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"]) @@ -52,7 +44,7 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase end def test_route_generation_allows_passing_non_string_values_to_generated_helper - assert_equal "/controller/action/variable/1/2", @set.generate(:controller => "controller", + assert_equal "/content/action/variable/1/2", @set.generate(:controller => "content", :action => "action", :variable => "variable", :additional => [1, 2]) @@ -118,8 +110,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase ActionController::Base.optimise_named_routes = true @rs = ::ActionController::Routing::RouteSet.new - - ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed) end def teardown @@ -366,10 +356,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F" assert results, "Recognition should have succeeded" assert_equal ['hello world', 'how are you?'], results[:path] - - results = rs.recognize_path "/file" - assert results, "Recognition should have succeeded" - assert_equal [], results[:path] end def test_paths_slashes_unescaped_with_ordered_parameters @@ -379,7 +365,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase # No / to %2F in URI, only for query params. x = setup_for_named_route - assert_equal("/file/hello/world", x.send(:path_path, 'hello/world')) + assert_equal("/file/hello/world", x.send(:path_path, ['hello', 'world'])) end def test_non_controllers_cannot_be_matched @@ -407,35 +393,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase rs.draw do |map| map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} end - exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") } - assert_match /^post_url failed to generate/, exception.message - from_match = exception.message.match(/from \{[^\}]+\}/).to_s - assert_match /:bad_param=>"foo"/, from_match - assert_match /:action=>"show"/, from_match - assert_match /:controller=>"post"/, from_match - - expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s - assert_no_match /:bad_param=>"foo"/, expected_match - assert_match /:action=>"show"/, expected_match - assert_match /:controller=>"post"/, expected_match - - diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s - assert_match /:bad_param=>"foo"/, diff_match - assert_no_match /:action=>"show"/, diff_match - assert_no_match /:controller=>"post"/, diff_match - end - - # this specifies the case where your formerly would get a very confusing error message with an empty diff - def test_should_have_better_error_message_when_options_diff_is_empty - rs.draw do |map| - map.content '/content/:query', :controller => 'content', :action => 'show' - end - - exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } - assert_match %r[:action=>"show"], exception.message - assert_match %r[:controller=>"content"], exception.message - assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message - assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message + assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") } end def test_dynamic_path_allowed @@ -503,17 +461,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) end - def test_recognition_with_uppercase_controller_name - @rs.draw {|m| m.connect ':controller/:action/:id' } - assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content")) - assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list")) - assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10")) - - # these used to work, before the routes rewrite, but support for this was pulled in the new version... - #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed")) - #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed")) - end - def test_requirement_should_prevent_optional_id rs.draw do |map| map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} @@ -760,12 +707,9 @@ class RouteSetTest < ActiveSupport::TestCase def default_route_set @default_route_set ||= begin - set = nil - ActionController::Routing.with_controllers(['accounts']) do - set = ROUTING::RouteSet.new - set.draw do |map| - map.connect '/:controller/:action/:id/' - end + set = ROUTING::RouteSet.new + set.draw do |map| + map.connect '/:controller/:action/:id/' end set end @@ -953,44 +897,38 @@ class RouteSetTest < ActiveSupport::TestCase end def test_draw_default_route - ActionController::Routing.with_controllers(['users']) do - set.draw do |map| - map.connect '/:controller/:action/:id' - end + set.draw do |map| + map.connect '/:controller/:action/:id' + end - assert_equal 1, set.routes.size + assert_equal 1, set.routes.size - assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10) - assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10) + assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10) + assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10) - assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10')) - assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/')) - end + assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10')) + assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/')) end def test_draw_default_route_with_default_controller - ActionController::Routing.with_controllers(['users']) do - set.draw do |map| - map.connect '/:controller/:action/:id', :controller => 'users' - end - assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/')) + set.draw do |map| + map.connect '/:controller/:action/:id', :controller => 'users' end + assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/')) end def test_route_with_parameter_shell - ActionController::Routing.with_controllers(['users', 'pages']) do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/ - map.connect '/:controller/:action/:id' - end + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/ + map.connect '/: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'}, 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 => 'show', :id => '10'}, set.recognize_path('/pages/show/10')) - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) - end + 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')) end def test_route_requirements_with_anchor_chars_are_invalid @@ -1019,14 +957,6 @@ class RouteSetTest < ActiveSupport::TestCase map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/ end end - assert_nothing_raised do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/ - end - assert_raise ActionController::RoutingError do - set.generate :controller => 'pages', :action => 'show', :id => 10 - end - end end def test_route_requirements_with_invalid_http_method_is_invalid @@ -1053,19 +983,6 @@ class RouteSetTest < ActiveSupport::TestCase end end - def test_non_path_route_requirements_match_all - set.draw do |map| - map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/ - end - assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis') - assert_raise ActionController::RoutingError do - set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis') - end - assert_raise ActionController::RoutingError do - set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david') - end - end - def test_recognize_with_encoded_id_and_regex set.draw do |map| map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/ @@ -1303,16 +1220,16 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal "/foo/bar/baz/7", url end - def test_id_is_not_impossibly_sticky - set.draw do |map| - map.connect 'foo/:number', :controller => "people", :action => "index" - map.connect ':controller/:action/:id' - end - - url = set.generate({:controller => "people", :action => "index", :number => 3}, - {:controller => "people", :action => "index", :id => "21"}) - assert_equal "/foo/3", url - end + # def test_id_is_not_impossibly_sticky + # set.draw do |map| + # map.connect 'foo/:number', :controller => "people", :action => "index" + # map.connect ':controller/:action/:id' + # end + # + # url = set.generate({:controller => "people", :action => "index", :number => 3}, + # {:controller => "people", :action => "index", :id => "21"}) + # assert_equal "/foo/3", url + # end def test_id_is_sticky_when_it_ought_to_be set.draw do |map| @@ -1375,20 +1292,20 @@ class RouteSetTest < ActiveSupport::TestCase set.draw do |map| map.connect ':controller/:action/:id' end - assert_equal '/post', set.generate( - {:controller => 'post', :action => 'index'}, - {:controller => 'post', :action => 'show', :id => '10'} + assert_equal '/books', set.generate( + {:controller => 'books', :action => 'index'}, + {:controller => 'books', :action => 'show', :id => '10'} ) end def test_query_params_will_be_shown_when_recalled set.draw do |map| - map.connect 'show_post/:parameter', :controller => 'post', :action => 'show' + map.connect 'show_weblog/:parameter', :controller => 'weblog', :action => 'show' map.connect ':controller/:action/:id' end - assert_equal '/post/edit?parameter=1', set.generate( + assert_equal '/weblog/edit?parameter=1', set.generate( {:action => 'edit', :parameter => 1}, - {:controller => 'post', :action => 'show', :parameter => 1} + {:controller => 'weblog', :action => 'show', :parameter => 1} ) end @@ -1410,23 +1327,9 @@ class RouteSetTest < ActiveSupport::TestCase def test_expiry_determination_should_consider_values_with_to_param set.draw { |map| map.connect 'projects/:project_id/:controller/:action' } - assert_equal '/projects/1/post/show', set.generate( + assert_equal '/projects/1/weblog/show', set.generate( {:action => 'show', :project_id => 1}, - {:controller => 'post', :action => 'show', :project_id => '1'}) - end - - def test_generate_all - set.draw do |map| - map.connect 'show_post/:id', :controller => 'post', :action => 'show' - map.connect ':controller/:action/:id' - end - all = set.generate( - {:action => 'show', :id => 10, :generate_all => true}, - {:controller => 'post', :action => 'show'} - ) - assert_equal 2, all.length - assert_equal '/show_post/10', all.first - assert_equal '/post/show/10', all.last + {:controller => 'weblog', :action => 'show', :project_id => '1'}) end def test_named_route_in_nested_resource @@ -1603,101 +1506,53 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named')) end - - def test_interpolation_chunk_should_respect_raw - ActionController::Routing.with_controllers(['hello']) do - set.draw do |map| - map.connect '/Hello World', :controller => 'hello' - end - - assert_equal '/Hello%20World', set.generate(:controller => 'hello') - assert_equal({:controller => "hello", :action => "index"}, set.recognize_path('/Hello World')) - assert_raise(ActionController::RoutingError) { set.recognize_path('/Hello%20World') } - end - end - - def test_value_should_not_be_double_unescaped - ActionController::Routing.with_controllers(['foo']) do - set.draw do |map| - map.connect '/Карта', :controller => 'foo' - end - - assert_equal '/%D0%9A%D0%B0%D1%80%D1%82%D0%B0', set.generate(:controller => 'foo') - assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Карта')) - assert_raise(ActionController::RoutingError) { set.recognize_path('/%D0%9A%D0%B0%D1%80%D1%82%D0%B0') } - end - end - - def test_regexp_chunk_should_escape_specials - ActionController::Routing.with_controllers(['foo', 'bar']) do - set.draw do |map| - map.connect '/Hello*World', :controller => 'foo' - map.connect '/HelloWorld', :controller => 'bar' - end - - assert_equal '/Hello*World', set.generate(:controller => 'foo') - assert_equal '/HelloWorld', set.generate(:controller => 'bar') - - assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Hello*World')) - assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/HelloWorld')) - end - end - def test_regexp_chunk_should_add_question_mark_for_optionals - ActionController::Routing.with_controllers(['foo', 'bar']) do - set.draw do |map| - map.connect '/', :controller => 'foo' - map.connect '/hello', :controller => 'bar' - end + set.draw do |map| + map.connect '/', :controller => 'foo' + map.connect '/hello', :controller => 'bar' + end - assert_equal '/', set.generate(:controller => 'foo') - assert_equal '/hello', set.generate(:controller => 'bar') + assert_equal '/', set.generate(:controller => 'foo') + assert_equal '/hello', set.generate(:controller => 'bar') - assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/')) - assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello')) - end + assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/')) + assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello')) end def test_assign_route_options_with_anchor_chars - ActionController::Routing.with_controllers(['cars']) do - set.draw do |map| - map.connect '/cars/:action/:person/:car/', :controller => 'cars' - end + set.draw do |map| + map.connect '/cars/:action/:person/:car/', :controller => 'cars' + end - assert_equal '/cars/buy/1/2', set.generate(:controller => 'cars', :action => 'buy', :person => '1', :car => '2') + assert_equal '/cars/buy/1/2', set.generate(:controller => 'cars', :action => 'buy', :person => '1', :car => '2') - assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2')) - end + assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2')) end def test_segmentation_of_dot_path - ActionController::Routing.with_controllers(['books']) do - set.draw do |map| - map.connect '/books/:action.rss', :controller => 'books' - end + set.draw do |map| + map.connect '/books/:action.rss', :controller => 'books' + end - assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list') + assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list') - assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss')) - end + assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss')) end def test_segmentation_of_dynamic_dot_path - ActionController::Routing.with_controllers(['books']) do - set.draw do |map| - map.connect '/books/:action.:format', :controller => 'books' - end + set.draw do |map| + map.connect '/books/:action.:format', :controller => 'books' + end - assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list', :format => 'rss') - assert_equal '/books/list.xml', set.generate(:controller => 'books', :action => 'list', :format => 'xml') - assert_equal '/books/list', set.generate(:controller => 'books', :action => 'list') - assert_equal '/books', set.generate(:controller => 'books', :action => 'index') + assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list', :format => 'rss') + assert_equal '/books/list.xml', set.generate(:controller => 'books', :action => 'list', :format => 'xml') + assert_equal '/books/list', set.generate(:controller => 'books', :action => 'list') + assert_equal '/books', set.generate(:controller => 'books', :action => 'index') - assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss')) - assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml')) - assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list')) - assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books')) - end + assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss')) + assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml')) + assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list')) + assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books')) end def test_slashes_are_implied @@ -1752,7 +1607,6 @@ class RouteSetTest < ActiveSupport::TestCase def test_default_route_should_uri_escape_pluses expected = { :controller => 'pages', :action => 'show', :id => 'hello world' } - assert_equal expected, default_route_set.recognize_path('/pages/show/hello world') assert_equal expected, default_route_set.recognize_path('/pages/show/hello%20world') assert_equal '/pages/show/hello%20world', default_route_set.generate(expected, expected) @@ -1762,52 +1616,44 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal '/pages/show/hello+world', default_route_set.generate(expected, expected) end - def test_parameter_shell - page_url = ROUTING::Route.new - page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/} - assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell) - end - - def test_defaults - route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html" - assert_equal( - { :controller => "users", :action => "show", :format => "html" }, - route.defaults) - end - - def test_builder_complains_without_controller - assert_raise(ArgumentError) do - ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index" - end - end - def test_build_empty_query_string - assert_equal '/foo', default_route_set.generate({:controller => 'foo'}) + assert_uri_equal '/foo', default_route_set.generate({:controller => 'foo'}) end def test_build_query_string_with_nil_value - assert_equal '/foo', default_route_set.generate({:controller => 'foo', :x => nil}) + assert_uri_equal '/foo', default_route_set.generate({:controller => 'foo', :x => nil}) end def test_simple_build_query_string - assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => '1', :y => '2'}) + assert_uri_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => '1', :y => '2'}) end def test_convert_ints_build_query_string - assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => 1, :y => 2}) + assert_uri_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => 1, :y => 2}) end def test_escape_spaces_build_query_string - assert_equal '/foo?x=hello+world&y=goodbye+world', default_route_set.generate({:controller => 'foo', :x => 'hello world', :y => 'goodbye world'}) + assert_uri_equal '/foo?x=hello+world&y=goodbye+world', default_route_set.generate({:controller => 'foo', :x => 'hello world', :y => 'goodbye world'}) end def test_expand_array_build_query_string - assert_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]}) + assert_uri_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]}) end def test_escape_spaces_build_query_string_selected_keys - assert_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'}) + assert_uri_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'}) end + + private + def assert_uri_equal(expected, actual) + assert_equal(sort_query_string_params(expected), sort_query_string_params(actual)) + end + + def sort_query_string_params(uri) + path, qs = uri.split('?') + qs = qs.split('&').sort.join('&') if qs + qs ? "#{path}?#{qs}" : path + end end class RouteLoadingTest < Test::Unit::TestCase @@ -1888,3 +1734,315 @@ class RouteLoadingTest < Test::Unit::TestCase ActionController::Routing::Routes end end + +class RackMountIntegrationTests < ActiveSupport::TestCase + Model = Struct.new(:to_param) + + Mapping = lambda { |map| + map.namespace :admin do |admin| + admin.resources :users + end + + map.namespace 'api' do |api| + api.root :controller => 'users' + end + + map.connect 'blog/:year/:month/:day', + :controller => 'posts', + :action => 'show_date', + :requirements => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/}, + :day => nil, + :month => nil + + map.blog('archive/:year', :controller => 'archive', :action => 'index', + :defaults => { :year => nil }, + :requirements => { :year => /\d{4}/ } + ) + + map.resources :people + map.connect 'legacy/people', :controller => 'people', :action => 'index', :legacy => 'true' + + map.connect 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol + map.connect 'id_default/:id', :controller => 'foo', :action => 'id_default', :id => 1 + map.connect 'get_or_post', :controller => 'foo', :action => 'get_or_post', :conditions => { :method => [:get, :post] } + map.connect 'optional/:optional', :controller => 'posts', :action => 'index' + map.project 'projects/:project_id', :controller => 'project' + map.connect 'clients', :controller => 'projects', :action => 'index' + + map.connect 'ignorecase/geocode/:postalcode', :controller => 'geocode', + :action => 'show', :postalcode => /hx\d\d-\d[a-z]{2}/i + map.geocode 'extended/geocode/:postalcode', :controller => 'geocode', + :action => 'show',:requirements => { + :postalcode => /# Postcode format + \d{5} #Prefix + (-\d{4})? #Suffix + /x + } + + map.connect '', :controller => 'news', :format => nil + map.connect 'news.:format', :controller => 'news' + + map.connect 'comment/:id/:action', :controller => 'comments', :action => 'show' + map.connect 'ws/:controller/:action/:id', :ws => true + map.connect 'account/:action', :controller => :account, :action => :subscription + map.connect 'pages/:page_id/:controller/:action/:id' + map.connect ':controller/ping', :action => 'ping' + map.connect ':controller/:action/:id' + } + + def setup + @routes = ActionController::Routing::RouteSet.new + @routes.draw(&Mapping) + end + + def test_add_route + @routes.clear! + + assert_raise(ActionController::RoutingError) do + @routes.draw do |map| + map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default) + map.connect ':controller/:action/:id' + end + end + end + + def test_recognize_path + assert_equal({:controller => 'admin/users', :action => 'index'}, @routes.recognize_path('/admin/users', :method => :get)) + assert_equal({:controller => 'admin/users', :action => 'create'}, @routes.recognize_path('/admin/users', :method => :post)) + assert_equal({:controller => 'admin/users', :action => 'new'}, @routes.recognize_path('/admin/users/new', :method => :get)) + assert_equal({:controller => 'admin/users', :action => 'show', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :get)) + assert_equal({:controller => 'admin/users', :action => 'update', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :put)) + assert_equal({:controller => 'admin/users', :action => 'destroy', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :delete)) + assert_equal({:controller => 'admin/users', :action => 'edit', :id => '1'}, @routes.recognize_path('/admin/users/1/edit', :method => :get)) + + assert_equal({:controller => 'admin/posts', :action => 'index'}, @routes.recognize_path('/admin/posts', :method => :get)) + assert_equal({:controller => 'admin/posts', :action => 'new'}, @routes.recognize_path('/admin/posts/new', :method => :get)) + + assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api', :method => :get)) + assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api/', :method => :get)) + + assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009'}, @routes.recognize_path('/blog/2009', :method => :get)) + assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01'}, @routes.recognize_path('/blog/2009/01', :method => :get)) + assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => '01'}, @routes.recognize_path('/blog/2009/01/01', :method => :get)) + assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/blog/123456789', :method => :get) } + + assert_equal({:controller => 'archive', :action => 'index', :year => '2010'}, @routes.recognize_path('/archive/2010')) + assert_equal({:controller => 'archive', :action => 'index'}, @routes.recognize_path('/archive')) + assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/archive/january') } + + assert_equal({:controller => 'people', :action => 'index'}, @routes.recognize_path('/people', :method => :get)) + assert_equal({:controller => 'people', :action => 'index', :format => 'xml'}, @routes.recognize_path('/people.xml', :method => :get)) + assert_equal({:controller => 'people', :action => 'create'}, @routes.recognize_path('/people', :method => :post)) + assert_equal({:controller => 'people', :action => 'new'}, @routes.recognize_path('/people/new', :method => :get)) + assert_equal({:controller => 'people', :action => 'show', :id => '1'}, @routes.recognize_path('/people/1', :method => :get)) + assert_equal({:controller => 'people', :action => 'show', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1.xml', :method => :get)) + assert_equal({:controller => 'people', :action => 'update', :id => '1'}, @routes.recognize_path('/people/1', :method => :put)) + assert_equal({:controller => 'people', :action => 'destroy', :id => '1'}, @routes.recognize_path('/people/1', :method => :delete)) + assert_equal({:controller => 'people', :action => 'edit', :id => '1'}, @routes.recognize_path('/people/1/edit', :method => :get)) + assert_equal({:controller => 'people', :action => 'edit', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1/edit.xml', :method => :get)) + + assert_equal({:controller => 'symbols', :action => 'show', :name => :as_symbol}, @routes.recognize_path('/symbols')) + assert_equal({:controller => 'foo', :action => 'id_default', :id => '1'}, @routes.recognize_path('/id_default/1')) + assert_equal({:controller => 'foo', :action => 'id_default', :id => '2'}, @routes.recognize_path('/id_default/2')) + assert_equal({:controller => 'foo', :action => 'id_default', :id => '1'}, @routes.recognize_path('/id_default')) + assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :get)) + assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :post)) + assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/get_or_post', :method => :put) } + assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/get_or_post', :method => :delete) } + + assert_equal({:controller => 'posts', :action => 'index', :optional => 'bar'}, @routes.recognize_path('/optional/bar')) + assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/optional') } + + assert_equal({:controller => 'posts', :action => 'show', :id => '1', :ws => true}, @routes.recognize_path('/ws/posts/show/1', :method => :get)) + assert_equal({:controller => 'posts', :action => 'list', :ws => true}, @routes.recognize_path('/ws/posts/list', :method => :get)) + assert_equal({:controller => 'posts', :action => 'index', :ws => true}, @routes.recognize_path('/ws/posts', :method => :get)) + + assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account', :method => :get)) + assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account/subscription', :method => :get)) + assert_equal({:controller => 'account', :action => 'billing'}, @routes.recognize_path('/account/billing', :method => :get)) + + assert_equal({:page_id => '1', :controller => 'notes', :action => 'index'}, @routes.recognize_path('/pages/1/notes', :method => :get)) + assert_equal({:page_id => '1', :controller => 'notes', :action => 'list'}, @routes.recognize_path('/pages/1/notes/list', :method => :get)) + assert_equal({:page_id => '1', :controller => 'notes', :action => 'show', :id => '2'}, @routes.recognize_path('/pages/1/notes/show/2', :method => :get)) + + assert_equal({:controller => 'posts', :action => 'ping'}, @routes.recognize_path('/posts/ping', :method => :get)) + assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts', :method => :get)) + assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts/index', :method => :get)) + assert_equal({:controller => 'posts', :action => 'show'}, @routes.recognize_path('/posts/show', :method => :get)) + assert_equal({:controller => 'posts', :action => 'show', :id => '1'}, @routes.recognize_path('/posts/show/1', :method => :get)) + assert_equal({:controller => 'posts', :action => 'create'}, @routes.recognize_path('/posts/create', :method => :post)) + + assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1az'}, @routes.recognize_path('/ignorecase/geocode/hx12-1az')) + assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1AZ'}, @routes.recognize_path('/ignorecase/geocode/hx12-1AZ')) + assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345-1234'}, @routes.recognize_path('/extended/geocode/12345-1234')) + assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345'}, @routes.recognize_path('/extended/geocode/12345')) + + assert_equal({:controller => 'news', :action => 'index', :format => nil}, @routes.recognize_path('/', :method => :get)) + assert_equal({:controller => 'news', :action => 'index', :format => 'rss'}, @routes.recognize_path('/news.rss', :method => :get)) + + assert_raise(ActionController::RoutingError) { @routes.recognize_path('/none', :method => :get) } + end + + def test_generate + assert_equal '/admin/users', @routes.generate(:use_route => 'admin_users') + assert_equal '/admin/users', @routes.generate(:controller => 'admin/users') + assert_equal '/admin/users', @routes.generate(:controller => 'admin/users', :action => 'index') + assert_equal '/admin/users', @routes.generate({:action => 'index'}, {:controller => 'admin/users'}) + assert_equal '/admin/users', @routes.generate({:controller => 'users', :action => 'index'}, {:controller => 'admin/accounts'}) + assert_equal '/people', @routes.generate({:controller => '/people', :action => 'index'}, {:controller => 'admin/accounts'}) + + assert_equal '/admin/posts', @routes.generate({:controller => 'admin/posts'}) + assert_equal '/admin/posts/new', @routes.generate({:controller => 'admin/posts', :action => 'new'}) + + assert_equal '/blog/2009', @routes.generate(:controller => 'posts', :action => 'show_date', :year => 2009) + assert_equal '/blog/2009/1', @routes.generate(:controller => 'posts', :action => 'show_date', :year => 2009, :month => 1) + assert_equal '/blog/2009/1/1', @routes.generate(:controller => 'posts', :action => 'show_date', :year => 2009, :month => 1, :day => 1) + + assert_equal '/archive/2010', @routes.generate(:controller => 'archive', :action => 'index', :year => '2010') + assert_equal '/archive', @routes.generate(:controller => 'archive', :action => 'index') + assert_equal '/archive?year=january', @routes.generate(:controller => 'archive', :action => 'index', :year => 'january') + + assert_equal '/people', @routes.generate(:use_route => 'people') + assert_equal '/people', @routes.generate(:use_route => 'people', :controller => 'people', :action => 'index') + assert_equal '/people.xml', @routes.generate(:use_route => 'people', :controller => 'people', :action => 'index', :format => 'xml') + assert_equal '/people', @routes.generate({:use_route => 'people', :controller => 'people', :action => 'index'}, {:controller => 'people', :action => 'index'}) + assert_equal '/people', @routes.generate(:controller => 'people') + assert_equal '/people', @routes.generate(:controller => 'people', :action => 'index') + assert_equal '/people', @routes.generate({:action => 'index'}, {:controller => 'people'}) + assert_equal '/people', @routes.generate({:action => 'index'}, {:controller => 'people', :action => 'show', :id => '1'}) + assert_equal '/people', @routes.generate({:controller => 'people', :action => 'index'}, {:controller => 'people', :action => 'show', :id => '1'}) + assert_equal '/people', @routes.generate({}, {:controller => 'people', :action => 'index'}) + assert_equal '/people/1', @routes.generate({:controller => 'people', :action => 'show'}, {:controller => 'people', :action => 'show', :id => '1'}) + assert_equal '/people/new', @routes.generate(:use_route => 'new_person') + assert_equal '/people/new', @routes.generate(:controller => 'people', :action => 'new') + assert_equal '/people/1', @routes.generate(:use_route => 'person', :id => '1') + assert_equal '/people/1', @routes.generate(:controller => 'people', :action => 'show', :id => '1') + assert_equal '/people/1.xml', @routes.generate(:controller => 'people', :action => 'show', :id => '1', :format => 'xml') + assert_equal '/people/1', @routes.generate(:controller => 'people', :action => 'show', :id => 1) + assert_equal '/people/1', @routes.generate(:controller => 'people', :action => 'show', :id => Model.new('1')) + assert_equal '/people/1', @routes.generate({:action => 'show', :id => '1'}, {:controller => 'people', :action => 'index'}) + assert_equal '/people/1', @routes.generate({:action => 'show', :id => 1}, {:controller => 'people', :action => 'show', :id => '1'}) + # assert_equal '/people', @routes.generate({:controller => 'people', :action => 'index'}, {:controller => 'people', :action => 'index', :id => '1'}) + assert_equal '/people', @routes.generate({:controller => 'people', :action => 'index'}, {:controller => 'people', :action => 'show', :id => '1'}) + assert_equal '/people/1', @routes.generate({}, {:controller => 'people', :action => 'show', :id => '1'}) + assert_equal '/people/1', @routes.generate({:controller => 'people', :action => 'show'}, {:controller => 'people', :action => 'index', :id => '1'}) + assert_equal '/people/1/edit', @routes.generate(:controller => 'people', :action => 'edit', :id => '1') + assert_equal '/people/1/edit.xml', @routes.generate(:controller => 'people', :action => 'edit', :id => '1', :format => 'xml') + assert_equal '/people/1/edit', @routes.generate(:use_route => 'edit_person', :id => '1') + assert_equal '/people/1?legacy=true', @routes.generate(:controller => 'people', :action => 'show', :id => '1', :legacy => 'true') + assert_equal '/people?legacy=true', @routes.generate(:controller => 'people', :action => 'index', :legacy => 'true') + + assert_equal '/id_default/2', @routes.generate(:controller => 'foo', :action => 'id_default', :id => '2') + assert_equal '/id_default', @routes.generate(:controller => 'foo', :action => 'id_default', :id => '1') + assert_equal '/id_default', @routes.generate(:controller => 'foo', :action => 'id_default', :id => 1) + assert_equal '/id_default', @routes.generate(:controller => 'foo', :action => 'id_default') + assert_equal '/optional/bar', @routes.generate(:controller => 'posts', :action => 'index', :optional => 'bar') + assert_equal '/posts', @routes.generate(:controller => 'posts', :action => 'index') + + assert_equal '/project', @routes.generate({:controller => 'project', :action => 'index'}) + assert_equal '/projects/1', @routes.generate({:controller => 'project', :action => 'index', :project_id => '1'}) + assert_equal '/projects/1', @routes.generate({:controller => 'project', :action => 'index'}, {:project_id => '1'}) + assert_raise(ActionController::RoutingError) { @routes.generate({:use_route => 'project', :controller => 'project', :action => 'index'}) } + assert_equal '/projects/1', @routes.generate({:use_route => 'project', :controller => 'project', :action => 'index', :project_id => '1'}) + assert_equal '/projects/1', @routes.generate({:use_route => 'project', :controller => 'project', :action => 'index'}, {:project_id => '1'}) + + assert_equal '/clients', @routes.generate(:controller => 'projects', :action => 'index') + assert_equal '/clients?project_id=1', @routes.generate(:controller => 'projects', :action => 'index', :project_id => '1') + assert_equal '/clients', @routes.generate({:controller => 'projects', :action => 'index'}, {:project_id => '1'}) + assert_equal '/clients', @routes.generate({:action => 'index'}, {:controller => 'projects', :action => 'index', :project_id => '1'}) + + assert_equal '/comment/20', @routes.generate({:id => 20}, {:controller => 'comments', :action => 'show'}) + assert_equal '/comment/20', @routes.generate(:controller => 'comments', :id => 20, :action => 'show') + assert_equal '/comments/boo', @routes.generate(:controller => 'comments', :action => 'boo') + + assert_equal '/ws/posts/show/1', @routes.generate(:controller => 'posts', :action => 'show', :id => '1', :ws => true) + assert_equal '/ws/posts', @routes.generate(:controller => 'posts', :action => 'index', :ws => true) + + assert_equal '/account', @routes.generate(:controller => 'account', :action => 'subscription') + assert_equal '/account/billing', @routes.generate(:controller => 'account', :action => 'billing') + + assert_equal '/pages/1/notes/show/1', @routes.generate(:page_id => '1', :controller => 'notes', :action => 'show', :id => '1') + assert_equal '/pages/1/notes/list', @routes.generate(:page_id => '1', :controller => 'notes', :action => 'list') + assert_equal '/pages/1/notes', @routes.generate(:page_id => '1', :controller => 'notes', :action => 'index') + assert_equal '/pages/1/notes', @routes.generate(:page_id => '1', :controller => 'notes') + assert_equal '/notes', @routes.generate(:page_id => nil, :controller => 'notes') + assert_equal '/notes', @routes.generate(:controller => 'notes') + assert_equal '/notes/print', @routes.generate(:controller => 'notes', :action => 'print') + assert_equal '/notes/print', @routes.generate({}, {:controller => 'notes', :action => 'print'}) + + assert_equal '/notes/index/1', @routes.generate({:controller => 'notes'}, {:controller => 'notes', :id => '1'}) + assert_equal '/notes/index/1', @routes.generate({:controller => 'notes'}, {:controller => 'notes', :id => '1', :foo => 'bar'}) + assert_equal '/notes/index/1', @routes.generate({:controller => 'notes'}, {:controller => 'notes', :id => '1'}) + assert_equal '/notes/index/1', @routes.generate({:action => 'index'}, {:controller => 'notes', :id => '1'}) + assert_equal '/notes/index/1', @routes.generate({}, {:controller => 'notes', :id => '1'}) + assert_equal '/notes/show/1', @routes.generate({}, {:controller => 'notes', :action => 'show', :id => '1'}) + assert_equal '/notes/index/1', @routes.generate({:controller => 'notes', :id => '1'}, {:foo => 'bar'}) + assert_equal '/posts', @routes.generate({:controller => 'posts'}, {:controller => 'notes', :action => 'show', :id => '1'}) + assert_equal '/notes/list', @routes.generate({:action => 'list'}, {:controller => 'notes', :action => 'show', :id => '1'}) + + assert_equal '/posts/ping', @routes.generate(:controller => 'posts', :action => 'ping') + assert_equal '/posts/show/1', @routes.generate(:controller => 'posts', :action => 'show', :id => '1') + assert_equal '/posts', @routes.generate(:controller => 'posts') + assert_equal '/posts', @routes.generate(:controller => 'posts', :action => 'index') + assert_equal '/posts', @routes.generate({:controller => 'posts'}, {:controller => 'posts', :action => 'index'}) + assert_equal '/posts/create', @routes.generate({:action => 'create'}, {:controller => 'posts'}) + assert_equal '/posts?foo=bar', @routes.generate(:controller => 'posts', :foo => 'bar') + assert_equal '/posts?foo%5B%5D=bar&foo%5B%5D=baz', @routes.generate(:controller => 'posts', :foo => ['bar', 'baz']) + assert_equal '/posts?page=2', @routes.generate(:controller => 'posts', :page => 2) + assert_equal '/posts?q%5Bfoo%5D%5Ba%5D=b', @routes.generate(:controller => 'posts', :q => { :foo => { :a => 'b'}}) + + assert_equal '/', @routes.generate(:controller => 'news', :action => 'index') + assert_equal '/', @routes.generate(:controller => 'news', :action => 'index', :format => nil) + assert_equal '/news.rss', @routes.generate(:controller => 'news', :action => 'index', :format => 'rss') + + + assert_raise(ActionController::RoutingError) { @routes.generate({:action => 'index'}) } + end + + def test_generate_extras + assert_equal ['/people', []], @routes.generate_extras(:controller => 'people') + assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :foo => 'bar') + assert_equal ['/people', []], @routes.generate_extras(:controller => 'people', :action => 'index') + assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'index', :foo => 'bar') + assert_equal ['/people/new', []], @routes.generate_extras(:controller => 'people', :action => 'new') + assert_equal ['/people/new', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'new', :foo => 'bar') + assert_equal ['/people/1', []], @routes.generate_extras(:controller => 'people', :action => 'show', :id => '1') + assert_equal ['/people/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'people', :action => 'show', :id => '1', :foo => '2', :bar => '3')) + assert_equal ['/people', [:person]], @routes.generate_extras(:controller => 'people', :action => 'create', :person => { :first_name => 'Josh', :last_name => 'Peek' }) + assert_equal ['/people', [:people]], @routes.generate_extras(:controller => 'people', :action => 'create', :people => ['Josh', 'Dave']) + + assert_equal ['/posts/show/1', []], @routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1') + assert_equal ['/posts/show/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1', :foo => '2', :bar => '3')) + assert_equal ['/posts', []], @routes.generate_extras(:controller => 'posts', :action => 'index') + assert_equal ['/posts', [:foo]], @routes.generate_extras(:controller => 'posts', :action => 'index', :foo => 'bar') + end + + def test_extras + params = {:controller => 'people'} + assert_equal [], @routes.extra_keys(params) + assert_equal({:controller => 'people'}, params) + + params = {:controller => 'people', :foo => 'bar'} + assert_equal [:foo], @routes.extra_keys(params) + assert_equal({:controller => 'people', :foo => 'bar'}, params) + + params = {:controller => 'people', :action => 'create', :person => { :name => 'Josh'}} + assert_equal [:person], @routes.extra_keys(params) + assert_equal({:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}, params) + end + + private + def sort_extras!(extras) + if extras.length == 2 + extras[1].sort! { |a, b| a.to_s <=> b.to_s } + end + extras + end + + def assert_raise(e) + result = yield + flunk "Did not raise #{e}, but returned #{result.inspect}" + rescue e + assert true + end +end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 4c4bf9ade4..3b14cbb2d8 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -224,9 +224,8 @@ class UrlWriterTests < ActionController::TestCase def test_named_routes with_routing do |set| set.draw do |map| - map.no_args '/this/is/verbose', :controller => 'home', :action => 'index' - map.home '/home/sweet/home/:user', :controller => 'home', :action => 'index' - map.connect ':controller/:action/:id' + match 'this/is/verbose', :to => 'home#index', :as => :no_args + match 'home/sweet/home/:user', :to => 'home#index', :as => :home end # We need to create a new class in order to install the new named route. @@ -264,7 +263,7 @@ class UrlWriterTests < ActionController::TestCase def test_only_path with_routing do |set| set.draw do |map| - map.home '/home/sweet/home/:user', :controller => 'home', :action => 'index' + match 'home/sweet/home/:user', :to => 'home#index', :as => :home map.connect ':controller/:action/:id' end @@ -321,8 +320,8 @@ class UrlWriterTests < ActionController::TestCase params = extract_params(url) assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query - assert_equal params[2], { 'query[person][position][]' => 'prof' }.to_query - assert_equal params[3], { 'query[person][position][]' => 'art director' }.to_query + assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query + assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query end def test_path_generation_for_symbol_parameter_keys @@ -334,7 +333,6 @@ class UrlWriterTests < ActionController::TestCase set.draw do |map| map.main '', :controller => 'posts', :format => nil map.resources :posts - map.connect ':controller/:action/:id' end # We need to create a new class in order to install the new named route. @@ -359,10 +357,10 @@ class UrlWriterTests < ActionController::TestCase controller = kls.new params = {:id => 1, :format => :xml} assert_deprecated do - assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params)) + assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params)) end assert_deprecated do - assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml)) + assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml)) end end end @@ -382,6 +380,6 @@ class UrlWriterTests < ActionController::TestCase private def extract_params(url) - url.split('?', 2).last.split('&') + url.split('?', 2).last.split('&').sort end end diff --git a/actionpack/test/controller/verification_test.rb b/actionpack/test/controller/verification_test.rb index 1a9eb65f29..63e8cf3e61 100644 --- a/actionpack/test/controller/verification_test.rb +++ b/actionpack/test/controller/verification_test.rb @@ -125,8 +125,8 @@ class VerificationTest < ActionController::TestCase assert_not_deprecated do with_routing do |set| set.draw do |map| - map.foo '/foo', :controller => 'test', :action => 'foo' - map.connect ":controller/:action/:id" + match 'foo', :to => 'test#foo', :as => :foo + match 'verification_test/:action', :to => TestController end get :guarded_one_for_named_route_test, :two => "not one" assert_redirected_to '/foo' diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb index db6cf7b330..3c2408de5f 100644 --- a/actionpack/test/dispatch/request/json_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb @@ -57,7 +57,7 @@ class JsonParamsParsingTest < ActionController::IntegrationTest def with_test_routing with_routing do |set| set.draw do |map| - map.connect ':action', :controller => "json_params_parsing_test/test" + match ':action', :to => TestController end yield end diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb index a31e326ddf..b764478d87 100644 --- a/actionpack/test/dispatch/request/query_string_parsing_test.rb +++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb @@ -109,7 +109,7 @@ class QueryStringParsingTest < ActionController::IntegrationTest def assert_parses(expected, actual) with_routing do |set| set.draw do |map| - map.connect ':action', :controller => "query_string_parsing_test/test" + match ':action', :to => TestController end get "/parse", actual diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb index 7167cdafac..e98a49980e 100644 --- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb @@ -130,7 +130,7 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest def with_test_routing with_routing do |set| set.draw do |map| - map.connect ':action', :controller => "url_encoded_params_parsing_test/test" + match ':action', :to => TestController end yield end diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb index 521002b519..0dc47ed9d5 100644 --- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb +++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb @@ -84,7 +84,7 @@ class XmlParamsParsingTest < ActionController::IntegrationTest def with_test_routing with_routing do |set| set.draw do |map| - map.connect ':action', :controller => "xml_params_parsing_test/test" + match ':action', :to => TestController end yield end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb new file mode 100644 index 0000000000..74e6c8e72d --- /dev/null +++ b/actionpack/test/dispatch/routing_test.rb @@ -0,0 +1,378 @@ +require 'abstract_unit' +require 'controller/fake_controllers' + +class TestRoutingMapper < ActionDispatch::IntegrationTest + SprocketsApp = lambda { |env| + [200, {"Content-Type" => "text/html"}, ["javascripts"]] + } + + class IpRestrictor + def self.matches?(request) + request.ip =~ /192\.168\.1\.1\d\d/ + end + end + + stub_controllers do |routes| + Routes = routes + Routes.draw do |map| + controller :sessions do + get 'login', :to => :new, :as => :login + post 'login', :to => :create + + delete 'logout', :to => :destroy, :as => :logout + end + + match 'account/login', :to => redirect("/login") + + match 'openid/login', :via => [:get, :post], :to => "openid#login" + + controller(:global) do + match 'global/:action' + match 'global/export', :to => :export, :as => :export_request + match 'global/hide_notice', :to => :hide_notice, :as => :hide_notice + match '/export/:id/:file', :to => :export, :as => :export_download, :constraints => { :file => /.*/ } + end + + constraints(:ip => /192\.168\.1\.\d\d\d/) do + get 'admin', :to => "queenbee#index" + end + + constraints IpRestrictor do + get 'admin/accounts', :to => "queenbee#accounts" + end + + resources :projects, :controller => :project do + resources :involvements, :attachments + + resources :participants do + put :update_all, :on => :collection + end + + resources :companies do + resources :people + resource :avatar + end + + resources :images do + post :revise, :on => :member + end + + resources :people do + namespace ":access_token" do + resource :avatar + end + + member do + put :accessible_projects + post :resend, :generate_new_password + end + end + + resources :posts do + get :archive, :toggle_view, :on => :collection + post :preview, :on => :member + + resource :subscription + + resources :comments do + post :preview, :on => :collection + end + end + end + + match 'sprockets.js', :to => SprocketsApp + + match 'people/:id/update', :to => 'people#update', :as => :update_person + match '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person + + # misc + match 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article + + namespace :account do + resource :subscription, :credit, :credit_card + end + + controller :articles do + scope 'articles' do + scope ':title', :title => /[a-z]+/, :as => :with_title do + match ':id', :to => :with_id + end + end + end + + scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do + resources :rooms + end + end + end + + def app + Routes + end + + def test_logout + with_test_routes do + delete '/logout' + assert_equal 'sessions#destroy', @response.body + + assert_equal '/logout', logout_path + assert_equal '/logout', url_for(:controller => 'sessions', :action => 'destroy', :only_path => true) + end + end + + def test_login + with_test_routes do + get '/login' + assert_equal 'sessions#new', @response.body + assert_equal '/login', login_path + + post '/login' + assert_equal 'sessions#create', @response.body + + assert_equal '/login', url_for(:controller => 'sessions', :action => 'create', :only_path => true) + assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true) + end + end + + def test_login_redirect + with_test_routes do + get '/account/login' + assert_equal 301, @response.status + assert_equal 'http://www.example.com/login', @response.headers['Location'] + assert_equal 'Moved Permanently', @response.body + end + end + + def test_openid + with_test_routes do + get '/openid/login' + assert_equal 'openid#login', @response.body + + post '/openid/login' + assert_equal 'openid#login', @response.body + end + end + + # TODO: rackmount is broken + # def test_admin + # with_test_routes do + # get '/admin', {}, {'REMOTE_ADDR' => '192.168.1.100'} + # assert_equal 'queenbee#index', @response.body + # + # assert_raise(ActionController::RoutingError) { get '/admin', {}, {'REMOTE_ADDR' => '10.0.0.100'} } + # + # get '/admin/accounts', {}, {'REMOTE_ADDR' => '192.168.1.100'} + # assert_equal 'queenbee#accounts', @response.body + # + # assert_raise(ActionController::RoutingError) { get '/admin/accounts', {}, {'REMOTE_ADDR' => '10.0.0.100'} } + # end + # end + + def test_global + with_test_routes do + get '/global/dashboard' + assert_equal 'global#dashboard', @response.body + + get '/global/export' + assert_equal 'global#export', @response.body + + get '/global/hide_notice' + assert_equal 'global#hide_notice', @response.body + + get '/export/123/foo.txt' + assert_equal 'global#export', @response.body + + assert_equal '/global/export', export_request_path + assert_equal '/global/hide_notice', hide_notice_path + assert_equal '/export/123/foo.txt', export_download_path(:id => 123, :file => 'foo.txt') + end + end + + def test_projects + with_test_routes do + get '/projects/1' + assert_equal 'projects#show', @response.body + end + end + + def test_projects_involvements + with_test_routes do + get '/projects/1/involvements' + assert_equal 'involvements#index', @response.body + + get '/projects/1/involvements/1' + assert_equal 'involvements#show', @response.body + end + end + + def test_projects_attachments + with_test_routes do + get '/projects/1/attachments' + assert_equal 'attachments#index', @response.body + end + end + + def test_projects_participants + with_test_routes do + get '/projects/1/participants' + assert_equal 'participants#index', @response.body + + put '/projects/1/participants/update_all' + assert_equal 'participants#update_all', @response.body + end + end + + def test_projects_companies + with_test_routes do + get '/projects/1/companies' + assert_equal 'companies#index', @response.body + + get '/projects/1/companies/1/people' + assert_equal 'people#index', @response.body + + get '/projects/1/companies/1/avatar' + assert_equal 'avatar#show', @response.body + end + end + + def test_project_images + with_test_routes do + get '/projects/1/images' + assert_equal 'images#index', @response.body + + post '/projects/1/images/1/revise' + assert_equal 'images#revise', @response.body + end + end + + def test_projects_people + with_test_routes do + get '/projects/1/people' + assert_equal 'people#index', @response.body + + get '/projects/1/people/1' + assert_equal 'people#show', @response.body + + get '/projects/1/people/1/7a2dec8/avatar' + assert_equal 'avatar#show', @response.body + + put '/projects/1/people/1/accessible_projects' + assert_equal 'people#accessible_projects', @response.body + + post '/projects/1/people/1/resend' + assert_equal 'people#resend', @response.body + + post '/projects/1/people/1/generate_new_password' + assert_equal 'people#generate_new_password', @response.body + end + end + + def test_projects_posts + with_test_routes do + get '/projects/1/posts' + assert_equal 'posts#index', @response.body + + get '/projects/1/posts/archive' + assert_equal 'posts#archive', @response.body + + get '/projects/1/posts/toggle_view' + assert_equal 'posts#toggle_view', @response.body + + post '/projects/1/posts/1/preview' + assert_equal 'posts#preview', @response.body + + get '/projects/1/posts/1/subscription' + assert_equal 'subscription#show', @response.body + + get '/projects/1/posts/1/comments' + assert_equal 'comments#index', @response.body + + post '/projects/1/posts/1/comments/preview' + assert_equal 'comments#preview', @response.body + end + end + + def test_sprockets + with_test_routes do + get '/sprockets.js' + assert_equal 'javascripts', @response.body + end + end + + def test_update_person_route + with_test_routes do + get '/people/1/update' + assert_equal 'people#update', @response.body + + assert_equal '/people/1/update', update_person_path(:id => 1) + end + end + + def test_update_project_person + with_test_routes do + get '/projects/1/people/2/update' + assert_equal 'people#update', @response.body + + assert_equal '/projects/1/people/2/update', update_project_person_path(:project_id => 1, :id => 2) + end + end + + def test_articles_perma + with_test_routes do + get '/articles/2009/08/18/rails-3' + assert_equal 'articles#show', @response.body + + assert_equal '/articles/2009/8/18/rails-3', article_path(:year => 2009, :month => 8, :day => 18, :title => 'rails-3') + end + end + + def test_account_namespace + with_test_routes do + get '/account/subscription' + assert_equal 'subscription#show', @response.body + + get '/account/credit' + assert_equal 'credit#show', @response.body + + get '/account/credit_card' + assert_equal 'credit_card#show', @response.body + end + end + + def test_articles_with_id + with_test_routes do + get '/articles/rails/1' + assert_equal 'articles#with_id', @response.body + + assert_raise(ActionController::RoutingError) { get '/articles/123/1' } + + assert_equal '/articles/rails/1', with_title_path(:title => 'rails', :id => 1) + end + end + + def test_access_token_rooms + with_test_routes do + get '/12345/rooms' + assert_equal 'rooms#index', @response.body + + get '/12345/rooms/1' + assert_equal 'rooms#show', @response.body + + get '/12345/rooms/1/edit' + assert_equal 'rooms#edit', @response.body + end + end + + private + def with_test_routes + real_routes, temp_routes = ActionController::Routing::Routes, Routes + + ActionController::Routing.module_eval { remove_const :Routes } + ActionController::Routing.module_eval { const_set :Routes, temp_routes } + + yield + ensure + ActionController::Routing.module_eval { remove_const :Routes } + ActionController::Routing.const_set(:Routes, real_routes) + end +end diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb index ab5fabde65..edfc303d3d 100644 --- a/actionpack/test/dispatch/session/cookie_store_test.rb +++ b/actionpack/test/dispatch/session/cookie_store_test.rb @@ -219,7 +219,7 @@ class CookieStoreTest < ActionController::IntegrationTest def with_test_route_set(options = {}) with_routing do |set| set.draw do |map| - map.connect "/:action", :controller => "cookie_store_test/test" + match ':action', :to => TestController end options = {:key => SessionKey, :secret => SessionSecret}.merge(options) @app = ActionDispatch::Session::CookieStore.new(set, options) diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb index c7435bd06b..afc9d91d50 100644 --- a/actionpack/test/dispatch/session/mem_cache_store_test.rb +++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb @@ -112,7 +112,7 @@ class MemCacheStoreTest < ActionController::IntegrationTest def with_test_route_set with_routing do |set| set.draw do |map| - map.connect "/:action", :controller => "mem_cache_store_test/test" + match ':action', :to => TestController end @app = ActionDispatch::Session::MemCacheStore.new(set, :key => '_session_id') yield diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb index c993836a61..250327e6dc 100644 --- a/actionpack/test/lib/controller/fake_controllers.rb +++ b/actionpack/test/lib/controller/fake_controllers.rb @@ -5,9 +5,10 @@ class NotAController; end module Admin class << self; alias_method :const_available?, :const_defined?; end - class UserController < ActionController::Base; end class NewsFeedController < ActionController::Base; end + class PostsController < ActionController::Base; end class StuffController < ActionController::Base; end + class UserController < ActionController::Base; end end module Api @@ -25,7 +26,9 @@ class ElsewhereController < ActionController::Base; end class FooController < ActionController::Base; end class HiController < ActionController::Base; end class ImageController < ActionController::Base; end +class NotesController < ActionController::Base; end class PeopleController < ActionController::Base; end +class PostsController < ActionController::Base; end class SessionsController < ActionController::Base; end class StuffController < ActionController::Base; end class SubpathBooksController < ActionController::Base; end diff --git a/actionpack/test/template/active_model_helper_i18n_test.rb b/actionpack/test/template/active_model_helper_i18n_test.rb new file mode 100644 index 0000000000..2465444fc5 --- /dev/null +++ b/actionpack/test/template/active_model_helper_i18n_test.rb @@ -0,0 +1,42 @@ +require 'abstract_unit' + +class ActiveModelHelperI18nTest < Test::Unit::TestCase + include ActionView::Context + include ActionView::Helpers::ActiveModelHelper + + attr_reader :request + + def setup + @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages']) + @object.stubs :to_model => @object + @object.stubs :class => stub(:model_name => stub(:human => "")) + + @object_name = 'book_seller' + @object_name_without_underscore = 'book seller' + + stubs(:content_tag).returns 'content_tag' + + I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" + I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:' + end + + def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').never + error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en') + end + + def test_error_messages_for_given_no_header_option_it_translates_header_message + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns 'header message' + error_messages_for(:object => @object, :locale => 'en') + end + + def test_error_messages_for_given_a_message_option_it_does_not_translate_message + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).never + error_messages_for(:object => @object, :message => 'message', :locale => 'en') + end + + def test_error_messages_for_given_no_message_option_it_translates_message + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:' + error_messages_for(:object => @object, :locale => 'en') + end +end diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb index c149070f2a..3e01ae78c3 100644 --- a/actionpack/test/template/active_record_helper_test.rb +++ b/actionpack/test/template/active_model_helper_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' -class ActiveRecordHelperTest < ActionView::TestCase +class ActiveModelHelperTest < ActionView::TestCase tests ActionView::Helpers::ActiveModelHelper silence_warnings do diff --git a/actionpack/test/template/active_record_helper_i18n_test.rb b/actionpack/test/template/active_record_helper_i18n_test.rb deleted file mode 100644 index 047f81be29..0000000000 --- a/actionpack/test/template/active_record_helper_i18n_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'abstract_unit' - -class ActiveRecordHelperI18nTest < Test::Unit::TestCase - include ActionView::Context - include ActionView::Helpers::ActiveModelHelper - - attr_reader :request - - def setup - @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages']) - @object.stubs :to_model => @object - @object.stubs :class => stub(:model_name => stub(:human => "")) - - @object_name = 'book_seller' - @object_name_without_underscore = 'book seller' - - stubs(:content_tag).returns 'content_tag' - - I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" - I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:' - end - - def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message - I18n.expects(:translate).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').never - error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en') - end - - def test_error_messages_for_given_no_header_option_it_translates_header_message - I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns 'header message' - I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' - error_messages_for(:object => @object, :locale => 'en') - end - - def test_error_messages_for_given_a_message_option_it_does_not_translate_message - I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).never - I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' - error_messages_for(:object => @object, :message => 'message', :locale => 'en') - end - - def test_error_messages_for_given_no_message_option_it_translates_message - I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:' - I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' - error_messages_for(:object => @object, :locale => 'en') - end - - def test_error_messages_for_given_object_name_it_translates_object_name - I18n.expects(:t).with(:header, :locale => 'en', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name_without_underscore).returns "1 error prohibited this #{@object_name_without_underscore} from being saved" - I18n.expects(:t).with(@object_name, :default => @object_name_without_underscore, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name_without_underscore - error_messages_for(:object => @object, :locale => 'en', :object_name => @object_name) - end -end diff --git a/actionpack/test/template/benchmark_helper_test.rb b/actionpack/test/template/benchmark_helper_test.rb deleted file mode 100644 index ac31fc6503..0000000000 --- a/actionpack/test/template/benchmark_helper_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'abstract_unit' -require 'action_view/helpers/benchmark_helper' - -class BenchmarkHelperTest < ActionView::TestCase - tests ActionView::Helpers::BenchmarkHelper - - def setup - super - controller.logger = ActiveSupport::BufferedLogger.new(StringIO.new) - controller.logger.auto_flushing = false - end - - def teardown - controller.logger.send(:clear_buffer) - end - - def test_without_block - assert_raise(LocalJumpError) { benchmark } - assert buffer.empty? - end - - def test_defaults - i_was_run = false - benchmark { i_was_run = true } - assert i_was_run - assert_last_logged - end - - def test_with_message - i_was_run = false - benchmark('test_run') { i_was_run = true } - assert i_was_run - assert_last_logged 'test_run' - end - - def test_with_message_and_deprecated_level - i_was_run = false - - assert_deprecated do - benchmark('debug_run', :debug) { i_was_run = true } - end - - assert i_was_run - assert_last_logged 'debug_run' - end - - def test_within_level - controller.logger.level = ActiveSupport::BufferedLogger::DEBUG - benchmark('included_debug_run', :level => :debug) { } - assert_last_logged 'included_debug_run' - end - - def test_outside_level - controller.logger.level = ActiveSupport::BufferedLogger::ERROR - benchmark('skipped_debug_run', :level => :debug) { } - assert_no_match(/skipped_debug_run/, buffer.last) - ensure - controller.logger.level = ActiveSupport::BufferedLogger::DEBUG - end - - def test_without_silencing - benchmark('debug_run', :silence => false) do - controller.logger.info "not silenced!" - end - - assert_equal 2, buffer.size - end - - def test_with_silencing - benchmark('debug_run', :silence => true) do - controller.logger.info "silenced!" - end - - assert_equal 1, buffer.size - end - - - private - def buffer - controller.logger.send(:buffer) - end - - def assert_last_logged(message = 'Benchmarking') - assert_match(/^#{message} \(.*\)$/, buffer.last) - end -end diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb index 05a14f3554..68e790cf46 100644 --- a/actionpack/test/template/test_test.rb +++ b/actionpack/test/template/test_test.rb @@ -48,8 +48,7 @@ class PeopleHelperTest < ActionView::TestCase def with_test_route_set with_routing do |set| set.draw do |map| - map.people 'people', :controller => 'people', :action => 'index' - map.connect ':controller/:action/:id' + match 'people', :to => 'people#index', :as => :people end yield end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index cec53e479c..bf0b4ad3a7 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -26,7 +26,7 @@ class UrlHelperTest < ActionView::TestCase assert_equal "http://www.example.com?a=b&c=d", url_for(:a => 'b', :c => 'd', :escape => true) assert_equal "http://www.example.com?a=b&c=d", url_for(:a => 'b', :c => 'd', :escape => false) end - + def test_url_for_escaping_is_safety_aware assert url_for(:a => 'b', :c => 'd', :escape => true).html_safe?, "escaped urls should be html_safe?" assert !url_for(:a => 'b', :c => 'd', :escape => false).html_safe?, "non-escaped urls shouldn't be safe" @@ -54,7 +54,7 @@ class UrlHelperTest < ActionView::TestCase path = @view.url_for(:controller => :cheeses, :foo => :bar, :baz => :quux) - assert_equal '/cheeses?baz=quux&foo=bar', path + assert_equal '/cheeses?baz=quux&foo=bar', sort_query_string_params(path) end # todo: missing test cases @@ -284,21 +284,21 @@ class UrlHelperTest < ActionView::TestCase assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end - + def test_current_page_ignoring_params @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end - + def test_current_page_with_params_that_match @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog", :order => "desc", :page => "1" }) assert current_page?("http://www.example.com/weblog/show?order=desc&page=1") end - + def test_link_unless_current @controller.request = RequestMock.new("http://www.example.com/weblog/show") @controller.url = "http://www.example.com/weblog/show" @@ -378,10 +378,17 @@ class UrlHelperTest < ActionView::TestCase assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)") assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%6d%65%28%61%74%29%64%6f%6d%61%69%6e%28%64%6f%74%29%63%6f%6d%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", nil, :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)") end - + def protect_against_forgery? false end + + private + def sort_query_string_params(uri) + path, qs = uri.split('?') + qs = qs.split('&').sort.join('&') if qs + qs ? "#{path}?#{qs}" : path + end end class UrlHelperController < ActionController::Base |