diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2010-01-17 03:20:30 +0530 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2010-01-17 03:20:30 +0530 |
commit | b04230e3bbf912d60601e9e7b797c4cd43581d51 (patch) | |
tree | 97a2f784a2ec2bfae4f960af56a9280dad6f7774 /actionpack/test | |
parent | 867829b187969607aa12f2b0457f25da9c204db0 (diff) | |
parent | 6e3bee6cf1f0d2684152292db0a8b757249824fd (diff) | |
download | rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.tar.gz rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.tar.bz2 rails-b04230e3bbf912d60601e9e7b797c4cd43581d51.zip |
Merge remote branch 'mainstream/master'
Conflicts:
actionpack/lib/action_controller/metal/flash.rb
Diffstat (limited to 'actionpack/test')
35 files changed, 1335 insertions, 721 deletions
diff --git a/actionpack/test/abstract/url_for_test.rb b/actionpack/test/abstract/url_for_test.rb new file mode 100644 index 0000000000..e5570349b8 --- /dev/null +++ b/actionpack/test/abstract/url_for_test.rb @@ -0,0 +1,272 @@ +require 'abstract_unit' + +module AbstractController + module Testing + + class UrlForTests < ActionController::TestCase + class W + include AbstractController::UrlFor + end + + def teardown + W.default_url_options.clear + end + + def add_host! + W.default_url_options[:host] = 'www.basecamphq.com' + end + + def test_exception_is_thrown_without_host + assert_raise RuntimeError do + W.new.url_for :controller => 'c', :action => 'a', :id => 'i' + end + end + + def test_anchor + assert_equal('/c/a#anchor', + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => 'anchor') + ) + end + + def test_anchor_should_call_to_param + assert_equal('/c/a#anchor', + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anchor')) + ) + end + + def test_anchor_should_be_cgi_escaped + assert_equal('/c/a#anc%2Fhor', + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anc/hor')) + ) + end + + def test_default_host + add_host! + assert_equal('http://www.basecamphq.com/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i') + ) + end + + def test_host_may_be_overridden + add_host! + assert_equal('http://37signals.basecamphq.com/c/a/i', + W.new.url_for(:host => '37signals.basecamphq.com', :controller => 'c', :action => 'a', :id => 'i') + ) + end + + def test_port + add_host! + assert_equal('http://www.basecamphq.com:3000/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :port => 3000) + ) + end + + def test_protocol + add_host! + assert_equal('https://www.basecamphq.com/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') + ) + end + + def test_protocol_with_and_without_separator + add_host! + assert_equal('https://www.basecamphq.com/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') + ) + assert_equal('https://www.basecamphq.com/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https://') + ) + end + + def test_trailing_slash + add_host! + options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'} + assert_equal('http://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) ) + end + + def test_trailing_slash_with_protocol + add_host! + options = { :trailing_slash => true,:protocol => 'https', :controller => 'foo', :action => 'bar', :id => '33'} + assert_equal('https://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) ) + assert_equal 'https://www.basecamphq.com/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string'})) + end + + def test_trailing_slash_with_only_path + options = {:controller => 'foo', :trailing_slash => true} + assert_equal '/foo/', W.new.url_for(options.merge({:only_path => true})) + options.update({:action => 'bar', :id => '33'}) + assert_equal '/foo/bar/33/', W.new.url_for(options.merge({:only_path => true})) + assert_equal '/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string',:only_path => true})) + end + + def test_trailing_slash_with_anchor + options = {:trailing_slash => true, :controller => 'foo', :action => 'bar', :id => '33', :only_path => true, :anchor=> 'chapter7'} + assert_equal '/foo/bar/33/#chapter7', W.new.url_for(options) + assert_equal '/foo/bar/33/?query=string#chapter7', W.new.url_for(options.merge({:query => 'string'})) + end + + def test_trailing_slash_with_params + url = W.new.url_for(:trailing_slash => true, :only_path => true, :controller => 'cont', :action => 'act', :p1 => 'cafe', :p2 => 'link') + params = extract_params(url) + assert_equal params[0], { :p1 => 'cafe' }.to_query + assert_equal params[1], { :p2 => 'link' }.to_query + end + + def test_relative_url_root_is_respected + orig_relative_url_root = ActionController::Base.relative_url_root + ActionController::Base.relative_url_root = '/subdir' + + add_host! + assert_equal('https://www.basecamphq.com/subdir/c/a/i', + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') + ) + ensure + ActionController::Base.relative_url_root = orig_relative_url_root + end + + def test_named_routes + with_routing do |set| + set.draw do |map| + match 'this/is/verbose', :to => 'home#index', :as => :no_args + match 'home/sweet/home/:user', :to => 'home#index', :as => :home + end + + # We need to create a new class in order to install the new named route. + kls = Class.new { include AbstractController::UrlFor } + controller = kls.new + assert controller.respond_to?(:home_url) + assert_equal 'http://www.basecamphq.com/home/sweet/home/again', + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') + + assert_equal("/home/sweet/home/alabama", controller.send(:home_path, :user => 'alabama', :host => 'unused')) + assert_equal("http://www.basecamphq.com/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'www.basecamphq.com')) + assert_equal("http://www.basecamphq.com/this/is/verbose", controller.send(:no_args_url, :host=>'www.basecamphq.com')) + end + end + + def test_relative_url_root_is_respected_for_named_routes + orig_relative_url_root = ActionController::Base.relative_url_root + ActionController::Base.relative_url_root = '/subdir' + + with_routing do |set| + set.draw do |map| + match '/home/sweet/home/:user', :to => 'home#index', :as => :home + end + + kls = Class.new { include AbstractController::UrlFor } + controller = kls.new + + assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') + end + ensure + ActionController::Base.relative_url_root = orig_relative_url_root + end + + def test_only_path + with_routing do |set| + set.draw do |map| + match 'home/sweet/home/:user', :to => 'home#index', :as => :home + match ':controller/:action/:id' + end + + # We need to create a new class in order to install the new named route. + kls = Class.new { include AbstractController::UrlFor } + controller = kls.new + assert controller.respond_to?(:home_url) + assert_equal '/brave/new/world', + controller.send(:url_for, :controller => 'brave', :action => 'new', :id => 'world', :only_path => true) + + assert_equal("/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'unused', :only_path => true)) + assert_equal("/home/sweet/home/alabama", controller.send(:home_path, 'alabama')) + end + end + + def test_one_parameter + assert_equal('/c/a?param=val', + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') + ) + end + + def test_two_parameters + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') + params = extract_params(url) + assert_equal params[0], { :p1 => 'X1' }.to_query + assert_equal params[1], { :p2 => 'Y2' }.to_query + end + + def test_hash_parameter + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) + params = extract_params(url) + assert_equal params[0], { 'query[category]' => 'prof' }.to_query + assert_equal params[1], { 'query[name]' => 'Bob' }.to_query + end + + def test_array_parameter + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) + params = extract_params(url) + assert_equal params[0], { 'query[]' => 'Bob' }.to_query + assert_equal params[1], { 'query[]' => 'prof' }.to_query + end + + def test_hash_recursive_parameters + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) + params = extract_params(url) + assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query + assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query + assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query + end + + def test_hash_recursive_and_array_parameters + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) + assert_match %r(^/c/a/101), url + params = extract_params(url) + assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query + assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query + assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query + assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query + end + + def test_path_generation_for_symbol_parameter_keys + assert_generates("/image", :controller=> :image) + end + + def test_named_routes_with_nil_keys + with_routing do |set| + set.draw do |map| + match 'posts.:format', :to => 'posts#index', :as => :posts + match '/', :to => 'posts#index', :as => :main + end + + # We need to create a new class in order to install the new named route. + kls = Class.new { include AbstractController::UrlFor } + kls.default_url_options[:host] = 'www.basecamphq.com' + + controller = kls.new + params = {:action => :index, :controller => :posts, :format => :xml} + assert_equal("http://www.basecamphq.com/posts.xml", controller.send(:url_for, params)) + params[:format] = nil + assert_equal("http://www.basecamphq.com/", controller.send(:url_for, params)) + end + end + + def test_multiple_includes_maintain_distinct_options + first_class = Class.new { include AbstractController::UrlFor } + second_class = Class.new { include AbstractController::UrlFor } + + first_host, second_host = 'firsthost.com', 'secondhost.com' + + first_class.default_url_options[:host] = first_host + second_class.default_url_options[:host] = second_host + + assert_equal first_class.default_url_options[:host], first_host + assert_equal second_class.default_url_options[:host], second_host + end + + private + def extract_params(url) + url.split('?', 2).last.split('&').sort + end + end + end +end
\ No newline at end of file diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 8c65087898..10913c0fdb 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -19,8 +19,6 @@ require 'action_view' require 'action_view/base' require 'action_dispatch' require 'fixture_template' -require 'active_support/test_case' -require 'action_view/test_case' require 'active_support/dependencies' activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) @@ -50,14 +48,6 @@ ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') FIXTURES = Pathname.new(FIXTURE_LOAD_PATH) -# Turn on notifications -require 'active_support/notifications' -Thread.abort_on_exception = true - -ActiveSupport::Notifications.subscribe do |*args| - ActionController::Base.log_event(*args) if ActionController::Base.logger -end - module SetupOnce extend ActiveSupport::Concern @@ -95,29 +85,15 @@ class ActiveSupport::TestCase end end -class MockLogger - attr_reader :logged - attr_accessor :level - - def initialize - @level = Logger::DEBUG - @logged = [] - end - - def method_missing(method, *args, &blk) - @logged << args.first - @logged << blk.call if block_given? - end -end - class ActionController::IntegrationTest < ActiveSupport::TestCase def self.build_app(routes = nil) + ActionDispatch::Flash ActionDispatch::MiddlewareStack.new { |middleware| - middleware.use "ActionDispatch::StringCoercion" middleware.use "ActionDispatch::ShowExceptions" middleware.use "ActionDispatch::Callbacks" middleware.use "ActionDispatch::ParamsParser" - middleware.use "Rack::Head" + middleware.use "ActionDispatch::Flash" + middleware.use "ActionDispatch::Head" }.build(routes || ActionController::Routing::Routes) end diff --git a/actionpack/test/active_record_unit.rb b/actionpack/test/active_record_unit.rb index 9a094cf66b..4f2b052720 100644 --- a/actionpack/test/active_record_unit.rb +++ b/actionpack/test/active_record_unit.rb @@ -17,7 +17,6 @@ unless defined?(ActiveRecord) && defined?(Fixtures) raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR) $LOAD_PATH.unshift PATH_TO_AR require 'active_record' - require 'active_record/fixtures' rescue LoadError => e $stderr.print "Failed to load Active Record. Skipping Active Record assertion tests: #{e}" ActiveRecordTestConnector.able_to_connect = false diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index 0f534da14b..37c7738301 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -1,39 +1,53 @@ require 'active_record_unit' require 'active_record/railties/controller_runtime' require 'fixtures/project' +require 'rails/subscriber/test_helper' +require 'action_controller/railties/subscriber' ActionController::Base.send :include, ActiveRecord::Railties::ControllerRuntime -class ARLoggingController < ActionController::Base - def show - render :inline => "<%= Project.all %>" +module ControllerRuntimeSubscriberTest + class SubscriberController < ActionController::Base + def show + render :inline => "<%= Project.all %>" + end end -end -class ARLoggingTest < ActionController::TestCase - tests ARLoggingController + def self.included(base) + base.tests SubscriberController + end def setup + @old_logger = ActionController::Base.logger + Rails::Subscriber.add(:action_controller, ActionController::Railties::Subscriber.new) super - set_logger end - def wait - ActiveSupport::Notifications.notifier.wait + def teardown + super + Rails::Subscriber.subscribers.clear + ActionController::Base.logger = @old_logger end + def set_logger(logger) + ActionController::Base.logger = logger + end + def test_log_with_active_record get :show wait - assert_match /ActiveRecord runtime/, logs[3] + + assert_equal 2, @logger.logged(:info).size + assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1] end - private - def set_logger - @controller.logger = MockLogger.new - end + class SyncSubscriberTest < ActionController::TestCase + include Rails::Subscriber::SyncTestHelper + include ControllerRuntimeSubscriberTest + end - def logs - @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} - end -end + class AsyncSubscriberTest < ActionController::TestCase + include Rails::Subscriber::AsyncTestHelper + include ControllerRuntimeSubscriberTest + end +end
\ No newline at end of file diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index ad744421db..ea82758cf5 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -26,7 +26,7 @@ class Series < ActiveRecord::Base end class PolymorphicRoutesTest < ActionController::TestCase - include ActionController::UrlWriter + include ActionController::UrlFor self.default_url_options[:host] = 'example.com' def setup diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 65118f9bc9..1510a6a7e0 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -6,6 +6,7 @@ require 'pp' # require 'pp' early to prevent hidden_methods from not picking up module Submodule class ContainedEmptyController < ActionController::Base end + class ContainedNonEmptyController < ActionController::Base def public_action render :nothing => true @@ -20,12 +21,15 @@ module Submodule end hide_action :another_hidden_action end + class SubclassedController < ContainedNonEmptyController hide_action :public_action # Hiding it here should not affect the superclass. end end + class EmptyController < ActionController::Base end + class NonEmptyController < ActionController::Base def public_action render :nothing => true @@ -37,7 +41,6 @@ class NonEmptyController < ActionController::Base end class MethodMissingController < ActionController::Base - hide_action :shouldnt_be_called def shouldnt_be_called raise "NO WAY!" @@ -48,16 +51,15 @@ protected def method_missing(selector) render :text => selector.to_s end - end class DefaultUrlOptionsController < ActionController::Base - def default_url_options_action - render :nothing => true + def from_view + render :inline => "<%= #{params[:route]} %>" end def default_url_options(options = nil) - { :host => 'www.override.com', :action => 'new', :bacon => 'chunky' } + { :host => 'www.override.com', :action => 'new', :locale => 'en' } end end @@ -68,6 +70,7 @@ class ControllerClassTests < Test::Unit::TestCase assert_equal 'submodule/contained_empty', Submodule::ContainedEmptyController.controller_path assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path end + def test_controller_name assert_equal 'empty', EmptyController.controller_name assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name @@ -86,41 +89,16 @@ class ControllerInstanceTests < Test::Unit::TestCase def test_action_methods @empty_controllers.each do |c| - hide_mocha_methods_from_controller(c) assert_equal Set.new, c.class.__send__(:action_methods), "#{c.controller_path} should be empty!" end + @non_empty_controllers.each do |c| - hide_mocha_methods_from_controller(c) assert_equal Set.new(%w(public_action)), c.class.__send__(:action_methods), "#{c.controller_path} should not be empty!" end end - - protected - # Mocha adds some public instance methods to Object that would be - # considered actions, so explicitly hide_action them. - def hide_mocha_methods_from_controller(controller) - mocha_methods = [ - :expects, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, - :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__, :to_matcher, - ] - controller.class.__send__(:hide_action, *mocha_methods) - end end - class PerformActionTest < ActionController::TestCase - class MockLogger - attr_reader :logged - - def initialize - @logged = [] - end - - def method_missing(method, *args) - @logged << args.first.to_s - end - end - def use_controller(controller_class) @controller = controller_class.new @@ -128,9 +106,8 @@ class PerformActionTest < ActionController::TestCase # a more accurate simulation of what happens in "real life". @controller.logger = Logger.new(nil) - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new @request.host = "www.nextangle.com" rescue_action_in_public! @@ -145,8 +122,7 @@ class PerformActionTest < ActionController::TestCase def test_method_missing_is_not_an_action_name use_controller MethodMissingController - - assert ! @controller.__send__(:action_method?, 'method_missing') + assert !@controller.__send__(:action_method?, 'method_missing') get :method_missing assert_response :success @@ -172,16 +148,43 @@ class DefaultUrlOptionsTest < ActionController::TestCase def test_default_url_options_are_used_if_set with_routing do |set| set.draw do |map| - match 'default_url_options', :to => 'default_url_options#default_url_options_action', :as => :default_url_options + match 'from_view', :to => 'default_url_options#from_view', :as => :from_view match ':controller/:action' end - get :default_url_options_action # Make a dummy request so that the controller is initialized properly. + get :from_view, :route => "from_view_url" - assert_equal 'http://www.override.com/default_url_options/new?bacon=chunky', @controller.url_for(:controller => 'default_url_options') - assert_equal 'http://www.override.com/default_url_options?bacon=chunky', @controller.send(:default_url_options_url) + assert_equal 'http://www.override.com/from_view?locale=en', @response.body + assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) + assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') end end + + def test_default_url_options_are_used_in_non_positional_parameters + with_routing do |set| + set.draw do |map| + scope("/:locale") do + resources :descriptions + end + match ':controller/:action' + end + + get :from_view, :route => "description_path(1)" + + assert_equal '/en/descriptions/1', @response.body + assert_equal '/en/descriptions', @controller.send(:descriptions_path) + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") + assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") + assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") + assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") + assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") + assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") + end + end + end class EmptyUrlOptionsTest < ActionController::TestCase @@ -197,15 +200,12 @@ class EmptyUrlOptionsTest < ActionController::TestCase get :public_action assert_equal "http://www.example.com/non_empty/public_action", @controller.url_for end -end -class EnsureNamedRoutesWorksTicket22BugTest < ActionController::TestCase - def test_named_routes_still_work + def test_named_routes_with_path_without_doing_a_request_first with_routing do |set| set.draw do |map| resources :things end - EmptyController.send :include, ActionController::UrlWriter assert_equal '/things', EmptyController.new.send(:things_path) end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 679eaf7b38..8a13d1e5f1 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -629,20 +629,6 @@ class FragmentCachingTest < ActionController::TestCase assert_equal 'generated till now -> fragment content', buffer end - def test_fragment_for_logging - fragment_computed = false - events = [] - ActiveSupport::Notifications.subscribe { |*args| events << args } - - buffer = 'generated till now -> ' - @controller.fragment_for(buffer, 'expensive') { fragment_computed = true } - - assert fragment_computed - assert_equal 'generated till now -> ', buffer - ActiveSupport::Notifications.notifier.wait - assert_equal [:exist_fragment?, :write_fragment], events.map(&:first) - end - end class FunctionalCachingController < ActionController::Base diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb index 64f1ad7610..7e19bce3b7 100644 --- a/actionpack/test/controller/dispatcher_test.rb +++ b/actionpack/test/controller/dispatcher_test.rb @@ -1,73 +1,59 @@ require 'abstract_unit' -class DispatcherTest < Test::Unit::TestCase - Dispatcher = ActionController::Dispatcher - - class Foo - cattr_accessor :a, :b - end +# Ensure deprecated dispatcher works +class DeprecatedDispatcherTest < ActiveSupport::TestCase + class DummyApp + def call(env) + [200, {}, 'response'] + end + end def setup - ENV['REQUEST_METHOD'] = 'GET' - - # Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks ActionDispatch::Callbacks.reset_callbacks(:prepare) ActionDispatch::Callbacks.reset_callbacks(:call) - - ActionController::Routing::Routes.stubs(:call).returns([200, {}, 'response']) - Dispatcher.stubs(:require_dependency) end - def teardown - ENV.delete 'REQUEST_METHOD' - end + def test_assert_deprecated_to_prepare + a = nil + + assert_deprecated do + ActionController::Dispatcher.to_prepare { a = 1 } + end - def test_clears_dependencies_after_dispatch_if_in_loading_mode - ActiveSupport::Dependencies.expects(:clear).once - dispatch(false) + assert_nil a + dispatch + assert_equal 1, a end - def test_prepare_callbacks - a = b = c = nil - ActionDispatch::Callbacks.to_prepare { |*args| a = b = c = 1 } - ActionDispatch::Callbacks.to_prepare { |*args| b = c = 2 } - ActionDispatch::Callbacks.to_prepare { |*args| c = 3 } + def test_assert_deprecated_before_dispatch + a = nil - # Ensure to_prepare callbacks are not run when defined - assert_nil a || b || c + assert_deprecated do + ActionController::Dispatcher.before_dispatch { a = 1 } + end - # Run callbacks + assert_nil a dispatch - assert_equal 1, a - assert_equal 2, b - assert_equal 3, c - - # Make sure they are only run once - a = b = c = nil - dispatch - assert_nil a || b || c end - def test_to_prepare_with_identifier_replaces - ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a, Foo.b = 1, 1 } - ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a = 2 } + def test_assert_deprecated_after_dispatch + a = nil + + assert_deprecated do + ActionController::Dispatcher.after_dispatch { a = 1 } + end + assert_nil a dispatch - assert_equal 2, Foo.a - assert_equal nil, Foo.b + assert_equal 1, a end private - def dispatch(cache_classes = true) - ActionController::Dispatcher.prepare_each_request = false - Dispatcher.define_dispatcher_callbacks(cache_classes) - @dispatcher ||= ActionDispatch::Callbacks.new(ActionController::Routing::Routes) - @dispatcher.call({'rack.input' => StringIO.new(''), 'action_dispatch.show_exceptions' => false}) + def dispatch(cache_classes = true) + @dispatcher ||= ActionDispatch::Callbacks.new(DummyApp.new, !cache_classes) + @dispatcher.call({'rack.input' => StringIO.new('')}) end - def assert_subclasses(howmany, klass, message = klass.subclasses.inspect) - assert_equal howmany, klass.subclasses.size, message - end end diff --git a/actionpack/test/controller/filter_params_test.rb b/actionpack/test/controller/filter_params_test.rb index 420ebeacf4..d0635669c2 100644 --- a/actionpack/test/controller/filter_params_test.rb +++ b/actionpack/test/controller/filter_params_test.rb @@ -66,18 +66,6 @@ class FilterParamTest < ActionController::TestCase assert_raise(NoMethodError) { @controller.filter_parameters([{'password' => '[FILTERED]'}]) } end - def test_filter_parameters_inside_logs - FilterParamController.filter_parameter_logging(:lifo, :amount) - - get :payment, :lifo => 'Pratik', :amount => '420', :step => '1' - ActiveSupport::Notifications.notifier.wait - - filtered_params_logs = logs.detect {|l| l =~ /\AParameters/ } - assert filtered_params_logs.index('"amount"=>"[FILTERED]"') - assert filtered_params_logs.index('"lifo"=>"[FILTERED]"') - assert filtered_params_logs.index('"step"=>"1"') - end - private def set_logger diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index a9b60386f1..85a2e7f44b 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -159,7 +159,7 @@ class FlashTest < ActionController::TestCase end def test_keep_and_discard_return_values - flash = ActionController::Flash::FlashHash.new + flash = ActionDispatch::Flash::FlashHash.new flash.update(:foo => :foo_indeed, :bar => :bar_indeed) assert_equal(:foo_indeed, flash.discard(:foo)) # valid key passed @@ -187,4 +187,42 @@ class FlashTest < ActionController::TestCase get :redirect_with_other_flashes assert_equal "Horses!", @controller.send(:flash)[:joyride] end -end
\ No newline at end of file +end + +class FlashIntegrationTest < ActionController::IntegrationTest + SessionKey = '_myapp_session' + SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33' + + class TestController < ActionController::Base + def set_flash + flash["that"] = "hello" + head :ok + end + + def use_flash + render :inline => "flash: #{flash["that"]}" + end + end + + def test_flash + with_test_route_set do + get '/set_flash' + assert_response :success + assert_equal "hello", @request.flash["that"] + + get '/use_flash' + assert_response :success + assert_equal "flash: hello", @response.body + end + end + + private + def with_test_route_set + with_routing do |set| + set.draw do |map| + match ':action', :to => ActionDispatch::Session::CookieStore.new(TestController, :key => SessionKey, :secret => SessionSecret) + end + yield + end + end +end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 624b14e69b..683ab5236c 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -254,6 +254,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest render :text => "Created", :status => 201 end + def method + render :text => "method: #{request.method}" + end + def cookie_monster cookies["cookie_1"] = nil cookies["cookie_3"] = "chocolate" @@ -379,6 +383,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest head '/post' assert_equal 201, status assert_equal "", body + + get '/get/method' + assert_equal 200, status + assert_equal "method: get", body + + head '/get/method' + assert_equal 200, status + assert_equal "", body end end @@ -391,6 +403,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest with_routing do |set| set.draw do |map| match ':action', :to => ::IntegrationProcessTest::IntegrationController + get 'get/:action', :to => ::IntegrationProcessTest::IntegrationController end yield end diff --git a/actionpack/test/controller/logging_test.rb b/actionpack/test/controller/logging_test.rb deleted file mode 100644 index 4206dffa7e..0000000000 --- a/actionpack/test/controller/logging_test.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'abstract_unit' - -module Another - class LoggingController < ActionController::Base - layout "layouts/standard" - - def show - render :nothing => true - end - - def with_layout - render :template => "test/hello_world", :layout => true - end - end -end - -class LoggingTest < ActionController::TestCase - tests Another::LoggingController - - def setup - super - set_logger - end - - def get(*args) - super - wait - end - - def wait - ActiveSupport::Notifications.notifier.wait - end - - def test_logging_without_parameters - get :show - assert_equal 4, logs.size - assert_nil logs.detect {|l| l =~ /Parameters/ } - end - - def test_logging_with_parameters - get :show, :id => '10' - assert_equal 5, logs.size - - params = logs.detect {|l| l =~ /Parameters/ } - assert_equal 'Parameters: {"id"=>"10"}', params - end - - def test_log_controller_with_namespace_and_action - get :show - assert_match /Processed\sAnother::LoggingController#show/, logs[1] - end - - def test_log_view_runtime - get :show - assert_match /View runtime/, logs[2] - end - - def test_log_completed_status_and_request_uri - get :show - last = logs.last - assert_match /Completed/, last - assert_match /200/, last - assert_match /another\/logging\/show/, last - end - - def test_logger_prints_layout_and_template_rendering_info - get :with_layout - logged = logs.find {|l| l =~ /render/i } - assert_match /Rendered (.*)test\/hello_world.erb within (.*)layouts\/standard.html.erb/, logged - end - - private - def set_logger - @controller.logger = MockLogger.new - end - - def logs - @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} - end -end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 6b9cace9cd..ba2347e4e2 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -461,31 +461,27 @@ end class RespondWithController < ActionController::Base respond_to :html, :json - respond_to :xml, :except => :using_defaults - respond_to :js, :only => [ :using_defaults, :using_resource ] + respond_to :xml, :except => :using_resource_with_block + respond_to :js, :only => [ :using_resource_with_block, :using_resource ] - def using_defaults - respond_to do |format| - format.csv { render :text => "CSV" } - end + def using_resource + respond_with(resource) end - def using_defaults_with_type_list - respond_to(:js, :xml) + def using_resource_with_block + respond_with(resource) do |format| + format.csv { render :text => "CSV" } + end end - def default_overwritten - respond_to do |format| + def using_resource_with_overwrite_block + respond_with(resource) do |format| format.html { render :text => "HTML" } end end - def using_resource - respond_with(Customer.new("david", 13)) - end - def using_resource_with_collection - respond_with([Customer.new("david", 13), Customer.new("jamis", 9)]) + respond_with([resource, Customer.new("jamis", 9)]) end def using_resource_with_parent @@ -493,16 +489,16 @@ class RespondWithController < ActionController::Base end def using_resource_with_status_and_location - respond_with(Customer.new("david", 13), :location => "http://test.host/", :status => :created) + respond_with(resource, :location => "http://test.host/", :status => :created) end def using_resource_with_responder responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" } - respond_with(Customer.new("david", 13), :responder => responder) + respond_with(resource, :responder => responder) end def using_resource_with_action - respond_with(Customer.new("david", 13), :action => :foo) do |format| + respond_with(resource, :action => :foo) do |format| format.html { raise ActionView::MissingTemplate.new([], "method") } end end @@ -511,11 +507,15 @@ class RespondWithController < ActionController::Base responder = Class.new(ActionController::Responder) do def respond; @controller.render :text => "respond #{format}"; end end - respond_with(Customer.new("david", 13), :responder => responder) + respond_with(resource, :responder => responder) end protected + def resource + Customer.new("david", 13) + end + def _render_js(js, options) self.content_type ||= Mime::JS self.response_body = js.respond_to?(:to_js) ? js.to_js : js @@ -527,12 +527,18 @@ class InheritedRespondWithController < RespondWithController respond_to :xml, :json def index - respond_with(Customer.new("david", 13)) do |format| + respond_with(resource) do |format| format.json { render :text => "JSON" } end end end +class EmptyRespondWithController < ActionController::Base + def index + respond_with(Customer.new("david", 13)) + end +end + class RespondWithControllerTest < ActionController::TestCase tests RespondWithController @@ -547,56 +553,54 @@ class RespondWithControllerTest < ActionController::TestCase ActionController::Base.use_accept_header = false end - def test_using_defaults + def test_using_resource + @request.accept = "text/javascript" + get :using_resource + assert_equal "text/javascript", @response.content_type + assert_equal '$("body").visualEffect("highlight");', @response.body + + @request.accept = "application/xml" + get :using_resource + assert_equal "application/xml", @response.content_type + assert_equal "<name>david</name>", @response.body + + @request.accept = "application/json" + assert_raise ActionView::MissingTemplate do + get :using_resource + end + end + + def test_using_resource_with_block @request.accept = "*/*" - get :using_defaults + get :using_resource_with_block assert_equal "text/html", @response.content_type assert_equal 'Hello world!', @response.body @request.accept = "text/csv" - get :using_defaults + get :using_resource_with_block assert_equal "text/csv", @response.content_type assert_equal "CSV", @response.body - @request.accept = "text/javascript" - get :using_defaults - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - end - - def test_using_defaults_with_type_list - @request.accept = "*/*" - get :using_defaults_with_type_list - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - @request.accept = "application/xml" - get :using_defaults_with_type_list + get :using_resource assert_equal "application/xml", @response.content_type - assert_equal "<p>Hello world!</p>\n", @response.body + assert_equal "<name>david</name>", @response.body end - def test_default_overwritten - get :default_overwritten + def test_using_resource_with_overwrite_block + get :using_resource_with_overwrite_block assert_equal "text/html", @response.content_type assert_equal "HTML", @response.body end - def test_using_resource - @request.accept = "text/javascript" - get :using_resource - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - + def test_not_acceptable @request.accept = "application/xml" - get :using_resource - assert_equal "application/xml", @response.content_type - assert_equal "<name>david</name>", @response.body + get :using_resource_with_block + assert_equal 406, @response.status - @request.accept = "application/json" - assert_raise ActionView::MissingTemplate do - get :using_resource - end + @request.accept = "text/javascript" + get :using_resource_with_overwrite_block + assert_equal 406, @response.status end def test_using_resource_for_post_with_html_redirects_on_success @@ -831,22 +835,12 @@ class RespondWithControllerTest < ActionController::TestCase RespondWithController.responder = ActionController::Responder end - def test_not_acceptable - @request.accept = "application/xml" - get :using_defaults - assert_equal 406, @response.status - - @request.accept = "text/html" - get :using_defaults_with_type_list - assert_equal 406, @response.status - - @request.accept = "application/json" - get :using_defaults_with_type_list - assert_equal 406, @response.status - - @request.accept = "text/javascript" - get :default_overwritten - assert_equal 406, @response.status + def test_error_is_raised_if_no_respond_to_is_declared_and_respond_with_is_called + @controller = EmptyRespondWithController.new + @request.accept = "*/*" + assert_raise RuntimeError do + get :index + end end private diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 1a03396ae9..01ed491732 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -30,16 +30,6 @@ module Backoffice end class ResourcesTest < ActionController::TestCase - # The assertions in these tests are incompatible with the hash method - # optimisation. This could indicate user level problems - def setup - ActionController::Base.optimise_named_routes = false - end - - def teardown - ActionController::Base.optimise_named_routes = true - end - def test_should_arrange_actions resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, :collection => { :rss => :get, :reorder => :post, :csv => :post }, @@ -304,27 +294,27 @@ class ResourcesTest < ActionController::TestCase end end - def test_member_when_changed_default_restful_actions_and_path_names_not_specified - default_path_names = ActionController::Base.resources_path_names - ActionController::Base.resources_path_names = {:new => 'nuevo', :edit => 'editar'} - - with_restful_routing :messages do - new_options = { :action => 'new', :controller => 'messages' } - new_path = "/messages/nuevo" - edit_options = { :action => 'edit', :id => '1', :controller => 'messages' } - edit_path = "/messages/1/editar" - - assert_restful_routes_for :messages do |options| - assert_recognizes(options.merge(new_options), :path => new_path, :method => :get) - end - - assert_restful_routes_for :messages do |options| - assert_recognizes(options.merge(edit_options), :path => edit_path, :method => :get) - end - end - ensure - ActionController::Base.resources_path_names = default_path_names - end + # def test_member_when_changed_default_restful_actions_and_path_names_not_specified + # default_path_names = ActionController::Base.resources_path_names + # ActionController::Base.resources_path_names = {:new => 'nuevo', :edit => 'editar'} + # + # with_restful_routing :messages do + # new_options = { :action => 'new', :controller => 'messages' } + # new_path = "/messages/nuevo" + # edit_options = { :action => 'edit', :id => '1', :controller => 'messages' } + # edit_path = "/messages/1/editar" + # + # assert_restful_routes_for :messages do |options| + # assert_recognizes(options.merge(new_options), :path => new_path, :method => :get) + # end + # + # assert_restful_routes_for :messages do |options| + # assert_recognizes(options.merge(edit_options), :path => edit_path, :method => :get) + # end + # end + # ensure + # ActionController::Base.resources_path_names = default_path_names + # end def test_with_two_member_actions_with_same_method [:put, :post].each do |method| diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index c15eaade58..f390bbdc89 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -82,9 +82,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase attr_reader :rs def setup - # These tests assume optimisation is on, so re-enable it. - ActionController::Base.optimise_named_routes = true - @rs = ::ActionController::Routing::RouteSet.new end @@ -632,7 +629,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase end def test_routes_changed_correctly_after_clear - ActionController::Base.optimise_named_routes = true rs = ::ActionController::Routing::RouteSet.new rs.draw do |r| r.connect 'ca', :controller => 'ca', :action => "aa" diff --git a/actionpack/test/controller/subscriber_test.rb b/actionpack/test/controller/subscriber_test.rb new file mode 100644 index 0000000000..ef1a325799 --- /dev/null +++ b/actionpack/test/controller/subscriber_test.rb @@ -0,0 +1,192 @@ +require "abstract_unit" +require "rails/subscriber/test_helper" +require "action_controller/railties/subscriber" + +module Another + class SubscribersController < ActionController::Base + def show + render :nothing => true + end + + def redirector + redirect_to "http://foo.bar/" + end + + def data_sender + send_data "cool data", :filename => "omg.txt" + end + + def xfile_sender + send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH), :x_sendfile => true + end + + def file_sender + send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH) + end + + def with_fragment_cache + render :inline => "<%= cache('foo'){ 'bar' } %>" + end + + def with_page_cache + cache_page("Super soaker", "/index.html") + render :nothing => true + end + end +end + +module ActionControllerSubscriberTest + + def self.included(base) + base.tests Another::SubscribersController + end + + def setup + @old_logger = ActionController::Base.logger + + @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) + ActionController::Base.page_cache_directory = @cache_path + ActionController::Base.cache_store = :file_store, @cache_path + + Rails::Subscriber.add(:action_controller, ActionController::Railties::Subscriber.new) + super + end + + def teardown + super + Rails::Subscriber.subscribers.clear + FileUtils.rm_rf(@cache_path) + ActionController::Base.logger = @old_logger + end + + def set_logger(logger) + ActionController::Base.logger = logger + end + + def test_process_action + get :show + wait + assert_equal 2, logs.size + assert_match /Processed\sAnother::SubscribersController#show/, logs[0] + end + + def test_process_action_formats + get :show + wait + assert_equal 2, logs.size + assert_match /text\/html/, logs[0] + end + + def test_process_action_without_parameters + get :show + wait + assert_nil logs.detect {|l| l =~ /Parameters/ } + end + + def test_process_action_with_parameters + get :show, :id => '10' + wait + + assert_equal 3, logs.size + assert_equal 'Parameters: {"id"=>"10"}', logs[1] + end + + def test_process_action_with_view_runtime + get :show + wait + assert_match /\(Views: [\d\.]+ms\)/, logs[1] + end + + def test_process_action_with_status_and_request_uri + get :show + wait + last = logs.last + assert_match /Completed/, last + assert_match /200/, last + assert_match /another\/subscribers\/show/, last + end + + def test_process_action_with_filter_parameters + Another::SubscribersController.filter_parameter_logging(:lifo, :amount) + + get :show, :lifo => 'Pratik', :amount => '420', :step => '1' + wait + + params = logs[1] + assert_match /"amount"=>"\[FILTERED\]"/, params + assert_match /"lifo"=>"\[FILTERED\]"/, params + assert_match /"step"=>"1"/, params + end + + def test_redirect_to + get :redirector + wait + + assert_equal 3, logs.size + assert_equal "Redirected to http://foo.bar/", logs[0] + end + + def test_send_data + get :data_sender + wait + + assert_equal 3, logs.size + assert_match /Sent data omg\.txt/, logs[0] + end + + def test_send_file + get :file_sender + wait + + assert_equal 3, logs.size + assert_match /Sent file/, logs[0] + assert_match /test\/fixtures\/company\.rb/, logs[0] + end + + def test_send_xfile + get :xfile_sender + wait + + assert_equal 3, logs.size + assert_match /Sent X\-Sendfile header/, logs[0] + assert_match /test\/fixtures\/company\.rb/, logs[0] + end + + def test_with_fragment_cache + ActionController::Base.perform_caching = true + get :with_fragment_cache + wait + + assert_equal 4, logs.size + assert_match /Exist fragment\? views\/foo/, logs[0] + assert_match /Write fragment views\/foo/, logs[1] + ensure + ActionController::Base.perform_caching = true + end + + def test_with_page_cache + ActionController::Base.perform_caching = true + get :with_page_cache + wait + + assert_equal 3, logs.size + assert_match /Write page/, logs[0] + assert_match /\/index\.html/, logs[0] + ensure + ActionController::Base.perform_caching = true + end + + def logs + @logs ||= @logger.logged(:info) + end + + class SyncSubscriberTest < ActionController::TestCase + include Rails::Subscriber::SyncTestHelper + include ActionControllerSubscriberTest + end + + class AsyncSubscriberTest < ActionController::TestCase + include Rails::Subscriber::AsyncTestHelper + include ActionControllerSubscriberTest + end +end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 428f40b9f8..c2b8cd85d8 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -100,286 +100,3 @@ class UrlRewriterTests < ActionController::TestCase end end -class UrlWriterTests < ActionController::TestCase - class W - include ActionController::UrlWriter - end - - def teardown - W.default_url_options.clear - end - - def add_host! - W.default_url_options[:host] = 'www.basecamphq.com' - end - - def test_exception_is_thrown_without_host - assert_raise RuntimeError do - W.new.url_for :controller => 'c', :action => 'a', :id => 'i' - end - end - - def test_anchor - assert_equal('/c/a#anchor', - W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => 'anchor') - ) - end - - def test_anchor_should_call_to_param - assert_equal('/c/a#anchor', - W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anchor')) - ) - end - - def test_anchor_should_be_cgi_escaped - assert_equal('/c/a#anc%2Fhor', - W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anc/hor')) - ) - end - - def test_default_host - add_host! - assert_equal('http://www.basecamphq.com/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i') - ) - end - - def test_host_may_be_overridden - add_host! - assert_equal('http://37signals.basecamphq.com/c/a/i', - W.new.url_for(:host => '37signals.basecamphq.com', :controller => 'c', :action => 'a', :id => 'i') - ) - end - - def test_port - add_host! - assert_equal('http://www.basecamphq.com:3000/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :port => 3000) - ) - end - - def test_protocol - add_host! - assert_equal('https://www.basecamphq.com/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') - ) - end - - def test_protocol_with_and_without_separator - add_host! - assert_equal('https://www.basecamphq.com/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') - ) - assert_equal('https://www.basecamphq.com/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https://') - ) - end - - def test_trailing_slash - add_host! - options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'} - assert_equal('http://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) ) - end - - def test_trailing_slash_with_protocol - add_host! - options = { :trailing_slash => true,:protocol => 'https', :controller => 'foo', :action => 'bar', :id => '33'} - assert_equal('https://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) ) - assert_equal 'https://www.basecamphq.com/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string'})) - end - - def test_trailing_slash_with_only_path - options = {:controller => 'foo', :trailing_slash => true} - assert_equal '/foo/', W.new.url_for(options.merge({:only_path => true})) - options.update({:action => 'bar', :id => '33'}) - assert_equal '/foo/bar/33/', W.new.url_for(options.merge({:only_path => true})) - assert_equal '/foo/bar/33/?query=string', W.new.url_for(options.merge({:query => 'string',:only_path => true})) - end - - def test_trailing_slash_with_anchor - options = {:trailing_slash => true, :controller => 'foo', :action => 'bar', :id => '33', :only_path => true, :anchor=> 'chapter7'} - assert_equal '/foo/bar/33/#chapter7', W.new.url_for(options) - assert_equal '/foo/bar/33/?query=string#chapter7', W.new.url_for(options.merge({:query => 'string'})) - end - - def test_trailing_slash_with_params - url = W.new.url_for(:trailing_slash => true, :only_path => true, :controller => 'cont', :action => 'act', :p1 => 'cafe', :p2 => 'link') - params = extract_params(url) - assert_equal params[0], { :p1 => 'cafe' }.to_query - assert_equal params[1], { :p2 => 'link' }.to_query - end - - def test_relative_url_root_is_respected - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' - - add_host! - assert_equal('https://www.basecamphq.com/subdir/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') - ) - ensure - ActionController::Base.relative_url_root = orig_relative_url_root - end - - def test_named_routes - with_routing do |set| - set.draw do |map| - match 'this/is/verbose', :to => 'home#index', :as => :no_args - match 'home/sweet/home/:user', :to => 'home#index', :as => :home - end - - # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlWriter } - controller = kls.new - assert controller.respond_to?(:home_url) - assert_equal 'http://www.basecamphq.com/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') - - assert_equal("/home/sweet/home/alabama", controller.send(:home_path, :user => 'alabama', :host => 'unused')) - assert_equal("http://www.basecamphq.com/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'www.basecamphq.com')) - assert_equal("http://www.basecamphq.com/this/is/verbose", controller.send(:no_args_url, :host=>'www.basecamphq.com')) - end - end - - def test_relative_url_root_is_respected_for_named_routes - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' - - with_routing do |set| - set.draw do |map| - match '/home/sweet/home/:user', :to => 'home#index', :as => :home - end - - kls = Class.new { include ActionController::UrlWriter } - controller = kls.new - - assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') - end - ensure - ActionController::Base.relative_url_root = orig_relative_url_root - end - - def test_only_path - with_routing do |set| - set.draw do |map| - match 'home/sweet/home/:user', :to => 'home#index', :as => :home - match ':controller/:action/:id' - end - - # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlWriter } - controller = kls.new - assert controller.respond_to?(:home_url) - assert_equal '/brave/new/world', - controller.send(:url_for, :controller => 'brave', :action => 'new', :id => 'world', :only_path => true) - - assert_equal("/home/sweet/home/alabama", controller.send(:home_url, :user => 'alabama', :host => 'unused', :only_path => true)) - assert_equal("/home/sweet/home/alabama", controller.send(:home_path, 'alabama')) - end - end - - def test_one_parameter - assert_equal('/c/a?param=val', - W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') - ) - end - - def test_two_parameters - url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') - params = extract_params(url) - assert_equal params[0], { :p1 => 'X1' }.to_query - assert_equal params[1], { :p2 => 'Y2' }.to_query - end - - def test_hash_parameter - url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) - params = extract_params(url) - assert_equal params[0], { 'query[category]' => 'prof' }.to_query - assert_equal params[1], { 'query[name]' => 'Bob' }.to_query - end - - def test_array_parameter - url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) - params = extract_params(url) - assert_equal params[0], { 'query[]' => 'Bob' }.to_query - assert_equal params[1], { 'query[]' => 'prof' }.to_query - end - - def test_hash_recursive_parameters - url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) - params = extract_params(url) - assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query - assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query - assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query - end - - def test_hash_recursive_and_array_parameters - url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) - assert_match %r(^/c/a/101), url - params = extract_params(url) - assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query - assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query - assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query - assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query - end - - def test_path_generation_for_symbol_parameter_keys - assert_generates("/image", :controller=> :image) - end - - def test_named_routes_with_nil_keys - with_routing do |set| - set.draw do |map| - match 'posts.:format', :to => 'posts#index', :as => :posts - match '/', :to => 'posts#index', :as => :main - end - - # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlWriter } - kls.default_url_options[:host] = 'www.basecamphq.com' - - controller = kls.new - params = {:action => :index, :controller => :posts, :format => :xml} - assert_equal("http://www.basecamphq.com/posts.xml", controller.send(:url_for, params)) - params[:format] = nil - assert_equal("http://www.basecamphq.com/", controller.send(:url_for, params)) - end - end - - def test_formatted_url_methods_are_deprecated - with_routing do |set| - set.draw do |map| - resources :posts - end - # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlWriter } - controller = kls.new - params = {:id => 1, :format => :xml} - assert_deprecated do - assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params)) - end - assert_deprecated do - assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml)) - end - end - end - - def test_multiple_includes_maintain_distinct_options - first_class = Class.new { include ActionController::UrlWriter } - second_class = Class.new { include ActionController::UrlWriter } - - first_host, second_host = 'firsthost.com', 'secondhost.com' - - first_class.default_url_options[:host] = first_host - second_class.default_url_options[:host] = second_host - - assert_equal first_class.default_url_options[:host], first_host - assert_equal second_class.default_url_options[:host], second_host - end - - private - def extract_params(url) - url.split('?', 2).last.split('&').sort - end -end diff --git a/actionpack/test/dispatch/callbacks_test.rb b/actionpack/test/dispatch/callbacks_test.rb new file mode 100644 index 0000000000..f3ea5209f4 --- /dev/null +++ b/actionpack/test/dispatch/callbacks_test.rb @@ -0,0 +1,107 @@ +require 'abstract_unit' + +class DispatcherTest < Test::Unit::TestCase + class Foo + cattr_accessor :a, :b + end + + class DummyApp + def call(env) + [200, {}, 'response'] + end + end + + def setup + Foo.a, Foo.b = 0, 0 + ActionDispatch::Callbacks.reset_callbacks(:prepare) + ActionDispatch::Callbacks.reset_callbacks(:call) + end + + def test_prepare_callbacks_with_cache_classes + a = b = c = nil + ActionDispatch::Callbacks.to_prepare { |*args| a = b = c = 1 } + ActionDispatch::Callbacks.to_prepare { |*args| b = c = 2 } + ActionDispatch::Callbacks.to_prepare { |*args| c = 3 } + + # Ensure to_prepare callbacks are not run when defined + assert_nil a || b || c + + # Run callbacks + dispatch + + assert_equal 1, a + assert_equal 2, b + assert_equal 3, c + + # Make sure they are only run once + a = b = c = nil + dispatch + assert_nil a || b || c + end + + def test_prepare_callbacks_without_cache_classes + a = b = c = nil + ActionDispatch::Callbacks.to_prepare { |*args| a = b = c = 1 } + ActionDispatch::Callbacks.to_prepare { |*args| b = c = 2 } + ActionDispatch::Callbacks.to_prepare { |*args| c = 3 } + + # Ensure to_prepare callbacks are not run when defined + assert_nil a || b || c + + # Run callbacks + dispatch(false) + + assert_equal 1, a + assert_equal 2, b + assert_equal 3, c + + # Make sure they are run again + a = b = c = nil + dispatch(false) + assert_equal 1, a + assert_equal 2, b + assert_equal 3, c + end + + def test_to_prepare_with_identifier_replaces + ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a, Foo.b = 1, 1 } + ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a = 2 } + + dispatch + assert_equal 2, Foo.a + assert_equal 0, Foo.b + end + + def test_before_and_after_callbacks + ActionDispatch::Callbacks.before { |*args| Foo.a += 1; Foo.b += 1 } + ActionDispatch::Callbacks.after { |*args| Foo.a += 1; Foo.b += 1 } + + dispatch + assert_equal 2, Foo.a + assert_equal 2, Foo.b + + dispatch + assert_equal 4, Foo.a + assert_equal 4, Foo.b + end + + def test_should_send_an_instrumentation_callback_for_async_processing + ActiveSupport::Notifications.expects(:instrument).with("action_dispatch.callback") + dispatch + end + + def test_should_send_an_instrumentation_callback_for_async_processing_even_on_failure + ActiveSupport::Notifications.notifier.expects(:publish) + assert_raise RuntimeError do + dispatch { |env| raise "OMG" } + end + end + + private + + def dispatch(cache_classes = true, &block) + @dispatcher ||= ActionDispatch::Callbacks.new(block || DummyApp.new, !cache_classes) + @dispatcher.call({'rack.input' => StringIO.new('')}) + end + +end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index b62df9a6b2..cb95ecea50 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -319,7 +319,7 @@ class RequestTest < ActiveSupport::TestCase end test "allow method hacking on post" do - [:get, :head, :options, :put, :post, :delete].each do |method| + [:get, :options, :put, :post, :delete].each do |method| request = stub_request "REQUEST_METHOD" => method.to_s.upcase assert_equal(method == :head ? :get : method, request.method) end @@ -341,7 +341,7 @@ class RequestTest < ActiveSupport::TestCase end test "head masquerading as get" do - request = stub_request 'REQUEST_METHOD' => 'HEAD' + request = stub_request 'REQUEST_METHOD' => 'GET', "rack.methodoverride.original_method" => "HEAD" assert_equal :get, request.method assert request.get? assert request.head? diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index c4b0b9cdbf..6dccabdb3f 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -22,6 +22,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest delete 'logout' => :destroy, :as => :logout end + resource :session do + get :create + end + match 'account/logout' => redirect("/logout"), :as => :logout_redirect match 'account/login', :to => redirect("/login") @@ -29,6 +33,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match 'account/modulo/:name', :to => redirect("/%{name}s") match 'account/proc/:name', :to => redirect {|params| "/#{params[:name].pluralize}" } + match 'account/google' => redirect('http://www.google.com/') match 'openid/login', :via => [:get, :post], :to => "openid#login" @@ -47,6 +52,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest get 'admin/accounts' => "queenbee#accounts" end + scope 'es' do + resources :projects, :path_names => { :edit => 'cambiar' }, :as => 'projeto' + end + resources :projects, :controller => :project do resources :involvements, :attachments @@ -56,7 +65,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :companies do resources :people - resource :avatar + resource :avatar, :controller => :avatar end resources :images do @@ -65,7 +74,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :people do nested do - namespace ":access_token" do + scope "/:access_token" do resource :avatar end end @@ -88,6 +97,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + resources :replies do + member do + put :answer, :to => :mark_as_answer + delete :answer, :to => :unmark_as_answer + end + end + + resources :posts, :only => [:index, :show] + match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp match 'people/:id/update', :to => 'people#update', :as => :update_person @@ -97,7 +115,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match 'articles/:year/:month/:day/:title', :to => "articles#show", :as => :article namespace :account do + match 'description', :to => "account#description", :as => "description" resource :subscription, :credit, :credit_card + + namespace :admin do + resource :subscription + end + end + + namespace :forum do + resources :products, :as => '' do + resources :questions + end end controller :articles do @@ -112,6 +141,16 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :rooms end + scope '(:locale)', :locale => /en|pl/ do + resources :descriptions + end + + namespace :admin do + scope '(/:locale)', :locale => /en|pl/ do + resources :descriptions + end + end + match '/info' => 'projects#info', :as => 'info' root :to => 'projects#index' @@ -165,6 +204,31 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_session_singleton_resource + with_test_routes do + 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 + end + end + def test_redirect_modulo with_test_routes do get '/account/modulo/name' @@ -193,20 +257,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - # TODO: rackmount is broken - # def test_admin - # with_test_routes do - # get '/admin', {}, {'REMOTE_ADDR' => '192.168.1.100'} - # assert_equal 'queenbee#index', @response.body - # - # assert_raise(ActionController::RoutingError) { get '/admin', {}, {'REMOTE_ADDR' => '10.0.0.100'} } - # - # get '/admin/accounts', {}, {'REMOTE_ADDR' => '192.168.1.100'} - # assert_equal 'queenbee#accounts', @response.body - # - # assert_raise(ActionController::RoutingError) { get '/admin/accounts', {}, {'REMOTE_ADDR' => '10.0.0.100'} } - # end - # end + def test_admin + with_test_routes do + get '/admin', {}, {'REMOTE_ADDR' => '192.168.1.100'} + assert_equal 'queenbee#index', @response.body + + assert_raise(ActionController::RoutingError) { get '/admin', {}, {'REMOTE_ADDR' => '10.0.0.100'} } + + get '/admin/accounts', {}, {'REMOTE_ADDR' => '192.168.1.100'} + assert_equal 'queenbee#accounts', @response.body + + assert_raise(ActionController::RoutingError) { get '/admin/accounts', {}, {'REMOTE_ADDR' => '10.0.0.100'} } + end + end def test_global with_test_routes do @@ -231,31 +294,34 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_projects with_test_routes do get '/projects' - assert_equal 'projects#index', @response.body + assert_equal 'project#index', @response.body assert_equal '/projects', projects_path + post '/projects' + assert_equal 'project#create', @response.body + get '/projects.xml' - assert_equal 'projects#index', @response.body + assert_equal 'project#index', @response.body assert_equal '/projects.xml', projects_path(:format => 'xml') get '/projects/new' - assert_equal 'projects#new', @response.body + assert_equal 'project#new', @response.body assert_equal '/projects/new', new_project_path get '/projects/new.xml' - assert_equal 'projects#new', @response.body + assert_equal 'project#new', @response.body assert_equal '/projects/new.xml', new_project_path(:format => 'xml') get '/projects/1' - assert_equal 'projects#show', @response.body + assert_equal 'project#show', @response.body assert_equal '/projects/1', project_path(:id => '1') get '/projects/1.xml' - assert_equal 'projects#show', @response.body + assert_equal 'project#show', @response.body assert_equal '/projects/1.xml', project_path(:id => '1', :format => 'xml') get '/projects/1/edit' - assert_equal 'projects#edit', @response.body + assert_equal 'project#edit', @response.body assert_equal '/projects/1/edit', edit_project_path(:id => '1') end end @@ -317,7 +383,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest 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 'avatars#show', @response.body + assert_equal 'avatar#show', @response.body assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1') end end @@ -394,6 +460,42 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_replies + with_test_routes do + 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 + end + + def test_posts + with_test_routes do + 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) + + assert_raise(ActionController::RoutingError) { post '/posts' } + assert_raise(ActionController::RoutingError) { put '/posts/1' } + assert_raise(ActionController::RoutingError) { delete '/posts/1' } + end + end + + def test_path_names + with_test_routes do + get '/es/projeto' + assert_equal 'projects#index', @response.body + + get '/es/projeto/1/cambiar' + assert_equal 'projects#edit', @response.body + end + end + def test_sprockets with_test_routes do get '/sprockets.js' @@ -419,6 +521,26 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_forum_products + with_test_routes do + 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 + end + def test_articles_perma with_test_routes do get '/articles/2009/08/18/rails-3' @@ -431,13 +553,24 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_account_namespace with_test_routes do get '/account/subscription' - assert_equal 'subscriptions#show', @response.body + assert_equal 'account/subscriptions#show', @response.body + assert_equal '/account/subscription', account_subscription_path get '/account/credit' - assert_equal 'credits#show', @response.body + assert_equal 'account/credits#show', @response.body + assert_equal '/account/credit', account_credit_path get '/account/credit_card' - assert_equal 'credit_cards#show', @response.body + assert_equal 'account/credit_cards#show', @response.body + assert_equal '/account/credit_card', account_credit_card_path + end + end + + def test_nested_namespace + with_test_routes do + get '/account/admin/subscription' + assert_equal 'account/admin/subscriptions#show', @response.body + assert_equal '/account/admin/subscription', account_admin_subscription_path end end @@ -472,7 +605,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal 'projects#index', @response.body end end - + def test_index with_test_routes do assert_equal '/info', info_path @@ -488,7 +621,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal 'projects#info', @response.body end end - + def test_convention_match_with_no_scope with_test_routes do assert_equal '/account/overview', account_overview_path @@ -497,6 +630,78 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_redirect_with_complete_url + with_test_routes do + get '/account/google' + assert_equal 301, @response.status + assert_equal 'http://www.google.com/', @response.headers['Location'] + assert_equal 'Moved Permanently', @response.body + end + end + + def test_redirect_with_port + previous_host, self.host = self.host, 'www.example.com:3000' + with_test_routes do + get '/account/login' + assert_equal 301, @response.status + assert_equal 'http://www.example.com:3000/login', @response.headers['Location'] + assert_equal 'Moved Permanently', @response.body + end + ensure + self.host = previous_host + end + + def test_normalize_namespaced_matches + with_test_routes do + assert_equal '/account/description', account_description_path + + get '/account/description' + assert_equal 'account#description', @response.body + end + end + + def test_optional_scoped_path + with_test_routes do + 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 + end + + def test_nested_optional_scoped_path + with_test_routes do + 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 + end + private def with_test_routes real_routes, temp_routes = ActionController::Routing::Routes, Routes diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb index 9f6a93756c..951fb4a22e 100644 --- a/actionpack/test/dispatch/show_exceptions_test.rb +++ b/actionpack/test/dispatch/show_exceptions_test.rb @@ -104,4 +104,27 @@ class ShowExceptionsTest < ActionController::IntegrationTest assert_response 405 assert_match /ActionController::MethodNotAllowed/, body end + + test "publishes notifications" do + # Wait pending notifications to be published + ActiveSupport::Notifications.notifier.wait + + @app, event = ProductionApp, nil + self.remote_addr = '127.0.0.1' + + ActiveSupport::Notifications.subscribe('action_dispatch.show_exception') do |*args| + event = args + end + + get "/" + assert_response 500 + assert_match /puke/, body + + ActiveSupport::Notifications.notifier.wait + + assert_equal 'action_dispatch.show_exception', event.first + assert_kind_of Hash, event.last[:env] + assert_equal 'GET', event.last[:env]["REQUEST_METHOD"] + assert_kind_of RuntimeError, event.last[:exception] + end end diff --git a/actionpack/test/dispatch/string_coercion_test.rb b/actionpack/test/dispatch/string_coercion_test.rb deleted file mode 100644 index d79b17b932..0000000000 --- a/actionpack/test/dispatch/string_coercion_test.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'abstract_unit' - -class StringCoercionTest < ActiveSupport::TestCase - test "body responds to each" do - original_body = [] - body = ActionDispatch::StringCoercion::UglyBody.new(original_body) - - assert original_body.respond_to?(:each) - assert body.respond_to?(:each) - end - - test "body responds to to_path" do - original_body = [] - def original_body.to_path; end - body = ActionDispatch::StringCoercion::UglyBody.new(original_body) - - assert original_body.respond_to?(:to_path) - assert body.respond_to?(:to_path) - end - - test "body does not responds to to_path" do - original_body = [] - body = ActionDispatch::StringCoercion::UglyBody.new(original_body) - - assert !original_body.respond_to?(:to_path) - assert !body.respond_to?(:to_path) - end - - test "calls to_s on body parts" do - app = lambda { |env| - [200, {'Content-Type' => 'html'}, [1, 2, 3]] - } - app = ActionDispatch::StringCoercion.new(app) - parts = [] - status, headers, body = app.call({}) - body.each { |part| parts << part } - - assert_equal %w( 1 2 3 ), parts - end -end diff --git a/actionpack/test/fixtures/respond_with/using_defaults.js.rjs b/actionpack/test/fixtures/respond_with/using_defaults.js.rjs deleted file mode 100644 index 469fcd8e15..0000000000 --- a/actionpack/test/fixtures/respond_with/using_defaults.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight
\ No newline at end of file diff --git a/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.js.rjs b/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.js.rjs deleted file mode 100644 index 469fcd8e15..0000000000 --- a/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight
\ No newline at end of file diff --git a/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.xml.builder b/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.xml.builder deleted file mode 100644 index 598d62e2fc..0000000000 --- a/actionpack/test/fixtures/respond_with/using_defaults_with_type_list.xml.builder +++ /dev/null @@ -1 +0,0 @@ -xml.p "Hello world!"
\ No newline at end of file diff --git a/actionpack/test/fixtures/respond_with/using_defaults.html.erb b/actionpack/test/fixtures/respond_with/using_resource_with_block.html.erb index 6769dd60bd..6769dd60bd 100644 --- a/actionpack/test/fixtures/respond_with/using_defaults.html.erb +++ b/actionpack/test/fixtures/respond_with/using_resource_with_block.html.erb diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index b0e5d7a94c..7346cb22bc 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -69,7 +69,7 @@ class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost attr_accessor :author def author_attributes=(attributes); end - attr_accessor :comments + attr_accessor :comments, :comment_ids def comments_attributes=(attributes); end attr_accessor :tags diff --git a/actionpack/test/template/active_model_helper_i18n_test.rb b/actionpack/test/template/active_model_helper_i18n_test.rb index 2465444fc5..4eb2f262bd 100644 --- a/actionpack/test/template/active_model_helper_i18n_test.rb +++ b/actionpack/test/template/active_model_helper_i18n_test.rb @@ -16,27 +16,27 @@ class ActiveModelHelperI18nTest < Test::Unit::TestCase stubs(:content_tag).returns 'content_tag' - I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" - I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:' + I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" + I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).returns 'There were problems with the following fields:' end def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message - I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').never + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').never error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en') end def test_error_messages_for_given_no_header_option_it_translates_header_message - I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:activemodel, :errors, :template], :count => 1, :model => '').returns 'header message' + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').returns 'header message' error_messages_for(:object => @object, :locale => 'en') end def test_error_messages_for_given_a_message_option_it_does_not_translate_message - I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).never + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).never error_messages_for(:object => @object, :message => 'message', :locale => 'en') end def test_error_messages_for_given_no_message_option_it_translates_message - I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:activemodel, :errors, :template]).returns 'There were problems with the following fields:' + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).returns 'There were problems with the following fields:' error_messages_for(:object => @object, :locale => 'en') end end diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 9fb2080f77..fb51b67185 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -2475,6 +2475,28 @@ class DateHelperTest < ActionView::TestCase }, options) end + def test_select_html_safety + assert select_day(16).html_safe? + assert select_month(8).html_safe? + assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? + assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? + assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? + + assert select_minute(8, :use_hidden => true).html_safe? + assert select_month(8, :prompt => 'Choose month').html_safe? + + assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, :class => 'selector').html_safe? + assert select_date(Time.mktime(2003, 8, 16), :date_separator => " / ", :start_year => 2003, :end_year => 2005, :prefix => "date[first]").html_safe? + end + + def test_object_select_html_safety + @post = Post.new + @post.written_on = Date.new(2004, 6, 15) + + assert date_select("post", "written_on", :default => Time.local(2006, 9, 19, 15, 16, 35), :include_blank => true).html_safe? + assert time_select("post", "written_on", :ignore_date => true).html_safe? + end + protected def with_env_tz(new_tz = 'US/Eastern') old_tz, ENV['TZ'] = ENV['TZ'], new_tz diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index b1e9fe99a2..0c5c5d17ee 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -16,8 +16,8 @@ class FormHelperTest < ActionView::TestCase } } }, - :views => { - :labels => { + :helpers => { + :label => { :post => { :body => "Write entire text here" } @@ -25,6 +25,20 @@ class FormHelperTest < ActionView::TestCase } } + # Create "submit" locale for testing I18n submit helpers + I18n.backend.store_translations 'submit', { + :helpers => { + :submit => { + :create => 'Create {{model}}', + :update => 'Confirm {{model}} changes', + :submit => 'Save changes', + :another_post => { + :update => 'Update your {{model}}' + } + } + } + } + @post = Post.new @comment = Comment.new def @post.errors() @@ -190,6 +204,11 @@ class FormHelperTest < ActionView::TestCase hidden_field("post", "title", :value => "Something Else") end + def test_text_field_with_custom_type + assert_dom_equal '<input id="user_email" size="30" name="user[email]" type="email" />', + text_field("user", "email", :type => "email") + end + def test_check_box assert_dom_equal( '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />', @@ -234,6 +253,19 @@ class FormHelperTest < ActionView::TestCase ) end + def test_check_box_with_multiple_behavior + @post.comment_ids = [2,3] + assert_dom_equal( + '<input name="post[comment_ids][]" type="hidden" value="0" /><input id="post_comment_ids_1" name="post[comment_ids][]" type="checkbox" value="1" />', + check_box("post", "comment_ids", { :multiple => true }, 1) + ) + assert_dom_equal( + '<input name="post[comment_ids][]" type="hidden" value="0" /><input checked="checked" id="post_comment_ids_3" name="post[comment_ids][]" type="checkbox" value="3" />', + check_box("post", "comment_ids", { :multiple => true }, 3) + ) + end + + def test_checkbox_disabled_still_submits_checked_value assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />', @@ -475,6 +507,67 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_submit_with_object_as_new_record_and_locale_strings + old_locale, I18n.locale = I18n.locale, :submit + + def @post.new_record?() true; end + form_for(:post, @post) do |f| + concat f.submit + end + + expected = "<form action='http://www.example.com' method='post'>" + + "<input name='commit' id='post_submit' type='submit' value='Create Post' />" + + "</form>" + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + + def test_submit_with_object_as_existing_record_and_locale_strings + old_locale, I18n.locale = I18n.locale, :submit + + form_for(:post, @post) do |f| + concat f.submit + end + + expected = "<form action='http://www.example.com' method='post'>" + + "<input name='commit' id='post_submit' type='submit' value='Confirm Post changes' />" + + "</form>" + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + + def test_submit_without_object_and_locale_strings + old_locale, I18n.locale = I18n.locale, :submit + + form_for(:post) do |f| + concat f.submit :class => "extra" + end + + expected = "<form action='http://www.example.com' method='post'>" + + "<input name='commit' class='extra' id='post_submit' type='submit' value='Save changes' />" + + "</form>" + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + + def test_submit_with_object_and_nested_lookup + old_locale, I18n.locale = I18n.locale, :submit + + form_for(:another_post, @post) do |f| + concat f.submit + end + + expected = "<form action='http://www.example.com' method='post'>" + + "<input name='commit' id='another_post_submit' type='submit' value='Update your Post' />" + + "</form>" + assert_dom_equal expected, output_buffer + ensure + I18n.locale = old_locale + end + def test_nested_fields_for form_for(:post, @post) do |f| f.fields_for(:comment, @post) do |c| @@ -659,7 +752,7 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end - + def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement @post.author = Author.new(321) @@ -670,7 +763,7 @@ class FormHelperTest < ActionView::TestCase concat af.text_field(:name) end end - + expected = '<form action="http://www.example.com" method="post">' + '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' + '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' + @@ -715,7 +808,7 @@ class FormHelperTest < ActionView::TestCase end end end - + expected = '<form action="http://www.example.com" method="post">' + '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + diff --git a/actionpack/test/template/form_options_helper_i18n_test.rb b/actionpack/test/template/form_options_helper_i18n_test.rb index 91e370efa7..4972ea6511 100644 --- a/actionpack/test/template/form_options_helper_i18n_test.rb +++ b/actionpack/test/template/form_options_helper_i18n_test.rb @@ -6,7 +6,7 @@ class FormOptionsHelperI18nTests < ActionView::TestCase def setup @prompt_message = 'Select!' I18n.backend.send(:init_translations) - I18n.backend.store_translations :en, :support => { :select => { :prompt => @prompt_message } } + I18n.backend.store_translations :en, :helpers => { :select => { :prompt => @prompt_message } } end def teardown @@ -14,7 +14,7 @@ class FormOptionsHelperI18nTests < ActionView::TestCase end def test_select_with_prompt_true_translates_prompt_message - I18n.expects(:translate).with('support.select.prompt', { :default => 'Please select' }) + I18n.expects(:translate).with('helpers.select.prompt', { :default => 'Please select' }) select('post', 'category', [], :prompt => true) end @@ -24,4 +24,4 @@ class FormOptionsHelperI18nTests < ActionView::TestCase select('post', 'category', [], :prompt => true) ) end -end
\ No newline at end of file +end diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index f0f686f6e2..03caad3d46 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -13,8 +13,13 @@ class JavaScriptHelperTest < ActionView::TestCase def setup super + ActiveSupport.escape_html_entities_in_json = true @template = self end + + def teardown + ActiveSupport.escape_html_entities_in_json = false + end def _evaluate_assigns_and_ivars() end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 313a769088..9225153798 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -317,6 +317,11 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest def setup super @generator = create_generator + ActiveSupport.escape_html_entities_in_json = true + end + + def teardown + ActiveSupport.escape_html_entities_in_json = false end def _evaluate_assigns_and_ivars() end diff --git a/actionpack/test/template/subscriber_test.rb b/actionpack/test/template/subscriber_test.rb new file mode 100644 index 0000000000..af0b3102cf --- /dev/null +++ b/actionpack/test/template/subscriber_test.rb @@ -0,0 +1,102 @@ +require "abstract_unit" +require "rails/subscriber/test_helper" +require "action_view/railties/subscriber" +require "controller/fake_models" + +module ActionViewSubscriberTest + + def setup + @old_logger = ActionController::Base.logger + @view = ActionView::Base.new(ActionController::Base.view_paths, {}) + Rails.stubs(:root).returns(File.expand_path(FIXTURE_LOAD_PATH)) + Rails::Subscriber.add(:action_view, ActionView::Railties::Subscriber.new) + super + end + + def teardown + super + Rails::Subscriber.subscribers.clear + ActionController::Base.logger = @old_logger + end + + def set_logger(logger) + ActionController::Base.logger = logger + end + + def test_render_file_template + @view.render(:file => "test/hello_world.erb") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/hello_world\.erb/, @logger.logged(:info).last + end + + def test_render_text_template + @view.render(:text => "OMG") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered text template/, @logger.logged(:info).last + end + + def test_render_inline_template + @view.render(:inline => "<%= 'OMG' %>") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered inline template/, @logger.logged(:info).last + end + + def test_render_partial_template + @view.render(:partial => "test/customer") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last + end + + def test_render_partial_with_implicit_path + @view.stubs(:controller_path).returns("test") + @view.render(Customer.new("david"), :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last + end + + def test_render_collection_template + @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ]) + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last + end + + def test_render_collection_with_implicit_path + @view.stubs(:controller_path).returns("test") + @view.render([ Customer.new("david"), Customer.new("mary") ], :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last + end + + def test_render_collection_template_without_path + @view.stubs(:controller_path).returns("test") + @view.render([ GoodCustomer.new("david"), Customer.new("mary") ], :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered collection/, @logger.logged(:info).last + end + + class SyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::SyncTestHelper + include ActionViewSubscriberTest + end + + class AsyncSubscriberTest < ActiveSupport::TestCase + include Rails::Subscriber::AsyncTestHelper + include ActionViewSubscriberTest + end +end
\ No newline at end of file diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index 08143ba680..088c07b8bb 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -360,6 +360,20 @@ class TextHelperTest < ActionView::TestCase assert_equal %(<p>#{link10_result} Link</p>), auto_link("<p>#{link10_raw} Link</p>") end + def test_auto_link_other_protocols + silence_warnings do + begin + old_re_value = ActionView::Helpers::TextHelper::AUTO_LINK_RE + ActionView::Helpers::TextHelper.const_set :AUTO_LINK_RE, %r{(ftp://)[^\s<]+} + link_raw = 'ftp://example.com/file.txt' + link_result = generate_result(link_raw) + assert_equal %(Download #{link_result}), auto_link("Download #{link_raw}") + ensure + ActionView::Helpers::TextHelper.const_set :AUTO_LINK_RE, old_re_value + end + end + end + def test_auto_link_already_linked linked1 = generate_result('Ruby On Rails', 'http://www.rubyonrails.com') linked2 = generate_result('www.rubyonrails.com', 'http://www.rubyonrails.com') |