mime_responds_test.rb 30.7 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
  def using_defaults
    respond_to do |type|
      type.html
      type.xml
    end
  end
79

80
  def using_defaults_with_type_list
X
Xavier Noria 已提交
81
    respond_to(:html, :xml)
82
  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
  def all_types_with_layout
    respond_to do |type|
      type.html
    end
133 134
  end

135

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

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

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

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

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

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

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

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

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

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

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

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

    get :just_xml
    assert_response 406
  end

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

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

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

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

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

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

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

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

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

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

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

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

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

300
    @request.accept = "application/xml"
301
    get :using_defaults
302
    assert_equal "application/xml", @response.content_type
303 304
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
305

306
  def test_using_defaults_with_type_list
307
    @request.accept = "*/*"
308
    get :using_defaults_with_type_list
309
    assert_equal "text/html", @response.content_type
310 311
    assert_equal 'Hello world!', @response.body

312
    @request.accept = "application/xml"
313
    get :using_defaults_with_type_list
314
    assert_equal "application/xml", @response.content_type
315 316
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
317

318
  def test_with_atom_content_type
319
    @request.accept = ""
320
    @request.env["CONTENT_TYPE"] = "application/atom+xml"
321
    xhr :get, :made_for_content_type
322
    assert_equal "ATOM", @response.body
323
  end
324

325
  def test_with_rss_content_type
326
    @request.accept = ""
327
    @request.env["CONTENT_TYPE"] = "application/rss+xml"
328
    xhr :get, :made_for_content_type
329 330
    assert_equal "RSS", @response.body
  end
331

332
  def test_synonyms
333
    @request.accept = "application/javascript"
334 335 336
    get :js_or_html
    assert_equal 'JS', @response.body

337
    @request.accept = "application/x-xml"
338 339
    get :html_xml_or_rss
    assert_equal "XML", @response.body
340
  end
341

342
  def test_custom_types
343
    @request.accept = "application/crazy-xml"
344
    get :custom_type_handling
345
    assert_equal "application/crazy-xml", @response.content_type
346 347
    assert_equal 'Crazy XML', @response.body

348
    @request.accept = "text/html"
349
    get :custom_type_handling
350
    assert_equal "text/html", @response.content_type
351 352
    assert_equal 'HTML', @response.body
  end
353 354

  def test_xhtml_alias
355
    @request.accept = "application/xhtml+xml,application/xml"
356 357 358
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
359

360
  def test_firefox_simulation
361
    @request.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
362 363 364
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
365 366

  def test_handle_any
367
    @request.accept = "*/*"
368 369 370
    get :handle_any
    assert_equal 'HTML', @response.body

371
    @request.accept = "text/javascript"
372 373 374
    get :handle_any
    assert_equal 'Either JS or XML', @response.body

375
    @request.accept = "text/xml"
376 377 378
    get :handle_any
    assert_equal 'Either JS or XML', @response.body
  end
379

380
  def test_handle_any_any
381
    @request.accept = "*/*"
382 383 384
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end
385

386 387 388 389
  def test_handle_any_any_parameter_format
    get :handle_any_any, {:format=>'html'}
    assert_equal 'HTML', @response.body
  end
390

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

  def test_handle_any_any_javascript
398
    @request.accept = "text/javascript"
399 400 401
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
402

403
  def test_handle_any_any_xml
404
    @request.accept = "text/xml"
405 406 407
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
408

409 410 411 412
  def test_browser_check_with_any_any
    @request.accept = "application/json, application/xml"
    get :json_xml_or_html
    assert_equal 'JSON', @response.body
413

414 415 416 417
    @request.accept = "application/json, application/xml, */*"
    get :json_xml_or_html
    assert_equal 'HTML', @response.body
  end
418

419
  def test_html_type_with_layout
420
    @request.accept = "text/html"
421
    get :all_types_with_layout
D
David Heinemeier Hansson 已提交
422
    assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
423
  end
424 425 426 427 428

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

430 431
  def test_custom_constant
    get :custom_constant_handling, :format => "mobile"
432
    assert_equal "text/x-mobile", @response.content_type
433 434
    assert_equal "Mobile", @response.body
  end
