render_test.rb 21.0 KB
Newer Older
1
require 'abstract_unit'
2
require 'controller/fake_models'
D
Initial  
David Heinemeier Hansson 已提交
3

4 5 6 7 8 9 10 11
class TestControllerWithExtraEtags < ActionController::Base
  etag { nil  }
  etag { 'ab' }
  etag { :cde }
  etag { [:f] }
  etag { nil  }

  def fresh
12
    render plain: "stale" if stale?(etag: '123', template: false)
13
  end
14 15

  def array
16
    render plain: "stale" if stale?(etag: %w(1 2 3), template: false)
17 18
  end

J
Jeremy Daer 已提交
19 20 21 22
  def strong
    render plain: "stale" if stale?(strong_etag: 'strong')
  end

23 24
  def with_template
    if stale? template: 'test/hello_world'
25
      render plain: 'stale'
26
    end
27
  end
28 29
end

30 31 32
class ImplicitRenderTestController < ActionController::Base
  def empty_action
  end
33 34 35

  def empty_action_with_template
  end
36 37
end

38
class TestController < ActionController::Base
P
Pratik Naik 已提交
39 40
  protect_from_forgery

41
  before_action :set_variable_for_layout
L
lest 已提交
42

J
Joshua Peek 已提交
43 44 45
  class LabellingFormBuilder < ActionView::Helpers::FormBuilder
  end

46
  layout :determine_layout
D
Initial  
David Heinemeier Hansson 已提交
47

48 49 50 51 52 53 54
  def name
    nil
  end

  private :name
  helper_method :name

55 56
  def hello_world
  end
D
Initial  
David Heinemeier Hansson 已提交
57

58
  def conditional_hello
59
    if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123])
60 61
      render :action => 'hello_world'
    end
62
  end
J
Joshua Peek 已提交
63

64
  def conditional_hello_with_record
65
    record = Struct.new(:updated_at, :cache_key).new(Time.now.utc.beginning_of_day, "foo/123")
66

67
    if stale?(record)
Ł
Łukasz Strzałkowski 已提交
68
      render :action => 'hello_world'
J
Joshua Peek 已提交
69 70 71
    end
  end

72
  def dynamic_render
A
Akira Matsuda 已提交
73
    render params[:id] # => String, AC::Params
74 75
  end

76 77 78 79
  def dynamic_render_permit
    render params[:id].permit(:file)
  end

80 81
  def dynamic_render_with_file
    # This is extremely bad, but should be possible to do.
A
Akira Matsuda 已提交
82
    file = params[:id] # => String, AC::Params
83 84 85
    render file: file
  end

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  class Collection
    def initialize(records)
      @records = records
    end

    def maximum(attribute)
      @records.max_by(&attribute).public_send(attribute)
    end
  end

  def conditional_hello_with_collection_of_records
    ts = Time.now.utc.beginning_of_day

    record = Struct.new(:updated_at, :cache_key).new(ts, "foo/123")
    old_record = Struct.new(:updated_at, :cache_key).new(ts - 1.day, "bar/123")

    if stale?(Collection.new([record, old_record]))
      render action: 'hello_world'
    end
  end

Ł
Łukasz Strzałkowski 已提交
107 108 109
  def conditional_hello_with_expires_in
    expires_in 60.1.seconds
    render :action => 'hello_world'
J
Joshua Peek 已提交
110 111
  end

Ł
Łukasz Strzałkowski 已提交
112 113 114
  def conditional_hello_with_expires_in_with_public
    expires_in 1.minute, :public => true
    render :action => 'hello_world'
J
Joshua Peek 已提交
115 116
  end

Ł
Łukasz Strzałkowski 已提交
117 118 119
  def conditional_hello_with_expires_in_with_must_revalidate
    expires_in 1.minute, :must_revalidate => true
    render :action => 'hello_world'
120 121
  end

Ł
Łukasz Strzałkowski 已提交
122 123 124
  def conditional_hello_with_expires_in_with_public_and_must_revalidate
    expires_in 1.minute, :public => true, :must_revalidate => true
    render :action => 'hello_world'
125 126
  end

Ł
Łukasz Strzałkowski 已提交
127 128 129
  def conditional_hello_with_expires_in_with_public_with_more_keys
    expires_in 1.minute, :public => true, 's-maxage' => 5.hours
    render :action => 'hello_world'
130 131
  end

Ł
Łukasz Strzałkowski 已提交
132 133 134
  def conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
    expires_in 1.minute, :public => true, :private => nil, 's-maxage' => 5.hours
    render :action => 'hello_world'
