mime_responds_test.rb 25.9 KB
Newer Older
1
require 'abstract_unit'
2
require 'controller/fake_models'
S
Santiago Pastorino 已提交
3
require 'active_support/core_ext/hash/conversions'
4 5

class RespondToController < ActionController::Base
6 7
  layout :set_layout

8 9 10 11 12 13 14 15
  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
16

17 18 19 20 21 22 23
  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
24

25 26 27
  def json_or_yaml
    respond_to do |type|
      type.json { render :text => "JSON" }
28
      type.yaml { render :text => "YAML" }
29 30
    end
  end
31 32 33 34 35 36 37 38

  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
39 40 41 42 43 44 45 46 47
  
  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
  
48

49 50 51 52 53 54 55 56 57
  def forced_xml
    request.format = :xml

    respond_to do |type|
      type.html { render :text => "HTML"    }
      type.xml  { render :text => "XML"     }
    end
  end

58 59 60 61 62
  def just_xml
    respond_to do |type|
      type.xml  { render :text => "XML" }
    end
  end
63

64 65 66 67 68 69 70
  def using_defaults
    respond_to do |type|
      type.html
      type.js
      type.xml
    end
  end
71

72 73 74
  def using_defaults_with_type_list
    respond_to(:html, :js, :xml)
  end
75

76 77 78 79 80 81 82 83
  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

84 85 86 87 88 89 90
  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
91

92
  Mime::Type.register("text/x-mobile", :mobile)
93

94
  def custom_constant_handling
95 96 97 98 99
    respond_to do |type|
      type.html   { render :text => "HTML"   }
      type.mobile { render :text => "Mobile" }
    end
  end
100

101 102 103 104 105 106
  def custom_constant_handling_without_block
    respond_to do |type|
      type.html   { render :text => "HTML"   }
      type.mobile
    end
  end
107

108 109 110 111 112 113
  def handle_any
    respond_to do |type|
      type.html { render :text => "HTML" }
      type.any(:js, :xml) { render :text => "Either JS or XML" }
    end
  end
114

115 116 117 118 119 120
  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
121

122 123 124 125 126
  def all_types_with_layout
    respond_to do |type|
      type.html
      type.js
    end
127 128
  end

129 130
  Mime::Type.register_alias("text/html", :iphone)

131
  def iphone_with_html_response_type
132
    request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
133

134 135
    respond_to do |type|
      type.html   { @type = "Firefox" }
136
      type.iphone { @type = "iPhone"  }
137
    end
138 139
  end

140 141
  def iphone_with_html_response_type_without_layout
    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
142

143 144 145 146 147 148
    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

149
  def rescue_action(e)
J
Jamis Buck 已提交
150
    raise
151
  end
152

153 154
  protected
    def set_layout
155
      if ["all_types_with_layout", "iphone_with_html_response_type"].include?(action_name)
D
David Heinemeier Hansson 已提交
156
        "respond_to/layouts/standard"
157 158
      elsif action_name == "iphone_with_html_response_type_without_layout"
        "respond_to/layouts/missing"
159 160
      end
    end
161 162
end

163
class RespondToControllerTest < ActionController::TestCase
164 165
  tests RespondToController

166
  def setup
167
    super
168 169
    @request.host = "www.example.com"
  end
170

171
  def teardown
172
    super
173 174
  end

175
  def test_html
176
    @request.accept = "text/html"
177 178
    get :js_or_html
    assert_equal 'HTML', @response.body
179

180 181 182 183 184 185 186 187
    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_response 406
  end

  def test_all
188
    @request.accept = "*/*"
189 190 191 192 193 194 195 196 197 198 199
    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
200
    @request.accept = "application/xml"
201 202 203 204 205
    get :html_xml_or_rss
    assert_equal 'XML', @response.body
  end

  def test_js_or_html
206
    @request.accept = "text/javascript, text/html"
207
    xhr :get, :js_or_html
208 209
    assert_equal 'JS', @response.body

210 211
    @request.accept = "text/javascript, text/html"
    xhr :get, :html_or_xml
212 213
    assert_equal 'HTML', @response.body