435 436 437 438 439

  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
440
  end
441

442 443 444 445 446 447 448 449 450 451 452 453 454
  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
455

456 457 458 459 460 461 462 463
  def test_internally_forced_format
    get :forced_xml
    assert_equal "XML", @response.body

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

464 465 466 467
  def test_extension_synonyms
    get :html_xml_or_rss, :format => "xhtml"
    assert_equal "HTML", @response.body
  end
468 469 470 471

  def test_render_action_for_html
    @controller.instance_eval do
      def render(*args)
472 473 474
        @action = args.first[:action] unless args.empty?
        @action ||= action_name

J
José Valim 已提交
475
        response.body = "#{@action} - #{formats}"
476 477 478 479
      end
    end

    get :using_defaults
480
    assert_equal "using_defaults - #{[:html].to_s}", @response.body
481 482

    get :using_defaults, :format => "xml"
483
    assert_equal "using_defaults - #{[:xml].to_s}", @response.body
484 485
  end

486 487
  def test_format_with_custom_response_type
    get :iphone_with_html_response_type
488 489
    assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body

490 491
    get :iphone_with_html_response_type, :format => "iphone"
    assert_equal "text/html", @response.content_type
D
David Heinemeier Hansson 已提交
492
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
493 494
  end

495
  def test_format_with_custom_response_type_and_request_headers
496
    @request.accept = "text/iphone"
497
    get :iphone_with_html_response_type
D
David Heinemeier Hansson 已提交
498
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
499
    assert_equal "text/html", @response.content_type
500
  end
501 502 503 504 505 506
  
  def test_invalid_format
    get :using_defaults, :format => "invalidformat"
    assert_equal " ", @response.body
    assert_equal "text/html", @response.content_type
  end
507
end
508

509
class RespondWithController < ActionController::Base
J
José Valim 已提交
510
  respond_to :html, :json
511
  respond_to :xml, :except => :using_resource_with_block
512
  respond_to :js,  :only => [ :using_resource_with_block, :using_resource, :using_hash_resource ]
513

514 515
  def using_resource
    respond_with(resource)
516 517
  end

518 519 520 521
  def using_hash_resource
    respond_with({:result => resource})
  end

522 523 524 525
  def using_resource_with_block
    respond_with(resource) do |format|
      format.csv { render :text => "CSV" }
    end
526
  end
J
José Valim 已提交
527

528 529
  def using_resource_with_overwrite_block
    respond_with(resource) do |format|
J
José Valim 已提交
530 531 532 533
      format.html { render :text => "HTML" }
    end
  end

534
  def using_resource_with_collection
535
    respond_with([resource, Customer.new("jamis", 9)])
536 537
  end

J
José Valim 已提交
538
  def using_resource_with_parent
539
    respond_with(Quiz::Store.new("developer?", 11), Customer.new("david", 13))
540 541
  end

542
  def using_resource_with_status_and_location
543
    respond_with(resource, :location => "http://test.host/", :status => :created)
544 545
  end

546 547 548 549
  def using_invalid_resource_with_template
    respond_with(resource)
  end

550 551 552 553 554
  def using_options_with_template
    @customer = resource
    respond_with(@customer, :status => 123, :location => "http://test.host/")
  end

555
  def using_resource_with_responder
556
    responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
557
    respond_with(resource, :responder => responder)
558 559
  end

560
  def using_resource_with_action
561
    respond_with(resource, :action => :foo) do |format|
562
      format.html { raise ActionView::MissingTemplate.new([], "bar", ["foo"], {}, false) }
563 564 565
    end
  end

566 567 568 569
  def using_responder_with_respond
    responder = Class.new(ActionController::Responder) do
      def respond; @controller.render :text => "respond #{format}"; end
    end
570
    respond_with(resource, :responder => responder)
571 572
  end

J
José Valim 已提交
573 574
protected

575
  def resource
576
    Customer.new("david", request.delete? ? nil : 13)
577
  end
578 579
end

580 581 582 583 584
class InheritedRespondWithController < RespondWithController
  clear_respond_to
  respond_to :xml, :json

  def index
585
    respond_with(resource) do |format|
586 587 588 589 590
      format.json { render :text => "JSON" }
    end
  end
