mime_responds_test.rb 13.6 KB
Newer Older
1
require 'abstract_unit'
2 3

class RespondToController < ActionController::Base
4 5
  layout :set_layout

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

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

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

  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
37

38 39 40 41 42 43 44 45 46
  def forced_xml
    request.format = :xml

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

47 48 49 50 51
  def just_xml
    respond_to do |type|
      type.xml  { render :text => "XML" }
    end
  end
52

53 54 55 56 57 58 59
  def using_defaults
    respond_to do |type|
      type.html
      type.js
      type.xml
    end
  end
60

61 62 63
  def using_defaults_with_type_list
    respond_to(:html, :js, :xml)
  end
64

65 66 67 68 69 70 71 72
  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

73 74 75 76 77 78 79
  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
80

81 82 83 84 85 86 87
  def custom_constant_handling
    Mime::Type.register("text/x-mobile", :mobile)

    respond_to do |type|
      type.html   { render :text => "HTML"   }
      type.mobile { render :text => "Mobile" }
    end
88
  ensure
89
    Mime::SET.delete(:mobile)
90
    Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
91
  end
92

93 94 95 96 97 98 99
  def custom_constant_handling_without_block
    Mime::Type.register("text/x-mobile", :mobile)

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

101
  ensure
102
    Mime::SET.delete(:mobile)
103
    Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
104
  end
105

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

113 114 115 116 117 118
  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
119

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

  def iphone_with_html_response_type
128
    Mime::Type.register_alias("text/html", :iphone)
129
    request.format = :iphone if request.env["HTTP_ACCEPT"] == "text/iphone"
130

131 132
    respond_to do |type|
      type.html   { @type = "Firefox" }
133
      type.iphone { @type = "iPhone"  }
134 135
    end

136
  ensure
137
    Mime::SET.delete(:iphone)
138
    Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
139 140
  end

141 142 143
  def iphone_with_html_response_type_without_layout
    Mime::Type.register_alias("text/html", :iphone)
    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
144

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

150
  ensure
151
    Mime::SET.delete(:iphone)
152
    Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
153 154
  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

169 170 171
class MimeControllerTest < ActionController::TestCase
  tests RespondToController

172
  def setup
173
    super
174
    ActionController::Base.use_accept_header = true
175 176
    @request.host = "www.example.com"
  end
177

178
  def teardown
179
    super
180 181 182
    ActionController::Base.use_accept_header = false
  end

183
  def test_html
184
    @request.accept = "text/html"
185 186
    get :js_or_html
    assert_equal 'HTML', @response.body
187

188 189 190 191 192 193 194 195
    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_response 406
  end

  def test_all
196
    @request.accept = "*/*"
197 198 199 200 201 202 203 204 205 206 207
    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
208
    @request.accept = "application/xml"
209 210 211 212 213
    get :html_xml_or_rss
    assert_equal 'XML', @response.body
  end

  def test_js_or_html
214
    @request.accept = "text/javascript, text/html"
215 216 217 218 219 220 221 222 223
    get :js_or_html
    assert_equal 'JS', @response.body

    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_response 406
  end
224

225 226 227
  def test_json_or_yaml
    get :json_or_yaml
    assert_equal 'JSON', @response.body
228 229

    get :json_or_yaml, :format => 'json'
230
    assert_equal 'JSON', @response.body
231 232 233 234 235 236 237 238

    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|
239
        @request.accept = content_type
240 241 242 243
        get :json_or_yaml
        assert_equal body, @response.body
      end
    end
244
  end
245 246

  def test_js_or_anything
247
    @request.accept = "text/javascript, */*"
248 249 250 251 252 253 254 255 256
    get :js_or_html
    assert_equal 'JS', @response.body

    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_equal 'XML', @response.body
  end
257

258
  def test_using_defaults
259
    @request.accept = "*/*"
260
    get :using_defaults
261
    assert_equal "text/html", @response.content_type
262 263
    assert_equal 'Hello world!', @response.body

264
    @request.accept = "text/javascript"
265
    get :using_defaults
266
    assert_equal "text/javascript", @response.content_type
267
    assert_equal '$("body").visualEffect("highlight");', @response.body
268

269
    @request.accept = "application/xml"
270
    get :using_defaults
271
    assert_equal "application/xml", @response.content_type
272 273
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
274

275
  def test_using_defaults_with_type_list
276
    @request.accept = "*/*"
277
    get :using_defaults_with_type_list
278
    assert_equal "text/html", @response.content_type
279 280
    assert_equal 'Hello world!', @response.body

281
    @request.accept = "text/javascript"
282
    get :using_defaults_with_type_list
283
    assert_equal "text/javascript", @response.content_type
284 285
    assert_equal '$("body").visualEffect("highlight");', @response.body

286
    @request.accept = "application/xml"
287
    get :using_defaults_with_type_list
288
    assert_equal "application/xml", @response.content_type
289 290
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
291

292
  def test_with_atom_content_type
293 294 295
    @request.env["CONTENT_TYPE"] = "application/atom+xml"
    get :made_for_content_type
    assert_equal "ATOM", @response.body