214 215
    @request.accept = "text/javascript, text/html"
    xhr :get, :just_xml
216 217
    assert_response 406
  end
218

219
  def test_json_or_yaml
220
    xhr :get, :json_or_yaml
221
    assert_equal 'JSON', @response.body
222 223

    get :json_or_yaml, :format => 'json'
224
    assert_equal 'JSON', @response.body
225 226 227 228 229 230 231 232

    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|
233
        @request.accept = content_type
234 235 236 237
        get :json_or_yaml
        assert_equal body, @response.body
      end
    end
238
  end
239 240

  def test_js_or_anything
241
    @request.accept = "text/javascript, */*"
242
    xhr :get, :js_or_html
243 244
    assert_equal 'JS', @response.body

245
    xhr :get, :html_or_xml
246 247
    assert_equal 'HTML', @response.body

248
    xhr :get, :just_xml
249 250
    assert_equal 'XML', @response.body
  end
251

252
  def test_using_defaults
253
    @request.accept = "*/*"
254
    get :using_defaults
255
    assert_equal "text/html", @response.content_type
256 257
    assert_equal 'Hello world!', @response.body

258
    @request.accept = "text/javascript"
259
    get :using_defaults
260
    assert_equal "text/javascript", @response.content_type
261
    assert_equal '$("body").visualEffect("highlight");', @response.body
262

263
    @request.accept = "application/xml"
264
    get :using_defaults
265
    assert_equal "application/xml", @response.content_type
266 267
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
268

269
  def test_using_defaults_with_type_list
270
    @request.accept = "*/*"
271
    get :using_defaults_with_type_list
272
    assert_equal "text/html", @response.content_type
273 274
    assert_equal 'Hello world!', @response.body

275
    @request.accept = "text/javascript"
276
    get :using_defaults_with_type_list
277
    assert_equal "text/javascript", @response.content_type
278 279
    assert_equal '$("body").visualEffect("highlight");', @response.body

280
    @request.accept = "application/xml"
281
    get :using_defaults_with_type_list
282
    assert_equal "application/xml", @response.content_type
283 284
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
285

286
  def test_with_atom_content_type
287
    @request.accept = ""
288
    @request.env["CONTENT_TYPE"] = "application/atom+xml"
289
    xhr :get, :made_for_content_type
290
    assert_equal "ATOM", @response.body
291
  end
292

293
  def test_with_rss_content_type
294
    @request.accept = ""
295
    @request.env["CONTENT_TYPE"] = "application/rss+xml"
296
    xhr :get, :made_for_content_type
297 298
    assert_equal "RSS", @response.body
  end
299

300
  def test_synonyms
301
    @request.accept = "application/javascript"
302 303 304
    get :js_or_html
    assert_equal 'JS', @response.body

305
    @request.accept = "application/x-xml"
306 307
    get :html_xml_or_rss
    assert_equal "XML", @response.body
308
  end
309

310
  def test_custom_types
311
    @request.accept = "application/crazy-xml"
312
    get :custom_type_handling
313
    assert_equal "application/crazy-xml", @response.content_type
314 315
    assert_equal 'Crazy XML', @response.body

316
    @request.accept = "text/html"
317
    get :custom_type_handling
318
    assert_equal "text/html", @response.content_type
319 320
    assert_equal 'HTML', @response.body
  end
321 322

  def test_xhtml_alias
323
    @request.accept = "application/xhtml+xml,application/xml"
324 325 326
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
327

328
  def test_firefox_simulation
329
    @request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
330 331 332
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
333 334

  def test_handle_any
335
    @request.accept = "*/*"
336 337 338
    get :handle_any
    assert_equal 'HTML', @response.body

339
    @request.accept = "text/javascript"
340 341 342
    get :handle_any
    assert_equal 'Either JS or XML', @response.body

343
    @request.accept = "text/xml"
344 345 346
    get :handle_any
    assert_equal 'Either JS or XML', @response.body
  end
347

348
  def test_handle_any_any
349
    @request.accept = "*/*"
350 351 352
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end
353

354 355 356 357
  def test_handle_any_any_parameter_format
    get :handle_any_any, {:format=>'html'}
    assert_equal 'HTML', @response.body
  end
