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

N
Neeraj Singh 已提交
5 6 7 8 9 10 11 12
class StarStarMimeController < ActionController::Base
  layout nil

  def index
    render
  end
end

13
class RespondToController < ActionController::Base
14 15
  layout :set_layout

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

25 26 27 28 29 30 31
  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
32

33 34 35
  def json_or_yaml
    respond_to do |type|
      type.json { render :text => "JSON" }
36
      type.yaml { render :text => "YAML" }
37 38
    end
  end
39 40 41 42 43 44 45 46

  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
47

48 49 50 51 52 53 54
  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
55

56

57 58 59 60 61 62 63 64 65
  def forced_xml
    request.format = :xml

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

66 67 68 69 70
  def just_xml
    respond_to do |type|
      type.xml  { render :text => "XML" }
    end
  end
71

72 73 74 75 76 77 78
  def using_defaults
    respond_to do |type|
      type.html
      type.js
      type.xml
    end
  end
79

80 81 82
  def using_defaults_with_type_list
    respond_to(:html, :js, :xml)
  end
83

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

92 93 94 95 96 97 98
  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
99

100

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

108 109 110 111 112 113
  def custom_constant_handling_without_block
    respond_to do |type|
      type.html   { render :text => "HTML"   }
      type.mobile
    end
  end
114

115 116 117 118 119 120
  def handle_any
    respond_to do |type|
      type.html { render :text => "HTML" }
      type.any(:js, :xml) { render :text => "Either JS or XML" }
    end
  end
121

122 123 124 125 126 127
  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
128

129 130 131 132 133
  def all_types_with_layout
    respond_to do |type|
      type.html
      type.js
    end
134 135
  end

136

137
  def iphone_with_html_response_type
138
    request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
139

140 141
    respond_to do |type|
      type.html   { @type = "Firefox" }
142
      type.iphone { @type = "iPhone"  }
143
    end
144 145
  end

146 147
  def iphone_with_html_response_type_without_layout
    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
148

149 150 151 152 153 154
    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

155
  def rescue_action(e)
J
Jamis Buck 已提交
156
    raise
157
  end
158

159 160
  protected
    def set_layout
161
      if ["all_types_with_layout", "iphone_with_html_response_type"].include?(action_name)
D
David Heinemeier Hansson 已提交
162
        "respond_to/layouts/standard"
163 164
      elsif action_name == "iphone_with_html_response_type_without_layout"
        "respond_to/layouts/missing"
165 166
      end
    end
167 168
end

N
Neeraj Singh 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
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

192
class RespondToControllerTest < ActionController::TestCase
193 194
  tests RespondToController

195
  def setup
196
    super
197
    @request.host = "www.example.com"
198 199
    Mime::Type.register_alias("text/html", :iphone)
    Mime::Type.register("text/x-mobile", :mobile)
200
  end
201

202
  def teardown
203
    super
J
José Valim 已提交
204 205
    Mime::Type.unregister(:iphone)
    Mime::Type.unregister(:mobile)
206 207
  end

208
  def test_html
209
    @request.accept = "text/html"
210 211
    get :js_or_html
    assert_equal 'HTML', @response.body
212

213 214 215 216 217 218 219 220
    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_response 406
  end

  def test_all
221
    @request.accept = "*/*"
222 223 224 225 226 227 228 229 230 231 232
    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
233
    @request.accept = "application/xml"
234 235 236 237 238
    get :html_xml_or_rss
    assert_equal 'XML', @response.body
  end

  def test_js_or_html
239
    @request.accept = "text/javascript, text/html"
240
    xhr :get, :js_or_html
241 242
    assert_equal 'JS', @response.body

243 244
    @request.accept = "text/javascript, text/html"
    xhr :get, :html_or_xml
245 246
    assert_equal 'HTML', @response.body

247 248
    @request.accept = "text/javascript, text/html"
    xhr :get, :just_xml
249 250
    assert_response 406
  end
251

252 253 254 255
  def test_json_or_yaml_with_leading_star_star
    @request.accept = "*/*, application/json"
    get :json_xml_or_html
    assert_equal 'HTML', @response.body
256 257 258 259

    @request.accept = "*/* , application/json"
    get :json_xml_or_html
    assert_equal 'HTML', @response.body
260 261
  end

262
  def test_json_or_yaml
263
    xhr :get, :json_or_yaml
264
    assert_equal 'JSON', @response.body
265 266

    get :json_or_yaml, :format => 'json'
267
    assert_equal 'JSON', @response.body
268 269 270 271 272 273 274 275

    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|
276
        @request.accept = content_type
