mime_responds_test.rb 14.4 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 89
  ensure
    Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
90
  end
91

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

100 101
  ensure
    Mime.module_eval { remove_const :MOBILE if const_defined?(:MOBILE) }
102
  end
103

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

111 112 113 114 115 116
  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
117

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

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

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

134 135
  ensure
    Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
136 137
  end

138 139 140
  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"
141

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

147 148
  ensure
    Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
149 150
  end

151
  def rescue_action(e)
J
Jamis Buck 已提交
152
    raise
153
  end
154

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

class MimeControllerTest < Test::Unit::TestCase
  def setup
167
    ActionController::Base.use_accept_header = true
168 169 170 171 172 173
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new

    @controller = RespondToController.new
    @request.host = "www.example.com"
  end
174

175 176 177 178
  def teardown
    ActionController::Base.use_accept_header = false
  end

179 180 181 182
  def test_html
    @request.env["HTTP_ACCEPT"] = "text/html"
    get :js_or_html
    assert_equal 'HTML', @response.body
183

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    get :html_or_xml
    assert_equal 'HTML', @response.body

    get :just_xml
    assert_response 406
  end

  def test_all
    @request.env["HTTP_ACCEPT"] = "*/*"
    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
    @request.env["HTTP_ACCEPT"] = "application/xml"
    get :html_xml_or_rss
    assert_equal 'XML', @response.body
  end

  def test_js_or_html
210
    @request.env["HTTP_ACCEPT"] = "text/javascript, text/html"
211 212 213 214 215 216 217 218 219
    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
220

221 222 223
  def test_json_or_yaml
    get :json_or_yaml
    assert_equal 'JSON', @response.body
224 225

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

    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|
        @request.env['HTTP_ACCEPT'] = content_type
        get :json_or_yaml
        assert_equal body, @response.body
      end
    end
240
  end
241 242

  def test_js_or_anything
243
    @request.env["HTTP_ACCEPT"] = "text/javascript, */*"
244 245 246 247 248 249 250 251 252
    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
253

254 255 256
  def test_using_defaults
    @request.env["HTTP_ACCEPT"] = "*/*"
    get :using_defaults
257
    assert_equal "text/html", @response.content_type
258 259 260 261
    assert_equal 'Hello world!', @response.body

    @request.env["HTTP_ACCEPT"] = "text/javascript"
    get :using_defaults
262
    assert_equal "text/javascript", @response.content_type
263
    assert_equal '$("body").visualEffect("highlight");', @response.body
264 265 266

    @request.env["HTTP_ACCEPT"] = "application/xml"
    get :using_defaults
267
    assert_equal "application/xml", @response.content_type
268 269
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
270

271 272 273
  def test_using_defaults_with_type_list
    @request.env["HTTP_ACCEPT"] = "*/*"
    get :using_defaults_with_type_list
274
    assert_equal "text/html", @response.content_type
275 276 277 278
    assert_equal 'Hello world!', @response.body

    @request.env["HTTP_ACCEPT"] = "text/javascript"
    get :using_defaults_with_type_list
279
    assert_equal "text/javascript", @response.content_type
280 281 282 283
    assert_equal '$("body").visualEffect("highlight");', @response.body

    @request.env["HTTP_ACCEPT"] = "application/xml"
    get :using_defaults_with_type_list
284
    assert_equal "application/xml", @response.content_type
285 286
    assert_equal "<p>Hello world!</p>\n", @response.body
  end
287

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

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

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

    @request.env["HTTP_ACCEPT"] = "application/x-xml"
306 307
    get :html_xml_or_rss
    assert_equal "XML", @response.body
308
  end
309

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

    @request.env["HTTP_ACCEPT"] = "text/html"
    get :custom_type_handling
318
    assert_equal "text/html", @response.content_type
319 320
    assert_equal 'HTML', @response.body
  end
321 322 323 324 325 326

  def test_xhtml_alias
    @request.env["HTTP_ACCEPT"] = "application/xhtml+xml,application/xml"
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
327

328 329 330 331 332
  def test_firefox_simulation
    @request.env["HTTP_ACCEPT"] = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
    get :html_or_xml
    assert_equal 'HTML', @response.body
  end
333 334 335 336 337 338 339 340 341 342 343 344 345 346

  def test_handle_any
    @request.env["HTTP_ACCEPT"] = "*/*"
    get :handle_any
    assert_equal 'HTML', @response.body

    @request.env["HTTP_ACCEPT"] = "text/javascript"
    get :handle_any
    assert_equal 'Either JS or XML', @response.body

    @request.env["HTTP_ACCEPT"] = "text/xml"
    get :handle_any
    assert_equal 'Either JS or XML', @response.body
  end