358

359
  def test_handle_any_any_explicit_html
360
    @request.accept = "text/html"
361 362 363 364 365
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end

  def test_handle_any_any_javascript
366
    @request.accept = "text/javascript"
367 368 369
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
370

371
  def test_handle_any_any_xml
372
    @request.accept = "text/xml"
373 374 375
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
376 377 378 379 380 381 382 383 384 385 386
  
  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
  
387

388
  def test_rjs_type_skips_layout
389 390 391
    @request.accept = "text/javascript"
    get :all_types_with_layout
    assert_equal 'RJS for all_types_with_layout', @response.body
392
  end
393

394
  def test_html_type_with_layout
395
    @request.accept = "text/html"
396
    get :all_types_with_layout
D
David Heinemeier Hansson 已提交
397
    assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
398
  end
399 400 401 402 403 404 405 406

  def test_xhr
    xhr :get, :js_or_html
    assert_equal 'JS', @response.body

    xhr :get, :using_defaults
    assert_equal '$("body").visualEffect("highlight");', @response.body
  end
407

408 409
  def test_custom_constant
    get :custom_constant_handling, :format => "mobile"
410
    assert_equal "text/x-mobile", @response.content_type
411 412
    assert_equal "Mobile", @response.body
  end
413 414 415 416 417

  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
418
  end
419

420 421 422 423 424 425 426 427 428 429 430 431 432
  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
433

434 435 436 437 438 439 440 441
  def test_internally_forced_format
    get :forced_xml
    assert_equal "XML", @response.body

    get :forced_xml, :format => "html"
    assert_equal "XML", @response.body
  end

442 443 444 445
  def test_extension_synonyms
    get :html_xml_or_rss, :format => "xhtml"
    assert_equal "HTML", @response.body
  end
446 447 448 449

  def test_render_action_for_html
    @controller.instance_eval do
      def render(*args)
450 451 452
        @action = args.first[:action] unless args.empty?
        @action ||= action_name

J
José Valim 已提交
453
        response.body = "#{@action} - #{formats}"
454 455 456 457
      end
    end

    get :using_defaults
458
    assert_equal "using_defaults - #{[:html].to_s}", @response.body
459 460

    get :using_defaults, :format => "xml"
461
    assert_equal "using_defaults - #{[:xml].to_s}", @response.body
462 463
  end

464 465
  def test_format_with_custom_response_type
    get :iphone_with_html_response_type
466 467
    assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body

468 469
    get :iphone_with_html_response_type, :format => "iphone"
    assert_equal "text/html", @response.content_type
D
David Heinemeier Hansson 已提交
470
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
471 472
  end

473
  def test_format_with_custom_response_type_and_request_headers
474
    @request.accept = "text/iphone"
475
    get :iphone_with_html_response_type
D
David Heinemeier Hansson 已提交
476
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
477
    assert_equal "text/html", @response.content_type
478
  end
479
end
480

481
class RespondWithController < ActionController::Base
J
José Valim 已提交
482
  respond_to :html, :json
483 484
  respond_to :xml, :except => :using_resource_with_block
  respond_to :js,  :only => [ :using_resource_with_block, :using_resource ]
485

486 487
  def using_resource
    respond_with(resource)
488 489
  end

490 491 492 493
  def using_resource_with_block
    respond_with(resource) do |format|
      format.csv { render :text => "CSV" }
    end
494
  end
J
José Valim 已提交
495

496 497
  def using_resource_with_overwrite_block
    respond_with(resource) do |format|
J
José Valim 已提交
498 499 500 501
      format.html { render :text => "HTML" }
    end
  end

502
  def using_resource_with_collection
503
    respond_with([resource, Customer.new("jamis", 9)])
504 505
  end

J
José Valim 已提交
506
  def using_resource_with_parent
507
    respond_with(Quiz::Store.new("developer?", 11), Customer.new("david", 13))
508 509
  end

510
  def using_resource_with_status_and_location
511
    respond_with(resource, :location => "http://test.host/", :status => :created)
512 513
  end

514
  def using_resource_with_responder
515
    responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
