PageRenderTime 63ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/actionpack/test/controller/routing_test.rb

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