mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
0b6175ac2d
Many named routes have keys that are required to successfully resolve. If a key is left off like this: <%= link_to 'user', user_path %> This will produce an error like this: No route matches {:action=>"show", :controller=>"users"} Since we know that the :id is missing, we can add extra debugging information to the error message. No route matches {:action=>"show", :controller=>"users"} missing required keys: [:id] This will help new and seasoned developers look closer at their parameters. I've also subclassed the routing error to be clear that this error is a result of attempting to generate a url and not because the user is trying to visit a bad url. While this may sound trivial this error message is misleading and confuses most developers. The important part isn't what's in the options its's what's missing. Adding this information to the error message will make debugging much more obvious. This is the sister pull request of https://github.com/rails/journey/pull/44 which will be required to get they missing keys into the correct error message. Example Development Error in Rails: http://cl.ly/image/3S0T0n1T3421
2730 lines
86 KiB
Ruby
2730 lines
86 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
|
|
|
|
stub_controllers do |routes|
|
|
Routes = routes
|
|
Routes.draw do
|
|
default_url_options :host => "rubyonrails.org"
|
|
resources_path_names :correlation_indexes => "info_about_correlation_indexes"
|
|
|
|
controller :sessions do
|
|
get 'login' => :new
|
|
post 'login' => :create
|
|
delete 'logout' => :destroy
|
|
end
|
|
|
|
resource :session do
|
|
get :create
|
|
post :reset
|
|
|
|
resource :info
|
|
|
|
member do
|
|
get :crush
|
|
end
|
|
end
|
|
|
|
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
|
|
|
|
scope "pagemark", :controller => "pagemarks", :as => :pagemark do
|
|
get "new", :path => "build"
|
|
post "create", :as => ""
|
|
put "update"
|
|
get "remove", :action => :destroy, :as => :remove
|
|
end
|
|
|
|
get 'account/logout' => redirect("/logout"), :as => :logout_redirect
|
|
get 'account/login', :to => redirect("/login")
|
|
get 'secure', :to => redirect("/secure/login")
|
|
|
|
get 'mobile', :to => redirect(:subdomain => 'mobile')
|
|
get 'documentation', :to => redirect(:domain => 'example-documentation.com', :path => '')
|
|
get 'new_documentation', :to => redirect(:path => '/documentation/new')
|
|
get 'super_new_documentation', :to => redirect(:host => 'super-docs.com')
|
|
|
|
get 'stores/:name', :to => redirect(:subdomain => 'stores', :path => '/%{name}')
|
|
get 'stores/:name(*rest)', :to => redirect(:subdomain => 'stores', :path => '/%{name}%{rest}')
|
|
|
|
get 'youtube_favorites/:youtube_id/:name', :to => redirect(YoutubeFavoritesRedirector)
|
|
|
|
constraints(lambda { |req| true }) do
|
|
get 'account/overview'
|
|
end
|
|
|
|
get '/account/nested/overview'
|
|
get 'sign_in' => "sessions#new"
|
|
|
|
get 'account/modulo/:name', :to => redirect("/%{name}s")
|
|
get 'account/proc/:name', :to => redirect {|params, req| "/#{params[:name].pluralize}" }
|
|
get 'account/proc_req' => redirect {|params, req| "/#{req.method}" }
|
|
|
|
get 'account/google' => redirect('http://www.google.com/', :status => 302)
|
|
|
|
match 'openid/login', :via => [:get, :post], :to => "openid#login"
|
|
|
|
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
|
|
|
|
get "/local/:action", :controller => "local"
|
|
|
|
get "/projects/status(.:format)"
|
|
get "/404", :to => lambda { |env| [404, {"Content-Type" => "text/plain"}, ["NOT FOUND"]] }
|
|
|
|
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
|
|
|
|
scope 'pt', :as => 'pt' do
|
|
resources :projects, :path_names => { :edit => 'editar', :new => 'novo' }, :path => 'projetos' do
|
|
post :preview, :on => :new
|
|
put :close, :on => :member, :path => 'fechar'
|
|
get :open, :on => :new, :path => 'abrir'
|
|
end
|
|
resource :admin, :path_names => { :new => 'novo', :activate => 'ativar' }, :path => 'administrador' do
|
|
post :preview, :on => :new
|
|
put :activate, :on => :member
|
|
end
|
|
resources :products, :path_names => { :new => 'novo' } do
|
|
new do
|
|
post :preview
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :projects, :controller => :project do
|
|
resources :involvements, :attachments
|
|
get :correlation_indexes, :on => :collection
|
|
|
|
resources :participants do
|
|
put :update_all, :on => :collection
|
|
end
|
|
|
|
resources :companies do
|
|
resources :people
|
|
resource :avatar, :controller => :avatar
|
|
end
|
|
|
|
resources :images, :as => :funny_images do
|
|
post :revise, :on => :member
|
|
end
|
|
|
|
resource :manager, :as => :super_manager do
|
|
post :fire
|
|
end
|
|
|
|
resources :people do
|
|
nested do
|
|
scope "/:access_token" do
|
|
resource :avatar
|
|
end
|
|
end
|
|
|
|
member do
|
|
get 'some_path_with_name'
|
|
put :accessible_projects
|
|
post :resend, :generate_new_password
|
|
end
|
|
end
|
|
|
|
resources :posts do
|
|
get :archive, :toggle_view, :on => :collection
|
|
post :preview, :on => :member
|
|
|
|
resource :subscription
|
|
|
|
resources :comments do
|
|
post :preview, :on => :collection
|
|
end
|
|
end
|
|
|
|
post 'new', :action => 'new', :on => :collection, :as => :new
|
|
end
|
|
|
|
resources :replies do
|
|
collection do
|
|
get 'page/:page' => 'replies#index', :page => %r{\d+}
|
|
get ':page' => 'replies#index', :page => %r{\d+}
|
|
end
|
|
|
|
new do
|
|
post :preview
|
|
end
|
|
|
|
member do
|
|
put :answer, :to => :mark_as_answer
|
|
delete :answer, :to => :unmark_as_answer
|
|
end
|
|
end
|
|
|
|
resources :posts, :only => [:index, :show] do
|
|
namespace :admin do
|
|
root :to => "index#index"
|
|
end
|
|
resources :comments, :except => :destroy do
|
|
get "views" => "comments#views", :as => :views
|
|
end
|
|
end
|
|
|
|
resource :past, :only => :destroy
|
|
resource :present, :only => :update
|
|
resource :future, :only => :create
|
|
resources :relationships, :only => [:create, :destroy]
|
|
resources :friendships, :only => [:update]
|
|
|
|
shallow do
|
|
namespace :api do
|
|
resources :teams do
|
|
resources :players
|
|
resource :captain
|
|
end
|
|
end
|
|
end
|
|
|
|
scope '/hello' do
|
|
shallow do
|
|
resources :notes do
|
|
resources :trackbacks
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :threads, :shallow => true do
|
|
resource :owner
|
|
resources :messages do
|
|
resources :comments do
|
|
member do
|
|
post :preview
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :sheep do
|
|
get "_it", :on => :member
|
|
end
|
|
|
|
resources :clients do
|
|
namespace :google do
|
|
resource :account do
|
|
namespace :secret do
|
|
resource :info
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
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
|
|
get "aged/:months", :on => :collection, :action => :aged, :as => :aged
|
|
end
|
|
resources :notes, :shallow => true do
|
|
get "preview" => "notes#preview", :as => :preview, :on => :new
|
|
get "print" => "notes#print", :as => :print, :on => :member
|
|
end
|
|
get "inactive", :on => :collection
|
|
post "deactivate", :on => :member
|
|
get "old", :on => :collection, :as => :stale
|
|
get "export"
|
|
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
|
|
scope(':version', :version => /.+/) do
|
|
resources :users, :id => /.+?/, :format => /json|xml/
|
|
end
|
|
end
|
|
|
|
get 'sprockets.js' => ::TestRoutingMapper::SprocketsApp
|
|
|
|
get 'people/:id/update', :to => 'people#update', :as => :update_person
|
|
get '/projects/:project_id/people/:id/update', :to => 'people#update', :as => :update_project_person
|
|
|
|
# misc
|
|
get 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article
|
|
|
|
# default params
|
|
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
|
|
|
|
namespace :account do
|
|
get 'shorthand'
|
|
get 'description', :to => :description, :as => "description"
|
|
get ':action/callback', :action => /twitter|github/, :to => "callbacks", :as => :callback
|
|
resource :subscription, :credit, :credit_card
|
|
|
|
root :to => "account#index"
|
|
|
|
namespace :admin do
|
|
resource :subscription
|
|
end
|
|
end
|
|
|
|
namespace :forum do
|
|
resources :products, :path => '' do
|
|
resources :questions
|
|
end
|
|
end
|
|
|
|
namespace :users, :path => 'usuarios' do
|
|
root :to => 'home#index'
|
|
end
|
|
|
|
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
|
|
|
|
scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do
|
|
resources :rooms
|
|
end
|
|
|
|
get '/info' => 'projects#info', :as => 'info'
|
|
|
|
namespace :admin do
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
resources :descriptions
|
|
end
|
|
end
|
|
|
|
scope '(:locale)', :locale => /en|pl/ do
|
|
get "registrations/new"
|
|
resources :descriptions
|
|
root :to => 'projects#index'
|
|
end
|
|
|
|
scope :only => [:index, :show] do
|
|
resources :products, :constraints => { :id => /\d{4}/ } do
|
|
root :to => "products#root"
|
|
get :favorite, :on => :collection
|
|
resources :images
|
|
end
|
|
resource :account
|
|
end
|
|
|
|
resource :dashboard, :constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
|
|
|
|
resource :token, :module => :api
|
|
scope :module => :api do
|
|
resources :errors, :shallow => true do
|
|
resources :notices
|
|
end
|
|
end
|
|
|
|
scope :path => 'api' do
|
|
resource :me
|
|
get '/' => 'mes#index'
|
|
end
|
|
|
|
get "(/:username)/followers" => "followers#index"
|
|
get "/groups(/user/:username)" => "groups#index"
|
|
get "(/user/:username)/photos" => "photos#index"
|
|
|
|
scope '(groups)' do
|
|
scope '(discussions)' do
|
|
resources :messages
|
|
end
|
|
end
|
|
|
|
get "whatever/:controller(/:action(/:id))", :id => /\d+/
|
|
|
|
resource :profile do
|
|
get :settings
|
|
|
|
new do
|
|
post :preview
|
|
end
|
|
end
|
|
|
|
resources :content
|
|
|
|
namespace :transport do
|
|
resources :taxis
|
|
end
|
|
|
|
namespace :medical do
|
|
resource :taxis
|
|
end
|
|
|
|
scope :constraints => { :id => /\d+/ } do
|
|
get '/tickets', :to => 'tickets#index', :as => :tickets
|
|
end
|
|
|
|
scope :constraints => { :id => /\d{4}/ } do
|
|
resources :movies do
|
|
resources :reviews
|
|
resource :trailer
|
|
end
|
|
end
|
|
|
|
namespace :private do
|
|
root :to => redirect('/private/index')
|
|
get "index", :to => 'private#index'
|
|
end
|
|
|
|
scope :only => [:index, :show] do
|
|
namespace :only do
|
|
resources :clubs do
|
|
resources :players
|
|
resource :chairman
|
|
end
|
|
end
|
|
end
|
|
|
|
scope :except => [:new, :create, :edit, :update, :destroy] do
|
|
namespace :except do
|
|
resources :clubs do
|
|
resources :players
|
|
resource :chairman
|
|
end
|
|
end
|
|
end
|
|
|
|
namespace :wiki do
|
|
resources :articles, :id => /[^\/]+/ do
|
|
resources :comments, :only => [:create, :new]
|
|
end
|
|
end
|
|
|
|
resources :wiki_pages, :path => :pages
|
|
resource :wiki_account, :path => :my_account
|
|
|
|
scope :only => :show do
|
|
namespace :only do
|
|
resources :sectors, :only => :index do
|
|
resources :companies do
|
|
scope :only => :index do
|
|
resources :divisions
|
|
end
|
|
scope :except => [:show, :update, :destroy] do
|
|
resources :departments
|
|
end
|
|
end
|
|
resource :leader
|
|
resources :managers, :except => [:show, :update, :destroy]
|
|
end
|
|
end
|
|
end
|
|
|
|
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
|
|
scope :only => :index do
|
|
resources :departments
|
|
end
|
|
end
|
|
resource :leader
|
|
resources :managers, :only => :index
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :sections, :id => /.+/ do
|
|
get :preview, :on => :member
|
|
end
|
|
|
|
resources :profiles, :param => :username, :username => /[a-z]+/ do
|
|
get :details, :on => :member
|
|
resources :messages
|
|
end
|
|
|
|
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
|
|
|
|
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
|
|
|
|
get '/purchases/:token/:filename',
|
|
:to => 'purchases#fetch',
|
|
:token => /[[:alnum:]]{10}/,
|
|
:filename => /(.+)/,
|
|
:as => :purchase
|
|
|
|
resources :lists, :id => /([A-Za-z0-9]{25})|default/ do
|
|
resources :todos, :id => /\d+/
|
|
end
|
|
|
|
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' }
|
|
|
|
get '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/
|
|
|
|
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
|
|
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 "/" => TestRoutingMapper::TestAltApp::XHeader.new, :constraints => {:x_header => /HEADER/}
|
|
get "/" => TestRoutingMapper::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
|
|
|
|
def app
|
|
Routes
|
|
end
|
|
|
|
include Routes.url_helpers
|
|
|
|
def test_logout
|
|
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
|
|
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', Routes.url_for(:controller => 'sessions', :action => 'create')
|
|
assert_equal 'http://rubyonrails.org/login', Routes.url_helpers.login_url
|
|
end
|
|
|
|
def test_login_redirect
|
|
get '/account/login'
|
|
verify_redirect 'http://www.example.com/login'
|
|
end
|
|
|
|
def test_logout_redirect_without_to
|
|
assert_equal '/account/logout', logout_redirect_path
|
|
get '/account/logout'
|
|
verify_redirect 'http://www.example.com/logout'
|
|
end
|
|
|
|
def test_namespace_redirect
|
|
get '/private'
|
|
verify_redirect 'http://www.example.com/private/index'
|
|
end
|
|
|
|
def test_namespace_with_controller_segment
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw do
|
|
namespace :admin do
|
|
get '/:controller(/:action(/:id(.:format)))'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_session_singleton_resource
|
|
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
|
|
get '/session/info'
|
|
assert_equal 'infos#show', @response.body
|
|
assert_equal '/session/info', session_info_path
|
|
end
|
|
|
|
def test_member_on_resource
|
|
get '/session/crush'
|
|
assert_equal 'sessions#crush', @response.body
|
|
assert_equal '/session/crush', crush_session_path
|
|
end
|
|
|
|
def test_redirect_modulo
|
|
get '/account/modulo/name'
|
|
verify_redirect 'http://www.example.com/names'
|
|
end
|
|
|
|
def test_redirect_proc
|
|
get '/account/proc/person'
|
|
verify_redirect 'http://www.example.com/people'
|
|
end
|
|
|
|
def test_redirect_proc_with_request
|
|
get '/account/proc_req'
|
|
verify_redirect 'http://www.example.com/GET'
|
|
end
|
|
|
|
def test_redirect_hash_with_subdomain
|
|
get '/mobile'
|
|
verify_redirect 'http://mobile.example.com/mobile'
|
|
end
|
|
|
|
def test_redirect_hash_with_domain_and_path
|
|
get '/documentation'
|
|
verify_redirect 'http://www.example-documentation.com'
|
|
end
|
|
|
|
def test_redirect_hash_with_path
|
|
get '/new_documentation'
|
|
verify_redirect 'http://www.example.com/documentation/new'
|
|
end
|
|
|
|
def test_redirect_hash_with_host
|
|
get '/super_new_documentation?section=top'
|
|
verify_redirect 'http://super-docs.com/super_new_documentation?section=top'
|
|
end
|
|
|
|
def test_redirect_hash_path_substitution
|
|
get '/stores/iernest'
|
|
verify_redirect 'http://stores.example.com/iernest'
|
|
end
|
|
|
|
def test_redirect_hash_path_substitution_with_catch_all
|
|
get '/stores/iernest/products'
|
|
verify_redirect 'http://stores.example.com/iernest/products'
|
|
end
|
|
|
|
def test_redirect_class
|
|
get '/youtube_favorites/oHg5SJYRHA0/rick-rolld'
|
|
verify_redirect 'http://www.youtube.com/watch?v=oHg5SJYRHA0'
|
|
end
|
|
|
|
def test_openid
|
|
get '/openid/login'
|
|
assert_equal 'openid#login', @response.body
|
|
|
|
post '/openid/login'
|
|
assert_equal 'openid#login', @response.body
|
|
end
|
|
|
|
def test_bookmarks
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
# 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
post '/projects/new'
|
|
assert_equal "project#new", @response.body
|
|
assert_equal "/projects/new", new_projects_path
|
|
end
|
|
|
|
def test_projects_involvements
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
get '/projects/info_about_correlation_indexes'
|
|
assert_equal 'project#correlation_indexes', @response.body
|
|
assert_equal '/projects/info_about_correlation_indexes', correlation_indexes_projects_path
|
|
end
|
|
|
|
def test_projects_posts
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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_path_names
|
|
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
|
|
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
|
|
get '/sprockets.js'
|
|
assert_equal 'javascripts', @response.body
|
|
end
|
|
|
|
def test_update_person_route
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
get '/usuarios'
|
|
assert_equal '/usuarios', users_root_path
|
|
assert_equal 'users/home#index', @response.body
|
|
end
|
|
|
|
def test_articles_with_id
|
|
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
|
|
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
|
|
assert_equal '/', root_path
|
|
get '/'
|
|
assert_equal 'projects#index', @response.body
|
|
end
|
|
|
|
def test_index
|
|
assert_equal '/info', info_path
|
|
get '/info'
|
|
assert_equal 'projects#info', @response.body
|
|
end
|
|
|
|
def test_match_shorthand_with_no_scope
|
|
assert_equal '/account/overview', account_overview_path
|
|
get '/account/overview'
|
|
assert_equal 'account#overview', @response.body
|
|
end
|
|
|
|
def test_match_shorthand_inside_namespace
|
|
assert_equal '/account/shorthand', account_shorthand_path
|
|
get '/account/shorthand'
|
|
assert_equal 'account#shorthand', @response.body
|
|
end
|
|
|
|
def test_dynamically_generated_helpers_on_collection_do_not_clobber_resources_url_helper
|
|
assert_equal '/replies', replies_path
|
|
end
|
|
|
|
def test_scoped_controller_with_namespace_and_action
|
|
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
|
|
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
|
|
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
|
|
get '/account/google'
|
|
verify_redirect 'http://www.google.com/', 302
|
|
end
|
|
|
|
def test_redirect_with_port
|
|
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
|
|
assert_equal '/account/description', account_description_path
|
|
|
|
get '/account/description'
|
|
assert_equal 'account#description', @response.body
|
|
end
|
|
|
|
def test_namespaced_roots
|
|
assert_equal '/account', account_root_path
|
|
get '/account'
|
|
assert_equal 'account/account#index', @response.body
|
|
end
|
|
|
|
def test_optional_scoped_root
|
|
assert_equal '/en', root_path("en")
|
|
get '/en'
|
|
assert_equal 'projects#index', @response.body
|
|
end
|
|
|
|
def test_optional_scoped_path
|
|
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
|
|
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
|
|
get '/registrations/new'
|
|
assert_nil @request.params[:locale]
|
|
|
|
get '/en/registrations/new'
|
|
assert_equal 'en', @request.params[:locale]
|
|
end
|
|
|
|
def test_default_params
|
|
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
|
|
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
|
|
get '/products'
|
|
assert_equal 'products#root', @response.body
|
|
assert_equal '/products', products_root_path
|
|
end
|
|
|
|
def test_module_scope
|
|
get '/token'
|
|
assert_equal 'api/tokens#show', @response.body
|
|
assert_equal '/token', token_path
|
|
end
|
|
|
|
def test_path_scope
|
|
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_url_generator_for_generic_route
|
|
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
|
|
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_assert_recognizes_account_overview
|
|
assert_recognizes({:controller => "account", :action => "overview"}, "/account/overview")
|
|
end
|
|
|
|
def test_resource_new_actions
|
|
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
|
|
assert_raise(NameError) { new_account_path }
|
|
|
|
get '/account/new'
|
|
assert_equal 404, status
|
|
end
|
|
|
|
def test_resources_merges_options_from_scope
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
get '/en/path/to/existing/file.html'
|
|
assert_equal 200, @response.status
|
|
end
|
|
|
|
def test_resources_controller_name_is_not_pluralized
|
|
get '/content'
|
|
assert_equal 'content#index', @response.body
|
|
end
|
|
|
|
def test_url_generator_for_optional_prefix_dynamic_segment
|
|
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
|
|
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
|
|
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
|
|
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
|
|
get '/tickets'
|
|
assert_equal 'tickets#index', @response.body
|
|
assert_equal '/tickets', tickets_path
|
|
end
|
|
|
|
def test_constraints_are_merged_from_scope
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
with_https do
|
|
get '/secure'
|
|
verify_redirect 'https://www.example.com/secure/login'
|
|
end
|
|
end
|
|
|
|
def test_symbolized_path_parameters_is_not_stale
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
assert !respond_to?(:routes_no_collision_path)
|
|
end
|
|
|
|
def test_controller_name_with_leading_slash_raise_error
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/feeds/:service', :to => '/feeds#show' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/feeds/:service', :controller => '/feeds', :action => 'show' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/api/feeds/:service', :to => '/api/feeds#show' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { controller("/feeds") { get '/feeds/:service', :to => :show } }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { resources :feeds, :controller => '/feeds' }
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_invalid_route_name_raises_error
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/products', :to => 'products#index', :as => 'products ' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/products', :to => 'products#index', :as => ' products' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/products', :to => 'products#index', :as => 'products!' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/products', :to => 'products#index', :as => 'products index' }
|
|
end
|
|
end
|
|
|
|
assert_raise(ArgumentError) do
|
|
self.class.stub_controllers do |routes|
|
|
routes.draw { get '/products', :to => 'products#index', :as => '1products' }
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_nested_route_in_nested_resource
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
|
|
private
|
|
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 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 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
|