516
    respond_with(resource, :responder => responder)
517 518
  end

519
  def using_resource_with_action
520
    respond_with(resource, :action => :foo) do |format|
521
      format.html { raise ActionView::MissingTemplate.new([], "foo/bar", {}, false) }
522 523 524
    end
  end

525 526 527 528
  def using_responder_with_respond
    responder = Class.new(ActionController::Responder) do
      def respond; @controller.render :text => "respond #{format}"; end
    end
529
    respond_with(resource, :responder => responder)
530 531
  end

J
José Valim 已提交
532 533
protected

534
  def resource
535
    Customer.new("david", request.delete? ? nil : 13)
536 537
  end

J
José Valim 已提交
538 539 540 541
  def _render_js(js, options)
    self.content_type ||= Mime::JS
    self.response_body = js.respond_to?(:to_js) ? js.to_js : js
  end
542 543
end

544 545 546 547 548
class InheritedRespondWithController < RespondWithController
  clear_respond_to
  respond_to :xml, :json

  def index
549
    respond_with(resource) do |format|
550 551 552 553 554
      format.json { render :text => "JSON" }
    end
  end
end

555 556 557 558 559 560
class EmptyRespondWithController < ActionController::Base
  def index
    respond_with(Customer.new("david", 13))
  end
end

561 562 563 564 565 566 567 568 569 570 571 572
class RespondWithControllerTest < ActionController::TestCase
  tests RespondWithController

  def setup
    super
    @request.host = "www.example.com"
  end

  def teardown
    super
  end

573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
  def test_using_resource
    @request.accept = "text/javascript"
    get :using_resource
    assert_equal "text/javascript", @response.content_type
    assert_equal '$("body").visualEffect("highlight");', @response.body

    @request.accept = "application/xml"
    get :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal "<name>david</name>", @response.body

    @request.accept = "application/json"
    assert_raise ActionView::MissingTemplate do
      get :using_resource
    end
  end

  def test_using_resource_with_block
591
    @request.accept = "*/*"
592
    get :using_resource_with_block
593 594 595 596
    assert_equal "text/html", @response.content_type
    assert_equal 'Hello world!', @response.body

    @request.accept = "text/csv"
597
    get :using_resource_with_block
598 599 600 601
    assert_equal "text/csv", @response.content_type
    assert_equal "CSV", @response.body

    @request.accept = "application/xml"
602
    get :using_resource
603
    assert_equal "application/xml", @response.content_type
604
    assert_equal "<name>david</name>", @response.body
605 606
  end

607 608
  def test_using_resource_with_overwrite_block
    get :using_resource_with_overwrite_block
J
José Valim 已提交
609 610 611 612
    assert_equal "text/html", @response.content_type
    assert_equal "HTML", @response.body
  end

613
  def test_not_acceptable
J
José Valim 已提交
614
    @request.accept = "application/xml"
615 616
    get :using_resource_with_block
    assert_equal 406, @response.status
J
José Valim 已提交
617

618 619 620
    @request.accept = "text/javascript"
    get :using_resource_with_overwrite_block
    assert_equal 406, @response.status
J
José Valim 已提交
621 622
  end

623
  def test_using_resource_for_post_with_html_redirects_on_success
624 625 626 627 628 629
    with_test_route_set do
      post :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 302, @response.status
      assert_equal "http://www.example.com/customers/13", @response.location
      assert @response.redirect?
630 631
    end
  end
632

633 634
  def test_using_resource_for_post_with_html_rerender_on_failure
    with_test_route_set do
635 636 637 638 639 640 641 642
      errors = { :name => :invalid }
      Customer.any_instance.stubs(:errors).returns(errors)
      post :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 200, @response.status
      assert_equal "New world!\n", @response.body
      assert_nil @response.location
    end
643 644
  end

645
  def test_using_resource_for_post_with_xml_yields_created_on_success
646 647 648 649 650 651 652
    with_test_route_set do
      @request.accept = "application/xml"
      post :using_resource
      assert_equal "application/xml", @response.content_type
      assert_equal 201, @response.status
      assert_equal "<name>david</name>", @response.body
      assert_equal "http://www.example.com/customers/13", @response.location
