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 include Rack::Test::Methods 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", last_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", last_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", last_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", last_response.body end test "[ENGINE] relative path root uses SCRIPT_NAME from request" do get "/awesome/blog/relative_path_root" verify_redirect "http://example.org/awesome/blog" end test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do get "/awesome/blog/relative_path_redirect" verify_redirect "http://example.org/awesome/blog/foo" end test "[ENGINE] relative option root uses SCRIPT_NAME from request" do get "/awesome/blog/relative_option_root" verify_redirect "http://example.org/awesome/blog" end test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do get "/awesome/blog/relative_option_redirect" verify_redirect "http://example.org/awesome/blog/foo" end test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do get "/awesome/blog/relative_custom_root" verify_redirect "http://example.org/awesome/blog" end test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do get "/awesome/blog/relative_custom_redirect" verify_redirect "http://example.org/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://example.org/" end test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do get "/awesome/blog/absolute_path_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do get "/awesome/blog/absolute_option_root" verify_redirect "http://example.org/" end test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do get "/awesome/blog/absolute_option_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do get "/awesome/blog/absolute_custom_root" verify_redirect "http://example.org/" end test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do get "/awesome/blog/absolute_custom_redirect" verify_redirect "http://example.org/foo" end # Inside Application test "[APP] generating engine's route includes prefix" do get "/generate" assert_equal "/awesome/blog/posts/1", last_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", last_response.body end test "[APP] generating engine's url with polymorphic path" do get "/polymorphic_path_for_engine" assert_equal "/awesome/blog/posts/1", last_response.body end test "polymorphic_path_for_app" do get "/polymorphic_path_for_app" assert_equal "/posts/1", last_response.body end test "[APP] generating engine's url with url_for(@post)" do get "/polymorphic_with_url_for" assert_equal "http://example.org/awesome/blog/posts/1", last_response.body end test "[APP] instance variable with same name as engine" do get "/ivar_usage" assert_equal "/awesome/blog/posts/1", last_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, last_response.status assert_equal url, last_response.headers["Location"] assert_equal expected_redirect_body(url), last_response.body end def expected_redirect_body(url) %(You are being redirected.) end end class EngineMountedAtRoot < ActionDispatch::IntegrationTest include Rack::Test::Methods 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", last_response.body end test "[ENGINE] relative path root uses SCRIPT_NAME from request" do get "/relative_path_root" verify_redirect "http://example.org/" end test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do get "/relative_path_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] relative option root uses SCRIPT_NAME from request" do get "/relative_option_root" verify_redirect "http://example.org/" end test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do get "/relative_option_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] relative custom root uses SCRIPT_NAME from request" do get "/relative_custom_root" verify_redirect "http://example.org/" end test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do get "/relative_custom_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] absolute path root doesn't use SCRIPT_NAME from request" do get "/absolute_path_root" verify_redirect "http://example.org/" end test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do get "/absolute_path_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] absolute option root doesn't use SCRIPT_NAME from request" do get "/absolute_option_root" verify_redirect "http://example.org/" end test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do get "/absolute_option_redirect" verify_redirect "http://example.org/foo" end test "[ENGINE] absolute custom root doesn't use SCRIPT_NAME from request" do get "/absolute_custom_root" verify_redirect "http://example.org/" end test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do get "/absolute_custom_redirect" verify_redirect "http://example.org/foo" end private def verify_redirect(url, status = 301) assert_equal status, last_response.status assert_equal url, last_response.headers["Location"] assert_equal expected_redirect_body(url), last_response.body end def expected_redirect_body(url) %(You are being redirected.) end end end