From 177a4bd5b7f903030a100f9b5092b1fa62c7c748 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Wed, 7 Jul 2010 18:38:14 +0200 Subject: Fix url generation for mounted Engine I added integration tests for generating urls in Engine and application and tweaked Engines to fully cooparate with new router's behavior: * Rails.application now sets ORIGINAL_SCRIPT_NAME * Rails.application also sets its routes as env['action_dispatch.parent_routes'] * Engine implements responds_to? class method to respond to all the instance methods, like #routes --- railties/lib/rails/application.rb | 10 +- railties/lib/rails/engine.rb | 9 +- .../test/railties/mounted_engine_routes_test.rb | 107 +++++++++++++++++++++ 3 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 railties/test/railties/mounted_engine_routes_test.rb diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 4ea828c549..3dba5f78a2 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -121,14 +121,20 @@ module Rails alias :build_middleware_stack :app def call(env) + if Rails.application == self + env["ORIGINAL_SCRIPT_NAME"] = env["SCRIPT_NAME"] + env["action_dispatch.parent_routes"] = routes + end + + env["action_dispatch.routes"] = routes app.call(env.reverse_merge!(env_defaults)) end def env_defaults - @env_defaults ||= super.merge({ + @env_defaults ||= { "action_dispatch.parameter_filter" => config.filter_parameters, "action_dispatch.secret_token" => config.secret_token - }) + } end def initializers diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 22a1a15bf5..401c4ff56b 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -159,13 +159,8 @@ module Rails end def call(env) - app.call(env.reverse_merge!(env_defaults)) - end - - def env_defaults - @env_defaults ||= { - "action_dispatch.routes" => routes - } + env["action_dispatch.routes"] = routes + app.call(env) end def routes diff --git a/railties/test/railties/mounted_engine_routes_test.rb b/railties/test/railties/mounted_engine_routes_test.rb new file mode 100644 index 0000000000..fe598b58b1 --- /dev/null +++ b/railties/test/railties/mounted_engine_routes_test.rb @@ -0,0 +1,107 @@ +require 'isolation/abstract_unit' + +module ApplicationTests + class ApplicationRoutingTest < Test::Unit::TestCase + require 'rack/test' + include Rack::Test::Methods + include ActiveSupport::Testing::Isolation + + def setup + build_app + + add_to_config("config.action_dispatch.show_exceptions = false") + + @plugin = engine "blog" + + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do |map| + match "/engine_route" => "application_generating#engine_route" + match "/url_for_engine_route" => "application_generating#url_for_engine_route" + scope "/:user", :user => "anonymous" do + mount Blog::Engine => "/blog" + end + root :to => 'main#index' + end + RUBY + + @plugin.write "lib/blog.rb", <<-RUBY + module Blog + class Engine < ::Rails::Engine + end + end + RUBY + + app_file "config/initializers/bla.rb", <<-RUBY + Blog::Engine.eager_load! + RUBY + + @plugin.write "config/routes.rb", <<-RUBY + Blog::Engine.routes.draw do + resources :posts do + get :generate_application_route + end + end + RUBY + + @plugin.write "app/controllers/posts_controller.rb", <<-RUBY + class PostsController < ActionController::Base + include Blog::Engine.routes.url_helpers + + def index + render :text => post_path(1) + end + + def generate_application_route + path = url_for( :routes => Rails.application.routes, + :controller => "main", + :action => "index", + :only_path => true) + render :text => path + end + end + RUBY + + app_file "app/controllers/application_generating_controller.rb", <<-RUBY + class ApplicationGeneratingController < ActionController::Base + include Blog::Engine.routes.url_helpers + + def engine_route + render :text => posts_path + end + + def url_for_engine_route + render :text => url_for(:controller => "posts", :action => "index", :user => "john", :only_path => true) + end + end + RUBY + + boot_rails + end + + def app + @app ||= begin + require "#{app_path}/config/environment" + Rails.application + end + end + + test "routes generation in engine and application" do + # test generating engine's route from engine + get "/john/blog/posts" + assert_equal "/john/blog/posts/1", last_response.body + + # test generating engine's route from application + get "/engine_route" + assert_equal "/anonymous/blog/posts", last_response.body + get "/url_for_engine_route" + assert_equal "/john/blog/posts", last_response.body + + # test generating application's route from engine + get "/someone/blog/generate_application_route" + assert_equal "/", last_response.body + get "/someone/blog/generate_application_route", {}, "SCRIPT_NAME" => "/foo" + assert_equal "/foo/", last_response.body + end + end +end + -- cgit v1.2.3