J
Joshua Peek 已提交
135 136
  end

Ł
Łukasz Strzałkowski 已提交
137 138 139
  def conditional_hello_with_expires_now
    expires_now
    render :action => 'hello_world'
140 141
  end

Ł
Łukasz Strzałkowski 已提交
142 143 144 145
  def conditional_hello_with_cache_control_headers
    response.headers['Cache-Control'] = 'no-transform'
    expires_now
    render :action => 'hello_world'
146 147
  end

148 149 150 151
  def respond_with_empty_body
    render nothing: true
  end

Ł
Łukasz Strzałkowski 已提交
152 153
  def conditional_hello_with_bangs
    render :action => 'hello_world'
154
  end
Ł
Łukasz Strzałkowski 已提交
155
  before_action :handle_last_modified_and_etags, :only=>:conditional_hello_with_bangs
156

Ł
Łukasz Strzałkowski 已提交
157 158
  def handle_last_modified_and_etags
    fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ])
J
Joshua Peek 已提交
159 160
  end

161 162 163 164 165 166 167 168
  def head_with_status_hash
    head status: :created
  end

  def head_with_hash_does_not_include_status
    head warning: :deprecated
  end

Ł
Łukasz Strzałkowski 已提交
169 170
  def head_created
    head :created
J
Joshua Peek 已提交
171 172
  end

Ł
Łukasz Strzałkowski 已提交
173 174
  def head_created_with_application_json_content_type
    head :created, :content_type => "application/json"
175 176
  end

Ł
Łukasz Strzałkowski 已提交
177 178
  def head_ok_with_image_png_content_type
    head :ok, :content_type => "image/png"
J
Joshua Peek 已提交
179 180
  end

Ł
Łukasz Strzałkowski 已提交
181
  def head_with_location_header
182
    head :ok, :location => "/foo"
183 184
  end

Ł
Łukasz Strzałkowski 已提交
185
  def head_with_location_object
186
    head :ok, :location => Customer.new("david", 1)
J
Joshua Peek 已提交
187 188
  end

Ł
Łukasz Strzałkowski 已提交
189
  def head_with_symbolic_status
190
    head params[:status].intern
J
Joshua Peek 已提交
191 192
  end

Ł
Łukasz Strzałkowski 已提交
193
  def head_with_integer_status
194
    head params[:status].to_i
J
Joshua Peek 已提交
195 196
  end

Ł
Łukasz Strzałkowski 已提交
197
  def head_with_string_status
198
    head params[:status]
J
Joshua Peek 已提交
199 200
  end

Ł
Łukasz Strzałkowski 已提交
201
  def head_with_custom_header
202
    head :ok, :x_custom_header => "something"
203 204
  end

Ł
Łukasz Strzałkowski 已提交
205
  def head_with_www_authenticate_header
206
    head :ok, 'WWW-Authenticate' => 'something'
207 208
  end

Ł
Łukasz Strzałkowski 已提交
209 210
  def head_with_status_code_first
    head :forbidden, :x_custom_header => "something"
J
Joshua Peek 已提交
211 212
  end

J
Joel Hayhurst 已提交
213 214 215 216 217
  def head_and_return
    head :ok and return
    raise 'should not reach this line'
  end

218 219 220 221 222 223 224 225 226
  def head_with_no_content
    # Fill in the headers with dummy data to make
    # sure they get removed during the testing
    response.headers["Content-Type"] = "dummy"
    response.headers["Content-Length"] = 42

    head 204
  end

Ł
Łukasz Strzałkowski 已提交
227
  private
J
Joshua Peek 已提交
228

Ł
Łukasz Strzałkowski 已提交
229 230
    def set_variable_for_layout
      @variable_for_layout = nil
J
Joshua Peek 已提交
231 232
    end

Ł
Łukasz Strzałkowski 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
    def determine_layout
      case action_name
        when "hello_world", "layout_test", "rendering_without_layout",
             "rendering_nothing_on_layout", "render_text_hello_world",
             "render_text_hello_world_with_layout",
             "hello_world_with_layout_false",
             "partial_only", "accessing_params_in_template",
             "accessing_params_in_template_with_layout",
             "render_with_explicit_template",
             "render_with_explicit_string_template",
             "update_page", "update_page_with_instance_variables"

          "layouts/standard"
        when "action_talk_to_layout", "layout_overriding_layout"
          "layouts/talk_from_action"
        when "render_implicit_html_template_from_xhr_request"
          (request.xhr? ? 'layouts/xhr' : 'layouts/standard')
      end
    end