277 278 279 280
        get :json_or_yaml
        assert_equal body, @response.body
      end
    end
281
  end
282 283

  def test_js_or_anything
284
    @request.accept = "text/javascript, */*"
285
    xhr :get, :js_or_html
286 287
    assert_equal 'JS', @response.body

288
    xhr :get, :html_or_xml
289 290
    assert_equal 'HTML', @response.body

291
    xhr :get, :just_xml
292 293
    assert_equal 'XML', @response.body
  end
294

295
  def test_using_defaults
296
    @request.accept = "*/*"
297
    get :using_defaults
298
    assert_equal "text/html", @response.content_type
299 300
    assert_equal 'Hello world!', @response.body

301
    @request.accept = "text/javascript"
302
    get :using_defaults
303
    assert_equal "text/javascript", @response.content_type
304
    assert_equal '$("body").visualEffect("highlight");', @response.body
305

306
    @request.accept = "application/xml"
307
    get :using_defaults
308
    assert_equal "application/xml", @response.content_type
309 310
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
311

312
  def test_using_defaults_with_type_list
313
    @request.accept = "*/*"
314
    get :using_defaults_with_type_list
315
    assert_equal "text/html", @response.content_type
316 317
    assert_equal 'Hello world!', @response.body

318
    @request.accept = "text/javascript"
319
    get :using_defaults_with_type_list
320
    assert_equal "text/javascript", @response.content_type
321 322
    assert_equal '$("body").visualEffect("highlight");', @response.body

323
    @request.accept = "application/xml"
324
    get :using_defaults_with_type_list
325
    assert_equal "application/xml", @response.content_type
326 327
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
328

329
  def test_with_atom_content_type
330
    @request.accept = ""
331
    @request.env["CONTENT_TYPE"] = "application/atom+xml"
332
    xhr :get, :made_for_content_type
333
    assert_equal "ATOM", @response.body
334
  end
335

336
  def test_with_rss_content_type
337
    @request.accept = ""
338
    @request.env["CONTENT_TYPE"] = "application/rss+xml"
339
    xhr :get, :made_for_content_type
340 341
    assert_equal "RSS", @response.body
  end
342

343
  def test_synonyms
344
    @request.accept = "application/javascript"
345 346 347
    get :js_or_html
    assert_equal 'JS', @response.body

348
    @request.accept = "application/x-xml"
349 350
    get :html_xml_or_rss
    assert_equal "XML", @response.body
351
  end
352

353
  def test_custom_types
354
    @request.accept = "application/crazy-xml"
355
    get :custom_type_handling
356
    assert_equal "application/crazy-xml", @response.content_type
357 358
    assert_equal 'Crazy XML', @response.body

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

  def test_xhtml_alias
366
    @request.accept = "application/xhtml+xml,application/xml"
367 368 369
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
370

371
  def test_firefox_simulation
372
    @request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
373 374 375
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
376 377

  def test_handle_any
378
    @request.accept = "*/*"
379 380 381
    get :handle_any
    assert_equal 'HTML', @response.body

382
    @request.accept = "text/javascript"
383 384 385
    get :handle_any
    assert_equal 'Either JS or XML', @response.body

386
    @request.accept = "text/xml"
387 388 389
    get :handle_any
    assert_equal 'Either JS or XML', @response.body
  end
390

391
  def test_handle_any_any
392
    @request.accept = "*/*"
393 394 395
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end
396

397 398 399 400
  def test_handle_any_any_parameter_format
    get :handle_any_any, {:format=>'html'}
    assert_equal 'HTML', @response.body
  end
401

402
  def test_handle_any_any_explicit_html
403
    @request.accept = "text/html"
404 405 406 407 408
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end

  def test_handle_any_any_javascript
409
    @request.accept = "text/javascript"
410 411 412
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
413

414
  def test_handle_any_any_xml
415
    @request.accept = "text/xml"
416 417 418
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
419

420 421 422 423
  def test_browser_check_with_any_any
    @request.accept = "application/json, application/xml"
    get :json_xml_or_html
    assert_equal 'JSON', @response.body
424

425 426 427 428
    @request.accept = "application/json, application/xml, */*"
    get :json_xml_or_html
    assert_equal 'HTML', @response.body
  end
429

430

431
  def test_rjs_type_skips_layout
432 433 434
    @request.accept = "text/javascript"
    get :all_types_with_layout
    assert_equal 'RJS for all_types_with_layout', @response.body
435
  end
436

437
  def test_html_type_with_layout
438
    @request.accept = "text/html"
439
    get :all_types_with_layout
D
David Heinemeier Hansson 已提交
440
    assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
