mime_responds_test.rb 30.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
require 'active_support/core_ext/object/inclusion'
5

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

  def index
    render
  end
end

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

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

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

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

  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
48

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

57

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

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

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

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

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

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

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

101

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

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

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

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

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

137

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

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

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

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

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

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

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

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

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

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

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

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

    get :just_xml
    assert_response 406
  end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

431

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

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

  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
451

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

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

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

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

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

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

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

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

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

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

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

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

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

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

530 531
  def using_resource
    respond_with(resource)
532 533
  end

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

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

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

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

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

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

562 563 564 565
  def using_invalid_resource_with_template
    respond_with(resource)
  end

566 567 568 569 570
  def using_options_with_template
    @customer = resource
    respond_with(@customer, :status => 123, :location => "http://test.host/")
  end

571
  def using_resource_with_responder
572
    responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
573
    respond_with(resource, :responder => responder)
574 575
  end

576
  def using_resource_with_action
577
    respond_with(resource, :action => :foo) do |format|
578
      format.html { raise ActionView::MissingTemplate.new([], "bar", ["foo"], {}, false) }
579 580 581
    end
  end

582 583 584 585
  def using_responder_with_respond
    responder = Class.new(ActionController::Responder) do
      def respond; @controller.render :text => "respond #{format}"; end
    end
586
    respond_with(resource, :responder => responder)
587 588
  end

J
José Valim 已提交
589 590
protected

591
  def resource
592
    Customer.new("david", request.delete? ? nil : 13)
593 594
  end

J
José Valim 已提交
595 596 597 598
  def _render_js(js, options)
    self.content_type ||= Mime::JS
    self.response_body = js.respond_to?(:to_js) ? js.to_js : js
  end
599 600
end

601 602 603 604 605
class InheritedRespondWithController < RespondWithController
  clear_respond_to
  respond_to :xml, :json

  def index
606
    respond_with(resource) do |format|
607 608 609 610 611
      format.json { render :text => "JSON" }
    end
  end
end

612 613 614 615 616 617 618 619 620 621 622
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

623 624 625 626 627 628
class EmptyRespondWithController < ActionController::Base
  def index
    respond_with(Customer.new("david", 13))
  end
end

629 630 631 632 633 634
class RespondWithControllerTest < ActionController::TestCase
  tests RespondWithController

  def setup
    super
    @request.host = "www.example.com"
J
José Valim 已提交
635 636
    Mime::Type.register_alias('text/html', :iphone)
    Mime::Type.register('text/x-mobile', :mobile)
637 638 639 640
  end

  def teardown
    super
J
José Valim 已提交
641 642
    Mime::Type.unregister(:iphone)
    Mime::Type.unregister(:mobile)
643 644
  end

645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
  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

662 663 664 665 666 667 668 669 670
  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 已提交
671
    assert_equal %Q[{"result":{"name":"david","id":13}}], @response.body
672 673
  end

674
  def test_using_resource_with_block
675
    @request.accept = "*/*"
676
    get :using_resource_with_block
677 678 679 680
    assert_equal "text/html", @response.content_type
    assert_equal 'Hello world!', @response.body

    @request.accept = "text/csv"
681
    get :using_resource_with_block
682 683 684 685
    assert_equal "text/csv", @response.content_type
    assert_equal "CSV", @response.body

    @request.accept = "application/xml"
686
    get :using_resource
687
    assert_equal "application/xml", @response.content_type
688
    assert_equal "<name>david</name>", @response.body
689 690
  end

691 692
  def test_using_resource_with_overwrite_block
    get :using_resource_with_overwrite_block
J
José Valim 已提交
693 694 695 696
    assert_equal "text/html", @response.content_type
    assert_equal "HTML", @response.body
  end

697
  def test_not_acceptable
J
José Valim 已提交
698
    @request.accept = "application/xml"
699 700
    get :using_resource_with_block
    assert_equal 406, @response.status
J
José Valim 已提交
701

702 703 704
    @request.accept = "text/javascript"
    get :using_resource_with_overwrite_block
    assert_equal 406, @response.status
J
José Valim 已提交
705 706
  end

707
  def test_using_resource_for_post_with_html_redirects_on_success
708 709 710 711 712 713
    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?
714 715
    end
  end
716

717 718
  def test_using_resource_for_post_with_html_rerender_on_failure
    with_test_route_set do
719 720 721 722 723 724 725 726
      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
727 728
  end

729
  def test_using_resource_for_post_with_xml_yields_created_on_success
730 731 732 733 734 735 736
    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
737 738
    end
  end
739

740 741 742
  def test_using_resource_for_post_with_xml_yields_unprocessable_entity_on_failure
    with_test_route_set do
      @request.accept = "application/xml"
743 744 745 746 747 748 749 750
      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
751 752
  end

753
  def test_using_resource_for_put_with_html_redirects_on_success
754 755 756 757 758 759
    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?
760 761
    end
  end
762

763 764
  def test_using_resource_for_put_with_html_rerender_on_failure
    with_test_route_set do
765 766 767 768 769 770 771 772
      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
773 774
  end

775 776 777 778 779 780 781 782 783 784 785 786 787
  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

