diff options
Diffstat (limited to 'actionpack/test/dispatch/prefix_generation_test.rb')
-rw-r--r-- | actionpack/test/dispatch/prefix_generation_test.rb | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb new file mode 100644 index 0000000000..7a7a201b11 --- /dev/null +++ b/actionpack/test/dispatch/prefix_generation_test.rb @@ -0,0 +1,463 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "rack/test" +require "rails/engine" + +module TestGenerationPrefix + class Post + extend ActiveModel::Naming + + def to_param + "1" + end + + def self.model_name + klass = +"Post" + def klass.name; self end + + ActiveModel::Name.new(klass) + end + + def to_model; self; end + def persisted?; true; end + end + + class WithMountedEngine < ActionDispatch::IntegrationTest + class BlogEngine < Rails::Engine + routes.draw do + get "/posts/:id", to: "inside_engine_generating#show", as: :post + get "/posts", to: "inside_engine_generating#index", as: :posts + get "/url_to_application", to: "inside_engine_generating#url_to_application" + get "/polymorphic_path_for_engine", to: "inside_engine_generating#polymorphic_path_for_engine" + get "/conflicting_url", to: "inside_engine_generating#conflicting" + get "/foo", to: "never#invoked", as: :named_helper_that_should_be_invoked_only_in_respond_to_test + + get "/relative_path_root", to: redirect("") + get "/relative_path_redirect", to: redirect("foo") + get "/relative_option_root", to: redirect(path: "") + get "/relative_option_redirect", to: redirect(path: "foo") + get "/relative_custom_root", to: redirect { |params, request| "" } + get "/relative_custom_redirect", to: redirect { |params, request| "foo" } + + get "/absolute_path_root", to: redirect("/") + get "/absolute_path_redirect", to: redirect("/foo") + get "/absolute_option_root", to: redirect(path: "/") + get "/absolute_option_redirect", to: redirect(path: "/foo") + get "/absolute_custom_root", to: redirect { |params, request| "/" } + get "/absolute_custom_redirect", to: redirect { |params, request| "/foo" } + end + end + + class RailsApplication < Rails::Engine + routes.draw do + scope "/:omg", omg: "awesome" do + mount BlogEngine => "/blog", :as => "blog_engine" + end + get "/posts/:id", to: "outside_engine_generating#post", as: :post + get "/generate", to: "outside_engine_generating#index" + get "/polymorphic_path_for_app", to: "outside_engine_generating#polymorphic_path_for_app" + get "/polymorphic_path_for_engine", to: "outside_engine_generating#polymorphic_path_for_engine" + get "/polymorphic_with_url_for", to: "outside_engine_generating#polymorphic_with_url_for" + get "/conflicting_url", to: "outside_engine_generating#conflicting" + get "/ivar_usage", to: "outside_engine_generating#ivar_usage" + root to: "outside_engine_generating#index" + end + end + + # force draw + RailsApplication.routes.define_mounted_helper(:main_app) + + class ::InsideEngineGeneratingController < ActionController::Base + include BlogEngine.routes.url_helpers + include RailsApplication.routes.mounted_helpers + + def index + render plain: posts_path + end + + def show + render plain: post_path(id: params[:id]) + end + + def url_to_application + path = main_app.url_for(controller: "outside_engine_generating", + action: "index", + only_path: true) + render plain: path + end + + def polymorphic_path_for_engine + render plain: polymorphic_path(Post.new) + end + + def conflicting + render plain: "engine" + end + end + + class ::OutsideEngineGeneratingController < ActionController::Base + include BlogEngine.routes.mounted_helpers + include RailsApplication.routes.url_helpers + + def index + render plain: blog_engine.post_path(id: 1) + end + + def polymorphic_path_for_engine + render plain: blog_engine.polymorphic_path(Post.new) + end + + def polymorphic_path_for_app + render plain: polymorphic_path(Post.new) + end + + def polymorphic_with_url_for + render plain: blog_engine.url_for(Post.new) + end + + def conflicting + render plain: "application" + end + + def ivar_usage + @blog_engine = "Not the engine route helper" + render plain: blog_engine.post_path(id: 1) + end + end + + class EngineObject + include ActionDispatch::Routing::UrlFor + include BlogEngine.routes.url_helpers + end + + class AppObject + include ActionDispatch::Routing::UrlFor + include RailsApplication.routes.url_helpers + end + + def app + RailsApplication.instance + end + + attr_reader :engine_object, :app_object + + def setup + RailsApplication.routes.default_url_options = {} + @engine_object = EngineObject.new + @app_object = AppObject.new + end + + include BlogEngine.routes.mounted_helpers + + # Inside Engine + test "[ENGINE] generating engine's url use SCRIPT_NAME from request" do + get "/pure-awesomeness/blog/posts/1" + assert_equal "/pure-awesomeness/blog/posts/1", response.body + end + + test "[ENGINE] generating application's url never uses SCRIPT_NAME from request" do + get "/pure-awesomeness/blog/url_to_application" + assert_equal "/generate", response.body + end + + test "[ENGINE] generating engine's url with polymorphic path" do + get "/pure-awesomeness/blog/polymorphic_path_for_engine" + assert_equal "/pure-awesomeness/blog/posts/1", response.body + end + + test "[ENGINE] url_helpers from engine have higher priority than application's url_helpers" do + get "/awesome/blog/conflicting_url" + assert_equal "engine", response.body + end + + test "[ENGINE] relative path root uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_path_root" + verify_redirect "http://www.example.com/awesome/blog" + end + + test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_path_redirect" + verify_redirect "http://www.example.com/awesome/blog/foo" + end + + test "[ENGINE] relative option root uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_option_root" + verify_redirect "http://www.example.com/awesome/blog" + end + + test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_option_redirect" + verify_redirect "http://www.example.com/awesome/blog/foo" + end + + test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_custom_root" + verify_redirect "http://www.example.com/awesome/blog" + end + + test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do + get "/awesome/blog/relative_custom_redirect" + verify_redirect "http://www.example.com/awesome/blog/foo" + end + + test "[ENGINE] absolute path root doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_path_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_path_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_option_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_option_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_custom_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do + get "/awesome/blog/absolute_custom_redirect" + verify_redirect "http://www.example.com/foo" + end + + # Inside Application + test "[APP] generating engine's route includes prefix" do + get "/generate" + assert_equal "/awesome/blog/posts/1", response.body + end + + test "[APP] generating engine's route includes default_url_options[:script_name]" do + RailsApplication.routes.default_url_options = { script_name: "/something" } + get "/generate" + assert_equal "/something/awesome/blog/posts/1", response.body + end + + test "[APP] generating engine's url with polymorphic path" do + get "/polymorphic_path_for_engine" + assert_equal "/awesome/blog/posts/1", response.body + end + + test "polymorphic_path_for_app" do + get "/polymorphic_path_for_app" + assert_equal "/posts/1", response.body + end + + test "[APP] generating engine's url with url_for(@post)" do + get "/polymorphic_with_url_for" + assert_equal "http://www.example.com/awesome/blog/posts/1", response.body + end + + test "[APP] instance variable with same name as engine" do + get "/ivar_usage" + assert_equal "/awesome/blog/posts/1", response.body + end + + # Inside any Object + test "[OBJECT] proxy route should override respond_to?() as expected" do + assert_respond_to blog_engine, :named_helper_that_should_be_invoked_only_in_respond_to_test_path + end + + test "[OBJECT] generating engine's route includes prefix" do + assert_equal "/awesome/blog/posts/1", engine_object.post_path(id: 1) + end + + test "[OBJECT] generating engine's route includes dynamic prefix" do + assert_equal "/pure-awesomeness/blog/posts/3", engine_object.post_path(id: 3, omg: "pure-awesomeness") + end + + test "[OBJECT] generating engine's route includes default_url_options[:script_name]" do + RailsApplication.routes.default_url_options = { script_name: "/something" } + assert_equal "/something/pure-awesomeness/blog/posts/3", engine_object.post_path(id: 3, omg: "pure-awesomeness") + end + + test "[OBJECT] generating application's route" do + assert_equal "/", app_object.root_path + end + + test "[OBJECT] generating application's route includes default_url_options[:script_name]" do + RailsApplication.routes.default_url_options = { script_name: "/something" } + assert_equal "/something/", app_object.root_path + end + + test "[OBJECT] generating application's route includes default_url_options[:trailing_slash]" do + RailsApplication.routes.default_url_options[:trailing_slash] = true + assert_equal "/awesome/blog/posts", engine_object.posts_path + end + + test "[OBJECT] generating engine's route with url_for" do + path = engine_object.url_for(controller: "inside_engine_generating", + action: "show", + only_path: true, + omg: "omg", + id: 1) + assert_equal "/omg/blog/posts/1", path + end + + test "[OBJECT] generating engine's route with named helpers" do + path = engine_object.posts_path + assert_equal "/awesome/blog/posts", path + + path = engine_object.posts_url(host: "example.com") + assert_equal "http://example.com/awesome/blog/posts", path + end + + test "[OBJECT] generating engine's route with polymorphic_url" do + path = engine_object.polymorphic_path(Post.new) + assert_equal "/awesome/blog/posts/1", path + + path = engine_object.polymorphic_url(Post.new, host: "www.example.com") + assert_equal "http://www.example.com/awesome/blog/posts/1", path + end + + private + def verify_redirect(url, status = 301) + assert_equal status, response.status + assert_equal url, response.headers["Location"] + assert_equal expected_redirect_body(url), response.body + end + + def expected_redirect_body(url) + %(<html><body>You are being <a href="#{url}">redirected</a>.</body></html>) + end + end + + class EngineMountedAtRoot < ActionDispatch::IntegrationTest + class BlogEngine + def self.routes + @routes ||= begin + routes = ActionDispatch::Routing::RouteSet.new + routes.draw do + get "/posts/:id", to: "posts#show", as: :post + + get "/relative_path_root", to: redirect("") + get "/relative_path_redirect", to: redirect("foo") + get "/relative_option_root", to: redirect(path: "") + get "/relative_option_redirect", to: redirect(path: "foo") + get "/relative_custom_root", to: redirect { |params, request| "" } + get "/relative_custom_redirect", to: redirect { |params, request| "foo" } + + get "/absolute_path_root", to: redirect("/") + get "/absolute_path_redirect", to: redirect("/foo") + get "/absolute_option_root", to: redirect(path: "/") + get "/absolute_option_redirect", to: redirect(path: "/foo") + get "/absolute_custom_root", to: redirect { |params, request| "/" } + get "/absolute_custom_redirect", to: redirect { |params, request| "/foo" } + end + + routes + end + end + + def self.call(env) + env["action_dispatch.routes"] = routes + routes.call(env) + end + end + + class RailsApplication < Rails::Engine + routes.draw do + mount BlogEngine => "/" + end + end + + class ::PostsController < ActionController::Base + include BlogEngine.routes.url_helpers + include RailsApplication.routes.mounted_helpers + + def show + render plain: post_path(id: params[:id]) + end + end + + def app + RailsApplication.instance + end + + test "generating path inside engine" do + get "/posts/1" + assert_equal "/posts/1", response.body + end + + test "[ENGINE] relative path root uses SCRIPT_NAME from request" do + get "/relative_path_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do + get "/relative_path_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] relative option root uses SCRIPT_NAME from request" do + get "/relative_option_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do + get "/relative_option_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do + get "/relative_custom_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do + get "/relative_custom_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] absolute path root doesn't use SCRIPT_NAME from request" do + get "/absolute_path_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do + get "/absolute_path_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do + get "/absolute_option_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do + get "/absolute_option_redirect" + verify_redirect "http://www.example.com/foo" + end + + test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do + get "/absolute_custom_root" + verify_redirect "http://www.example.com/" + end + + test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do + get "/absolute_custom_redirect" + verify_redirect "http://www.example.com/foo" + end + + private + def verify_redirect(url, status = 301) + assert_equal status, response.status + assert_equal url, response.headers["Location"] + assert_equal expected_redirect_body(url), response.body + end + + def expected_redirect_body(url) + %(<html><body>You are being <a href="#{url}">redirected</a>.</body></html>) + end + end +end |