mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
0b6175ac2d
Many named routes have keys that are required to successfully resolve. If a key is left off like this: <%= link_to 'user', user_path %> This will produce an error like this: No route matches {:action=>"show", :controller=>"users"} Since we know that the :id is missing, we can add extra debugging information to the error message. No route matches {:action=>"show", :controller=>"users"} missing required keys: [:id] This will help new and seasoned developers look closer at their parameters. I've also subclassed the routing error to be clear that this error is a result of attempting to generate a url and not because the user is trying to visit a bad url. While this may sound trivial this error message is misleading and confuses most developers. The important part isn't what's in the options its's what's missing. Adding this information to the error message will make debugging much more obvious. This is the sister pull request of https://github.com/rails/journey/pull/44 which will be required to get they missing keys into the correct error message. Example Development Error in Rails: http://cl.ly/image/3S0T0n1T3421
1898 lines
71 KiB
Ruby
1898 lines
71 KiB
Ruby
# encoding: utf-8
|
|
require 'abstract_unit'
|
|
require 'controller/fake_controllers'
|
|
require 'active_support/core_ext/object/with_options'
|
|
|
|
class MilestonesController < ActionController::Base
|
|
def index() head :ok end
|
|
alias_method :show, :index
|
|
end
|
|
|
|
ROUTING = ActionDispatch::Routing
|
|
|
|
# See RFC 3986, section 3.3 for allowed path characters.
|
|
class UriReservedCharactersRoutingTest < ActiveSupport::TestCase
|
|
include RoutingTestHelpers
|
|
|
|
def setup
|
|
@set = ActionDispatch::Routing::RouteSet.new
|
|
@set.draw do
|
|
get ':controller/:action/:variable/*additional'
|
|
end
|
|
|
|
safe, unsafe = %w(: @ & = + $ , ;), %w(^ ? # [ ])
|
|
hex = unsafe.map { |char| '%' + char.unpack('H2').first.upcase }
|
|
|
|
@segment = "#{safe.join}#{unsafe.join}".freeze
|
|
@escaped = "#{safe.join}#{hex.join}".freeze
|
|
end
|
|
|
|
def test_route_generation_escapes_unsafe_path_characters
|
|
assert_equal "/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2",
|
|
url_for(@set, {
|
|
:controller => "content",
|
|
:action => "act#{@segment}ion",
|
|
:variable => "var#{@segment}iable",
|
|
:additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"]
|
|
})
|
|
end
|
|
|
|
def test_route_recognition_unescapes_path_components
|
|
options = { :controller => "content",
|
|
:action => "act#{@segment}ion",
|
|
:variable => "var#{@segment}iable",
|
|
:additional => "add#{@segment}itional-1/add#{@segment}itional-2" }
|
|
assert_equal options, @set.recognize_path("/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2")
|
|
end
|
|
|
|
def test_route_generation_allows_passing_non_string_values_to_generated_helper
|
|
assert_equal "/content/action/variable/1/2",
|
|
url_for(@set, {
|
|
:controller => "content",
|
|
:action => "action",
|
|
:variable => "variable",
|
|
:additional => [1, 2]
|
|
})
|
|
end
|
|
end
|
|
|
|
class MockController
|
|
def self.build(helpers)
|
|
Class.new do
|
|
def url_options
|
|
options = super
|
|
options[:protocol] ||= "http"
|
|
options[:host] ||= "test.host"
|
|
options
|
|
end
|
|
|
|
include helpers
|
|
end
|
|
end
|
|
end
|
|
|
|
class LegacyRouteSetTests < ActiveSupport::TestCase
|
|
include RoutingTestHelpers
|
|
include ActionDispatch::RoutingVerbs
|
|
|
|
attr_reader :rs
|
|
alias :routes :rs
|
|
|
|
def setup
|
|
@rs = ::ActionDispatch::Routing::RouteSet.new
|
|
@response = nil
|
|
end
|
|
|
|
def test_symbols_with_dashes
|
|
rs.draw do
|
|
get '/:artist/:song-omg', :to => lambda { |env|
|
|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
|
|
[200, {}, [resp]]
|
|
}
|
|
end
|
|
|
|
hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
|
|
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
|
|
end
|
|
|
|
def test_id_with_dash
|
|
rs.draw do
|
|
get '/journey/:id', :to => lambda { |env|
|
|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
|
|
[200, {}, [resp]]
|
|
}
|
|
end
|
|
|
|
hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
|
|
assert_equal({"id"=>"faithfully-omg"}, hash)
|
|
end
|
|
|
|
def test_dash_with_custom_regexp
|
|
rs.draw do
|
|
get '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env|
|
|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
|
|
[200, {}, [resp]]
|
|
}
|
|
end
|
|
|
|
hash = JSON.load get(URI('http://example.org/journey/123-omg'))
|
|
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
|
|
assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg'))
|
|
end
|
|
|
|
def test_pre_dash
|
|
rs.draw do
|
|
get '/:artist/omg-:song', :to => lambda { |env|
|
|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
|
|
[200, {}, [resp]]
|
|
}
|
|
end
|
|
|
|
hash = JSON.load get(URI('http://example.org/journey/omg-faithfully'))
|
|
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
|
|
end
|
|
|
|
def test_pre_dash_with_custom_regexp
|
|
rs.draw do
|
|
get '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env|
|
|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
|
|
[200, {}, [resp]]
|
|
}
|
|
end
|
|
|
|
hash = JSON.load get(URI('http://example.org/journey/omg-123'))
|
|
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
|
|
assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully'))
|
|
end
|
|
|
|
def test_star_paths_are_greedy
|
|
rs.draw do
|
|
get "/*path", :to => lambda { |env|
|
|
x = env["action_dispatch.request.path_parameters"][:path]
|
|
[200, {}, [x]]
|
|
}, :format => false
|
|
end
|
|
|
|
u = URI('http://example.org/foo/bar.html')
|
|
assert_equal u.path.sub(/^\//, ''), get(u)
|
|
end
|
|
|
|
def test_star_paths_are_greedy_but_not_too_much
|
|
rs.draw do
|
|
get "/*path", :to => lambda { |env|
|
|
x = JSON.dump env["action_dispatch.request.path_parameters"]
|
|
[200, {}, [x]]
|
|
}
|
|
end
|
|
|
|
expected = { "path" => "foo/bar", "format" => "html" }
|
|
u = URI('http://example.org/foo/bar.html')
|
|
assert_equal expected, JSON.parse(get(u))
|
|
end
|
|
|
|
def test_optional_star_paths_are_greedy
|
|
rs.draw do
|
|
get "/(*filters)", :to => lambda { |env|
|
|
x = env["action_dispatch.request.path_parameters"][:filters]
|
|
[200, {}, [x]]
|
|
}, :format => false
|
|
end
|
|
|
|
u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
|
|
assert_equal u.path.sub(/^\//, ''), get(u)
|
|
end
|
|
|
|
def test_optional_star_paths_are_greedy_but_not_too_much
|
|
rs.draw do
|
|
get "/(*filters)", :to => lambda { |env|
|
|
x = JSON.dump env["action_dispatch.request.path_parameters"]
|
|
[200, {}, [x]]
|
|
}
|
|
end
|
|
|
|
expected = { "filters" => "ne_27.065938,-80.6092/sw_25.489856,-82",
|
|
"format" => "542794" }
|
|
u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
|
|
assert_equal expected, JSON.parse(get(u))
|
|
end
|
|
|
|
def test_regexp_precidence
|
|
rs.draw do
|
|
get '/whois/:domain', :constraints => {
|
|
:domain => /\w+\.[\w\.]+/ },
|
|
:to => lambda { |env| [200, {}, %w{regexp}] }
|
|
|
|
get '/whois/:id', :to => lambda { |env| [200, {}, %w{id}] }
|
|
end
|
|
|
|
assert_equal 'regexp', get(URI('http://example.org/whois/example.org'))
|
|
assert_equal 'id', get(URI('http://example.org/whois/123'))
|
|
end
|
|
|
|
def test_class_and_lambda_constraints
|
|
subdomain = Class.new {
|
|
def matches? request
|
|
request.subdomain.present? and request.subdomain != 'clients'
|
|
end
|
|
}
|
|
|
|
rs.draw do
|
|
get '/', :constraints => subdomain.new,
|
|
:to => lambda { |env| [200, {}, %w{default}] }
|
|
get '/', :constraints => { :subdomain => 'clients' },
|
|
:to => lambda { |env| [200, {}, %w{clients}] }
|
|
end
|
|
|
|
assert_equal 'default', get(URI('http://www.example.org/'))
|
|
assert_equal 'clients', get(URI('http://clients.example.org/'))
|
|
end
|
|
|
|
def test_lambda_constraints
|
|
rs.draw do
|
|
get '/', :constraints => lambda { |req|
|
|
req.subdomain.present? and req.subdomain != "clients" },
|
|
:to => lambda { |env| [200, {}, %w{default}] }
|
|
|
|
get '/', :constraints => lambda { |req|
|
|
req.subdomain.present? && req.subdomain == "clients" },
|
|
:to => lambda { |env| [200, {}, %w{clients}] }
|
|
end
|
|
|
|
assert_equal 'default', get(URI('http://www.example.org/'))
|
|
assert_equal 'clients', get(URI('http://clients.example.org/'))
|
|
end
|
|
|
|
def test_empty_string_match
|
|
rs.draw do
|
|
get '/:username', :constraints => { :username => /[^\/]+/ },
|
|
:to => lambda { |e| [200, {}, ['foo']] }
|
|
end
|
|
assert_equal 'Not Found', get(URI('http://example.org/'))
|
|
assert_equal 'foo', get(URI('http://example.org/hello'))
|
|
end
|
|
|
|
def test_non_greedy_glob_regexp
|
|
params = nil
|
|
rs.draw do
|
|
get '/posts/:id(/*filters)', :constraints => { :filters => /.+?/ },
|
|
:to => lambda { |e|
|
|
params = e["action_dispatch.request.path_parameters"]
|
|
[200, {}, ['foo']]
|
|
}
|
|
end
|
|
assert_equal 'foo', get(URI('http://example.org/posts/1/foo.js'))
|
|
assert_equal({:id=>"1", :filters=>"foo", :format=>"js"}, params)
|
|
end
|
|
|
|
def test_draw_with_block_arity_one_raises
|
|
assert_raise(RuntimeError) do
|
|
rs.draw { |map| map.match '/:controller(/:action(/:id))' }
|
|
end
|
|
end
|
|
|
|
def test_specific_controller_action_failure
|
|
rs.draw do
|
|
mount lambda {} => "/foo"
|
|
end
|
|
|
|
assert_raises(ActionController::UrlGenerationError) do
|
|
url_for(rs, :controller => "omg", :action => "lol")
|
|
end
|
|
end
|
|
|
|
def test_default_setup
|
|
rs.draw { get '/:controller(/:action(/:id))' }
|
|
assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
|
|
assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
|
|
assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
|
|
|
|
assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
|
|
|
|
assert_equal '/admin/user/show/10', url_for(rs, { :controller => 'admin/user', :action => 'show', :id => 10 })
|
|
|
|
assert_equal '/admin/user/show', url_for(rs, { :action => 'show' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
|
|
assert_equal '/admin/user/list/10', url_for(rs, {}, { :controller => 'admin/user', :action => 'list', :id => '10' })
|
|
|
|
assert_equal '/admin/stuff', url_for(rs, { :controller => 'stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
|
|
assert_equal '/stuff', url_for(rs, { :controller => '/stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
|
|
end
|
|
|
|
def test_ignores_leading_slash
|
|
rs.clear!
|
|
rs.draw { get '/:controller(/:action(/:id))'}
|
|
test_default_setup
|
|
end
|
|
|
|
def test_route_with_colon_first
|
|
rs.draw do
|
|
get '/:controller/:action/:id', :action => 'index', :id => nil
|
|
get ':url', :controller => 'tiny_url', :action => 'translate'
|
|
end
|
|
end
|
|
|
|
def test_route_with_regexp_for_controller
|
|
rs.draw do
|
|
get ':controller/:admintoken(/:action(/:id))', :controller => /admin\/.+/
|
|
get '/:controller(/:action(/:id))'
|
|
end
|
|
|
|
assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
|
|
rs.recognize_path("/admin/user/foo"))
|
|
assert_equal({:controller => "content", :action => "foo"},
|
|
rs.recognize_path("/content/foo"))
|
|
|
|
assert_equal '/admin/user/foo', url_for(rs, { :controller => "admin/user", :admintoken => "foo", :action => "index" })
|
|
assert_equal '/content/foo', url_for(rs, { :controller => "content", :action => "foo" })
|
|
end
|
|
|
|
def test_route_with_regexp_and_captures_for_controller
|
|
rs.draw do
|
|
get '/:controller(/:action(/:id))', :controller => /admin\/(accounts|users)/
|
|
end
|
|
assert_equal({:controller => "admin/accounts", :action => "index"}, rs.recognize_path("/admin/accounts"))
|
|
assert_equal({:controller => "admin/users", :action => "index"}, rs.recognize_path("/admin/users"))
|
|
assert_raise(ActionController::RoutingError) { rs.recognize_path("/admin/products") }
|
|
end
|
|
|
|
def test_route_with_regexp_and_dot
|
|
rs.draw do
|
|
get ':controller/:action/:file',
|
|
:controller => /admin|user/,
|
|
:action => /upload|download/,
|
|
:defaults => {:file => nil},
|
|
:constraints => {:file => %r{[^/]+(\.[^/]+)?}}
|
|
end
|
|
# Without a file extension
|
|
assert_equal '/user/download/file',
|
|
url_for(rs, { :controller => "user", :action => "download", :file => "file" })
|
|
|
|
assert_equal({:controller => "user", :action => "download", :file => "file"},
|
|
rs.recognize_path("/user/download/file"))
|
|
|
|
# Now, let's try a file with an extension, really a dot (.)
|
|
assert_equal '/user/download/file.jpg',
|
|
url_for(rs, { :controller => "user", :action => "download", :file => "file.jpg" })
|
|
|
|
assert_equal({:controller => "user", :action => "download", :file => "file.jpg"},
|
|
rs.recognize_path("/user/download/file.jpg"))
|
|
end
|
|
|
|
def test_basic_named_route
|
|
rs.draw do
|
|
root :to => 'content#list', :as => 'home'
|
|
end
|
|
assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
|
|
end
|
|
|
|
def test_named_route_with_option
|
|
rs.draw do
|
|
get 'page/:title' => 'content#show_page', :as => 'page'
|
|
end
|
|
|
|
assert_equal("http://test.host/page/new%20stuff",
|
|
setup_for_named_route.send(:page_url, :title => 'new stuff'))
|
|
end
|
|
|
|
def test_named_route_with_default
|
|
rs.draw do
|
|
get 'page/:title' => 'content#show_page', :title => 'AboutPage', :as => 'page'
|
|
end
|
|
|
|
assert_equal("http://test.host/page/AboutRails",
|
|
setup_for_named_route.send(:page_url, :title => "AboutRails"))
|
|
end
|
|
|
|
def test_named_route_with_path_prefix
|
|
rs.draw do
|
|
scope "my" do
|
|
get 'page' => 'content#show_page', :as => 'page'
|
|
end
|
|
end
|
|
|
|
assert_equal("http://test.host/my/page",
|
|
setup_for_named_route.send(:page_url))
|
|
end
|
|
|
|
def test_named_route_with_blank_path_prefix
|
|
rs.draw do
|
|
scope "" do
|
|
get 'page' => 'content#show_page', :as => 'page'
|
|
end
|
|
end
|
|
|
|
assert_equal("http://test.host/page",
|
|
setup_for_named_route.send(:page_url))
|
|
end
|
|
|
|
def test_named_route_with_nested_controller
|
|
rs.draw do
|
|
get 'admin/user' => 'admin/user#index', :as => "users"
|
|
end
|
|
|
|
assert_equal("http://test.host/admin/user",
|
|
setup_for_named_route.send(:users_url))
|
|
end
|
|
|
|
def test_optimised_named_route_with_host
|
|
rs.draw do
|
|
get 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com'
|
|
end
|
|
routes = setup_for_named_route
|
|
routes.expects(:url_for).with({
|
|
:host => 'foo.com',
|
|
:only_path => false,
|
|
:controller => 'content',
|
|
:action => 'show_page',
|
|
:use_route => 'pages'
|
|
}).once
|
|
routes.send(:pages_url)
|
|
end
|
|
|
|
def setup_for_named_route
|
|
MockController.build(rs.url_helpers).new
|
|
end
|
|
|
|
def test_named_route_without_hash
|
|
rs.draw do
|
|
get ':controller/:action/:id', :as => 'normal'
|
|
end
|
|
end
|
|
|
|
def test_named_route_root
|
|
rs.draw do
|
|
root :to => "hello#index"
|
|
end
|
|
routes = setup_for_named_route
|
|
assert_equal("http://test.host/", routes.send(:root_url))
|
|
assert_equal("/", routes.send(:root_path))
|
|
end
|
|
|
|
def test_named_route_root_without_hash
|
|
rs.draw do
|
|
root "hello#index"
|
|
end
|
|
routes = setup_for_named_route
|
|
assert_equal("http://test.host/", routes.send(:root_url))
|
|
assert_equal("/", routes.send(:root_path))
|
|
end
|
|
|
|
def test_named_route_with_regexps
|
|
rs.draw do
|
|
get 'page/:year/:month/:day/:title' => 'page#show', :as => 'article',
|
|
:year => /\d+/, :month => /\d+/, :day => /\d+/
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
routes = setup_for_named_route
|
|
|
|
assert_equal "http://test.host/page/2005/6/10/hi",
|
|
routes.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
|
|
end
|
|
|
|
def test_changing_controller
|
|
rs.draw { get ':controller/:action/:id' }
|
|
|
|
assert_equal '/admin/stuff/show/10',
|
|
url_for(rs, {:controller => 'stuff', :action => 'show', :id => 10},
|
|
{:controller => 'admin/user', :action => 'index'})
|
|
end
|
|
|
|
def test_paths_escaped
|
|
rs.draw do
|
|
get 'file/*path' => 'content#show_file', :as => 'path'
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
# No + to space in URI escaping, only for query params.
|
|
results = rs.recognize_path "/file/hello+world/how+are+you%3F"
|
|
assert results, "Recognition should have succeeded"
|
|
assert_equal 'hello+world/how+are+you?', results[:path]
|
|
|
|
# Use %20 for space instead.
|
|
results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
|
|
assert results, "Recognition should have succeeded"
|
|
assert_equal 'hello world/how are you?', results[:path]
|
|
end
|
|
|
|
def test_paths_slashes_unescaped_with_ordered_parameters
|
|
rs.draw do
|
|
get '/file/*path' => 'content#index', :as => 'path'
|
|
end
|
|
|
|
# No / to %2F in URI, only for query params.
|
|
assert_equal("/file/hello/world", setup_for_named_route.send(:path_path, ['hello', 'world']))
|
|
end
|
|
|
|
def test_non_controllers_cannot_be_matched
|
|
rs.draw do
|
|
get ':controller/:action/:id'
|
|
end
|
|
assert_raise(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
|
|
end
|
|
|
|
def test_should_list_options_diff_when_routing_constraints_dont_match
|
|
rs.draw do
|
|
get 'post/:id' => 'post#show', :constraints => { :id => /\d+/ }, :as => 'post'
|
|
end
|
|
assert_raise(ActionController::UrlGenerationError) do
|
|
url_for(rs, { :controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post" })
|
|
end
|
|
end
|
|
|
|
def test_dynamic_path_allowed
|
|
rs.draw do
|
|
get '*path' => 'content#show_file'
|
|
end
|
|
|
|
assert_equal '/pages/boo',
|
|
url_for(rs, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
|
|
end
|
|
|
|
def test_dynamic_recall_paths_allowed
|
|
rs.draw do
|
|
get '*path' => 'content#show_file'
|
|
end
|
|
|
|
assert_equal '/pages/boo',
|
|
url_for(rs, {}, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
|
|
end
|
|
|
|
def test_backwards
|
|
rs.draw do
|
|
get 'page/:id(/:action)' => 'pages#show'
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
|
|
assert_equal '/page/20', url_for(rs, { :id => 20 }, { :controller => 'pages', :action => 'show' })
|
|
assert_equal '/page/20', url_for(rs, { :controller => 'pages', :id => 20, :action => 'show' })
|
|
assert_equal '/pages/boo', url_for(rs, { :controller => 'pages', :action => 'boo' })
|
|
end
|
|
|
|
def test_route_with_fixnum_default
|
|
rs.draw do
|
|
get 'page(/:id)' => 'content#show_page', :id => 1
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page' })
|
|
assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 1 })
|
|
assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => '1' })
|
|
assert_equal '/page/10', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 10 })
|
|
|
|
assert_equal({:controller => "content", :action => 'show_page', :id => 1 }, rs.recognize_path("/page"))
|
|
assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
|
|
assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
|
|
end
|
|
|
|
# For newer revision
|
|
def test_route_with_text_default
|
|
rs.draw do
|
|
get 'page/:id' => 'content#show_page', :id => 1
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/page/foo', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 'foo' })
|
|
assert_equal({ :controller => "content", :action => 'show_page', :id => 'foo' }, rs.recognize_path("/page/foo"))
|
|
|
|
token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in Russian
|
|
token.force_encoding(Encoding::BINARY)
|
|
escaped_token = CGI::escape(token)
|
|
|
|
assert_equal '/page/' + escaped_token, url_for(rs, { :controller => 'content', :action => 'show_page', :id => token })
|
|
assert_equal({ :controller => "content", :action => 'show_page', :id => token }, rs.recognize_path("/page/#{escaped_token}"))
|
|
end
|
|
|
|
def test_action_expiry
|
|
rs.draw { get ':controller(/:action(/:id))' }
|
|
assert_equal '/content', url_for(rs, { :controller => 'content' }, { :controller => 'content', :action => 'show' })
|
|
end
|
|
|
|
def test_requirement_should_prevent_optional_id
|
|
rs.draw do
|
|
get 'post/:id' => 'post#show', :constraints => {:id => /\d+/}, :as => 'post'
|
|
end
|
|
|
|
assert_equal '/post/10', url_for(rs, { :controller => 'post', :action => 'show', :id => 10 })
|
|
|
|
assert_raise(ActionController::UrlGenerationError) do
|
|
url_for(rs, { :controller => 'post', :action => 'show' })
|
|
end
|
|
end
|
|
|
|
def test_both_requirement_and_optional
|
|
rs.draw do
|
|
get('test(/:year)' => 'post#show', :as => 'blog',
|
|
:defaults => { :year => nil },
|
|
:constraints => { :year => /\d{4}/ }
|
|
)
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show' })
|
|
assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show', :year => nil })
|
|
|
|
assert_equal("http://test.host/test", setup_for_named_route.send(:blog_url))
|
|
end
|
|
|
|
def test_set_to_nil_forgets
|
|
rs.draw do
|
|
get 'pages(/:year(/:month(/:day)))' => 'content#list_pages', :month => nil, :day => nil
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/pages/2005',
|
|
url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005 })
|
|
assert_equal '/pages/2005/6',
|
|
url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6 })
|
|
assert_equal '/pages/2005/6/12',
|
|
url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12 })
|
|
|
|
assert_equal '/pages/2005/6/4',
|
|
url_for(rs, { :day => 4 }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
|
|
|
|
assert_equal '/pages/2005/6',
|
|
url_for(rs, { :day => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
|
|
|
|
assert_equal '/pages/2005',
|
|
url_for(rs, { :day => nil, :month => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
|
|
end
|
|
|
|
def test_root_url_generation_with_controller_and_action
|
|
rs.draw do
|
|
root :to => "content#index"
|
|
end
|
|
|
|
assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
|
|
assert_equal '/', url_for(rs, { :controller => 'content' })
|
|
end
|
|
|
|
def test_named_root_url_generation_with_controller_and_action
|
|
rs.draw do
|
|
root :to => "content#index", :as => 'home'
|
|
end
|
|
|
|
assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
|
|
assert_equal '/', url_for(rs, { :controller => 'content' })
|
|
|
|
assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
|
|
end
|
|
|
|
def test_named_route_method
|
|
rs.draw do
|
|
get 'categories' => 'content#categories', :as => 'categories'
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
|
|
assert_equal '/categories', url_for(rs, { :controller => 'content', :action => 'categories' })
|
|
assert_equal '/content/hi', url_for(rs, { :controller => 'content', :action => 'hi' })
|
|
end
|
|
|
|
def test_named_routes_array
|
|
test_named_route_method
|
|
assert_equal [:categories], rs.named_routes.names
|
|
end
|
|
|
|
def test_nil_defaults
|
|
rs.draw do
|
|
get 'journal' => 'content#list_journal',
|
|
:date => nil, :user_id => nil
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/journal', url_for(rs, {
|
|
:controller => 'content',
|
|
:action => 'list_journal',
|
|
:date => nil,
|
|
:user_id => nil
|
|
})
|
|
end
|
|
|
|
def setup_request_method_routes_for(method)
|
|
rs.draw do
|
|
match '/match' => 'books#get', :via => :get
|
|
match '/match' => 'books#post', :via => :post
|
|
match '/match' => 'books#put', :via => :put
|
|
match '/match' => 'books#patch', :via => :patch
|
|
match '/match' => 'books#delete', :via => :delete
|
|
end
|
|
end
|
|
|
|
%w(GET PATCH POST PUT DELETE).each do |request_method|
|
|
define_method("test_request_method_recognized_with_#{request_method}") do
|
|
setup_request_method_routes_for(request_method)
|
|
params = rs.recognize_path("/match", :method => request_method)
|
|
assert_equal request_method.downcase, params[:action]
|
|
end
|
|
end
|
|
|
|
def test_recognize_array_of_methods
|
|
rs.draw do
|
|
match '/match' => 'books#get_or_post', :via => [:get, :post]
|
|
put '/match' => 'books#not_get_or_post'
|
|
end
|
|
|
|
params = rs.recognize_path("/match", :method => :post)
|
|
assert_equal 'get_or_post', params[:action]
|
|
|
|
params = rs.recognize_path("/match", :method => :put)
|
|
assert_equal 'not_get_or_post', params[:action]
|
|
end
|
|
|
|
def test_subpath_recognized
|
|
rs.draw do
|
|
get '/books/:id/edit' => 'subpath_books#edit'
|
|
get '/items/:id/:action' => 'subpath_books'
|
|
get '/posts/new/:action' => 'subpath_books'
|
|
get '/posts/:id' => 'subpath_books#show'
|
|
end
|
|
|
|
hash = rs.recognize_path "/books/17/edit"
|
|
assert_not_nil hash
|
|
assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
|
|
|
|
hash = rs.recognize_path "/items/3/complete"
|
|
assert_not_nil hash
|
|
assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
|
|
|
|
hash = rs.recognize_path "/posts/new/preview"
|
|
assert_not_nil hash
|
|
assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
|
|
|
|
hash = rs.recognize_path "/posts/7"
|
|
assert_not_nil hash
|
|
assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
|
|
end
|
|
|
|
def test_subpath_generated
|
|
rs.draw do
|
|
get '/books/:id/edit' => 'subpath_books#edit'
|
|
get '/items/:id/:action' => 'subpath_books'
|
|
get '/posts/new/:action' => 'subpath_books'
|
|
end
|
|
|
|
assert_equal "/books/7/edit", url_for(rs, { :controller => "subpath_books", :id => 7, :action => "edit" })
|
|
assert_equal "/items/15/complete", url_for(rs, { :controller => "subpath_books", :id => 15, :action => "complete" })
|
|
assert_equal "/posts/new/preview", url_for(rs, { :controller => "subpath_books", :action => "preview" })
|
|
end
|
|
|
|
def test_failed_constraints_raises_exception_with_violated_constraints
|
|
rs.draw do
|
|
get 'foos/:id' => 'foos#show', :as => 'foo_with_requirement', :constraints => { :id => /\d+/ }
|
|
end
|
|
|
|
assert_raise(ActionController::UrlGenerationError) do
|
|
setup_for_named_route.send(:foo_with_requirement_url, "I am Against the constraints")
|
|
end
|
|
end
|
|
|
|
def test_routes_changed_correctly_after_clear
|
|
rs = ::ActionDispatch::Routing::RouteSet.new
|
|
rs.draw do
|
|
get 'ca' => 'ca#aa'
|
|
get 'cb' => 'cb#ab'
|
|
get 'cc' => 'cc#ac'
|
|
get ':controller/:action/:id'
|
|
get ':controller/:action/:id.:format'
|
|
end
|
|
|
|
hash = rs.recognize_path "/cc"
|
|
|
|
assert_not_nil hash
|
|
assert_equal %w(cc ac), [hash[:controller], hash[:action]]
|
|
|
|
rs.draw do
|
|
get 'cb' => 'cb#ab'
|
|
get 'cc' => 'cc#ac'
|
|
get ':controller/:action/:id'
|
|
get ':controller/:action/:id.:format'
|
|
end
|
|
|
|
hash = rs.recognize_path "/cc"
|
|
|
|
assert_not_nil hash
|
|
assert_equal %w(cc ac), [hash[:controller], hash[:action]]
|
|
end
|
|
end
|
|
|
|
class RouteSetTest < ActiveSupport::TestCase
|
|
include RoutingTestHelpers
|
|
|
|
def set
|
|
@set ||= ROUTING::RouteSet.new
|
|
end
|
|
|
|
def request
|
|
@request ||= ActionController::TestRequest.new
|
|
end
|
|
|
|
def default_route_set
|
|
@default_route_set ||= begin
|
|
set = ROUTING::RouteSet.new
|
|
set.draw do
|
|
get '/:controller(/:action(/:id))'
|
|
end
|
|
set
|
|
end
|
|
end
|
|
|
|
def test_generate_extras
|
|
set.draw { get ':controller/(:action(/:id))' }
|
|
path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
|
|
assert_equal "/foo/bar/15", path
|
|
assert_equal %w(that this), extras.map { |e| e.to_s }.sort
|
|
end
|
|
|
|
def test_extra_keys
|
|
set.draw { get ':controller/:action/:id' }
|
|
extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
|
|
assert_equal %w(that this), extras.map { |e| e.to_s }.sort
|
|
end
|
|
|
|
def test_generate_extras_not_first
|
|
set.draw do
|
|
get ':controller/:action/:id.:format'
|
|
get ':controller/:action/:id'
|
|
end
|
|
path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
|
|
assert_equal "/foo/bar/15", path
|
|
assert_equal %w(that this), extras.map { |e| e.to_s }.sort
|
|
end
|
|
|
|
def test_generate_not_first
|
|
set.draw do
|
|
get ':controller/:action/:id.:format'
|
|
get ':controller/:action/:id'
|
|
end
|
|
assert_equal "/foo/bar/15?this=hello",
|
|
url_for(set, { :controller => "foo", :action => "bar", :id => 15, :this => "hello" })
|
|
end
|
|
|
|
def test_extra_keys_not_first
|
|
set.draw do
|
|
get ':controller/:action/:id.:format'
|
|
get ':controller/:action/:id'
|
|
end
|
|
extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
|
|
assert_equal %w(that this), extras.map { |e| e.to_s }.sort
|
|
end
|
|
|
|
def test_draw
|
|
assert_equal 0, set.routes.size
|
|
set.draw do
|
|
get '/hello/world' => 'a#b'
|
|
end
|
|
assert_equal 1, set.routes.size
|
|
end
|
|
|
|
def test_draw_symbol_controller_name
|
|
assert_equal 0, set.routes.size
|
|
set.draw do
|
|
get '/users/index' => 'users#index'
|
|
end
|
|
set.recognize_path('/users/index', :method => :get)
|
|
assert_equal 1, set.routes.size
|
|
end
|
|
|
|
def test_named_draw
|
|
assert_equal 0, set.routes.size
|
|
set.draw do
|
|
get '/hello/world' => 'a#b', :as => 'hello'
|
|
end
|
|
assert_equal 1, set.routes.size
|
|
assert_equal set.routes.first, set.named_routes[:hello]
|
|
end
|
|
|
|
def test_earlier_named_routes_take_precedence
|
|
set.draw do
|
|
get '/hello/world' => 'a#b', :as => 'hello'
|
|
get '/hello' => 'a#b', :as => 'hello'
|
|
end
|
|
assert_equal set.routes.first, set.named_routes[:hello]
|
|
end
|
|
|
|
def setup_named_route_test
|
|
set.draw do
|
|
get '/people(/:id)' => 'people#show', :as => 'show'
|
|
get '/people' => 'people#index', :as => 'index'
|
|
get '/people/go/:foo/:bar/joe(/:id)' => 'people#multi', :as => 'multi'
|
|
get '/admin/users' => 'admin/users#index', :as => "users"
|
|
end
|
|
|
|
MockController.build(set.url_helpers).new
|
|
end
|
|
|
|
def test_named_route_url_method
|
|
controller = setup_named_route_test
|
|
|
|
assert_equal "http://test.host/people/5", controller.send(:show_url, :id => 5)
|
|
assert_equal "/people/5", controller.send(:show_path, :id => 5)
|
|
|
|
assert_equal "http://test.host/people", controller.send(:index_url)
|
|
assert_equal "/people", controller.send(:index_path)
|
|
|
|
assert_equal "http://test.host/admin/users", controller.send(:users_url)
|
|
assert_equal '/admin/users', controller.send(:users_path)
|
|
end
|
|
|
|
def test_named_route_url_method_with_anchor
|
|
controller = setup_named_route_test
|
|
|
|
assert_equal "http://test.host/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
|
|
assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
|
|
|
|
assert_equal "http://test.host/people#location", controller.send(:index_url, :anchor => 'location')
|
|
assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
|
|
|
|
assert_equal "http://test.host/admin/users#location", controller.send(:users_url, :anchor => 'location')
|
|
assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
|
|
|
|
assert_equal "http://test.host/people/go/7/hello/joe/5#location",
|
|
controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
|
|
|
|
assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar#location",
|
|
controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
|
|
|
|
assert_equal "http://test.host/people?baz=bar#location",
|
|
controller.send(:index_url, :baz => "bar", :anchor => 'location')
|
|
end
|
|
|
|
def test_named_route_url_method_with_port
|
|
controller = setup_named_route_test
|
|
assert_equal "http://test.host:8080/people/5", controller.send(:show_url, 5, :port=>8080)
|
|
end
|
|
|
|
def test_named_route_url_method_with_host
|
|
controller = setup_named_route_test
|
|
assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
|
|
end
|
|
|
|
def test_named_route_url_method_with_protocol
|
|
controller = setup_named_route_test
|
|
assert_equal "https://test.host/people/5", controller.send(:show_url, 5, :protocol => "https")
|
|
end
|
|
|
|
def test_named_route_url_method_with_ordered_parameters
|
|
controller = setup_named_route_test
|
|
assert_equal "http://test.host/people/go/7/hello/joe/5",
|
|
controller.send(:multi_url, 7, "hello", 5)
|
|
end
|
|
|
|
def test_named_route_url_method_with_ordered_parameters_and_hash
|
|
controller = setup_named_route_test
|
|
assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar",
|
|
controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
|
|
end
|
|
|
|
def test_named_route_url_method_with_ordered_parameters_and_empty_hash
|
|
controller = setup_named_route_test
|
|
assert_equal "http://test.host/people/go/7/hello/joe/5",
|
|
controller.send(:multi_url, 7, "hello", 5, {})
|
|
end
|
|
|
|
def test_named_route_url_method_with_no_positional_arguments
|
|
controller = setup_named_route_test
|
|
assert_equal "http://test.host/people?baz=bar",
|
|
controller.send(:index_url, :baz => "bar")
|
|
end
|
|
|
|
def test_draw_default_route
|
|
set.draw do
|
|
get '/:controller/:action/:id'
|
|
end
|
|
|
|
assert_equal 1, set.routes.size
|
|
|
|
assert_equal '/users/show/10', url_for(set, { :controller => 'users', :action => 'show', :id => 10 })
|
|
assert_equal '/users/index/10', url_for(set, { :controller => 'users', :id => 10 })
|
|
|
|
assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
|
|
assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
|
|
end
|
|
|
|
def test_route_with_parameter_shell
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /\d+/
|
|
get '/:controller(/:action(/:id))'
|
|
end
|
|
|
|
assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
|
|
assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
|
|
assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
|
|
|
|
assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
|
|
assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
|
|
end
|
|
|
|
def test_route_constraints_on_request_object_with_anchors_are_valid
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :constraints => { :host => /^foo$/ }
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_constraints_with_anchor_chars_are_invalid
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /^\d+/
|
|
end
|
|
end
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /\A\d+/
|
|
end
|
|
end
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /\d+$/
|
|
end
|
|
end
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /\d+\Z/
|
|
end
|
|
end
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /\d+\z/
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_constraints_with_options_method_condition_is_valid
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
match 'valid/route' => 'pages#show', :via => :options
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_error_with_missing_controller
|
|
set.draw do
|
|
get "/people" => "missing#index"
|
|
end
|
|
|
|
assert_raise(ActionController::RoutingError) {
|
|
set.recognize_path("/people", :method => :get)
|
|
}
|
|
end
|
|
|
|
def test_recognize_with_encoded_id_and_regex
|
|
set.draw do
|
|
get 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/
|
|
end
|
|
|
|
assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
|
|
assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
|
|
end
|
|
|
|
def test_recognize_with_http_methods
|
|
set.draw do
|
|
get "/people" => "people#index", :as => "people"
|
|
post "/people" => "people#create"
|
|
get "/people/:id" => "people#show", :as => "person"
|
|
put "/people/:id" => "people#update"
|
|
patch "/people/:id" => "people#update"
|
|
delete "/people/:id" => "people#destroy"
|
|
end
|
|
|
|
params = set.recognize_path("/people", :method => :get)
|
|
assert_equal("index", params[:action])
|
|
|
|
params = set.recognize_path("/people", :method => :post)
|
|
assert_equal("create", params[:action])
|
|
|
|
params = set.recognize_path("/people/5", :method => :put)
|
|
assert_equal("update", params[:action])
|
|
|
|
params = set.recognize_path("/people/5", :method => :patch)
|
|
assert_equal("update", params[:action])
|
|
|
|
assert_raise(ActionController::UnknownHttpMethod) {
|
|
set.recognize_path("/people", :method => :bacon)
|
|
}
|
|
|
|
params = set.recognize_path("/people/5", :method => :get)
|
|
assert_equal("show", params[:action])
|
|
assert_equal("5", params[:id])
|
|
|
|
params = set.recognize_path("/people/5", :method => :put)
|
|
assert_equal("update", params[:action])
|
|
assert_equal("5", params[:id])
|
|
|
|
params = set.recognize_path("/people/5", :method => :patch)
|
|
assert_equal("update", params[:action])
|
|
assert_equal("5", params[:id])
|
|
|
|
params = set.recognize_path("/people/5", :method => :delete)
|
|
assert_equal("destroy", params[:action])
|
|
assert_equal("5", params[:id])
|
|
|
|
assert_raise(ActionController::RoutingError) {
|
|
set.recognize_path("/people/5", :method => :post)
|
|
}
|
|
end
|
|
|
|
def test_recognize_with_alias_in_conditions
|
|
set.draw do
|
|
match "/people" => 'people#index', :as => 'people', :via => :get
|
|
root :to => "people#index"
|
|
end
|
|
|
|
params = set.recognize_path("/people", :method => :get)
|
|
assert_equal("people", params[:controller])
|
|
assert_equal("index", params[:action])
|
|
|
|
params = set.recognize_path("/", :method => :get)
|
|
assert_equal("people", params[:controller])
|
|
assert_equal("index", params[:action])
|
|
end
|
|
|
|
def test_typo_recognition
|
|
set.draw do
|
|
get 'articles/:year/:month/:day/:title' => 'articles#permalink',
|
|
:year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
|
|
end
|
|
|
|
params = set.recognize_path("/articles/2005/11/05/a-very-interesting-article", :method => :get)
|
|
assert_equal("permalink", params[:action])
|
|
assert_equal("2005", params[:year])
|
|
assert_equal("11", params[:month])
|
|
assert_equal("05", params[:day])
|
|
assert_equal("a-very-interesting-article", params[:title])
|
|
end
|
|
|
|
def test_routing_traversal_does_not_load_extra_classes
|
|
assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
|
|
set.draw do
|
|
get '/profile' => 'profile#index'
|
|
end
|
|
|
|
set.recognize_path("/profile") rescue nil
|
|
|
|
assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
|
|
end
|
|
|
|
def test_recognize_with_conditions_and_format
|
|
set.draw do
|
|
get "people/:id" => "people#show", :as => "person"
|
|
put "people/:id" => "people#update"
|
|
patch "people/:id" => "people#update"
|
|
get "people/:id(.:format)" => "people#show"
|
|
end
|
|
|
|
params = set.recognize_path("/people/5", :method => :get)
|
|
assert_equal("show", params[:action])
|
|
assert_equal("5", params[:id])
|
|
|
|
params = set.recognize_path("/people/5", :method => :put)
|
|
assert_equal("update", params[:action])
|
|
|
|
params = set.recognize_path("/people/5", :method => :patch)
|
|
assert_equal("update", params[:action])
|
|
|
|
params = set.recognize_path("/people/5.png", :method => :get)
|
|
assert_equal("show", params[:action])
|
|
assert_equal("5", params[:id])
|
|
assert_equal("png", params[:format])
|
|
end
|
|
|
|
def test_generate_with_default_action
|
|
set.draw do
|
|
get "/people", :controller => "people", :action => "index"
|
|
get "/people/list", :controller => "people", :action => "list"
|
|
end
|
|
|
|
url = url_for(set, { :controller => "people", :action => "list" })
|
|
assert_equal "/people/list", url
|
|
end
|
|
|
|
def test_root_map
|
|
set.draw { root :to => 'people#index' }
|
|
|
|
params = set.recognize_path("", :method => :get)
|
|
assert_equal("people", params[:controller])
|
|
assert_equal("index", params[:action])
|
|
end
|
|
|
|
def test_namespace
|
|
set.draw do
|
|
|
|
namespace 'api' do
|
|
get 'inventory' => 'products#inventory'
|
|
end
|
|
|
|
end
|
|
|
|
params = set.recognize_path("/api/inventory", :method => :get)
|
|
assert_equal("api/products", params[:controller])
|
|
assert_equal("inventory", params[:action])
|
|
end
|
|
|
|
def test_namespaced_root_map
|
|
set.draw do
|
|
namespace 'api' do
|
|
root :to => 'products#index'
|
|
end
|
|
end
|
|
|
|
params = set.recognize_path("/api", :method => :get)
|
|
assert_equal("api/products", params[:controller])
|
|
assert_equal("index", params[:action])
|
|
end
|
|
|
|
def test_namespace_with_path_prefix
|
|
set.draw do
|
|
scope :module => "api", :path => "prefix" do
|
|
get 'inventory' => 'products#inventory'
|
|
end
|
|
end
|
|
|
|
params = set.recognize_path("/prefix/inventory", :method => :get)
|
|
assert_equal("api/products", params[:controller])
|
|
assert_equal("inventory", params[:action])
|
|
end
|
|
|
|
def test_namespace_with_blank_path_prefix
|
|
set.draw do
|
|
scope :module => "api", :path => "" do
|
|
get 'inventory' => 'products#inventory'
|
|
end
|
|
end
|
|
|
|
params = set.recognize_path("/inventory", :method => :get)
|
|
assert_equal("api/products", params[:controller])
|
|
assert_equal("inventory", params[:action])
|
|
end
|
|
|
|
def test_generate_changes_controller_module
|
|
set.draw { get ':controller/:action/:id' }
|
|
current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
|
|
|
|
assert_equal "/foo/bar/baz/7",
|
|
url_for(set, { :controller => "foo/bar", :action => "baz", :id => 7 }, current)
|
|
end
|
|
|
|
def test_id_is_sticky_when_it_ought_to_be
|
|
set.draw do
|
|
get ':controller/:id/:action'
|
|
end
|
|
|
|
url = url_for(set, { :action => "destroy" }, { :controller => "people", :action => "show", :id => "7" })
|
|
assert_equal "/people/7/destroy", url
|
|
end
|
|
|
|
def test_use_static_path_when_possible
|
|
set.draw do
|
|
get 'about' => "welcome#about"
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
url = url_for(set, { :controller => "welcome", :action => "about" },
|
|
{ :controller => "welcome", :action => "get", :id => "7" })
|
|
|
|
assert_equal "/about", url
|
|
end
|
|
|
|
def test_generate
|
|
set.draw { get ':controller/:action/:id' }
|
|
|
|
args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
|
|
assert_equal "/foo/bar/7?x=y", url_for(set, args)
|
|
assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
|
|
assert_equal [:x], set.extra_keys(args)
|
|
end
|
|
|
|
def test_generate_with_path_prefix
|
|
set.draw do
|
|
scope "my" do
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
end
|
|
|
|
args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
|
|
assert_equal "/my/foo/bar/7?x=y", url_for(set, args)
|
|
end
|
|
|
|
def test_generate_with_blank_path_prefix
|
|
set.draw do
|
|
scope "" do
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
end
|
|
|
|
args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
|
|
assert_equal "/foo/bar/7?x=y", url_for(set, args)
|
|
end
|
|
|
|
def test_named_routes_are_never_relative_to_modules
|
|
set.draw do
|
|
get "/connection/manage(/:action)" => 'connection/manage#index'
|
|
get "/connection/connection" => "connection/connection#index"
|
|
get '/connection' => 'connection#index', :as => 'family_connection'
|
|
end
|
|
|
|
url = url_for(set, { :controller => "connection" }, { :controller => 'connection/manage' })
|
|
assert_equal "/connection/connection", url
|
|
|
|
url = url_for(set, { :use_route => :family_connection, :controller => "connection" }, { :controller => 'connection/manage' })
|
|
assert_equal "/connection", url
|
|
end
|
|
|
|
def test_action_left_off_when_id_is_recalled
|
|
set.draw do
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
assert_equal '/books', url_for(set,
|
|
{:controller => 'books', :action => 'index'},
|
|
{:controller => 'books', :action => 'show', :id => '10'}
|
|
)
|
|
end
|
|
|
|
def test_query_params_will_be_shown_when_recalled
|
|
set.draw do
|
|
get 'show_weblog/:parameter' => 'weblog#show'
|
|
get ':controller(/:action(/:id))'
|
|
end
|
|
assert_equal '/weblog/edit?parameter=1', url_for(set,
|
|
{:action => 'edit', :parameter => 1},
|
|
{:controller => 'weblog', :action => 'show', :parameter => 1}
|
|
)
|
|
end
|
|
|
|
def test_format_is_not_inherit
|
|
set.draw do
|
|
get '/posts(.:format)' => 'posts#index'
|
|
end
|
|
|
|
assert_equal '/posts', url_for(set,
|
|
{:controller => 'posts'},
|
|
{:controller => 'posts', :action => 'index', :format => 'xml'}
|
|
)
|
|
|
|
assert_equal '/posts.xml', url_for(set,
|
|
{:controller => 'posts', :format => 'xml'},
|
|
{:controller => 'posts', :action => 'index', :format => 'xml'}
|
|
)
|
|
end
|
|
|
|
def test_expiry_determination_should_consider_values_with_to_param
|
|
set.draw { get 'projects/:project_id/:controller/:action' }
|
|
assert_equal '/projects/1/weblog/show', url_for(set,
|
|
{ :action => 'show', :project_id => 1 },
|
|
{ :controller => 'weblog', :action => 'show', :project_id => '1' })
|
|
end
|
|
|
|
def test_named_route_in_nested_resource
|
|
set.draw do
|
|
resources :projects do
|
|
member do
|
|
get 'milestones' => 'milestones#index', :as => 'milestones'
|
|
end
|
|
end
|
|
end
|
|
|
|
params = set.recognize_path("/projects/1/milestones", :method => :get)
|
|
assert_equal("milestones", params[:controller])
|
|
assert_equal("index", params[:action])
|
|
end
|
|
|
|
def test_setting_root_in_namespace_using_symbol
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
namespace :admin do
|
|
root :to => "home#index"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_setting_root_in_namespace_using_string
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
namespace 'admin' do
|
|
root :to => "home#index"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_constraints_with_unsupported_regexp_options_must_error
|
|
assert_raise ArgumentError do
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => { :name => /(david|jamis)/m }
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_constraints_with_supported_options_must_not_error
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => { :name => /(david|jamis)/i }
|
|
end
|
|
end
|
|
assert_nothing_raised do
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => { :name => / # Desperately overcommented regexp
|
|
( #Either
|
|
david #The Creator
|
|
| #Or
|
|
jamis #The Deployer
|
|
)/x }
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_route_with_subdomain_and_constraints_must_receive_params
|
|
name_param = nil
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show', :constraints => lambda {|request|
|
|
name_param = request.params[:name]
|
|
return true
|
|
}
|
|
end
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'mypage'},
|
|
set.recognize_path('http://subdomain.example.org/page/mypage'))
|
|
assert_equal(name_param, 'mypage')
|
|
end
|
|
|
|
def test_route_requirement_recognize_with_ignore_case
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => {:name => /(david|jamis)/i}
|
|
end
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
|
|
assert_raise ActionController::RoutingError do
|
|
set.recognize_path('/page/davidjamis')
|
|
end
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID'))
|
|
end
|
|
|
|
def test_route_requirement_generate_with_ignore_case
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => {:name => /(david|jamis)/i}
|
|
end
|
|
|
|
url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'david' })
|
|
assert_equal "/page/david", url
|
|
assert_raise(ActionController::UrlGenerationError) do
|
|
url_for(set, { :controller => 'pages', :action => 'show', :name => 'davidjamis' })
|
|
end
|
|
url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'JAMIS' })
|
|
assert_equal "/page/JAMIS", url
|
|
end
|
|
|
|
def test_route_requirement_recognize_with_extended_syntax
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => {:name => / # Desperately overcommented regexp
|
|
( #Either
|
|
david #The Creator
|
|
| #Or
|
|
jamis #The Deployer
|
|
)/x}
|
|
end
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david'))
|
|
assert_raise ActionController::RoutingError do
|
|
set.recognize_path('/page/david #The Creator')
|
|
end
|
|
assert_raise ActionController::RoutingError do
|
|
set.recognize_path('/page/David')
|
|
end
|
|
end
|
|
|
|
def test_route_requirement_with_xi_modifiers
|
|
set.draw do
|
|
get 'page/:name' => 'pages#show',
|
|
:constraints => {:name => / # Desperately overcommented regexp
|
|
( #Either
|
|
david #The Creator
|
|
| #Or
|
|
jamis #The Deployer
|
|
)/xi}
|
|
end
|
|
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'},
|
|
set.recognize_path('/page/JAMIS'))
|
|
|
|
assert_equal "/page/JAMIS",
|
|
url_for(set, { :controller => 'pages', :action => 'show', :name => 'JAMIS' })
|
|
end
|
|
|
|
def test_routes_with_symbols
|
|
set.draw do
|
|
get 'unnamed', :controller => :pages, :action => :show, :name => :as_symbol
|
|
get 'named' , :controller => :pages, :action => :show, :name => :as_symbol, :as => :named
|
|
end
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/unnamed'))
|
|
assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named'))
|
|
end
|
|
|
|
def test_regexp_chunk_should_add_question_mark_for_optionals
|
|
set.draw do
|
|
get '/' => 'foo#index'
|
|
get '/hello' => 'bar#index'
|
|
end
|
|
|
|
assert_equal '/', url_for(set, { :controller => 'foo' })
|
|
assert_equal '/hello', url_for(set, { :controller => 'bar' })
|
|
|
|
assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/'))
|
|
assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello'))
|
|
end
|
|
|
|
def test_assign_route_options_with_anchor_chars
|
|
set.draw do
|
|
get '/cars/:action/:person/:car/', :controller => 'cars'
|
|
end
|
|
|
|
assert_equal '/cars/buy/1/2', url_for(set, { :controller => 'cars', :action => 'buy', :person => '1', :car => '2' })
|
|
|
|
assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2'))
|
|
end
|
|
|
|
def test_segmentation_of_dot_path
|
|
set.draw do
|
|
get '/books/:action.rss', :controller => 'books'
|
|
end
|
|
|
|
assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list' })
|
|
|
|
assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss'))
|
|
end
|
|
|
|
def test_segmentation_of_dynamic_dot_path
|
|
set.draw do
|
|
get '/books(/:action(.:format))', :controller => 'books'
|
|
end
|
|
|
|
assert_equal '/books/list.rss', url_for(set, { :controller => 'books', :action => 'list', :format => 'rss' })
|
|
assert_equal '/books/list.xml', url_for(set, { :controller => 'books', :action => 'list', :format => 'xml' })
|
|
assert_equal '/books/list', url_for(set, { :controller => 'books', :action => 'list' })
|
|
assert_equal '/books', url_for(set, { :controller => 'books', :action => 'index' })
|
|
|
|
assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss'))
|
|
assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml'))
|
|
assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list'))
|
|
assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books'))
|
|
end
|
|
|
|
def test_slashes_are_implied
|
|
@set = nil
|
|
set.draw { get("/:controller(/:action(/:id))") }
|
|
|
|
assert_equal '/content', url_for(set, { :controller => 'content', :action => 'index' })
|
|
assert_equal '/content/list', url_for(set, { :controller => 'content', :action => 'list' })
|
|
assert_equal '/content/show/1', url_for(set, { :controller => 'content', :action => 'show', :id => '1' })
|
|
|
|
assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content'))
|
|
assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content/index'))
|
|
assert_equal({:controller => "content", :action => "list"}, set.recognize_path('/content/list'))
|
|
assert_equal({:controller => "content", :action => "show", :id => "1"}, set.recognize_path('/content/show/1'))
|
|
end
|
|
|
|
def test_default_route_recognition
|
|
expected = {:controller => 'pages', :action => 'show', :id => '10'}
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/10')
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/10/')
|
|
|
|
expected[:id] = 'jamis'
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/jamis/')
|
|
|
|
expected.delete :id
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show')
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/')
|
|
|
|
expected[:action] = 'index'
|
|
assert_equal expected, default_route_set.recognize_path('/pages/')
|
|
assert_equal expected, default_route_set.recognize_path('/pages')
|
|
|
|
assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/') }
|
|
assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/pages/how/goood/it/is/to/be/free') }
|
|
end
|
|
|
|
def test_default_route_should_omit_default_action
|
|
assert_equal '/accounts', url_for(default_route_set, { :controller => 'accounts', :action => 'index' })
|
|
end
|
|
|
|
def test_default_route_should_include_default_action_when_id_present
|
|
assert_equal '/accounts/index/20', url_for(default_route_set, { :controller => 'accounts', :action => 'index', :id => '20' })
|
|
end
|
|
|
|
def test_default_route_should_work_with_action_but_no_id
|
|
assert_equal '/accounts/list_all', url_for(default_route_set, { :controller => 'accounts', :action => 'list_all' })
|
|
end
|
|
|
|
def test_default_route_should_uri_escape_pluses
|
|
expected = { :controller => 'pages', :action => 'show', :id => 'hello world' }
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/hello%20world')
|
|
assert_equal '/pages/show/hello%20world', url_for(default_route_set, expected)
|
|
|
|
expected[:id] = 'hello+world'
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/hello+world')
|
|
assert_equal expected, default_route_set.recognize_path('/pages/show/hello%2Bworld')
|
|
assert_equal '/pages/show/hello+world', url_for(default_route_set, expected)
|
|
end
|
|
|
|
def test_build_empty_query_string
|
|
assert_uri_equal '/foo', url_for(default_route_set, { :controller => 'foo' })
|
|
end
|
|
|
|
def test_build_query_string_with_nil_value
|
|
assert_uri_equal '/foo', url_for(default_route_set, { :controller => 'foo', :x => nil })
|
|
end
|
|
|
|
def test_simple_build_query_string
|
|
assert_uri_equal '/foo?x=1&y=2', url_for(default_route_set, { :controller => 'foo', :x => '1', :y => '2' })
|
|
end
|
|
|
|
def test_convert_ints_build_query_string
|
|
assert_uri_equal '/foo?x=1&y=2', url_for(default_route_set, { :controller => 'foo', :x => 1, :y => 2 })
|
|
end
|
|
|
|
def test_escape_spaces_build_query_string
|
|
assert_uri_equal '/foo?x=hello+world&y=goodbye+world', url_for(default_route_set, { :controller => 'foo', :x => 'hello world', :y => 'goodbye world' })
|
|
end
|
|
|
|
def test_expand_array_build_query_string
|
|
assert_uri_equal '/foo?x%5B%5D=1&x%5B%5D=2', url_for(default_route_set, { :controller => 'foo', :x => [1, 2] })
|
|
end
|
|
|
|
def test_escape_spaces_build_query_string_selected_keys
|
|
assert_uri_equal '/foo?x=hello+world', url_for(default_route_set, { :controller => 'foo', :x => 'hello world' })
|
|
end
|
|
|
|
def test_generate_with_default_params
|
|
set.draw do
|
|
get 'dummy/page/:page' => 'dummy#show'
|
|
get 'dummy/dots/page.:page' => 'dummy#dots'
|
|
get 'ibocorp(/:page)' => 'ibocorp#show',
|
|
:constraints => { :page => /\d+/ },
|
|
:defaults => { :page => 1 }
|
|
|
|
get ':controller/:action/:id'
|
|
end
|
|
|
|
assert_equal '/ibocorp', url_for(set, { :controller => 'ibocorp', :action => "show", :page => 1 })
|
|
end
|
|
|
|
def test_generate_with_optional_params_recalls_last_request
|
|
set.draw do
|
|
get "blog/", :controller => "blog", :action => "index"
|
|
|
|
get "blog(/:year(/:month(/:day)))",
|
|
:controller => "blog",
|
|
:action => "show_date",
|
|
:constraints => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/ },
|
|
:day => nil, :month => nil
|
|
|
|
get "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/
|
|
get "blog/:controller/:action(/:id)"
|
|
get "*anything", :controller => "blog", :action => "unknown_request"
|
|
end
|
|
|
|
assert_equal({:controller => "blog", :action => "index"}, set.recognize_path("/blog"))
|
|
assert_equal({:controller => "blog", :action => "show", :id => "123"}, set.recognize_path("/blog/show/123"))
|
|
assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :day => nil, :month => nil }, set.recognize_path("/blog/2004"))
|
|
assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => nil }, set.recognize_path("/blog/2004/12"))
|
|
assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => "25"}, set.recognize_path("/blog/2004/12/25"))
|
|
assert_equal({:controller => "articles", :action => "edit", :id => "123"}, set.recognize_path("/blog/articles/edit/123"))
|
|
assert_equal({:controller => "articles", :action => "show_stats"}, set.recognize_path("/blog/articles/show_stats"))
|
|
assert_equal({:controller => "blog", :action => "unknown_request", :anything => "blog/wibble"}, set.recognize_path("/blog/wibble"))
|
|
assert_equal({:controller => "blog", :action => "unknown_request", :anything => "junk"}, set.recognize_path("/junk"))
|
|
|
|
last_request = set.recognize_path("/blog/2006/07/28").freeze
|
|
assert_equal({:controller => "blog", :action => "show_date", :year => "2006", :month => "07", :day => "28"}, last_request)
|
|
assert_equal("/blog/2006/07/25", url_for(set, { :day => 25 }, last_request))
|
|
assert_equal("/blog/2005", url_for(set, { :year => 2005 }, last_request))
|
|
assert_equal("/blog/show/123", url_for(set, { :action => "show" , :id => 123 }, last_request))
|
|
assert_equal("/blog/2006", url_for(set, { :year => 2006 }, last_request))
|
|
assert_equal("/blog/2006", url_for(set, { :year => 2006, :month => nil }, last_request))
|
|
end
|
|
|
|
private
|
|
def assert_uri_equal(expected, actual)
|
|
assert_equal(sort_query_string_params(expected), sort_query_string_params(actual))
|
|
end
|
|
|
|
def sort_query_string_params(uri)
|
|
path, qs = uri.split('?')
|
|
qs = qs.split('&').sort.join('&') if qs
|
|
qs ? "#{path}?#{qs}" : path
|
|
end
|
|
end
|
|
|
|
class RackMountIntegrationTests < ActiveSupport::TestCase
|
|
include RoutingTestHelpers
|
|
|
|
Model = Struct.new(:to_param)
|
|
|
|
Mapping = lambda {
|
|
namespace :admin do
|
|
resources :users, :posts
|
|
end
|
|
|
|
namespace 'api' do
|
|
root :to => 'users#index'
|
|
end
|
|
|
|
get '/blog(/:year(/:month(/:day)))' => 'posts#show_date',
|
|
:constraints => {
|
|
:year => /(19|20)\d\d/,
|
|
:month => /[01]?\d/,
|
|
:day => /[0-3]?\d/
|
|
},
|
|
:day => nil,
|
|
:month => nil
|
|
|
|
get 'archive/:year', :controller => 'archive', :action => 'index',
|
|
:defaults => { :year => nil },
|
|
:constraints => { :year => /\d{4}/ },
|
|
:as => "blog"
|
|
|
|
resources :people
|
|
get 'legacy/people' => "people#index", :legacy => "true"
|
|
|
|
get 'symbols', :controller => :symbols, :action => :show, :name => :as_symbol
|
|
get 'id_default(/:id)' => "foo#id_default", :id => 1
|
|
match 'get_or_post' => "foo#get_or_post", :via => [:get, :post]
|
|
get 'optional/:optional' => "posts#index"
|
|
get 'projects/:project_id' => "project#index", :as => "project"
|
|
get 'clients' => "projects#index"
|
|
|
|
get 'ignorecase/geocode/:postalcode' => 'geocode#show', :postalcode => /hx\d\d-\d[a-z]{2}/i
|
|
get 'extended/geocode/:postalcode' => 'geocode#show',:constraints => {
|
|
:postalcode => /# Postcode format
|
|
\d{5} #Prefix
|
|
(-\d{4})? #Suffix
|
|
/x
|
|
}, :as => "geocode"
|
|
|
|
get 'news(.:format)' => "news#index"
|
|
|
|
get 'comment/:id(/:action)' => "comments#show"
|
|
get 'ws/:controller(/:action(/:id))', :ws => true
|
|
get 'account(/:action)' => "account#subscription"
|
|
get 'pages/:page_id/:controller(/:action(/:id))'
|
|
get ':controller/ping', :action => 'ping'
|
|
get 'こんにちは/世界', :controller => 'news', :action => 'index'
|
|
match ':controller(/:action(/:id))(.:format)', :via => :all
|
|
root :to => "news#index"
|
|
}
|
|
|
|
def setup
|
|
@routes = ActionDispatch::Routing::RouteSet.new
|
|
@routes.draw(&Mapping)
|
|
end
|
|
|
|
def test_recognize_path
|
|
assert_equal({:controller => 'admin/users', :action => 'index'}, @routes.recognize_path('/admin/users', :method => :get))
|
|
assert_equal({:controller => 'admin/users', :action => 'create'}, @routes.recognize_path('/admin/users', :method => :post))
|
|
assert_equal({:controller => 'admin/users', :action => 'new'}, @routes.recognize_path('/admin/users/new', :method => :get))
|
|
assert_equal({:controller => 'admin/users', :action => 'show', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :get))
|
|
assert_equal({:controller => 'admin/users', :action => 'update', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :put))
|
|
assert_equal({:controller => 'admin/users', :action => 'destroy', :id => '1'}, @routes.recognize_path('/admin/users/1', :method => :delete))
|
|
assert_equal({:controller => 'admin/users', :action => 'edit', :id => '1'}, @routes.recognize_path('/admin/users/1/edit', :method => :get))
|
|
|
|
assert_equal({:controller => 'admin/posts', :action => 'index'}, @routes.recognize_path('/admin/posts', :method => :get))
|
|
assert_equal({:controller => 'admin/posts', :action => 'new'}, @routes.recognize_path('/admin/posts/new', :method => :get))
|
|
|
|
assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api', :method => :get))
|
|
assert_equal({:controller => 'api/users', :action => 'index'}, @routes.recognize_path('/api/', :method => :get))
|
|
|
|
assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => nil, :day => nil }, @routes.recognize_path('/blog/2009', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => nil }, @routes.recognize_path('/blog/2009/01', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => '01'}, @routes.recognize_path('/blog/2009/01/01', :method => :get))
|
|
|
|
assert_equal({:controller => 'archive', :action => 'index', :year => '2010'}, @routes.recognize_path('/archive/2010'))
|
|
assert_equal({:controller => 'archive', :action => 'index'}, @routes.recognize_path('/archive'))
|
|
|
|
assert_equal({:controller => 'people', :action => 'index'}, @routes.recognize_path('/people', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'index', :format => 'xml'}, @routes.recognize_path('/people.xml', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'create'}, @routes.recognize_path('/people', :method => :post))
|
|
assert_equal({:controller => 'people', :action => 'new'}, @routes.recognize_path('/people/new', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'show', :id => '1'}, @routes.recognize_path('/people/1', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'show', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1.xml', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'update', :id => '1'}, @routes.recognize_path('/people/1', :method => :put))
|
|
assert_equal({:controller => 'people', :action => 'destroy', :id => '1'}, @routes.recognize_path('/people/1', :method => :delete))
|
|
assert_equal({:controller => 'people', :action => 'edit', :id => '1'}, @routes.recognize_path('/people/1/edit', :method => :get))
|
|
assert_equal({:controller => 'people', :action => 'edit', :id => '1', :format => 'xml'}, @routes.recognize_path('/people/1/edit.xml', :method => :get))
|
|
|
|
assert_equal({:controller => 'symbols', :action => 'show', :name => :as_symbol}, @routes.recognize_path('/symbols'))
|
|
assert_equal({:controller => 'foo', :action => 'id_default', :id => '1'}, @routes.recognize_path('/id_default/1'))
|
|
assert_equal({:controller => 'foo', :action => 'id_default', :id => '2'}, @routes.recognize_path('/id_default/2'))
|
|
assert_equal({:controller => 'foo', :action => 'id_default', :id => 1 }, @routes.recognize_path('/id_default'))
|
|
assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :get))
|
|
assert_equal({:controller => 'foo', :action => 'get_or_post'}, @routes.recognize_path('/get_or_post', :method => :post))
|
|
assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/get_or_post', :method => :put) }
|
|
assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/get_or_post', :method => :delete) }
|
|
|
|
assert_equal({:controller => 'posts', :action => 'index', :optional => 'bar'}, @routes.recognize_path('/optional/bar'))
|
|
assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/optional') }
|
|
|
|
assert_equal({:controller => 'posts', :action => 'show', :id => '1', :ws => true}, @routes.recognize_path('/ws/posts/show/1', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'list', :ws => true}, @routes.recognize_path('/ws/posts/list', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'index', :ws => true}, @routes.recognize_path('/ws/posts', :method => :get))
|
|
|
|
assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account', :method => :get))
|
|
assert_equal({:controller => 'account', :action => 'subscription'}, @routes.recognize_path('/account/subscription', :method => :get))
|
|
assert_equal({:controller => 'account', :action => 'billing'}, @routes.recognize_path('/account/billing', :method => :get))
|
|
|
|
assert_equal({:page_id => '1', :controller => 'notes', :action => 'index'}, @routes.recognize_path('/pages/1/notes', :method => :get))
|
|
assert_equal({:page_id => '1', :controller => 'notes', :action => 'list'}, @routes.recognize_path('/pages/1/notes/list', :method => :get))
|
|
assert_equal({:page_id => '1', :controller => 'notes', :action => 'show', :id => '2'}, @routes.recognize_path('/pages/1/notes/show/2', :method => :get))
|
|
|
|
assert_equal({:controller => 'posts', :action => 'ping'}, @routes.recognize_path('/posts/ping', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'index'}, @routes.recognize_path('/posts/index', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'show'}, @routes.recognize_path('/posts/show', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'show', :id => '1'}, @routes.recognize_path('/posts/show/1', :method => :get))
|
|
assert_equal({:controller => 'posts', :action => 'create'}, @routes.recognize_path('/posts/create', :method => :post))
|
|
|
|
assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1az'}, @routes.recognize_path('/ignorecase/geocode/hx12-1az'))
|
|
assert_equal({:controller => 'geocode', :action => 'show', :postalcode => 'hx12-1AZ'}, @routes.recognize_path('/ignorecase/geocode/hx12-1AZ'))
|
|
assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345-1234'}, @routes.recognize_path('/extended/geocode/12345-1234'))
|
|
assert_equal({:controller => 'geocode', :action => 'show', :postalcode => '12345'}, @routes.recognize_path('/extended/geocode/12345'))
|
|
|
|
assert_equal({:controller => 'news', :action => 'index' }, @routes.recognize_path('/', :method => :get))
|
|
assert_equal({:controller => 'news', :action => 'index', :format => 'rss'}, @routes.recognize_path('/news.rss', :method => :get))
|
|
|
|
assert_raise(ActionController::RoutingError) { @routes.recognize_path('/none', :method => :get) }
|
|
end
|
|
|
|
def test_generate_extras
|
|
assert_equal ['/people', []], @routes.generate_extras(:controller => 'people')
|
|
assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :foo => 'bar')
|
|
assert_equal ['/people', []], @routes.generate_extras(:controller => 'people', :action => 'index')
|
|
assert_equal ['/people', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'index', :foo => 'bar')
|
|
assert_equal ['/people/new', []], @routes.generate_extras(:controller => 'people', :action => 'new')
|
|
assert_equal ['/people/new', [:foo]], @routes.generate_extras(:controller => 'people', :action => 'new', :foo => 'bar')
|
|
assert_equal ['/people/1', []], @routes.generate_extras(:controller => 'people', :action => 'show', :id => '1')
|
|
assert_equal ['/people/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'people', :action => 'show', :id => '1', :foo => '2', :bar => '3'))
|
|
assert_equal ['/people', [:person]], @routes.generate_extras(:controller => 'people', :action => 'create', :person => { :first_name => 'Josh', :last_name => 'Peek' })
|
|
assert_equal ['/people', [:people]], @routes.generate_extras(:controller => 'people', :action => 'create', :people => ['Josh', 'Dave'])
|
|
|
|
assert_equal ['/posts/show/1', []], @routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1')
|
|
assert_equal ['/posts/show/1', [:bar, :foo]], sort_extras!(@routes.generate_extras(:controller => 'posts', :action => 'show', :id => '1', :foo => '2', :bar => '3'))
|
|
assert_equal ['/posts', []], @routes.generate_extras(:controller => 'posts', :action => 'index')
|
|
assert_equal ['/posts', [:foo]], @routes.generate_extras(:controller => 'posts', :action => 'index', :foo => 'bar')
|
|
end
|
|
|
|
def test_extras
|
|
params = {:controller => 'people'}
|
|
assert_equal [], @routes.extra_keys(params)
|
|
assert_equal({:controller => 'people'}, params)
|
|
|
|
params = {:controller => 'people', :foo => 'bar'}
|
|
assert_equal [:foo], @routes.extra_keys(params)
|
|
assert_equal({:controller => 'people', :foo => 'bar'}, params)
|
|
|
|
params = {:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}
|
|
assert_equal [:person], @routes.extra_keys(params)
|
|
assert_equal({:controller => 'people', :action => 'create', :person => { :name => 'Josh'}}, params)
|
|
end
|
|
|
|
def test_unicode_path
|
|
assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界'), :method => :get))
|
|
end
|
|
|
|
private
|
|
def sort_extras!(extras)
|
|
if extras.length == 2
|
|
extras[1].sort! { |a, b| a.to_s <=> b.to_s }
|
|
end
|
|
extras
|
|
end
|
|
|
|
def assert_raise(e)
|
|
result = yield
|
|
flunk "Did not raise #{e}, but returned #{result.inspect}"
|
|
rescue e
|
|
assert true
|
|
end
|
|
end
|