end

class MetalTestController < ActionController::Metal
  include AbstractController::Rendering
  include ActionView::Rendering
  include ActionController::Rendering
J
Joshua Peek 已提交
258

Ł
Łukasz Strzałkowski 已提交
259 260
  def accessing_logger_in_template
    render :inline =>  "<%= logger.class %>"
261
  end
262 263
end

264 265 266
class ExpiresInRenderTest < ActionController::TestCase
  tests TestController

267 268 269 270 271
  def setup
    super
    ActionController::Base.view_paths.paths.each(&:clear_cache)
  end

272 273 274 275 276 277 278 279
  def test_dynamic_render_with_file
    # This is extremely bad, but should be possible to do.
    assert File.exist?(File.join(File.dirname(__FILE__), '../../test/abstract_unit.rb'))
    response = get :dynamic_render_with_file, params: { id: '../\\../test/abstract_unit.rb' }
    assert_equal File.read(File.join(File.dirname(__FILE__), '../../test/abstract_unit.rb')),
      response.body
  end

280
  def test_dynamic_render_with_absolute_path
281
    file = Tempfile.new('name')
282 283 284
    file.write "secrets!"
    file.flush
    assert_raises ActionView::MissingTemplate do
285
      get :dynamic_render, params: { id: file.path }
286 287
    end
  ensure
288
    file.close
289 290 291
    file.unlink
  end

292 293 294 295 296 297 298
  def test_dynamic_render
    assert File.exist?(File.join(File.dirname(__FILE__), '../../test/abstract_unit.rb'))
    assert_raises ActionView::MissingTemplate do
      get :dynamic_render, params: { id: '../\\../test/abstract_unit.rb' }
    end
  end

299
  def test_permitted_dynamic_render_file_hash
A
Aaron Patterson 已提交
300
    skip "FIXME: this test passes on 4-2-stable but not master. Why?"
301
    assert File.exist?(File.join(File.dirname(__FILE__), '../../test/abstract_unit.rb'))
A
Aaron Patterson 已提交
302
    response = get :dynamic_render_permit, params: { id: { file: '../\\../test/abstract_unit.rb' } }
303 304 305 306
    assert_equal File.read(File.join(File.dirname(__FILE__), '../../test/abstract_unit.rb')),
      response.body
  end

307 308 309 310 311 312
  def test_dynamic_render_file_hash
    assert_raises ArgumentError do
      get :dynamic_render, params: { id: { file: '../\\../test/abstract_unit.rb' } }
    end
  end

313 314 315 316
  def test_expires_in_header
    get :conditional_hello_with_expires_in
    assert_equal "max-age=60, private", @response.headers["Cache-Control"]
  end
J
Joshua Peek 已提交
317

318
  def test_expires_in_header_with_public
319 320 321
    get :conditional_hello_with_expires_in_with_public
    assert_equal "max-age=60, public", @response.headers["Cache-Control"]
  end
J
Joshua Peek 已提交
322

323 324 325 326 327 328 329 330 331 332
  def test_expires_in_header_with_must_revalidate
    get :conditional_hello_with_expires_in_with_must_revalidate
    assert_equal "max-age=60, private, must-revalidate", @response.headers["Cache-Control"]
  end

  def test_expires_in_header_with_public_and_must_revalidate
    get :conditional_hello_with_expires_in_with_public_and_must_revalidate
    assert_equal "max-age=60, public, must-revalidate", @response.headers["Cache-Control"]
  end

333 334
  def test_expires_in_header_with_additional_headers
    get :conditional_hello_with_expires_in_with_public_with_more_keys
335
    assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"]
336
  end
J
Joshua Peek 已提交
337

338 339
  def test_expires_in_old_syntax
    get :conditional_hello_with_expires_in_with_public_with_more_keys_old_syntax
340
    assert_equal "max-age=60, public, s-maxage=18000", @response.headers["Cache-Control"]
341
  end
342 343 344 345 346

  def test_expires_now
    get :conditional_hello_with_expires_now
    assert_equal "no-cache", @response.headers["Cache-Control"]
  end
347

A
Arun Agrawal 已提交
348
  def test_expires_now_with_cache_control_headers
349
    get :conditional_hello_with_cache_control_headers
A
Arun Agrawal 已提交
350 351
    assert_match(/no-cache/, @response.headers["Cache-Control"])
    assert_match(/no-transform/, @response.headers["Cache-Control"])
