mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
c4106d0c08
Ruby 1.9 freezes Hash string keys by default so where a route is defined like this: get 'search' => 'search' then the Mapper will derive the action from the key. This blows up later when the action is added to the parameters hash and the encoding is forced. Closes #3429
3339 lines
96 KiB
Ruby
3339 lines
96 KiB
Ruby
# encoding: UTF-8
|
|
require 'erb'
|
|
require 'abstract_unit'
|
|
require 'controller/fake_controllers'
|
|
|
|
class TestRoutingMapper < ActionDispatch::IntegrationTest
|
|
SprocketsApp = lambda { |env|
|
|
[200, {"Content-Type" => "text/html"}, ["javascripts"]]
|
|
}
|
|
|
|
class IpRestrictor
|
|
def self.matches?(request)
|
|
request.ip =~ /192\.168\.1\.1\d\d/
|
|
end
|
|
end
|
|
|
|
class YoutubeFavoritesRedirector
|
|
def self.call(params, request)
|
|
"http://www.youtube.com/watch?v=#{params[:youtube_id]}"
|
|
end
|
|
end
|
|
|
|
def test_logout
|
|
draw do
|
|
controller :sessions do
|
|
delete 'logout' => :destroy
|
|
end
|
|
end
|
|
|
|
delete '/logout'
|
|
assert_equal 'sessions#destroy', @response.body
|
|
|
|
assert_equal '/logout', logout_path
|
|
assert_equal '/logout', url_for(:controller => 'sessions', :action => 'destroy', :only_path => true)
|
|
end
|
|
|
|
def test_login
|
|
draw do
|
|
default_url_options :host => "rubyonrails.org"
|
|
|
|
controller :sessions do
|
|
get 'login' => :new
|
|
post 'login' => :create
|
|
end
|
|
end
|
|
|
|
get '/login'
|
|
assert_equal 'sessions#new', @response.body
|
|
assert_equal '/login', login_path
|
|
|
|
post '/login'
|
|
assert_equal 'sessions#create', @response.body
|
|
|
|
assert_equal '/login', url_for(:controller => 'sessions', :action => 'create', :only_path => true)
|
|
assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true)
|
|
|
|
assert_equal 'http://rubyonrails.org/login', url_for(:controller => 'sessions', :action => 'create')
|
|
assert_equal 'http://rubyonrails.org/login', login_url
|
|
end
|
|
|
|
def test_login_redirect
|
|
draw do
|
|
get 'account/login', :to => redirect("/login")
|
|
end
|
|
|
|
get '/account/login'
|
|
verify_redirect 'http://www.example.com/login'
|
|
end
|
|
|
|
def test_logout_redirect_without_to
|
|
draw do
|
|
get 'account/logout' => redirect("/logout"), :as => :logout_redirect
|
|
end
|
|
|
|
assert_equal '/account/logout', logout_redirect_path
|
|
get '/account/logout'
|
|
verify_redirect 'http://www.example.com/logout'
|
|
end
|
|
|
|
def test_namespace_redirect
|
|
draw do
|
|
namespace :private do
|
|
root :to => redirect('/private/index')
|
|
get "index", :to => 'private#index'
|
|
end
|
|
end
|
|
|
|
get '/private'
|
|
verify_redirect 'http://www.example.com/private/index'
|
|
end
|
|
|
|
def test_namespace_with_controller_segment
|
|
assert_raise(ArgumentError) do
|
|
draw do
|
|
namespace :admin do
|
|
get '/:controller(/:action(/:id(.:format)))'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_session_singleton_resource
|
|
draw do
|
|
resource :session do
|
|
get :create
|
|
post :reset
|
|
end
|
|
end
|
|
|
|
get '/session'
|
|
assert_equal 'sessions#create', @response.body
|
|
assert_equal '/session', session_path
|
|
|
|
post '/session'
|
|
assert_equal 'sessions#create', @response.body
|
|
|
|
put '/session'
|
|
assert_equal 'sessions#update', @response.body
|
|
|
|
delete '/session'
|
|
assert_equal 'sessions#destroy', @response.body
|
|
|
|
get '/session/new'
|
|
assert_equal 'sessions#new', @response.body
|
|
assert_equal '/session/new', new_session_path
|
|
|
|
get '/session/edit'
|
|
assert_equal 'sessions#edit', @response.body
|
|
assert_equal '/session/edit', edit_session_path
|
|
|
|
post '/session/reset'
|
|
assert_equal 'sessions#reset', @response.body
|
|
assert_equal '/session/reset', reset_session_path
|
|
end
|
|
|
|
def test_session_info_nested_singleton_resource
|
|
draw do
|
|
resource :session do
|
|
resource :info
|
|
end
|
|
end
|
|
|
|
get '/session/info'
|
|
assert_equal 'infos#show', @response.body
|
|
assert_equal '/session/info', session_info_path
|
|
end
|
|
|
|
def test_member_on_resource
|
|
draw do
|
|
resource :session do
|
|
member do
|
|
get :crush
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/session/crush'
|
|
assert_equal 'sessions#crush', @response.body
|
|
assert_equal '/session/crush', crush_session_path
|
|
end
|
|
|
|
def test_redirect_modulo
|
|
draw do
|
|
get 'account/modulo/:name', :to => redirect("/%{name}s")
|
|
end
|
|
|
|
get '/account/modulo/name'
|
|
verify_redirect 'http://www.example.com/names'
|
|
end
|
|
|
|
def test_redirect_proc
|
|
draw do
|
|
get 'account/proc/:name', :to => redirect {|params, req| "/#{params[:name].pluralize}" }
|
|
end
|
|
|
|
get '/account/proc/person'
|
|
verify_redirect 'http://www.example.com/people'
|
|
end
|
|
|
|
def test_redirect_proc_with_request
|
|
draw do
|
|
get 'account/proc_req' => redirect {|params, req| "/#{req.method}" }
|
|
end
|
|
|
|
get '/account/proc_req'
|
|
verify_redirect 'http://www.example.com/GET'
|
|
end
|
|
|
|
def test_redirect_hash_with_subdomain
|
|
draw do
|
|
get 'mobile', :to => redirect(:subdomain => 'mobile')
|
|
end
|
|
|
|
get '/mobile'
|
|
verify_redirect 'http://mobile.example.com/mobile'
|
|
end
|
|
|
|
def test_redirect_hash_with_domain_and_path
|
|
draw do
|
|
get 'documentation', :to => redirect(:domain => 'example-documentation.com', :path => '')
|
|
end
|
|
|
|
get '/documentation'
|
|
verify_redirect 'http://www.example-documentation.com'
|
|
end
|
|
|
|
def test_redirect_hash_with_path
|
|
draw do
|
|
get 'new_documentation', :to => redirect(:path => '/documentation/new')
|
|
end
|
|
|
|
get '/new_documentation'
|
|
verify_redirect 'http://www.example.com/documentation/new'
|
|
end
|
|
|
|
def test_redirect_hash_with_host
|
|
draw do
|
|
get 'super_new_documentation', :to => redirect(:host => 'super-docs.com')
|
|
end
|
|
|
|
get '/super_new_documentation?section=top'
|
|
verify_redirect 'http://super-docs.com/super_new_documentation?section=top'
|
|
end
|
|
|
|
def test_redirect_hash_path_substitution
|
|
draw do
|
|
get 'stores/:name', :to => redirect(:subdomain => 'stores', :path => '/%{name}')
|
|
end
|
|
|
|
get '/stores/iernest'
|
|
verify_redirect 'http://stores.example.com/iernest'
|
|
end
|
|
|
|
def test_redirect_hash_path_substitution_with_catch_all
|
|
draw do
|
|
get 'stores/:name(*rest)', :to => redirect(:subdomain => 'stores', :path => '/%{name}%{rest}')
|
|
end
|
|
|
|
get '/stores/iernest/products'
|
|
verify_redirect 'http://stores.example.com/iernest/products'
|
|
end
|
|
|
|
def test_redirect_class
|
|
draw do
|
|
get 'youtube_favorites/:youtube_id/:name', :to => redirect(YoutubeFavoritesRedirector)
|
|
end
|
|
|
|
get '/youtube_favorites/oHg5SJYRHA0/rick-rolld'
|
|
verify_redirect 'http://www.youtube.com/watch?v=oHg5SJYRHA0'
|
|
end
|
|
|
|
def test_openid
|
|
draw do
|
|
match 'openid/login', :via => [:get, :post], :to => "openid#login"
|
|
end
|
|
|
|
get '/openid/login'
|
|
assert_equal 'openid#login', @response.body
|
|
|
|
post '/openid/login'
|
|
assert_equal 'openid#login', @response.body
|
|
end
|
|
|
|
def test_bookmarks
|
|
draw do
|
|
scope "bookmark", :controller => "bookmarks", :as => :bookmark do
|
|
get :new, :path => "build"
|
|
post :create, :path => "create", :as => ""
|
|
put :update
|
|
get :remove, :action => :destroy, :as => :remove
|
|
end
|
|
end
|
|
|
|
get '/bookmark/build'
|
|
assert_equal 'bookmarks#new', @response.body
|
|
assert_equal '/bookmark/build', bookmark_new_path
|
|
|
|
post '/bookmark/create'
|
|
assert_equal 'bookmarks#create', @response.body
|
|
assert_equal '/bookmark/create', bookmark_path
|
|
|
|
put '/bookmark/update'
|
|
assert_equal 'bookmarks#update', @response.body
|
|
assert_equal '/bookmark/update', bookmark_update_path
|
|
|
|
get '/bookmark/remove'
|
|
assert_equal 'bookmarks#destroy', @response.body
|
|
assert_equal '/bookmark/remove', bookmark_remove_path
|
|
end
|
|
|
|
def test_pagemarks
|
|
draw do
|
|
scope "pagemark", :controller => "pagemarks", :as => :pagemark do
|
|
get "new", :path => "build"
|
|
post "create", :as => ""
|
|
put "update"
|
|
get "remove", :action => :destroy, :as => :remove
|
|
end
|
|
end
|
|
|
|
get '/pagemark/build'
|
|
assert_equal 'pagemarks#new', @response.body
|
|
assert_equal '/pagemark/build', pagemark_new_path
|
|
|
|
post '/pagemark/create'
|
|
assert_equal 'pagemarks#create', @response.body
|
|
assert_equal '/pagemark/create', pagemark_path
|
|
|
|
put '/pagemark/update'
|
|
assert_equal 'pagemarks#update', @response.body
|
|
assert_equal '/pagemark/update', pagemark_update_path
|
|
|
|
get '/pagemark/remove'
|
|
assert_equal 'pagemarks#destroy', @response.body
|
|
assert_equal '/pagemark/remove', pagemark_remove_path
|
|
end
|
|
|
|
def test_admin
|
|
draw do
|
|
constraints(:ip => /192\.168\.1\.\d\d\d/) do
|
|
get 'admin' => "queenbee#index"
|
|
end
|
|
|
|
constraints ::TestRoutingMapper::IpRestrictor do
|
|
get 'admin/accounts' => "queenbee#accounts"
|
|
end
|
|
|
|
get 'admin/passwords' => "queenbee#passwords", :constraints => ::TestRoutingMapper::IpRestrictor
|
|
end
|
|
|
|
get '/admin', {}, {'REMOTE_ADDR' => '192.168.1.100'}
|
|
assert_equal 'queenbee#index', @response.body
|
|
|
|
get '/admin', {}, {'REMOTE_ADDR' => '10.0.0.100'}
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
|
|
get '/admin/accounts', {}, {'REMOTE_ADDR' => '192.168.1.100'}
|
|
assert_equal 'queenbee#accounts', @response.body
|
|
|
|
get '/admin/accounts', {}, {'REMOTE_ADDR' => '10.0.0.100'}
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
|
|
get '/admin/passwords', {}, {'REMOTE_ADDR' => '192.168.1.100'}
|
|
assert_equal 'queenbee#passwords', @response.body
|
|
|
|
get '/admin/passwords', {}, {'REMOTE_ADDR' => '10.0.0.100'}
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
end
|
|
|
|
def test_global
|
|
draw do
|
|
controller(:global) do
|
|
get 'global/hide_notice'
|
|
get 'global/export', :to => :export, :as => :export_request
|
|
get '/export/:id/:file', :to => :export, :as => :export_download, :constraints => { :file => /.*/ }
|
|
get 'global/:action'
|
|
end
|
|
end
|
|
|
|
get '/global/dashboard'
|
|
assert_equal 'global#dashboard', @response.body
|
|
|
|
get '/global/export'
|
|
assert_equal 'global#export', @response.body
|
|
|
|
get '/global/hide_notice'
|
|
assert_equal 'global#hide_notice', @response.body
|
|
|
|
get '/export/123/foo.txt'
|
|
assert_equal 'global#export', @response.body
|
|
|
|
assert_equal '/global/export', export_request_path
|
|
assert_equal '/global/hide_notice', global_hide_notice_path
|
|
assert_equal '/export/123/foo.txt', export_download_path(:id => 123, :file => 'foo.txt')
|
|
end
|
|
|
|
def test_local
|
|
draw do
|
|
get "/local/:action", :controller => "local"
|
|
end
|
|
|
|
get '/local/dashboard'
|
|
assert_equal 'local#dashboard', @response.body
|
|
end
|
|
|
|
# tests the use of dup in url_for
|
|
def test_url_for_with_no_side_effects
|
|
draw do
|
|
get "/projects/status(.:format)"
|
|
end
|
|
|
|
# without dup, additional (and possibly unwanted) values will be present in the options (eg. :host)
|
|
original_options = {:controller => 'projects', :action => 'status'}
|
|
options = original_options.dup
|
|
|
|
url_for options
|
|
|
|
# verify that the options passed in have not changed from the original ones
|
|
assert_equal original_options, options
|
|
end
|
|
|
|
def test_url_for_does_not_modify_controller
|
|
draw do
|
|
get "/projects/status(.:format)"
|
|
end
|
|
|
|
controller = '/projects'
|
|
options = {:controller => controller, :action => 'status', :only_path => true}
|
|
url = url_for(options)
|
|
|
|
assert_equal '/projects/status', url
|
|
assert_equal '/projects', controller
|
|
end
|
|
|
|
# tests the arguments modification free version of define_hash_access
|
|
def test_named_route_with_no_side_effects
|
|
draw do
|
|
resources :customers do
|
|
get "profile", :on => :member
|
|
end
|
|
end
|
|
|
|
original_options = { :host => 'test.host' }
|
|
options = original_options.dup
|
|
|
|
profile_customer_url("customer_model", options)
|
|
|
|
# verify that the options passed in have not changed from the original ones
|
|
assert_equal original_options, options
|
|
end
|
|
|
|
def test_projects_status
|
|
draw do
|
|
get "/projects/status(.:format)"
|
|
end
|
|
|
|
assert_equal '/projects/status', url_for(:controller => 'projects', :action => 'status', :only_path => true)
|
|
assert_equal '/projects/status.json', url_for(:controller => 'projects', :action => 'status', :format => 'json', :only_path => true)
|
|
end
|
|
|
|
def test_projects
|
|
draw do
|
|
resources :projects, :controller => :project
|
|
end
|
|
|
|
get '/projects'
|
|
assert_equal 'project#index', @response.body
|
|
assert_equal '/projects', projects_path
|
|
|
|
post '/projects'
|
|
assert_equal 'project#create', @response.body
|
|
|
|
get '/projects.xml'
|
|
assert_equal 'project#index', @response.body
|
|
assert_equal '/projects.xml', projects_path(:format => 'xml')
|
|
|
|
get '/projects/new'
|
|
assert_equal 'project#new', @response.body
|
|
assert_equal '/projects/new', new_project_path
|
|
|
|
get '/projects/new.xml'
|
|
assert_equal 'project#new', @response.body
|
|
assert_equal '/projects/new.xml', new_project_path(:format => 'xml')
|
|
|
|
get '/projects/1'
|
|
assert_equal 'project#show', @response.body
|
|
assert_equal '/projects/1', project_path(:id => '1')
|
|
|
|
get '/projects/1.xml'
|
|
assert_equal 'project#show', @response.body
|
|
assert_equal '/projects/1.xml', project_path(:id => '1', :format => 'xml')
|
|
|
|
get '/projects/1/edit'
|
|
assert_equal 'project#edit', @response.body
|
|
assert_equal '/projects/1/edit', edit_project_path(:id => '1')
|
|
end
|
|
|
|
def test_projects_with_post_action_and_new_path_on_collection
|
|
draw do
|
|
resources :projects, :controller => :project do
|
|
post 'new', :action => 'new', :on => :collection, :as => :new
|
|
end
|
|
end
|
|
|
|
post '/projects/new'
|
|
assert_equal "project#new", @response.body
|
|
assert_equal "/projects/new", new_projects_path
|
|
end
|
|
|
|
def test_projects_involvements
|
|
draw do
|
|
resources :projects, :controller => :project do
|
|
resources :involvements, :attachments
|
|
end
|
|
end
|
|
|
|
get '/projects/1/involvements'
|
|
assert_equal 'involvements#index', @response.body
|
|
assert_equal '/projects/1/involvements', project_involvements_path(:project_id => '1')
|
|
|
|
get '/projects/1/involvements/new'
|
|
assert_equal 'involvements#new', @response.body
|
|
assert_equal '/projects/1/involvements/new', new_project_involvement_path(:project_id => '1')
|
|
|
|
get '/projects/1/involvements/1'
|
|
assert_equal 'involvements#show', @response.body
|
|
assert_equal '/projects/1/involvements/1', project_involvement_path(:project_id => '1', :id => '1')
|
|
|
|
put '/projects/1/involvements/1'
|
|
assert_equal 'involvements#update', @response.body
|
|
|
|
delete '/projects/1/involvements/1'
|
|
assert_equal 'involvements#destroy', @response.body
|
|
|
|
get '/projects/1/involvements/1/edit'
|
|
assert_equal 'involvements#edit', @response.body
|
|
assert_equal '/projects/1/involvements/1/edit', edit_project_involvement_path(:project_id => '1', :id => '1')
|
|
end
|
|
|
|
def test_projects_attachments
|
|
draw do
|
|
resources :projects, :controller => :project do
|
|
resources :involvements, :attachments
|
|
end
|
|
end
|
|
|
|
get '/projects/1/attachments'
|
|
assert_equal 'attachments#index', @response.body
|
|
assert_equal '/projects/1/attachments', project_attachments_path(:project_id => '1')
|
|
end
|
|
|
|
def test_projects_participants
|
|
draw do
|
|
resources :projects, :controller => :project do
|
|
resources :participants do
|
|
put :update_all, :on => :collection
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/participants'
|
|
assert_equal 'participants#index', @response.body
|
|
assert_equal '/projects/1/participants', project_participants_path(:project_id => '1')
|
|
|
|
put '/projects/1/participants/update_all'
|
|
assert_equal 'participants#update_all', @response.body
|
|
assert_equal '/projects/1/participants/update_all', update_all_project_participants_path(:project_id => '1')
|
|
end
|
|
|
|
def test_projects_companies
|
|
draw do
|
|
resources :projects, :controller => :project do
|
|
resources :companies do
|
|
resources :people
|
|
resource :avatar, :controller => :avatar
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/companies'
|
|
assert_equal 'companies#index', @response.body
|
|
assert_equal '/projects/1/companies', project_companies_path(:project_id => '1')
|
|
|
|
get '/projects/1/companies/1/people'
|
|
assert_equal 'people#index', @response.body
|
|
assert_equal '/projects/1/companies/1/people', project_company_people_path(:project_id => '1', :company_id => '1')
|
|
|
|
get '/projects/1/companies/1/avatar'
|
|
assert_equal 'avatar#show', @response.body
|
|
assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1')
|
|
end
|
|
|
|
def test_project_manager
|
|
draw do
|
|
resources :projects do
|
|
resource :manager, :as => :super_manager do
|
|
post :fire
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/manager'
|
|
assert_equal 'managers#show', @response.body
|
|
assert_equal '/projects/1/manager', project_super_manager_path(:project_id => '1')
|
|
|
|
get '/projects/1/manager/new'
|
|
assert_equal 'managers#new', @response.body
|
|
assert_equal '/projects/1/manager/new', new_project_super_manager_path(:project_id => '1')
|
|
|
|
post '/projects/1/manager/fire'
|
|
assert_equal 'managers#fire', @response.body
|
|
assert_equal '/projects/1/manager/fire', fire_project_super_manager_path(:project_id => '1')
|
|
end
|
|
|
|
def test_project_images
|
|
draw do
|
|
resources :projects do
|
|
resources :images, :as => :funny_images do
|
|
post :revise, :on => :member
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/images'
|
|
assert_equal 'images#index', @response.body
|
|
assert_equal '/projects/1/images', project_funny_images_path(:project_id => '1')
|
|
|
|
get '/projects/1/images/new'
|
|
assert_equal 'images#new', @response.body
|
|
assert_equal '/projects/1/images/new', new_project_funny_image_path(:project_id => '1')
|
|
|
|
post '/projects/1/images/1/revise'
|
|
assert_equal 'images#revise', @response.body
|
|
assert_equal '/projects/1/images/1/revise', revise_project_funny_image_path(:project_id => '1', :id => '1')
|
|
end
|
|
|
|
def test_projects_people
|
|
draw do
|
|
resources :projects do
|
|
resources :people do
|
|
nested do
|
|
scope "/:access_token" do
|
|
resource :avatar
|
|
end
|
|
end
|
|
|
|
member do
|
|
put :accessible_projects
|
|
post :resend, :generate_new_password
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/people'
|
|
assert_equal 'people#index', @response.body
|
|
assert_equal '/projects/1/people', project_people_path(:project_id => '1')
|
|
|
|
get '/projects/1/people/1'
|
|
assert_equal 'people#show', @response.body
|
|
assert_equal '/projects/1/people/1', project_person_path(:project_id => '1', :id => '1')
|
|
|
|
get '/projects/1/people/1/7a2dec8/avatar'
|
|
assert_equal 'avatars#show', @response.body
|
|
assert_equal '/projects/1/people/1/7a2dec8/avatar', project_person_avatar_path(:project_id => '1', :person_id => '1', :access_token => '7a2dec8')
|
|
|
|
put '/projects/1/people/1/accessible_projects'
|
|
assert_equal 'people#accessible_projects', @response.body
|
|
assert_equal '/projects/1/people/1/accessible_projects', accessible_projects_project_person_path(:project_id => '1', :id => '1')
|
|
|
|
post '/projects/1/people/1/resend'
|
|
assert_equal 'people#resend', @response.body
|
|
assert_equal '/projects/1/people/1/resend', resend_project_person_path(:project_id => '1', :id => '1')
|
|
|
|
post '/projects/1/people/1/generate_new_password'
|
|
assert_equal 'people#generate_new_password', @response.body
|
|
assert_equal '/projects/1/people/1/generate_new_password', generate_new_password_project_person_path(:project_id => '1', :id => '1')
|
|
end
|
|
|
|
def test_projects_with_resources_path_names
|
|
draw do
|
|
resources_path_names :correlation_indexes => "info_about_correlation_indexes"
|
|
|
|
resources :projects do
|
|
get :correlation_indexes, :on => :collection
|
|
end
|
|
end
|
|
|
|
get '/projects/info_about_correlation_indexes'
|
|
assert_equal 'projects#correlation_indexes', @response.body
|
|
assert_equal '/projects/info_about_correlation_indexes', correlation_indexes_projects_path
|
|
end
|
|
|
|
def test_projects_posts
|
|
draw do
|
|
resources :projects do
|
|
resources :posts do
|
|
get :archive, :toggle_view, :on => :collection
|
|
post :preview, :on => :member
|
|
|
|
resource :subscription
|
|
|
|
resources :comments do
|
|
post :preview, :on => :collection
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/projects/1/posts'
|
|
assert_equal 'posts#index', @response.body
|
|
assert_equal '/projects/1/posts', project_posts_path(:project_id => '1')
|
|
|
|
get '/projects/1/posts/archive'
|
|
assert_equal 'posts#archive', @response.body
|
|
assert_equal '/projects/1/posts/archive', archive_project_posts_path(:project_id => '1')
|
|
|
|
get '/projects/1/posts/toggle_view'
|
|
assert_equal 'posts#toggle_view', @response.body
|
|
assert_equal '/projects/1/posts/toggle_view', toggle_view_project_posts_path(:project_id => '1')
|
|
|
|
post '/projects/1/posts/1/preview'
|
|
assert_equal 'posts#preview', @response.body
|
|
assert_equal '/projects/1/posts/1/preview', preview_project_post_path(:project_id => '1', :id => '1')
|
|
|
|
get '/projects/1/posts/1/subscription'
|
|
assert_equal 'subscriptions#show', @response.body
|
|
assert_equal '/projects/1/posts/1/subscription', project_post_subscription_path(:project_id => '1', :post_id => '1')
|
|
|
|
get '/projects/1/posts/1/comments'
|
|
assert_equal 'comments#index', @response.body
|
|
assert_equal '/projects/1/posts/1/comments', project_post_comments_path(:project_id => '1', :post_id => '1')
|
|
|
|
post '/projects/1/posts/1/comments/preview'
|
|
assert_equal 'comments#preview', @response.body
|
|
assert_equal '/projects/1/posts/1/comments/preview', preview_project_post_comments_path(:project_id => '1', :post_id => '1')
|
|
end
|
|
|
|
def test_replies
|
|
draw do
|
|
resources :replies do
|
|
member do
|
|
put :answer, :to => :mark_as_answer
|
|
delete :answer, :to => :unmark_as_answer
|
|
end
|
|
end
|
|
end
|
|
|
|
put '/replies/1/answer'
|
|
assert_equal 'replies#mark_as_answer', @response.body
|
|
|
|
delete '/replies/1/answer'
|
|
assert_equal 'replies#unmark_as_answer', @response.body
|
|
end
|
|
|
|
def test_resource_routes_with_only_and_except
|
|
draw do
|
|
resources :posts, :only => [:index, :show] do
|
|
resources :comments, :except => :destroy
|
|
end
|
|
end
|
|
|
|
get '/posts'
|
|
assert_equal 'posts#index', @response.body
|
|
assert_equal '/posts', posts_path
|
|
|
|
get '/posts/1'
|
|
assert_equal 'posts#show', @response.body
|
|
assert_equal '/posts/1', post_path(:id => 1)
|
|
|
|
get '/posts/1/comments'
|
|
assert_equal 'comments#index', @response.body
|
|
assert_equal '/posts/1/comments', post_comments_path(:post_id => 1)
|
|
|
|
post '/posts'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
put '/posts/1'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
delete '/posts/1'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
delete '/posts/1/comments'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
end
|
|
|
|
def test_resource_routes_only_create_update_destroy
|
|
draw do
|
|
resource :past, :only => :destroy
|
|
resource :present, :only => :update
|
|
resource :future, :only => :create
|
|
end
|
|
|
|
delete '/past'
|
|
assert_equal 'pasts#destroy', @response.body
|
|
assert_equal '/past', past_path
|
|
|
|
patch '/present'
|
|
assert_equal 'presents#update', @response.body
|
|
assert_equal '/present', present_path
|
|
|
|
put '/present'
|
|
assert_equal 'presents#update', @response.body
|
|
assert_equal '/present', present_path
|
|
|
|
post '/future'
|
|
assert_equal 'futures#create', @response.body
|
|
assert_equal '/future', future_path
|
|
end
|
|
|
|
def test_resources_routes_only_create_update_destroy
|
|
draw do
|
|
resources :relationships, :only => [:create, :destroy]
|
|
resources :friendships, :only => [:update]
|
|
end
|
|
|
|
post '/relationships'
|
|
assert_equal 'relationships#create', @response.body
|
|
assert_equal '/relationships', relationships_path
|
|
|
|
delete '/relationships/1'
|
|
assert_equal 'relationships#destroy', @response.body
|
|
assert_equal '/relationships/1', relationship_path(1)
|
|
|
|
patch '/friendships/1'
|
|
assert_equal 'friendships#update', @response.body
|
|
assert_equal '/friendships/1', friendship_path(1)
|
|
|
|
put '/friendships/1'
|
|
assert_equal 'friendships#update', @response.body
|
|
assert_equal '/friendships/1', friendship_path(1)
|
|
end
|
|
|
|
def test_resource_with_slugs_in_ids
|
|
draw do
|
|
resources :posts
|
|
end
|
|
|
|
get '/posts/rails-rocks'
|
|
assert_equal 'posts#show', @response.body
|
|
assert_equal '/posts/rails-rocks', post_path(:id => 'rails-rocks')
|
|
end
|
|
|
|
def test_resources_for_uncountable_names
|
|
draw do
|
|
resources :sheep do
|
|
get "_it", :on => :member
|
|
end
|
|
end
|
|
|
|
assert_equal '/sheep', sheep_index_path
|
|
assert_equal '/sheep/1', sheep_path(1)
|
|
assert_equal '/sheep/new', new_sheep_path
|
|
assert_equal '/sheep/1/edit', edit_sheep_path(1)
|
|
assert_equal '/sheep/1/_it', _it_sheep_path(1)
|
|
end
|
|
|
|
def test_resource_does_not_modify_passed_options
|
|
options = {:id => /.+?/, :format => /json|xml/}
|
|
draw { resource :user, options }
|
|
assert_equal({:id => /.+?/, :format => /json|xml/}, options)
|
|
end
|
|
|
|
def test_resources_does_not_modify_passed_options
|
|
options = {:id => /.+?/, :format => /json|xml/}
|
|
draw { resources :users, options }
|
|
assert_equal({:id => /.+?/, :format => /json|xml/}, options)
|
|
end
|
|
|
|
def test_path_names
|
|
draw do
|
|
scope 'pt', :as => 'pt' do
|
|
resources :projects, :path_names => { :edit => 'editar', :new => 'novo' }, :path => 'projetos'
|
|
resource :admin, :path_names => { :new => 'novo', :activate => 'ativar' }, :path => 'administrador' do
|
|
put :activate, :on => :member
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/pt/projetos'
|
|
assert_equal 'projects#index', @response.body
|
|
assert_equal '/pt/projetos', pt_projects_path
|
|
|
|
get '/pt/projetos/1/editar'
|
|
assert_equal 'projects#edit', @response.body
|
|
assert_equal '/pt/projetos/1/editar', edit_pt_project_path(1)
|
|
|
|
get '/pt/administrador'
|
|
assert_equal 'admins#show', @response.body
|
|
assert_equal '/pt/administrador', pt_admin_path
|
|
|
|
get '/pt/administrador/novo'
|
|
assert_equal 'admins#new', @response.body
|
|
assert_equal '/pt/administrador/novo', new_pt_admin_path
|
|
|
|
put '/pt/administrador/ativar'
|
|
assert_equal 'admins#activate', @response.body
|
|
assert_equal '/pt/administrador/ativar', activate_pt_admin_path
|
|
end
|
|
|
|
def test_path_option_override
|
|
draw do
|
|
scope 'pt', :as => 'pt' do
|
|
resources :projects, :path_names => { :new => 'novo' }, :path => 'projetos' do
|
|
put :close, :on => :member, :path => 'fechar'
|
|
get :open, :on => :new, :path => 'abrir'
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/pt/projetos/novo/abrir'
|
|
assert_equal 'projects#open', @response.body
|
|
assert_equal '/pt/projetos/novo/abrir', open_new_pt_project_path
|
|
|
|
put '/pt/projetos/1/fechar'
|
|
assert_equal 'projects#close', @response.body
|
|
assert_equal '/pt/projetos/1/fechar', close_pt_project_path(1)
|
|
end
|
|
|
|
def test_sprockets
|
|
draw do
|
|
get 'sprockets.js' => ::TestRoutingMapper::SprocketsApp
|
|
end
|
|
|
|
get '/sprockets.js'
|
|
assert_equal 'javascripts', @response.body
|
|
end
|
|
|
|
def test_update_person_route
|
|
draw do
|
|
get 'people/:id/update', :to => 'people#update', :as => :update_person
|
|
end
|
|
|
|
get '/people/1/update'
|
|
assert_equal 'people#update', @response.body
|
|
|
|
assert_equal '/people/1/update', update_person_path(:id => 1)
|
|
end
|
|
|
|
def test_update_project_person
|
|
draw do
|
|
get '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person
|
|
end
|
|
|
|
get '/projects/1/people/2/update'
|
|
assert_equal 'people#update', @response.body
|
|
|
|
assert_equal '/projects/1/people/2/update', update_project_person_path(:project_id => 1, :id => 2)
|
|
end
|
|
|
|
def test_forum_products
|
|
draw do
|
|
namespace :forum do
|
|
resources :products, :path => '' do
|
|
resources :questions
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/forum'
|
|
assert_equal 'forum/products#index', @response.body
|
|
assert_equal '/forum', forum_products_path
|
|
|
|
get '/forum/basecamp'
|
|
assert_equal 'forum/products#show', @response.body
|
|
assert_equal '/forum/basecamp', forum_product_path(:id => 'basecamp')
|
|
|
|
get '/forum/basecamp/questions'
|
|
assert_equal 'forum/questions#index', @response.body
|
|
assert_equal '/forum/basecamp/questions', forum_product_questions_path(:product_id => 'basecamp')
|
|
|
|
get '/forum/basecamp/questions/1'
|
|
assert_equal 'forum/questions#show', @response.body
|
|
assert_equal '/forum/basecamp/questions/1', forum_product_question_path(:product_id => 'basecamp', :id => 1)
|
|
end
|
|
|
|
def test_articles_perma
|
|
draw do
|
|
get 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article
|
|
end
|
|
|
|
get '/articles/2009/08/18/rails-3'
|
|
assert_equal 'articles#show', @response.body
|
|
|
|
assert_equal '/articles/2009/8/18/rails-3', article_path(:year => 2009, :month => 8, :day => 18, :title => 'rails-3')
|
|
end
|
|
|
|
def test_account_namespace
|
|
draw do
|
|
namespace :account do
|
|
resource :subscription, :credit, :credit_card
|
|
end
|
|
end
|
|
|
|
get '/account/subscription'
|
|
assert_equal 'account/subscriptions#show', @response.body
|
|
assert_equal '/account/subscription', account_subscription_path
|
|
|
|
get '/account/credit'
|
|
assert_equal 'account/credits#show', @response.body
|
|
assert_equal '/account/credit', account_credit_path
|
|
|
|
get '/account/credit_card'
|
|
assert_equal 'account/credit_cards#show', @response.body
|
|
assert_equal '/account/credit_card', account_credit_card_path
|
|
end
|
|
|
|
def test_nested_namespace
|
|
draw do
|
|
namespace :account do
|
|
namespace :admin do
|
|
resource :subscription
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/account/admin/subscription'
|
|
assert_equal 'account/admin/subscriptions#show', @response.body
|
|
assert_equal '/account/admin/subscription', account_admin_subscription_path
|
|
end
|
|
|
|
def test_namespace_nested_in_resources
|
|
draw do
|
|
resources :clients do
|
|
namespace :google do
|
|
resource :account do
|
|
namespace :secret do
|
|
resource :info
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/clients/1/google/account'
|
|
assert_equal '/clients/1/google/account', client_google_account_path(1)
|
|
assert_equal 'google/accounts#show', @response.body
|
|
|
|
get '/clients/1/google/account/secret/info'
|
|
assert_equal '/clients/1/google/account/secret/info', client_google_account_secret_info_path(1)
|
|
assert_equal 'google/secret/infos#show', @response.body
|
|
end
|
|
|
|
def test_namespace_with_options
|
|
draw do
|
|
namespace :users, :path => 'usuarios' do
|
|
root :to => 'home#index'
|
|
end
|
|
end
|
|
|
|
get '/usuarios'
|
|
assert_equal '/usuarios', users_root_path
|
|
assert_equal 'users/home#index', @response.body
|
|
end
|
|
|
|
def test_articles_with_id
|
|
draw do
|
|
controller :articles do
|
|
scope '/articles', :as => 'article' do
|
|
scope :path => '/:title', :title => /[a-z]+/, :as => :with_title do
|
|
get '/:id', :to => :with_id, :as => ""
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/articles/rails/1'
|
|
assert_equal 'articles#with_id', @response.body
|
|
|
|
get '/articles/123/1'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
|
|
assert_equal '/articles/rails/1', article_with_title_path(:title => 'rails', :id => 1)
|
|
end
|
|
|
|
def test_access_token_rooms
|
|
draw do
|
|
scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do
|
|
resources :rooms
|
|
end
|
|
end
|
|
|
|
get '/12345/rooms'
|
|
assert_equal 'rooms#index', @response.body
|
|
|
|
get '/12345/rooms/1'
|
|
assert_equal 'rooms#show', @response.body
|
|
|
|
get '/12345/rooms/1/edit'
|
|
assert_equal 'rooms#edit', @response.body
|
|
end
|
|
|
|
def test_root
|
|
draw do
|
|
root :to => 'projects#index'
|
|
end
|
|
|
|
assert_equal '/', root_path
|
|
get '/'
|
|
assert_equal 'projects#index', @response.body
|
|
end
|
|
|
|
def test_scoped_root
|
|
draw do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
root :to => 'projects#index'
|
|
end
|
|
end
|
|
|
|
assert_equal '/en', root_path(:locale => 'en')
|
|
get '/en'
|
|
assert_equal 'projects#index', @response.body
|
|
end
|
|
|
|
def test_index
|
|
draw do
|
|
get '/info' => 'projects#info', :as => 'info'
|
|
end
|
|
|
|
assert_equal '/info', info_path
|
|
get '/info'
|
|
assert_equal 'projects#info', @response.body
|
|
end
|
|
|
|
def test_match_shorthand_with_no_scope
|
|
draw do
|
|
get 'account/overview'
|
|
end
|
|
|
|
assert_equal '/account/overview', account_overview_path
|
|
get '/account/overview'
|
|
assert_equal 'account#overview', @response.body
|
|
end
|
|
|
|
def test_match_shorthand_inside_namespace
|
|
draw do
|
|
namespace :account do
|
|
get 'shorthand'
|
|
end
|
|
end
|
|
|
|
assert_equal '/account/shorthand', account_shorthand_path
|
|
get '/account/shorthand'
|
|
assert_equal 'account#shorthand', @response.body
|
|
end
|
|
|
|
def test_match_shorthand_inside_namespace_with_controller
|
|
draw do
|
|
namespace :api do
|
|
get "products/list"
|
|
end
|
|
end
|
|
|
|
assert_equal '/api/products/list', api_products_list_path
|
|
get '/api/products/list'
|
|
assert_equal 'api/products#list', @response.body
|
|
end
|
|
|
|
def test_dynamically_generated_helpers_on_collection_do_not_clobber_resources_url_helper
|
|
draw do
|
|
resources :replies do
|
|
collection do
|
|
get 'page/:page' => 'replies#index', :page => %r{\d+}
|
|
get ':page' => 'replies#index', :page => %r{\d+}
|
|
end
|
|
end
|
|
end
|
|
|
|
assert_equal '/replies', replies_path
|
|
end
|
|
|
|
def test_scoped_controller_with_namespace_and_action
|
|
draw do
|
|
namespace :account do
|
|
get ':action/callback', :action => /twitter|github/, :to => "callbacks", :as => :callback
|
|
end
|
|
end
|
|
|
|
assert_equal '/account/twitter/callback', account_callback_path("twitter")
|
|
get '/account/twitter/callback'
|
|
assert_equal 'account/callbacks#twitter', @response.body
|
|
|
|
get '/account/whatever/callback'
|
|
assert_equal 'Not Found', @response.body
|
|
end
|
|
|
|
def test_convention_match_nested_and_with_leading_slash
|
|
draw do
|
|
get '/account/nested/overview'
|
|
end
|
|
|
|
assert_equal '/account/nested/overview', account_nested_overview_path
|
|
get '/account/nested/overview'
|
|
assert_equal 'account/nested#overview', @response.body
|
|
end
|
|
|
|
def test_convention_with_explicit_end
|
|
draw do
|
|
get 'sign_in' => "sessions#new"
|
|
end
|
|
|
|
get '/sign_in'
|
|
assert_equal 'sessions#new', @response.body
|
|
assert_equal '/sign_in', sign_in_path
|
|
end
|
|
|
|
def test_redirect_with_complete_url_and_status
|
|
draw do
|
|
get 'account/google' => redirect('http://www.google.com/', :status => 302)
|
|
end
|
|
|
|
get '/account/google'
|
|
verify_redirect 'http://www.google.com/', 302
|
|
end
|
|
|
|
def test_redirect_with_port
|
|
draw do
|
|
get 'account/login', :to => redirect("/login")
|
|
end
|
|
|
|
previous_host, self.host = self.host, 'www.example.com:3000'
|
|
|
|
get '/account/login'
|
|
verify_redirect 'http://www.example.com:3000/login'
|
|
ensure
|
|
self.host = previous_host
|
|
end
|
|
|
|
def test_normalize_namespaced_matches
|
|
draw do
|
|
namespace :account do
|
|
get 'description', :to => :description, :as => "description"
|
|
end
|
|
end
|
|
|
|
assert_equal '/account/description', account_description_path
|
|
|
|
get '/account/description'
|
|
assert_equal 'account#description', @response.body
|
|
end
|
|
|
|
def test_namespaced_roots
|
|
draw do
|
|
namespace :account do
|
|
root :to => "account#index"
|
|
end
|
|
end
|
|
|
|
assert_equal '/account', account_root_path
|
|
get '/account'
|
|
assert_equal 'account/account#index', @response.body
|
|
end
|
|
|
|
def test_optional_scoped_root
|
|
draw do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
root :to => 'projects#index'
|
|
end
|
|
end
|
|
|
|
assert_equal '/en', root_path("en")
|
|
get '/en'
|
|
assert_equal 'projects#index', @response.body
|
|
end
|
|
|
|
def test_optional_scoped_path
|
|
draw do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
resources :descriptions
|
|
end
|
|
end
|
|
|
|
assert_equal '/en/descriptions', descriptions_path("en")
|
|
assert_equal '/descriptions', descriptions_path(nil)
|
|
assert_equal '/en/descriptions/1', description_path("en", 1)
|
|
assert_equal '/descriptions/1', description_path(nil, 1)
|
|
|
|
get '/en/descriptions'
|
|
assert_equal 'descriptions#index', @response.body
|
|
|
|
get '/descriptions'
|
|
assert_equal 'descriptions#index', @response.body
|
|
|
|
get '/en/descriptions/1'
|
|
assert_equal 'descriptions#show', @response.body
|
|
|
|
get '/descriptions/1'
|
|
assert_equal 'descriptions#show', @response.body
|
|
end
|
|
|
|
def test_nested_optional_scoped_path
|
|
draw do
|
|
namespace :admin do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
resources :descriptions
|
|
end
|
|
end
|
|
end
|
|
|
|
assert_equal '/admin/en/descriptions', admin_descriptions_path("en")
|
|
assert_equal '/admin/descriptions', admin_descriptions_path(nil)
|
|
assert_equal '/admin/en/descriptions/1', admin_description_path("en", 1)
|
|
assert_equal '/admin/descriptions/1', admin_description_path(nil, 1)
|
|
|
|
get '/admin/en/descriptions'
|
|
assert_equal 'admin/descriptions#index', @response.body
|
|
|
|
get '/admin/descriptions'
|
|
assert_equal 'admin/descriptions#index', @response.body
|
|
|
|
get '/admin/en/descriptions/1'
|
|
assert_equal 'admin/descriptions#show', @response.body
|
|
|
|
get '/admin/descriptions/1'
|
|
assert_equal 'admin/descriptions#show', @response.body
|
|
end
|
|
|
|
def test_nested_optional_path_shorthand
|
|
draw do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
get "registrations/new"
|
|
end
|
|
end
|
|
|
|
get '/registrations/new'
|
|
assert_nil @request.params[:locale]
|
|
|
|
get '/en/registrations/new'
|
|
assert_equal 'en', @request.params[:locale]
|
|
end
|
|
|
|
def test_default_params
|
|
draw do
|
|
get 'inline_pages/(:id)', :to => 'pages#show', :id => 'home'
|
|
get 'default_pages/(:id)', :to => 'pages#show', :defaults => { :id => 'home' }
|
|
|
|
defaults :id => 'home' do
|
|
get 'scoped_pages/(:id)', :to => 'pages#show'
|
|
end
|
|
end
|
|
|
|
get '/inline_pages'
|
|
assert_equal 'home', @request.params[:id]
|
|
|
|
get '/default_pages'
|
|
assert_equal 'home', @request.params[:id]
|
|
|
|
get '/scoped_pages'
|
|
assert_equal 'home', @request.params[:id]
|
|
end
|
|
|
|
def test_resource_constraints
|
|
draw do
|
|
resources :products, :constraints => { :id => /\d{4}/ } do
|
|
root :to => "products#root"
|
|
get :favorite, :on => :collection
|
|
resources :images
|
|
end
|
|
|
|
resource :dashboard, :constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
|
|
end
|
|
|
|
get '/products/1'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
get '/products'
|
|
assert_equal 'products#root', @response.body
|
|
get '/products/favorite'
|
|
assert_equal 'products#favorite', @response.body
|
|
get '/products/0001'
|
|
assert_equal 'products#show', @response.body
|
|
|
|
get '/products/1/images'
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
get '/products/0001/images'
|
|
assert_equal 'images#index', @response.body
|
|
get '/products/0001/images/0001'
|
|
assert_equal 'images#show', @response.body
|
|
|
|
get '/dashboard', {}, {'REMOTE_ADDR' => '10.0.0.100'}
|
|
assert_equal 'pass', @response.headers['X-Cascade']
|
|
get '/dashboard', {}, {'REMOTE_ADDR' => '192.168.1.100'}
|
|
assert_equal 'dashboards#show', @response.body
|
|
end
|
|
|
|
def test_root_works_in_the_resources_scope
|
|
draw do
|
|
resources :products do
|
|
root :to => "products#root"
|
|
end
|
|
end
|
|
|
|
get '/products'
|
|
assert_equal 'products#root', @response.body
|
|
assert_equal '/products', products_root_path
|
|
end
|
|
|
|
def test_module_scope
|
|
draw do
|
|
resource :token, :module => :api
|
|
end
|
|
|
|
get '/token'
|
|
assert_equal 'api/tokens#show', @response.body
|
|
assert_equal '/token', token_path
|
|
end
|
|
|
|
def test_path_scope
|
|
draw do
|
|
scope :path => 'api' do
|
|
resource :me
|
|
get '/' => 'mes#index'
|
|
end
|
|
end
|
|
|
|
get '/api/me'
|
|
assert_equal 'mes#show', @response.body
|
|
assert_equal '/api/me', me_path
|
|
|
|
get '/api'
|
|
assert_equal 'mes#index', @response.body
|
|
end
|
|
|
|
def test_symbol_scope
|
|
draw do
|
|
scope :path => 'api' do
|
|
scope :v2 do
|
|
resource :me, as: 'v2_me'
|
|
get '/' => 'mes#index'
|
|
end
|
|
|
|
scope :v3, :admin do
|
|
resource :me, as: 'v3_me'
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/api/v2/me'
|
|
assert_equal 'mes#show', @response.body
|
|
assert_equal '/api/v2/me', v2_me_path
|
|
|
|
get '/api/v2'
|
|
assert_equal 'mes#index', @response.body
|
|
|
|
get '/api/v3/admin/me'
|
|
assert_equal 'mes#show', @response.body
|
|
end
|
|
|
|
def test_url_generator_for_generic_route
|
|
draw do
|
|
get "whatever/:controller(/:action(/:id))"
|
|
end
|
|
|
|
get 'whatever/foo/bar'
|
|
assert_equal 'foo#bar', @response.body
|
|
|
|
assert_equal 'http://www.example.com/whatever/foo/bar/1',
|
|
url_for(:controller => "foo", :action => "bar", :id => 1)
|
|
end
|
|
|
|
def test_url_generator_for_namespaced_generic_route
|
|
draw do
|
|
get "whatever/:controller(/:action(/:id))", :id => /\d+/
|
|
end
|
|
|
|
get 'whatever/foo/bar/show'
|
|
assert_equal 'foo/bar#show', @response.body
|
|
|
|
get 'whatever/foo/bar/show/1'
|
|
assert_equal 'foo/bar#show', @response.body
|
|
|
|
assert_equal 'http://www.example.com/whatever/foo/bar/show',
|
|
url_for(:controller => "foo/bar", :action => "show")
|
|
|
|
assert_equal 'http://www.example.com/whatever/foo/bar/show/1',
|
|
url_for(:controller => "foo/bar", :action => "show", :id => '1')
|
|
end
|
|
|
|
def test_resource_new_actions
|
|
draw do
|
|
resources :replies do
|
|
new do
|
|
post :preview
|
|
end
|
|
end
|
|
|
|
scope 'pt', :as => 'pt' do
|
|
resources :projects, :path_names => { :new => 'novo' }, :path => 'projetos' do
|
|
post :preview, :on => :new
|
|
end
|
|
|
|
resource :admin, :path_names => { :new => 'novo' }, :path => 'administrador' do
|
|
post :preview, :on => :new
|
|
end
|
|
|
|
resources :products, :path_names => { :new => 'novo' } do
|
|
new do
|
|
post :preview
|
|
end
|
|
end
|
|
end
|
|
|
|
resource :profile do
|
|
new do
|
|
post :preview
|
|
end
|
|
end
|
|
end
|
|
|
|
assert_equal '/replies/new/preview', preview_new_reply_path
|
|
assert_equal '/pt/projetos/novo/preview', preview_new_pt_project_path
|
|
assert_equal '/pt/administrador/novo/preview', preview_new_pt_admin_path
|
|
assert_equal '/pt/products/novo/preview', preview_new_pt_product_path
|
|
assert_equal '/profile/new/preview', preview_new_profile_path
|
|
|
|
post '/replies/new/preview'
|
|
assert_equal 'replies#preview', @response.body
|
|
|
|
post '/pt/projetos/novo/preview'
|
|
assert_equal 'projects#preview', @response.body
|
|
|
|
post '/pt/administrador/novo/preview'
|
|
assert_equal 'admins#preview', @response.body
|
|
|
|
post '/pt/products/novo/preview'
|
|
assert_equal 'products#preview', @response.body
|
|
|
|
post '/profile/new/preview'
|
|
assert_equal 'profiles#preview', @response.body
|
|
end
|
|
|
|
def test_resource_merges_options_from_scope
|
|
draw do
|
|
scope :only => :show do
|
|
resource :account
|
|
end
|
|
end
|
|
|
|
assert_raise(NoMethodError) { new_account_path }
|
|
|
|
get '/account/new'
|
|
assert_equal 404, status
|
|
end
|
|
|
|
def test_resources_merges_options_from_scope
|
|
draw do
|
|
scope :only => [:index, :show] do
|
|
resources :products do
|
|
resources :images
|
|
end
|
|
end
|
|
end
|
|
|
|
assert_raise(NoMethodError) { edit_product_path('1') }
|
|
|
|
get '/products/1/edit'
|
|
assert_equal 404, status
|
|
|
|
assert_raise(NoMethodError) { edit_product_image_path('1', '2') }
|
|
|
|
post '/products/1/images/2/edit'
|
|
assert_equal 404, status
|
|
end
|
|
|
|
def test_shallow_nested_resources
|
|
draw do
|
|
shallow do
|
|
namespace :api do
|
|
resources :teams do
|
|
resources :players
|
|
resource :captain
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :threads, :shallow => true do
|
|
resource :owner
|
|
resources :messages do
|
|
resources :comments do
|
|
member do
|
|
post :preview
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/api/teams'
|
|
assert_equal 'api/teams#index', @response.body
|
|
assert_equal '/api/teams', api_teams_path
|
|
|
|
get '/api/teams/new'
|
|
assert_equal 'api/teams#new', @response.body
|
|
assert_equal '/api/teams/new', new_api_team_path
|
|
|
|
get '/api/teams/1'
|
|
assert_equal 'api/teams#show', @response.body
|
|
assert_equal '/api/teams/1', api_team_path(:id => '1')
|
|
|
|
get '/api/teams/1/edit'
|
|
assert_equal 'api/teams#edit', @response.body
|
|
assert_equal '/api/teams/1/edit', edit_api_team_path(:id => '1')
|
|
|
|
get '/api/teams/1/players'
|
|
assert_equal 'api/players#index', @response.body
|
|
assert_equal '/api/teams/1/players', api_team_players_path(:team_id => '1')
|
|
|
|
get '/api/teams/1/players/new'
|
|
assert_equal 'api/players#new', @response.body
|
|
assert_equal '/api/teams/1/players/new', new_api_team_player_path(:team_id => '1')
|
|
|
|
get '/api/players/2'
|
|
assert_equal 'api/players#show', @response.body
|
|
assert_equal '/api/players/2', api_player_path(:id => '2')
|
|
|
|
get '/api/players/2/edit'
|
|
assert_equal 'api/players#edit', @response.body
|
|
assert_equal '/api/players/2/edit', edit_api_player_path(:id => '2')
|
|
|
|
get '/api/teams/1/captain'
|
|
assert_equal 'api/captains#show', @response.body
|
|
assert_equal '/api/teams/1/captain', api_team_captain_path(:team_id => '1')
|
|
|
|
get '/api/teams/1/captain/new'
|
|
assert_equal 'api/captains#new', @response.body
|
|
assert_equal '/api/teams/1/captain/new', new_api_team_captain_path(:team_id => '1')
|
|
|
|
get '/api/teams/1/captain/edit'
|
|
assert_equal 'api/captains#edit', @response.body
|
|
assert_equal '/api/teams/1/captain/edit', edit_api_team_captain_path(:team_id => '1')
|
|
|
|
get '/threads'
|
|
assert_equal 'threads#index', @response.body
|
|
assert_equal '/threads', threads_path
|
|
|
|
get '/threads/new'
|
|
assert_equal 'threads#new', @response.body
|
|
assert_equal '/threads/new', new_thread_path
|
|
|
|
get '/threads/1'
|
|
assert_equal 'threads#show', @response.body
|
|
assert_equal '/threads/1', thread_path(:id => '1')
|
|
|
|
get '/threads/1/edit'
|
|
assert_equal 'threads#edit', @response.body
|
|
assert_equal '/threads/1/edit', edit_thread_path(:id => '1')
|
|
|
|
get '/threads/1/owner'
|
|
assert_equal 'owners#show', @response.body
|
|
assert_equal '/threads/1/owner', thread_owner_path(:thread_id => '1')
|
|
|
|
get '/threads/1/messages'
|
|
assert_equal 'messages#index', @response.body
|
|
assert_equal '/threads/1/messages', thread_messages_path(:thread_id => '1')
|
|
|
|
get '/threads/1/messages/new'
|
|
assert_equal 'messages#new', @response.body
|
|
assert_equal '/threads/1/messages/new', new_thread_message_path(:thread_id => '1')
|
|
|
|
get '/messages/2'
|
|
assert_equal 'messages#show', @response.body
|
|
assert_equal '/messages/2', message_path(:id => '2')
|
|
|
|
get '/messages/2/edit'
|
|
assert_equal 'messages#edit', @response.body
|
|
assert_equal '/messages/2/edit', edit_message_path(:id => '2')
|
|
|
|
get '/messages/2/comments'
|
|
assert_equal 'comments#index', @response.body
|
|
assert_equal '/messages/2/comments', message_comments_path(:message_id => '2')
|
|
|
|
get '/messages/2/comments/new'
|
|
assert_equal 'comments#new', @response.body
|
|
assert_equal '/messages/2/comments/new', new_message_comment_path(:message_id => '2')
|
|
|
|
get '/comments/3'
|
|
assert_equal 'comments#show', @response.body
|
|
assert_equal '/comments/3', comment_path(:id => '3')
|
|
|
|
get '/comments/3/edit'
|
|
assert_equal 'comments#edit', @response.body
|
|
assert_equal '/comments/3/edit', edit_comment_path(:id => '3')
|
|
|
|
post '/comments/3/preview'
|
|
assert_equal 'comments#preview', @response.body
|
|
assert_equal '/comments/3/preview', preview_comment_path(:id => '3')
|
|
end
|
|
|
|
def test_shallow_nested_resources_within_scope
|
|
draw do
|
|
scope '/hello' do
|
|
shallow do
|
|
resources :notes do
|
|
resources :trackbacks
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/hello/notes/1/trackbacks'
|
|
assert_equal 'trackbacks#index', @response.body
|
|
assert_equal '/hello/notes/1/trackbacks', note_trackbacks_path(:note_id => 1)
|
|
|
|
get '/hello/notes/1/edit'
|
|
assert_equal 'notes#edit', @response.body
|
|
assert_equal '/hello/notes/1/edit', edit_note_path(:id => '1')
|
|
|
|
get '/hello/notes/1/trackbacks/new'
|
|
assert_equal 'trackbacks#new', @response.body
|
|
assert_equal '/hello/notes/1/trackbacks/new', new_note_trackback_path(:note_id => 1)
|
|
|
|
get '/hello/trackbacks/1'
|
|
assert_equal 'trackbacks#show', @response.body
|
|
assert_equal '/hello/trackbacks/1', trackback_path(:id => '1')
|
|
|
|
get '/hello/trackbacks/1/edit'
|
|
assert_equal 'trackbacks#edit', @response.body
|
|
assert_equal '/hello/trackbacks/1/edit', edit_trackback_path(:id => '1')
|
|
|
|
put '/hello/trackbacks/1'
|
|
assert_equal 'trackbacks#update', @response.body
|
|
|
|
post '/hello/notes/1/trackbacks'
|
|
assert_equal 'trackbacks#create', @response.body
|
|
|
|
delete '/hello/trackbacks/1'
|
|
assert_equal 'trackbacks#destroy', @response.body
|
|
|
|
get '/hello/notes'
|
|
assert_equal 'notes#index', @response.body
|
|
|
|
post '/hello/notes'
|
|
assert_equal 'notes#create', @response.body
|
|
|
|
get '/hello/notes/new'
|
|
assert_equal 'notes#new', @response.body
|
|
assert_equal '/hello/notes/new', new_note_path
|
|
|
|
get '/hello/notes/1'
|
|
assert_equal 'notes#show', @response.body
|
|
assert_equal '/hello/notes/1', note_path(:id => 1)
|
|
|
|
put '/hello/notes/1'
|
|
assert_equal 'notes#update', @response.body
|
|
|
|
delete '/hello/notes/1'
|
|
assert_equal 'notes#destroy', @response.body
|
|
end
|
|
|
|
def test_custom_resource_routes_are_scoped
|
|
draw do
|
|
resources :customers do
|
|
get :recent, :on => :collection
|
|
get "profile", :on => :member
|
|
get "secret/profile" => "customers#secret", :on => :member
|
|
post "preview" => "customers#preview", :as => :another_preview, :on => :new
|
|
resource :avatar do
|
|
get "thumbnail" => "avatars#thumbnail", :as => :thumbnail, :on => :member
|
|
end
|
|
resources :invoices do
|
|
get "outstanding" => "invoices#outstanding", :on => :collection
|
|
get "overdue", :to => :overdue, :on => :collection
|
|
get "print" => "invoices#print", :as => :print, :on => :member
|
|
post "preview" => "invoices#preview", :as => :preview, :on => :new
|
|
end
|
|
resources :notes, :shallow => true do
|
|
get "preview" => "notes#preview", :as => :preview, :on => :new
|
|
get "print" => "notes#print", :as => :print, :on => :member
|
|
end
|
|
end
|
|
|
|
namespace :api do
|
|
resources :customers do
|
|
get "recent" => "customers#recent", :as => :recent, :on => :collection
|
|
get "profile" => "customers#profile", :as => :profile, :on => :member
|
|
post "preview" => "customers#preview", :as => :preview, :on => :new
|
|
end
|
|
end
|
|
end
|
|
|
|
assert_equal '/customers/recent', recent_customers_path
|
|
assert_equal '/customers/1/profile', profile_customer_path(:id => '1')
|
|
assert_equal '/customers/1/secret/profile', secret_profile_customer_path(:id => '1')
|
|
assert_equal '/customers/new/preview', another_preview_new_customer_path
|
|
assert_equal '/customers/1/avatar/thumbnail.jpg', thumbnail_customer_avatar_path(:customer_id => '1', :format => :jpg)
|
|
assert_equal '/customers/1/invoices/outstanding', outstanding_customer_invoices_path(:customer_id => '1')
|
|
assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')
|
|
assert_equal '/customers/1/invoices/new/preview', preview_new_customer_invoice_path(:customer_id => '1')
|
|
assert_equal '/customers/1/notes/new/preview', preview_new_customer_note_path(:customer_id => '1')
|
|
assert_equal '/notes/1/print', print_note_path(:id => '1')
|
|
assert_equal '/api/customers/recent', recent_api_customers_path
|
|
assert_equal '/api/customers/1/profile', profile_api_customer_path(:id => '1')
|
|
assert_equal '/api/customers/new/preview', preview_new_api_customer_path
|
|
|
|
get '/customers/1/invoices/overdue'
|
|
assert_equal 'invoices#overdue', @response.body
|
|
|
|
get '/customers/1/secret/profile'
|
|
assert_equal 'customers#secret', @response.body
|
|
end
|
|
|
|
def test_shallow_nested_routes_ignore_module
|
|
draw do
|
|
scope :module => :api do
|
|
resources :errors, :shallow => true do
|
|
resources :notices
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/errors/1/notices'
|
|
assert_equal 'api/notices#index', @response.body
|
|
assert_equal '/errors/1/notices', error_notices_path(:error_id => '1')
|
|
|
|
get '/notices/1'
|
|
assert_equal 'api/notices#show', @response.body
|
|
assert_equal '/notices/1', notice_path(:id => '1')
|
|
end
|
|
|
|
def test_non_greedy_regexp
|
|
draw do
|
|
namespace :api do
|
|
scope(':version', :version => /.+/) do
|
|
resources :users, :id => /.+?/, :format => /json|xml/
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/api/1.0/users'
|
|
assert_equal 'api/users#index', @response.body
|
|
assert_equal '/api/1.0/users', api_users_path(:version => '1.0')
|
|
|
|
get '/api/1.0/users.json'
|
|
assert_equal 'api/users#index', @response.body
|
|
assert_equal true, @request.format.json?
|
|
assert_equal '/api/1.0/users.json', api_users_path(:version => '1.0', :format => :json)
|
|
|
|
get '/api/1.0/users/first.last'
|
|
assert_equal 'api/users#show', @response.body
|
|
assert_equal 'first.last', @request.params[:id]
|
|
assert_equal '/api/1.0/users/first.last', api_user_path(:version => '1.0', :id => 'first.last')
|
|
|
|
get '/api/1.0/users/first.last.xml'
|
|
assert_equal 'api/users#show', @response.body
|
|
assert_equal 'first.last', @request.params[:id]
|
|
assert_equal true, @request.format.xml?
|
|
assert_equal '/api/1.0/users/first.last.xml', api_user_path(:version => '1.0', :id => 'first.last', :format => :xml)
|
|
end
|
|
|
|
def test_glob_parameter_accepts_regexp
|
|
draw do
|
|
get '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/
|
|
end
|
|
|
|
get '/en/path/to/existing/file.html'
|
|
assert_equal 200, @response.status
|
|
end
|
|
|
|
def test_resources_controller_name_is_not_pluralized
|
|
draw do
|
|
resources :content
|
|
end
|
|
|
|
get '/content'
|
|
assert_equal 'content#index', @response.body
|
|
end
|
|
|
|
def test_url_generator_for_optional_prefix_dynamic_segment
|
|
draw do
|
|
get "(/:username)/followers" => "followers#index"
|
|
end
|
|
|
|
get '/bob/followers'
|
|
assert_equal 'followers#index', @response.body
|
|
assert_equal 'http://www.example.com/bob/followers',
|
|
url_for(:controller => "followers", :action => "index", :username => "bob")
|
|
|
|
get '/followers'
|
|
assert_equal 'followers#index', @response.body
|
|
assert_equal 'http://www.example.com/followers',
|
|
url_for(:controller => "followers", :action => "index", :username => nil)
|
|
end
|
|
|
|
def test_url_generator_for_optional_suffix_static_and_dynamic_segment
|
|
draw do
|
|
get "/groups(/user/:username)" => "groups#index"
|
|
end
|
|
|
|
get '/groups/user/bob'
|
|
assert_equal 'groups#index', @response.body
|
|
assert_equal 'http://www.example.com/groups/user/bob',
|
|
url_for(:controller => "groups", :action => "index", :username => "bob")
|
|
|
|
get '/groups'
|
|
assert_equal 'groups#index', @response.body
|
|
assert_equal 'http://www.example.com/groups',
|
|
url_for(:controller => "groups", :action => "index", :username => nil)
|
|
end
|
|
|
|
def test_url_generator_for_optional_prefix_static_and_dynamic_segment
|
|
draw do
|
|
get "(/user/:username)/photos" => "photos#index"
|
|
end
|
|
|
|
get 'user/bob/photos'
|
|
assert_equal 'photos#index', @response.body
|
|
assert_equal 'http://www.example.com/user/bob/photos',
|
|
url_for(:controller => "photos", :action => "index", :username => "bob")
|
|
|
|
get 'photos'
|
|
assert_equal 'photos#index', @response.body
|
|
assert_equal 'http://www.example.com/photos',
|
|
url_for(:controller => "photos", :action => "index", :username => nil)
|
|
end
|
|
|
|
def test_url_recognition_for_optional_static_segments
|
|
draw do
|
|
scope '(groups)' do
|
|
scope '(discussions)' do
|
|
resources :messages
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/groups/discussions/messages'
|
|
assert_equal 'messages#index', @response.body
|
|
|
|
get '/groups/discussions/messages/1'
|
|
assert_equal 'messages#show', @response.body
|
|
|
|
get '/groups/messages'
|
|
assert_equal 'messages#index', @response.body
|
|
|
|
get '/groups/messages/1'
|
|
assert_equal 'messages#show', @response.body
|
|
|
|
get '/discussions/messages'
|
|
assert_equal 'messages#index', @response.body
|
|
|
|
get '/discussions/messages/1'
|
|
assert_equal 'messages#show', @response.body
|
|
|
|
get '/messages'
|
|
assert_equal 'messages#index', @response.body
|
|
|
|
get '/messages/1'
|
|
assert_equal 'messages#show', @response.body
|
|
end
|
|
|
|
def test_router_removes_invalid_conditions
|
|
draw do
|
|
scope :constraints => { :id => /\d+/ } do
|
|
get '/tickets', :to => 'tickets#index', :as => :tickets
|
|
end
|
|
end
|
|
|
|
get '/tickets'
|
|
assert_equal 'tickets#index', @response.body
|
|
assert_equal '/tickets', tickets_path
|
|
end
|
|
|
|
def test_constraints_are_merged_from_scope
|
|
draw do
|
|
scope :constraints => { :id => /\d{4}/ } do
|
|
resources :movies do
|
|
resources :reviews
|
|
resource :trailer
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/movies/0001'
|
|
assert_equal 'movies#show', @response.body
|
|
assert_equal '/movies/0001', movie_path(:id => '0001')
|
|
|
|
get '/movies/00001'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raises(ActionController::UrlGenerationError){ movie_path(:id => '00001') }
|
|
|
|
get '/movies/0001/reviews'
|
|
assert_equal 'reviews#index', @response.body
|
|
assert_equal '/movies/0001/reviews', movie_reviews_path(:movie_id => '0001')
|
|
|
|
get '/movies/00001/reviews'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raises(ActionController::UrlGenerationError){ movie_reviews_path(:movie_id => '00001') }
|
|
|
|
get '/movies/0001/reviews/0001'
|
|
assert_equal 'reviews#show', @response.body
|
|
assert_equal '/movies/0001/reviews/0001', movie_review_path(:movie_id => '0001', :id => '0001')
|
|
|
|
get '/movies/00001/reviews/0001'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raises(ActionController::UrlGenerationError){ movie_path(:movie_id => '00001', :id => '00001') }
|
|
|
|
get '/movies/0001/trailer'
|
|
assert_equal 'trailers#show', @response.body
|
|
assert_equal '/movies/0001/trailer', movie_trailer_path(:movie_id => '0001')
|
|
|
|
get '/movies/00001/trailer'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raises(ActionController::UrlGenerationError){ movie_trailer_path(:movie_id => '00001') }
|
|
end
|
|
|
|
def test_only_should_be_read_from_scope
|
|
draw do
|
|
scope :only => [:index, :show] do
|
|
namespace :only do
|
|
resources :clubs do
|
|
resources :players
|
|
resource :chairman
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/clubs'
|
|
assert_equal 'only/clubs#index', @response.body
|
|
assert_equal '/only/clubs', only_clubs_path
|
|
|
|
get '/only/clubs/1/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_only_club_path(:id => '1') }
|
|
|
|
get '/only/clubs/1/players'
|
|
assert_equal 'only/players#index', @response.body
|
|
assert_equal '/only/clubs/1/players', only_club_players_path(:club_id => '1')
|
|
|
|
get '/only/clubs/1/players/2/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_only_club_player_path(:club_id => '1', :id => '2') }
|
|
|
|
get '/only/clubs/1/chairman'
|
|
assert_equal 'only/chairmen#show', @response.body
|
|
assert_equal '/only/clubs/1/chairman', only_club_chairman_path(:club_id => '1')
|
|
|
|
get '/only/clubs/1/chairman/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_only_club_chairman_path(:club_id => '1') }
|
|
end
|
|
|
|
def test_except_should_be_read_from_scope
|
|
draw do
|
|
scope :except => [:new, :create, :edit, :update, :destroy] do
|
|
namespace :except do
|
|
resources :clubs do
|
|
resources :players
|
|
resource :chairman
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/clubs'
|
|
assert_equal 'except/clubs#index', @response.body
|
|
assert_equal '/except/clubs', except_clubs_path
|
|
|
|
get '/except/clubs/1/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_except_club_path(:id => '1') }
|
|
|
|
get '/except/clubs/1/players'
|
|
assert_equal 'except/players#index', @response.body
|
|
assert_equal '/except/clubs/1/players', except_club_players_path(:club_id => '1')
|
|
|
|
get '/except/clubs/1/players/2/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_except_club_player_path(:club_id => '1', :id => '2') }
|
|
|
|
get '/except/clubs/1/chairman'
|
|
assert_equal 'except/chairmen#show', @response.body
|
|
assert_equal '/except/clubs/1/chairman', except_club_chairman_path(:club_id => '1')
|
|
|
|
get '/except/clubs/1/chairman/edit'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { edit_except_club_chairman_path(:club_id => '1') }
|
|
end
|
|
|
|
def test_only_option_should_override_scope
|
|
draw do
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/sectors'
|
|
assert_equal 'only/sectors#index', @response.body
|
|
assert_equal '/only/sectors', only_sectors_path
|
|
|
|
get '/only/sectors/1'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { only_sector_path(:id => '1') }
|
|
end
|
|
|
|
def test_only_option_should_not_inherit
|
|
draw do
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index do
|
|
resources :companies
|
|
resource :leader
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/sectors/1/companies/2'
|
|
assert_equal 'only/companies#show', @response.body
|
|
assert_equal '/only/sectors/1/companies/2', only_sector_company_path(:sector_id => '1', :id => '2')
|
|
|
|
get '/only/sectors/1/leader'
|
|
assert_equal 'only/leaders#show', @response.body
|
|
assert_equal '/only/sectors/1/leader', only_sector_leader_path(:sector_id => '1')
|
|
end
|
|
|
|
def test_except_option_should_override_scope
|
|
draw do
|
|
scope :except => :index do
|
|
namespace :except do
|
|
resources :sectors, :except => [:show, :update, :destroy]
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/sectors'
|
|
assert_equal 'except/sectors#index', @response.body
|
|
assert_equal '/except/sectors', except_sectors_path
|
|
|
|
get '/except/sectors/1'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { except_sector_path(:id => '1') }
|
|
end
|
|
|
|
def test_except_option_should_not_inherit
|
|
draw do
|
|
scope :except => :index do
|
|
namespace :except do
|
|
resources :sectors, :except => [:show, :update, :destroy] do
|
|
resources :companies
|
|
resource :leader
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/sectors/1/companies/2'
|
|
assert_equal 'except/companies#show', @response.body
|
|
assert_equal '/except/sectors/1/companies/2', except_sector_company_path(:sector_id => '1', :id => '2')
|
|
|
|
get '/except/sectors/1/leader'
|
|
assert_equal 'except/leaders#show', @response.body
|
|
assert_equal '/except/sectors/1/leader', except_sector_leader_path(:sector_id => '1')
|
|
end
|
|
|
|
def test_except_option_should_override_scoped_only
|
|
draw do
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index do
|
|
resources :managers, :except => [:show, :update, :destroy]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/sectors/1/managers'
|
|
assert_equal 'only/managers#index', @response.body
|
|
assert_equal '/only/sectors/1/managers', only_sector_managers_path(:sector_id => '1')
|
|
|
|
get '/only/sectors/1/managers/2'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { only_sector_manager_path(:sector_id => '1', :id => '2') }
|
|
end
|
|
|
|
def test_only_option_should_override_scoped_except
|
|
draw do
|
|
scope :except => :index do
|
|
namespace :except do
|
|
resources :sectors, :except => [:show, :update, :destroy] do
|
|
resources :managers, :only => :index
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/sectors/1/managers'
|
|
assert_equal 'except/managers#index', @response.body
|
|
assert_equal '/except/sectors/1/managers', except_sector_managers_path(:sector_id => '1')
|
|
|
|
get '/except/sectors/1/managers/2'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { except_sector_manager_path(:sector_id => '1', :id => '2') }
|
|
end
|
|
|
|
def test_only_scope_should_override_parent_scope
|
|
draw do
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index do
|
|
resources :companies do
|
|
scope :only => :index do
|
|
resources :divisions
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/sectors/1/companies/2/divisions'
|
|
assert_equal 'only/divisions#index', @response.body
|
|
assert_equal '/only/sectors/1/companies/2/divisions', only_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
|
|
|
|
get '/only/sectors/1/companies/2/divisions/3'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { only_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
|
|
end
|
|
|
|
def test_except_scope_should_override_parent_scope
|
|
draw do
|
|
scope :except => :index do
|
|
namespace :except do
|
|
resources :sectors, :except => [:show, :update, :destroy] do
|
|
resources :companies do
|
|
scope :except => [:show, :update, :destroy] do
|
|
resources :divisions
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/sectors/1/companies/2/divisions'
|
|
assert_equal 'except/divisions#index', @response.body
|
|
assert_equal '/except/sectors/1/companies/2/divisions', except_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
|
|
|
|
get '/except/sectors/1/companies/2/divisions/3'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { except_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
|
|
end
|
|
|
|
def test_except_scope_should_override_parent_only_scope
|
|
draw do
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index do
|
|
resources :companies do
|
|
scope :except => [:show, :update, :destroy] do
|
|
resources :departments
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/only/sectors/1/companies/2/departments'
|
|
assert_equal 'only/departments#index', @response.body
|
|
assert_equal '/only/sectors/1/companies/2/departments', only_sector_company_departments_path(:sector_id => '1', :company_id => '2')
|
|
|
|
get '/only/sectors/1/companies/2/departments/3'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { only_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
|
|
end
|
|
|
|
def test_only_scope_should_override_parent_except_scope
|
|
draw do
|
|
scope :except => :index do
|
|
namespace :except do
|
|
resources :sectors, :except => [:show, :update, :destroy] do
|
|
resources :companies do
|
|
scope :only => :index do
|
|
resources :departments
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/except/sectors/1/companies/2/departments'
|
|
assert_equal 'except/departments#index', @response.body
|
|
assert_equal '/except/sectors/1/companies/2/departments', except_sector_company_departments_path(:sector_id => '1', :company_id => '2')
|
|
|
|
get '/except/sectors/1/companies/2/departments/3'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raise(NoMethodError) { except_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
|
|
end
|
|
|
|
def test_resources_are_not_pluralized
|
|
draw do
|
|
namespace :transport do
|
|
resources :taxis
|
|
end
|
|
end
|
|
|
|
get '/transport/taxis'
|
|
assert_equal 'transport/taxis#index', @response.body
|
|
assert_equal '/transport/taxis', transport_taxis_path
|
|
|
|
get '/transport/taxis/new'
|
|
assert_equal 'transport/taxis#new', @response.body
|
|
assert_equal '/transport/taxis/new', new_transport_taxi_path
|
|
|
|
post '/transport/taxis'
|
|
assert_equal 'transport/taxis#create', @response.body
|
|
|
|
get '/transport/taxis/1'
|
|
assert_equal 'transport/taxis#show', @response.body
|
|
assert_equal '/transport/taxis/1', transport_taxi_path(:id => '1')
|
|
|
|
get '/transport/taxis/1/edit'
|
|
assert_equal 'transport/taxis#edit', @response.body
|
|
assert_equal '/transport/taxis/1/edit', edit_transport_taxi_path(:id => '1')
|
|
|
|
put '/transport/taxis/1'
|
|
assert_equal 'transport/taxis#update', @response.body
|
|
|
|
delete '/transport/taxis/1'
|
|
assert_equal 'transport/taxis#destroy', @response.body
|
|
end
|
|
|
|
def test_singleton_resources_are_not_singularized
|
|
draw do
|
|
namespace :medical do
|
|
resource :taxis
|
|
end
|
|
end
|
|
|
|
get '/medical/taxis/new'
|
|
assert_equal 'medical/taxis#new', @response.body
|
|
assert_equal '/medical/taxis/new', new_medical_taxis_path
|
|
|
|
post '/medical/taxis'
|
|
assert_equal 'medical/taxis#create', @response.body
|
|
|
|
get '/medical/taxis'
|
|
assert_equal 'medical/taxis#show', @response.body
|
|
assert_equal '/medical/taxis', medical_taxis_path
|
|
|
|
get '/medical/taxis/edit'
|
|
assert_equal 'medical/taxis#edit', @response.body
|
|
assert_equal '/medical/taxis/edit', edit_medical_taxis_path
|
|
|
|
put '/medical/taxis'
|
|
assert_equal 'medical/taxis#update', @response.body
|
|
|
|
delete '/medical/taxis'
|
|
assert_equal 'medical/taxis#destroy', @response.body
|
|
end
|
|
|
|
def test_greedy_resource_id_regexp_doesnt_match_edit_and_custom_action
|
|
draw do
|
|
resources :sections, :id => /.+/ do
|
|
get :preview, :on => :member
|
|
end
|
|
end
|
|
|
|
get '/sections/1/edit'
|
|
assert_equal 'sections#edit', @response.body
|
|
assert_equal '/sections/1/edit', edit_section_path(:id => '1')
|
|
|
|
get '/sections/1/preview'
|
|
assert_equal 'sections#preview', @response.body
|
|
assert_equal '/sections/1/preview', preview_section_path(:id => '1')
|
|
end
|
|
|
|
def test_resource_constraints_are_pushed_to_scope
|
|
draw do
|
|
namespace :wiki do
|
|
resources :articles, :id => /[^\/]+/ do
|
|
resources :comments, :only => [:create, :new]
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/wiki/articles/Ruby_on_Rails_3.0'
|
|
assert_equal 'wiki/articles#show', @response.body
|
|
assert_equal '/wiki/articles/Ruby_on_Rails_3.0', wiki_article_path(:id => 'Ruby_on_Rails_3.0')
|
|
|
|
get '/wiki/articles/Ruby_on_Rails_3.0/comments/new'
|
|
assert_equal 'wiki/comments#new', @response.body
|
|
assert_equal '/wiki/articles/Ruby_on_Rails_3.0/comments/new', new_wiki_article_comment_path(:article_id => 'Ruby_on_Rails_3.0')
|
|
|
|
post '/wiki/articles/Ruby_on_Rails_3.0/comments'
|
|
assert_equal 'wiki/comments#create', @response.body
|
|
assert_equal '/wiki/articles/Ruby_on_Rails_3.0/comments', wiki_article_comments_path(:article_id => 'Ruby_on_Rails_3.0')
|
|
end
|
|
|
|
def test_resources_path_can_be_a_symbol
|
|
draw do
|
|
resources :wiki_pages, :path => :pages
|
|
resource :wiki_account, :path => :my_account
|
|
end
|
|
|
|
get '/pages'
|
|
assert_equal 'wiki_pages#index', @response.body
|
|
assert_equal '/pages', wiki_pages_path
|
|
|
|
get '/pages/Ruby_on_Rails'
|
|
assert_equal 'wiki_pages#show', @response.body
|
|
assert_equal '/pages/Ruby_on_Rails', wiki_page_path(:id => 'Ruby_on_Rails')
|
|
|
|
get '/my_account'
|
|
assert_equal 'wiki_accounts#show', @response.body
|
|
assert_equal '/my_account', wiki_account_path
|
|
end
|
|
|
|
def test_redirect_https
|
|
draw do
|
|
get 'secure', :to => redirect("/secure/login")
|
|
end
|
|
|
|
with_https do
|
|
get '/secure'
|
|
verify_redirect 'https://www.example.com/secure/login'
|
|
end
|
|
end
|
|
|
|
def test_symbolized_path_parameters_is_not_stale
|
|
draw do
|
|
scope '/countries/:country', :constraints => lambda { |params, req| %w(all France).include?(params[:country]) } do
|
|
get '/', :to => 'countries#index'
|
|
get '/cities', :to => 'countries#cities'
|
|
end
|
|
|
|
get '/countries/:country/(*other)', :to => redirect{ |params, req| params[:other] ? "/countries/all/#{params[:other]}" : '/countries/all' }
|
|
end
|
|
|
|
get '/countries/France'
|
|
assert_equal 'countries#index', @response.body
|
|
|
|
get '/countries/France/cities'
|
|
assert_equal 'countries#cities', @response.body
|
|
|
|
get '/countries/UK'
|
|
verify_redirect 'http://www.example.com/countries/all'
|
|
|
|
get '/countries/UK/cities'
|
|
verify_redirect 'http://www.example.com/countries/all/cities'
|
|
end
|
|
|
|
def test_constraints_block_not_carried_to_following_routes
|
|
draw do
|
|
scope '/italians' do
|
|
get '/writers', :to => 'italians#writers', :constraints => ::TestRoutingMapper::IpRestrictor
|
|
get '/sculptors', :to => 'italians#sculptors'
|
|
get '/painters/:painter', :to => 'italians#painters', :constraints => {:painter => /michelangelo/}
|
|
end
|
|
end
|
|
|
|
get '/italians/writers'
|
|
assert_equal 'Not Found', @response.body
|
|
|
|
get '/italians/sculptors'
|
|
assert_equal 'italians#sculptors', @response.body
|
|
|
|
get '/italians/painters/botticelli'
|
|
assert_equal 'Not Found', @response.body
|
|
|
|
get '/italians/painters/michelangelo'
|
|
assert_equal 'italians#painters', @response.body
|
|
end
|
|
|
|
def test_custom_resource_actions_defined_using_string
|
|
draw do
|
|
resources :customers do
|
|
resources :invoices do
|
|
get "aged/:months", :on => :collection, :action => :aged, :as => :aged
|
|
end
|
|
|
|
get "inactive", :on => :collection
|
|
post "deactivate", :on => :member
|
|
get "old", :on => :collection, :as => :stale
|
|
end
|
|
end
|
|
|
|
get '/customers/inactive'
|
|
assert_equal 'customers#inactive', @response.body
|
|
assert_equal '/customers/inactive', inactive_customers_path
|
|
|
|
post '/customers/1/deactivate'
|
|
assert_equal 'customers#deactivate', @response.body
|
|
assert_equal '/customers/1/deactivate', deactivate_customer_path(:id => '1')
|
|
|
|
get '/customers/old'
|
|
assert_equal 'customers#old', @response.body
|
|
assert_equal '/customers/old', stale_customers_path
|
|
|
|
get '/customers/1/invoices/aged/3'
|
|
assert_equal 'invoices#aged', @response.body
|
|
assert_equal '/customers/1/invoices/aged/3', aged_customer_invoices_path(:customer_id => '1', :months => '3')
|
|
end
|
|
|
|
def test_route_defined_in_resources_scope_level
|
|
draw do
|
|
resources :customers do
|
|
get "export"
|
|
end
|
|
end
|
|
|
|
get '/customers/1/export'
|
|
assert_equal 'customers#export', @response.body
|
|
assert_equal '/customers/1/export', customer_export_path(:customer_id => '1')
|
|
end
|
|
|
|
def test_named_character_classes_in_regexp_constraints
|
|
draw do
|
|
get '/purchases/:token/:filename',
|
|
:to => 'purchases#fetch',
|
|
:token => /[[:alnum:]]{10}/,
|
|
:filename => /(.+)/,
|
|
:as => :purchase
|
|
end
|
|
|
|
get '/purchases/315004be7e/Ruby_on_Rails_3.pdf'
|
|
assert_equal 'purchases#fetch', @response.body
|
|
assert_equal '/purchases/315004be7e/Ruby_on_Rails_3.pdf', purchase_path(:token => '315004be7e', :filename => 'Ruby_on_Rails_3.pdf')
|
|
end
|
|
|
|
def test_nested_resource_constraints
|
|
draw do
|
|
resources :lists, :id => /([A-Za-z0-9]{25})|default/ do
|
|
resources :todos, :id => /\d+/
|
|
end
|
|
end
|
|
|
|
get '/lists/01234012340123401234fffff'
|
|
assert_equal 'lists#show', @response.body
|
|
assert_equal '/lists/01234012340123401234fffff', list_path(:id => '01234012340123401234fffff')
|
|
|
|
get '/lists/01234012340123401234fffff/todos/1'
|
|
assert_equal 'todos#show', @response.body
|
|
assert_equal '/lists/01234012340123401234fffff/todos/1', list_todo_path(:list_id => '01234012340123401234fffff', :id => '1')
|
|
|
|
get '/lists/2/todos/1'
|
|
assert_equal 'Not Found', @response.body
|
|
assert_raises(ActionController::UrlGenerationError){ list_todo_path(:list_id => '2', :id => '1') }
|
|
end
|
|
|
|
def test_named_routes_collision_is_avoided_unless_explicitly_given_as
|
|
draw do
|
|
scope :as => "routes" do
|
|
get "/c/:id", :as => :collision, :to => "collision#show"
|
|
get "/collision", :to => "collision#show"
|
|
get "/no_collision", :to => "collision#show", :as => nil
|
|
|
|
get "/fc/:id", :as => :forced_collision, :to => "forced_collision#show"
|
|
get "/forced_collision", :as => :forced_collision, :to => "forced_collision#show"
|
|
end
|
|
end
|
|
|
|
assert_equal "/c/1", routes_collision_path(1)
|
|
assert_equal "/fc/1", routes_forced_collision_path(1)
|
|
end
|
|
|
|
def test_redirect_argument_error
|
|
routes = Class.new { include ActionDispatch::Routing::Redirection }.new
|
|
assert_raises(ArgumentError) { routes.redirect Object.new }
|
|
end
|
|
|
|
def test_explicitly_avoiding_the_named_route
|
|
draw do
|
|
scope :as => "routes" do
|
|
get "/c/:id", :as => :collision, :to => "collision#show"
|
|
get "/collision", :to => "collision#show"
|
|
get "/no_collision", :to => "collision#show", :as => nil
|
|
|
|
get "/fc/:id", :as => :forced_collision, :to => "forced_collision#show"
|
|
get "/forced_collision", :as => :forced_collision, :to => "forced_collision#show"
|
|
end
|
|
end
|
|
|
|
assert !respond_to?(:routes_no_collision_path)
|
|
end
|
|
|
|
def test_controller_name_with_leading_slash_raise_error
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/feeds/:service', :to => '/feeds#show' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/feeds/:service', :controller => '/feeds', :action => 'show' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/api/feeds/:service', :to => '/api/feeds#show' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { controller("/feeds") { get '/feeds/:service', :to => :show } }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { resources :feeds, :controller => '/feeds' }
|
|
end
|
|
end
|
|
|
|
def test_invalid_route_name_raises_error
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/products', :to => 'products#index', :as => 'products ' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/products', :to => 'products#index', :as => ' products' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/products', :to => 'products#index', :as => 'products!' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/products', :to => 'products#index', :as => 'products index' }
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
draw { get '/products', :to => 'products#index', :as => '1products' }
|
|
end
|
|
end
|
|
|
|
def test_nested_route_in_nested_resource
|
|
draw do
|
|
resources :posts, :only => [:index, :show] do
|
|
resources :comments, :except => :destroy do
|
|
get "views" => "comments#views", :as => :views
|
|
end
|
|
end
|
|
end
|
|
|
|
get "/posts/1/comments/2/views"
|
|
assert_equal "comments#views", @response.body
|
|
assert_equal "/posts/1/comments/2/views", post_comment_views_path(:post_id => '1', :comment_id => '2')
|
|
end
|
|
|
|
def test_root_in_deeply_nested_scope
|
|
draw do
|
|
resources :posts, :only => [:index, :show] do
|
|
namespace :admin do
|
|
root :to => "index#index"
|
|
end
|
|
end
|
|
end
|
|
|
|
get "/posts/1/admin"
|
|
assert_equal "admin/index#index", @response.body
|
|
assert_equal "/posts/1/admin", post_admin_root_path(:post_id => '1')
|
|
end
|
|
|
|
def test_custom_param
|
|
draw do
|
|
resources :profiles, :param => :username do
|
|
get :details, :on => :member
|
|
resources :messages
|
|
end
|
|
end
|
|
|
|
get '/profiles/bob'
|
|
assert_equal 'profiles#show', @response.body
|
|
assert_equal 'bob', @request.params[:username]
|
|
|
|
get '/profiles/bob/details'
|
|
assert_equal 'bob', @request.params[:username]
|
|
|
|
get '/profiles/bob/messages/34'
|
|
assert_equal 'bob', @request.params[:profile_username]
|
|
assert_equal '34', @request.params[:id]
|
|
end
|
|
|
|
def test_custom_param_constraint
|
|
draw do
|
|
resources :profiles, :param => :username, :username => /[a-z]+/ do
|
|
get :details, :on => :member
|
|
resources :messages
|
|
end
|
|
end
|
|
|
|
get '/profiles/bob1'
|
|
assert_equal 404, @response.status
|
|
|
|
get '/profiles/bob1/details'
|
|
assert_equal 404, @response.status
|
|
|
|
get '/profiles/bob1/messages/34'
|
|
assert_equal 404, @response.status
|
|
end
|
|
|
|
def test_shallow_custom_param
|
|
draw do
|
|
resources :orders do
|
|
constraints :download => /[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}/ do
|
|
resources :downloads, :param => :download, :shallow => true
|
|
end
|
|
end
|
|
end
|
|
|
|
get '/downloads/0c0c0b68-d24b-11e1-a861-001ff3fffe6f.zip'
|
|
assert_equal 'downloads#show', @response.body
|
|
assert_equal '0c0c0b68-d24b-11e1-a861-001ff3fffe6f', @request.params[:download]
|
|
end
|
|
|
|
def test_action_from_path_is_not_frozen
|
|
draw do
|
|
get 'search' => 'search'
|
|
end
|
|
|
|
get '/search'
|
|
assert !@request.params[:action].frozen?
|
|
end
|
|
|
|
private
|
|
|
|
def draw(&block)
|
|
self.class.stub_controllers do |routes|
|
|
@app = routes
|
|
@app.default_url_options = { host: 'www.example.com' }
|
|
@app.draw(&block)
|
|
end
|
|
end
|
|
|
|
def url_for(options = {})
|
|
@app.url_helpers.url_for(options)
|
|
end
|
|
|
|
def method_missing(method, *args, &block)
|
|
if method.to_s =~ /_(path|url)$/
|
|
@app.url_helpers.send(method, *args, &block)
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
def with_https
|
|
old_https = https?
|
|
https!
|
|
yield
|
|
ensure
|
|
https!(old_https)
|
|
end
|
|
|
|
def verify_redirect(url, status=301)
|
|
assert_equal status, @response.status
|
|
assert_equal url, @response.headers['Location']
|
|
assert_equal expected_redirect_body(url), @response.body
|
|
end
|
|
|
|
def expected_redirect_body(url)
|
|
%(<html><body>You are being <a href="#{ERB::Util.h(url)}">redirected</a>.</body></html>)
|
|
end
|
|
end
|
|
|
|
class TestAltApp < ActionDispatch::IntegrationTest
|
|
class AltRequest
|
|
def initialize(env)
|
|
@env = env
|
|
end
|
|
|
|
def path_info
|
|
"/"
|
|
end
|
|
|
|
def request_method
|
|
"GET"
|
|
end
|
|
|
|
def ip
|
|
"127.0.0.1"
|
|
end
|
|
|
|
def x_header
|
|
@env["HTTP_X_HEADER"] || ""
|
|
end
|
|
end
|
|
|
|
class XHeader
|
|
def call(env)
|
|
[200, {"Content-Type" => "text/html"}, ["XHeader"]]
|
|
end
|
|
end
|
|
|
|
class AltApp
|
|
def call(env)
|
|
[200, {"Content-Type" => "text/html"}, ["Alternative App"]]
|
|
end
|
|
end
|
|
|
|
AltRoutes = ActionDispatch::Routing::RouteSet.new(AltRequest)
|
|
AltRoutes.draw do
|
|
get "/" => TestAltApp::XHeader.new, :constraints => {:x_header => /HEADER/}
|
|
get "/" => TestAltApp::AltApp.new
|
|
end
|
|
|
|
def app
|
|
AltRoutes
|
|
end
|
|
|
|
def test_alt_request_without_header
|
|
get "/"
|
|
assert_equal "Alternative App", @response.body
|
|
end
|
|
|
|
def test_alt_request_with_matched_header
|
|
get "/", {}, "HTTP_X_HEADER" => "HEADER"
|
|
assert_equal "XHeader", @response.body
|
|
end
|
|
|
|
def test_alt_request_with_unmatched_header
|
|
get "/", {}, "HTTP_X_HEADER" => "NON_MATCH"
|
|
assert_equal "Alternative App", @response.body
|
|
end
|
|
end
|
|
|
|
class TestAppendingRoutes < ActionDispatch::IntegrationTest
|
|
def simple_app(resp)
|
|
lambda { |e| [ 200, { 'Content-Type' => 'text/plain' }, [resp] ] }
|
|
end
|
|
|
|
def setup
|
|
super
|
|
s = self
|
|
@app = ActionDispatch::Routing::RouteSet.new
|
|
@app.append do
|
|
get '/hello' => s.simple_app('fail')
|
|
get '/goodbye' => s.simple_app('goodbye')
|
|
end
|
|
|
|
@app.draw do
|
|
get '/hello' => s.simple_app('hello')
|
|
end
|
|
end
|
|
|
|
def test_goodbye_should_be_available
|
|
get '/goodbye'
|
|
assert_equal 'goodbye', @response.body
|
|
end
|
|
|
|
def test_hello_should_not_be_overwritten
|
|
get '/hello'
|
|
assert_equal 'hello', @response.body
|
|
end
|
|
|
|
def test_missing_routes_are_still_missing
|
|
get '/random'
|
|
assert_equal 404, @response.status
|
|
end
|
|
end
|
|
|
|
class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
|
|
module ::Admin
|
|
class StorageFilesController < ActionController::Base
|
|
def index
|
|
render :text => "admin/storage_files#index"
|
|
end
|
|
end
|
|
end
|
|
|
|
DefaultScopeRoutes = ActionDispatch::Routing::RouteSet.new
|
|
DefaultScopeRoutes.draw do
|
|
namespace :admin do
|
|
resources :storage_files, :controller => "StorageFiles"
|
|
end
|
|
end
|
|
|
|
def app
|
|
DefaultScopeRoutes
|
|
end
|
|
|
|
def test_controller_options
|
|
get '/admin/storage_files'
|
|
assert_equal "admin/storage_files#index", @response.body
|
|
end
|
|
end
|
|
|
|
class TestDefaultScope < ActionDispatch::IntegrationTest
|
|
module ::Blog
|
|
class PostsController < ActionController::Base
|
|
def index
|
|
render :text => "blog/posts#index"
|
|
end
|
|
end
|
|
end
|
|
|
|
DefaultScopeRoutes = ActionDispatch::Routing::RouteSet.new
|
|
DefaultScopeRoutes.default_scope = {:module => :blog}
|
|
DefaultScopeRoutes.draw do
|
|
resources :posts
|
|
end
|
|
|
|
def app
|
|
DefaultScopeRoutes
|
|
end
|
|
|
|
include DefaultScopeRoutes.url_helpers
|
|
|
|
def test_default_scope
|
|
get '/posts'
|
|
assert_equal "blog/posts#index", @response.body
|
|
end
|
|
end
|
|
|
|
class TestHttpMethods < ActionDispatch::IntegrationTest
|
|
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
|
|
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
|
|
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
|
|
RFC3648 = %w(ORDERPATCH)
|
|
RFC3744 = %w(ACL)
|
|
RFC5323 = %w(SEARCH)
|
|
RFC5789 = %w(PATCH)
|
|
|
|
def simple_app(response)
|
|
lambda { |env| [ 200, { 'Content-Type' => 'text/plain' }, [response] ] }
|
|
end
|
|
|
|
setup do
|
|
s = self
|
|
@app = ActionDispatch::Routing::RouteSet.new
|
|
|
|
@app.draw do
|
|
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789).each do |method|
|
|
match '/' => s.simple_app(method), :via => method.underscore.to_sym
|
|
end
|
|
end
|
|
end
|
|
|
|
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789).each do |method|
|
|
test "request method #{method.underscore} can be matched" do
|
|
get '/', nil, 'REQUEST_METHOD' => method
|
|
assert_equal method, @response.body
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestUriPathEscaping < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
get '/:segment' => lambda { |env|
|
|
path_params = env['action_dispatch.request.path_parameters']
|
|
[200, { 'Content-Type' => 'text/plain' }, [path_params[:segment]]]
|
|
}, :as => :segment
|
|
|
|
get '/*splat' => lambda { |env|
|
|
path_params = env['action_dispatch.request.path_parameters']
|
|
[200, { 'Content-Type' => 'text/plain' }, [path_params[:splat]]]
|
|
}, :as => :splat
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test 'escapes generated path segment' do
|
|
assert_equal '/a%20b/c+d', segment_path(:segment => 'a b/c+d')
|
|
end
|
|
|
|
test 'unescapes recognized path segment' do
|
|
get '/a%20b%2Fc+d'
|
|
assert_equal 'a b/c+d', @response.body
|
|
end
|
|
|
|
test 'escapes generated path splat' do
|
|
assert_equal '/a%20b/c+d', splat_path(:splat => 'a b/c+d')
|
|
end
|
|
|
|
test 'unescapes recognized path splat' do
|
|
get '/a%20b/c+d'
|
|
assert_equal 'a b/c+d', @response.body
|
|
end
|
|
end
|
|
|
|
class TestUnicodePaths < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
get "/ほげ" => lambda { |env|
|
|
[200, { 'Content-Type' => 'text/plain' }, []]
|
|
}, :as => :unicode_path
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test 'recognizes unicode path' do
|
|
get "/#{Rack::Utils.escape("ほげ")}"
|
|
assert_equal "200", @response.code
|
|
end
|
|
end
|
|
|
|
class TestMultipleNestedController < ActionDispatch::IntegrationTest
|
|
module ::Foo
|
|
module Bar
|
|
class BazController < ActionController::Base
|
|
def index
|
|
render :inline => "<%= url_for :controller => '/pooh', :action => 'index' %>"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
namespace :foo do
|
|
namespace :bar do
|
|
get "baz" => "baz#index"
|
|
end
|
|
end
|
|
get "pooh" => "pooh#index"
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test "controller option which starts with '/' from multiple nested controller" do
|
|
get "/foo/bar/baz"
|
|
assert_equal "/pooh", @response.body
|
|
end
|
|
end
|
|
|
|
class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
get "/~user" => ok
|
|
get "/young-and-fine" => ok
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test 'recognizes tilde path' do
|
|
get "/~user"
|
|
assert_equal "200", @response.code
|
|
end
|
|
|
|
test 'recognizes minus path' do
|
|
get "/young-and-fine"
|
|
assert_equal "200", @response.code
|
|
end
|
|
|
|
end
|
|
|
|
class TestRedirectInterpolation < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
get "/foo/:id" => redirect("/foo/bar/%{id}")
|
|
get "/bar/:id" => redirect(:path => "/foo/bar/%{id}")
|
|
get "/foo/bar/:id" => ok
|
|
end
|
|
end
|
|
|
|
def app; Routes end
|
|
|
|
test "redirect escapes interpolated parameters with redirect proc" do
|
|
get "/foo/1%3E"
|
|
verify_redirect "http://www.example.com/foo/bar/1%3E"
|
|
end
|
|
|
|
test "redirect escapes interpolated parameters with option proc" do
|
|
get "/bar/1%3E"
|
|
verify_redirect "http://www.example.com/foo/bar/1%3E"
|
|
end
|
|
|
|
private
|
|
def verify_redirect(url, status=301)
|
|
assert_equal status, @response.status
|
|
assert_equal url, @response.headers['Location']
|
|
assert_equal expected_redirect_body(url), @response.body
|
|
end
|
|
|
|
def expected_redirect_body(url)
|
|
%(<html><body>You are being <a href="#{ERB::Util.h(url)}">redirected</a>.</body></html>)
|
|
end
|
|
end
|
|
|
|
class TestConstraintsAccessingParameters < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
get "/:foo" => ok, :constraints => lambda { |r| r.params[:foo] == 'foo' }
|
|
get "/:bar" => ok
|
|
end
|
|
end
|
|
|
|
def app; Routes end
|
|
|
|
test "parameters are reset between constraint checks" do
|
|
get "/bar"
|
|
assert_equal nil, @request.params[:foo]
|
|
assert_equal "bar", @request.params[:bar]
|
|
end
|
|
end
|
|
|
|
class TestGlobRoutingMapper < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
get "/*id" => redirect("/not_cars"), :constraints => {id: /dummy/}
|
|
get "/cars" => ok
|
|
end
|
|
end
|
|
|
|
#include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
def test_glob_constraint
|
|
get "/dummy"
|
|
assert_equal "301", @response.code
|
|
assert_equal "/not_cars", @response.header['Location'].match('/[^/]+$')[0]
|
|
end
|
|
|
|
def test_glob_constraint_skip_route
|
|
get "/cars"
|
|
assert_equal "200", @response.code
|
|
end
|
|
def test_glob_constraint_skip_all
|
|
get "/missing"
|
|
assert_equal "404", @response.code
|
|
end
|
|
end
|
|
|
|
class TestOptimizedNamedRoutes < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
get '/foo' => ok, as: :foo
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test 'enabled when not mounted and default_url_options is empty' do
|
|
assert Routes.url_helpers.optimize_routes_generation?
|
|
end
|
|
|
|
test 'named route called as singleton method' do
|
|
assert_equal '/foo', Routes.url_helpers.foo_path
|
|
end
|
|
|
|
test 'named route called on included module' do
|
|
assert_equal '/foo', foo_path
|
|
end
|
|
end
|
|
|
|
class TestNamedRouteUrlHelpers < ActionDispatch::IntegrationTest
|
|
class CategoriesController < ActionController::Base
|
|
def show
|
|
render :text => "categories#show"
|
|
end
|
|
end
|
|
|
|
class ProductsController < ActionController::Base
|
|
def show
|
|
render :text => "products#show"
|
|
end
|
|
end
|
|
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
scope :module => "test_named_route_url_helpers" do
|
|
get "/categories/:id" => 'categories#show', :as => :category
|
|
get "/products/:id" => 'products#show', :as => :product
|
|
end
|
|
end
|
|
end
|
|
|
|
def app; Routes end
|
|
|
|
include Routes.url_helpers
|
|
|
|
test "url helpers do not ignore nil parameters when using non-optimized routes" do
|
|
Routes.stubs(:optimize_routes_generation?).returns(false)
|
|
|
|
get "/categories/1"
|
|
assert_response :success
|
|
assert_raises(ActionController::UrlGenerationError) { product_path(nil) }
|
|
end
|
|
end
|
|
|
|
class TestUrlConstraints < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
constraints :subdomain => 'admin' do
|
|
get '/' => ok, :as => :admin_root
|
|
end
|
|
|
|
scope :constraints => { :protocol => 'https://' } do
|
|
get '/' => ok, :as => :secure_root
|
|
end
|
|
|
|
get '/' => ok, :as => :alternate_root, :constraints => { :port => 8080 }
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
test "constraints are copied to defaults when using constraints method" do
|
|
assert_equal 'http://admin.example.com/', admin_root_url
|
|
|
|
get 'http://admin.example.com/'
|
|
assert_response :success
|
|
end
|
|
|
|
test "constraints are copied to defaults when using scope constraints hash" do
|
|
assert_equal 'https://www.example.com/', secure_root_url
|
|
|
|
get 'https://www.example.com/'
|
|
assert_response :success
|
|
end
|
|
|
|
test "constraints are copied to defaults when using route constraints hash" do
|
|
assert_equal 'http://www.example.com:8080/', alternate_root_url
|
|
|
|
get 'http://www.example.com:8080/'
|
|
assert_response :success
|
|
end
|
|
end
|
|
|
|
class TestInvalidUrls < ActionDispatch::IntegrationTest
|
|
class FooController < ActionController::Base
|
|
def show
|
|
render :text => "foo#show"
|
|
end
|
|
end
|
|
|
|
test "invalid UTF-8 encoding returns a 400 Bad Request" do
|
|
with_routing do |set|
|
|
set.draw do
|
|
get "/bar/:id", :to => redirect("/foo/show/%{id}")
|
|
get "/foo/show(/:id)", :to => "test_invalid_urls/foo#show"
|
|
get "/foo(/:action(/:id))", :to => "test_invalid_urls/foo"
|
|
get "/:controller(/:action(/:id))"
|
|
end
|
|
|
|
get "/%E2%EF%BF%BD%A6"
|
|
assert_response :bad_request
|
|
|
|
get "/foo/%E2%EF%BF%BD%A6"
|
|
assert_response :bad_request
|
|
|
|
get "/foo/show/%E2%EF%BF%BD%A6"
|
|
assert_response :bad_request
|
|
|
|
get "/bar/%E2%EF%BF%BD%A6"
|
|
assert_response :bad_request
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestOptionalRootSegments < ActionDispatch::IntegrationTest
|
|
stub_controllers do |routes|
|
|
Routes = routes
|
|
Routes.draw do
|
|
get '/(page/:page)', :to => 'pages#index', :as => :root
|
|
end
|
|
end
|
|
|
|
def app
|
|
Routes
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
|
|
def test_optional_root_segments
|
|
get '/'
|
|
assert_equal 'pages#index', @response.body
|
|
assert_equal '/', root_path
|
|
|
|
get '/page/1'
|
|
assert_equal 'pages#index', @response.body
|
|
assert_equal '1', @request.params[:page]
|
|
assert_equal '/page/1', root_path('1')
|
|
assert_equal '/page/1', root_path(:page => '1')
|
|
end
|
|
end
|
|
|
|
class TestPortConstraints < ActionDispatch::IntegrationTest
|
|
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
|
|
app.draw do
|
|
ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
|
|
|
|
get '/integer', to: ok, constraints: { :port => 8080 }
|
|
get '/string', to: ok, constraints: { :port => '8080' }
|
|
get '/array', to: ok, constraints: { :port => [8080] }
|
|
get '/regexp', to: ok, constraints: { :port => /8080/ }
|
|
end
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
def app; Routes end
|
|
|
|
def test_integer_port_constraints
|
|
get 'http://www.example.com/integer'
|
|
assert_response :not_found
|
|
|
|
get 'http://www.example.com:8080/integer'
|
|
assert_response :success
|
|
end
|
|
|
|
def test_string_port_constraints
|
|
get 'http://www.example.com/string'
|
|
assert_response :not_found
|
|
|
|
get 'http://www.example.com:8080/string'
|
|
assert_response :success
|
|
end
|
|
|
|
def test_array_port_constraints
|
|
get 'http://www.example.com/array'
|
|
assert_response :not_found
|
|
|
|
get 'http://www.example.com:8080/array'
|
|
assert_response :success
|
|
end
|
|
|
|
def test_regexp_port_constraints
|
|
get 'http://www.example.com/regexp'
|
|
assert_response :not_found
|
|
|
|
get 'http://www.example.com:8080/regexp'
|
|
assert_response :success
|
|
end
|
|
end
|
|
|
|
class TestRouteDefaults < ActionDispatch::IntegrationTest
|
|
stub_controllers do |routes|
|
|
Routes = routes
|
|
Routes.draw do
|
|
resources :posts, bucket_type: 'post'
|
|
resources :projects, defaults: { bucket_type: 'project' }
|
|
end
|
|
end
|
|
|
|
def app
|
|
Routes
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
|
|
def test_route_options_are_required_for_url_for
|
|
assert_raises(ActionController::UrlGenerationError) do
|
|
assert_equal '/posts/1', url_for(controller: 'posts', action: 'show', id: 1, only_path: true)
|
|
end
|
|
|
|
assert_equal '/posts/1', url_for(controller: 'posts', action: 'show', id: 1, bucket_type: 'post', only_path: true)
|
|
end
|
|
|
|
def test_route_defaults_are_not_required_for_url_for
|
|
assert_equal '/projects/1', url_for(controller: 'projects', action: 'show', id: 1, only_path: true)
|
|
end
|
|
end
|