441
  end
442 443 444 445 446 447 448 449

  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
450

451 452
  def test_custom_constant
    get :custom_constant_handling, :format => "mobile"
453
    assert_equal "text/x-mobile", @response.content_type
454 455
    assert_equal "Mobile", @response.body
  end
456 457 458 459 460

  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
461
  end
462

463 464 465 466 467 468 469 470 471 472 473 474 475
  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
476

477 478 479 480 481 482 483 484
  def test_internally_forced_format
    get :forced_xml
    assert_equal "XML", @response.body

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

485 486 487 488
  def test_extension_synonyms
    get :html_xml_or_rss, :format => "xhtml"
    assert_equal "HTML", @response.body
  end
489 490 491 492

  def test_render_action_for_html
    @controller.instance_eval do
      def render(*args)
493 494 495
        @action = args.first[:action] unless args.empty?
        @action ||= action_name

J
José Valim 已提交
496
        response.body = "#{@action} - #{formats}"
497 498 499 500
      end
    end

    get :using_defaults
501
    assert_equal "using_defaults - #{[:html].to_s}", @response.body
502 503

    get :using_defaults, :format => "xml"
504
    assert_equal "using_defaults - #{[:xml].to_s}", @response.body
505 506
  end

507 508
  def test_format_with_custom_response_type
    get :iphone_with_html_response_type
509 510
    assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body

511 512
    get :iphone_with_html_response_type, :format => "iphone"
    assert_equal "text/html", @response.content_type
D
David Heinemeier Hansson 已提交
513
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
514 515
  end

516
  def test_format_with_custom_response_type_and_request_headers
517
    @request.accept = "text/iphone"
518
    get :iphone_with_html_response_type
D
David Heinemeier Hansson 已提交
519
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
520
    assert_equal "text/html", @response.content_type
521
  end
522
end
523

524
class RespondWithController < ActionController::Base
J
José Valim 已提交
525
  respond_to :html, :json
526 527
  respond_to :xml, :except => :using_resource_with_block
  respond_to :js,  :only => [ :using_resource_with_block, :using_resource ]
528

529 530
  def using_resource
    respond_with(resource)
531 532
  end

533 534 535 536
  def using_hash_resource
    respond_with({:result => resource})
  end

537 538 539 540
  def using_resource_with_block
    respond_with(resource) do |format|
      format.csv { render :text => "CSV" }
    end
541
  end
J
José Valim 已提交
542

543 544
  def using_resource_with_overwrite_block
    respond_with(resource) do |format|
J
José Valim 已提交
545 546 547 548
      format.html { render :text => "HTML" }
    end
  end

549
  def using_resource_with_collection
550
    respond_with([resource, Customer.new("jamis", 9)])
551 552
  end

J
José Valim 已提交
553
  def using_resource_with_parent
554
    respond_with(Quiz::Store.new("developer?", 11), Customer.new("david", 13))
555 556
  end

557
  def using_resource_with_status_and_location
558
    respond_with(resource, :location => "http://test.host/", :status => :created)
559 560
  end

561
  def using_resource_with_responder
562
    responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
563
    respond_with(resource, :responder => responder)
564 565
  end

566
  def using_resource_with_action
567
    respond_with(resource, :action => :foo) do |format|
568
      format.html { raise ActionView::MissingTemplate.new([], "bar", ["foo"], {}, false) }
569 570 571
    end
  end

572 573 574 575
  def using_responder_with_respond
    responder = Class.new(ActionController::Responder) do
      def respond; @controller.render :text => "respond #{format}"; end
    end
576
    respond_with(resource, :responder => responder)
577 578
  end

J
José Valim 已提交
579 580
protected

581
  def resource
582
    Customer.new("david", request.delete? ? nil : 13)
583 584
  end

J
José Valim 已提交
585 586 587 588
  def _render_js(js, options)
    self.content_type ||= Mime::JS
    self.response_body = js.respond_to?(:to_js) ? js.to_js : js
  end
589 590
end

591 592 593 594 595
class InheritedRespondWithController < RespondWithController
  clear_respond_to
  respond_to :xml, :json

  def index
596
    respond_with(resource) do |format|
597 598 599 600 601
      format.json { render :text => "JSON" }
    end
  end
end

602 603 604 605 606 607 608 609 610 611 612
class RenderJsonRespondWithController < RespondWithController
  clear_respond_to
  respond_to :json

  def index
    respond_with(resource) do |format|
      format.json { render :json => RenderJsonTestException.new('boom') }
    end
  end
end

613 614 615 616 617 618
class EmptyRespondWithController < ActionController::Base
  def index
    respond_with(Customer.new("david", 13))
  end