end

591 592 593 594 595 596 597 598 599 600 601
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

602 603 604 605 606 607
class EmptyRespondWithController < ActionController::Base
  def index
    respond_with(Customer.new("david", 13))
  end
end

608 609 610 611 612 613
class RespondWithControllerTest < ActionController::TestCase
  tests RespondWithController

  def setup
    super
    @request.host = "www.example.com"
J
José Valim 已提交
614 615
    Mime::Type.register_alias('text/html', :iphone)
    Mime::Type.register('text/x-mobile', :mobile)
616 617 618 619
  end

  def teardown
    super
J
José Valim 已提交
620 621
    Mime::Type.unregister(:iphone)
    Mime::Type.unregister(:mobile)
622 623
  end

624 625 626 627 628 629 630 631 632 633 634 635
  def test_using_resource
    @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

636 637 638 639 640 641 642 643 644 645 646 647 648 649
  def test_using_resource_with_js_simply_tries_to_render_the_template
    @request.accept = "text/javascript"
    get :using_resource
    assert_equal "text/javascript", @response.content_type
    assert_equal "alert(\"Hi\");", @response.body
  end

  def test_using_hash_resource_with_js_raises_an_error_if_template_cant_be_found
    @request.accept = "text/javascript"
    assert_raise ActionView::MissingTemplate do
      get :using_hash_resource
    end
  end

650 651 652 653 654 655 656 657 658
  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 已提交
659
    assert_equal %Q[{"result":{"name":"david","id":13}}], @response.body
660 661
  end

662 663 664 665 666 667 668
  def test_using_hash_resource_with_post
    @request.accept = "application/json"
    assert_raise ArgumentError, "Nil location provided. Can't build URI." do
      post :using_hash_resource
    end
  end

669
  def test_using_resource_with_block
670
    @request.accept = "*/*"
671
    get :using_resource_with_block
672 673 674 675
    assert_equal "text/html", @response.content_type
    assert_equal 'Hello world!', @response.body

    @request.accept = "text/csv"
676
    get :using_resource_with_block
677 678 679 680
    assert_equal "text/csv", @response.content_type
    assert_equal "CSV", @response.body

    @request.accept = "application/xml"
681
    get :using_resource
682
    assert_equal "application/xml", @response.content_type
683
    assert_equal "<name>david</name>", @response.body
684 685
  end

686 687
  def test_using_resource_with_overwrite_block
    get :using_resource_with_overwrite_block
J
José Valim 已提交
688 689 690 691
    assert_equal "text/html", @response.content_type
    assert_equal "HTML", @response.body
  end

692
  def test_not_acceptable
J
José Valim 已提交
693
    @request.accept = "application/xml"
694 695
    get :using_resource_with_block
    assert_equal 406, @response.status
J
José Valim 已提交
696

697 698 699
    @request.accept = "text/javascript"
    get :using_resource_with_overwrite_block
    assert_equal 406, @response.status
J
José Valim 已提交
700 701
  end

702
  def test_using_resource_for_post_with_html_redirects_on_success
703 704 705 706 707 708
    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?
709 710
    end
  end
711

712 713
  def test_using_resource_for_post_with_html_rerender_on_failure
    with_test_route_set do
714 715 716 717 718 719 720 721
      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
722 723
  end

724
  def test_using_resource_for_post_with_xml_yields_created_on_success
725 726 727 728 729 730 731
    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
732 733
    end
  end
734

735 736 737
  def test_using_resource_for_post_with_xml_yields_unprocessable_entity_on_failure
    with_test_route_set do
      @request.accept = "application/xml"
738 739 740 741 742 743 744 745
      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
746 747
  end

748
  def test_using_resource_for_put_with_html_redirects_on_success
749 750 751 752 753 754
    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?
755 756
    end
  end
757

758 759
  def test_using_resource_for_put_with_html_rerender_on_failure
    with_test_route_set do
760 761 762 763 764 765 766 767
      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
768 769
  end

770 771 772 773 774 775 776 777 778 779 780 781 782
  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

783
  def test_using_resource_for_put_with_xml_yields_ok_on_success
