diff options
Diffstat (limited to 'actionpack/test/controller')
32 files changed, 1350 insertions, 2547 deletions
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 22a410db94..ba4cffcd3e 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -39,6 +39,8 @@ class ActionPackAssertionsController < ActionController::Base def redirect_external() redirect_to "http://www.rubyonrails.org"; end + def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end + def response404() head '404 AWOL' end def response500() head '500 Sorry' end @@ -258,6 +260,19 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end end + def test_assert_redirect_failure_message_with_protocol_relative_url + begin + process :redirect_external_protocol_relative + assert_redirected_to "/foo" + rescue ActiveSupport::TestCase::Assertion => ex + assert_no_match( + /#{request.protocol}#{request.host}\/\/www.rubyonrails.org/, + ex.message, + 'protocol relative url was incorrectly normalized' + ) + end + end + def test_template_objects_exist process :assign_this assert !@controller.instance_variable_defined?(:"@hi") @@ -309,6 +324,9 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase process :redirect_external assert_equal 'http://www.rubyonrails.org', @response.redirect_url + + process :redirect_external_protocol_relative + assert_equal '//www.rubyonrails.org', @response.redirect_url end def test_no_redirect_url diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index 3d667f0a2f..114bbf3c22 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -8,6 +8,9 @@ require 'abstract_unit' require 'controller/fake_controllers' require 'action_mailer' +require 'action_view' + +ActionMailer::Base.send(:include, ActionView::Layouts) ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH class AssertSelectTest < ActionController::TestCase diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 9b42e7631f..b2bfdae174 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -61,11 +61,14 @@ class UrlOptionsController < ActionController::Base end end -class RecordIdentifierController < ActionController::Base +class RecordIdentifierIncludedController < ActionController::Base + include ActionView::RecordIdentifier end -class RecordIdentifierWithoutDeprecationController < ActionController::Base - include ActionView::RecordIdentifier +class ActionMissingController < ActionController::Base + def action_missing(action) + render :text => "Response for #{action}" + end end class ControllerClassTests < ActiveSupport::TestCase @@ -82,43 +85,20 @@ class ControllerClassTests < ActiveSupport::TestCase assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name end - def test_record_identifier - assert_respond_to RecordIdentifierController.new, :dom_id - assert_respond_to RecordIdentifierController.new, :dom_class - end - - def test_record_identifier_is_deprecated - record = Comment.new - record.save - - dom_id = nil - assert_deprecated 'dom_id method will no longer' do - dom_id = RecordIdentifierController.new.dom_id(record) - end - - assert_equal 'comment_1', dom_id - - dom_class = nil - assert_deprecated 'dom_class method will no longer' do - dom_class = RecordIdentifierController.new.dom_class(record) - end - assert_equal 'comment', dom_class - end - def test_no_deprecation_when_action_view_record_identifier_is_included record = Comment.new record.save dom_id = nil assert_not_deprecated do - dom_id = RecordIdentifierWithoutDeprecationController.new.dom_id(record) + dom_id = RecordIdentifierIncludedController.new.dom_id(record) end assert_equal 'comment_1', dom_id dom_class = nil assert_not_deprecated do - dom_class = RecordIdentifierWithoutDeprecationController.new.dom_class(record) + dom_class = RecordIdentifierIncludedController.new.dom_class(record) end assert_equal 'comment', dom_class end @@ -186,6 +166,12 @@ class PerformActionTest < ActionController::TestCase assert_raise(AbstractController::ActionNotFound) { get :hidden_action } assert_raise(AbstractController::ActionNotFound) { get :another_hidden_action } end + + def test_action_missing_should_work + use_controller ActionMissingController + get :arbitrary_action + assert_equal "Response for arbitrary_action", @response.body + end end class UrlOptionsTest < ActionController::TestCase diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index ca86837a2c..57b45b8f7b 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -1,6 +1,5 @@ require 'fileutils' require 'abstract_unit' -require 'active_record_unit' CACHE_DIR = 'test_cache' # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed @@ -21,7 +20,7 @@ class FragmentCachingMetalTest < ActionController::TestCase @controller = FragmentCachingMetalTestController.new @controller.perform_caching = true @controller.cache_store = @store - @params = { controller: 'posts', action: 'index'} + @params = { controller: 'posts', action: 'index' } @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @controller.params = @params @@ -41,7 +40,7 @@ class CachingController < ActionController::Base end class FragmentCachingTestController < CachingController - def some_action; end; + def some_action; end end class FragmentCachingTest < ActionController::TestCase @@ -313,18 +312,3 @@ class ViewCacheDependencyTest < ActionController::TestCase assert_equal %w(trombone flute), HasDependenciesController.new.view_cache_dependencies end end - -class DeprecatedPageCacheExtensionTest < ActiveSupport::TestCase - def test_page_cache_extension_binds_default_static_extension - deprecation_behavior = ActiveSupport::Deprecation.behavior - ActiveSupport::Deprecation.behavior = :silence - old_extension = ActionController::Base.default_static_extension - - ActionController::Base.page_cache_extension = '.rss' - - assert_equal '.rss', ActionController::Base.default_static_extension - ensure - ActiveSupport::Deprecation.behavior = deprecation_behavior - ActionController::Base.default_static_extension = old_extension - end -end diff --git a/actionpack/test/controller/capture_test.rb b/actionpack/test/controller/capture_test.rb deleted file mode 100644 index 72263156d9..0000000000 --- a/actionpack/test/controller/capture_test.rb +++ /dev/null @@ -1,79 +0,0 @@ -require 'abstract_unit' -require 'active_support/logger' - -class CaptureController < ActionController::Base - def self.controller_name; "test"; end - def self.controller_path; "test"; end - - def content_for - @title = nil - render :layout => "talk_from_action" - end - - def content_for_with_parameter - @title = nil - render :layout => "talk_from_action" - end - - def content_for_concatenated - @title = nil - render :layout => "talk_from_action" - end - - def non_erb_block_content_for - @title = nil - render :layout => "talk_from_action" - end - - def proper_block_detection - @todo = "some todo" - end -end - -class CaptureTest < ActionController::TestCase - tests CaptureController - - def setup - super - # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get - # a more accurate simulation of what happens in "real life". - @controller.logger = ActiveSupport::Logger.new(nil) - - @request.host = "www.nextangle.com" - end - - def test_simple_capture - get :capturing - assert_equal "Dreamy days", @response.body.strip - end - - def test_content_for - get :content_for - assert_equal expected_content_for_output, @response.body - end - - def test_should_concatentate_content_for - get :content_for_concatenated - assert_equal expected_content_for_output, @response.body - end - - def test_should_set_content_for_with_parameter - get :content_for_with_parameter - assert_equal expected_content_for_output, @response.body - end - - def test_non_erb_block_content_for - get :non_erb_block_content_for - assert_equal expected_content_for_output, @response.body - end - - def test_proper_block_detection - get :proper_block_detection - assert_equal "some todo", @response.body - end - - private - def expected_content_for_output - "<title>Putting stuff in the title!</title>\nGreat stuff!" - end -end diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index 3b79161ad3..3b5d7ef446 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -10,7 +10,7 @@ class ActionController::Base def before_filters filters = _process_action_callbacks.select { |c| c.kind == :before } - filters.map! { |c| c.instance_variable_get(:@raw_filter) } + filters.map! { |c| c.raw_filter } end end @@ -208,11 +208,23 @@ class FilterTest < ActionController::TestCase before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:"@ran_proc_filter1", true)}, :except => :show_without_filter) { |c| c.instance_variable_set(:"@ran_proc_filter2", true)} end + class OnlyConditionalOptionsFilter < ConditionalFilterController + before_filter :ensure_login, :only => :index, :if => Proc.new {|c| c.instance_variable_set(:"@ran_conditional_index_proc", true) } + end + class ConditionalOptionsFilter < ConditionalFilterController before_filter :ensure_login, :if => Proc.new { |c| true } before_filter :clean_up_tmp, :if => Proc.new { |c| false } end + class ConditionalOptionsSkipFilter < ConditionalFilterController + before_filter :ensure_login + before_filter :clean_up_tmp + + skip_before_filter :ensure_login, if: -> { false } + skip_before_filter :clean_up_tmp, if: -> { true } + end + class PrependingController < TestController prepend_before_filter :wonderful_life # skip_before_filter :fire_flash @@ -593,6 +605,11 @@ class FilterTest < ActionController::TestCase assert_equal %w( ensure_login ), assigns["ran_filter"] end + def test_running_conditional_skip_options + test_process(ConditionalOptionsSkipFilter) + assert_equal %w( ensure_login ), assigns["ran_filter"] + end + def test_running_collection_condition_filters test_process(ConditionalCollectionFilterController) assert_equal %w( ensure_login ), assigns["ran_filter"] @@ -636,6 +653,11 @@ class FilterTest < ActionController::TestCase assert !assigns["ran_class_filter"] end + def test_running_only_condition_and_conditional_options + test_process(OnlyConditionalOptionsFilter, "show") + assert_not assigns["ran_conditional_index_proc"] + end + def test_running_before_and_after_condition_filters test_process(BeforeAndAfterConditionController) assert_equal %w( ensure_login clean_up_tmp), assigns["ran_filter"] diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index 9d4356f546..c64ffef654 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -1,5 +1,4 @@ require 'abstract_unit' -# FIXME remove DummyKeyGenerator and this require in 4.1 require 'active_support/key_generator' class FlashTest < ActionController::TestCase @@ -215,11 +214,23 @@ class FlashTest < ActionController::TestCase get :redirect_with_foo_flash assert_equal "for great justice", @controller.send(:flash)[:foo] end + + class SubclassesTestController < TestController; end + + def test_add_flash_type_to_subclasses + TestController.add_flash_types :foo + assert SubclassesTestController._flash_types.include?(:foo) + end + + def test_do_not_add_flash_type_to_parent_class + SubclassesTestController.add_flash_types :bar + assert_not TestController._flash_types.include?(:bar) + end end class FlashIntegrationTest < ActionDispatch::IntegrationTest SessionKey = '_myapp_session' - Generator = ActiveSupport::DummyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') + Generator = ActiveSupport::LegacyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') class TestController < ActionController::Base add_flash_types :bar diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb index 6758668b7a..3655b90e32 100644 --- a/actionpack/test/controller/force_ssl_test.rb +++ b/actionpack/test/controller/force_ssl_test.rb @@ -14,8 +14,42 @@ class ForceSSLControllerLevel < ForceSSLController force_ssl end -class ForceSSLCustomDomain < ForceSSLController - force_ssl :host => "secure.test.host" +class ForceSSLCustomOptions < ForceSSLController + force_ssl :host => "secure.example.com", :only => :redirect_host + force_ssl :port => 8443, :only => :redirect_port + force_ssl :subdomain => 'secure', :only => :redirect_subdomain + force_ssl :domain => 'secure.com', :only => :redirect_domain + force_ssl :path => '/foo', :only => :redirect_path + force_ssl :status => :found, :only => :redirect_status + force_ssl :flash => { :message => 'Foo, Bar!' }, :only => :redirect_flash + force_ssl :alert => 'Foo, Bar!', :only => :redirect_alert + force_ssl :notice => 'Foo, Bar!', :only => :redirect_notice + + def force_ssl_action + render :text => action_name + end + + alias_method :redirect_host, :force_ssl_action + alias_method :redirect_port, :force_ssl_action + alias_method :redirect_subdomain, :force_ssl_action + alias_method :redirect_domain, :force_ssl_action + alias_method :redirect_path, :force_ssl_action + alias_method :redirect_status, :force_ssl_action + alias_method :redirect_flash, :force_ssl_action + alias_method :redirect_alert, :force_ssl_action + alias_method :redirect_notice, :force_ssl_action + + def use_flash + render :text => flash[:message] + end + + def use_alert + render :text => flash[:alert] + end + + def use_notice + render :text => flash[:notice] + end end class ForceSSLOnlyAction < ForceSSLController @@ -80,19 +114,77 @@ class ForceSSLControllerLevelTest < ActionController::TestCase end end -class ForceSSLCustomDomainTest < ActionController::TestCase - tests ForceSSLCustomDomain +class ForceSSLCustomOptionsTest < ActionController::TestCase + tests ForceSSLCustomOptions - def test_banana_redirects_to_https_with_custom_host - get :banana + def setup + @request.env['HTTP_HOST'] = 'www.example.com:80' + end + + def test_redirect_to_custom_host + get :redirect_host assert_response 301 - assert_equal "https://secure.test.host/force_ssl_custom_domain/banana", redirect_to_url + assert_equal "https://secure.example.com/force_ssl_custom_options/redirect_host", redirect_to_url end - def test_cheeseburger_redirects_to_https_with_custom_host - get :cheeseburger + def test_redirect_to_custom_port + get :redirect_port + assert_response 301 + assert_equal "https://www.example.com:8443/force_ssl_custom_options/redirect_port", redirect_to_url + end + + def test_redirect_to_custom_subdomain + get :redirect_subdomain assert_response 301 - assert_equal "https://secure.test.host/force_ssl_custom_domain/cheeseburger", redirect_to_url + assert_equal "https://secure.example.com/force_ssl_custom_options/redirect_subdomain", redirect_to_url + end + + def test_redirect_to_custom_domain + get :redirect_domain + assert_response 301 + assert_equal "https://www.secure.com/force_ssl_custom_options/redirect_domain", redirect_to_url + end + + def test_redirect_to_custom_path + get :redirect_path + assert_response 301 + assert_equal "https://www.example.com/foo", redirect_to_url + end + + def test_redirect_to_custom_status + get :redirect_status + assert_response 302 + assert_equal "https://www.example.com/force_ssl_custom_options/redirect_status", redirect_to_url + end + + def test_redirect_to_custom_flash + get :redirect_flash + assert_response 301 + assert_equal "https://www.example.com/force_ssl_custom_options/redirect_flash", redirect_to_url + + get :use_flash + assert_response 200 + assert_equal "Foo, Bar!", @response.body + end + + def test_redirect_to_custom_alert + get :redirect_alert + assert_response 301 + assert_equal "https://www.example.com/force_ssl_custom_options/redirect_alert", redirect_to_url + + get :use_alert + assert_response 200 + assert_equal "Foo, Bar!", @response.body + end + + def test_redirect_to_custom_notice + get :redirect_notice + assert_response 301 + assert_equal "https://www.example.com/force_ssl_custom_options/redirect_notice", redirect_to_url + + get :use_notice + assert_response 200 + assert_equal "Foo, Bar!", @response.body end end @@ -149,16 +241,79 @@ class ForceSSLFlashTest < ActionController::TestCase assert_response 302 assert_equal "http://test.host/force_ssl_flash/cheeseburger", redirect_to_url + # FIXME: AC::TestCase#build_request_uri doesn't build a new uri if PATH_INFO exists + @request.env.delete('PATH_INFO') + get :cheeseburger assert_response 301 assert_equal "https://test.host/force_ssl_flash/cheeseburger", redirect_to_url + # FIXME: AC::TestCase#build_request_uri doesn't build a new uri if PATH_INFO exists + @request.env.delete('PATH_INFO') + get :use_flash assert_equal "hello", assigns["flash_copy"]["that"] assert_equal "hello", assigns["flashy"] end end +class ForceSSLDuplicateRoutesTest < ActionController::TestCase + tests ForceSSLControllerLevel + + def test_force_ssl_redirects_to_same_path + with_routing do |set| + set.draw do + get '/foo', :to => 'force_ssl_controller_level#banana' + get '/bar', :to => 'force_ssl_controller_level#banana' + end + + @request.env['PATH_INFO'] = '/bar' + + get :banana + assert_response 301 + assert_equal 'https://test.host/bar', redirect_to_url + end + end +end + +class ForceSSLFormatTest < ActionController::TestCase + tests ForceSSLControllerLevel + + def test_force_ssl_redirects_to_same_format + with_routing do |set| + set.draw do + get '/foo', :to => 'force_ssl_controller_level#banana' + end + + get :banana, :format => :json + assert_response 301 + assert_equal 'https://test.host/foo.json', redirect_to_url + end + end +end + +class ForceSSLOptionalSegmentsTest < ActionController::TestCase + tests ForceSSLControllerLevel + + def test_force_ssl_redirects_to_same_format + with_routing do |set| + set.draw do + scope '(:locale)' do + defaults :locale => 'en' do + get '/foo', :to => 'force_ssl_controller_level#banana' + end + end + end + + @request.env['PATH_INFO'] = '/en/foo' + get :banana, :locale => 'en' + assert_equal 'en', @controller.params[:locale] + assert_response 301 + assert_equal 'https://test.host/en/foo', redirect_to_url + end + end +end + class RedirectToSSLTest < ActionController::TestCase tests RedirectToSSL def test_banana_redirects_to_https_if_not_https diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 248c81193e..20f99f19ee 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -201,6 +201,12 @@ class HelperTest < ActiveSupport::TestCase # fun/pdf_helper.rb assert methods.include?(:foobar) end + + def test_helper_proxy_config + AllHelpersController.config.my_var = 'smth' + + assert_equal 'smth', AllHelpersController.helpers.config.my_var + end private def expected_helper_methods diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 537de7a2dd..9f1c168209 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -1,5 +1,4 @@ require 'abstract_unit' -# FIXME remove DummyKeyGenerator and this require in 4.1 require 'active_support/key_generator' class HttpDigestAuthenticationTest < ActionController::TestCase @@ -43,7 +42,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase setup do # Used as secret in generating nonce to prevent tampering of timestamp @secret = "4fb45da9e4ab4ddeb7580d6a35503d99" - @request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new(@secret) + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new(@secret) end teardown do @@ -249,6 +248,14 @@ class HttpDigestAuthenticationTest < ActionController::TestCase assert_equal 'Definitely Maybe', @response.body end + test "when sent a basic auth header, returns Unauthorized" do + @request.env['HTTP_AUTHORIZATION'] = 'Basic Gwf2aXq8ZLF3Hxq=' + + get :display + + assert_response :unauthorized + end + private def encode_credentials(options) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 72b882539c..e851cc6a63 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -117,12 +117,6 @@ class SessionTest < ActiveSupport::TestCase @session.head(path,params,headers) end - def test_options - path = "/index"; params = "blah"; headers = {:location => 'blah'} - @session.expects(:process).with(:options,path,params,headers) - @session.options(path,params,headers) - end - def test_xml_http_request_get path = "/index"; params = "blah"; headers = {:location => 'blah'} headers_after_xhr = headers.merge( @@ -183,16 +177,6 @@ class SessionTest < ActiveSupport::TestCase @session.xml_http_request(:head,path,params,headers) end - def test_xml_http_request_options - path = "/index"; params = "blah"; headers = {:location => 'blah'} - headers_after_xhr = headers.merge( - "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest", - "HTTP_ACCEPT" => "text/javascript, text/html, application/xml, text/xml, */*" - ) - @session.expects(:process).with(:options,path,params,headers_after_xhr) - @session.xml_http_request(:options,path,params,headers) - end - def test_xml_http_request_override_accept path = "/index"; params = "blah"; headers = {:location => 'blah', "HTTP_ACCEPT" => "application/xml"} headers_after_xhr = headers.merge( @@ -250,7 +234,7 @@ class IntegrationTestUsesCorrectClass < ActionDispatch::IntegrationTest @integration_session.stubs(:generic_url_rewriter) @integration_session.stubs(:process) - %w( get post head patch put delete options ).each do |verb| + %w( get post head patch put delete ).each do |verb| assert_nothing_raised("'#{verb}' should use integration test methods") { __send__(verb, '/') } end end @@ -293,7 +277,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end def redirect - redirect_to :action => "get" + redirect_to action_url('get') end end @@ -527,8 +511,8 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end set.draw do - match ':action', :to => controller, :via => [:get, :post] - get 'get/:action', :to => controller + match ':action', :to => controller, :via => [:get, :post], :as => :action + get 'get/:action', :to => controller, :as => :get_action end self.singleton_class.send(:include, set.url_helpers) @@ -573,6 +557,21 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest def test_generate_url_without_controller assert_equal 'http://www.example.com/foo', url_for(:controller => "foo") end + + def test_pass_headers + get "/success", {}, "Referer" => "http://www.example.com/foo", "Host" => "http://nohost.com" + + assert_equal "http://nohost.com", @request.env["HTTP_HOST"] + assert_equal "http://www.example.com/foo", @request.env["HTTP_REFERER"] + end + + def test_pass_env + get "/success", {}, "HTTP_REFERER" => "http://test.com/", "HTTP_HOST" => "http://test.com" + + assert_equal "http://test.com", @request.env["HTTP_HOST"] + assert_equal "http://test.com/", @request.env["HTTP_REFERER"] + end + end class ApplicationIntegrationTest < ActionDispatch::IntegrationTest diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb deleted file mode 100644 index 71bcfd664e..0000000000 --- a/actionpack/test/controller/layout_test.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'abstract_unit' -require 'rbconfig' -require 'active_support/core_ext/array/extract_options' - -# The view_paths array must be set on Base and not LayoutTest so that LayoutTest's inherited -# method has access to the view_paths array when looking for a layout to automatically assign. -old_load_paths = ActionController::Base.view_paths - -ActionView::Template::register_template_handler :mab, - lambda { |template| template.source.inspect } - -ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] - -class LayoutTest < ActionController::Base - def self.controller_path; 'views' end - def self._implied_layout_name; to_s.underscore.gsub(/_controller$/, '') ; end - self.view_paths = ActionController::Base.view_paths.dup -end - -# Restore view_paths to previous value -ActionController::Base.view_paths = old_load_paths - -class ProductController < LayoutTest -end - -class ItemController < LayoutTest -end - -class ThirdPartyTemplateLibraryController < LayoutTest -end - -module ControllerNameSpace -end - -class ControllerNameSpace::NestedController < LayoutTest -end - -class MultipleExtensions < LayoutTest -end - -class LayoutAutoDiscoveryTest < ActionController::TestCase - def setup - super - @request.host = "www.nextangle.com" - end - - def test_application_layout_is_default_when_no_controller_match - @controller = ProductController.new - get :hello - assert_equal 'layout_test.erb hello.erb', @response.body - end - - def test_controller_name_layout_name_match - @controller = ItemController.new - get :hello - assert_equal 'item.erb hello.erb', @response.body - end - - def test_third_party_template_library_auto_discovers_layout - @controller = ThirdPartyTemplateLibraryController.new - get :hello - assert_response :success - assert_equal 'layouts/third_party_template_library.mab', @response.body - end - - def test_namespaced_controllers_auto_detect_layouts1 - @controller = ControllerNameSpace::NestedController.new - get :hello - assert_equal 'controller_name_space/nested.erb hello.erb', @response.body - end - - def test_namespaced_controllers_auto_detect_layouts2 - @controller = MultipleExtensions.new - get :hello - assert_equal 'multiple_extensions.html.erb hello.erb', @response.body.strip - end -end - -class DefaultLayoutController < LayoutTest -end - -class StreamingLayoutController < LayoutTest - def render(*args) - options = args.extract_options! - super(*args, options.merge(:stream => true)) - end -end - -class AbsolutePathLayoutController < LayoutTest - layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test') -end - -class HasOwnLayoutController < LayoutTest - layout 'item' -end - -class PrependsViewPathController < LayoutTest - def hello - prepend_view_path File.dirname(__FILE__) + '/../fixtures/layout_tests/alt/' - render :layout => 'alt' - end -end - -class OnlyLayoutController < LayoutTest - layout 'item', :only => "hello" -end - -class ExceptLayoutController < LayoutTest - layout 'item', :except => "goodbye" -end - -class SetsLayoutInRenderController < LayoutTest - def hello - render :layout => 'third_party_template_library' - end -end - -class RendersNoLayoutController < LayoutTest - def hello - render :layout => false - end -end - -class LayoutSetInResponseTest < ActionController::TestCase - include ActionView::Template::Handlers - - def test_layout_set_when_using_default_layout - @controller = DefaultLayoutController.new - get :hello - assert_template :layout => "layouts/layout_test" - end - - def test_layout_set_when_using_streaming_layout - @controller = StreamingLayoutController.new - get :hello - assert_template :hello - end - - def test_layout_set_when_set_in_controller - @controller = HasOwnLayoutController.new - get :hello - assert_template :layout => "layouts/item" - end - - def test_layout_only_exception_when_included - @controller = OnlyLayoutController.new - get :hello - assert_template :layout => "layouts/item" - end - - def test_layout_only_exception_when_excepted - @controller = OnlyLayoutController.new - get :goodbye - assert !@response.body.include?("item.erb"), "#{@response.body.inspect} included 'item.erb'" - end - - def test_layout_except_exception_when_included - @controller = ExceptLayoutController.new - get :hello - assert_template :layout => "layouts/item" - end - - def test_layout_except_exception_when_excepted - @controller = ExceptLayoutController.new - get :goodbye - assert !@response.body.include?("item.erb"), "#{@response.body.inspect} included 'item.erb'" - end - - def test_layout_set_when_using_render - @controller = SetsLayoutInRenderController.new - get :hello - assert_template :layout => "layouts/third_party_template_library" - end - - def test_layout_is_not_set_when_none_rendered - @controller = RendersNoLayoutController.new - get :hello - assert_template :layout => nil - end - - def test_layout_is_picked_from_the_controller_instances_view_path - @controller = PrependsViewPathController.new - get :hello - assert_template :layout => /layouts\/alt/ - end - - def test_absolute_pathed_layout - @controller = AbsolutePathLayoutController.new - get :hello - assert_equal "layout_test.erb hello.erb", @response.body.strip - end -end - -class RenderWithTemplateOptionController < LayoutTest - def hello - render :template => 'alt/hello' - end -end - -class SetsNonExistentLayoutFile < LayoutTest - layout "nofile" -end - -class LayoutExceptionRaisedTest < ActionController::TestCase - def test_exception_raised_when_layout_file_not_found - @controller = SetsNonExistentLayoutFile.new - assert_raise(ActionView::MissingTemplate) { get :hello } - end -end - -class LayoutStatusIsRendered < LayoutTest - def hello - render :status => 401 - end -end - -class LayoutStatusIsRenderedTest < ActionController::TestCase - def test_layout_status_is_rendered - @controller = LayoutStatusIsRendered.new - get :hello - assert_response 401 - end -end - -unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ - class LayoutSymlinkedTest < LayoutTest - layout "symlinked/symlinked_layout" - end - - class LayoutSymlinkedIsRenderedTest < ActionController::TestCase - def test_symlinked_layout_is_rendered - @controller = LayoutSymlinkedTest.new - get :hello - assert_response 200 - assert_template :layout => "layouts/symlinked/symlinked_layout" - end - end -end diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb index 3b1a07d7af..0a431270b5 100644 --- a/actionpack/test/controller/live_stream_test.rb +++ b/actionpack/test/controller/live_stream_test.rb @@ -2,6 +2,94 @@ require 'abstract_unit' require 'active_support/concurrency/latch' module ActionController + class SSETest < ActionController::TestCase + class SSETestController < ActionController::Base + include ActionController::Live + + def basic_sse + response.headers['Content-Type'] = 'text/event-stream' + sse = SSE.new(response.stream) + sse.write("{\"name\":\"John\"}") + sse.write({ name: "Ryan" }) + ensure + sse.close + end + + def sse_with_event + sse = SSE.new(response.stream, event: "send-name") + sse.write("{\"name\":\"John\"}") + sse.write({ name: "Ryan" }) + ensure + sse.close + end + + def sse_with_retry + sse = SSE.new(response.stream, retry: 1000) + sse.write("{\"name\":\"John\"}") + sse.write({ name: "Ryan" }, retry: 1500) + ensure + sse.close + end + + def sse_with_id + sse = SSE.new(response.stream) + sse.write("{\"name\":\"John\"}", id: 1) + sse.write({ name: "Ryan" }, id: 2) + ensure + sse.close + end + end + + tests SSETestController + + def wait_for_response_stream_close + while !response.stream.closed? + sleep 0.01 + end + end + + def test_basic_sse + get :basic_sse + + wait_for_response_stream_close + assert_match(/data: {\"name\":\"John\"}/, response.body) + assert_match(/data: {\"name\":\"Ryan\"}/, response.body) + end + + def test_sse_with_event_name + get :sse_with_event + + wait_for_response_stream_close + assert_match(/data: {\"name\":\"John\"}/, response.body) + assert_match(/data: {\"name\":\"Ryan\"}/, response.body) + assert_match(/event: send-name/, response.body) + end + + def test_sse_with_retry + get :sse_with_retry + + wait_for_response_stream_close + first_response, second_response = response.body.split("\n\n") + assert_match(/data: {\"name\":\"John\"}/, first_response) + assert_match(/retry: 1000/, first_response) + + assert_match(/data: {\"name\":\"Ryan\"}/, second_response) + assert_match(/retry: 1500/, second_response) + end + + def test_sse_with_id + get :sse_with_id + + wait_for_response_stream_close + first_response, second_response = response.body.split("\n\n") + assert_match(/data: {\"name\":\"John\"}/, first_response) + assert_match(/id: 1/, first_response) + + assert_match(/data: {\"name\":\"Ryan\"}/, second_response) + assert_match(/id: 2/, second_response) + end + end + class LiveStreamTest < ActionController::TestCase class TestController < ActionController::Base include ActionController::Live @@ -48,6 +136,33 @@ module ActionController end response.stream.close end + + def with_stale + render :text => 'stale' if stale?(:etag => "123") + end + + def exception_in_view + render 'doesntexist' + end + + def exception_with_callback + response.headers['Content-Type'] = 'text/event-stream' + + response.stream.on_error do + response.stream.write %(data: "500 Internal Server Error"\n\n) + response.stream.close + end + + raise 'An exception occurred...' + end + + def exception_in_exception_callback + response.headers['Content-Type'] = 'text/event-stream' + response.stream.on_error do + raise 'We need to go deeper.' + end + response.stream.write params[:widget][:didnt_check_for_nil] + end end tests TestController @@ -62,6 +177,21 @@ module ActionController TestResponse.new end + def assert_stream_closed + assert response.stream.closed?, 'stream should be closed' + end + + def capture_log_output + output = StringIO.new + old_logger, ActionController::Base.logger = ActionController::Base.logger, ActiveSupport::Logger.new(output) + + begin + yield output + ensure + ActionController::Base.logger = old_logger + end + end + def test_set_response! @controller.set_response!(@request) assert_kind_of(Live::Response, @controller.response) @@ -93,7 +223,7 @@ module ActionController @controller.process :blocking_stream - assert t.join + assert t.join(3), 'timeout expired before the thread terminated' end def test_thread_locals_get_copied @@ -115,7 +245,54 @@ module ActionController def test_render_text get :render_text assert_equal 'zomg', response.body - assert response.stream.closed?, 'stream should be closed' + assert_stream_closed + end + + def test_exception_handling_html + capture_log_output do |output| + get :exception_in_view + assert_match %r((window\.location = "/500\.html"</script></html>)$), response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end + end + + def test_exception_handling_plain_text + capture_log_output do |output| + get :exception_in_view, format: :json + assert_equal '', response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end + end + + def test_exception_callback + capture_log_output do |output| + get :exception_with_callback, format: 'text/event-stream' + assert_equal %(data: "500 Internal Server Error"\n\n), response.body + assert_match 'An exception occurred...', output.rewind && output.read + assert_stream_closed + end + end + + def test_exceptions_raised_handling_exceptions + capture_log_output do |output| + get :exception_in_exception_callback, format: 'text/event-stream' + assert_equal '', response.body + assert_match 'We need to go deeper', output.rewind && output.read + assert_stream_closed + end + end + + def test_stale_without_etag + get :with_stale + assert_equal 200, @response.status.to_i + end + + def test_stale_with_etag + @request.if_none_match = Digest::MD5.hexdigest("123") + get :with_stale + assert_equal 304, @response.status.to_i end end end diff --git a/actionpack/test/controller/localized_templates_test.rb b/actionpack/test/controller/localized_templates_test.rb index bac1d02977..6b02eedaed 100644 --- a/actionpack/test/controller/localized_templates_test.rb +++ b/actionpack/test/controller/localized_templates_test.rb @@ -25,4 +25,13 @@ class LocalizedTemplatesTest < ActionController::TestCase ensure I18n.locale = old_locale end + + def test_use_fallback_locales + I18n.locale = :"de-AT" + I18n.backend.class.send(:include, I18n::Backend::Fallbacks) + I18n.fallbacks[:"de-AT"] = [:de] + + get :hello_world + assert_equal "Gutten Tag", @response.body + end end diff --git a/actionpack/test/controller/mime/accept_format_test.rb b/actionpack/test/controller/mime/accept_format_test.rb new file mode 100644 index 0000000000..c03c7edeb8 --- /dev/null +++ b/actionpack/test/controller/mime/accept_format_test.rb @@ -0,0 +1,94 @@ +require 'abstract_unit' + +class StarStarMimeController < ActionController::Base + layout nil + + def index + render + end +end + +class StarStarMimeControllerTest < ActionController::TestCase + tests StarStarMimeController + + def test_javascript_with_format + @request.accept = "text/javascript" + get :index, :format => 'js' + assert_match "function addition(a,b){ return a+b; }", @response.body + end + + def test_javascript_with_no_format + @request.accept = "text/javascript" + get :index + assert_match "function addition(a,b){ return a+b; }", @response.body + end + + def test_javascript_with_no_format_only_star_star + @request.accept = "*/*" + get :index + assert_match "function addition(a,b){ return a+b; }", @response.body + end +end + +class AbstractPostController < ActionController::Base + self.view_paths = File.dirname(__FILE__) + "/../../fixtures/post_test/" +end + +# For testing layouts which are set automatically +class PostController < AbstractPostController + around_action :with_iphone + + def index + respond_to(:html, :iphone, :js) + end + +protected + + def with_iphone + request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" + yield + end +end + +class SuperPostController < PostController +end + +class MimeControllerLayoutsTest < ActionController::TestCase + tests PostController + + def setup + super + @request.host = "www.example.com" + Mime::Type.register_alias("text/html", :iphone) + end + + def teardown + super + Mime::Type.unregister(:iphone) + end + + def test_missing_layout_renders_properly + get :index + assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body + + @request.accept = "text/iphone" + get :index + assert_equal 'Hello iPhone', @response.body + end + + def test_format_with_inherited_layouts + @controller = SuperPostController.new + + get :index + assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body + + @request.accept = "text/iphone" + get :index + assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body + end + + def test_non_navigational_format_with_no_template_fallbacks_to_html_template_with_no_layout + get :index, :format => :js + assert_equal "Hello Firefox", @response.body + end +end diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb new file mode 100644 index 0000000000..774dabe105 --- /dev/null +++ b/actionpack/test/controller/mime/respond_to_test.rb @@ -0,0 +1,493 @@ +require 'abstract_unit' + +class RespondToController < ActionController::Base + layout :set_layout + + def html_xml_or_rss + respond_to do |type| + type.html { render :text => "HTML" } + type.xml { render :text => "XML" } + type.rss { render :text => "RSS" } + type.all { render :text => "Nothing" } + end + end + + def js_or_html + respond_to do |type| + type.html { render :text => "HTML" } + type.js { render :text => "JS" } + type.all { render :text => "Nothing" } + end + end + + def json_or_yaml + respond_to do |type| + type.json { render :text => "JSON" } + type.yaml { render :text => "YAML" } + end + end + + def html_or_xml + respond_to do |type| + type.html { render :text => "HTML" } + type.xml { render :text => "XML" } + type.all { render :text => "Nothing" } + end + end + + def json_xml_or_html + respond_to do |type| + type.json { render :text => 'JSON' } + type.xml { render :xml => 'XML' } + type.html { render :text => 'HTML' } + end + end + + + def forced_xml + request.format = :xml + + respond_to do |type| + type.html { render :text => "HTML" } + type.xml { render :text => "XML" } + end + end + + def just_xml + respond_to do |type| + type.xml { render :text => "XML" } + end + end + + def using_defaults + respond_to do |type| + type.html + type.xml + end + end + + def using_defaults_with_type_list + respond_to(:html, :xml) + end + + def using_defaults_with_all + respond_to do |type| + type.html + type.all{ render text: "ALL" } + end + end + + def made_for_content_type + respond_to do |type| + type.rss { render :text => "RSS" } + type.atom { render :text => "ATOM" } + type.all { render :text => "Nothing" } + end + end + + def custom_type_handling + respond_to do |type| + type.html { render :text => "HTML" } + type.custom("application/crazy-xml") { render :text => "Crazy XML" } + type.all { render :text => "Nothing" } + end + end + + + def custom_constant_handling + respond_to do |type| + type.html { render :text => "HTML" } + type.mobile { render :text => "Mobile" } + end + end + + def custom_constant_handling_without_block + respond_to do |type| + type.html { render :text => "HTML" } + type.mobile + end + end + + def handle_any + respond_to do |type| + type.html { render :text => "HTML" } + type.any(:js, :xml) { render :text => "Either JS or XML" } + end + end + + def handle_any_any + respond_to do |type| + type.html { render :text => 'HTML' } + type.any { render :text => 'Whatever you ask for, I got it' } + end + end + + def all_types_with_layout + respond_to do |type| + type.html + end + end + + def iphone_with_html_response_type + request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone" + + respond_to do |type| + type.html { @type = "Firefox" } + type.iphone { @type = "iPhone" } + end + end + + def iphone_with_html_response_type_without_layout + request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" + + respond_to do |type| + type.html { @type = "Firefox"; render :action => "iphone_with_html_response_type" } + type.iphone { @type = "iPhone" ; render :action => "iphone_with_html_response_type" } + end + end + + protected + def set_layout + case action_name + when "all_types_with_layout", "iphone_with_html_response_type" + "respond_to/layouts/standard" + when "iphone_with_html_response_type_without_layout" + "respond_to/layouts/missing" + end + end +end + +class RespondToControllerTest < ActionController::TestCase + tests RespondToController + + def setup + super + @request.host = "www.example.com" + Mime::Type.register_alias("text/html", :iphone) + Mime::Type.register("text/x-mobile", :mobile) + end + + def teardown + super + Mime::Type.unregister(:iphone) + Mime::Type.unregister(:mobile) + end + + def test_html + @request.accept = "text/html" + get :js_or_html + assert_equal 'HTML', @response.body + + get :html_or_xml + assert_equal 'HTML', @response.body + + assert_raises(ActionController::UnknownFormat) do + get :just_xml + end + end + + def test_all + @request.accept = "*/*" + get :js_or_html + assert_equal 'HTML', @response.body # js is not part of all + + get :html_or_xml + assert_equal 'HTML', @response.body + + get :just_xml + assert_equal 'XML', @response.body + end + + def test_xml + @request.accept = "application/xml" + get :html_xml_or_rss + assert_equal 'XML', @response.body + end + + def test_js_or_html + @request.accept = "text/javascript, text/html" + xhr :get, :js_or_html + assert_equal 'JS', @response.body + + @request.accept = "text/javascript, text/html" + xhr :get, :html_or_xml + assert_equal 'HTML', @response.body + + @request.accept = "text/javascript, text/html" + + assert_raises(ActionController::UnknownFormat) do + xhr :get, :just_xml + end + end + + def test_json_or_yaml_with_leading_star_star + @request.accept = "*/*, application/json" + get :json_xml_or_html + assert_equal 'HTML', @response.body + + @request.accept = "*/* , application/json" + get :json_xml_or_html + assert_equal 'HTML', @response.body + end + + def test_json_or_yaml + xhr :get, :json_or_yaml + assert_equal 'JSON', @response.body + + get :json_or_yaml, :format => 'json' + assert_equal 'JSON', @response.body + + get :json_or_yaml, :format => 'yaml' + assert_equal 'YAML', @response.body + + { 'YAML' => %w(text/yaml), + 'JSON' => %w(application/json text/x-json) + }.each do |body, content_types| + content_types.each do |content_type| + @request.accept = content_type + get :json_or_yaml + assert_equal body, @response.body + end + end + end + + def test_js_or_anything + @request.accept = "text/javascript, */*" + xhr :get, :js_or_html + assert_equal 'JS', @response.body + + xhr :get, :html_or_xml + assert_equal 'HTML', @response.body + + xhr :get, :just_xml + assert_equal 'XML', @response.body + end + + def test_using_defaults + @request.accept = "*/*" + get :using_defaults + assert_equal "text/html", @response.content_type + assert_equal 'Hello world!', @response.body + + @request.accept = "application/xml" + get :using_defaults + assert_equal "application/xml", @response.content_type + assert_equal "<p>Hello world!</p>\n", @response.body + end + + def test_using_defaults_with_all + @request.accept = "*/*" + get :using_defaults_with_all + assert_equal "HTML!", @response.body.strip + + @request.accept = "text/html" + get :using_defaults_with_all + assert_equal "HTML!", @response.body.strip + + @request.accept = "application/json" + get :using_defaults_with_all + assert_equal "ALL", @response.body + end + + def test_using_defaults_with_type_list + @request.accept = "*/*" + get :using_defaults_with_type_list + assert_equal "text/html", @response.content_type + assert_equal 'Hello world!', @response.body + + @request.accept = "application/xml" + get :using_defaults_with_type_list + assert_equal "application/xml", @response.content_type + assert_equal "<p>Hello world!</p>\n", @response.body + end + + def test_with_atom_content_type + @request.accept = "" + @request.env["CONTENT_TYPE"] = "application/atom+xml" + xhr :get, :made_for_content_type + assert_equal "ATOM", @response.body + end + + def test_with_rss_content_type + @request.accept = "" + @request.env["CONTENT_TYPE"] = "application/rss+xml" + xhr :get, :made_for_content_type + assert_equal "RSS", @response.body + end + + def test_synonyms + @request.accept = "application/javascript" + get :js_or_html + assert_equal 'JS', @response.body + + @request.accept = "application/x-xml" + get :html_xml_or_rss + assert_equal "XML", @response.body + end + + def test_custom_types + @request.accept = "application/crazy-xml" + get :custom_type_handling + assert_equal "application/crazy-xml", @response.content_type + assert_equal 'Crazy XML', @response.body + + @request.accept = "text/html" + get :custom_type_handling + assert_equal "text/html", @response.content_type + assert_equal 'HTML', @response.body + end + + def test_xhtml_alias + @request.accept = "application/xhtml+xml,application/xml" + get :html_or_xml + assert_equal 'HTML', @response.body + end + + def test_firefox_simulation + @request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + get :html_or_xml + assert_equal 'HTML', @response.body + end + + def test_handle_any + @request.accept = "*/*" + get :handle_any + assert_equal 'HTML', @response.body + + @request.accept = "text/javascript" + get :handle_any + assert_equal 'Either JS or XML', @response.body + + @request.accept = "text/xml" + get :handle_any + assert_equal 'Either JS or XML', @response.body + end + + def test_handle_any_any + @request.accept = "*/*" + get :handle_any_any + assert_equal 'HTML', @response.body + end + + def test_handle_any_any_parameter_format + get :handle_any_any, {:format=>'html'} + assert_equal 'HTML', @response.body + end + + def test_handle_any_any_explicit_html + @request.accept = "text/html" + get :handle_any_any + assert_equal 'HTML', @response.body + end + + def test_handle_any_any_javascript + @request.accept = "text/javascript" + get :handle_any_any + assert_equal 'Whatever you ask for, I got it', @response.body + end + + def test_handle_any_any_xml + @request.accept = "text/xml" + get :handle_any_any + assert_equal 'Whatever you ask for, I got it', @response.body + end + + def test_browser_check_with_any_any + @request.accept = "application/json, application/xml" + get :json_xml_or_html + assert_equal 'JSON', @response.body + + @request.accept = "application/json, application/xml, */*" + get :json_xml_or_html + assert_equal 'HTML', @response.body + end + + def test_html_type_with_layout + @request.accept = "text/html" + get :all_types_with_layout + assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body + end + + def test_xhr + xhr :get, :js_or_html + assert_equal 'JS', @response.body + end + + def test_custom_constant + get :custom_constant_handling, :format => "mobile" + assert_equal "text/x-mobile", @response.content_type + assert_equal "Mobile", @response.body + end + + def test_custom_constant_handling_without_block + get :custom_constant_handling_without_block, :format => "mobile" + assert_equal "text/x-mobile", @response.content_type + assert_equal "Mobile", @response.body + end + + def test_forced_format + get :html_xml_or_rss + assert_equal "HTML", @response.body + + get :html_xml_or_rss, :format => "html" + assert_equal "HTML", @response.body + + get :html_xml_or_rss, :format => "xml" + assert_equal "XML", @response.body + + get :html_xml_or_rss, :format => "rss" + assert_equal "RSS", @response.body + end + + def test_internally_forced_format + get :forced_xml + assert_equal "XML", @response.body + + get :forced_xml, :format => "html" + assert_equal "XML", @response.body + end + + def test_extension_synonyms + get :html_xml_or_rss, :format => "xhtml" + assert_equal "HTML", @response.body + end + + def test_render_action_for_html + @controller.instance_eval do + def render(*args) + @action = args.first[:action] unless args.empty? + @action ||= action_name + + response.body = "#{@action} - #{formats}" + end + end + + get :using_defaults + assert_equal "using_defaults - #{[:html].to_s}", @response.body + + get :using_defaults, :format => "xml" + assert_equal "using_defaults - #{[:xml].to_s}", @response.body + end + + def test_format_with_custom_response_type + get :iphone_with_html_response_type + assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body + + get :iphone_with_html_response_type, :format => "iphone" + assert_equal "text/html", @response.content_type + assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body + end + + def test_format_with_custom_response_type_and_request_headers + @request.accept = "text/iphone" + get :iphone_with_html_response_type + assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body + assert_equal "text/html", @response.content_type + end + + def test_invalid_format + assert_raises(ActionController::UnknownFormat) do + get :using_defaults, :format => "invalidformat" + end + end +end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime/respond_with_test.rb index a9c62899b5..a70592fa1b 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime/respond_with_test.rb @@ -1,529 +1,5 @@ require 'abstract_unit' require 'controller/fake_models' -require 'active_support/core_ext/hash/conversions' - -class StarStarMimeController < ActionController::Base - layout nil - - def index - render - end -end - -class RespondToController < ActionController::Base - layout :set_layout - - def html_xml_or_rss - respond_to do |type| - type.html { render :text => "HTML" } - type.xml { render :text => "XML" } - type.rss { render :text => "RSS" } - type.all { render :text => "Nothing" } - end - end - - def js_or_html - respond_to do |type| - type.html { render :text => "HTML" } - type.js { render :text => "JS" } - type.all { render :text => "Nothing" } - end - end - - def json_or_yaml - respond_to do |type| - type.json { render :text => "JSON" } - type.yaml { render :text => "YAML" } - end - end - - def html_or_xml - respond_to do |type| - type.html { render :text => "HTML" } - type.xml { render :text => "XML" } - type.all { render :text => "Nothing" } - end - end - - def json_xml_or_html - respond_to do |type| - type.json { render :text => 'JSON' } - type.xml { render :xml => 'XML' } - type.html { render :text => 'HTML' } - end - end - - - def forced_xml - request.format = :xml - - respond_to do |type| - type.html { render :text => "HTML" } - type.xml { render :text => "XML" } - end - end - - def just_xml - respond_to do |type| - type.xml { render :text => "XML" } - end - end - - def using_defaults - respond_to do |type| - type.html - type.xml - end - end - - def using_defaults_with_type_list - respond_to(:html, :xml) - end - - def using_defaults_with_all - respond_to do |type| - type.html - type.all{ render text: "ALL" } - end - end - - def made_for_content_type - respond_to do |type| - type.rss { render :text => "RSS" } - type.atom { render :text => "ATOM" } - type.all { render :text => "Nothing" } - end - end - - def custom_type_handling - respond_to do |type| - type.html { render :text => "HTML" } - type.custom("application/crazy-xml") { render :text => "Crazy XML" } - type.all { render :text => "Nothing" } - end - end - - - def custom_constant_handling - respond_to do |type| - type.html { render :text => "HTML" } - type.mobile { render :text => "Mobile" } - end - end - - def custom_constant_handling_without_block - respond_to do |type| - type.html { render :text => "HTML" } - type.mobile - end - end - - def handle_any - respond_to do |type| - type.html { render :text => "HTML" } - type.any(:js, :xml) { render :text => "Either JS or XML" } - end - end - - def handle_any_any - respond_to do |type| - type.html { render :text => 'HTML' } - type.any { render :text => 'Whatever you ask for, I got it' } - end - end - - def all_types_with_layout - respond_to do |type| - type.html - end - end - - def iphone_with_html_response_type - request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone" - - respond_to do |type| - type.html { @type = "Firefox" } - type.iphone { @type = "iPhone" } - end - end - - def iphone_with_html_response_type_without_layout - request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" - - respond_to do |type| - type.html { @type = "Firefox"; render :action => "iphone_with_html_response_type" } - type.iphone { @type = "iPhone" ; render :action => "iphone_with_html_response_type" } - end - end - - protected - def set_layout - case action_name - when "all_types_with_layout", "iphone_with_html_response_type" - "respond_to/layouts/standard" - when "iphone_with_html_response_type_without_layout" - "respond_to/layouts/missing" - end - end -end - -class StarStarMimeControllerTest < ActionController::TestCase - tests StarStarMimeController - - def test_javascript_with_format - @request.accept = "text/javascript" - get :index, :format => 'js' - assert_match "function addition(a,b){ return a+b; }", @response.body - end - - def test_javascript_with_no_format - @request.accept = "text/javascript" - get :index - assert_match "function addition(a,b){ return a+b; }", @response.body - end - - def test_javascript_with_no_format_only_star_star - @request.accept = "*/*" - get :index - assert_match "function addition(a,b){ return a+b; }", @response.body - end - -end - -class RespondToControllerTest < ActionController::TestCase - tests RespondToController - - def setup - super - @request.host = "www.example.com" - Mime::Type.register_alias("text/html", :iphone) - Mime::Type.register("text/x-mobile", :mobile) - end - - def teardown - super - Mime::Type.unregister(:iphone) - Mime::Type.unregister(:mobile) - end - - def test_html - @request.accept = "text/html" - get :js_or_html - assert_equal 'HTML', @response.body - - get :html_or_xml - assert_equal 'HTML', @response.body - - assert_raises(ActionController::UnknownFormat) do - get :just_xml - end - end - - def test_all - @request.accept = "*/*" - get :js_or_html - assert_equal 'HTML', @response.body # js is not part of all - - get :html_or_xml - assert_equal 'HTML', @response.body - - get :just_xml - assert_equal 'XML', @response.body - end - - def test_xml - @request.accept = "application/xml" - get :html_xml_or_rss - assert_equal 'XML', @response.body - end - - def test_js_or_html - @request.accept = "text/javascript, text/html" - xhr :get, :js_or_html - assert_equal 'JS', @response.body - - @request.accept = "text/javascript, text/html" - xhr :get, :html_or_xml - assert_equal 'HTML', @response.body - - @request.accept = "text/javascript, text/html" - - assert_raises(ActionController::UnknownFormat) do - xhr :get, :just_xml - end - end - - def test_json_or_yaml_with_leading_star_star - @request.accept = "*/*, application/json" - get :json_xml_or_html - assert_equal 'HTML', @response.body - - @request.accept = "*/* , application/json" - get :json_xml_or_html - assert_equal 'HTML', @response.body - end - - def test_json_or_yaml - xhr :get, :json_or_yaml - assert_equal 'JSON', @response.body - - get :json_or_yaml, :format => 'json' - assert_equal 'JSON', @response.body - - get :json_or_yaml, :format => 'yaml' - assert_equal 'YAML', @response.body - - { 'YAML' => %w(text/yaml), - 'JSON' => %w(application/json text/x-json) - }.each do |body, content_types| - content_types.each do |content_type| - @request.accept = content_type - get :json_or_yaml - assert_equal body, @response.body - end - end - end - - def test_js_or_anything - @request.accept = "text/javascript, */*" - xhr :get, :js_or_html - assert_equal 'JS', @response.body - - xhr :get, :html_or_xml - assert_equal 'HTML', @response.body - - xhr :get, :just_xml - assert_equal 'XML', @response.body - end - - def test_using_defaults - @request.accept = "*/*" - get :using_defaults - assert_equal "text/html", @response.content_type - assert_equal 'Hello world!', @response.body - - @request.accept = "application/xml" - get :using_defaults - assert_equal "application/xml", @response.content_type - assert_equal "<p>Hello world!</p>\n", @response.body - end - - def test_using_defaults_with_all - @request.accept = "*/*" - get :using_defaults_with_all - assert_equal "HTML!", @response.body.strip - - @request.accept = "text/html" - get :using_defaults_with_all - assert_equal "HTML!", @response.body.strip - - @request.accept = "application/json" - get :using_defaults_with_all - assert_equal "ALL", @response.body - end - - def test_using_defaults_with_type_list - @request.accept = "*/*" - get :using_defaults_with_type_list - assert_equal "text/html", @response.content_type - assert_equal 'Hello world!', @response.body - - @request.accept = "application/xml" - get :using_defaults_with_type_list - assert_equal "application/xml", @response.content_type - assert_equal "<p>Hello world!</p>\n", @response.body - end - - def test_with_atom_content_type - @request.accept = "" - @request.env["CONTENT_TYPE"] = "application/atom+xml" - xhr :get, :made_for_content_type - assert_equal "ATOM", @response.body - end - - def test_with_rss_content_type - @request.accept = "" - @request.env["CONTENT_TYPE"] = "application/rss+xml" - xhr :get, :made_for_content_type - assert_equal "RSS", @response.body - end - - def test_synonyms - @request.accept = "application/javascript" - get :js_or_html - assert_equal 'JS', @response.body - - @request.accept = "application/x-xml" - get :html_xml_or_rss - assert_equal "XML", @response.body - end - - def test_custom_types - @request.accept = "application/crazy-xml" - get :custom_type_handling - assert_equal "application/crazy-xml", @response.content_type - assert_equal 'Crazy XML', @response.body - - @request.accept = "text/html" - get :custom_type_handling - assert_equal "text/html", @response.content_type - assert_equal 'HTML', @response.body - end - - def test_xhtml_alias - @request.accept = "application/xhtml+xml,application/xml" - get :html_or_xml - assert_equal 'HTML', @response.body - end - - def test_firefox_simulation - @request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" - get :html_or_xml - assert_equal 'HTML', @response.body - end - - def test_handle_any - @request.accept = "*/*" - get :handle_any - assert_equal 'HTML', @response.body - - @request.accept = "text/javascript" - get :handle_any - assert_equal 'Either JS or XML', @response.body - - @request.accept = "text/xml" - get :handle_any - assert_equal 'Either JS or XML', @response.body - end - - def test_handle_any_any - @request.accept = "*/*" - get :handle_any_any - assert_equal 'HTML', @response.body - end - - def test_handle_any_any_parameter_format - get :handle_any_any, {:format=>'html'} - assert_equal 'HTML', @response.body - end - - def test_handle_any_any_explicit_html - @request.accept = "text/html" - get :handle_any_any - assert_equal 'HTML', @response.body - end - - def test_handle_any_any_javascript - @request.accept = "text/javascript" - get :handle_any_any - assert_equal 'Whatever you ask for, I got it', @response.body - end - - def test_handle_any_any_xml - @request.accept = "text/xml" - get :handle_any_any - assert_equal 'Whatever you ask for, I got it', @response.body - end - - def test_browser_check_with_any_any - @request.accept = "application/json, application/xml" - get :json_xml_or_html - assert_equal 'JSON', @response.body - - @request.accept = "application/json, application/xml, */*" - get :json_xml_or_html - assert_equal 'HTML', @response.body - end - - def test_html_type_with_layout - @request.accept = "text/html" - get :all_types_with_layout - assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body - end - - def test_xhr - xhr :get, :js_or_html - assert_equal 'JS', @response.body - end - - def test_custom_constant - get :custom_constant_handling, :format => "mobile" - assert_equal "text/x-mobile", @response.content_type - assert_equal "Mobile", @response.body - end - - def test_custom_constant_handling_without_block - get :custom_constant_handling_without_block, :format => "mobile" - assert_equal "text/x-mobile", @response.content_type - assert_equal "Mobile", @response.body - end - - def test_forced_format - get :html_xml_or_rss - assert_equal "HTML", @response.body - - get :html_xml_or_rss, :format => "html" - assert_equal "HTML", @response.body - - get :html_xml_or_rss, :format => "xml" - assert_equal "XML", @response.body - - get :html_xml_or_rss, :format => "rss" - assert_equal "RSS", @response.body - end - - def test_internally_forced_format - get :forced_xml - assert_equal "XML", @response.body - - get :forced_xml, :format => "html" - assert_equal "XML", @response.body - end - - def test_extension_synonyms - get :html_xml_or_rss, :format => "xhtml" - assert_equal "HTML", @response.body - end - - def test_render_action_for_html - @controller.instance_eval do - def render(*args) - @action = args.first[:action] unless args.empty? - @action ||= action_name - - response.body = "#{@action} - #{formats}" - end - end - - get :using_defaults - assert_equal "using_defaults - #{[:html].to_s}", @response.body - - get :using_defaults, :format => "xml" - assert_equal "using_defaults - #{[:xml].to_s}", @response.body - end - - def test_format_with_custom_response_type - get :iphone_with_html_response_type - assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body - - get :iphone_with_html_response_type, :format => "iphone" - assert_equal "text/html", @response.content_type - assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body - end - - def test_format_with_custom_response_type_and_request_headers - @request.accept = "text/iphone" - get :iphone_with_html_response_type - assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body - assert_equal "text/html", @response.content_type - end - - def test_invalid_format - assert_raises(ActionController::UnknownFormat) do - get :using_defaults, :format => "invalidformat" - end - end -end class RespondWithController < ActionController::Base respond_to :html, :json, :touch @@ -589,7 +65,17 @@ class RespondWithController < ActionController::Base respond_with(resource, :responder => responder) end + def respond_with_additional_params + @params = RespondWithController.params + respond_with({:result => resource}, @params) + end + protected + def self.params + { + :foo => 'bar' + } + end def resource Customer.new("david", request.delete? ? nil : 13) @@ -631,6 +117,20 @@ class RenderJsonRespondWithController < RespondWithController end end +class CsvRespondWithController < ActionController::Base + respond_to :csv + + class RespondWithCsv + def to_csv + "c,s,v" + end + end + + def index + respond_with(RespondWithCsv.new) + end +end + class EmptyRespondWithController < ActionController::Base def index respond_with(Customer.new("david", 13)) @@ -655,6 +155,11 @@ class RespondWithControllerTest < ActionController::TestCase Mime::Type.unregister(:mobile) end + def test_respond_with_shouldnt_modify_original_hash + get :respond_with_additional_params + assert_equal RespondWithController.params, assigns(:params) + end + def test_using_resource @request.accept = "application/xml" get :using_resource @@ -847,6 +352,7 @@ class RespondWithControllerTest < ActionController::TestCase errors = { :name => :invalid } Customer.any_instance.stubs(:errors).returns(errors) put :using_resource + assert_equal "text/html", @response.content_type assert_equal 200, @response.status assert_equal "Edit world!\n", @response.body @@ -1131,6 +637,23 @@ class RespondWithControllerTest < ActionController::TestCase RespondWithController.responder = ActionController::Responder end + def test_uses_renderer_if_an_api_behavior + ActionController::Renderers.add :csv do |obj, options| + send_data obj.to_csv, type: Mime::CSV + end + @controller = CsvRespondWithController.new + get :index, format: 'csv' + assert_equal Mime::CSV, @response.content_type + assert_equal "c,s,v", @response.body + end + + def test_raises_missing_renderer_if_an_api_behavior_with_no_renderer + @controller = CsvRespondWithController.new + assert_raise ActionController::MissingRenderer do + get :index, format: 'csv' + end + end + def test_error_is_raised_if_no_respond_to_is_declared_and_respond_with_is_called @controller = EmptyRespondWithController.new @request.accept = "*/*" @@ -1154,69 +677,6 @@ class RespondWithControllerTest < ActionController::TestCase end end -class AbstractPostController < ActionController::Base - self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/" -end - -# For testing layouts which are set automatically -class PostController < AbstractPostController - around_action :with_iphone - - def index - respond_to(:html, :iphone, :js) - end - -protected - - def with_iphone - request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" - yield - end -end - -class SuperPostController < PostController -end - -class MimeControllerLayoutsTest < ActionController::TestCase - tests PostController - - def setup - super - @request.host = "www.example.com" - Mime::Type.register_alias("text/html", :iphone) - end - - def teardown - super - Mime::Type.unregister(:iphone) - end - - def test_missing_layout_renders_properly - get :index - assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body - - @request.accept = "text/iphone" - get :index - assert_equal 'Hello iPhone', @response.body - end - - def test_format_with_inherited_layouts - @controller = SuperPostController.new - - get :index - assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body - - @request.accept = "text/iphone" - get :index - assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body - end - - def test_non_navigational_format_with_no_template_fallbacks_to_html_template_with_no_layout - get :index, :format => :js - assert_equal "Hello Firefox", @response.body - end -end - class FlashResponder < ActionController::Responder def initialize(controller, resources, options={}) super diff --git a/actionpack/test/controller/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb index 2f1aa22208..9e5022c9f4 100644 --- a/actionpack/test/controller/new_base/render_partial_test.rb +++ b/actionpack/test/controller/new_base/render_partial_test.rb @@ -5,14 +5,14 @@ module RenderPartial class BasicController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new( - "render_partial/basic/_basic.html.erb" => "BasicPartial!", - "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>", - "render_partial/basic/with_json.html.erb" => "<%= render :partial => 'with_json', :formats => [:json] %>", - "render_partial/basic/_with_json.json.erb" => "<%= render :partial => 'final', :formats => [:json] %>", - "render_partial/basic/_final.json.erb" => "{ final: json }", - "render_partial/basic/overriden.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'overriden' %><%= @test_unchanged %>", - "render_partial/basic/_overriden.html.erb" => "ParentPartial!", - "render_partial/child/_overriden.html.erb" => "OverridenPartial!" + "render_partial/basic/_basic.html.erb" => "BasicPartial!", + "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>", + "render_partial/basic/with_json.html.erb" => "<%= render :partial => 'with_json', :formats => [:json] %>", + "render_partial/basic/_with_json.json.erb" => "<%= render :partial => 'final', :formats => [:json] %>", + "render_partial/basic/_final.json.erb" => "{ final: json }", + "render_partial/basic/overridden.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'overridden' %><%= @test_unchanged %>", + "render_partial/basic/_overridden.html.erb" => "ParentPartial!", + "render_partial/child/_overridden.html.erb" => "OverriddenPartial!" )] def html_with_json_inside_json @@ -24,7 +24,7 @@ module RenderPartial render :action => "basic" end - def overriden + def overridden @test_unchanged = 'hello' end end @@ -55,8 +55,8 @@ module RenderPartial end test "partial from child controller gets picked" do - get :overriden - assert_response("goodbyeOverridenPartial!goodbye") + get :overridden + assert_response("goodbyeOverriddenPartial!goodbye") end end diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index f4bdd3e1d4..2b36a399bb 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -92,7 +92,7 @@ module RenderStreaming io.rewind assert_match "(undefined method `invalid!' for nil:NilClass)", io.read ensure - ActionController::Base.logger = _old + ActionView::Base.logger = _old end end diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb index cc7f12ac6d..5635e16234 100644 --- a/actionpack/test/controller/new_base/render_test.rb +++ b/actionpack/test/controller/new_base/render_test.rb @@ -7,10 +7,10 @@ module Render "render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>", "render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>", "render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>", - "render/blank_render/overriden_with_own_view_paths_appended.html.erb" => "parent content", - "render/blank_render/overriden_with_own_view_paths_prepended.html.erb" => "parent content", - "render/blank_render/overriden.html.erb" => "parent content", - "render/child_render/overriden.html.erb" => "child content" + "render/blank_render/overridden_with_own_view_paths_appended.html.erb" => "parent content", + "render/blank_render/overridden_with_own_view_paths_prepended.html.erb" => "parent content", + "render/blank_render/overridden.html.erb" => "parent content", + "render/child_render/overridden.html.erb" => "child content" )] def index @@ -25,13 +25,13 @@ module Render render :action => "access_action_name" end - def overriden_with_own_view_paths_appended + def overridden_with_own_view_paths_appended end - def overriden_with_own_view_paths_prepended + def overridden_with_own_view_paths_prepended end - def overriden + def overridden end private @@ -49,8 +49,8 @@ module Render end class ChildRenderController < BlankRenderController - append_view_path ActionView::FixtureResolver.new("render/child_render/overriden_with_own_view_paths_appended.html.erb" => "child content") - prepend_view_path ActionView::FixtureResolver.new("render/child_render/overriden_with_own_view_paths_prepended.html.erb" => "child content") + append_view_path ActionView::FixtureResolver.new("render/child_render/overridden_with_own_view_paths_appended.html.erb" => "child content") + prepend_view_path ActionView::FixtureResolver.new("render/child_render/overridden_with_own_view_paths_prepended.html.erb" => "child content") end class RenderTest < Rack::TestCase @@ -114,17 +114,17 @@ module Render class TestViewInheritance < Rack::TestCase test "Template from child controller gets picked over parent one" do - get "/render/child_render/overriden" + get "/render/child_render/overridden" assert_body "child content" end test "Template from child controller with custom view_paths prepended gets picked over parent one" do - get "/render/child_render/overriden_with_own_view_paths_prepended" + get "/render/child_render/overridden_with_own_view_paths_prepended" assert_body "child content" end test "Template from child controller with custom view_paths appended gets picked over parent one" do - get "/render/child_render/overriden_with_own_view_paths_appended" + get "/render/child_render/overridden_with_own_view_paths_appended" assert_body "child content" end diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb index d6c3926a4d..2a253799f3 100644 --- a/actionpack/test/controller/new_base/render_text_test.rb +++ b/actionpack/test/controller/new_base/render_text_test.rb @@ -1,6 +1,15 @@ require 'abstract_unit' module RenderText + class MinimalController < ActionController::Metal + include AbstractController::Rendering + include ActionController::Rendering + + def index + render text: "Hello World!" + end + end + class SimpleController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new] @@ -63,6 +72,12 @@ module RenderText end class RenderTextTest < Rack::TestCase + test "rendering text from a minimal controller" do + get "/render_text/minimal/index" + assert_body "Hello World!" + assert_status 200 + end + test "rendering text from an action with default options renders the text with the layout" do with_routing do |set| set.draw { get ':controller', :action => 'index' } diff --git a/actionpack/test/controller/output_escaping_test.rb b/actionpack/test/controller/output_escaping_test.rb index 43a8c05cda..c3c549fbfc 100644 --- a/actionpack/test/controller/output_escaping_test.rb +++ b/actionpack/test/controller/output_escaping_test.rb @@ -11,8 +11,6 @@ class OutputEscapingTest < ActiveSupport::TestCase end test "escapeHTML shouldn't touch explicitly safe strings" do - # TODO this seems easier to compose and reason about, but - # this should be verified assert_equal "<", ERB::Util.h("<".html_safe) end diff --git a/actionpack/test/controller/parameters/nested_parameters_test.rb b/actionpack/test/controller/parameters/nested_parameters_test.rb index 91df527dec..3b1257e8d5 100644 --- a/actionpack/test/controller/parameters/nested_parameters_test.rb +++ b/actionpack/test/controller/parameters/nested_parameters_test.rb @@ -169,4 +169,19 @@ class NestedParametersTest < ActiveSupport::TestCase assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death end + + test "nested number as key" do + params = ActionController::Parameters.new({ + product: { + properties: { + '0' => "prop0", + '1' => "prop1" + } + } + }) + params = params.require(:product).permit(:properties => ["0"]) + assert_not_nil params[:properties]["0"] + assert_nil params[:properties]["1"] + assert_equal "prop0", params[:properties]["0"] + end end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 437da43d9b..b60c5f058d 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -107,6 +107,15 @@ class ParametersPermitTest < ActiveSupport::TestCase assert_equal [], permitted[:id] end + test 'do not break params filtering on nil values' do + params = ActionController::Parameters.new(a: 1, b: [1, 2, 3], c: nil) + + permitted = params.permit(:a, c: [], b: []) + assert_equal 1, permitted[:a] + assert_equal [1, 2, 3], permitted[:b] + assert_equal nil, permitted[:c] + end + test 'key to empty array: arrays of permitted scalars pass' do [['foo'], [1], ['foo', 'bar'], [1, 2, 3]].each do |array| params = ActionController::Parameters.new(id: array) @@ -138,6 +147,12 @@ class ParametersPermitTest < ActiveSupport::TestCase assert_equal :foo, e.param end + test "fetch with a default value of a hash does not mutate the object" do + params = ActionController::Parameters.new({}) + params.fetch :foo, {} + assert_equal nil, params[:foo] + end + test "fetch doesnt raise ParameterMissing exception if there is a default" do assert_equal "monkey", @params.fetch(:foo, "monkey") assert_equal "monkey", @params.fetch(:foo) { "monkey" } diff --git a/actionpack/test/controller/record_identifier_test.rb b/actionpack/test/controller/record_identifier_test.rb deleted file mode 100644 index ff5d7fd3bd..0000000000 --- a/actionpack/test/controller/record_identifier_test.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'abstract_unit' -require 'controller/fake_models' - -class ControllerRecordIdentifierTest < ActiveSupport::TestCase - include ActionController::RecordIdentifier - - def setup - @record = Comment.new - end - - def test_dom_id_deprecation - assert_deprecated(/dom_id method will no longer be included by default in controllers/) do - dom_id(@record) - end - end - - def test_dom_class_deprecation - assert_deprecated(/dom_class method will no longer be included by default in controllers/) do - dom_class(@record) - end - end - - def test_dom_id_from_module_deprecation - assert_deprecated(/Calling ActionController::RecordIdentifier.dom_id is deprecated/) do - ActionController::RecordIdentifier.dom_id(@record) - end - end - - def test_dom_class_from_module_deprecation - assert_deprecated(/Calling ActionController::RecordIdentifier.dom_class is deprecated/) do - ActionController::RecordIdentifier.dom_class(@record) - end - end -end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 0e5bad7482..f41287381a 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -2,26 +2,6 @@ require 'abstract_unit' require 'controller/fake_models' require 'pathname' -module Fun - class GamesController < ActionController::Base - # :ported: - def hello_world - end - - def nested_partial_with_form_builder - render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}) - end - end -end - -module Quiz - class QuestionsController < ActionController::Base - def new - render :partial => Quiz::Question.new("Namespaced Partial") - end - end -end - class TestControllerWithExtraEtags < ActionController::Base etag { nil } etag { 'ab' } @@ -32,6 +12,10 @@ class TestControllerWithExtraEtags < ActionController::Base def fresh render text: "stale" if stale?(etag: '123') end + + def array + render text: "stale" if stale?(etag: %w(1 2 3)) + end end class TestController < ActionController::Base @@ -54,10 +38,6 @@ class TestController < ActionController::Base def hello_world end - def hello_world_file - render :file => File.expand_path("../../fixtures/hello", __FILE__), :formats => [:html] - end - def conditional_hello if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123]) render :action => 'hello_world' @@ -143,327 +123,10 @@ class TestController < ActionController::Base fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ]) end - # :ported: - def render_hello_world - render :template => "test/hello_world" - end - - def render_hello_world_with_last_modified_set - response.last_modified = Date.new(2008, 10, 10).to_time - render :template => "test/hello_world" - end - - # :ported: compatibility - def render_hello_world_with_forward_slash - render :template => "/test/hello_world" - end - - # :ported: - def render_template_in_top_directory - render :template => 'shared' - end - - # :deprecated: - def render_template_in_top_directory_with_slash - render :template => '/shared' - end - - # :ported: - def render_hello_world_from_variable - @person = "david" - render :text => "hello #{@person}" - end - - # :ported: - def render_action_hello_world - render :action => "hello_world" - end - - def render_action_upcased_hello_world - render :action => "Hello_world" - end - - def render_action_hello_world_as_string - render "hello_world" - end - - def render_action_hello_world_with_symbol - render :action => :hello_world - end - - # :ported: - def render_text_hello_world - render :text => "hello world" - end - - # :ported: - def render_text_hello_world_with_layout - @variable_for_layout = ", I am here!" - render :text => "hello world", :layout => true - end - - def hello_world_with_layout_false - render :layout => false - end - - # :ported: - def render_file_with_instance_variables - @secret = 'in the sauce' - path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar') - render :file => path - end - - # :ported: - def render_file_as_string_with_instance_variables - @secret = 'in the sauce' - path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar')) - render path - end - - # :ported: - def render_file_not_using_full_path - @secret = 'in the sauce' - render :file => 'test/render_file_with_ivar' - end - - def render_file_not_using_full_path_with_dot_in_path - @secret = 'in the sauce' - render :file => 'test/dot.directory/render_file_with_ivar' - end - - def render_file_using_pathname - @secret = 'in the sauce' - render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar') - end - - def render_file_from_template - @secret = 'in the sauce' - @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar')) - end - - def render_file_with_locals - path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals') - render :file => path, :locals => {:secret => 'in the sauce'} - end - - def render_file_as_string_with_locals - path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals')) - render path, :locals => {:secret => 'in the sauce'} - end - - def accessing_request_in_template - render :inline => "Hello: <%= request.host %>" - end - - def accessing_logger_in_template - render :inline => "<%= logger.class %>" - end - - def accessing_action_name_in_template - render :inline => "<%= action_name %>" - end - - def accessing_controller_name_in_template - render :inline => "<%= controller_name %>" - end - - # :ported: - def render_custom_code - render :text => "hello world", :status => 404 - end - - # :ported: - def render_text_with_nil - render :text => nil - end - - # :ported: - def render_text_with_false - render :text => false - end - - def render_text_with_resource - render :text => Customer.new("David") - end - - # :ported: - def render_nothing_with_appendix - render :text => "appended" - end - - # This test is testing 3 things: - # render :file in AV :ported: - # render :template in AC :ported: - # setting content type - def render_xml_hello - @name = "David" - render :template => "test/hello" - end - - def render_xml_hello_as_string_template - @name = "David" - render "test/hello" - end - - def render_line_offset - render :inline => '<% raise %>', :locals => {:foo => 'bar'} - end - def heading head :ok end - def greeting - # let's just rely on the template - end - - # :ported: - def blank_response - render :text => ' ' - end - - # :ported: - def layout_test - render :action => "hello_world" - end - - # :ported: - def builder_layout_test - @name = nil - render :action => "hello", :layout => "layouts/builder" - end - - # :move: test this in Action View - def builder_partial_test - render :action => "hello_world_container" - end - - # :ported: - def partials_list - @test_unchanged = 'hello' - @customers = [ Customer.new("david"), Customer.new("mary") ] - render :action => "list" - end - - def partial_only - render :partial => true - end - - def hello_in_a_string - @customers = [ Customer.new("david"), Customer.new("mary") ] - render :text => "How's there? " + render_to_string(:template => "test/list") - end - - def accessing_params_in_template - render :inline => "Hello: <%= params[:name] %>" - end - - def accessing_local_assigns_in_inline_template - name = params[:local_name] - render :inline => "<%= 'Goodbye, ' + local_name %>", - :locals => { :local_name => name } - end - - def render_implicit_html_template_from_xhr_request - end - - def render_implicit_js_template_without_layout - end - - def formatted_html_erb - end - - def formatted_xml_erb - end - - def render_to_string_test - @foo = render_to_string :inline => "this is a test" - end - - def default_render - @alternate_default_render ||= nil - if @alternate_default_render - @alternate_default_render.call - else - super - end - end - - def render_action_hello_world_as_symbol - render :action => :hello_world - end - - def layout_test_with_different_layout - render :action => "hello_world", :layout => "standard" - end - - def layout_test_with_different_layout_and_string_action - render "hello_world", :layout => "standard" - end - - def layout_test_with_different_layout_and_symbol_action - render :hello_world, :layout => "standard" - end - - def rendering_without_layout - render :action => "hello_world", :layout => false - end - - def layout_overriding_layout - render :action => "hello_world", :layout => "standard" - end - - def rendering_nothing_on_layout - render :nothing => true - end - - def render_to_string_with_assigns - @before = "i'm before the render" - render_to_string :text => "foo" - @after = "i'm after the render" - render :template => "test/hello_world" - end - - def render_to_string_with_exception - render_to_string :file => "exception that will not be caught - this will certainly not work" - end - - def render_to_string_with_caught_exception - @before = "i'm before the render" - begin - render_to_string :file => "exception that will be caught- hope my future instance vars still work!" - rescue - end - @after = "i'm after the render" - render :template => "test/hello_world" - end - - def accessing_params_in_template_with_layout - render :layout => true, :inline => "Hello: <%= params[:name] %>" - end - - # :ported: - def render_with_explicit_template - render :template => "test/hello_world" - end - - def render_with_explicit_unescaped_template - render :template => "test/h*llo_world" - end - - def render_with_explicit_escaped_template - render :template => "test/hello,world" - end - - def render_with_explicit_string_template - render "test/hello_world" - end - - # :ported: - def render_with_explicit_template_with_locals - render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' } - end - # :ported: def double_render render :text => "hello" @@ -504,25 +167,6 @@ class TestController < ActionController::Base render :template => "test/hello_world_from_rxml", :handlers => [:builder] end - def action_talk_to_layout - # Action template sets variable that's picked up by layout - end - - # :addressed: - def render_text_with_assigns - @hello = "world" - render :text => "foo" - end - - def yield_content_for - render :action => "content_for", :layout => "yield" - end - - def render_content_type_from_body - response.content_type = Mime::RSS - render :text => "hello world!" - end - def head_created head :created end @@ -567,162 +211,6 @@ class TestController < ActionController::Base head :forbidden, :x_custom_header => "something" end - def render_using_layout_around_block - render :action => "using_layout_around_block" - end - - def render_using_layout_around_block_in_main_layout_and_within_content_for_layout - render :action => "using_layout_around_block", :layout => "layouts/block_with_layout" - end - - def partial_formats_html - render :partial => 'partial', :formats => [:html] - end - - def partial - render :partial => 'partial' - end - - def partial_html_erb - render :partial => 'partial_html_erb' - end - - def render_to_string_with_partial - @partial_only = render_to_string :partial => "partial_only" - @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") } - render :template => "test/hello_world" - end - - def render_to_string_with_template_and_html_partial - @text = render_to_string :template => "test/with_partial", :formats => [:text] - @html = render_to_string :template => "test/with_partial", :formats => [:html] - render :template => "test/with_html_partial" - end - - def render_to_string_and_render_with_different_formats - @html = render_to_string :template => "test/with_partial", :formats => [:html] - render :template => "test/with_partial", :formats => [:text] - end - - def render_template_within_a_template_with_other_format - render :template => "test/with_xml_template", - :formats => [:html], - :layout => "with_html_partial" - end - - def partial_with_counter - render :partial => "counter", :locals => { :counter_counter => 5 } - end - - def partial_with_locals - render :partial => "customer", :locals => { :customer => Customer.new("david") } - end - - def partial_with_form_builder - render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}) - end - - def partial_with_form_builder_subclass - render :partial => LabellingFormBuilder.new(:post, nil, view_context, {}) - end - - def partial_collection - render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ] - end - - def partial_collection_with_as - render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer - end - - def partial_collection_with_counter - render :partial => "customer_counter", :collection => [ Customer.new("david"), Customer.new("mary") ] - end - - def partial_collection_with_as_and_counter - render :partial => "customer_counter_with_as", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :client - end - - def partial_collection_with_locals - render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" } - end - - def partial_collection_with_spacer - render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ] - end - - def partial_collection_with_spacer_which_uses_render - render :partial => "customer", :spacer_template => "partial_with_partial", :collection => [ Customer.new("david"), Customer.new("mary") ] - end - - def partial_collection_shorthand_with_locals - render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" } - end - - def partial_collection_shorthand_with_different_types_of_records - render :partial => [ - BadCustomer.new("mark"), - GoodCustomer.new("craig"), - BadCustomer.new("john"), - GoodCustomer.new("zach"), - GoodCustomer.new("brandon"), - BadCustomer.new("dan") ], - :locals => { :greeting => "Bonjour" } - end - - def empty_partial_collection - render :partial => "customer", :collection => [] - end - - def partial_collection_shorthand_with_different_types_of_records_with_counter - partial_collection_shorthand_with_different_types_of_records - end - - def missing_partial - render :partial => 'thisFileIsntHere' - end - - def partial_with_hash_object - render :partial => "hash_object", :object => {:first_name => "Sam"} - end - - def partial_with_nested_object - render :partial => "quiz/questions/question", :object => Quiz::Question.new("first") - end - - def partial_with_nested_object_shorthand - render Quiz::Question.new("first") - end - - def partial_hash_collection - render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ] - end - - def partial_hash_collection_with_locals - render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" } - end - - def partial_with_implicit_local_assignment - @customer = Customer.new("Marcel") - render :partial => "customer" - end - - def render_call_to_partial_with_layout - render :action => "calling_partial_with_layout" - end - - def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout - render :action => "calling_partial_with_layout", :layout => "layouts/partial_with_layout" - end - - before_action only: :render_with_filters do - request.format = :xml - end - - # Ensure that the before filter is executed *before* self.formats is set. - def render_with_filters - render :action => :formatted_xml_erb - end - private def set_variable_for_layout @@ -751,6 +239,8 @@ class TestController < ActionController::Base end class MetalTestController < ActionController::Metal + include AbstractController::Rendering + include ActionView::Rendering include ActionController::Rendering def accessing_logger_in_template @@ -758,463 +248,188 @@ class MetalTestController < ActionController::Metal end end -class RenderTest < ActionController::TestCase +class ExpiresInRenderTest < ActionController::TestCase tests TestController - def setup - # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get - # a more accurate simulation of what happens in "real life". - super - @controller.logger = ActiveSupport::Logger.new(nil) - ActionView::Base.logger = ActiveSupport::Logger.new(nil) - - @request.host = "www.nextangle.com" - end - - # :ported: - def test_simple_show - get :hello_world - assert_response 200 - assert_response :success - assert_template "test/hello_world" - assert_equal "<html>Hello world!</html>", @response.body - end - - # :ported: - def test_renders_default_template_for_missing_action - get :'hyphen-ated' - assert_template 'test/hyphen-ated' + def test_expires_in_header + get :conditional_hello_with_expires_in + assert_equal "max-age=60, private", @response.headers["Cache-Control"] end - # :ported: - def test_render - get :render_hello_world - assert_template "test/hello_world" + def test_expires_in_header_with_public + get :conditional_hello_with_expires_in_with_public + assert_equal "max-age=60, public", @response.headers["Cache-Control"] end - def test_line_offset - get :render_line_offset - flunk "the action should have raised an exception" - rescue StandardError => exc - line = exc.backtrace.first - assert(line =~ %r{:(\d+):}) - assert_equal "1", $1, - "The line offset is wrong, perhaps the wrong exception has been raised, exception was: #{exc.inspect}" + def test_expires_in_header_with_must_revalidate + get :conditional_hello_with_expires_in_with_must_revalidate + assert_equal "max-age=60, private, must-revalidate", @response.headers["Cache-Control"] end - # :ported: compatibility - def test_render_with_forward_slash - get :render_hello_world_with_forward_slash - assert_template "test/hello_world" + def test_expires_in_header_with_public_and_must_revalidate + get :conditional_hello_with_expires_in_with_public_and_must_revalidate + assert_equal "max-age=60, public, must-revalidate", @response.headers["Cache-Control"] end - # :ported: - def test_render_in_top_directory - get :render_template_in_top_directory - assert_template "shared" - assert_equal "Elastica", @response.body + def test_expires_in_header_with_additional_headers + get :conditional_hello_with_expires_in_with_public_with_more_keys + assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"] end - # :ported: - def test_render_in_top_directory_with_slash - get :render_template_in_top_directory_with_slash - assert_template "shared" - assert_equal "Elastica", @response.body + def test_expires_in_old_syntax + get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax + assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"] end - # :ported: - def test_render_from_variable - get :render_hello_world_from_variable - assert_equal "hello david", @response.body + def test_expires_now + get :conditional_hello_with_expires_now + assert_equal "no-cache", @response.headers["Cache-Control"] end - # :ported: - def test_render_action - get :render_action_hello_world - assert_template "test/hello_world" + def test_expires_now_with_cache_control_headers + get :conditional_hello_with_cache_control_headers + assert_match(/no-cache/, @response.headers["Cache-Control"]) + assert_match(/no-transform/, @response.headers["Cache-Control"]) end - def test_render_action_upcased - assert_raise ActionView::MissingTemplate do - get :render_action_upcased_hello_world - end + def test_date_header_when_expires_in + time = Time.mktime(2011,10,30) + Time.stubs(:now).returns(time) + get :conditional_hello_with_expires_in + assert_equal Time.now.httpdate, @response.headers["Date"] end +end - # :ported: - def test_render_action_hello_world_as_string - get :render_action_hello_world_as_string - assert_equal "Hello world!", @response.body - assert_template "test/hello_world" - end +class LastModifiedRenderTest < ActionController::TestCase + tests TestController - # :ported: - def test_render_action_with_symbol - get :render_action_hello_world_with_symbol - assert_template "test/hello_world" + def setup + super + @last_modified = Time.now.utc.beginning_of_day.httpdate end - # :ported: - def test_render_text - get :render_text_hello_world - assert_equal "hello world", @response.body + def test_responds_with_last_modified + get :conditional_hello + assert_equal @last_modified, @response.headers['Last-Modified'] end - # :ported: - def test_do_with_render_text_and_layout - get :render_text_hello_world_with_layout - assert_equal "<html>hello world, I am here!</html>", @response.body + def test_request_not_modified + @request.if_modified_since = @last_modified + get :conditional_hello + assert_equal 304, @response.status.to_i + assert @response.body.blank? + assert_equal @last_modified, @response.headers['Last-Modified'] end - # :ported: - def test_do_with_render_action_and_layout_false - get :hello_world_with_layout_false - assert_equal 'Hello world!', @response.body + def test_request_not_modified_but_etag_differs + @request.if_modified_since = @last_modified + @request.if_none_match = "234" + get :conditional_hello + assert_response :success end - # :ported: - def test_render_file_with_instance_variables - get :render_file_with_instance_variables - assert_equal "The secret is in the sauce\n", @response.body + def test_request_modified + @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' + get :conditional_hello + assert_equal 200, @response.status.to_i + assert @response.body.present? + assert_equal @last_modified, @response.headers['Last-Modified'] end - def test_render_file - get :hello_world_file - assert_equal "Hello world!", @response.body - end - # :ported: - def test_render_file_as_string_with_instance_variables - get :render_file_as_string_with_instance_variables - assert_equal "The secret is in the sauce\n", @response.body + def test_responds_with_last_modified_with_record + get :conditional_hello_with_record + assert_equal @last_modified, @response.headers['Last-Modified'] end - # :ported: - def test_render_file_not_using_full_path - get :render_file_not_using_full_path - assert_equal "The secret is in the sauce\n", @response.body + def test_request_not_modified_with_record + @request.if_modified_since = @last_modified + get :conditional_hello_with_record + assert_equal 304, @response.status.to_i + assert @response.body.blank? + assert_equal @last_modified, @response.headers['Last-Modified'] end - # :ported: - def test_render_file_not_using_full_path_with_dot_in_path - get :render_file_not_using_full_path_with_dot_in_path - assert_equal "The secret is in the sauce\n", @response.body + def test_request_not_modified_but_etag_differs_with_record + @request.if_modified_since = @last_modified + @request.if_none_match = "234" + get :conditional_hello_with_record + assert_response :success end - # :ported: - def test_render_file_using_pathname - get :render_file_using_pathname - assert_equal "The secret is in the sauce\n", @response.body + def test_request_modified_with_record + @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' + get :conditional_hello_with_record + assert_equal 200, @response.status.to_i + assert @response.body.present? + assert_equal @last_modified, @response.headers['Last-Modified'] end - # :ported: - def test_render_file_with_locals - get :render_file_with_locals - assert_equal "The secret is in the sauce\n", @response.body + def test_request_with_bang_gets_last_modified + get :conditional_hello_with_bangs + assert_equal @last_modified, @response.headers['Last-Modified'] + assert_response :success end - # :ported: - def test_render_file_as_string_with_locals - get :render_file_as_string_with_locals - assert_equal "The secret is in the sauce\n", @response.body + def test_request_with_bang_obeys_last_modified + @request.if_modified_since = @last_modified + get :conditional_hello_with_bangs + assert_response :not_modified end - # :assessed: - def test_render_file_from_template - get :render_file_from_template - assert_equal "The secret is in the sauce\n", @response.body + def test_last_modified_works_with_less_than_too + @request.if_modified_since = 5.years.ago.httpdate + get :conditional_hello_with_bangs + assert_response :success end +end - # :ported: - def test_render_custom_code - get :render_custom_code - assert_response 404 - assert_response :missing - assert_equal 'hello world', @response.body - end +class EtagRenderTest < ActionController::TestCase + tests TestControllerWithExtraEtags - # :ported: - def test_render_text_with_nil - get :render_text_with_nil - assert_response 200 - assert_equal ' ', @response.body + def setup + super end - # :ported: - def test_render_text_with_false - get :render_text_with_false - assert_equal 'false', @response.body - end + def test_multiple_etags + @request.if_none_match = etag(["123", 'ab', :cde, [:f]]) + get :fresh + assert_response :not_modified - # :ported: - def test_render_nothing_with_appendix - get :render_nothing_with_appendix - assert_response 200 - assert_equal 'appended', @response.body + @request.if_none_match = %("nomatch") + get :fresh + assert_response :success end - def test_render_text_with_resource - get :render_text_with_resource - assert_equal 'name: "David"', @response.body - end + def test_array + @request.if_none_match = etag([%w(1 2 3), 'ab', :cde, [:f]]) + get :array + assert_response :not_modified - # :ported: - def test_attempt_to_access_object_method - assert_raise(AbstractController::ActionNotFound, "No action responded to [clone]") { get :clone } + @request.if_none_match = %("nomatch") + get :array + assert_response :success end - # :ported: - def test_private_methods - assert_raise(AbstractController::ActionNotFound, "No action responded to [determine_layout]") { get :determine_layout } + def etag(record) + Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(record)).inspect end +end - # :ported: - def test_access_to_request_in_view - get :accessing_request_in_template - assert_equal "Hello: www.nextangle.com", @response.body - end +class MetalRenderTest < ActionController::TestCase + tests MetalTestController def test_access_to_logger_in_view get :accessing_logger_in_template - assert_equal "ActiveSupport::Logger", @response.body - end - - # :ported: - def test_access_to_action_name_in_view - get :accessing_action_name_in_template - assert_equal "accessing_action_name_in_template", @response.body - end - - # :ported: - def test_access_to_controller_name_in_view - get :accessing_controller_name_in_template - assert_equal "test", @response.body # name is explicitly set in the controller. - end - - # :ported: - def test_render_xml - get :render_xml_hello - assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body - assert_equal "application/xml", @response.content_type - end - - # :ported: - def test_render_xml_as_string_template - get :render_xml_hello_as_string_template - assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body - assert_equal "application/xml", @response.content_type - end - - # :ported: - def test_render_xml_with_default - get :greeting - assert_equal "<p>This is grand!</p>\n", @response.body - end - - # :move: test in AV - def test_render_xml_with_partial - get :builder_partial_test - assert_equal "<test>\n <hello/>\n</test>\n", @response.body - end - - # :ported: - def test_layout_rendering - get :layout_test - assert_equal "<html>Hello world!</html>", @response.body - end - - def test_render_xml_with_layouts - get :builder_layout_test - assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body - end - - def test_partials_list - get :partials_list - assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body - end - - def test_render_to_string - get :hello_in_a_string - assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body - end - - def test_render_to_string_resets_assigns - get :render_to_string_test - assert_equal "The value of foo is: ::this is a test::\n", @response.body - end - - def test_render_to_string_inline - get :render_to_string_with_inline_and_render - assert_template "test/hello_world" - end - - # :ported: - def test_nested_rendering - @controller = Fun::GamesController.new - get :hello_world - assert_equal "Living in a nested world", @response.body - end - - def test_accessing_params_in_template - get :accessing_params_in_template, :name => "David" - assert_equal "Hello: David", @response.body - end - - def test_accessing_local_assigns_in_inline_template - get :accessing_local_assigns_in_inline_template, :local_name => "Local David" - assert_equal "Goodbye, Local David", @response.body - assert_equal "text/html", @response.content_type - end - - def test_should_implicitly_render_html_template_from_xhr_request - xhr :get, :render_implicit_html_template_from_xhr_request - assert_equal "XHR!\nHello HTML!", @response.body - end - - def test_should_implicitly_render_js_template_without_layout - get :render_implicit_js_template_without_layout, :format => :js - assert_no_match %r{<html>}, @response.body - end - - def test_should_render_formatted_template - get :formatted_html_erb - assert_equal 'formatted html erb', @response.body - end - - def test_should_render_formatted_html_erb_template - get :formatted_xml_erb - assert_equal '<test>passed formatted html erb</test>', @response.body - end - - def test_should_render_formatted_html_erb_template_with_faulty_accepts_header - @request.accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, appliction/x-shockwave-flash, */*" - get :formatted_xml_erb - assert_equal '<test>passed formatted html erb</test>', @response.body - end - - def test_layout_test_with_different_layout - get :layout_test_with_different_layout - assert_equal "<html>Hello world!</html>", @response.body - end - - def test_layout_test_with_different_layout_and_string_action - get :layout_test_with_different_layout_and_string_action - assert_equal "<html>Hello world!</html>", @response.body - end - - def test_layout_test_with_different_layout_and_symbol_action - get :layout_test_with_different_layout_and_symbol_action - assert_equal "<html>Hello world!</html>", @response.body - end - - def test_rendering_without_layout - get :rendering_without_layout - assert_equal "Hello world!", @response.body - end - - def test_layout_overriding_layout - get :layout_overriding_layout - assert_no_match %r{<title>}, @response.body - end - - def test_rendering_nothing_on_layout - get :rendering_nothing_on_layout - assert_equal " ", @response.body - end - - def test_render_to_string_doesnt_break_assigns - get :render_to_string_with_assigns - assert_equal "i'm before the render", assigns(:before) - assert_equal "i'm after the render", assigns(:after) - end - - def test_bad_render_to_string_still_throws_exception - assert_raise(ActionView::MissingTemplate) { get :render_to_string_with_exception } - end - - def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns - assert_nothing_raised { get :render_to_string_with_caught_exception } - assert_equal "i'm before the render", assigns(:before) - assert_equal "i'm after the render", assigns(:after) - end - - def test_accessing_params_in_template_with_layout - get :accessing_params_in_template_with_layout, :name => "David" - assert_equal "<html>Hello: David</html>", @response.body - end - - def test_render_with_explicit_template - get :render_with_explicit_template - assert_response :success - end - - def test_render_with_explicit_unescaped_template - assert_raise(ActionView::MissingTemplate) { get :render_with_explicit_unescaped_template } - get :render_with_explicit_escaped_template - assert_equal "Hello w*rld!", @response.body - end - - def test_render_with_explicit_string_template - get :render_with_explicit_string_template - assert_equal "<html>Hello world!</html>", @response.body - end - - def test_render_with_filters - get :render_with_filters - assert_equal "<test>passed formatted xml erb</test>", @response.body - end - - # :ported: - def test_double_render - assert_raise(AbstractController::DoubleRenderError) { get :double_render } - end - - def test_double_redirect - assert_raise(AbstractController::DoubleRenderError) { get :double_redirect } - end - - def test_render_and_redirect - assert_raise(AbstractController::DoubleRenderError) { get :render_and_redirect } - end - - # specify the one exception to double render rule - render_to_string followed by render - def test_render_to_string_and_render - get :render_to_string_and_render - assert_equal("Hi web users! here is some cached stuff", @response.body) - end - - def test_rendering_with_conflicting_local_vars - get :rendering_with_conflicting_local_vars - assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body) - end - - def test_action_talk_to_layout - get :action_talk_to_layout - assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body - end - - # :addressed: - def test_render_text_with_assigns - get :render_text_with_assigns - assert_equal "world", assigns["hello"] - end - - # :ported: - def test_template_with_locals - get :render_with_explicit_template_with_locals - assert_equal "The secret is area51\n", @response.body - end - - def test_yield_content_for - get :yield_content_for - assert_equal "<title>Putting stuff in the title!</title>\nGreat stuff!\n", @response.body + assert_equal "NilClass", @response.body end +end - def test_overwritting_rendering_relative_file_with_extension - get :hello_world_from_rxml_using_template - assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body +class HeadRenderTest < ActionController::TestCase + tests TestController - get :hello_world_from_rxml_using_action - assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body + def setup + @request.host = "www.nextangle.com" end def test_head_created @@ -1314,386 +529,4 @@ class RenderTest < ActionController::TestCase assert_equal "something", @response.headers["X-Custom-Header"] assert_response :forbidden end - - def test_using_layout_around_block - get :render_using_layout_around_block - assert_equal "Before (David)\nInside from block\nAfter", @response.body - end - - def test_using_layout_around_block_in_main_layout_and_within_content_for_layout - get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout - assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body - end - - def test_partial_only - get :partial_only - assert_equal "only partial", @response.body - assert_equal "text/html", @response.content_type - end - - def test_should_render_html_formatted_partial - get :partial - assert_equal "partial html", @response.body - assert_equal "text/html", @response.content_type - end - - def test_render_html_formatted_partial_even_with_other_mime_time_in_accept - @request.accept = "text/javascript, text/html" - - get :partial_html_erb - - assert_equal "partial.html.erb", @response.body.strip - assert_equal "text/html", @response.content_type - end - - def test_should_render_html_partial_with_formats - get :partial_formats_html - assert_equal "partial html", @response.body - assert_equal "text/html", @response.content_type - end - - def test_render_to_string_partial - get :render_to_string_with_partial - assert_equal "only partial", assigns(:partial_only) - assert_equal "Hello: david", assigns(:partial_with_locals) - assert_equal "text/html", @response.content_type - end - - def test_render_to_string_with_template_and_html_partial - get :render_to_string_with_template_and_html_partial - assert_equal "**only partial**\n", assigns(:text) - assert_equal "<strong>only partial</strong>\n", assigns(:html) - assert_equal "<strong>only html partial</strong>\n", @response.body - assert_equal "text/html", @response.content_type - end - - def test_render_to_string_and_render_with_different_formats - get :render_to_string_and_render_with_different_formats - assert_equal "<strong>only partial</strong>\n", assigns(:html) - assert_equal "**only partial**\n", @response.body - assert_equal "text/plain", @response.content_type - end - - def test_render_template_within_a_template_with_other_format - get :render_template_within_a_template_with_other_format - expected = "only html partial<p>This is grand!</p>" - assert_equal expected, @response.body.strip - assert_equal "text/html", @response.content_type - end - - def test_partial_with_counter - get :partial_with_counter - assert_equal "5", @response.body - end - - def test_partial_with_locals - get :partial_with_locals - assert_equal "Hello: david", @response.body - end - - def test_partial_with_form_builder - get :partial_with_form_builder - assert_match(/<label/, @response.body) - assert_template('test/_form') - end - - def test_partial_with_form_builder_subclass - get :partial_with_form_builder_subclass - assert_match(/<label/, @response.body) - assert_template('test/_labelling_form') - end - - def test_nested_partial_with_form_builder - @controller = Fun::GamesController.new - get :nested_partial_with_form_builder - assert_match(/<label/, @response.body) - assert_template('fun/games/_form') - end - - def test_namespaced_object_partial - @controller = Quiz::QuestionsController.new - get :new - assert_equal "Namespaced Partial", @response.body - end - - def test_partial_collection - get :partial_collection - assert_equal "Hello: davidHello: mary", @response.body - end - - def test_partial_collection_with_as - get :partial_collection_with_as - assert_equal "david david davidmary mary mary", @response.body - end - - def test_partial_collection_with_counter - get :partial_collection_with_counter - assert_equal "david0mary1", @response.body - end - - def test_partial_collection_with_as_and_counter - get :partial_collection_with_as_and_counter - assert_equal "david0mary1", @response.body - end - - def test_partial_collection_with_locals - get :partial_collection_with_locals - assert_equal "Bonjour: davidBonjour: mary", @response.body - end - - def test_locals_option_to_assert_template_is_not_supported - get :partial_collection_with_locals - - warning_buffer = StringIO.new - $stderr = warning_buffer - - assert_template partial: 'customer_greeting', locals: { greeting: 'Bonjour' } - assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string - ensure - $stderr = STDERR - end - - def test_partial_collection_with_spacer - get :partial_collection_with_spacer - assert_equal "Hello: davidonly partialHello: mary", @response.body - assert_template :partial => '_customer' - end - - def test_partial_collection_with_spacer_which_uses_render - get :partial_collection_with_spacer_which_uses_render - assert_equal "Hello: davidpartial html\npartial with partial\nHello: mary", @response.body - assert_template :partial => '_customer' - end - - def test_partial_collection_shorthand_with_locals - get :partial_collection_shorthand_with_locals - assert_equal "Bonjour: davidBonjour: mary", @response.body - assert_template :partial => 'customers/_customer', :count => 2 - assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0 - end - - def test_partial_collection_shorthand_with_different_types_of_records - get :partial_collection_shorthand_with_different_types_of_records - assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body - assert_template :partial => 'good_customers/_good_customer', :count => 3 - assert_template :partial => 'bad_customers/_bad_customer', :count => 3 - end - - def test_empty_partial_collection - get :empty_partial_collection - assert_equal " ", @response.body - assert_template :partial => false - end - - def test_partial_with_hash_object - get :partial_with_hash_object - assert_equal "Sam\nmaS\n", @response.body - end - - def test_partial_with_nested_object - get :partial_with_nested_object - assert_equal "first", @response.body - end - - def test_partial_with_nested_object_shorthand - get :partial_with_nested_object_shorthand - assert_equal "first", @response.body - end - - def test_hash_partial_collection - get :partial_hash_collection - assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body - end - - def test_partial_hash_collection_with_locals - get :partial_hash_collection_with_locals - assert_equal "Hola: PratikHola: Amy", @response.body - end - - def test_render_missing_partial_template - assert_raise(ActionView::MissingTemplate) do - get :missing_partial - end - end - - def test_render_call_to_partial_with_layout - get :render_call_to_partial_with_layout - assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body - end - - def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout - get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout - assert_equal "Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter", @response.body - end -end - -class ExpiresInRenderTest < ActionController::TestCase - tests TestController - - def setup - @request.host = "www.nextangle.com" - end - - def test_expires_in_header - get :conditional_hello_with_expires_in - assert_equal "max-age=60, private", @response.headers["Cache-Control"] - end - - def test_expires_in_header_with_public - get :conditional_hello_with_expires_in_with_public - assert_equal "max-age=60, public", @response.headers["Cache-Control"] - end - - def test_expires_in_header_with_must_revalidate - get :conditional_hello_with_expires_in_with_must_revalidate - assert_equal "max-age=60, private, must-revalidate", @response.headers["Cache-Control"] - end - - def test_expires_in_header_with_public_and_must_revalidate - get :conditional_hello_with_expires_in_with_public_and_must_revalidate - assert_equal "max-age=60, public, must-revalidate", @response.headers["Cache-Control"] - end - - def test_expires_in_header_with_additional_headers - get :conditional_hello_with_expires_in_with_public_with_more_keys - assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"] - end - - def test_expires_in_old_syntax - get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax - assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"] - end - - def test_expires_now - get :conditional_hello_with_expires_now - assert_equal "no-cache", @response.headers["Cache-Control"] - end - - def test_expires_now_with_cache_control_headers - get :conditional_hello_with_cache_control_headers - assert_match(/no-cache/, @response.headers["Cache-Control"]) - assert_match(/no-transform/, @response.headers["Cache-Control"]) - end - - def test_date_header_when_expires_in - time = Time.mktime(2011,10,30) - Time.stubs(:now).returns(time) - get :conditional_hello_with_expires_in - assert_equal Time.now.httpdate, @response.headers["Date"] - end -end - -class LastModifiedRenderTest < ActionController::TestCase - tests TestController - - def setup - super - @request.host = "www.nextangle.com" - @last_modified = Time.now.utc.beginning_of_day.httpdate - end - - def test_responds_with_last_modified - get :conditional_hello - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - def test_request_not_modified - @request.if_modified_since = @last_modified - get :conditional_hello - assert_equal 304, @response.status.to_i - assert @response.body.blank? - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - def test_request_not_modified_but_etag_differs - @request.if_modified_since = @last_modified - @request.if_none_match = "234" - get :conditional_hello - assert_response :success - end - - def test_request_modified - @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' - get :conditional_hello - assert_equal 200, @response.status.to_i - assert @response.body.present? - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - - def test_responds_with_last_modified_with_record - get :conditional_hello_with_record - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - def test_request_not_modified_with_record - @request.if_modified_since = @last_modified - get :conditional_hello_with_record - assert_equal 304, @response.status.to_i - assert @response.body.blank? - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - def test_request_not_modified_but_etag_differs_with_record - @request.if_modified_since = @last_modified - @request.if_none_match = "234" - get :conditional_hello_with_record - assert_response :success - end - - def test_request_modified_with_record - @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' - get :conditional_hello_with_record - assert_equal 200, @response.status.to_i - assert @response.body.present? - assert_equal @last_modified, @response.headers['Last-Modified'] - end - - - def test_request_with_bang_gets_last_modified - get :conditional_hello_with_bangs - assert_equal @last_modified, @response.headers['Last-Modified'] - assert_response :success - end - - def test_request_with_bang_obeys_last_modified - @request.if_modified_since = @last_modified - get :conditional_hello_with_bangs - assert_response :not_modified - end - - def test_last_modified_works_with_less_than_too - @request.if_modified_since = 5.years.ago.httpdate - get :conditional_hello_with_bangs - assert_response :success - end -end - -class EtagRenderTest < ActionController::TestCase - tests TestControllerWithExtraEtags - - def setup - super - @request.host = "www.nextangle.com" - end - - def test_multiple_etags - @request.if_none_match = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key([ "123", 'ab', :cde, [:f] ]))}") - get :fresh - assert_response :not_modified - - @request.if_none_match = %("nomatch") - get :fresh - assert_response :success - end -end - - -class MetalRenderTest < ActionController::TestCase - tests MetalTestController - - def test_access_to_logger_in_view - get :accessing_logger_in_template - assert_equal "NilClass", @response.body - end -end +end
\ No newline at end of file diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb index c272e785c2..727db79241 100644 --- a/actionpack/test/controller/request_forgery_protection_test.rb +++ b/actionpack/test/controller/request_forgery_protection_test.rb @@ -78,6 +78,11 @@ class RequestForgeryProtectionControllerUsingNullSession < ActionController::Bas cookies.encrypted[:foo] = 'bar' render :nothing => true end + + def try_to_reset_session + reset_session + render :nothing => true + end end class FreeCookieController < RequestForgeryProtectionControllerUsingResetSession @@ -320,6 +325,11 @@ class RequestForgeryProtectionControllerUsingNullSessionTest < ActionController: post :encrypted assert_response :ok end + + test 'should allow reset_session' do + post :try_to_reset_session + assert_response :ok + end end class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 93e94f0f48..46df1a7bd5 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -715,17 +715,13 @@ class LegacyRouteSetTests < ActiveSupport::TestCase def setup_request_method_routes_for(method) rs.draw do - match '/match' => 'books#get', :via => :get - match '/match' => 'books#post', :via => :post - match '/match' => 'books#put', :via => :put - match '/match' => 'books#patch', :via => :patch - match '/match' => 'books#delete', :via => :delete + match '/match' => "books##{method}", :via => method.to_sym end end %w(GET PATCH POST PUT DELETE).each do |request_method| define_method("test_request_method_recognized_with_#{request_method}") do - setup_request_method_routes_for(request_method) + setup_request_method_routes_for(request_method.downcase) params = rs.recognize_path("/match", :method => request_method) assert_equal request_method.downcase, params[:action] end @@ -908,12 +904,13 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal set.routes.first, set.named_routes[:hello] end - def test_earlier_named_routes_take_precedence - set.draw do - get '/hello/world' => 'a#b', :as => 'hello' - get '/hello' => 'a#b', :as => 'hello' + def test_duplicate_named_route_raises_rather_than_pick_precedence + assert_raise ArgumentError do + set.draw do + get '/hello/world' => 'a#b', :as => 'hello' + get '/hello' => 'a#b', :as => 'hello' + end end - assert_equal set.routes.first, set.named_routes[:hello] end def setup_named_route_test @@ -1907,6 +1904,10 @@ class RackMountIntegrationTests < ActiveSupport::TestCase assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界'), :method => :get)) end + def test_downcased_unicode_path + assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界').downcase, :method => :get)) + end + private def sort_extras!(extras) if extras.length == 2 diff --git a/actionpack/test/controller/show_exceptions_test.rb b/actionpack/test/controller/show_exceptions_test.rb index 888791b874..ff23b22040 100644 --- a/actionpack/test/controller/show_exceptions_test.rb +++ b/actionpack/test/controller/show_exceptions_test.rb @@ -47,7 +47,7 @@ module ShowExceptions end end - class ShowExceptionsOverridenController < ShowExceptionsController + class ShowExceptionsOverriddenController < ShowExceptionsController private def show_detailed_exceptions? @@ -55,15 +55,15 @@ module ShowExceptions end end - class ShowExceptionsOverridenTest < ActionDispatch::IntegrationTest + class ShowExceptionsOverriddenTest < ActionDispatch::IntegrationTest test 'show error page' do - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) get '/', {'detailed' => '0'} assert_equal "500 error fixture\n", body end test 'show diagnostics message' do - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) get '/', {'detailed' => '1'} assert_match(/boom/, body) end @@ -71,23 +71,23 @@ module ShowExceptions class ShowExceptionsFormatsTest < ActionDispatch::IntegrationTest def test_render_json_exception - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) get "/", {}, 'HTTP_ACCEPT' => 'application/json' assert_response :internal_server_error assert_equal 'application/json', response.content_type.to_s - assert_equal({ :status => '500', :error => 'boom!' }.to_json, response.body) + assert_equal({ :status => '500', :error => 'Internal Server Error' }.to_json, response.body) end def test_render_xml_exception - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) get "/", {}, 'HTTP_ACCEPT' => 'application/xml' assert_response :internal_server_error assert_equal 'application/xml', response.content_type.to_s - assert_equal({ :status => '500', :error => 'boom!' }.to_xml, response.body) + assert_equal({ :status => '500', :error => 'Internal Server Error' }.to_xml, response.body) end def test_render_fallback_exception - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) get "/", {}, 'HTTP_ACCEPT' => 'text/csv' assert_response :internal_server_error assert_equal 'text/html', response.content_type.to_s @@ -96,7 +96,7 @@ module ShowExceptions class ShowFailsafeExceptionsTest < ActionDispatch::IntegrationTest def test_render_failsafe_exception - @app = ShowExceptionsOverridenController.action(:boom) + @app = ShowExceptionsOverriddenController.action(:boom) @exceptions_app = @app.instance_variable_get(:@exceptions_app) @app.instance_variable_set(:@exceptions_app, nil) $stderr = StringIO.new diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index df31338f09..f75c604277 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -57,6 +57,10 @@ class TestCaseTest < ActionController::TestCase render :text => request.protocol end + def test_headers + render text: request.headers.env.to_json + end + def test_html_output render :text => <<HTML <html> @@ -197,11 +201,6 @@ XML assert_raise(NoMethodError) { head :test_params, "document body", :id => 10 } end - def test_options - options :test_params - assert_equal 200, @response.status - end - def test_process_without_flash process :set_flash assert_equal '><', flash['test'] @@ -281,13 +280,6 @@ XML assert_equal "/test_case_test/test/test_uri/7", @response.body end - def test_process_with_old_api - assert_deprecated do - process :test_uri, :id => 7 - assert_equal "/test_case_test/test/test_uri/7", @response.body - end - end - def test_process_with_request_uri_with_params_with_explicit_uri @request.env['PATH_INFO'] = "/explicit/uri" process :test_uri, "GET", :id => 7 @@ -626,6 +618,24 @@ XML assert_equal 2004, page[:year] end + test "set additional HTTP headers" do + @request.headers['Referer'] = "http://nohost.com/home" + @request.headers['Content-Type'] = "application/rss+xml" + get :test_headers + parsed_env = JSON.parse(@response.body) + assert_equal "http://nohost.com/home", parsed_env["HTTP_REFERER"] + assert_equal "application/rss+xml", parsed_env["CONTENT_TYPE"] + end + + test "set additional env variables" do + @request.headers['HTTP_REFERER'] = "http://example.com/about" + @request.headers['CONTENT_TYPE'] = "application/json" + get :test_headers + parsed_env = JSON.parse(@response.body) + assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"] + assert_equal "application/json", parsed_env["CONTENT_TYPE"] + end + def test_id_converted_to_string get :test_params, :id => 20, :foo => Object.new assert_kind_of String, @request.path_parameters['id'] diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index ba24e7fac5..088ad73f2f 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -89,6 +89,13 @@ module AbstractController ) end + def test_subdomain_may_be_removed_with_blank_string + W.default_url_options[:host] = 'api.basecamphq.com' + assert_equal('http://basecamphq.com/c/a/i', + W.new.url_for(:subdomain => '', :controller => 'c', :action => 'a', :id => 'i') + ) + end + def test_multiple_subdomains_may_be_removed W.default_url_options[:host] = 'mobile.www.api.basecamphq.com' assert_equal('http://basecamphq.com/c/a/i', diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb deleted file mode 100644 index c6e7a523b9..0000000000 --- a/actionpack/test/controller/view_paths_test.rb +++ /dev/null @@ -1,174 +0,0 @@ -require 'abstract_unit' - -class ViewLoadPathsTest < ActionController::TestCase - class TestController < ActionController::Base - def self.controller_path() "test" end - - before_action :add_view_path, only: :hello_world_at_request_time - - def hello_world() end - def hello_world_at_request_time() render(:action => 'hello_world') end - - private - def add_view_path - prepend_view_path "#{FIXTURE_LOAD_PATH}/override" - end - end - - module Test - class SubController < ActionController::Base - layout 'test/sub' - def hello_world; render(:template => 'test/hello_world'); end - end - end - - def setup - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @controller = TestController.new - @paths = TestController.view_paths - end - - def teardown - TestController.view_paths = @paths - end - - def expand(array) - array.map {|x| File.expand_path(x.to_s)} - end - - def assert_paths(*paths) - controller = paths.first.is_a?(Class) ? paths.shift : @controller - assert_equal expand(paths), controller.view_paths.map { |p| p.to_s } - end - - def test_template_load_path_was_set_correctly - assert_paths FIXTURE_LOAD_PATH - end - - def test_controller_appends_view_path_correctly - @controller.append_view_path 'foo' - assert_paths(FIXTURE_LOAD_PATH, "foo") - - @controller.append_view_path(%w(bar baz)) - assert_paths(FIXTURE_LOAD_PATH, "foo", "bar", "baz") - - @controller.append_view_path(FIXTURE_LOAD_PATH) - assert_paths(FIXTURE_LOAD_PATH, "foo", "bar", "baz", FIXTURE_LOAD_PATH) - end - - def test_controller_prepends_view_path_correctly - @controller.prepend_view_path 'baz' - assert_paths("baz", FIXTURE_LOAD_PATH) - - @controller.prepend_view_path(%w(foo bar)) - assert_paths "foo", "bar", "baz", FIXTURE_LOAD_PATH - - @controller.prepend_view_path(FIXTURE_LOAD_PATH) - assert_paths FIXTURE_LOAD_PATH, "foo", "bar", "baz", FIXTURE_LOAD_PATH - end - - def test_template_appends_view_path_correctly - @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller) - class_view_paths = TestController.view_paths - - @controller.append_view_path 'foo' - assert_paths FIXTURE_LOAD_PATH, "foo" - - @controller.append_view_path(%w(bar baz)) - assert_paths FIXTURE_LOAD_PATH, "foo", "bar", "baz" - assert_paths TestController, *class_view_paths - end - - def test_template_prepends_view_path_correctly - @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller) - class_view_paths = TestController.view_paths - - @controller.prepend_view_path 'baz' - assert_paths "baz", FIXTURE_LOAD_PATH - - @controller.prepend_view_path(%w(foo bar)) - assert_paths "foo", "bar", "baz", FIXTURE_LOAD_PATH - assert_paths TestController, *class_view_paths - end - - def test_view_paths - get :hello_world - assert_response :success - assert_equal "Hello world!", @response.body - end - - def test_view_paths_override - TestController.prepend_view_path "#{FIXTURE_LOAD_PATH}/override" - get :hello_world - assert_response :success - assert_equal "Hello overridden world!", @response.body - end - - def test_view_paths_override_for_layouts_in_controllers_with_a_module - @controller = Test::SubController.new - Test::SubController.view_paths = [ "#{FIXTURE_LOAD_PATH}/override", FIXTURE_LOAD_PATH, "#{FIXTURE_LOAD_PATH}/override2" ] - get :hello_world - assert_response :success - assert_equal "layout: Hello overridden world!", @response.body - end - - def test_view_paths_override_at_request_time - get :hello_world_at_request_time - assert_response :success - assert_equal "Hello overridden world!", @response.body - end - - def test_decorate_view_paths_with_custom_resolver - decorator_class = Class.new(ActionView::PathResolver) do - def initialize(path_set) - @path_set = path_set - end - - def find_all(*args) - @path_set.find_all(*args).collect do |template| - ::ActionView::Template.new( - "Decorated body", - template.identifier, - template.handler, - { - :virtual_path => template.virtual_path, - :format => template.formats - } - ) - end - end - end - - decorator = decorator_class.new(TestController.view_paths) - TestController.view_paths = ActionView::PathSet.new.push(decorator) - - get :hello_world - assert_response :success - assert_equal "Decorated body", @response.body - end - - def test_inheritance - original_load_paths = ActionController::Base.view_paths - - self.class.class_eval %{ - class A < ActionController::Base; end - class B < A; end - class C < ActionController::Base; end - } - - A.view_paths = ['a/path'] - - assert_paths A, "a/path" - assert_paths A, *B.view_paths - assert_paths C, *original_load_paths - - C.view_paths = [] - assert_nothing_raised { C.append_view_path 'c/path' } - assert_paths C, "c/path" - end - - def test_lookup_context_accessor - assert_equal ["test"], TestController.new.lookup_context.prefixes - end -end |