352 353
  end

354 355 356 357 358 359
  def test_render_nothing_deprecated
    assert_deprecated do
      get :respond_with_empty_body
    end
  end

360 361
  def test_date_header_when_expires_in
    time = Time.mktime(2011,10,30)
362 363 364 365
    Time.stub :now, time do
      get :conditional_hello_with_expires_in
      assert_equal Time.now.httpdate, @response.headers["Date"]
    end
366
  end
367 368
end

369 370
class LastModifiedRenderTest < ActionController::TestCase
  tests TestController
371

372
  def setup
373
    super
374
    @last_modified = Time.now.utc.beginning_of_day.httpdate
375 376
  end

377 378 379
  def test_responds_with_last_modified
    get :conditional_hello
    assert_equal @last_modified, @response.headers['Last-Modified']
380 381
  end

382
  def test_request_not_modified
383
    @request.if_modified_since = @last_modified
384
    get :conditional_hello
385
    assert_equal 304, @response.status.to_i
386
    assert @response.body.blank?
387
    assert_equal @last_modified, @response.headers['Last-Modified']
388 389
  end

390 391
  def test_request_not_modified_but_etag_differs
    @request.if_modified_since = @last_modified
J
Jeremy Daer 已提交
392
    @request.if_none_match = '"234"'
393 394 395 396
    get :conditional_hello
    assert_response :success
  end

397
  def test_request_modified
398
    @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
399
    get :conditional_hello
400
    assert_equal 200, @response.status.to_i
401
    assert @response.body.present?
402
    assert_equal @last_modified, @response.headers['Last-Modified']
403
  end
404

405 406 407 408 409 410 411 412 413
  def test_responds_with_last_modified_with_record
    get :conditional_hello_with_record
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

  def test_request_not_modified_with_record
    @request.if_modified_since = @last_modified
    get :conditional_hello_with_record
    assert_equal 304, @response.status.to_i
414
    assert @response.body.blank?
C
claudiob 已提交
415
    assert_not_nil @response.etag
416 417 418 419 420
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

  def test_request_not_modified_but_etag_differs_with_record
    @request.if_modified_since = @last_modified
J
Jeremy Daer 已提交
421
    @request.if_none_match = '"234"'
422 423 424 425 426 427 428 429
    get :conditional_hello_with_record
    assert_response :success
  end

  def test_request_modified_with_record
    @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
    get :conditional_hello_with_record
    assert_equal 200, @response.status.to_i
430
    assert @response.body.present?
431 432 433
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
  def test_responds_with_last_modified_with_collection_of_records
    get :conditional_hello_with_collection_of_records
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

  def test_request_not_modified_with_collection_of_records
    @request.if_modified_since = @last_modified
    get :conditional_hello_with_collection_of_records
    assert_equal 304, @response.status.to_i
    assert @response.body.blank?
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

  def test_request_not_modified_but_etag_differs_with_collection_of_records
    @request.if_modified_since = @last_modified
J
Jeremy Daer 已提交
449
    @request.if_none_match = '"234"'
450 451 452 453 454 455 456 457 458 459 460 461
    get :conditional_hello_with_collection_of_records
    assert_response :success
  end

  def test_request_modified_with_collection_of_records
    @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
    get :conditional_hello_with_collection_of_records
    assert_equal 200, @response.status.to_i
    assert @response.body.present?
    assert_equal @last_modified, @response.headers['Last-Modified']
  end

462 463 464 465 466
  def test_request_with_bang_gets_last_modified
    get :conditional_hello_with_bangs
    assert_equal @last_modified, @response.headers['Last-Modified']
    assert_response :success
  end
467

468 469 470 471 472
  def test_request_with_bang_obeys_last_modified
    @request.if_modified_since = @last_modified
    get :conditional_hello_with_bangs
    assert_response :not_modified
  end
473 474 475 476

  def test_last_modified_works_with_less_than_too
    @request.if_modified_since = 5.years.ago.httpdate
    get :conditional_hello_with_bangs
477
    assert_response :success
478
  end
479
end
480

481 482 483
class EtagRenderTest < ActionController::TestCase
  tests TestControllerWithExtraEtags

J
Jeremy Daer 已提交
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
  def test_strong_etag
    @request.if_none_match = strong_etag(['strong', 'ab', :cde, [:f]])
    get :strong
    assert_response :not_modified

    @request.if_none_match = '*'
    get :strong
    assert_response :not_modified

    @request.if_none_match = '"strong"'
    get :strong
    assert_response :ok

    @request.if_none_match = weak_etag(['strong', 'ab', :cde, [:f]])
    get :strong
    assert_response :ok
  end