788
  def test_using_resource_for_put_with_xml_yields_ok_on_success
789 790 791 792 793
    @request.accept = "application/xml"
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_equal " ", @response.body
794
  end
795

796 797 798 799 800 801 802 803 804
  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

805 806
  def test_using_resource_for_put_with_xml_yields_unprocessable_entity_on_failure
    @request.accept = "application/xml"
807
    errors = { :name => :invalid }
808
    Customer.any_instance.stubs(:errors).returns(errors)
809 810 811 812
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 422, @response.status
    assert_equal errors.to_xml, @response.body
813
    assert_nil @response.location
814 815
  end

816
  def test_using_resource_for_delete_with_html_redirects_on_success
817 818 819 820 821 822 823
    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
824 825
  end

826
  def test_using_resource_for_delete_with_xml_yields_ok_on_success
827
    Customer.any_instance.stubs(:destroyed?).returns(true)
828 829 830 831 832
    @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 已提交
833 834
  end

835 836 837 838 839 840 841 842 843 844
  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

845 846 847 848 849 850 851 852
  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
853
      assert_equal "http://www.example.com/customers", @response.location
854 855 856
    end
  end

857 858 859 860 861
  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
862
    assert_equal "<name>david</name>", @response.body
863 864 865
  end

  def test_using_resource_with_parent_for_post
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
    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
883 884
  end

885 886 887 888 889
  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
890 891
    assert_match(/<name>david<\/name>/, @response.body)
    assert_match(/<name>jamis<\/name>/, @response.body)
892 893
  end

894 895 896 897 898 899 900 901 902 903 904
  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
905
    assert_equal "foo - #{[:html].to_s}", @controller.response.body
906 907
  end

908 909 910 911 912 913 914 915 916 917
  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

918 919 920 921 922 923 924 925 926 927 928 929
  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
930
    assert_equal "<name>david</name>", @response.body
931 932
  end

933 934 935 936 937 938 939
  def test_block_inside_respond_with_is_rendered
    @controller = InheritedRespondWithController.new
    @request.accept = "application/json"
    get :index
    assert_equal "JSON", @response.body
  end

940 941 942 943
  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 已提交
944 945
    assert_match(/"message":"boom"/, @response.body)
    assert_match(/"error":"RenderJsonTestException"/, @response.body)
946 947
  end

948 949 950 951 952 953 954
  def test_no_double_render_is_raised
    @request.accept = "text/html"
    assert_raise ActionView::MissingTemplate do
      get :using_resource
    end
  end

955
  def test_using_resource_with_status_and_location
956
    @request.accept = "text/html"
957
    post :using_resource_with_status_and_location
958 959
    assert @response.redirect?
    assert_equal "http://test.host/", @response.location
960 961 962 963 964 965

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

966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
  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

983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
  def test_using_invalid_resource_with_template
    errors = { :name => :invalid }
    Customer.any_instance.stubs(:errors).returns(errors)

    @request.accept = "text/xml"

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

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

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
  def test_using_options_with_template
    @request.accept = "text/xml"

    post :using_options_with_template
    assert_equal "<customer-name>david</customer-name>", @response.body
    assert_equal 123, @response.status
    assert_equal "http://test.host/", @response.location

    put :using_options_with_template
    assert_equal "<customer-name>david</customer-name>", @response.body
    assert_equal 123, @response.status
    assert_equal "http://test.host/", @response.location
  end

1014 1015
  def test_using_resource_with_responder
    get :using_resource_with_responder
1016
    assert_equal "Resource name is david", @response.body
1017 1018
  end

1019
  def test_using_resource_with_set_responder
1020 1021 1022 1023 1024 1025 1026
    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

1027 1028 1029 1030 1031 1032
  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
1033
  end
1034 1035 1036 1037

  private
    def with_test_route_set
      with_routing do |set|
1038
        set.draw do
J
Joshua Peek 已提交
1039 1040 1041 1042 1043
          resources :customers
          resources :quiz_stores do
            resources :customers
          end
          match ":controller/:action"
1044 1045 1046 1047
        end
        yield
      end
    end
1048 1049
end

1050
class AbstractPostController < ActionController::Base
1051
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
1052 1053 1054 1055 1056
end

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

1058
  def index
1059
    respond_to(:html, :iphone)
1060
  end
1061

1062 1063 1064 1065 1066 1067
protected

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

1070
class SuperPostController < PostController
1071 1072
end

1073 1074
class MimeControllerLayoutsTest < ActionController::TestCase
  tests PostController
1075

1076
  def setup
1077
    super
1078
    @request.host = "www.example.com"
1079 1080 1081 1082 1083
    Mime::Type.register_alias("text/html", :iphone)
  end

  def teardown
    super
J
José Valim 已提交
1084
    Mime::Type.unregister(:iphone)
1085
  end
1086

1087 1088
  def test_missing_layout_renders_properly
    get :index
1089
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
1090

1091
    @request.accept = "text/iphone"
1092 1093 1094
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
1095

1096 1097
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
1098

1099 1100
    get :index
    assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
1101

1102 1103 1104
    @request.accept = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
1105 1106
  end
end