Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / actionpack / test / controller / new_render_test.rb
blob8a3013bec6e9d1c21e7a8ac4d6ab82a6dc4c5b26
1 require File.dirname(__FILE__) + '/../abstract_unit'
2 require File.dirname(__FILE__) + '/fake_models'
4 class CustomersController < ActionController::Base
5 end
7 module Fun
8   class GamesController < ActionController::Base
9     def hello_world
10     end
11   end
12 end
14 module NewRenderTestHelper
15   def rjs_helper_method_from_module
16     page.visual_effect :highlight
17   end
18 end
20 class NewRenderTestController < ActionController::Base
21   layout :determine_layout
23   def self.controller_name; "test"; end
24   def self.controller_path; "test"; end
26   def hello_world
27   end
29   def render_hello_world
30     render :template => "test/hello_world"
31   end
33   def render_hello_world_from_variable
34     @person = "david"
35     render :text => "hello #{@person}"
36   end
38   def render_action_hello_world
39     render :action => "hello_world"
40   end
42   def render_action_hello_world_as_symbol
43     render :action => :hello_world
44   end
45   
46   def render_text_hello_world
47     render :text => "hello world"
48   end
50   def render_text_hello_world_with_layout
51     @variable_for_layout = ", I'm here!"
52     render :text => "hello world", :layout => true
53   end
55   def hello_world_with_layout_false
56     render :layout => false
57   end
59   def render_custom_code
60     render :text => "hello world", :status => "404 Moved"
61   end
63   def render_file_with_instance_variables
64     @secret = 'in the sauce'
65     path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
66     render :file => path
67   end
69   def render_file_with_locals
70     path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
71     render :file => path, :locals => {:secret => 'in the sauce'} 
72   end
74   def render_file_not_using_full_path
75     @secret = 'in the sauce'
76     render :file => 'test/render_file_with_ivar', :use_full_path => true
77   end
79   def render_file_not_using_full_path_with_relative_path
80     @secret = 'in the sauce'
81     render :file => 'test/../test/render_file_with_ivar', :use_full_path => true
82   end
83   
84   def render_file_not_using_full_path_with_dot_in_path
85     @secret = 'in the sauce'
86     render :file => 'test/dot.directory/render_file_with_ivar', :use_full_path => true
87   end
89   def render_xml_hello
90     @name = "David"
91     render :template => "test/hello"
92   end
94   def greeting
95     # let's just rely on the template
96   end
98   def layout_test
99     render :action => "hello_world"
100   end
102   def layout_test_with_different_layout
103     render :action => "hello_world", :layout => "standard"
104   end
105   
106   def rendering_without_layout
107     render :action => "hello_world", :layout => false
108   end
110   def layout_overriding_layout
111     render :action => "hello_world", :layout => "standard"
112   end
113   
114   def rendering_nothing_on_layout
115     render :nothing => true
116   end
117   
118   def builder_layout_test
119     render :action => "hello"
120   end
122   def partials_list
123     @test_unchanged = 'hello'
124     @customers = [ Customer.new("david"), Customer.new("mary") ]
125     render :action => "list"
126   end
128   def partial_only
129     render :partial => true
130   end
132   def partial_only_with_layout
133     render :partial => "partial_only", :layout => true
134   end
135   
136   def partial_with_locals
137     render :partial => "customer", :locals => { :customer => Customer.new("david") } 
138   end
139   
140   def partial_collection
141     render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
142   end
144   def partial_collection_with_locals
145     render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
146   end
148   def empty_partial_collection
149     render :partial => "customer", :collection => []
150   end
151   
152   def partial_with_hash_object
153     render :partial => "hash_object", :object => {:first_name => "Sam"}
154   end
155   
156   def partial_hash_collection
157     render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
158   end
159   
160   def partial_hash_collection_with_locals
161     render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" }
162   end
163   
164   def partial_with_implicit_local_assignment
165     @customer = Customer.new("Marcel")
166     render :partial => "customer"
167   end
168   
169   def missing_partial
170     render :partial => 'thisFileIsntHere'
171   end
172   
173   def hello_in_a_string
174     @customers = [ Customer.new("david"), Customer.new("mary") ]
175     render :text =>  "How's there? " << render_to_string(:template => "test/list")
176   end
177   
178   def render_to_string_with_assigns
179     @before = "i'm before the render"
180     render_to_string :text => "foo"
181     @after = "i'm after the render"
182     render :action => "test/hello_world"
183   end
185  def render_to_string_with_partial
186     @partial_only = render_to_string :partial => "partial_only"
187     @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }     
188     render :action => "test/hello_world"  
189   end  
190   
191   def render_to_string_with_exception
192     render_to_string :file => "exception that will not be caught - this will certainly not work", :use_full_path => true
193   end
194   
195   def render_to_string_with_caught_exception
196     @before = "i'm before the render"
197     begin
198       render_to_string :file => "exception that will be caught- hope my future instance vars still work!", :use_full_path => true
199     rescue
200     end
201     @after = "i'm after the render"
202     render :action => "test/hello_world"
203   end
205   def accessing_params_in_template
206     render :inline =>  "Hello: <%= params[:name] %>"
207   end
209   def accessing_params_in_template_with_layout
210     render :layout => nil, :inline =>  "Hello: <%= params[:name] %>"
211   end
213   def render_with_explicit_template
214     render :template => "test/hello_world"
215   end
217   def double_render
218     render :text => "hello"
219     render :text => "world"
220   end
222   def double_redirect
223     redirect_to :action => "double_render"
224     redirect_to :action => "double_render"
225   end
227   def render_and_redirect
228     render :text => "hello"
229     redirect_to :action => "double_render"
230   end
231   
232   def render_to_string_and_render
233     @stuff = render_to_string :text => "here is some cached stuff"
234     render :text => "Hi web users! #{@stuff}"
235   end
237   def rendering_with_conflicting_local_vars
238     @name = "David"
239     def @template.name() nil end
240     render :action => "potential_conflicts"
241   end
243   def hello_world_from_rxml_using_action
244     render :action => "hello_world.builder"
245   end
247   def hello_world_from_rxml_using_template
248     render :template => "test/hello_world.builder"
249   end
251   def head_with_location_header
252     head :location => "/foo"
253   end
255   def head_with_symbolic_status
256     head :status => params[:status].intern
257   end
259   def head_with_integer_status
260     head :status => params[:status].to_i
261   end
263   def head_with_string_status
264     head :status => params[:status]
265   end
267   def head_with_custom_header
268     head :x_custom_header => "something"
269   end
271   def head_with_status_code_first
272     head :forbidden, :x_custom_header => "something"
273   end
275   def render_with_location
276     render :xml => "<hello/>", :location => "http://example.com", :status => 201
277   end
278   
279   def render_with_object_location
280     customer = Customer.new("Some guy", 1)
281     render :xml => "<customer/>", :location => customer_url(customer), :status => :created
282   end
284   def render_with_to_xml
285     to_xmlable = Class.new do
286       def to_xml
287         "<i-am-xml/>"
288       end
289     end.new
290     
291     render :xml => to_xmlable
292   end
294   helper NewRenderTestHelper
295   helper do 
296     def rjs_helper_method(value)
297       page.visual_effect :highlight, value
298     end
299   end
301   def enum_rjs_test
302     render :update do |page|
303       page.select('.product').each do |value|
304         page.rjs_helper_method_from_module
305         page.rjs_helper_method(value)
306         page.sortable(value, :url => { :action => "order" })
307         page.draggable(value)
308       end
309     end
310   end
312   def delete_with_js
313     @project_id = 4
314   end
316   def render_js_with_explicit_template
317     @project_id = 4
318     render :template => 'test/delete_with_js'
319   end
321   def render_js_with_explicit_action_template
322     @project_id = 4
323     render :action => 'delete_with_js'
324   end
326   def update_page
327     render :update do |page|
328       page.replace_html 'balance', '$37,000,000.00'
329       page.visual_effect :highlight, 'balance'
330     end
331   end
332   
333   def update_page_with_instance_variables
334     @money = '$37,000,000.00'
335     @div_id = 'balance'
336     render :update do |page|
337       page.replace_html @div_id, @money
338       page.visual_effect :highlight, @div_id
339     end
340   end
342   def action_talk_to_layout
343     # Action template sets variable that's picked up by layout
344   end
346   def render_text_with_assigns
347     @hello = "world"
348     render :text => "foo"
349   end
351   def yield_content_for
352     render :action => "content_for", :layout => "yield"
353   end
355   def render_content_type_from_body
356     response.content_type = Mime::RSS
357     render :text => "hello world!"
358   end
360   def render_call_to_partial_with_layout
361     render :action => "calling_partial_with_layout"
362   end
364   def render_using_layout_around_block
365     render :action => "using_layout_around_block"
366   end
368   def rescue_action(e) raise end
369     
370   private
371     def determine_layout
372       case action_name 
373         when "hello_world", "layout_test", "rendering_without_layout",
374              "rendering_nothing_on_layout", "render_text_hello_world",
375              "render_text_hello_world_with_layout",
376              "hello_world_with_layout_false",
377              "partial_only", "partial_only_with_layout",
378              "accessing_params_in_template",
379              "accessing_params_in_template_with_layout",
380              "render_with_explicit_template",
381              "render_js_with_explicit_template",
382              "render_js_with_explicit_action_template",
383              "delete_with_js", "update_page", "update_page_with_instance_variables"
384     
385           "layouts/standard"
386         when "builder_layout_test"
387           "layouts/builder"
388         when "action_talk_to_layout", "layout_overriding_layout"
389           "layouts/talk_from_action"
390       end
391     end
394 NewRenderTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
395 Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
397 class NewRenderTest < Test::Unit::TestCase
398   def setup
399     @controller = NewRenderTestController.new
401     # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
402     # a more accurate simulation of what happens in "real life".
403     @controller.logger = Logger.new(nil)
405     @request    = ActionController::TestRequest.new
406     @response   = ActionController::TestResponse.new
408     @request.host = "www.nextangle.com"
409   end
411   def test_simple_show
412     get :hello_world
413     assert_response :success
414     assert_template "test/hello_world"
415     assert_equal "<html>Hello world!</html>", @response.body
416   end
418   def test_do_with_render
419     get :render_hello_world
420     assert_template "test/hello_world"
421   end
423   def test_do_with_render_from_variable
424     get :render_hello_world_from_variable
425     assert_equal "hello david", @response.body
426   end
428   def test_do_with_render_action
429     get :render_action_hello_world
430     assert_template "test/hello_world"
431   end
433   def test_do_with_render_action_as_symbol
434     get :render_action_hello_world_as_symbol
435     assert_template "test/hello_world"
436   end
438   def test_do_with_render_text
439     get :render_text_hello_world
440     assert_equal "hello world", @response.body
441   end
443   def test_do_with_render_text_and_layout
444     get :render_text_hello_world_with_layout
445     assert_equal "<html>hello world, I'm here!</html>", @response.body
446   end
448   def test_do_with_render_action_and_layout_false
449     get :hello_world_with_layout_false
450     assert_equal 'Hello world!', @response.body
451   end
453   def test_do_with_render_custom_code
454     get :render_custom_code
455     assert_response :missing
456   end
458   def test_render_file_with_instance_variables
459     get :render_file_with_instance_variables
460     assert_equal "The secret is in the sauce\n", @response.body
461   end
463   def test_render_file_not_using_full_path
464     get :render_file_not_using_full_path 
465     assert_equal "The secret is in the sauce\n", @response.body
466   end
468   def test_render_file_not_using_full_path_with_relative_path
469     get :render_file_not_using_full_path_with_relative_path
470     assert_equal "The secret is in the sauce\n", @response.body
471   end
473   def test_render_file_not_using_full_path_with_dot_in_path
474     get :render_file_not_using_full_path_with_dot_in_path
475     assert_equal "The secret is in the sauce\n", @response.body
476   end
478   def test_render_file_with_locals
479     get :render_file_with_locals
480     assert_equal "The secret is in the sauce\n", @response.body
481   end
483   def test_attempt_to_access_object_method
484     assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
485   end
487   def test_private_methods
488     assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
489   end
491   def test_access_to_request_in_view
492     view_internals_old_value = ActionController::Base.view_controller_internals
494     ActionController::Base.view_controller_internals = false
495     ActionController::Base.protected_variables_cache = nil
497     get :hello_world
498     assert !assigns.include?('request'), 'request should not be in assigns'
500     ActionController::Base.view_controller_internals = true
501     ActionController::Base.protected_variables_cache = nil
503     get :hello_world
504     assert !assigns.include?('request'), 'request should not be in assigns'
505     assert_kind_of ActionController::AbstractRequest, assigns['_request']
506     assert_kind_of ActionController::AbstractRequest, @response.template.request
508   ensure
509     ActionController::Base.view_controller_internals = view_internals_old_value
510     ActionController::Base.protected_variables_cache = nil
511   end
513   def test_render_xml
514     get :render_xml_hello
515     assert_equal "<html>\n  <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
516   end
518   def test_enum_rjs_test
519     get :enum_rjs_test
520     assert_equal <<-EOS.strip, @response.body
521 $$(".product").each(function(value, index) {
522 new Effect.Highlight(element,{});
523 new Effect.Highlight(value,{});
524 Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value)})}});
525 new Draggable(value, {});
528   end
530   def test_render_xml_with_default
531     get :greeting
532     assert_equal "<p>This is grand!</p>\n", @response.body
533   end
535   def test_render_rjs_with_default
536     get :delete_with_js
537     assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
538   end
540   def test_render_rjs_template_explicitly
541     get :render_js_with_explicit_template
542     assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
543   end
545   def test_rendering_rjs_action_explicitly
546     get :render_js_with_explicit_action_template
547     assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
548   end
550   def test_layout_rendering
551     get :layout_test
552     assert_equal "<html>Hello world!</html>", @response.body
553   end
555   def test_layout_test_with_different_layout
556     get :layout_test_with_different_layout
557     assert_equal "<html>Hello world!</html>", @response.body
558   end
560   def test_rendering_without_layout
561     get :rendering_without_layout
562     assert_equal "Hello world!", @response.body
563   end
565   def test_layout_overriding_layout
566     get :layout_overriding_layout
567     assert_no_match %r{<title>}, @response.body
568   end
570   def test_rendering_nothing_on_layout
571     get :rendering_nothing_on_layout
572     assert_equal " ", @response.body
573   end
575   def test_render_xml_with_layouts
576     get :builder_layout_test
577     assert_equal "<wrapper>\n<html>\n  <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
578   end
580   def test_partial_only
581     get :partial_only
582     assert_equal "only partial", @response.body
583   end
585   def test_partial_only_with_layout
586     get :partial_only_with_layout
587     assert_equal "<html>only partial</html>", @response.body
588   end
590   def test_render_to_string
591     assert_not_deprecated { get :hello_in_a_string }
592     assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
593   end
594   
595   def test_render_to_string_doesnt_break_assigns
596     get :render_to_string_with_assigns
597     assert_equal "i'm before the render", assigns(:before)
598     assert_equal "i'm after the render", assigns(:after)
599   end
601   def test_render_to_string_partial
602     get :render_to_string_with_partial
603     assert_equal "only partial", assigns(:partial_only)
604     assert_equal "Hello: david", assigns(:partial_with_locals)
605   end  
607   def test_bad_render_to_string_still_throws_exception
608     assert_raises(ActionController::MissingTemplate) { get :render_to_string_with_exception }
609   end
610   
611   def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
612     assert_nothing_raised { get :render_to_string_with_caught_exception }
613     assert_equal "i'm before the render", assigns(:before)
614     assert_equal "i'm after the render", assigns(:after)
615   end
617   def test_nested_rendering
618     get :hello_world
619     assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body
620   end
622   def test_accessing_params_in_template
623     get :accessing_params_in_template, :name => "David"
624     assert_equal "Hello: David", @response.body
625   end
627   def test_accessing_params_in_template_with_layout
628     get :accessing_params_in_template_with_layout, :name => "David"
629     assert_equal "<html>Hello: David</html>", @response.body
630   end
632   def test_render_with_explicit_template
633     get :render_with_explicit_template
634     assert_response :success
635   end
637   def test_double_render
638     assert_raises(ActionController::DoubleRenderError) { get :double_render }
639   end
641   def test_double_redirect
642     assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
643   end
645   def test_render_and_redirect
646     assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
647   end
648   
649   # specify the one exception to double render rule - render_to_string followed by render
650   def test_render_to_string_and_render
651     get :render_to_string_and_render
652     assert_equal("Hi web users! here is some cached stuff", @response.body)
653   end
655   def test_rendering_with_conflicting_local_vars
656     get :rendering_with_conflicting_local_vars
657     assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
658   end
660   def test_action_talk_to_layout
661     get :action_talk_to_layout
662     assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
663   end
665   def test_partials_list
666     get :partials_list
667     assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
668   end
669   
670   def test_partial_with_locals
671     get :partial_with_locals
672     assert_equal "Hello: david", @response.body
673   end
675   def test_partial_collection
676     get :partial_collection
677     assert_equal "Hello: davidHello: mary", @response.body
678   end
680   def test_partial_collection_with_locals
681     get :partial_collection_with_locals
682     assert_equal "Bonjour: davidBonjour: mary", @response.body
683   end
685   def test_empty_partial_collection
686     get :empty_partial_collection
687     assert_equal " ", @response.body
688   end
690   def test_partial_with_hash_object
691     get :partial_with_hash_object
692     assert_equal "Sam\nmaS\n", @response.body
693   end
694   
695   def test_hash_partial_collection
696     get :partial_hash_collection
697     assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
698   end
699   
700   def test_partial_hash_collection_with_locals
701     get :partial_hash_collection_with_locals
702     assert_equal "Hola: PratikHola: Amy", @response.body
703   end
705   def test_partial_with_implicit_local_assignment
706     get :partial_with_implicit_local_assignment
707     assert_equal "Hello: Marcel", @response.body
708   end
709   
710   def test_render_missing_partial_template
711     assert_raises(ActionView::ActionViewError) do
712       get :missing_partial
713     end
714   end
715   
716   def test_render_text_with_assigns
717     get :render_text_with_assigns
718     assert_equal "world", assigns["hello"]
719   end
720   
721   def test_update_page
722     get :update_page
723     assert_template nil
724     assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
725     assert_equal 2, @response.body.split($/).length
726   end
727   
728   def test_update_page_with_instance_variables
729     get :update_page_with_instance_variables
730     assert_template nil
731     assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
732     assert_match /balance/, @response.body
733     assert_match /\$37/, @response.body
734   end
735   
736   def test_yield_content_for
737     assert_not_deprecated { get :yield_content_for }
738     assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
739   end
742   def test_overwritting_rendering_relative_file_with_extension
743     get :hello_world_from_rxml_using_template
744     assert_equal "<html>\n  <p>Hello</p>\n</html>\n", @response.body
746     get :hello_world_from_rxml_using_action
747     assert_equal "<html>\n  <p>Hello</p>\n</html>\n", @response.body
748   end
751   def test_head_with_location_header
752     get :head_with_location_header
753     assert @response.body.blank?
754     assert_equal "/foo", @response.headers["Location"]
755     assert_response :ok
756   end
758   def test_head_with_custom_header
759     get :head_with_custom_header
760     assert @response.body.blank?
761     assert_equal "something", @response.headers["X-Custom-Header"]
762     assert_response :ok
763   end
765   def test_head_with_symbolic_status
766     get :head_with_symbolic_status, :status => "ok"
767     assert_equal "200 OK", @response.headers["Status"]
768     assert_response :ok
770     get :head_with_symbolic_status, :status => "not_found"
771     assert_equal "404 Not Found", @response.headers["Status"]
772     assert_response :not_found
774     ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code|
775       get :head_with_symbolic_status, :status => status.to_s
776       assert_equal code, @response.response_code
777       assert_response status
778     end
779   end
781   def test_head_with_integer_status
782     ActionController::StatusCodes::STATUS_CODES.each do |code, message|
783       get :head_with_integer_status, :status => code.to_s
784       assert_equal message, @response.message
785     end
786   end
788   def test_head_with_string_status
789     get :head_with_string_status, :status => "404 Eat Dirt"
790     assert_equal 404, @response.response_code
791     assert_equal "Eat Dirt", @response.message
792     assert_response :not_found
793   end
795   def test_head_with_status_code_first
796     get :head_with_status_code_first
797     assert_equal 403, @response.response_code
798     assert_equal "Forbidden", @response.message
799     assert_equal "something", @response.headers["X-Custom-Header"]
800     assert_response :forbidden
801   end
803   def test_rendering_with_location_should_set_header
804     get :render_with_location
805     assert_equal "http://example.com", @response.headers["Location"]
806   end
807   
808   def test_rendering_xml_should_call_to_xml_if_possible
809     get :render_with_to_xml
810     assert_equal "<i-am-xml/>", @response.body
811   end
812   
813   def test_rendering_with_object_location_should_set_header_with_url_for
814     ActionController::Routing::Routes.draw do |map|
815       map.resources :customers
816       map.connect ':controller/:action/:id'
817     end
819     get :render_with_object_location
820     assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
821   end
823   def test_render_call_to_partial_with_layout
824     get :render_call_to_partial_with_layout
825     assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
826   end
827   
828   def test_using_layout_around_block
829     get :using_layout_around_block
830     assert_equal "Before (David)\nInside from block\nAfter", @response.body
831   end