X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Factionpack%2Ftest%2Fcontroller%2Frescue_test.rb;fp=vendor%2Frails%2Factionpack%2Ftest%2Fcontroller%2Frescue_test.rb;h=32c6c013f1708040472c801cfe88986188e84bf9;hb=d115f2e23823271635bad69229a42cd8ac68debe;hp=0000000000000000000000000000000000000000;hpb=37cb670bf3ddde90b214e591f100ed4446469484;p=depot.git diff --git a/vendor/rails/actionpack/test/controller/rescue_test.rb b/vendor/rails/actionpack/test/controller/rescue_test.rb new file mode 100644 index 0000000..32c6c01 --- /dev/null +++ b/vendor/rails/actionpack/test/controller/rescue_test.rb @@ -0,0 +1,513 @@ +require 'abstract_unit' + +uses_mocha 'rescue' do + +class RescueController < ActionController::Base + class NotAuthorized < StandardError + end + class NotAuthorizedToRescueAsString < StandardError + end + + class RecordInvalid < StandardError + end + class RecordInvalidToRescueAsString < StandardError + end + + class NotAllowed < StandardError + end + class NotAllowedToRescueAsString < StandardError + end + + class InvalidRequest < StandardError + end + class InvalidRequestToRescueAsString < StandardError + end + + class BadGateway < StandardError + end + class BadGatewayToRescueAsString < StandardError + end + + class ResourceUnavailable < StandardError + end + class ResourceUnavailableToRescueAsString < StandardError + end + + # We use a fully-qualified name in some strings, and a relative constant + # name in some other to test correct handling of both cases. + + rescue_from NotAuthorized, :with => :deny_access + rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access + + rescue_from RecordInvalid, :with => :show_errors + rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors + + rescue_from NotAllowed, :with => proc { head :forbidden } + rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden } + + rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message } + rescue_from 'InvalidRequestToRescueAsString', :with => proc { |exception| render :text => exception.message } + + rescue_from BadGateway do + head :status => 502 + end + rescue_from 'BadGatewayToRescueAsString' do + head :status => 502 + end + + rescue_from ResourceUnavailable do |exception| + render :text => exception.message + end + rescue_from 'ResourceUnavailableToRescueAsString' do |exception| + render :text => exception.message + end + + # This is a Dispatcher exception and should be in ApplicationController. + rescue_from ActionController::RoutingError do + render :text => 'no way' + end + + def raises + render :text => 'already rendered' + raise "don't panic!" + end + + def method_not_allowed + raise ActionController::MethodNotAllowed.new(:get, :head, :put) + end + + def not_implemented + raise ActionController::NotImplemented.new(:get, :put) + end + + def not_authorized + raise NotAuthorized + end + def not_authorized_raise_as_string + raise NotAuthorizedToRescueAsString + end + + def not_allowed + raise NotAllowed + end + def not_allowed_raise_as_string + raise NotAllowedToRescueAsString + end + + def invalid_request + raise InvalidRequest + end + def invalid_request_raise_as_string + raise InvalidRequestToRescueAsString + end + + def record_invalid + raise RecordInvalid + end + def record_invalid_raise_as_string + raise RecordInvalidToRescueAsString + end + + def bad_gateway + raise BadGateway + end + def bad_gateway_raise_as_string + raise BadGatewayToRescueAsString + end + + def resource_unavailable + raise ResourceUnavailable + end + def resource_unavailable_raise_as_string + raise ResourceUnavailableToRescueAsString + end + + def missing_template + end + + protected + def deny_access + head :forbidden + end + + def show_errors(exception) + head :unprocessable_entity + end +end + +class RescueControllerTest < ActionController::TestCase + FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze + + setup :set_all_requests_local + setup :populate_exception_object + + def set_all_requests_local + RescueController.consider_all_requests_local = true + @request.remote_addr = '1.2.3.4' + @request.host = 'example.com' + end + + def populate_exception_object + begin + raise 'foo' + rescue => @exception + end + end + + def test_rescue_action_locally_if_all_requests_local + @controller.expects(:local_request?).never + @controller.expects(:rescue_action_locally).with(@exception) + @controller.expects(:rescue_action_in_public).never + + with_all_requests_local do + @controller.send :rescue_action, @exception + end + end + + def test_rescue_action_locally_if_remote_addr_is_localhost + @controller.expects(:local_request?).returns(true) + @controller.expects(:rescue_action_locally).with(@exception) + @controller.expects(:rescue_action_in_public).never + + with_all_requests_local false do + @controller.send :rescue_action, @exception + end + end + + def test_rescue_action_in_public_otherwise + @controller.expects(:local_request?).returns(false) + @controller.expects(:rescue_action_locally).never + @controller.expects(:rescue_action_in_public).with(@exception) + + with_all_requests_local false do + @controller.send :rescue_action, @exception + end + end + + def test_rescue_action_in_public_with_error_file + with_rails_root FIXTURE_PUBLIC do + with_all_requests_local false do + get :raises + end + end + + assert_response :internal_server_error + body = File.read("#{FIXTURE_PUBLIC}/public/500.html") + assert_equal body, @response.body + end + + def test_rescue_action_in_public_without_error_file + with_rails_root '/tmp' do + with_all_requests_local false do + get :raises + end + end + + assert_response :internal_server_error + assert_equal ' ', @response.body + end + + def test_rescue_unknown_action_in_public_with_error_file + with_rails_root FIXTURE_PUBLIC do + with_all_requests_local false do + get :foobar_doesnt_exist + end + end + + assert_response :not_found + body = File.read("#{FIXTURE_PUBLIC}/public/404.html") + assert_equal body, @response.body + end + + def test_rescue_unknown_action_in_public_without_error_file + with_rails_root '/tmp' do + with_all_requests_local false do + get :foobar_doesnt_exist + end + end + + assert_response :not_found + assert_equal ' ', @response.body + end + + def test_rescue_missing_template_in_public + with_rails_root FIXTURE_PUBLIC do + with_all_requests_local true do + get :missing_template + end + end + + assert_response :internal_server_error + assert @response.body.include?('missing_template'), "Response should include the template name." + end + + def test_rescue_action_locally + get :raises + assert_response :internal_server_error + assert_template 'diagnostics.erb' + assert @response.body.include?('RescueController#raises'), "Response should include controller and action." + assert @response.body.include?("don't panic"), "Response should include exception message." + end + + def test_local_request_when_remote_addr_is_localhost + @controller.expects(:request).returns(@request).at_least_once + with_remote_addr '127.0.0.1' do + assert @controller.send(:local_request?) + end + end + + def test_local_request_when_remote_addr_isnt_locahost + @controller.expects(:request).returns(@request) + with_remote_addr '1.2.3.4' do + assert !@controller.send(:local_request?) + end + end + + def test_rescue_responses + responses = ActionController::Base.rescue_responses + + assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses.default + assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses[Exception.new] + + assert_equal :not_found, responses[ActionController::RoutingError.name] + assert_equal :not_found, responses[ActionController::UnknownAction.name] + assert_equal :not_found, responses['ActiveRecord::RecordNotFound'] + assert_equal :conflict, responses['ActiveRecord::StaleObjectError'] + assert_equal :unprocessable_entity, responses['ActiveRecord::RecordInvalid'] + assert_equal :unprocessable_entity, responses['ActiveRecord::RecordNotSaved'] + assert_equal :method_not_allowed, responses['ActionController::MethodNotAllowed'] + assert_equal :not_implemented, responses['ActionController::NotImplemented'] + end + + def test_rescue_templates + templates = ActionController::Base.rescue_templates + + assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates.default + assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates[Exception.new] + + assert_equal 'missing_template', templates[ActionView::MissingTemplate.name] + assert_equal 'routing_error', templates[ActionController::RoutingError.name] + assert_equal 'unknown_action', templates[ActionController::UnknownAction.name] + assert_equal 'template_error', templates[ActionView::TemplateError.name] + end + + def test_clean_backtrace + with_rails_root nil do + # No action if RAILS_ROOT isn't set. + cleaned = @controller.send(:clean_backtrace, @exception) + assert_equal @exception.backtrace, cleaned + end + + with_rails_root Dir.pwd do + # RAILS_ROOT is removed from backtrace. + cleaned = @controller.send(:clean_backtrace, @exception) + expected = @exception.backtrace.map { |line| line.sub(RAILS_ROOT, '') } + assert_equal expected, cleaned + + # No action if backtrace is nil. + assert_nil @controller.send(:clean_backtrace, Exception.new) + end + end + + def test_not_implemented + with_all_requests_local false do + with_rails_public_path(".") do + head :not_implemented + end + end + assert_response :not_implemented + assert_equal "GET, PUT", @response.headers['Allow'] + end + + def test_method_not_allowed + with_all_requests_local false do + with_rails_public_path(".") do + get :method_not_allowed + end + end + assert_response :method_not_allowed + assert_equal "GET, HEAD, PUT", @response.headers['Allow'] + end + + def test_rescue_handler + get :not_authorized + assert_response :forbidden + end + def test_rescue_handler_string + get :not_authorized_raise_as_string + assert_response :forbidden + end + + def test_rescue_handler_with_argument + @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) } + get :record_invalid + end + def test_rescue_handler_with_argument_as_string + @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) } + get :record_invalid_raise_as_string + end + + def test_proc_rescue_handler + get :not_allowed + assert_response :forbidden + end + def test_proc_rescue_handler_as_string + get :not_allowed_raise_as_string + assert_response :forbidden + end + + def test_proc_rescue_handle_with_argument + get :invalid_request + assert_equal "RescueController::InvalidRequest", @response.body + end + def test_proc_rescue_handle_with_argument_as_string + get :invalid_request_raise_as_string + assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body + end + + def test_block_rescue_handler + get :bad_gateway + assert_response 502 + end + def test_block_rescue_handler_as_string + get :bad_gateway_raise_as_string + assert_response 502 + end + + def test_block_rescue_handler_with_argument + get :resource_unavailable + assert_equal "RescueController::ResourceUnavailable", @response.body + end + + def test_block_rescue_handler_with_argument_as_string + get :resource_unavailable_raise_as_string + assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body + end + + def test_rescue_dispatcher_exceptions + RescueController.process_with_exception(@request, @response, ActionController::RoutingError.new("Route not found")) + assert_equal "no way", @response.body + end + + protected + def with_all_requests_local(local = true) + old_local, ActionController::Base.consider_all_requests_local = + ActionController::Base.consider_all_requests_local, local + yield + ensure + ActionController::Base.consider_all_requests_local = old_local + end + + def with_remote_addr(addr) + old_remote_addr, @request.remote_addr = @request.remote_addr, addr + yield + ensure + @request.remote_addr = old_remote_addr + end + + def with_rails_public_path(rails_root) + old_rails = Object.const_get(:Rails) rescue nil + mod = Object.const_set(:Rails, Module.new) + (class << mod; self; end).instance_eval do + define_method(:public_path) { "#{rails_root}/public" } + end + yield + ensure + Object.module_eval { remove_const(:Rails) } if defined?(Rails) + Object.const_set(:Rails, old_rails) if old_rails + end + + def with_rails_root(path = nil,&block) + old_rails_root = RAILS_ROOT if defined?(RAILS_ROOT) + if path + silence_warnings { Object.const_set(:RAILS_ROOT, path) } + else + Object.remove_const(:RAILS_ROOT) rescue nil + end + + with_rails_public_path(path, &block) + + ensure + if old_rails_root + silence_warnings { Object.const_set(:RAILS_ROOT, old_rails_root) } + else + Object.remove_const(:RAILS_ROOT) rescue nil + end + end +end + +class ExceptionInheritanceRescueController < ActionController::Base + + class ParentException < StandardError + end + + class ChildException < ParentException + end + + class GrandchildException < ChildException + end + + rescue_from ChildException, :with => lambda { head :ok } + rescue_from ParentException, :with => lambda { head :created } + rescue_from GrandchildException, :with => lambda { head :no_content } + + def raise_parent_exception + raise ParentException + end + + def raise_child_exception + raise ChildException + end + + def raise_grandchild_exception + raise GrandchildException + end +end + +class ExceptionInheritanceRescueControllerTest < ActionController::TestCase + def test_bottom_first + get :raise_grandchild_exception + assert_response :no_content + end + + def test_inheritance_works + get :raise_child_exception + assert_response :created + end +end + +class ControllerInheritanceRescueController < ExceptionInheritanceRescueController + class FirstExceptionInChildController < StandardError + end + + class SecondExceptionInChildController < StandardError + end + + rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone } + + def raise_first_exception_in_child_controller + raise FirstExceptionInChildController + end + + def raise_second_exception_in_child_controller + raise SecondExceptionInChildController + end +end + +class ControllerInheritanceRescueControllerTest < ActionController::TestCase + def test_first_exception_in_child_controller + get :raise_first_exception_in_child_controller + assert_response :gone + end + + def test_second_exception_in_child_controller + get :raise_second_exception_in_child_controller + assert_response :gone + end + + def test_exception_in_parent_controller + get :raise_parent_exception + assert_response :created + end +end +end # uses_mocha