296
  end
297

298
  def test_with_rss_content_type
299 300 301 302
    @request.env["CONTENT_TYPE"] = "application/rss+xml"
    get :made_for_content_type
    assert_equal "RSS", @response.body
  end
303

304
  def test_synonyms
305
    @request.accept = "application/javascript"
306 307 308
    get :js_or_html
    assert_equal 'JS', @response.body

309
    @request.accept = "application/x-xml"
310 311
    get :html_xml_or_rss
    assert_equal "XML", @response.body
312
  end
313

314
  def test_custom_types
315
    @request.accept = "application/crazy-xml"
316
    get :custom_type_handling
317
    assert_equal "application/crazy-xml", @response.content_type
318 319
    assert_equal 'Crazy XML', @response.body

320
    @request.accept = "text/html"
321
    get :custom_type_handling
322
    assert_equal "text/html", @response.content_type
323 324
    assert_equal 'HTML', @response.body
  end
325 326

  def test_xhtml_alias
327
    @request.accept = "application/xhtml+xml,application/xml"
328 329 330
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
331

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

  def test_handle_any
339
    @request.accept = "*/*"
340 341 342
    get :handle_any
    assert_equal 'HTML', @response.body

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

347
    @request.accept = "text/xml"
348 349 350
    get :handle_any
    assert_equal 'Either JS or XML', @response.body
  end
351

352
  def test_handle_any_any
353
    @request.accept = "*/*"
354 355 356
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end
357

358 359 360 361
  def test_handle_any_any_parameter_format
    get :handle_any_any, {:format=>'html'}
    assert_equal 'HTML', @response.body
  end
362

363
  def test_handle_any_any_explicit_html
364
    @request.accept = "text/html"
365 366 367 368 369
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end

  def test_handle_any_any_javascript
370
    @request.accept = "text/javascript"
371 372 373
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
374

375
  def test_handle_any_any_xml
376
    @request.accept = "text/xml"
377 378 379 380
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end

381
  def test_rjs_type_skips_layout
382 383 384
    @request.accept = "text/javascript"
    get :all_types_with_layout
    assert_equal 'RJS for all_types_with_layout', @response.body
385
  end
386

387
  def test_html_type_with_layout
388
    @request.accept = "text/html"
389
    get :all_types_with_layout
D
David Heinemeier Hansson 已提交
390
    assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
391
  end
392 393 394 395 396 397 398 399

  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
400

401 402
  def test_custom_constant
    get :custom_constant_handling, :format => "mobile"
403
    assert_equal "text/x-mobile", @response.content_type
404 405
    assert_equal "Mobile", @response.body
  end
406 407 408 409 410

  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
411
  end
412

413 414 415 416 417 418 419 420 421 422 423 424 425
  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
426

427 428 429 430 431 432 433 434
  def test_internally_forced_format
    get :forced_xml
    assert_equal "XML", @response.body

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

435 436 437 438
  def test_extension_synonyms
    get :html_xml_or_rss, :format => "xhtml"
    assert_equal "HTML", @response.body
  end
439 440 441 442

  def test_render_action_for_html
    @controller.instance_eval do
      def render(*args)
443 444 445
        @action = args.first[:action] unless args.empty?
        @action ||= action_name

446
        response.body = "#{@action} - #{@template.formats}"
447 448 449 450
      end
    end

    get :using_defaults
451
    assert_equal "using_defaults - #{[:html].to_s}", @response.body
452 453

    get :using_defaults, :format => "xml"
454
    assert_equal "using_defaults - #{[:xml].to_s}", @response.body
455 456
  end

457 458
  def test_format_with_custom_response_type
    get :iphone_with_html_response_type
459 460
    assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body

461 462
    get :iphone_with_html_response_type, :format => "iphone"
    assert_equal "text/html", @response.content_type
D
David Heinemeier Hansson 已提交
463
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
464 465
  end

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

474 475 476 477
class ClassRespondToController < ActionController::Base

end

478
class AbstractPostController < ActionController::Base
479 480
  respond_to :html, :iphone

481
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
482 483 484 485 486
end

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

488
  def index
489
    respond_to # It will use formats declared above
490
  end
491

492 493 494 495 496 497 498
protected

  def with_iphone
    Mime::Type.register_alias("text/html", :iphone)
    request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
    yield
  ensure
499
    Mime::SET.delete(:iphone)
500 501
    Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
  end
502
end
503

504
class SuperPostController < PostController
505 506
end

507 508
class MimeControllerLayoutsTest < ActionController::TestCase
  tests PostController
509

510
  def setup
511
    super
512 513
    @request.host = "www.example.com"
  end
514

515 516
  def test_missing_layout_renders_properly
    get :index
517
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
518

519
    @request.accept = "text/iphone"
520 521 522
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
523

524 525
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
526

527 528
    get :index
    assert_equal '<html><div id="html">Super Firefox</div></html>', @response.body
529

530 531 532
    @request.accept = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
533 534
  end
end