PageRenderTime 54ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/actionpack/test/controller/routing_test.rb

https://bitbucket.org/druly/rails_cherry_pick
Ruby | 1906 lines | 1552 code | 345 blank | 9 comment | 8 complexity | 7723e6107c3d0684105e8b9fa2740c69 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. # encoding: utf-8
  2. require 'abstract_unit'
  3. require 'controller/fake_controllers'
  4. require 'active_support/core_ext/object/with_options'
  5. class MilestonesController < ActionController::Base
  6. def index() head :ok end
  7. alias_method :show, :index
  8. def rescue_action(e) raise e end
  9. end
  10. ROUTING = ActionDispatch::Routing
  11. # See RFC 3986, section 3.3 for allowed path characters.
  12. class UriReservedCharactersRoutingTest < Test::Unit::TestCase
  13. include RoutingTestHelpers
  14. def setup
  15. @set = ActionDispatch::Routing::RouteSet.new
  16. @set.draw do
  17. match ':controller/:action/:variable/*additional'
  18. end
  19. safe, unsafe = %w(: @ & = + $ , ;), %w(^ ? # [ ])
  20. hex = unsafe.map { |char| '%' + char.unpack('H2').first.upcase }
  21. @segment = "#{safe.join}#{unsafe.join}".freeze
  22. @escaped = "#{safe.join}#{hex.join}".freeze
  23. end
  24. def test_route_generation_escapes_unsafe_path_characters
  25. assert_equal "/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2",
  26. url_for(@set, {
  27. :controller => "content",
  28. :action => "act#{@segment}ion",
  29. :variable => "var#{@segment}iable",
  30. :additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"]
  31. })
  32. end
  33. def test_route_recognition_unescapes_path_components
  34. options = { :controller => "content",
  35. :action => "act#{@segment}ion",
  36. :variable => "var#{@segment}iable",
  37. :additional => "add#{@segment}itional-1/add#{@segment}itional-2" }
  38. assert_equal options, @set.recognize_path("/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2")
  39. end
  40. def test_route_generation_allows_passing_non_string_values_to_generated_helper
  41. assert_equal "/content/action/variable/1/2",
  42. url_for(@set, {
  43. :controller => "content",
  44. :action => "action",
  45. :variable => "variable",
  46. :additional => [1, 2]
  47. })
  48. end
  49. end
  50. class MockController
  51. def self.build(helpers)
  52. Class.new do
  53. def url_for(options)
  54. options[:protocol] ||= "http"
  55. options[:host] ||= "test.host"
  56. super(options)
  57. end
  58. include helpers
  59. end
  60. end
  61. end
  62. class LegacyRouteSetTests < Test::Unit::TestCase
  63. include RoutingTestHelpers
  64. attr_reader :rs
  65. def setup
  66. @rs = ::ActionDispatch::Routing::RouteSet.new
  67. @response = nil
  68. end
  69. def get(uri_or_host, path = nil, port = nil)
  70. host = uri_or_host.host unless path
  71. path ||= uri_or_host.path
  72. params = {'PATH_INFO' => path,
  73. 'REQUEST_METHOD' => 'GET',
  74. 'HTTP_HOST' => host}
  75. @rs.call(params)[2].join
  76. end
  77. def test_symbols_with_dashes
  78. rs.draw do
  79. match '/:artist/:song-omg', :to => lambda { |env|
  80. resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  81. [200, {}, [resp]]
  82. }
  83. end
  84. hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
  85. assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
  86. end
  87. def test_id_with_dash
  88. rs.draw do
  89. match '/journey/:id', :to => lambda { |env|
  90. resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  91. [200, {}, [resp]]
  92. }
  93. end
  94. hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
  95. assert_equal({"id"=>"faithfully-omg"}, hash)
  96. end
  97. def test_dash_with_custom_regexp
  98. rs.draw do
  99. match '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env|
  100. resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  101. [200, {}, [resp]]
  102. }
  103. end
  104. hash = JSON.load get(URI('http://example.org/journey/123-omg'))
  105. assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
  106. assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg'))
  107. end
  108. def test_pre_dash
  109. rs.draw do
  110. match '/:artist/omg-:song', :to => lambda { |env|
  111. resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  112. [200, {}, [resp]]
  113. }
  114. end
  115. hash = JSON.load get(URI('http://example.org/journey/omg-faithfully'))
  116. assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
  117. end
  118. def test_pre_dash_with_custom_regexp
  119. rs.draw do
  120. match '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env|
  121. resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
  122. [200, {}, [resp]]
  123. }
  124. end
  125. hash = JSON.load get(URI('http://example.org/journey/omg-123'))
  126. assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
  127. assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully'))
  128. end
  129. def test_star_paths_are_greedy
  130. rs.draw do
  131. match "/*path", :to => lambda { |env|
  132. x = env["action_dispatch.request.path_parameters"][:path]
  133. [200, {}, [x]]
  134. }, :format => false
  135. end
  136. u = URI('http://example.org/foo/bar.html')
  137. assert_equal u.path.sub(/^\//, ''), get(u)
  138. end
  139. def test_star_paths_are_greedy_but_not_too_much
  140. rs.draw do
  141. match "/*path", :to => lambda { |env|
  142. x = JSON.dump env["action_dispatch.request.path_parameters"]
  143. [200, {}, [x]]
  144. }
  145. end
  146. expected = { "path" => "foo/bar", "format" => "html" }
  147. u = URI('http://example.org/foo/bar.html')
  148. assert_equal expected, JSON.parse(get(u))
  149. end
  150. def test_optional_star_paths_are_greedy
  151. rs.draw do
  152. match "/(*filters)", :to => lambda { |env|
  153. x = env["action_dispatch.request.path_parameters"][:filters]
  154. [200, {}, [x]]
  155. }, :format => false
  156. end
  157. u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
  158. assert_equal u.path.sub(/^\//, ''), get(u)
  159. end
  160. def test_optional_star_paths_are_greedy_but_not_too_much
  161. rs.draw do
  162. match "/(*filters)", :to => lambda { |env|
  163. x = JSON.dump env["action_dispatch.request.path_parameters"]
  164. [200, {}, [x]]
  165. }
  166. end
  167. expected = { "filters" => "ne_27.065938,-80.6092/sw_25.489856,-82",
  168. "format" => "542794" }
  169. u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
  170. assert_equal expected, JSON.parse(get(u))
  171. end
  172. def test_regexp_precidence
  173. @rs.draw do
  174. match '/whois/:domain', :constraints => {
  175. :domain => /\w+\.[\w\.]+/ },
  176. :to => lambda { |env| [200, {}, %w{regexp}] }
  177. match '/whois/:id', :to => lambda { |env| [200, {}, %w{id}] }
  178. end
  179. assert_equal 'regexp', get(URI('http://example.org/whois/example.org'))
  180. assert_equal 'id', get(URI('http://example.org/whois/123'))
  181. end
  182. def test_class_and_lambda_constraints
  183. subdomain = Class.new {
  184. def matches? request
  185. request.subdomain.present? and request.subdomain != 'clients'
  186. end
  187. }
  188. @rs.draw do
  189. match '/', :constraints => subdomain.new,
  190. :to => lambda { |env| [200, {}, %w{default}] }
  191. match '/', :constraints => { :subdomain => 'clients' },
  192. :to => lambda { |env| [200, {}, %w{clients}] }
  193. end
  194. assert_equal 'default', get(URI('http://www.example.org/'))
  195. assert_equal 'clients', get(URI('http://clients.example.org/'))
  196. end
  197. def test_lambda_constraints
  198. @rs.draw do
  199. match '/', :constraints => lambda { |req|
  200. req.subdomain.present? and req.subdomain != "clients" },
  201. :to => lambda { |env| [200, {}, %w{default}] }
  202. match '/', :constraints => lambda { |req|
  203. req.subdomain.present? && req.subdomain == "clients" },
  204. :to => lambda { |env| [200, {}, %w{clients}] }
  205. end
  206. assert_equal 'default', get(URI('http://www.example.org/'))
  207. assert_equal 'clients', get(URI('http://clients.example.org/'))
  208. end
  209. def test_empty_string_match
  210. rs.draw do
  211. get '/:username', :constraints => { :username => /[^\/]+/ },
  212. :to => lambda { |e| [200, {}, ['foo']] }
  213. end
  214. assert_equal 'Not Found', get(URI('http://example.org/'))
  215. assert_equal 'foo', get(URI('http://example.org/hello'))
  216. end
  217. def test_non_greedy_glob_regexp
  218. params = nil
  219. rs.draw do
  220. get '/posts/:id(/*filters)', :constraints => { :filters => /.+?/ },
  221. :to => lambda { |e|
  222. params = e["action_dispatch.request.path_parameters"]
  223. [200, {}, ['foo']]
  224. }
  225. end
  226. assert_equal 'foo', get(URI('http://example.org/posts/1/foo.js'))
  227. assert_equal({:id=>"1", :filters=>"foo", :format=>"js"}, params)
  228. end
  229. def test_draw_with_block_arity_one_raises
  230. assert_raise(RuntimeError) do
  231. @rs.draw { |map| map.match '/:controller(/:action(/:id))' }
  232. end
  233. end
  234. def test_specific_controller_action_failure
  235. @rs.draw do
  236. mount lambda {} => "/foo"
  237. end
  238. assert_raises(ActionController::RoutingError) do
  239. url_for(@rs, :controller => "omg", :action => "lol")
  240. end
  241. end
  242. def test_default_setup
  243. @rs.draw { match '/:controller(/:action(/:id))' }
  244. assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
  245. assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
  246. assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
  247. assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
  248. assert_equal '/admin/user/show/10', url_for(rs, { :controller => 'admin/user', :action => 'show', :id => 10 })
  249. assert_equal '/admin/user/show', url_for(rs, { :action => 'show' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
  250. assert_equal '/admin/user/list/10', url_for(rs, {}, { :controller => 'admin/user', :action => 'list', :id => '10' })
  251. assert_equal '/admin/stuff', url_for(rs, { :controller => 'stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
  252. assert_equal '/stuff', url_for(rs, { :controller => '/stuff' }, { :controller => 'admin/user', :action => 'list', :id => '10' })
  253. end
  254. def test_ignores_leading_slash
  255. @rs.clear!
  256. @rs.draw { match '/:controller(/:action(/:id))'}
  257. test_default_setup
  258. end
  259. def test_time_recognition
  260. # We create many routes to make situation more realistic
  261. @rs = ::ActionDispatch::Routing::RouteSet.new
  262. @rs.draw {
  263. root :to => "search#new", :as => "frontpage"
  264. resources :videos do
  265. resources :comments
  266. resource :file, :controller => 'video_file'
  267. resource :share, :controller => 'video_shares'
  268. resource :abuse, :controller => 'video_abuses'
  269. end
  270. resources :abuses, :controller => 'video_abuses'
  271. resources :video_uploads
  272. resources :video_visits
  273. resources :users do
  274. resource :settings
  275. resources :videos
  276. end
  277. resources :channels do
  278. resources :videos, :controller => 'channel_videos'
  279. end
  280. resource :session
  281. resource :lost_password
  282. match 'search' => 'search#index', :as => 'search'
  283. resources :pages
  284. match ':controller/:action/:id'
  285. }
  286. end
  287. def test_route_with_colon_first
  288. rs.draw do
  289. match '/:controller/:action/:id', :action => 'index', :id => nil
  290. match ':url', :controller => 'tiny_url', :action => 'translate'
  291. end
  292. end
  293. def test_route_with_regexp_for_controller
  294. rs.draw do
  295. match ':controller/:admintoken(/:action(/:id))', :controller => /admin\/.+/
  296. match '/:controller(/:action(/:id))'
  297. end
  298. assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
  299. rs.recognize_path("/admin/user/foo"))
  300. assert_equal({:controller => "content", :action => "foo"},
  301. rs.recognize_path("/content/foo"))
  302. assert_equal '/admin/user/foo', url_for(rs, { :controller => "admin/user", :admintoken => "foo", :action => "index" })
  303. assert_equal '/content/foo', url_for(rs, { :controller => "content", :action => "foo" })
  304. end
  305. def test_route_with_regexp_and_captures_for_controller
  306. rs.draw do
  307. match '/:controller(/:action(/:id))', :controller => /admin\/(accounts|users)/
  308. end
  309. assert_equal({:controller => "admin/accounts", :action => "index"}, rs.recognize_path("/admin/accounts"))
  310. assert_equal({:controller => "admin/users", :action => "index"}, rs.recognize_path("/admin/users"))
  311. assert_raise(ActionController::RoutingError) { rs.recognize_path("/admin/products") }
  312. end
  313. def test_route_with_regexp_and_dot
  314. rs.draw do
  315. match ':controller/:action/:file',
  316. :controller => /admin|user/,
  317. :action => /upload|download/,
  318. :defaults => {:file => nil},
  319. :constraints => {:file => %r{[^/]+(\.[^/]+)?}}
  320. end
  321. # Without a file extension
  322. assert_equal '/user/download/file',
  323. url_for(rs, { :controller => "user", :action => "download", :file => "file" })
  324. assert_equal({:controller => "user", :action => "download", :file => "file"},
  325. rs.recognize_path("/user/download/file"))
  326. # Now, let's try a file with an extension, really a dot (.)
  327. assert_equal '/user/download/file.jpg',
  328. url_for(rs, { :controller => "user", :action => "download", :file => "file.jpg" })
  329. assert_equal({:controller => "user", :action => "download", :file => "file.jpg"},
  330. rs.recognize_path("/user/download/file.jpg"))
  331. end
  332. def test_basic_named_route
  333. rs.draw do
  334. root :to => 'content#list', :as => 'home'
  335. end
  336. assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
  337. end
  338. def test_named_route_with_option
  339. rs.draw do
  340. match 'page/:title' => 'content#show_page', :as => 'page'
  341. end
  342. assert_equal("http://test.host/page/new%20stuff",
  343. setup_for_named_route.send(:page_url, :title => 'new stuff'))
  344. end
  345. def test_named_route_with_default
  346. rs.draw do
  347. match 'page/:title' => 'content#show_page', :title => 'AboutPage', :as => 'page'
  348. end
  349. assert_equal("http://test.host/page/AboutRails",
  350. setup_for_named_route.send(:page_url, :title => "AboutRails"))
  351. end
  352. def test_named_route_with_path_prefix
  353. rs.draw do
  354. scope "my" do
  355. match 'page' => 'content#show_page', :as => 'page'
  356. end
  357. end
  358. assert_equal("http://test.host/my/page",
  359. setup_for_named_route.send(:page_url))
  360. end
  361. def test_named_route_with_blank_path_prefix
  362. rs.draw do
  363. scope "" do
  364. match 'page' => 'content#show_page', :as => 'page'
  365. end
  366. end
  367. assert_equal("http://test.host/page",
  368. setup_for_named_route.send(:page_url))
  369. end
  370. def test_named_route_with_nested_controller
  371. rs.draw do
  372. match 'admin/user' => 'admin/user#index', :as => "users"
  373. end
  374. assert_equal("http://test.host/admin/user",
  375. setup_for_named_route.send(:users_url))
  376. end
  377. def test_optimised_named_route_with_host
  378. rs.draw do
  379. match 'page' => 'content#show_page', :as => 'pages', :host => 'foo.com'
  380. end
  381. routes = setup_for_named_route
  382. routes.expects(:url_for).with({
  383. :host => 'foo.com',
  384. :only_path => false,
  385. :controller => 'content',
  386. :action => 'show_page',
  387. :use_route => 'pages'
  388. }).once
  389. routes.send(:pages_url)
  390. end
  391. def setup_for_named_route
  392. MockController.build(rs.url_helpers).new
  393. end
  394. def test_named_route_without_hash
  395. rs.draw do
  396. match ':controller/:action/:id', :as => 'normal'
  397. end
  398. end
  399. def test_named_route_root
  400. rs.draw do
  401. root :to => "hello#index"
  402. end
  403. routes = setup_for_named_route
  404. assert_equal("http://test.host/", routes.send(:root_url))
  405. assert_equal("/", routes.send(:root_path))
  406. end
  407. def test_named_route_with_regexps
  408. rs.draw do
  409. match 'page/:year/:month/:day/:title' => 'page#show', :as => 'article',
  410. :year => /\d+/, :month => /\d+/, :day => /\d+/
  411. match ':controller/:action/:id'
  412. end
  413. routes = setup_for_named_route
  414. assert_equal "http://test.host/page/2005/6/10/hi",
  415. routes.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
  416. end
  417. def test_changing_controller
  418. @rs.draw { match ':controller/:action/:id' }
  419. assert_equal '/admin/stuff/show/10',
  420. url_for(rs, {:controller => 'stuff', :action => 'show', :id => 10},
  421. {:controller => 'admin/user', :action => 'index'})
  422. end
  423. def test_paths_escaped
  424. rs.draw do
  425. match 'file/*path' => 'content#show_file', :as => 'path'
  426. match ':controller/:action/:id'
  427. end
  428. # No + to space in URI escaping, only for query params.
  429. results = rs.recognize_path "/file/hello+world/how+are+you%3F"
  430. assert results, "Recognition should have succeeded"
  431. assert_equal 'hello+world/how+are+you?', results[:path]
  432. # Use %20 for space instead.
  433. results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
  434. assert results, "Recognition should have succeeded"
  435. assert_equal 'hello world/how are you?', results[:path]
  436. end
  437. def test_paths_slashes_unescaped_with_ordered_parameters
  438. rs.draw do
  439. match '/file/*path' => 'content#index', :as => 'path'
  440. end
  441. # No / to %2F in URI, only for query params.
  442. assert_equal("/file/hello/world", setup_for_named_route.send(:path_path, ['hello', 'world']))
  443. end
  444. def test_non_controllers_cannot_be_matched
  445. rs.draw do
  446. match ':controller/:action/:id'
  447. end
  448. assert_raise(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
  449. end
  450. def test_should_list_options_diff_when_routing_constraints_dont_match
  451. rs.draw do
  452. match 'post/:id' => 'post#show', :constraints => { :id => /\d+/ }, :as => 'post'
  453. end
  454. assert_raise(ActionController::RoutingError) do
  455. url_for(rs, { :controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post" })
  456. end
  457. end
  458. def test_dynamic_path_allowed
  459. rs.draw do
  460. match '*path' => 'content#show_file'
  461. end
  462. assert_equal '/pages/boo',
  463. url_for(rs, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
  464. end
  465. def test_dynamic_recall_paths_allowed
  466. rs.draw do
  467. match '*path' => 'content#show_file'
  468. end
  469. assert_equal '/pages/boo',
  470. url_for(rs, {}, { :controller => 'content', :action => 'show_file', :path => %w(pages boo) })
  471. end
  472. def test_backwards
  473. rs.draw do
  474. match 'page/:id(/:action)' => 'pages#show'
  475. match ':controller(/:action(/:id))'
  476. end
  477. assert_equal '/page/20', url_for(rs, { :id => 20 }, { :controller => 'pages', :action => 'show' })
  478. assert_equal '/page/20', url_for(rs, { :controller => 'pages', :id => 20, :action => 'show' })
  479. assert_equal '/pages/boo', url_for(rs, { :controller => 'pages', :action => 'boo' })
  480. end
  481. def test_route_with_fixnum_default
  482. rs.draw do
  483. match 'page(/:id)' => 'content#show_page', :id => 1
  484. match ':controller/:action/:id'
  485. end
  486. assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page' })
  487. assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 1 })
  488. assert_equal '/page', url_for(rs, { :controller => 'content', :action => 'show_page', :id => '1' })
  489. assert_equal '/page/10', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 10 })
  490. assert_equal({:controller => "content", :action => 'show_page', :id => 1 }, rs.recognize_path("/page"))
  491. assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
  492. assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
  493. end
  494. # For newer revision
  495. def test_route_with_text_default
  496. rs.draw do
  497. match 'page/:id' => 'content#show_page', :id => 1
  498. match ':controller/:action/:id'
  499. end
  500. assert_equal '/page/foo', url_for(rs, { :controller => 'content', :action => 'show_page', :id => 'foo' })
  501. assert_equal({ :controller => "content", :action => 'show_page', :id => 'foo' }, rs.recognize_path("/page/foo"))
  502. token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in Russian
  503. token.force_encoding(Encoding::BINARY) if token.respond_to?(:force_encoding)
  504. escaped_token = CGI::escape(token)
  505. assert_equal '/page/' + escaped_token, url_for(rs, { :controller => 'content', :action => 'show_page', :id => token })
  506. assert_equal({ :controller => "content", :action => 'show_page', :id => token }, rs.recognize_path("/page/#{escaped_token}"))
  507. end
  508. def test_action_expiry
  509. @rs.draw { match ':controller(/:action(/:id))' }
  510. assert_equal '/content', url_for(rs, { :controller => 'content' }, { :controller => 'content', :action => 'show' })
  511. end
  512. def test_requirement_should_prevent_optional_id
  513. rs.draw do
  514. match 'post/:id' => 'post#show', :constraints => {:id => /\d+/}, :as => 'post'
  515. end
  516. assert_equal '/post/10', url_for(rs, { :controller => 'post', :action => 'show', :id => 10 })
  517. assert_raise ActionController::RoutingError do
  518. url_for(rs, { :controller => 'post', :action => 'show' })
  519. end
  520. end
  521. def test_both_requirement_and_optional
  522. rs.draw do
  523. match('test(/:year)' => 'post#show', :as => 'blog',
  524. :defaults => { :year => nil },
  525. :constraints => { :year => /\d{4}/ }
  526. )
  527. match ':controller/:action/:id'
  528. end
  529. assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show' })
  530. assert_equal '/test', url_for(rs, { :controller => 'post', :action => 'show', :year => nil })
  531. assert_equal("http://test.host/test", setup_for_named_route.send(:blog_url))
  532. end
  533. def test_set_to_nil_forgets
  534. rs.draw do
  535. match 'pages(/:year(/:month(/:day)))' => 'content#list_pages', :month => nil, :day => nil
  536. match ':controller/:action/:id'
  537. end
  538. assert_equal '/pages/2005',
  539. url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005 })
  540. assert_equal '/pages/2005/6',
  541. url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6 })
  542. assert_equal '/pages/2005/6/12',
  543. url_for(rs, { :controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12 })
  544. assert_equal '/pages/2005/6/4',
  545. url_for(rs, { :day => 4 }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
  546. assert_equal '/pages/2005/6',
  547. url_for(rs, { :day => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
  548. assert_equal '/pages/2005',
  549. url_for(rs, { :day => nil, :month => nil }, { :controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12' })
  550. end
  551. def test_root_url_generation_with_controller_and_action
  552. rs.draw do
  553. root :to => "content#index"
  554. end
  555. assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
  556. assert_equal '/', url_for(rs, { :controller => 'content' })
  557. end
  558. def test_named_root_url_generation_with_controller_and_action
  559. rs.draw do
  560. root :to => "content#index", :as => 'home'
  561. end
  562. assert_equal '/', url_for(rs, { :controller => 'content', :action => 'index' })
  563. assert_equal '/', url_for(rs, { :controller => 'content' })
  564. assert_equal("http://test.host/", setup_for_named_route.send(:home_url))
  565. end
  566. def test_named_route_method
  567. rs.draw do
  568. match 'categories' => 'content#categories', :as => 'categories'
  569. match ':controller(/:action(/:id))'
  570. end
  571. assert_equal '/categories', url_for(rs, { :controller => 'content', :action => 'categories' })
  572. assert_equal '/content/hi', url_for(rs, { :controller => 'content', :action => 'hi' })
  573. end
  574. def test_named_routes_array
  575. test_named_route_method
  576. assert_equal [:categories], rs.named_routes.names
  577. end
  578. def test_nil_defaults
  579. rs.draw do
  580. match 'journal' => 'content#list_journal',
  581. :date => nil, :user_id => nil
  582. match ':controller/:action/:id'
  583. end
  584. assert_equal '/journal', url_for(rs, {
  585. :controller => 'content',
  586. :action => 'list_journal',
  587. :date => nil,
  588. :user_id => nil
  589. })
  590. end
  591. def setup_request_method_routes_for(method)
  592. rs.draw do
  593. match '/match' => 'books#get', :via => :get
  594. match '/match' => 'books#post', :via => :post
  595. match '/match' => 'books#put', :via => :put
  596. match '/match' => 'books#delete', :via => :delete
  597. end
  598. end
  599. %w(GET POST PUT DELETE).each do |request_method|
  600. define_method("test_request_method_recognized_with_#{request_method}") do
  601. setup_request_method_routes_for(request_method)
  602. params = rs.recognize_path("/match", :method => request_method)
  603. assert_equal request_method.downcase, params[:action]
  604. end
  605. end
  606. def test_recognize_array_of_methods
  607. rs.draw do
  608. match '/match' => 'books#get_or_post', :via => [:get, :post]
  609. match '/match' => 'books#not_get_or_post'
  610. end
  611. params = rs.recognize_path("/match", :method => :post)
  612. assert_equal 'get_or_post', params[:action]
  613. params = rs.recognize_path("/match", :method => :put)
  614. assert_equal 'not_get_or_post', params[:action]
  615. end
  616. def test_subpath_recognized
  617. rs.draw do
  618. match '/books/:id/edit' => 'subpath_books#edit'
  619. match '/items/:id/:action' => 'subpath_books'
  620. match '/posts/new/:action' => 'subpath_books'
  621. match '/posts/:id' => 'subpath_books#show'
  622. end
  623. hash = rs.recognize_path "/books/17/edit"
  624. assert_not_nil hash
  625. assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
  626. hash = rs.recognize_path "/items/3/complete"
  627. assert_not_nil hash
  628. assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
  629. hash = rs.recognize_path "/posts/new/preview"
  630. assert_not_nil hash
  631. assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
  632. hash = rs.recognize_path "/posts/7"
  633. assert_not_nil hash
  634. assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
  635. end
  636. def test_subpath_generated
  637. rs.draw do
  638. match '/books/:id/edit' => 'subpath_books#edit'
  639. match '/items/:id/:action' => 'subpath_books'
  640. match '/posts/new/:action' => 'subpath_books'
  641. end
  642. assert_equal "/books/7/edit", url_for(rs, { :controller => "subpath_books", :id => 7, :action => "edit" })
  643. assert_equal "/items/15/complete", url_for(rs, { :controller => "subpath_books", :id => 15, :action => "complete" })
  644. assert_equal "/posts/new/preview", url_for(rs, { :controller => "subpath_books", :action => "preview" })
  645. end
  646. def test_failed_constraints_raises_exception_with_violated_constraints
  647. rs.draw do
  648. match 'foos/:id' => 'foos#show', :as => 'foo_with_requirement', :constraints => { :id => /\d+/ }
  649. end
  650. assert_raise(ActionController::RoutingError) do
  651. setup_for_named_route.send(:foo_with_requirement_url, "I am Against the constraints")
  652. end
  653. end
  654. def test_routes_changed_correctly_after_clear
  655. rs = ::ActionDispatch::Routing::RouteSet.new
  656. rs.draw do
  657. match 'ca' => 'ca#aa'
  658. match 'cb' => 'cb#ab'
  659. match 'cc' => 'cc#ac'
  660. match ':controller/:action/:id'
  661. match ':controller/:action/:id.:format'
  662. end
  663. hash = rs.recognize_path "/cc"
  664. assert_not_nil hash
  665. assert_equal %w(cc ac), [hash[:controller], hash[:action]]
  666. rs.draw do
  667. match 'cb' => 'cb#ab'
  668. match 'cc' => 'cc#ac'
  669. match ':controller/:action/:id'
  670. match ':controller/:action/:id.:format'
  671. end
  672. hash = rs.recognize_path "/cc"
  673. assert_not_nil hash
  674. assert_equal %w(cc ac), [hash[:controller], hash[:action]]
  675. end
  676. end
  677. class RouteSetTest < ActiveSupport::TestCase
  678. include RoutingTestHelpers
  679. def set
  680. @set ||= ROUTING::RouteSet.new
  681. end
  682. def request
  683. @request ||= ActionController::TestRequest.new
  684. end
  685. def default_route_set
  686. @default_route_set ||= begin
  687. set = ROUTING::RouteSet.new
  688. set.draw do
  689. match '/:controller(/:action(/:id))'
  690. end
  691. set
  692. end
  693. end
  694. def test_generate_extras
  695. set.draw { match ':controller/(:action(/:id))' }
  696. path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
  697. assert_equal "/foo/bar/15", path
  698. assert_equal %w(that this), extras.map { |e| e.to_s }.sort
  699. end
  700. def test_extra_keys
  701. set.draw { match ':controller/:action/:id' }
  702. extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
  703. assert_equal %w(that this), extras.map { |e| e.to_s }.sort
  704. end
  705. def test_generate_extras_not_first
  706. set.draw do
  707. match ':controller/:action/:id.:format'
  708. match ':controller/:action/:id'
  709. end
  710. path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
  711. assert_equal "/foo/bar/15", path
  712. assert_equal %w(that this), extras.map { |e| e.to_s }.sort
  713. end
  714. def test_generate_not_first
  715. set.draw do
  716. match ':controller/:action/:id.:format'
  717. match ':controller/:action/:id'
  718. end
  719. assert_equal "/foo/bar/15?this=hello",
  720. url_for(set, { :controller => "foo", :action => "bar", :id => 15, :this => "hello" })
  721. end
  722. def test_extra_keys_not_first
  723. set.draw do
  724. match ':controller/:action/:id.:format'
  725. match ':controller/:action/:id'
  726. end
  727. extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
  728. assert_equal %w(that this), extras.map { |e| e.to_s }.sort
  729. end
  730. def test_draw
  731. assert_equal 0, set.routes.size
  732. set.draw do
  733. match '/hello/world' => 'a#b'
  734. end
  735. assert_equal 1, set.routes.size
  736. end
  737. def test_draw_symbol_controller_name
  738. assert_equal 0, set.routes.size
  739. set.draw do
  740. match '/users/index' => 'users#index'
  741. end
  742. set.recognize_path('/users/index', :method => :get)
  743. assert_equal 1, set.routes.size
  744. end
  745. def test_named_draw
  746. assert_equal 0, set.routes.size
  747. set.draw do
  748. match '/hello/world' => 'a#b', :as => 'hello'
  749. end
  750. assert_equal 1, set.routes.size
  751. assert_equal set.routes.first, set.named_routes[:hello]
  752. end
  753. def test_later_named_routes_take_precedence
  754. set.draw do
  755. match '/hello/world' => 'a#b', :as => 'hello'
  756. match '/hello' => 'a#b', :as => 'hello'
  757. end
  758. assert_equal set.routes.last, set.named_routes[:hello]
  759. end
  760. def setup_named_route_test
  761. set.draw do
  762. match '/people(/:id)' => 'people#show', :as => 'show'
  763. match '/people' => 'people#index', :as => 'index'
  764. match '/people/go/:foo/:bar/joe(/:id)' => 'people#multi', :as => 'multi'
  765. match '/admin/users' => 'admin/users#index', :as => "users"
  766. end
  767. MockController.build(set.url_helpers).new
  768. end
  769. def test_named_route_hash_access_method
  770. controller = setup_named_route_test
  771. assert_equal(
  772. { :controller => 'people', :action => 'show', :id => 5, :use_route => "show", :only_path => false },
  773. controller.send(:hash_for_show_url, :id => 5))
  774. assert_equal(
  775. { :controller => 'people', :action => 'index', :use_route => "index", :only_path => false },
  776. controller.send(:hash_for_index_url))
  777. assert_equal(
  778. { :controller => 'people', :action => 'show', :id => 5, :use_route => "show", :only_path => true },
  779. controller.send(:hash_for_show_path, :id => 5)
  780. )
  781. end
  782. def test_named_route_url_method
  783. controller = setup_named_route_test
  784. assert_equal "http://test.host/people/5", controller.send(:show_url, :id => 5)
  785. assert_equal "/people/5", controller.send(:show_path, :id => 5)
  786. assert_equal "http://test.host/people", controller.send(:index_url)
  787. assert_equal "/people", controller.send(:index_path)
  788. assert_equal "http://test.host/admin/users", controller.send(:users_url)
  789. assert_equal '/admin/users', controller.send(:users_path)
  790. assert_equal '/admin/users', url_for(set, controller.send(:hash_for_users_url), { :controller => 'users', :action => 'index' })
  791. end
  792. def test_named_route_url_method_with_anchor
  793. controller = setup_named_route_test
  794. assert_equal "http://test.host/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
  795. assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
  796. assert_equal "http://test.host/people#location", controller.send(:index_url, :anchor => 'location')
  797. assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
  798. assert_equal "http://test.host/admin/users#location", controller.send(:users_url, :anchor => 'location')
  799. assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
  800. assert_equal "http://test.host/people/go/7/hello/joe/5#location",
  801. controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
  802. assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar#location",
  803. controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
  804. assert_equal "http://test.host/people?baz=bar#location",
  805. controller.send(:index_url, :baz => "bar", :anchor => 'location')
  806. end
  807. def test_named_route_url_method_with_port
  808. controller = setup_named_route_test
  809. assert_equal "http://test.host:8080/people/5", controller.send(:show_url, 5, :port=>8080)
  810. end
  811. def test_named_route_url_method_with_host
  812. controller = setup_named_route_test
  813. assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
  814. end
  815. def test_named_route_url_method_with_protocol
  816. controller = setup_named_route_test
  817. assert_equal "https://test.host/people/5", controller.send(:show_url, 5, :protocol => "https")
  818. end
  819. def test_named_route_url_method_with_ordered_parameters
  820. controller = setup_named_route_test
  821. assert_equal "http://test.host/people/go/7/hello/joe/5",
  822. controller.send(:multi_url, 7, "hello", 5)
  823. end
  824. def test_named_route_url_method_with_ordered_parameters_and_hash
  825. controller = setup_named_route_test
  826. assert_equal "http://test.host/people/go/7/hello/joe/5?baz=bar",
  827. controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
  828. end
  829. def test_named_route_url_method_with_ordered_parameters_and_empty_hash
  830. controller = setup_named_route_test
  831. assert_equal "http://test.host/people/go/7/hello/joe/5",
  832. controller.send(:multi_url, 7, "hello", 5, {})
  833. end
  834. def test_named_route_url_method_with_no_positional_arguments
  835. controller = setup_named_route_test
  836. assert_equal "http://test.host/people?baz=bar",
  837. controller.send(:index_url, :baz => "bar")
  838. end
  839. def test_draw_default_route
  840. set.draw do
  841. match '/:controller/:action/:id'
  842. end
  843. assert_equal 1, set.routes.size
  844. assert_equal '/users/show/10', url_for(set, { :controller => 'users', :action => 'show', :id => 10 })
  845. assert_equal '/users/index/10', url_for(set, { :controller => 'users', :id => 10 })
  846. assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
  847. assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
  848. end
  849. def test_route_with_parameter_shell
  850. set.draw do
  851. match 'page/:id' => 'pages#show', :id => /\d+/
  852. match '/:controller(/:action(/:id))'
  853. end
  854. assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
  855. assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
  856. assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
  857. assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
  858. assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
  859. end
  860. def test_route_constraints_on_request_object_with_anchors_are_valid
  861. assert_nothing_raised do
  862. set.draw do
  863. match 'page/:id' => 'pages#show', :constraints => { :host => /^foo$/ }
  864. end
  865. end
  866. end
  867. def test_route_constraints_with_anchor_chars_are_invalid
  868. assert_raise ArgumentError do
  869. set.draw do
  870. match 'page/:id' => 'pages#show', :id => /^\d+/
  871. end
  872. end
  873. assert_raise ArgumentError do
  874. set.draw do
  875. match 'page/:id' => 'pages#show', :id => /\A\d+/
  876. end
  877. end
  878. assert_raise ArgumentError do
  879. set.draw do
  880. match 'page/:id' => 'pages#show', :id => /\d+$/
  881. end
  882. end
  883. assert_raise ArgumentError do
  884. set.draw do
  885. match 'page/:id' => 'pages#show', :id => /\d+\Z/
  886. end
  887. end
  888. assert_raise ArgumentError do
  889. set.draw do
  890. match 'page/:id' => 'pages#show', :id => /\d+\z/
  891. end
  892. end
  893. end
  894. def test_route_constraints_with_options_method_condition_is_valid
  895. assert_nothing_raised do
  896. set.draw do
  897. match 'valid/route' => 'pages#show', :via => :options
  898. end
  899. end
  900. end
  901. def test_recognize_with_encoded_id_and_regex
  902. set.draw do
  903. match 'page/:id' => 'pages#show', :id => /[a-zA-Z0-9\+]+/
  904. end
  905. assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
  906. assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
  907. end
  908. def test_recognize_with_http_methods
  909. set.draw do
  910. get "/people" => "people#index", :as => "people"
  911. post "/people" => "people#create"
  912. get "/people/:id" => "people#show", :as => "person"
  913. put "/people/:id" => "people#update"
  914. delete "/people/:id" => "people#destroy"
  915. end
  916. params = set.recognize_path("/people", :method => :get)
  917. assert_equal("index", params[:action])
  918. params = set.recognize_path("/people", :method => :post)
  919. assert_equal("create", params[:action])
  920. params = set.recognize_path("/people/5", :method => :put)
  921. assert_equal("update", params[:action])
  922. assert_raise(ActionController::UnknownHttpMethod) {
  923. set.recognize_path("/people", :method => :bacon)
  924. }
  925. params = set.recognize_path("/people/5", :method => :get)
  926. assert_equal("show", params[:action])
  927. assert_equal("5", params[:id])
  928. params = set.recognize_path("/people/5", :method => :put)
  929. assert_equal("update", params[:action])
  930. assert_equal("5", params[:id])
  931. params = set.recognize_path("/people/5", :method => :delete)
  932. assert_equal("destroy", params[:action])
  933. assert_equal("5", params[:id])
  934. assert_raise(ActionController::RoutingError) {
  935. set.recognize_path("/people/5", :method => :post)
  936. }
  937. end
  938. def test_recognize_with_alias_in_conditions
  939. set.draw do
  940. match "/people" => 'people#index', :as => 'people', :via => :get
  941. root :to => "people#index"
  942. end
  943. params = set.recognize_path("/people", :method => :get)
  944. assert_equal("people", params[:controller])
  945. assert_equal("index", params[:action])
  946. params = set.recognize_path("/", :method => :get)
  947. assert_equal("people", params[:controller])
  948. assert_equal("index", params[:action])
  949. end
  950. def test_typo_recognition
  951. set.draw do
  952. match 'articles/:year/:month/:day/:title' => 'articles#permalink',
  953. :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
  954. end
  955. params = set.recognize_path("/articles/2005/11/05/a-very-interesting-article", :method => :get)
  956. assert_equal("permalink", params[:action])
  957. assert_equal("2005", params[:year])
  958. assert_equal("11", params[:month])
  959. assert_equal("05", params[:day])
  960. assert_equal("a-very-interesting-article", params[:title])
  961. end
  962. def test_routing_traversal_does_not_load_extra_classes
  963. assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
  964. set.draw do
  965. match '/profile' => 'profile#index'
  966. end
  967. set.recognize_path("/profile") rescue nil
  968. assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
  969. end
  970. def test_recognize_with_conditions_and_format
  971. set.draw do
  972. get "people/:id" => "people#show", :as => "person"
  973. put "people/:id" => "people#update"
  974. get "people/:id(.:format)" => "people#show"
  975. end
  976. params = set.recognize_path("/people/5", :method => :get)
  977. assert_equal("show", params[:action])
  978. assert_equal("5", params[:id])
  979. params = set.recognize_path("/people/5", :method => :put)
  980. assert_equal("update", params[:action])
  981. params = set.recognize_path("/people/5.png", :method => :get)
  982. assert_equal("show", params[:action])
  983. assert_equal("5", params[:id])
  984. assert_equal("png", params[:format])
  985. end
  986. def test_generate_with_default_action
  987. set.draw do
  988. match "/people", :controller => "people", :action => "index"
  989. match "/people/list", :controller => "people", :action => "list"
  990. end
  991. url = url_for(set, { :controller => "people", :action => "list" })
  992. assert_equal "/people/list", url
  993. end
  994. def test_root_map
  995. set.draw { root :to => 'people#index' }
  996. params = set.recognize_path("", :method => :get)
  997. assert_equal("people", params[:controller])
  998. assert_equal("index", params[:action])
  999. end
  1000. def test_namespace
  1001. set.draw do
  1002. namespace 'api' do
  1003. match 'inventory' => 'products#inventory'
  1004. end
  1005. end
  1006. params = set.recognize_path("/api/inventory", :method => :get)
  1007. assert_equal("api/products", params[:controller])
  1008. assert_equal("inventory", params[:action])
  1009. end
  1010. def test_namespaced_root_map
  1011. set.draw do
  1012. namespace 'api' do
  1013. root :to => 'products#index'
  1014. end
  1015. end
  1016. params = set.recognize_path("/api", :method => :get)
  1017. assert_equal("api/products", params[:controller])
  1018. assert_equal("index", params[:action])
  1019. end
  1020. def test_namespace_with_path_prefix
  1021. set.draw do
  1022. scope :module => "api", :path => "prefix" do
  1023. match 'inventory' => 'products#inventory'
  1024. end
  1025. end
  1026. params = set.recognize_path("/prefix/inventory", :method => :get)
  1027. assert_equal("api/products", params[:controller])
  1028. assert_equal("inventory", params[:action])
  1029. end
  1030. def test_namespace_with_blank_path_prefix
  1031. set.draw do
  1032. scope :module => "api", :path => "" do
  1033. match 'inventory' => 'products#inventory'
  1034. end
  1035. end
  1036. params = set.recognize_path("/inventory", :method => :get)
  1037. assert_equal("api/products", params[:controller])
  1038. assert_equal("inventory", params[:action])
  1039. end
  1040. def test_generate_changes_controller_module
  1041. set.draw { match ':controller/:action/:id' }
  1042. current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
  1043. assert_equal "/foo/bar/baz/7",
  1044. url_for(set, { :controller => "foo/bar", :action => "baz", :id => 7 }, current)
  1045. end
  1046. def test_id_is_sticky_when_it_ought_to_be
  1047. set.draw do
  1048. match ':controller/:id/:action'
  1049. end
  1050. url = url_for(set, { :action => "destroy" }, { :controller => "people", :action => "show", :id => "7" })
  1051. assert_equal "/people/7/destroy", url
  1052. end
  1053. def test_use_static_path_when_possible
  1054. set.draw do
  1055. match 'about' => "welcome#about"
  1056. match ':controller/:action/:id'
  1057. end
  1058. url = url_for(set, { :controller => "welcome", :action => "about" },
  1059. { :controller => "welcome", :action => "get", :id => "7" })
  1060. assert_equal "/about", url
  1061. end
  1062. def test_generate
  1063. set.draw { match ':controller/:action/:id' }
  1064. args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
  1065. assert_equal "/foo/bar/7?x=y", url_for(set, args)
  1066. assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
  1067. assert_equal [:x], set.extra_keys(args)
  1068. end
  1069. def test_generate_with_path_prefix
  1070. set.draw do
  1071. scope "my" do
  1072. match ':controller(/:action(/:id))'
  1073. end
  1074. end
  1075. args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
  1076. assert_equal "/my/foo/bar/7?x=y", url_for(set, args)
  1077. end
  1078. def test_generate_with_blank_path_prefix
  1079. set.draw do
  1080. scope "" do
  1081. match ':controller(/:action(/:id))'
  1082. end
  1083. end
  1084. args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
  1085. assert_equal "/foo/bar/7?x=y", url_for(set, args)
  1086. end
  1087. def test_named_routes_are_never_relative_to_modules
  1088. set.draw do
  1089. match "/connection/manage(/:action)" => 'connection/manage#index'
  1090. match "/connection/connection" => "connection/connection#index"
  1091. match '/connection' => 'connection#index', :as => 'family_connection'
  1092. end
  1093. url = url_for(set, { :controller => "connection" }, { :controller => 'connection/manage' })
  1094. assert_equal "/connection/connection", url
  1095. url = url_for(set, { :use_route => :family_connection, :controller => "connection" }, { :controller => 'connection/manage' })
  1096. assert_equal "/connection", url
  1097. end
  1098. def test_action_left_off_when_id_is_recalled
  1099. set.draw do
  1100. match ':controller(/:action(/:id))'
  1101. end
  1102. assert_equal '/books', url_for(set,
  1103. {:controller => 'books', :action => 'index'},
  1104. {:controller => 'books', :action => 'show', :id => '10'}
  1105. )
  1106. end
  1107. def test_query_params_will_be_shown_when_recalled
  1108. set.draw do
  1109. match 'show_weblog/:parameter' => 'weblog#show'
  1110. match ':controller(/:action(/:id))'
  1111. end
  1112. assert_equal '/weblog/edit?parameter=1', url_for(set,
  1113. {:action => 'edit', :parameter => 1},
  1114. {:controller => 'weblog', :action => 'show', :parameter => 1}
  1115. )
  1116. end
  1117. def test_format_is_not_inherit
  1118. set.draw do
  1119. match '/posts(.:format)' => 'posts#index'
  1120. end
  1121. assert_equal '/posts', url_for(set,
  1122. {:controller => 'posts'},
  1123. {:controller => 'posts', :action => 'index', :format => 'xml'}
  1124. )
  1125. assert_equal '/posts.xml', url_for(set,
  1126. {:controller => 'posts', :format => 'xml'},
  1127. {:controller => 'posts', :action => 'index', :format => 'xml'}
  1128. )
  1129. end
  1130. def test_expiry_determination_should_consider_values_with_to_param
  1131. set.draw { match 'projects/:project_id/:controller/:action' }
  1132. assert_equal '/projects/1/weblog/show', url_for(set,
  1133. { :action => 'show', :project_id => 1 },
  1134. { :controller => 'weblog', :action => 'show', :project_id => '1' })
  1135. end
  1136. def test_named_route_in_nested_resource
  1137. set.draw do
  1138. resources :projects do
  1139. member do
  1140. match 'milestones' => 'milestones#index', :as => 'milestones'
  1141. end
  1142. end
  1143. end
  1144. params = set.recognize_path("/projects/1/milestones", :method => :get)
  1145. assert_equal("milestones", params[:controller])
  1146. assert_equal("index", params[:action])
  1147. end
  1148. def test_setting_root_in_namespace_using_symbol
  1149. assert_nothing_raised do
  1150. set.draw do
  1151. namespace :admin do
  1152. root :to => "home#index"
  1153. end
  1154. end
  1155. end
  1156. end
  1157. def test_setting_root_in_namespace_using_string
  1158. assert_nothing_raised do
  1159. set.draw do
  1160. namespace 'admin' do
  1161. root :to => "home#index"
  1162. end
  1163. end
  1164. end
  1165. end
  1166. def test_route_constraints_with_unsupported_regexp_options_must_error
  1167. assert_raise ArgumentError do
  1168. set.draw do
  1169. match 'page/:name' => 'pages#show',
  1170. :constraints => { :name => /(david|jamis)/m }
  1171. end
  1172. end
  1173. end
  1174. def test_route_constraints_with_supported_options_must_not_error
  1175. assert_nothing_raised do
  1176. set.draw do
  1177. match 'page/:name' => 'pages#show',
  1178. :constraints => { :name => /(david|jamis)/i }
  1179. end
  1180. end
  1181. assert_nothing_raised do
  1182. set.draw do
  1183. match 'page/:name' => 'pages#show',
  1184. :constraints => { :name => / # Desperately overcommented regexp
  1185. ( #Either
  1186. david #The Creator
  1187. | #Or
  1188. jamis #The Deployer
  1189. )/x }
  1190. end
  1191. end
  1192. end
  1193. def test_route_requirement_recognize_with_ignore_case
  1194. set.draw do
  1195. match 'page/:name' => 'pages#show',
  1196. :constraints => {:name => /(david|jamis)/i}
  1197. end
  1198. assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
  1199. assert_raise ActionController::RoutingError do
  1200. set.recognize_path('/page/davidjamis')
  1201. end
  1202. assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID'))
  1203. end
  1204. def test_route_requirement_generate_with_ignore_case
  1205. set.draw do
  1206. match 'page/:name' => 'pages#show',
  1207. :constraints => {:name => /(david|jamis)/i}
  1208. end
  1209. url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'david' })
  1210. assert_equal "/page/david", url
  1211. assert_raise ActionController::RoutingError do
  1212. url_for(set, { :controller => 'pages', :action => 'show', :name => 'davidjamis' })
  1213. end
  1214. url = url_for(set, { :controller => 'pages', :action => 'show', :name => 'JAMIS' })
  1215. assert_equal "/page/JAMIS", url
  1216. end
  1217. def test_route_requirement_recognize_with_extended_syntax
  1218. set.draw do
  1219. match 'page/:name' => 'pages#show',
  1220. :constraints => {:name => / # Desperately overcommented regexp
  1221. ( #Either
  1222. david #The Creator
  1223. | #Or
  1224. jamis #The Deployer
  1225. )/x}
  1226. end
  1227. assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/j…

Large files files are truncated, but you can click here to view the full file