653 654
    end
  end
655

656 657 658
  def test_using_resource_for_post_with_xml_yields_unprocessable_entity_on_failure
    with_test_route_set do
      @request.accept = "application/xml"
659 660 661 662 663 664 665 666
      errors = { :name => :invalid }
      Customer.any_instance.stubs(:errors).returns(errors)
      post :using_resource
      assert_equal "application/xml", @response.content_type
      assert_equal 422, @response.status
      assert_equal errors.to_xml, @response.body
      assert_nil @response.location
    end
667 668
  end

669
  def test_using_resource_for_put_with_html_redirects_on_success
670 671 672 673 674 675
    with_test_route_set do
      put :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 302, @response.status
      assert_equal "http://www.example.com/customers/13", @response.location
      assert @response.redirect?
676 677
    end
  end
678

679 680
  def test_using_resource_for_put_with_html_rerender_on_failure
    with_test_route_set do
681 682 683 684 685 686 687 688
      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
      assert_nil @response.location
    end
689 690
  end

691 692 693 694 695 696 697 698 699 700 701 702 703
  def test_using_resource_for_put_with_html_rerender_on_failure_even_on_method_override
    with_test_route_set do
      errors = { :name => :invalid }
      Customer.any_instance.stubs(:errors).returns(errors)
      @request.env["rack.methodoverride.original_method"] = "POST"
      put :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 200, @response.status
      assert_equal "Edit world!\n", @response.body
      assert_nil @response.location
    end
  end

704
  def test_using_resource_for_put_with_xml_yields_ok_on_success
705 706 707 708 709
    @request.accept = "application/xml"
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_equal " ", @response.body
710
  end
711

712 713
  def test_using_resource_for_put_with_xml_yields_unprocessable_entity_on_failure
    @request.accept = "application/xml"
714
    errors = { :name => :invalid }
715
    Customer.any_instance.stubs(:errors).returns(errors)
716 717 718 719
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 422, @response.status
    assert_equal errors.to_xml, @response.body
720
    assert_nil @response.location
721 722
  end

723
  def test_using_resource_for_delete_with_html_redirects_on_success
724 725 726 727 728 729 730
    with_test_route_set do
      Customer.any_instance.stubs(:destroyed?).returns(true)
      delete :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 302, @response.status
      assert_equal "http://www.example.com/customers", @response.location
    end
731 732
  end

733
  def test_using_resource_for_delete_with_xml_yields_ok_on_success
734
    Customer.any_instance.stubs(:destroyed?).returns(true)
735 736 737 738 739
    @request.accept = "application/xml"
    delete :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_equal " ", @response.body
J
José Valim 已提交
740 741
  end

742 743 744 745 746 747 748 749
  def test_using_resource_for_delete_with_html_redirects_on_failure
    with_test_route_set do
      errors = { :name => :invalid }
      Customer.any_instance.stubs(:errors).returns(errors)
      Customer.any_instance.stubs(:destroyed?).returns(false)
      delete :using_resource
      assert_equal "text/html", @response.content_type
      assert_equal 302, @response.status
750
      assert_equal "http://www.example.com/customers", @response.location
751 752 753
    end
  end

754 755 756 757 758
  def test_using_resource_with_parent_for_get
    @request.accept = "application/xml"
    get :using_resource_with_parent
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
759
    assert_equal "<name>david</name>", @response.body
760 761 762
  end

  def test_using_resource_with_parent_for_post
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
    with_test_route_set do
      @request.accept = "application/xml"

      post :using_resource_with_parent
      assert_equal "application/xml", @response.content_type
      assert_equal 201, @response.status
      assert_equal "<name>david</name>", @response.body
      assert_equal "http://www.example.com/quiz_stores/11/customers/13", @response.location

      errors = { :name => :invalid }
      Customer.any_instance.stubs(:errors).returns(errors)
      post :using_resource
      assert_equal "application/xml", @response.content_type
      assert_equal 422, @response.status
      assert_equal errors.to_xml, @response.body
      assert_nil @response.location
    end
780 781
  end

