diff options
Diffstat (limited to 'actionview/test/activerecord/polymorphic_routes_test.rb')
-rw-r--r-- | actionview/test/activerecord/polymorphic_routes_test.rb | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb new file mode 100644 index 0000000000..724129a7d9 --- /dev/null +++ b/actionview/test/activerecord/polymorphic_routes_test.rb @@ -0,0 +1,786 @@ +# frozen_string_literal: true + +require "active_record_unit" +require "fixtures/project" + +class Task < ActiveRecord::Base + self.table_name = "projects" +end + +class Step < ActiveRecord::Base + self.table_name = "projects" +end + +class Bid < ActiveRecord::Base + self.table_name = "projects" +end + +class Tax < ActiveRecord::Base + self.table_name = "projects" +end + +class Fax < ActiveRecord::Base + self.table_name = "projects" +end + +class Series < ActiveRecord::Base + self.table_name = "projects" +end + +class ModelDelegator + def to_model + ModelDelegate.new + end +end + +class ModelDelegate + def persisted? + true + end + + def model_name + ActiveModel::Name.new(self.class) + end + + def to_param + "overridden" + end +end + +module Weblog + class Post < ActiveRecord::Base + self.table_name = "projects" + end + + class Blog < ActiveRecord::Base + self.table_name = "projects" + end + + def self.use_relative_model_naming? + true + end +end + +class PolymorphicRoutesTest < ActionController::TestCase + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw { } + include Routes.url_helpers + + default_url_options[:host] = "example.com" + + def setup + super + @project = Project.new + @task = Task.new + @step = Step.new + @bid = Bid.new + @tax = Tax.new + @fax = Fax.new + @delegator = ModelDelegator.new + @series = Series.new + @blog_post = Weblog::Post.new + @blog_blog = Weblog::Blog.new + end + + def assert_url(url, args) + host = self.class.default_url_options[:host] + + assert_equal url.sub(/http:\/\/#{host}/, ""), polymorphic_path(args) + assert_equal url, polymorphic_url(args) + assert_equal url, url_for(args) + end + + def test_string + with_test_routes do + assert_equal "/projects", polymorphic_path("projects") + assert_equal "http://example.com/projects", polymorphic_url("projects") + assert_equal "projects", url_for("projects") + end + end + + def test_string_with_options + with_test_routes do + assert_equal "http://example.com/projects?id=10", polymorphic_url("projects", id: 10) + end + end + + def test_symbol + with_test_routes do + assert_url "http://example.com/projects", :projects + end + end + + def test_symbol_with_options + with_test_routes do + assert_equal "http://example.com/projects?id=10", polymorphic_url(:projects, id: 10) + end + end + + def test_passing_routes_proxy + with_namespaced_routes(:blog) do + proxy = ActionDispatch::Routing::RoutesProxy.new(_routes, self, _routes.url_helpers) + @blog_post.save + assert_url "http://example.com/posts/#{@blog_post.id}", [proxy, @blog_post] + end + end + + def test_namespaced_model + with_namespaced_routes(:blog) do + @blog_post.save + assert_url "http://example.com/posts/#{@blog_post.id}", @blog_post + end + end + + def test_namespaced_model_with_name_the_same_as_namespace + with_namespaced_routes(:blog) do + @blog_blog.save + assert_url "http://example.com/blogs/#{@blog_blog.id}", @blog_blog + end + end + + def test_polymorphic_url_with_2_objects + with_namespaced_routes(:blog) do + @blog_blog.save + @blog_post.save + assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}", polymorphic_url([@blog_blog, @blog_post]) + end + end + + def test_polymorphic_url_with_3_objects + with_namespaced_routes(:blog) do + @blog_blog.save + @blog_post.save + @fax.save + assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}/faxes/#{@fax.id}", polymorphic_url([@blog_blog, @blog_post, @fax]) + end + end + + def test_namespaced_model_with_nested_resources + with_namespaced_routes(:blog) do + @blog_post.save + @blog_blog.save + assert_url "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}", [@blog_blog, @blog_post] + end + end + + def test_with_nil + with_test_routes do + exception = assert_raise ArgumentError do + polymorphic_url(nil) + end + assert_equal "Nil location provided. Can't build URI.", exception.message + end + end + + def test_with_empty_list + with_test_routes do + exception = assert_raise ArgumentError do + polymorphic_url([]) + end + assert_equal "Nil location provided. Can't build URI.", exception.message + end + end + + def test_with_nil_id + with_test_routes do + exception = assert_raise ArgumentError do + polymorphic_url(id: nil) + end + assert_equal "Nil location provided. Can't build URI.", exception.message + end + end + + def test_with_entirely_nil_list + with_test_routes do + exception = assert_raise ArgumentError do + @series.save + polymorphic_url([nil, nil]) + end + assert_equal "Nil location provided. Can't build URI.", exception.message + end + end + + def test_with_nil_in_list_for_resource_that_could_be_top_level_or_nested + with_top_level_and_nested_routes do + @blog_post.save + assert_equal "http://example.com/posts/#{@blog_post.id}", polymorphic_url([nil, @blog_post]) + end + end + + def test_with_nil_in_list_does_not_generate_invalid_link + with_top_level_and_nested_routes do + exception = assert_raise NoMethodError do + @series.save + polymorphic_url([nil, @series]) + end + assert_match(/undefined method `series_url'/, exception.message) + end + end + + def test_with_record + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}", @project + end + end + + def test_with_class + with_test_routes do + assert_url "http://example.com/projects", @project.class + end + end + + def test_with_class_list_of_one + with_test_routes do + assert_url "http://example.com/projects", [@project.class] + end + end + + def test_class_with_options + with_test_routes do + assert_equal "http://example.com/projects?foo=bar", polymorphic_url(@project.class, foo: :bar) + assert_equal "/projects?foo=bar", polymorphic_path(@project.class, foo: :bar) + end + end + + def test_with_new_record + with_test_routes do + assert_url "http://example.com/projects", @project + end + end + + def test_new_record_arguments + params = nil + + with_test_routes do + extend Module.new { + define_method("projects_url") { |*args| + params = args + super(*args) + } + + define_method("projects_path") { |*args| + params = args + super(*args) + } + } + + assert_url "http://example.com/projects", @project + assert_equal [], params + end + end + + def test_with_destroyed_record + with_test_routes do + @project.destroy + assert_url "http://example.com/projects", @project + end + end + + def test_with_record_and_action + with_test_routes do + assert_equal "http://example.com/projects/new", polymorphic_url(@project, action: "new") + end + end + + def test_url_helper_prefixed_with_new + with_test_routes do + assert_equal "http://example.com/projects/new", new_polymorphic_url(@project) + end + end + + def test_regression_path_helper_prefixed_with_new_and_edit + with_test_routes do + assert_equal "/projects/new", new_polymorphic_path(@project) + + @project.save + assert_equal "/projects/#{@project.id}/edit", edit_polymorphic_path(@project) + end + end + + def test_url_helper_prefixed_with_edit + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}/edit", edit_polymorphic_url(@project) + end + end + + def test_url_helper_prefixed_with_edit_with_url_options + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}/edit?param1=10", edit_polymorphic_url(@project, param1: "10") + end + end + + def test_url_helper_with_url_options + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}?param1=10", polymorphic_url(@project, param1: "10") + end + end + + def test_format_option + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}.pdf", polymorphic_url(@project, format: :pdf) + end + end + + def test_format_option_with_url_options + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}.pdf?param1=10", polymorphic_url(@project, format: :pdf, param1: "10") + end + end + + def test_id_and_format_option + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}.pdf", polymorphic_url(id: @project, format: :pdf) + end + end + + def test_with_nested + with_test_routes do + @project.save + @task.save + assert_url "http://example.com/projects/#{@project.id}/tasks/#{@task.id}", [@project, @task] + end + end + + def test_with_nested_unsaved + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}/tasks", [@project, @task] + end + end + + def test_with_nested_destroyed + with_test_routes do + @project.save + @task.destroy + assert_url "http://example.com/projects/#{@project.id}/tasks", [@project, @task] + end + end + + def test_with_nested_class + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}/tasks", [@project, @task.class] + end + end + + def test_class_with_array_and_namespace + with_admin_test_routes do + assert_url "http://example.com/admin/projects", [:admin, @project.class] + end + end + + def test_new_with_array_and_namespace + with_admin_test_routes do + assert_equal "http://example.com/admin/projects/new", polymorphic_url([:admin, @project], action: "new") + end + end + + def test_unsaved_with_array_and_namespace + with_admin_test_routes do + assert_url "http://example.com/admin/projects", [:admin, @project] + end + end + + def test_nested_unsaved_with_array_and_namespace + with_admin_test_routes do + @project.save + assert_url "http://example.com/admin/projects/#{@project.id}/tasks", [:admin, @project, @task] + end + end + + def test_nested_with_array_and_namespace + with_admin_test_routes do + @project.save + @task.save + assert_url "http://example.com/admin/projects/#{@project.id}/tasks/#{@task.id}", [:admin, @project, @task] + end + end + + def test_ordering_of_nesting_and_namespace + with_admin_and_site_test_routes do + @project.save + @task.save + @step.save + assert_url "http://example.com/admin/projects/#{@project.id}/site/tasks/#{@task.id}/steps/#{@step.id}", [:admin, @project, :site, @task, @step] + end + end + + def test_nesting_with_array_ending_in_singleton_resource + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}/bid", [@project, :bid] + end + end + + def test_nesting_with_array_containing_singleton_resource + with_test_routes do + @project.save + @task.save + assert_url "http://example.com/projects/#{@project.id}/bid/tasks/#{@task.id}", [@project, :bid, @task] + end + end + + def test_nesting_with_array_containing_singleton_resource_and_format + with_test_routes do + @project.save + @task.save + assert_equal "http://example.com/projects/#{@project.id}/bid/tasks/#{@task.id}.pdf", polymorphic_url([@project, :bid, @task], format: :pdf) + end + end + + def test_nesting_with_array_containing_namespace_and_singleton_resource + with_admin_test_routes do + @project.save + @task.save + assert_url "http://example.com/admin/projects/#{@project.id}/bid/tasks/#{@task.id}", [:admin, @project, :bid, @task] + end + end + + def test_nesting_with_array + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}/bid", [@project, :bid] + end + end + + def test_with_array_containing_single_object + with_test_routes do + @project.save + assert_url "http://example.com/projects/#{@project.id}", [@project] + end + end + + def test_with_array_containing_single_name + with_test_routes do + @project.save + assert_url "http://example.com/projects", [:projects] + end + end + + def test_with_array_containing_single_string_name + with_test_routes do + assert_url "http://example.com/projects", ["projects"] + end + end + + def test_with_array_containing_symbols + with_test_routes do + assert_url "http://example.com/series/new", [:new, :series] + end + end + + def test_with_hash + with_test_routes do + @project.save + assert_equal "http://example.com/projects/#{@project.id}", polymorphic_url(id: @project) + end + end + + def test_polymorphic_path_accepts_options + with_test_routes do + assert_equal "/projects/new", polymorphic_path(@project, action: "new") + end + end + + def test_polymorphic_path_does_not_modify_arguments + with_admin_test_routes do + @project.save + @task.save + + options = {} + object_array = [:admin, @project, @task] + original_args = [object_array.dup, options.dup] + + assert_no_difference("object_array.size") { polymorphic_path(object_array, options) } + assert_equal original_args, [object_array, options] + end + end + + # Tests for names where .plural.singular doesn't round-trip + def test_with_irregular_plural_record + with_test_routes do + @tax.save + assert_url "http://example.com/taxes/#{@tax.id}", @tax + end + end + + def test_with_irregular_plural_class + with_test_routes do + assert_url "http://example.com/taxes", @tax.class + end + end + + def test_with_irregular_plural_new_record + with_test_routes do + assert_url "http://example.com/taxes", @tax + end + end + + def test_with_irregular_plural_destroyed_record + with_test_routes do + @tax.destroy + assert_url "http://example.com/taxes", @tax + end + end + + def test_with_irregular_plural_record_and_action + with_test_routes do + assert_equal "http://example.com/taxes/new", polymorphic_url(@tax, action: "new") + end + end + + def test_irregular_plural_url_helper_prefixed_with_new + with_test_routes do + assert_equal "http://example.com/taxes/new", new_polymorphic_url(@tax) + end + end + + def test_irregular_plural_url_helper_prefixed_with_edit + with_test_routes do + @tax.save + assert_equal "http://example.com/taxes/#{@tax.id}/edit", edit_polymorphic_url(@tax) + end + end + + def test_with_nested_irregular_plurals + with_test_routes do + @tax.save + @fax.save + assert_equal "http://example.com/taxes/#{@tax.id}/faxes/#{@fax.id}", polymorphic_url([@tax, @fax]) + end + end + + def test_with_nested_unsaved_irregular_plurals + with_test_routes do + @tax.save + assert_url "http://example.com/taxes/#{@tax.id}/faxes", [@tax, @fax] + end + end + + def test_new_with_irregular_plural_array_and_namespace + with_admin_test_routes do + assert_equal "http://example.com/admin/taxes/new", polymorphic_url([:admin, @tax], action: "new") + end + end + + def test_class_with_irregular_plural_array_and_namespace + with_admin_test_routes do + assert_url "http://example.com/admin/taxes", [:admin, @tax.class] + end + end + + def test_unsaved_with_irregular_plural_array_and_namespace + with_admin_test_routes do + assert_url "http://example.com/admin/taxes", [:admin, @tax] + end + end + + def test_nesting_with_irregular_plurals_and_array_ending_in_singleton_resource + with_test_routes do + @tax.save + assert_url "http://example.com/taxes/#{@tax.id}/bid", [@tax, :bid] + end + end + + def test_with_array_containing_single_irregular_plural_object + with_test_routes do + @tax.save + assert_url "http://example.com/taxes/#{@tax.id}", [@tax] + end + end + + def test_with_array_containing_single_name_irregular_plural + with_test_routes do + @tax.save + assert_url "http://example.com/taxes", [:taxes] + end + end + + # Tests for uncountable names + def test_uncountable_resource + with_test_routes do + @series.save + assert_url "http://example.com/series/#{@series.id}", @series + assert_url "http://example.com/series", Series.new + end + end + + def test_routing_to_a_model_delegate + with_test_routes do + assert_url "http://example.com/model_delegates/overridden", @delegator + end + end + + def test_nested_routing_to_a_model_delegate + with_test_routes do + assert_url "http://example.com/foo/model_delegates/overridden", [:foo, @delegator] + end + end + + def with_namespaced_routes(name) + with_routing do |set| + set.draw do + scope(module: name) do + resources :blogs do + resources :posts do + resources :faxes + end + end + resources :posts + end + end + + extend @routes.url_helpers + yield + end + end + + def with_test_routes(options = {}) + with_routing do |set| + set.draw do + resources :projects do + resources :tasks + resource :bid do + resources :tasks + end + end + resources :taxes do + resources :faxes + resource :bid + end + resources :series + resources :model_delegates + namespace :foo do + resources :model_delegates + end + end + + extend @routes.url_helpers + yield + end + end + + def with_top_level_and_nested_routes(options = {}) + with_routing do |set| + set.draw do + resources :blogs do + resources :posts + resources :series + end + resources :posts + end + + extend @routes.url_helpers + yield + end + end + + def with_admin_test_routes(options = {}) + with_routing do |set| + set.draw do + namespace :admin do + resources :projects do + resources :tasks + resource :bid do + resources :tasks + end + end + resources :taxes do + resources :faxes + end + resources :series + end + end + + extend @routes.url_helpers + yield + end + end + + def with_admin_and_site_test_routes(options = {}) + with_routing do |set| + set.draw do + namespace :admin do + resources :projects do + namespace :site do + resources :tasks do + resources :steps + end + end + end + end + end + + extend @routes.url_helpers + yield + end + end +end + +class PolymorphicPathRoutesTest < PolymorphicRoutesTest + include ActionView::RoutingUrlFor + include ActionView::Context + + attr_accessor :controller + + def assert_url(url, args) + host = self.class.default_url_options[:host] + + assert_equal url.sub(/http:\/\/#{host}/, ""), url_for(args) + end +end + +class DirectRoutesTest < ActionView::TestCase + class Linkable + attr_reader :id + + def self.name + super.demodulize + end + + def initialize(id) + @id = id + end + + def linkable_type + self.class.name.underscore + end + end + + class Category < Linkable; end + class Collection < Linkable; end + class Product < Linkable; end + + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw do + resources :categories, :collections, :products + direct(:linkable) { |linkable| [:"#{linkable.linkable_type}", { id: linkable.id }] } + end + + include Routes.url_helpers + + def setup + super + @category = Category.new("1") + @collection = Collection.new("2") + @product = Product.new("3") + @controller.singleton_class.include Routes.url_helpers + end + + def test_direct_routes + assert_equal "/categories/1", linkable_path(@category) + assert_equal "/collections/2", linkable_path(@collection) + assert_equal "/products/3", linkable_path(@product) + + assert_equal "http://test.host/categories/1", linkable_url(@category) + assert_equal "http://test.host/collections/2", linkable_url(@collection) + assert_equal "http://test.host/products/3", linkable_url(@product) + end +end |