end

619 620 621 622 623 624
class RespondWithControllerTest < ActionController::TestCase
  tests RespondWithController

  def setup
    super
    @request.host = "www.example.com"
J
José Valim 已提交
625 626
    Mime::Type.register_alias('text/html', :iphone)
    Mime::Type.register('text/x-mobile', :mobile)
627 628 629 630
  end

  def teardown
    super
J
José Valim 已提交
631 632
    Mime::Type.unregister(:iphone)
    Mime::Type.unregister(:mobile)
633 634
  end

635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
  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

652 653 654 655 656 657 658 659 660
  def test_using_hash_resource
    @request.accept = "application/xml"
    get :using_hash_resource
    assert_equal "application/xml", @response.content_type
    assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n  <name>david</name>\n</hash>\n", @response.body

    @request.accept = "application/json"
    get :using_hash_resource
    assert_equal "application/json", @response.content_type
A
Aaron Patterson 已提交
661
    assert_equal %Q[{"result":{"name":"david","id":13}}], @response.body
662 663
  end

664
  def test_using_resource_with_block
665
    @request.accept = "*/*"
666
    get :using_resource_with_block
667 668 669 670
    assert_equal "text/html", @response.content_type
    assert_equal 'Hello world!', @response.body

    @request.accept = "text/csv"
671
    get :using_resource_with_block
672 673 674 675
    assert_equal "text/csv", @response.content_type
    assert_equal "CSV", @response.body

    @request.accept = "application/xml"
676
    get :using_resource
677
    assert_equal "application/xml", @response.content_type
678
    assert_equal "<name>david</name>", @response.body
679 680
  end

681 682
  def test_using_resource_with_overwrite_block
    get :using_resource_with_overwrite_block
J
José Valim 已提交
683 684 685 686
    assert_equal "text/html", @response.content_type
    assert_equal "HTML", @response.body
  end

687
  def test_not_acceptable
J
José Valim 已提交
688
    @request.accept = "application/xml"
689 690
    get :using_resource_with_block
    assert_equal 406, @response.status
J
José Valim 已提交
691

692 693 694
    @request.accept = "text/javascript"
    get :using_resource_with_overwrite_block
    assert_equal 406, @response.status
J
José Valim 已提交
695 696
  end

697
  def test_using_resource_for_post_with_html_redirects_on_success
698 699 700 701 702 703
    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?
704 705
    end
  end
706

707 708
  def test_using_resource_for_post_with_html_rerender_on_failure
    with_test_route_set do
709 710 711 712 713 714 715 716
      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
717 718
  end

719
  def test_using_resource_for_post_with_xml_yields_created_on_success
720 721 722 723 724 725 726
    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
727 728
    end
  end
729

730 731 732
  def test_using_resource_for_post_with_xml_yields_unprocessable_entity_on_failure
    with_test_route_set do
      @request.accept = "application/xml"
733 734 735 736 737 738 739 740
      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
741 742
  end

743
  def test_using_resource_for_put_with_html_redirects_on_success
744 745 746 747 748 749
    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?
750 751
    end
  end
752

753 754
  def test_using_resource_for_put_with_html_rerender_on_failure
    with_test_route_set do
755 756 757 758 759 760 761 762
      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
763 764
  end

765 766 767 768 769 770 771 772 773 774 775 776 777
  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

778
  def test_using_resource_for_put_with_xml_yields_ok_on_success
779 780 781 782 783
    @request.accept = "application/xml"
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_equal " ", @response.body
784
  end
785

786 787 788 789 790 791 792 793 794
  def test_using_resource_for_put_with_json_yields_ok_on_success
    Customer.any_instance.stubs(:to_json).returns('{"name": "David"}')
    @request.accept = "application/json"
    put :using_resource
    assert_equal "application/json", @response.content_type
    assert_equal 200, @response.status
    assert_equal "{}", @response.body
  end

795 796
  def test_using_resource_for_put_with_xml_yields_unprocessable_entity_on_failure
    @request.accept = "application/xml"
797
    errors = { :name => :invalid }
798
    Customer.any_instance.stubs(:errors).returns(errors)
799 800 801 802
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 422, @response.status
    assert_equal errors.to_xml, @response.body
803
    assert_nil @response.location
804 805
  end

806
  def test_using_resource_for_delete_with_html_redirects_on_success
807 808 809 810 811 812 813
    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
814 815
  end

816
  def test_using_resource_for_delete_with_xml_yields_ok_on_success
817
    Customer.any_instance.stubs(:destroyed?).returns(true)
818 819 820 821 822
    @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 已提交