502
  def test_multiple_etags
J
Jeremy Daer 已提交
503
    @request.if_none_match = weak_etag(["123", 'ab', :cde, [:f]])
504 505 506 507 508 509 510
    get :fresh
    assert_response :not_modified

    @request.if_none_match = %("nomatch")
    get :fresh
    assert_response :success
  end
511 512

  def test_array
J
Jeremy Daer 已提交
513
    @request.if_none_match = weak_etag([%w(1 2 3), 'ab', :cde, [:f]])
514 515 516 517 518 519 520 521
    get :array
    assert_response :not_modified

    @request.if_none_match = %("nomatch")
    get :array
    assert_response :success
  end

522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
  def test_etag_reflects_template_digest
    get :with_template
    assert_response :ok
    assert_not_nil etag = @response.etag

    request.if_none_match = etag
    get :with_template
    assert_response :not_modified

    # Modify the template digest
    path = File.expand_path('../../fixtures/test/hello_world.erb', __FILE__)
    old = File.read(path)

    begin
      File.write path, 'foo'
J
Jon Moss 已提交
537
      ActionView::LookupContext::DetailsKey.clear
538 539 540 541 542 543 544 545 546 547

      request.if_none_match = etag
      get :with_template
      assert_response :ok
      assert_not_equal etag, @response.etag
    ensure
      File.write path, old
    end
  end

J
Jeremy Daer 已提交
548 549 550 551 552 553 554 555
  private
    def weak_etag(record)
      "W/#{strong_etag record}"
    end

    def strong_etag(record)
      %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(record))}")
    end
556 557
end

558 559 560 561 562 563 564 565
class MetalRenderTest < ActionController::TestCase
  tests MetalTestController

  def test_access_to_logger_in_view
    get :accessing_logger_in_template
    assert_equal "NilClass", @response.body
  end
end
Ł
Łukasz Strzałkowski 已提交
566

567 568 569
class ImplicitRenderTest < ActionController::TestCase
  tests ImplicitRenderTestController

570 571 572 573 574 575 576 577
  def test_implicit_no_content_response_as_browser
    assert_raises(ActionController::UnknownFormat) do
      get :empty_action
    end
  end

  def test_implicit_no_content_response_as_xhr
    get :empty_action, xhr: true
578 579
    assert_response :no_content
  end
580 581 582 583 584 585 586 587 588 589 590 591

  def test_implicit_success_response_with_right_format
    get :empty_action_with_template
    assert_equal "<h1>Empty action rendered this implicitly.</h1>\n", @response.body
    assert_response :success
  end

  def test_implicit_unknown_format_response
    assert_raises(ActionController::UnknownFormat) do
      get :empty_action_with_template, format: 'json'
    end
  end
592 593
end

Ł
Łukasz Strzałkowski 已提交
594 595 596 597 598 599 600 601 602 603 604 605 606
class HeadRenderTest < ActionController::TestCase
  tests TestController

  def setup
    @request.host = "www.nextangle.com"
  end

  def test_head_created
    post :head_created
    assert @response.body.blank?
    assert_response :created
  end

607 608 609 610 611 612 613 614 615 616 617 618 619
  def test_passing_hash_to_head_as_first_parameter_deprecated
    assert_deprecated do
      get :head_with_status_hash
    end
  end

  def test_head_with_default_value_is_deprecated
    assert_deprecated do
      get :head_with_hash_does_not_include_status
      assert_response :ok
    end
  end

Ł
Łukasz Strzałkowski 已提交
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
  def test_head_created_with_application_json_content_type
    post :head_created_with_application_json_content_type
    assert @response.body.blank?
    assert_equal "application/json", @response.header["Content-Type"]
    assert_response :created
  end

  def test_head_ok_with_image_png_content_type
    post :head_ok_with_image_png_content_type
    assert @response.body.blank?
    assert_equal "image/png", @response.header["Content-Type"]
    assert_response :ok
  end

  def test_head_with_location_header
    get :head_with_location_header
    assert @response.body.blank?
    assert_equal "/foo", @response.headers["Location"]
    assert_response :ok
  end

  def test_head_with_location_object
    with_routing do |set|
      set.draw do
        resources :customers
645 646 647 648

        ActiveSupport::Deprecation.silence do
          get ':controller/:action'
        end
