diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 57c697207821d..0ec4e41470107 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -594,6 +594,7 @@ def call(env) def recognize_path(path, environment = {}) method = (environment[:method] || "GET").to_s.upcase path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://} + extras = environment[:extras] || {} begin env = Rack::MockRequest.env_for(path, {:method => method}) @@ -603,6 +604,7 @@ def recognize_path(path, environment = {}) req = @request_class.new(env) @router.recognize(req) do |route, matches, params| + params.merge!(extras) params.each do |key, value| if value.is_a?(String) value = value.dup.force_encoding(Encoding::BINARY) diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 1552676fbb7e5..1f4b905d183bd 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -39,10 +39,9 @@ module RoutingAssertions # # Test a custom route # assert_recognizes({:controller => 'items', :action => 'show', :id => '1'}, 'view/item1') def assert_recognizes(expected_options, path, extras={}, message=nil) - request = recognized_request_for(path) + request = recognized_request_for(path, extras) expected_options = expected_options.clone - extras.each_key { |key| expected_options.delete key } unless extras.nil? expected_options.stringify_keys! @@ -181,7 +180,7 @@ def method_missing(selector, *args, &block) private # Recognizes the route for a given path. - def recognized_request_for(path) + def recognized_request_for(path, extras = {}) if path.is_a?(Hash) method = path[:method] path = path[:path] @@ -209,7 +208,7 @@ def recognized_request_for(path) request.request_method = method if method - params = @routes.recognize_path(path, { :method => method }) + params = @routes.recognize_path(path, { :method => method, :extras => extras }) request.path_parameters = params.with_indifferent_access request diff --git a/actionpack/test/dispatch/routing_assertions_test.rb b/actionpack/test/dispatch/routing_assertions_test.rb index 9f95d82129e18..e953029456556 100644 --- a/actionpack/test/dispatch/routing_assertions_test.rb +++ b/actionpack/test/dispatch/routing_assertions_test.rb @@ -3,6 +3,7 @@ class SecureArticlesController < ArticlesController; end class BlockArticlesController < ArticlesController; end +class QueryArticlesController < ArticlesController; end class RoutingAssertionsTest < ActionController::TestCase @@ -18,6 +19,10 @@ def setup scope 'block', :constraints => lambda { |r| r.ssl? } do resources :articles, :controller => 'block_articles' end + + scope 'query', :constraints => lambda { |r| r.params[:use_query] == 'true' } do + resources :articles, :controller => 'query_articles' + end end end @@ -62,6 +67,13 @@ def test_assert_recognizes_with_block_constraint assert_recognizes({ :controller => 'block_articles', :action => 'index' }, 'https://test.host/block/articles') end + def test_assert_recognizes_with_query_constraint + assert_raise(ActionController::RoutingError) do + assert_recognizes({ :controller => 'query_articles', :action => 'index', :use_query => 'false' }, '/query/articles', { :use_query => 'false' }) + end + assert_recognizes({ :controller => 'query_articles', :action => 'index', :use_query => 'true' }, '/query/articles', { :use_query => 'true' }) + end + def test_assert_routing assert_routing('/articles', :controller => 'articles', :action => 'index') end