823 824
  end

825 826 827 828 829 830 831 832 833 834
  def test_using_resource_for_delete_with_json_yields_ok_on_success
    Customer.any_instance.stubs(:to_json).returns('{"name": "David"}')
    Customer.any_instance.stubs(:destroyed?).returns(true)
    @request.accept = "application/json"
    delete :using_resource
    assert_equal "application/json", @response.content_type
    assert_equal 200, @response.status
    assert_equal "{}", @response.body
  end

835 836 837 838 839 840 841 842
  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
843
      assert_equal "http://www.example.com/customers", @response.location
844 845 846
    end
  end

847 848 849 850 851
  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
852
    assert_equal "<name>david</name>", @response.body
853 854 855
  end

  def test_using_resource_with_parent_for_post
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
    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
873 874
  end

875 876 877 878 879
  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
880 881
    assert_match(/<name>david<\/name>/, @response.body)
    assert_match(/<name>jamis<\/name>/, @response.body)
882 883
  end

884 885 886 887 888 889 890 891 892 893 894
  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
895
    assert_equal "foo - #{[:html].to_s}", @controller.response.body
896 897
  end

898 899 900 901 902 903 904 905 906 907
  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

908 909 910 911 912 913 914 915 916 917 918 919
  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
920
    assert_equal "<name>david</name>", @response.body
921 922
  end

923 924 925 926 927 928 929
  def test_block_inside_respond_with_is_rendered
    @controller = InheritedRespondWithController.new
    @request.accept = "application/json"
    get :index
    assert_equal "JSON", @response.body
  end

930 931 932 933
  def test_render_json_object_responds_to_str_still_produce_json
    @controller = RenderJsonRespondWithController.new
    @request.accept = "application/json"
    get :index, :format => :json
J
José Valim 已提交
934 935
    assert_match(/"message":"boom"/, @response.body)
    assert_match(/"error":"RenderJsonTestException"/, @response.body)
936 937
  end

938 939 940 941 942 943 944
  def test_no_double_render_is_raised
    @request.accept = "text/html"
    assert_raise ActionView::MissingTemplate do
      get :using_resource
    end
  end

945
  def test_using_resource_with_status_and_location
946
    @request.accept = "text/html"
947
    post :using_resource_with_status_and_location
948 949
    assert @response.redirect?
    assert_equal "http://test.host/", @response.location
950 951 952 953 954 955

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

956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
  def test_using_resource_with_status_and_location_with_invalid_resource
    errors = { :name => :invalid }
    Customer.any_instance.stubs(:errors).returns(errors)

    @request.accept = "text/xml"

    post :using_resource_with_status_and_location
    assert_equal errors.to_xml, @response.body
    assert_equal 422, @response.status
    assert_equal nil, @response.location

    put :using_resource_with_status_and_location
    assert_equal errors.to_xml, @response.body
    assert_equal 422, @response.status
    assert_equal nil, @response.location
  end

973 974
  def test_using_resource_with_responder
    get :using_resource_with_responder
975
    assert_equal "Resource name is david", @response.body
976 977
  end

978
  def test_using_resource_with_set_responder
979 980 981 982 983 984 985
    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

986 987 988 989 990 991
  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
992
  end
993 994 995 996

  private
    def with_test_route_set
      with_routing do |set|
997
        set.draw do
J
Joshua Peek 已提交
998 999 1000 1001 1002
          resources :customers
          resources :quiz_stores do
            resources :customers
          end
          match ":controller/:action"
1003 1004 1005 1006
        end
        yield
      end
    end
1007 1008
end

1009
class AbstractPostController < ActionController::Base
1010
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
1011 1012 1013 1014 1015
end

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

1017
  def index
1018
    respond_to(:html, :iphone)
1019
  end
1020

1021 1022 1023 1024 1025 1026
protected

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

1029
class SuperPostController < PostController
1030 1031
end

1032 1033
class MimeControllerLayoutsTest < ActionController::TestCase
  tests PostController
1034

1035
  def setup
1036
    super
1037
    @request.host = "www.example.com"
1038 1039 1040 1041 1042
    Mime::Type.register_alias("text/html", :iphone)
  end

  def teardown
    super
J
José Valim 已提交
1043
    Mime::Type.unregister(:iphone)
1044
  end
1045

1046 1047
  def test_missing_layout_renders_properly
    get :index
1048
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
1049

1050
    @request.accept = "text/iphone"
1051 1052 1053
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
1054

1055 1056
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
1057

1058 1059
    get :index
    assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
1060

1061 1062 1063
    @request.accept = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
1064 1065
  end
end