aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/dispatch/routing/inspector_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test/dispatch/routing/inspector_test.rb')
-rw-r--r--actionpack/test/dispatch/routing/inspector_test.rb495
1 files changed, 495 insertions, 0 deletions
diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb
new file mode 100644
index 0000000000..fe1f1995d8
--- /dev/null
+++ b/actionpack/test/dispatch/routing/inspector_test.rb
@@ -0,0 +1,495 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rails/engine"
+require "action_dispatch/routing/inspector"
+require "io/console/size"
+
+class MountedRackApp
+ def self.call(env)
+ end
+end
+
+class Rails::DummyController
+end
+
+module ActionDispatch
+ module Routing
+ class RoutesInspectorTest < ActiveSupport::TestCase
+ setup do
+ @set = ActionDispatch::Routing::RouteSet.new
+ end
+
+ def test_displaying_routes_for_engines
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ end
+
+ output = draw do
+ get "/custom/assets", to: "custom_assets#show"
+ mount engine => "/blog", :as => "blog"
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "custom_assets GET /custom/assets(.:format) custom_assets#show",
+ " blog /blog Blog::Engine",
+ "",
+ "Routes for Blog::Engine:",
+ " cart GET /cart(.:format) cart#show"
+ ], output
+ end
+
+ def test_displaying_routes_for_engines_without_routes
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ end
+
+ output = draw do
+ mount engine => "/blog", as: "blog"
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " blog /blog Blog::Engine",
+ "",
+ "Routes for Blog::Engine:"
+ ], output
+ end
+
+ def test_cart_inspect
+ output = draw do
+ get "/cart", to: "cart#show"
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " cart GET /cart(.:format) cart#show"
+ ], output
+ end
+
+ def test_articles_inspect_with_multiple_verbs
+ output = draw do
+ match "articles/:id", to: "articles#update", via: [:put, :patch]
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " PUT|PATCH /articles/:id(.:format) articles#update"
+ ], output
+ end
+
+ def test_inspect_shows_custom_assets
+ output = draw do
+ get "/custom/assets", to: "custom_assets#show"
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "custom_assets GET /custom/assets(.:format) custom_assets#show"
+ ], output
+ end
+
+ def test_inspect_routes_shows_resources_route
+ output = draw do
+ resources :articles
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ " articles GET /articles(.:format) articles#index",
+ " POST /articles(.:format) articles#create",
+ " new_article GET /articles/new(.:format) articles#new",
+ "edit_article GET /articles/:id/edit(.:format) articles#edit",
+ " article GET /articles/:id(.:format) articles#show",
+ " PATCH /articles/:id(.:format) articles#update",
+ " PUT /articles/:id(.:format) articles#update",
+ " DELETE /articles/:id(.:format) articles#destroy"
+ ], output
+ end
+
+ def test_inspect_routes_shows_root_route
+ output = draw do
+ root to: "pages#main"
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " root GET / pages#main"
+ ], output
+ end
+
+ def test_inspect_routes_shows_dynamic_action_route
+ output = draw do
+ ActiveSupport::Deprecation.silence do
+ get "api/:action" => "api"
+ end
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " GET /api/:action(.:format) api#:action"
+ ], output
+ end
+
+ def test_inspect_routes_shows_controller_and_action_only_route
+ output = draw do
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " GET /:controller/:action(.:format) :controller#:action"
+ ], output
+ end
+
+ def test_inspect_routes_shows_controller_and_action_route_with_constraints
+ output = draw do
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action(/:id))", id: /\d+/
+ end
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " GET /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"
+ ], output
+ end
+
+ def test_rails_routes_shows_route_with_defaults
+ output = draw do
+ get "photos/:id" => "photos#show", :defaults => { format: "jpg" }
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ ' GET /photos/:id(.:format) photos#show {:format=>"jpg"}'
+ ], output
+ end
+
+ def test_rails_routes_shows_route_with_constraints
+ output = draw do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " GET /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"
+ ], output
+ end
+
+ def test_rails_routes_shows_routes_with_dashes
+ output = draw do
+ get "about-us" => "pages#about_us"
+ get "our-work/latest"
+
+ resources :photos, only: [:show] do
+ get "user-favorites", on: :collection
+ get "preview-photo", on: :member
+ get "summary-text"
+ end
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ " about_us GET /about-us(.:format) pages#about_us",
+ " our_work_latest GET /our-work/latest(.:format) our_work#latest",
+ "user_favorites_photos GET /photos/user-favorites(.:format) photos#user_favorites",
+ " preview_photo_photo GET /photos/:id/preview-photo(.:format) photos#preview_photo",
+ " photo_summary_text GET /photos/:photo_id/summary-text(.:format) photos#summary_text",
+ " photo GET /photos/:id(.:format) photos#show"
+ ], output
+ end
+
+ def test_rails_routes_shows_route_with_rack_app
+ output = draw do
+ get "foo/:id" => MountedRackApp, :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " GET /foo/:id(.:format) MountedRackApp {:id=>/[A-Z]\\d{5}/}"
+ ], output
+ end
+
+ def test_rails_routes_shows_named_route_with_mounted_rack_app
+ output = draw do
+ mount MountedRackApp => "/foo"
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "mounted_rack_app /foo MountedRackApp"
+ ], output
+ end
+
+ def test_rails_routes_shows_overridden_named_route_with_mounted_rack_app_with_name
+ output = draw do
+ mount MountedRackApp => "/foo", as: "blog"
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " blog /foo MountedRackApp"
+ ], output
+ end
+
+ def test_rails_routes_shows_route_with_rack_app_nested_with_dynamic_constraints
+ constraint = Class.new do
+ def inspect
+ "( my custom constraint )"
+ end
+ end
+
+ output = draw do
+ scope constraint: constraint.new do
+ mount MountedRackApp => "/foo"
+ end
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "mounted_rack_app /foo MountedRackApp {:constraint=>( my custom constraint )}"
+ ], output
+ end
+
+ def test_rails_routes_dont_show_app_mounted_in_assets_prefix
+ output = draw do
+ get "/sprockets" => MountedRackApp
+ end
+ assert_no_match(/MountedRackApp/, output.first)
+ assert_no_match(/\/sprockets/, output.first)
+ end
+
+ def test_rails_routes_shows_route_defined_in_under_assets_prefix
+ output = draw do
+ scope "/sprockets" do
+ get "/foo" => "foo#bar"
+ end
+ end
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " foo GET /sprockets/foo(.:format) foo#bar"
+ ], output
+ end
+
+ def test_redirect
+ output = draw do
+ get "/foo" => redirect("/foo/bar"), :constraints => { subdomain: "admin" }
+ get "/bar" => redirect(path: "/foo/bar", status: 307)
+ get "/foobar" => redirect { "/foo/bar" }
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " foo GET /foo(.:format) redirect(301, /foo/bar) {:subdomain=>\"admin\"}",
+ " bar GET /bar(.:format) redirect(307, path: /foo/bar)",
+ "foobar GET /foobar(.:format) redirect(301)"
+ ], output
+ end
+
+ def test_routes_can_be_filtered
+ output = draw(grep: "posts") do
+ resources :articles
+ resources :posts
+ end
+
+ assert_equal [" Prefix Verb URI Pattern Controller#Action",
+ " posts GET /posts(.:format) posts#index",
+ " POST /posts(.:format) posts#create",
+ " new_post GET /posts/new(.:format) posts#new",
+ "edit_post GET /posts/:id/edit(.:format) posts#edit",
+ " post GET /posts/:id(.:format) posts#show",
+ " PATCH /posts/:id(.:format) posts#update",
+ " PUT /posts/:id(.:format) posts#update",
+ " DELETE /posts/:id(.:format) posts#destroy"], output
+ end
+
+ def test_routes_when_expanded
+ previous_console_winsize = IO.console.winsize
+ IO.console.winsize = [0, 23]
+
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ end
+
+ output = draw(formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "/custom/assets", to: "custom_assets#show"
+ get "/custom/furnitures", to: "custom_furnitures#show"
+ mount engine => "/blog", :as => "blog"
+ end
+
+ assert_equal ["--[ Route 1 ]----------",
+ "Prefix | custom_assets",
+ "Verb | GET",
+ "URI | /custom/assets(.:format)",
+ "Controller#Action | custom_assets#show",
+ "--[ Route 2 ]----------",
+ "Prefix | custom_furnitures",
+ "Verb | GET",
+ "URI | /custom/furnitures(.:format)",
+ "Controller#Action | custom_furnitures#show",
+ "--[ Route 3 ]----------",
+ "Prefix | blog",
+ "Verb | ",
+ "URI | /blog",
+ "Controller#Action | Blog::Engine",
+ "",
+ "[ Routes for Blog::Engine ]",
+ "--[ Route 1 ]----------",
+ "Prefix | cart",
+ "Verb | GET",
+ "URI | /cart(.:format)",
+ "Controller#Action | cart#show"], output
+ ensure
+ IO.console.winsize = previous_console_winsize
+ end
+
+ def test_no_routes_matched_filter_when_expanded
+ output = draw(grep: "rails/dummy", formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this grep pattern.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_not_routes_when_expanded
+ output = draw(grep: "rails/dummy", formatter: ActionDispatch::Routing::ConsoleFormatter::Expanded.new) { }
+
+ assert_equal [
+ "You don't have any routes defined!",
+ "",
+ "Please add some routes in config/routes.rb.",
+ "",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_routes_can_be_filtered_with_namespaced_controllers
+ output = draw(grep: "admin/posts") do
+ resources :articles
+ namespace :admin do
+ resources :posts
+ end
+ end
+
+ assert_equal [" Prefix Verb URI Pattern Controller#Action",
+ " admin_posts GET /admin/posts(.:format) admin/posts#index",
+ " POST /admin/posts(.:format) admin/posts#create",
+ " new_admin_post GET /admin/posts/new(.:format) admin/posts#new",
+ "edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit",
+ " admin_post GET /admin/posts/:id(.:format) admin/posts#show",
+ " PATCH /admin/posts/:id(.:format) admin/posts#update",
+ " PUT /admin/posts/:id(.:format) admin/posts#update",
+ " DELETE /admin/posts/:id(.:format) admin/posts#destroy"], output
+ end
+
+ def test_regression_route_with_controller_regexp
+ output = draw do
+ ActiveSupport::Deprecation.silence do
+ get ":controller(/:action)", controller: /api\/[^\/]+/, format: false
+ end
+ end
+
+ assert_equal ["Prefix Verb URI Pattern Controller#Action",
+ " GET /:controller(/:action) :controller#:action"], output
+ end
+
+ def test_inspect_routes_shows_resources_route_when_assets_disabled
+ @set = ActionDispatch::Routing::RouteSet.new
+
+ output = draw do
+ get "/cart", to: "cart#show"
+ end
+
+ assert_equal [
+ "Prefix Verb URI Pattern Controller#Action",
+ " cart GET /cart(.:format) cart#show"
+ ], output
+ end
+
+ def test_routes_with_undefined_filter
+ output = draw(controller: "Rails::MissingController") do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this controller.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_no_routes_matched_filter
+ output = draw(grep: "rails/dummy") do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this grep pattern.",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_no_routes_were_defined
+ output = draw(grep: "Rails::DummyController") { }
+
+ assert_equal [
+ "You don't have any routes defined!",
+ "",
+ "Please add some routes in config/routes.rb.",
+ "",
+ "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_displaying_routes_for_internal_engines
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ post "/cart", to: "cart#create"
+ patch "/cart", to: "cart#update"
+ end
+
+ output = draw do
+ get "/custom/assets", to: "custom_assets#show"
+ mount engine => "/blog", as: "blog", internal: true
+ end
+
+ assert_equal [
+ " Prefix Verb URI Pattern Controller#Action",
+ "custom_assets GET /custom/assets(.:format) custom_assets#show",
+ ], output
+ end
+
+ private
+ def draw(formatter: ActionDispatch::Routing::ConsoleFormatter::Sheet.new, **options, &block)
+ @set.draw(&block)
+ inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes)
+ inspector.format(formatter, options).split("\n")
+ end
+ end
+ end
+end