784 785 786 787 788
    @request.accept = "application/xml"
    put :using_resource
    assert_equal "application/xml", @response.content_type
    assert_equal 200, @response.status
    assert_equal " ", @response.body
789
  end
790

791 792 793 794 795 796 797 798 799
  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

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

811
  def test_using_resource_for_delete_with_html_redirects_on_success
812 813 814 815 816 817 818
    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
819 820
  end

821
  def test_using_resource_for_delete_with_xml_yields_ok_on_success
822
    Customer.any_instance.stubs(:destroyed?).returns(true)
823 824 825 826 827
    @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 已提交
828 829
  end

830 831 832 833 834 835 836 837 838 839
  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

840 841 842 843 844 845 846 847
  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
848
      assert_equal "http://www.example.com/customers", @response.location
849 850 851
    end
  end

852 853 854 855 856
  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
857
    assert_equal "<name>david</name>", @response.body
858 859 860
  end

  def test_using_resource_with_parent_for_post
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
    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
878 879
  end

880 881 882 883 884
  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
885 886
    assert_match(/<name>david<\/name>/, @response.body)
    assert_match(/<name>jamis<\/name>/, @response.body)
887 888
  end

889 890 891 892 893 894 895 896 897 898 899
  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
900
    assert_equal "foo - #{[:html].to_s}", @controller.response.body
901 902
  end

903 904 905 906 907 908 909 910 911 912
  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

913 914 915 916 917 918 919 920 921 922 923 924
  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
925
    assert_equal "<name>david</name>", @response.body
926 927
  end

928 929 930 931 932 933 934
  def test_block_inside_respond_with_is_rendered
    @controller = InheritedRespondWithController.new
    @request.accept = "application/json"
    get :index
    assert_equal "JSON", @response.body
  end

935 936 937 938
  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 已提交
939 940
    assert_match(/"message":"boom"/, @response.body)
    assert_match(/"error":"RenderJsonTestException"/, @response.body)
941 942
  end

943 944 945 946 947 948 949
  def test_no_double_render_is_raised
    @request.accept = "text/html"
    assert_raise ActionView::MissingTemplate do
      get :using_resource
    end
  end

950
  def test_using_resource_with_status_and_location
951
    @request.accept = "text/html"
952
    post :using_resource_with_status_and_location
953 954
    assert @response.redirect?
    assert_equal "http://test.host/", @response.location
955 956 957 958 959 960

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

961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977
  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

978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
  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

995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
  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

1009 1010
  def test_using_resource_with_responder
    get :using_resource_with_responder
1011
    assert_equal "Resource name is david", @response.body
1012 1013
  end

1014
  def test_using_resource_with_set_responder
1015 1016 1017 1018 1019 1020 1021
    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

1022 1023 1024 1025 1026 1027
  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
1028
  end
1029 1030 1031 1032

  private
    def with_test_route_set
      with_routing do |set|
1033
        set.draw do
J
Joshua Peek 已提交
1034 1035 1036 1037 1038
          resources :customers
          resources :quiz_stores do
            resources :customers
          end
          match ":controller/:action"
1039 1040 1041 1042
        end
        yield
      end
    end
1043 1044
end

1045
class AbstractPostController < ActionController::Base
1046
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
1047 1048 1049 1050 1051
end

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

1053
  def index
1054
    respond_to(:html, :iphone)
1055
  end
1056

1057 1058 1059 1060 1061 1062
protected

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

1065
class SuperPostController < PostController
1066 1067
end

1068 1069
class MimeControllerLayoutsTest < ActionController::TestCase
  tests PostController
1070

1071
  def setup
1072
    super
1073
    @request.host = "www.example.com"
1074 1075 1076 1077 1078
    Mime::Type.register_alias("text/html", :iphone)
  end

  def teardown
    super
J
José Valim 已提交
1079
    Mime::Type.unregister(:iphone)
1080
  end
1081

1082 1083
  def test_missing_layout_renders_properly
    get :index
1084
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
1085

1086
    @request.accept = "text/iphone"
1087 1088 1089
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
1090

1091 1092
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
1093

1094 1095
    get :index
    assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
1096

1097 1098 1099
    @request.accept = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
1100 1101
  end
end