347

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

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

359 360 361 362 363 364 365 366 367 368 369
  def test_handle_any_any_explicit_html
    @request.env["HTTP_ACCEPT"] = "text/html"
    get :handle_any_any
    assert_equal 'HTML', @response.body
  end

  def test_handle_any_any_javascript
    @request.env["HTTP_ACCEPT"] = "text/javascript"
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end
370

371 372 373 374 375 376
  def test_handle_any_any_xml
    @request.env["HTTP_ACCEPT"] = "text/xml"
    get :handle_any_any
    assert_equal 'Whatever you ask for, I got it', @response.body
  end

377
  def test_rjs_type_skips_layout
378 379 380
    @request.env["HTTP_ACCEPT"] = "text/javascript"
    get :all_types_with_layout
    assert_equal 'RJS for all_types_with_layout', @response.body
381
  end
382

383
  def test_html_type_with_layout
384 385
    @request.env["HTTP_ACCEPT"] = "text/html"
    get :all_types_with_layout
D
David Heinemeier Hansson 已提交
386
    assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
387
  end
388 389 390 391 392 393 394 395

  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
396

397 398
  def test_custom_constant
    get :custom_constant_handling, :format => "mobile"
399
    assert_equal "text/x-mobile", @response.content_type
400 401
    assert_equal "Mobile", @response.body
  end
402 403 404 405 406

  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
407
  end
408

409 410 411 412 413 414 415 416 417 418 419 420 421
  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
422

423 424 425 426 427 428 429 430
  def test_internally_forced_format
    get :forced_xml
    assert_equal "XML", @response.body

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

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

  def test_render_action_for_html
    @controller.instance_eval do
      def render(*args)
        unless args.empty?
          @action = args.first[:action]
        end
442
        response.body = "#{@action} - #{@template.template_format}"
443 444 445 446
      end
    end

    get :using_defaults
447
    assert_equal "using_defaults - html", @response.body
448 449

    get :using_defaults, :format => "xml"
450
    assert_equal "using_defaults - xml", @response.body
451 452
  end

453 454
  def test_format_with_custom_response_type
    get :iphone_with_html_response_type
455 456
    assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body

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

462 463 464
  def test_format_with_custom_response_type_and_request_headers
    @request.env["HTTP_ACCEPT"] = "text/iphone"
    get :iphone_with_html_response_type
D
David Heinemeier Hansson 已提交
465
    assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
466
    assert_equal "text/html", @response.content_type
467
  end
468 469 470

  def test_format_with_custom_response_type_and_request_headers_with_only_one_layout_present
    get :iphone_with_html_response_type_without_layout
471
    assert_equal '<html><div id="html_missing">Hello future from Firefox!</div></html>', @response.body
472 473

    @request.env["HTTP_ACCEPT"] = "text/iphone"
474
    assert_raises(ActionView::MissingTemplate) { get :iphone_with_html_response_type_without_layout }
475
  end
476
end
477 478

class AbstractPostController < ActionController::Base
479
  self.view_paths = File.dirname(__FILE__) + "/../fixtures/post_test/"
480 481 482 483 484
end

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

486 487 488 489 490 491
  def index
    respond_to do |type|
      type.html
      type.iphone
    end
  end
492

493
  protected
494 495 496 497 498 499 500 501
    def with_iphone
      Mime::Type.register_alias("text/html", :iphone)
      request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone"
      yield
    ensure
      Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) }
    end
end
502

503
class SuperPostController < PostController
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
  def index
    respond_to do |type|
      type.html
      type.iphone
    end
  end
end

class MimeControllerLayoutsTest < Test::Unit::TestCase
  def setup
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new

    @controller   = PostController.new
    @request.host = "www.example.com"
  end
520

521 522
  def test_missing_layout_renders_properly
    get :index
523
    assert_equal '<html><div id="html">Hello Firefox</div></html>', @response.body
524 525 526 527 528

    @request.env["HTTP_ACCEPT"] = "text/iphone"
    get :index
    assert_equal 'Hello iPhone', @response.body
  end
529

530 531
  def test_format_with_inherited_layouts
    @controller = SuperPostController.new
532

533 534
    get :index
    assert_equal 'Super Firefox', @response.body
535

536 537 538 539 540
    @request.env["HTTP_ACCEPT"] = "text/iphone"
    get :index
    assert_equal '<html><div id="super_iphone">Super iPhone</div></html>', @response.body
  end
end