diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/Rakefile | 21 | ||||
-rw-r--r-- | actionpack/actionpack.gemspec | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/responder.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/url.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 43 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/form_tag_helper.rb | 2 | ||||
-rw-r--r-- | actionpack/test/dispatch/request_test.rb | 36 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing_test.rb | 139 | ||||
-rw-r--r-- | actionpack/test/template/form_helper_test.rb | 2 | ||||
-rw-r--r-- | actionpack/test/template/form_tag_helper_test.rb | 2 |
10 files changed, 215 insertions, 54 deletions
diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 4af8ea167a..d67c6f2410 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -1,8 +1,5 @@ -gem 'rdoc', '>= 2.5.9' -require 'rdoc' require 'rake' require 'rake/testtask' -require 'rdoc/task' require 'rake/packagetask' require 'rake/gempackagetask' @@ -36,24 +33,6 @@ Rake::TestTask.new(:test_active_record_integration) do |t| t.test_files = Dir.glob("test/activerecord/*_test.rb") end -# Genereate the RDoc documentation - -RDoc::Task.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Action Pack -- On rails from request to response" - rdoc.options << '--charset' << 'utf-8' - rdoc.options << '-f' << 'horo' - rdoc.options << '--main' << 'README.rdoc' - if ENV['DOC_FILES'] - rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/)) - else - rdoc.rdoc_files.include('README.rdoc', 'RUNNING_UNIT_TESTS', 'CHANGELOG') - rdoc.rdoc_files.include(Dir['lib/**/*.rb'] - - Dir['lib/*/vendor/**/*.rb']) - rdoc.rdoc_files.exclude('lib/actionpack.rb') - end -} - spec = eval(File.read('actionpack.gemspec')) Rake::GemPackageTask.new(spec) do |p| diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 99deff234c..a5ebc18e2a 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |s| s.add_dependency('i18n', '~> 0.4.1') s.add_dependency('rack', '~> 1.2.1') s.add_dependency('rack-test', '~> 0.5.4') - s.add_dependency('rack-mount', '~> 0.6.9') - s.add_dependency('tzinfo', '~> 0.3.22') + s.add_dependency('rack-mount', '~> 0.6.10') + s.add_dependency('tzinfo', '~> 0.3.23') s.add_dependency('erubis', '~> 2.6.6') end diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index cb644dfd16..aafba2a65f 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -89,6 +89,8 @@ module ActionController #:nodoc: def initialize(controller, resources, options={}) @controller = controller + @request = @controller.request + @format = @controller.formats.first @resource = resources.last @resources = resources @options = options @@ -99,14 +101,6 @@ module ActionController #:nodoc: delegate :head, :render, :redirect_to, :to => :controller delegate :get?, :post?, :put?, :delete?, :to => :request - def request - @request ||= @controller.request - end - - def format - @format ||= @controller.formats.first - end - # Undefine :to_json and :to_yaml since it's defined on Object undef_method(:to_json) if method_defined?(:to_json) undef_method(:to_yaml) if method_defined?(:to_yaml) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index b64a83c62e..ffb7bdd586 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -6,6 +6,11 @@ module ActionDispatch protocol + host_with_port + fullpath end + # Returns 'https' if this is an SSL request and 'http' otherwise. + def scheme + ssl? ? 'https' : 'http' + end + # Returns 'https://' if this is an SSL request and 'http://' otherwise. def protocol ssl? ? 'https://' : 'http://' @@ -53,6 +58,11 @@ module ActionDispatch end end + # Returns whether this request is using the standard port + def standard_port? + port == standard_port + end + # Returns a \port suffix like ":8080" if the \port number of this request # is not the default HTTP \port 80 or HTTPS \port 443. def port_string diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index c118c72440..800c6b469e 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -288,7 +288,7 @@ module ActionDispatch uri = URI.parse(path_proc.call(*params)) uri.scheme ||= req.scheme uri.host ||= req.host - uri.port ||= req.port unless req.port == 80 + uri.port ||= req.port unless req.standard_port? body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>) @@ -473,7 +473,7 @@ module ActionDispatch def initialize(entities, options = {}) @name = entities.to_s - @path = options.delete(:path) || @name + @path = (options.delete(:path) || @name).to_s @controller = (options.delete(:controller) || @name).to_s @as = options.delete(:as) @options = options @@ -498,16 +498,14 @@ module ActionDispatch end def plural - name.to_s.pluralize + @plural ||= name.to_s end def singular - name.to_s.singularize + @singular ||= name.to_s.singularize end - def member_name - singular - end + alias :member_name :singular # Checks for uncountable plurals, and appends "_index" if they're. def collection_name @@ -518,9 +516,7 @@ module ActionDispatch { :controller => controller } end - def collection_scope - path - end + alias :collection_scope :path def member_scope "#{path}/:id" @@ -541,21 +537,25 @@ module ActionDispatch def initialize(entities, options) @name = entities.to_s - @path = options.delete(:path) || @name + @path = (options.delete(:path) || @name).to_s @controller = (options.delete(:controller) || plural).to_s @as = options.delete(:as) @options = options end - def member_name - name + def plural + @plural ||= name.to_s.pluralize end - alias :collection_name :member_name - def member_scope - path + def singular + @singular ||= name.to_s end - alias :nested_scope :member_scope + + alias :member_name :singular + alias :collection_name :singular + + alias :member_scope :path + alias :nested_scope :path end def initialize(*args) #:nodoc: @@ -586,10 +586,10 @@ module ActionDispatch end if parent_resource.actions.include?(:new) member_scope do + get :edit if parent_resource.actions.include?(:edit) get :show if parent_resource.actions.include?(:show) put :update if parent_resource.actions.include?(:update) delete :destroy if parent_resource.actions.include?(:destroy) - get :edit if parent_resource.actions.include?(:edit) end end @@ -616,10 +616,10 @@ module ActionDispatch end if parent_resource.actions.include?(:new) member_scope do + get :edit if parent_resource.actions.include?(:edit) get :show if parent_resource.actions.include?(:show) put :update if parent_resource.actions.include?(:update) delete :destroy if parent_resource.actions.include?(:destroy) - get :edit if parent_resource.actions.include?(:edit) end end @@ -731,6 +731,7 @@ module ActionDispatch end elsif resource_method_scope? path = path_for_custom_action + options[:action] ||= action options[:as] = name_for_action(options[:as]) if options[:as] args.push(options) @@ -773,6 +774,10 @@ module ActionDispatch return true end + options.each do |k,v| + (options[:constraints] ||= {})[k] = options.delete(k) if options[k].is_a?(Regexp) + end + scope_options = options.slice!(*RESOURCE_OPTIONS) unless scope_options.empty? scope(scope_options) do diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index b9d27be639..43ffadc004 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -538,7 +538,7 @@ module ActionView def extra_tags_for_form(html_options) snowman_tag = tag(:input, :type => "hidden", - :name => "_utf8", :value => "☃".html_safe) + :name => "utf8", :value => "✓".html_safe) method = html_options.delete("method").to_s diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 249fa406a0..546c4cb253 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -132,6 +132,32 @@ class RequestTest < ActiveSupport::TestCase assert_equal [], request.subdomains end + test "standard_port" do + request = stub_request + assert_equal 80, request.standard_port + + request = stub_request 'HTTPS' => 'on' + assert_equal 443, request.standard_port + end + + test "standard_port?" do + request = stub_request + assert !request.ssl? + assert request.standard_port? + + request = stub_request 'HTTPS' => 'on' + assert request.ssl? + assert request.standard_port? + + request = stub_request 'HTTP_HOST' => 'www.example.org:8080' + assert !request.ssl? + assert !request.standard_port? + + request = stub_request 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on' + assert request.ssl? + assert !request.standard_port? + end + test "port string" do request = stub_request 'HTTP_HOST' => 'www.example.org:80' assert_equal "", request.port_string @@ -223,6 +249,16 @@ class RequestTest < ActiveSupport::TestCase assert request.ssl? end + test "scheme returns https when proxied" do + request = stub_request 'rack.url_scheme' => 'http' + assert !request.ssl? + assert_equal 'http', request.scheme + + request = stub_request 'rack.url_scheme' => 'http', 'HTTP_X_FORWARDED_PROTO' => 'https' + assert request.ssl? + assert_equal 'https', request.scheme + end + test "String request methods" do [:get, :post, :put, :delete].each do |method| request = stub_request 'REQUEST_METHOD' => method.to_s.upcase diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 3f090b7254..44b83f3afc 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -45,6 +45,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match 'account/logout' => redirect("/logout"), :as => :logout_redirect match 'account/login', :to => redirect("/login") + match 'secure', :to => redirect("/secure/login") constraints(lambda { |req| true }) do match 'account/overview' @@ -128,7 +129,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end member do - get :some_path_with_name + get 'some_path_with_name' put :accessible_projects post :resend, :generate_new_password end @@ -337,6 +338,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest 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 @@ -371,6 +380,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest 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 @@ -405,6 +423,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + resources :sections, :id => /.+/ do + get :preview, :on => :member + end + match '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/ end end @@ -1884,11 +1906,126 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_resources_are_not_pluralized + with_test_routes do + 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 + end + + def test_singleton_resources_are_not_singularized + with_test_routes do + get '/medical/taxis/new' + assert_equal 'medical/taxes#new', @response.body + assert_equal '/medical/taxis/new', new_medical_taxis_path + + post '/medical/taxis' + assert_equal 'medical/taxes#create', @response.body + + get '/medical/taxis' + assert_equal 'medical/taxes#show', @response.body + assert_equal '/medical/taxis', medical_taxis_path + + get '/medical/taxis/edit' + assert_equal 'medical/taxes#edit', @response.body + assert_equal '/medical/taxis/edit', edit_medical_taxis_path + + put '/medical/taxis' + assert_equal 'medical/taxes#update', @response.body + + delete '/medical/taxis' + assert_equal 'medical/taxes#destroy', @response.body + end + end + + def test_greedy_resource_id_regexp_doesnt_match_edit_and_custom_action + with_test_routes do + 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 + end + + def test_resource_constraints_are_pushed_to_scope + with_test_routes do + 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 + end + + def test_resources_path_can_be_a_symbol + with_test_routes do + 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 + end + + def test_redirect_https + with_test_routes do + with_https do + get '/secure' + verify_redirect 'https://www.example.com/secure/login' + end + end + end + private def with_test_routes yield 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'] diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 4c81e691b2..71a5ae0245 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -1513,7 +1513,7 @@ class FormHelperTest < ActionView::TestCase def snowman(method = nil) txt = %{<div style="margin:0;padding:0;display:inline">} - txt << %{<input name="_utf8" type="hidden" value="☃" />} + txt << %{<input name="utf8" type="hidden" value="✓" />} txt << %{<input name="_method" type="hidden" value="#{method}" />} if method txt << %{</div>} end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index d2f725a994..532f086d21 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -12,7 +12,7 @@ class FormTagHelperTest < ActionView::TestCase method = options[:method] txt = %{<div style="margin:0;padding:0;display:inline">} - txt << %{<input name="_utf8" type="hidden" value="☃" />} + txt << %{<input name="utf8" type="hidden" value="✓" />} txt << %{<input name="_method" type="hidden" value="#{method}" />} if method txt << %{</div>} end |