Ł
Łukasz Strzałkowski 已提交
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
      end

      get :head_with_location_object
      assert @response.body.blank?
      assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
      assert_response :ok
    end
  end

  def test_head_with_custom_header
    get :head_with_custom_header
    assert @response.body.blank?
    assert_equal "something", @response.headers["X-Custom-Header"]
    assert_response :ok
  end

  def test_head_with_www_authenticate_header
    get :head_with_www_authenticate_header
    assert @response.body.blank?
    assert_equal "something", @response.headers["WWW-Authenticate"]
    assert_response :ok
  end

  def test_head_with_symbolic_status
673
    get :head_with_symbolic_status, params: { status: "ok" }
Ł
Łukasz Strzałkowski 已提交
674 675 676
    assert_equal 200, @response.status
    assert_response :ok

677
    get :head_with_symbolic_status, params: { status: "not_found" }
Ł
Łukasz Strzałkowski 已提交
678 679 680
    assert_equal 404, @response.status
    assert_response :not_found

681
    get :head_with_symbolic_status, params: { status: "no_content" }
Ł
Łukasz Strzałkowski 已提交
682 683 684 685 686
    assert_equal 204, @response.status
    assert !@response.headers.include?('Content-Length')
    assert_response :no_content

    Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |status, code|
687
      get :head_with_symbolic_status, params: { status: status.to_s }
Ł
Łukasz Strzałkowski 已提交
688 689 690 691 692 693 694
      assert_equal code, @response.response_code
      assert_response status
    end
  end

  def test_head_with_integer_status
    Rack::Utils::HTTP_STATUS_CODES.each do |code, message|
695
      get :head_with_integer_status, params: { status: code.to_s }
Ł
Łukasz Strzałkowski 已提交
696 697 698 699
      assert_equal message, @response.message
    end
  end

700 701 702 703 704 705 706 707
  def test_head_with_no_content
    get :head_with_no_content

    assert_equal 204, @response.status
    assert_nil @response.headers["Content-Type"]
    assert_nil @response.headers["Content-Length"]
  end

Ł
Łukasz Strzałkowski 已提交
708
  def test_head_with_string_status
709
    get :head_with_string_status, params: { status: "404 Eat Dirt" }
Ł
Łukasz Strzałkowski 已提交
710 711 712 713 714 715 716 717 718 719 720 721
    assert_equal 404, @response.response_code
    assert_equal "Not Found", @response.message
    assert_response :not_found
  end

  def test_head_with_status_code_first
    get :head_with_status_code_first
    assert_equal 403, @response.response_code
    assert_equal "Forbidden", @response.message
    assert_equal "something", @response.headers["X-Custom-Header"]
    assert_response :forbidden
  end
J
Joel Hayhurst 已提交
722 723 724 725 726 727

  def test_head_returns_truthy_value
    assert_nothing_raised do
      get :head_and_return
    end
  end
728
end
729 730 731 732

class HttpCacheForeverTest < ActionController::TestCase
  class HttpCacheForeverController < ActionController::Base
    def cache_me_forever
733
      http_cache_forever(public: params[:public]) do
734
        render plain: 'hello'
735 736 737 738 739 740 741 742
      end
    end
  end

  tests HttpCacheForeverController

  def test_cache_with_public
    get :cache_me_forever, params: {public: true}
J
Jeremy Daer 已提交
743
    assert_response :ok
744
    assert_equal "max-age=#{100.years}, public", @response.headers["Cache-Control"]
745
    assert_not_nil @response.etag
J
Jeremy Daer 已提交
746
    assert @response.weak_etag?
747 748 749 750
  end

  def test_cache_with_private
    get :cache_me_forever
J
Jeremy Daer 已提交
751
    assert_response :ok
752
    assert_equal "max-age=#{100.years}, private", @response.headers["Cache-Control"]
753
    assert_not_nil @response.etag
J
Jeremy Daer 已提交
754
    assert @response.weak_etag?
755 756 757 758
  end

  def test_cache_response_code_with_if_modified_since
    get :cache_me_forever
J
Jeremy Daer 已提交
759 760
    assert_response :ok

761 762 763 764 765 766 767
    @request.if_modified_since = @response.headers['Last-Modified']
    get :cache_me_forever
    assert_response :not_modified
  end

  def test_cache_response_code_with_etag
    get :cache_me_forever
J
Jeremy Daer 已提交
768
    assert_response :ok
769

J
Jeremy Daer 已提交
770
    @request.if_none_match = @response.etag
771 772 773 774
    get :cache_me_forever
    assert_response :not_modified
  end
end