Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / actionpack / test / controller / rescue_test.rb
bloba63fd06005a09cd2d1769a42bfaf55ba0b956828
1 require File.dirname(__FILE__) + '/../abstract_unit'
3 uses_mocha 'rescue' do
5 class RescueController < ActionController::Base
6   class NotAuthorized < StandardError
7   end
8   class NotAuthorizedToRescueAsString < StandardError
9   end
11   class RecordInvalid < StandardError
12   end
13   class RecordInvalidToRescueAsString < StandardError
14   end
16   class NotAllowed < StandardError
17   end
18   class NotAllowedToRescueAsString < StandardError
19   end
21   class InvalidRequest < StandardError
22   end
23   class InvalidRequestToRescueAsString < StandardError
24   end
26   class BadGateway < StandardError
27   end
28   class BadGatewayToRescueAsString < StandardError
29   end
31   class ResourceUnavailable < StandardError
32   end
33   class ResourceUnavailableToRescueAsString < StandardError
34   end
36   # We use a fully-qualified name in some strings, and a relative constant
37   # name in some other to test correct handling of both cases.
39   rescue_from NotAuthorized, :with => :deny_access
40   rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access
42   rescue_from RecordInvalid, :with => :show_errors
43   rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors
45   rescue_from NotAllowed, :with => proc { head :forbidden }
46   rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden }
48   rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message }
49   rescue_from 'InvalidRequestToRescueAsString', :with => proc { |exception| render :text => exception.message }
51   rescue_from BadGateway do
52     head :status => 502
53   end
54   rescue_from 'BadGatewayToRescueAsString' do
55     head :status => 502
56   end
58   rescue_from ResourceUnavailable do |exception|
59     render :text => exception.message
60   end
61   rescue_from 'ResourceUnavailableToRescueAsString' do |exception|
62     render :text => exception.message
63   end
65   def raises
66     render :text => 'already rendered'
67     raise "don't panic!"
68   end
70   def method_not_allowed
71     raise ActionController::MethodNotAllowed.new(:get, :head, :put)
72   end
73   
74   def not_implemented
75     raise ActionController::NotImplemented.new(:get, :put)
76   end
78   def not_authorized
79     raise NotAuthorized
80   end
81   def not_authorized_raise_as_string
82     raise NotAuthorizedToRescueAsString
83   end
85   def not_allowed
86     raise NotAllowed
87   end
88   def not_allowed_raise_as_string
89     raise NotAllowedToRescueAsString
90   end
92   def invalid_request
93     raise InvalidRequest
94   end
95   def invalid_request_raise_as_string
96     raise InvalidRequestToRescueAsString
97   end
99   def record_invalid
100     raise RecordInvalid
101   end
102   def record_invalid_raise_as_string
103     raise RecordInvalidToRescueAsString
104   end
105   
106   def bad_gateway
107     raise BadGateway
108   end
109   def bad_gateway_raise_as_string
110     raise BadGatewayToRescueAsString
111   end
113   def resource_unavailable
114     raise ResourceUnavailable
115   end
116   def resource_unavailable_raise_as_string
117     raise ResourceUnavailableToRescueAsString
118   end
120   def missing_template
121   end
123   protected
124     def deny_access
125       head :forbidden
126     end
128     def show_errors(exception)
129       head :unprocessable_entity
130     end
133 class RescueTest < Test::Unit::TestCase
134   FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze
136   def setup
137     @controller = RescueController.new
138     @request    = ActionController::TestRequest.new
139     @response   = ActionController::TestResponse.new
141     RescueController.consider_all_requests_local = true
142     @request.remote_addr = '1.2.3.4'
143     @request.host = 'example.com'
145     begin
146       raise 'foo'
147     rescue => @exception
148     end
149   end
151   def test_rescue_action_locally_if_all_requests_local
152     @controller.expects(:local_request?).never
153     @controller.expects(:rescue_action_locally).with(@exception)
154     @controller.expects(:rescue_action_in_public).never
156     with_all_requests_local do
157       @controller.send :rescue_action, @exception
158     end
159   end
161   def test_rescue_action_locally_if_remote_addr_is_localhost
162     @controller.expects(:local_request?).returns(true)
163     @controller.expects(:rescue_action_locally).with(@exception)
164     @controller.expects(:rescue_action_in_public).never
166     with_all_requests_local false do
167       @controller.send :rescue_action, @exception
168     end
169   end
171   def test_rescue_action_in_public_otherwise
172     @controller.expects(:local_request?).returns(false)
173     @controller.expects(:rescue_action_locally).never
174     @controller.expects(:rescue_action_in_public).with(@exception)
176     with_all_requests_local false do
177       @controller.send :rescue_action, @exception
178     end
179   end
181   def test_rescue_action_in_public_with_error_file
182     with_rails_root FIXTURE_PUBLIC do
183       with_all_requests_local false do
184         get :raises
185       end
186     end
188     assert_response :internal_server_error
189     body = File.read("#{FIXTURE_PUBLIC}/public/500.html")
190     assert_equal body, @response.body
191   end
193   def test_rescue_action_in_public_without_error_file
194     with_rails_root '/tmp' do
195       with_all_requests_local false do
196         get :raises
197       end
198     end
200     assert_response :internal_server_error
201     assert_equal ' ', @response.body
202   end
204   def test_rescue_unknown_action_in_public_with_error_file
205     with_rails_root FIXTURE_PUBLIC do
206       with_all_requests_local false do
207         get :foobar_doesnt_exist
208       end
209     end
211     assert_response :not_found
212     body = File.read("#{FIXTURE_PUBLIC}/public/404.html")
213     assert_equal body, @response.body
214   end
216   def test_rescue_unknown_action_in_public_without_error_file
217     with_rails_root '/tmp' do
218       with_all_requests_local false do
219         get :foobar_doesnt_exist
220       end
221     end
223     assert_response :not_found
224     assert_equal ' ', @response.body
225   end
227   def test_rescue_missing_template_in_public
228     with_rails_root FIXTURE_PUBLIC do
229       with_all_requests_local true do
230         get :missing_template
231       end
232     end
234     assert_response :internal_server_error
235     assert @response.body.include?('missing_template'), "Response should include the template name."
236   end
238   def test_rescue_action_locally
239     get :raises
240     assert_response :internal_server_error
241     assert_template 'diagnostics.erb'
242     assert @response.body.include?('RescueController#raises'), "Response should include controller and action."
243     assert @response.body.include?("don't panic"), "Response should include exception message."
244   end
246   def test_local_request_when_remote_addr_is_localhost
247     @controller.expects(:request).returns(@request).at_least_once
248     with_remote_addr '127.0.0.1' do
249       assert @controller.send(:local_request?)
250     end
251   end
253   def test_local_request_when_remote_addr_isnt_locahost
254     @controller.expects(:request).returns(@request)
255     with_remote_addr '1.2.3.4' do
256       assert !@controller.send(:local_request?)
257     end
258   end
260   def test_rescue_responses
261     responses = ActionController::Base.rescue_responses
263     assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses.default
264     assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses[Exception.new]
266     assert_equal :not_found, responses[ActionController::RoutingError.name]
267     assert_equal :not_found, responses[ActionController::UnknownAction.name]
268     assert_equal :not_found, responses['ActiveRecord::RecordNotFound']
269     assert_equal :conflict, responses['ActiveRecord::StaleObjectError']
270     assert_equal :unprocessable_entity, responses['ActiveRecord::RecordInvalid']
271     assert_equal :unprocessable_entity, responses['ActiveRecord::RecordNotSaved']
272     assert_equal :method_not_allowed, responses['ActionController::MethodNotAllowed']
273     assert_equal :not_implemented, responses['ActionController::NotImplemented']
274   end
276   def test_rescue_templates
277     templates = ActionController::Base.rescue_templates
279     assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates.default
280     assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates[Exception.new]
282     assert_equal 'missing_template',  templates[ActionController::MissingTemplate.name]
283     assert_equal 'routing_error',     templates[ActionController::RoutingError.name]
284     assert_equal 'unknown_action',    templates[ActionController::UnknownAction.name]
285     assert_equal 'template_error',    templates[ActionView::TemplateError.name]
286   end
288   def test_clean_backtrace
289     with_rails_root nil do
290       # No action if RAILS_ROOT isn't set.
291       cleaned = @controller.send(:clean_backtrace, @exception)
292       assert_equal @exception.backtrace, cleaned
293     end
295     with_rails_root Dir.pwd do
296       # RAILS_ROOT is removed from backtrace.
297       cleaned = @controller.send(:clean_backtrace, @exception)
298       expected = @exception.backtrace.map { |line| line.sub(RAILS_ROOT, '') }
299       assert_equal expected, cleaned
301       # No action if backtrace is nil.
302       assert_nil @controller.send(:clean_backtrace, Exception.new)
303     end
304   end
305   
306   def test_not_implemented
307     with_all_requests_local false do
308       head :not_implemented
309     end
310     assert_response :not_implemented
311     assert_equal "GET, PUT", @response.headers['Allow']
312   end
314   def test_method_not_allowed
315     with_all_requests_local false do
316       get :method_not_allowed
317     end
318     assert_response :method_not_allowed
319     assert_equal "GET, HEAD, PUT", @response.headers['Allow']
320   end
322   def test_rescue_handler
323     get :not_authorized
324     assert_response :forbidden
325   end
326   def test_rescue_handler_string
327     get :not_authorized_raise_as_string
328     assert_response :forbidden
329   end
331   def test_rescue_handler_with_argument
332     @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
333     get :record_invalid
334   end
335   def test_rescue_handler_with_argument_as_string
336     @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
337     get :record_invalid_raise_as_string
338   end
340   def test_proc_rescue_handler
341     get :not_allowed
342     assert_response :forbidden
343   end
344   def test_proc_rescue_handler_as_string
345     get :not_allowed_raise_as_string
346     assert_response :forbidden
347   end
349   def test_proc_rescue_handle_with_argument
350     get :invalid_request
351     assert_equal "RescueController::InvalidRequest", @response.body
352   end
353   def test_proc_rescue_handle_with_argument_as_string
354     get :invalid_request_raise_as_string
355     assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
356   end
358   def test_block_rescue_handler
359     get :bad_gateway
360     assert_response 502
361   end
362   def test_block_rescue_handler_as_string
363     get :bad_gateway_raise_as_string
364     assert_response 502
365   end
367   def test_block_rescue_handler_with_argument
368     get :resource_unavailable
369     assert_equal "RescueController::ResourceUnavailable", @response.body
370   end
372   def test_block_rescue_handler_with_argument_as_string
373     get :resource_unavailable_raise_as_string
374     assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
375   end
378   protected
379     def with_all_requests_local(local = true)
380       old_local, ActionController::Base.consider_all_requests_local =
381         ActionController::Base.consider_all_requests_local, local
382       yield
383     ensure
384       ActionController::Base.consider_all_requests_local = old_local
385     end
387     def with_remote_addr(addr)
388       old_remote_addr, @request.remote_addr = @request.remote_addr, addr
389       yield
390     ensure
391       @request.remote_addr = old_remote_addr
392     end
394     def with_rails_root(path = nil)
395       old_rails_root = RAILS_ROOT if defined?(RAILS_ROOT)
396       if path
397         silence_warnings { Object.const_set(:RAILS_ROOT, path) }
398       else
399         Object.remove_const(:RAILS_ROOT) rescue nil
400       end
402       yield
404     ensure
405       if old_rails_root
406         silence_warnings { Object.const_set(:RAILS_ROOT, old_rails_root) }
407       else
408         Object.remove_const(:RAILS_ROOT) rescue nil
409       end
410     end
413 class ExceptionInheritanceRescueController < ActionController::Base
415   class ParentException < StandardError
416   end
418   class ChildException < ParentException
419   end
421   class GrandchildException < ChildException
422   end
424   rescue_from ChildException,      :with => lambda { head :ok }
425   rescue_from ParentException,     :with => lambda { head :created }
426   rescue_from GrandchildException, :with => lambda { head :no_content }
428   def raise_parent_exception
429     raise ParentException
430   end
432   def raise_child_exception
433     raise ChildException
434   end
436   def raise_grandchild_exception
437     raise GrandchildException
438   end
441 class ExceptionInheritanceRescueTest < Test::Unit::TestCase
443   def setup
444     @controller = ExceptionInheritanceRescueController.new
445     @request    = ActionController::TestRequest.new
446     @response   = ActionController::TestResponse.new
447   end
449   def test_bottom_first
450     get :raise_grandchild_exception
451     assert_response :no_content
452   end
454   def test_inheritance_works
455     get :raise_child_exception
456     assert_response :created
457   end
460 class ControllerInheritanceRescueController < ExceptionInheritanceRescueController
461   class FirstExceptionInChildController < StandardError
462   end
464   class SecondExceptionInChildController < StandardError
465   end
467   rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone }
469   def raise_first_exception_in_child_controller
470     raise FirstExceptionInChildController
471   end
473   def raise_second_exception_in_child_controller
474     raise SecondExceptionInChildController
475   end
478 class ControllerInheritanceRescueControllerTest < Test::Unit::TestCase
480   def setup
481     @controller = ControllerInheritanceRescueController.new
482     @request    = ActionController::TestRequest.new
483     @response   = ActionController::TestResponse.new
484   end
486   def test_first_exception_in_child_controller
487     get :raise_first_exception_in_child_controller
488     assert_response :gone
489   end
491   def test_second_exception_in_child_controller
492     get :raise_second_exception_in_child_controller
493     assert_response :gone
494   end
496   def test_exception_in_parent_controller
497     get :raise_parent_exception
498     assert_response :created
499   end
501 end # uses_mocha