782 783 784 785 786 787 788 789 790
  def test_using_resource_with_collection
    @request.accept = "application/xml"
    get :using_resource_with_collection
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_match /<name>david<\/name>/, @response.body
    assert_match /<name>jamis<\/name>/, @response.body
  end

791 792 793 794 795 796 797 798 799 800 801
  def test_using_resource_with_action
    @controller.instance_eval do
      def render(params={})
        self.response_body = "#{params[:action]} - #{formats}"
      end
    end

    errors = { :name => :invalid }
    Customer.any_instance.stubs(:errors).returns(errors)

    post :using_resource_with_action
802
    assert_equal "foo - #{[:html].to_s}", @controller.response.body
803 804
  end

805 806 807 808 809 810 811 812 813 814
  def test_respond_as_responder_entry_point
    @request.accept = "text/html"
    get :using_responder_with_respond
    assert_equal "respond html", @response.body

    @request.accept = "application/xml"
    get :using_responder_with_respond
    assert_equal "respond xml", @response.body
  end

815 816 817 818 819 820 821 822 823 824 825 826
  def test_clear_respond_to
    @controller = InheritedRespondWithController.new
    @request.accept = "text/html"
    get :index
    assert_equal 406, @response.status
  end

  def test_first_in_respond_to_has_higher_priority
    @controller = InheritedRespondWithController.new
    @request.accept = "*/*"
    get :index
    assert_equal "application/xml", @response.content_type
827
    assert_equal "<name>david</name>", @response.body
828 829
  end

830 831 832 833 834 835 836
  def test_block_inside_respond_with_is_rendered
    @controller = InheritedRespondWithController.new
    @request.accept = "application/json"
    get :index
    assert_equal "JSON", @response.body
  end

837 838 839 840 841 842 843
  def test_no_double_render_is_raised
    @request.accept = "text/html"
    assert_raise ActionView::MissingTemplate do
      get :using_resource
    end
  end

844
  def test_using_resource_with_status_and_location
845
    @request.accept = "text/html"
846
    post :using_resource_with_status_and_location
847 848
    assert @response.redirect?
    assert_equal "http://test.host/", @response.location
849 850 851 852 853 854

    @request.accept = "application/xml"
    get :using_resource_with_status_and_location
    assert_equal 201, @response.status
  end

855 856
  def test_using_resource_with_responder
    get :using_resource_with_responder
857
    assert_equal "Resource name is david", @response.body
858 859
  end

860
  def test_using_resource_with_set_responder
861 862 863 864 865 866 867
    RespondWithController.responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
    get :using_resource
    assert_equal "Resource name is david", @response.body
  ensure
    RespondWithController.responder = ActionController::Responder
  end

868 869 870 871 872 873
  def test_error_is_raised_if_no_respond_to_is_declared_and_respond_with_is_called
    @controller = EmptyRespondWithController.new
    @request.accept = "*/*"
    assert_raise RuntimeError do
      get :index
    end
874
  end
875 876 877 878 879

  private
    def with_test_route_set
      with_routing do |set|
        set.draw do |map|
J
Joshua Peek 已提交
880 881 882 883 884
          resources :customers
          resources :quiz_stores do
            resources :customers
          end
          match ":controller/:action"
885 886 887 888
        end
        yield
      end
    end
889 890
end

891
class AbstractPostController < ActionController::Base
892
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
893 894 895 896 897
end

# For testing layouts which are set automatically
class PostController < AbstractPostController
  around_filter :with_iphone
898

899
  def index
900
    respond_to(:html, :iphone)
901
  end
902

903 904 905 906 907 908
protected

  def with_iphone
    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
    yield
  end
909
end
910

911
class SuperPostController < PostController
912 913
end

914 915
class MimeControllerLayoutsTest < ActionController::TestCase
  tests PostController
916

917
  def setup
918
    super
919 920
    @request.host = "www.example.com"
  end
921

922 923
  def test_missing_layout_renders_properly
    get :index
924
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
925

926
    @request.accept = "text/iphone"
927 928 929
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
930

931 932
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
933

934 935
    get :index
    assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
936

937 938 939
    @request.accept = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
940 941
  end
end