test_case_test.rb 35.1 KB
Newer Older
1 2 3 4
require "abstract_unit"
require "controller/fake_controllers"
require "active_support/json/decoding"
require "rails/engine"
5

6
class TestCaseTest < ActionController::TestCase
7 8
  def self.fixture_path; end;

9
  class TestController < ActionController::Base
10
    def no_op
11
      render plain: "dummy"
12 13
    end

14 15
    def set_flash
      flash["test"] = ">#{flash["test"]}<"
16
      render plain: "ignore me"
17
    end
18

19 20
    def delete_flash
      flash.delete("test")
21
      render plain: "ignore me"
22 23
    end

24 25
    def set_flash_now
      flash.now["test_now"] = ">#{flash["test_now"]}<"
26
      render plain: "ignore me"
27 28
    end

29
    def set_session
30 31 32
      session["string"] = "A wonder"
      session[:symbol] = "it works"
      render plain: "Success"
33 34
    end

35 36
    def reset_the_session
      reset_session
37
      render plain: "ignore me"
38 39
    end

40
    def render_raw_post
41
      raise ActiveSupport::TestCase::Assertion, "#raw_post is blank" if request.raw_post.blank?
42
      render plain: request.raw_post
43 44
    end

45
    def render_body
46
      render plain: request.body.read
47 48
    end

49
    def test_params
50
      render plain: ::JSON.dump(params.to_unsafe_h)
51 52
    end

53
    def test_query_parameters
54
      render plain: ::JSON.dump(request.query_parameters)
55 56 57
    end

    def test_request_parameters
58
      render plain: request.request_parameters.inspect
59 60
    end

61
    def test_uri
62
      render plain: request.fullpath
63
    end
64

65
    def test_format
66
      render plain: request.format
67 68
    end

69
    def test_query_string
70
      render plain: request.query_string
71 72
    end

A
Andrew White 已提交
73
    def test_protocol
74
      render plain: request.protocol
A
Andrew White 已提交
75 76
    end

77
    def test_headers
78
      render plain: ::JSON.dump(request.headers.env)
79 80
    end

81
    def test_html_output
82
      render plain: <<HTML
83 84
<html>
  <body>
85
    <a href="/"><img src="/images/button.png" /></a>
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
    <div id="foo">
      <ul>
        <li class="item">hello</li>
        <li class="item">goodbye</li>
      </ul>
    </div>
    <div id="bar">
      <form action="/somewhere">
        Name: <input type="text" name="person[name]" id="person_name" />
      </form>
    </div>
  </body>
</html>
HTML
    end
J
Joshua Peek 已提交
101

102 103
    def test_xml_output
      response.content_type = "application/xml"
104
      render plain: <<XML
105 106 107 108 109 110
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <area>area is an empty tag in HTML, raising an error if not in xml mode</area>
</root>
XML
    end
111

112
    def test_only_one_param
113
      render plain: (params[:left] && params[:right]) ? "EEP, Both here!" : "OK"
114 115 116
    end

    def test_remote_addr
117
      render plain: (request.remote_addr || "not specified")
118
    end
119

120
    def test_file_upload
121
      render plain: params[:file].size
122
    end
123

124 125 126 127
    def test_send_file
      send_file(File.expand_path(__FILE__))
    end

128
    def redirect_to_same_controller
129
      redirect_to controller: "test", action: "test_uri", id: 5
130 131 132
    end

    def redirect_to_different_controller
133
      redirect_to controller: "fail", id: 5
134 135
    end

136
    def create
137
      head :created, location: "created resource"
138 139
    end

140 141 142 143
    def render_cookie
      render plain: cookies["foo"]
    end

144 145
    def delete_cookie
      cookies.delete("foo")
146
      render plain: "ok"
147 148
    end

149 150 151 152 153 154 155 156
    def test_without_body
      render html: '<div class="foo"></div>'.html_safe
    end

    def test_with_body
      render html: '<body class="foo"></body>'.html_safe
    end

157
    def boom
158
      raise "boom!"
159 160
    end

161 162 163
    private

      def generate_url(opts)
164
        url_for(opts.merge(action: "test_uri"))
165
      end
166 167 168
  end

  def setup
169
    super
170
    @controller = TestController.new
171
    @request.delete_header "PATH_INFO"
172 173
    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
174
        ActiveSupport::Deprecation.silence do
175
          get ":controller(/:action(/:id))"
176
        end
177 178
      end
    end
179 180
  end

181
  class DefaultUrlOptionsCachingController < ActionController::Base
182
    before_action { @dynamic_opt = "opt" }
183 184

    def test_url_options_reset
185
      render plain: url_for
186 187 188 189 190 191 192 193 194 195 196
    end

    def default_url_options
      if defined?(@dynamic_opt)
        super.merge dynamic_opt: @dynamic_opt
      else
        super
      end
    end
  end

197 198 199
  def test_assert_select_without_body
    get :test_without_body

200 201
    assert_select "body", 0
    assert_select "div.foo"
202 203 204 205 206
  end

  def test_assert_select_with_body
    get :test_with_body

207
    assert_select "body.foo"
208 209
  end

210 211 212
  def test_url_options_reset
    @controller = DefaultUrlOptionsCachingController.new
    get :test_url_options_reset
213
    assert_nil @request.params["dynamic_opt"]
214 215 216
    assert_match(/dynamic_opt=opt/, @response.body)
  end

217
  def test_raw_post_handling
218
    params = Hash[:page, { name: "page name" }, "some key", 123]
219
    post :render_raw_post, params: params.dup
220

221 222 223 224
    assert_equal params.to_query, @response.body
  end

  def test_body_stream
225
    params = Hash[:page, { name: "page name" }, "some key", 123]
226

227 228 229 230 231 232
    post :render_body, params: params.dup

    assert_equal params.to_query, @response.body
  end

  def test_deprecated_body_stream
233
    params = Hash[:page, { name: "page name" }, "some key", 123]
234 235

    assert_deprecated { post :render_body, params.dup }
236 237

    assert_equal params.to_query, @response.body
238
  end
239

240
  def test_document_body_and_params_with_post
241
    post :test_params, params: { id: 1 }
242
    assert_equal({ "id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body))
243
  end
244

245
  def test_document_body_with_post
246 247 248 249 250 251
    post :render_body, body: "document body"
    assert_equal "document body", @response.body
  end

  def test_deprecated_document_body_with_post
    assert_deprecated { post :render_body, "document body" }
252 253
    assert_equal "document body", @response.body
  end
254

255
  def test_document_body_with_put
256 257 258 259 260 261
    put :render_body, body: "document body"
    assert_equal "document body", @response.body
  end

  def test_deprecated_document_body_with_put
    assert_deprecated { put :render_body, "document body" }
262 263
    assert_equal "document body", @response.body
  end
264

265 266 267 268 269
  def test_head
    head :test_params
    assert_equal 200, @response.status
  end

270 271
  def test_process_without_flash
    process :set_flash
272
    assert_equal "><", flash["test"]
273 274
  end

275
  def test_deprecated_process_with_flash
276
    assert_deprecated { process :set_flash, "GET", nil, nil, "test" => "value" }
277
    assert_equal ">value<", flash["test"]
278 279
  end

280
  def test_process_with_flash
281 282 283
    process :set_flash,
      method: "GET",
      flash: { "test" => "value" }
284
    assert_equal ">value<", flash["test"]
285
  end
286

287
  def test_deprecated_process_with_flash_now
288
    assert_deprecated { process :set_flash_now, "GET", nil, nil, "test_now" => "value_now" }
289
    assert_equal ">value_now<", flash["test_now"]
290 291
  end

292
  def test_process_with_flash_now
293 294 295
    process :set_flash_now,
      method: "GET",
      flash: { "test_now" => "value_now" }
296
    assert_equal ">value_now<", flash["test_now"]
297 298
  end

299 300 301 302 303 304 305
  def test_process_delete_flash
    process :set_flash
    process :delete_flash
    assert_empty flash
    assert_empty session
  end

306 307
  def test_process_with_session
    process :set_session
308 309 310 311
    assert_equal "A wonder", session["string"], "A value stored in the session should be available by string key"
    assert_equal "A wonder", session[:string], "Test session hash should allow indifferent access"
    assert_equal "it works", session["symbol"], "Test session hash should allow indifferent access"
    assert_equal "it works", session[:symbol], "Test session hash should allow indifferent access"
312 313 314
  end

  def test_process_with_session_arg
315
    assert_deprecated { process :no_op, "GET", nil, "string" => "value1", symbol: "value2" }
316 317 318 319
    assert_equal "value1", session["string"]
    assert_equal "value1", session[:string]
    assert_equal "value2", session["symbol"]
    assert_equal "value2", session[:symbol]
320 321 322
  end

  def test_process_with_session_kwarg
323 324 325 326 327
    process :no_op, method: "GET", session: { "string" => "value1", symbol: "value2" }
    assert_equal "value1", session["string"]
    assert_equal "value1", session[:string]
    assert_equal "value2", session["symbol"]
    assert_equal "value2", session[:symbol]
328 329
  end

330
  def test_deprecated_process_merges_session_arg
331
    session[:foo] = "bar"
332
    assert_deprecated {
333
      get :no_op, nil, bar: "baz"
334
    }
335 336
    assert_equal "bar", session[:foo]
    assert_equal "baz", session[:bar]
337 338
  end

339
  def test_process_merges_session_arg
340 341 342 343
    session[:foo] = "bar"
    get :no_op, session: { bar: "baz" }
    assert_equal "bar", session[:foo]
    assert_equal "baz", session[:bar]
344 345
  end

346 347
  def test_deprecated_merged_session_arg_is_retained_across_requests
    assert_deprecated {
348
      get :no_op, nil, foo: "bar"
349
    }
350
    assert_equal "bar", session[:foo]
351
    get :no_op
352
    assert_equal "bar", session[:foo]
353 354
  end

355
  def test_merged_session_arg_is_retained_across_requests
356 357
    get :no_op, session: { foo: "bar" }
    assert_equal "bar", session[:foo]
358
    get :no_op
359
    assert_equal "bar", session[:foo]
360 361 362
  end

  def test_process_overwrites_existing_session_arg
363 364 365
    session[:foo] = "bar"
    get :no_op, session: { foo: "baz" }
    assert_equal "baz", session[:foo]
366 367
  end

368 369 370 371 372 373 374 375 376 377 378 379
  def test_session_is_cleared_from_controller_after_reset_session
    process :set_session
    process :reset_the_session
    assert_equal Hash.new, @controller.session.to_hash
  end

  def test_session_is_cleared_from_request_after_reset_session
    process :set_session
    process :reset_the_session
    assert_equal Hash.new, @request.session.to_hash
  end

380 381 382 383 384 385
  def test_response_and_request_have_nice_accessors
    process :no_op
    assert_equal @response, response
    assert_equal @request, request
  end

386 387
  def test_process_with_request_uri_with_no_params
    process :test_uri
388
    assert_equal "/test_case_test/test/test_uri", @response.body
389 390
  end

391 392 393 394 395 396
  def test_process_with_symbol_method
    process :test_uri, method: :get
    assert_equal "/test_case_test/test/test_uri", @response.body
  end

  def test_deprecated_process_with_request_uri_with_params
397
    assert_deprecated { process :test_uri, "GET", id: 7 }
398 399 400
    assert_equal "/test_case_test/test/test_uri/7", @response.body
  end

401
  def test_process_with_request_uri_with_params
402 403 404 405
    process :test_uri,
      method: "GET",
      params: { id: 7 }

406
    assert_equal "/test_case_test/test/test_uri/7", @response.body
407
  end
408

409
  def test_deprecated_process_with_request_uri_with_params_with_explicit_uri
410
    @request.env["PATH_INFO"] = "/explicit/uri"
411 412 413 414
    assert_deprecated { process :test_uri, "GET", id: 7 }
    assert_equal "/explicit/uri", @response.body
  end

415
  def test_process_with_request_uri_with_params_with_explicit_uri
416
    @request.env["PATH_INFO"] = "/explicit/uri"
417
    process :test_uri, method: "GET", params: { id: 7 }
418
    assert_equal "/explicit/uri", @response.body
419 420
  end

421
  def test_process_with_query_string
422 423
    process :test_query_string,
      method: "GET",
424
      params: { q: "test" }
425 426 427 428
    assert_equal "q=test", @response.body
  end

  def test_process_with_query_string_with_explicit_uri
429 430
    @request.env["PATH_INFO"] = "/explicit/uri"
    @request.env["QUERY_STRING"] = "q=test?extra=question"
431 432 433 434
    process :test_query_string
    assert_equal "q=test?extra=question", @response.body
  end

435
  def test_multiple_calls
436
    process :test_only_one_param, method: "GET", params: { left: true }
437
    assert_equal "OK", @response.body
438
    process :test_only_one_param, method: "GET", params: { right: true }
439
    assert_equal "OK", @response.body
440
  end
441

442 443 444 445 446
  def test_should_not_impose_childless_html_tags_in_xml
    process :test_xml_output

    begin
      $stderr = StringIO.new
447
      assert_select "area" #This will cause a warning if content is processed as HTML
448 449 450 451 452 453 454
      $stderr.rewind && err = $stderr.read
    ensure
      $stderr = STDERR
    end

    assert err.empty?
  end
455

456
  def test_assert_generates
457
    assert_generates "controller/action/5", controller: "controller", action: "action", id: "5"
458 459 460
    assert_generates "controller/action/7", { id: "7" }, controller: "controller", action: "action"
    assert_generates "controller/action/5", { controller: "controller", action: "action", id: "5", name: "bob" }, {}, name: "bob"
    assert_generates "controller/action/7", { id: "7", name: "bob" }, { controller: "controller", action: "action" }, name: "bob"
461
    assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action", name: "bob" }, {}
462
  end
463

464
  def test_assert_routing
465
    assert_routing "content", controller: "content", action: "index"
466 467
  end

468 469
  def test_assert_routing_with_method
    with_routing do |set|
470
      set.draw { resources(:content) }
471
      assert_routing({ method: "post", path: "content" }, controller: "content", action: "create")
472 473 474
    end
  end

475
  def test_assert_routing_in_module
476 477 478
    with_routing do |set|
      set.draw do
        namespace :admin do
479
          get "user" => "user#index"
480 481 482
        end
      end

483
      assert_routing "admin/user", controller: "admin/user", action: "index"
484
    end
485
  end
486

487 488
  def test_assert_routing_with_glob
    with_routing do |set|
489
      set.draw { get("*path" => "pages#show") }
490
      assert_routing("/company/about", controller: "pages", action: "show", path: "company/about")
491 492
    end
  end
493

494 495
  def test_deprecated_params_passing
    assert_deprecated {
496
      get :test_params, page: { name: "Page name", month: "4", year: "2004", day: "6" }
497
    }
498
    parsed_params = ::JSON.parse(@response.body)
499
    assert_equal(
500
      {
501 502
        "controller" => "test_case_test/test", "action" => "test_params",
        "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" }
503
      },
504 505 506 507
      parsed_params
    )
  end

508
  def test_params_passing
509 510 511
    get :test_params, params: {
      page: {
        name: "Page name",
512 513 514
        month: "4",
        year: "2004",
        day: "6"
515 516
      }
    }
517
    parsed_params = ::JSON.parse(@response.body)
518
    assert_equal(
519
      {
520 521
        "controller" => "test_case_test/test", "action" => "test_params",
        "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" }
522
      },
523 524 525 526
      parsed_params
    )
  end

527
  def test_query_param_named_action
528
    get :test_query_parameters, params: { action: "foobar" }
529
    parsed_params = JSON.parse(@response.body)
530
    assert_equal({ "action" => "foobar" }, parsed_params)
531 532 533
  end

  def test_request_param_named_action
534
    post :test_request_parameters, params: { action: "foobar" }
535
    parsed_params = eval(@response.body)
536
    assert_equal({ "action" => "foobar" }, parsed_params)
537 538
  end

539 540 541 542
  def test_kwarg_params_passing_with_session_and_flash
    get :test_params, params: {
      page: {
        name: "Page name",
543 544 545
        month: "4",
        year: "2004",
        day: "6"
546
      }
547
    }, session: { "foo" => "bar" }, flash: { notice: "created" }
548

549
    parsed_params = ::JSON.parse(@response.body)
550
    assert_equal(
551 552
      { "controller" => "test_case_test/test", "action" => "test_params",
       "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
553 554
      parsed_params
    )
555

556 557
    assert_equal "bar", session[:foo]
    assert_equal "created", flash[:notice]
558 559
  end

560
  def test_params_passing_with_integer
561 562 563
    get :test_params, params: {
      page: { name: "Page name", month: 4, year: 2004, day: 6 }
    }
564
    parsed_params = ::JSON.parse(@response.body)
565
    assert_equal(
566 567
      { "controller" => "test_case_test/test", "action" => "test_params",
       "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
568 569 570 571
      parsed_params
    )
  end

572
  def test_params_passing_with_integers_when_not_html_request
573
    get :test_params, params: { format: "json", count: 999 }
574
    parsed_params = ::JSON.parse(@response.body)
575
    assert_equal(
576
      { "controller" => "test_case_test/test", "action" => "test_params",
577
       "format" => "json", "count" => "999" },
578 579 580 581 582
      parsed_params
    )
  end

  def test_params_passing_path_parameter_is_string_when_not_html_request
583
    get :test_params, params: { format: "json", id: 1 }
584
    parsed_params = ::JSON.parse(@response.body)
585
    assert_equal(
586
      { "controller" => "test_case_test/test", "action" => "test_params",
587
       "format" => "json", "id" => "1" },
588 589 590 591 592
      parsed_params
    )
  end

  def test_deprecated_params_passing_path_parameter_is_string_when_not_html_request
593
    assert_deprecated { get :test_params, format: "json", id: 1 }
594
    parsed_params = ::JSON.parse(@response.body)
595
    assert_equal(
596
      { "controller" => "test_case_test/test", "action" => "test_params",
597
       "format" => "json", "id" => "1" },
598 599 600 601
      parsed_params
    )
  end

602 603
  def test_params_passing_with_frozen_values
    assert_nothing_raised do
604
      get :test_params, params: {
605
        frozen: "icy".freeze, frozens: ["icy".freeze].freeze, deepfreeze: { frozen: "icy".freeze }.freeze
606
      }
607
    end
608
    parsed_params = ::JSON.parse(@response.body)
609
    assert_equal(
610 611
      { "controller" => "test_case_test/test", "action" => "test_params",
       "frozen" => "icy", "frozens" => ["icy"], "deepfreeze" => { "frozen" => "icy" } },
612 613 614 615
      parsed_params
    )
  end

616
  def test_params_passing_doesnt_modify_in_place
617
    page = { name: "Page name", month: 4, year: 2004, day: 6 }
618
    get :test_params, params: { page: page }
619 620 621
    assert_equal 2004, page[:year]
  end

622
  test "set additional HTTP headers" do
623 624
    @request.headers["Referer"] = "http://nohost.com/home"
    @request.headers["Content-Type"] = "application/rss+xml"
625
    get :test_headers
626
    parsed_env = ActiveSupport::JSON.decode(@response.body)
627 628 629 630 631
    assert_equal "http://nohost.com/home", parsed_env["HTTP_REFERER"]
    assert_equal "application/rss+xml", parsed_env["CONTENT_TYPE"]
  end

  test "set additional env variables" do
632 633
    @request.headers["HTTP_REFERER"] = "http://example.com/about"
    @request.headers["CONTENT_TYPE"] = "application/json"
634
    get :test_headers
635
    parsed_env = ActiveSupport::JSON.decode(@response.body)
636 637 638 639
    assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"]
    assert_equal "application/json", parsed_env["CONTENT_TYPE"]
  end

640 641 642 643 644 645 646 647 648
  def test_using_as_json_sets_request_content_type_to_json
    post :render_body, params: { bool_value: true, str_value: "string", num_value: 2 }, as: :json

    assert_equal "application/json", @request.headers["CONTENT_TYPE"]
    assert_equal true, @request.request_parameters[:bool_value]
    assert_equal "string", @request.request_parameters[:str_value]
    assert_equal 2, @request.request_parameters[:num_value]
  end

649
  def test_mutating_content_type_headers_for_plain_text_files_sets_the_header
650 651
    @request.headers["Content-Type"] = "text/plain"
    post :render_body, params: { name: "foo.txt" }
652

653 654 655
    assert_equal "text/plain", @request.headers["Content-type"]
    assert_equal "foo.txt", @request.request_parameters[:name]
    assert_equal "render_body", @request.path_parameters[:action]
656 657 658
  end

  def test_mutating_content_type_headers_for_html_files_sets_the_header
659 660
    @request.headers["Content-Type"] = "text/html"
    post :render_body, params: { name: "foo.html" }
661

662 663 664
    assert_equal "text/html", @request.headers["Content-type"]
    assert_equal "foo.html", @request.request_parameters[:name]
    assert_equal "render_body", @request.path_parameters[:action]
665 666 667 668
  end

  def test_mutating_content_type_headers_for_non_registered_mime_type_raises_an_error
    assert_raises(RuntimeError) do
669 670
      @request.headers["Content-Type"] = "type/fake"
      post :render_body, params: { name: "foo.fake" }
671 672 673
    end
  end

674
  def test_id_converted_to_string
675 676 677 678 679 680 681
    get :test_params, params: {
      id: 20, foo: Object.new
    }
    assert_kind_of String, @request.path_parameters[:id]
  end

  def test_deprecared_id_converted_to_string
682
    assert_deprecated { get :test_params, id: 20, foo: Object.new }
683
    assert_kind_of String, @request.path_parameters[:id]
684 685 686 687
  end

  def test_array_path_parameter_handled_properly
    with_routing do |set|
688
      set.draw do
689
        get "file/*path", to: "test_case_test/test#test_params"
690 691

        ActiveSupport::Deprecation.silence do
692
          get ":controller/:action"
693
        end
694
      end
695

696 697 698
      get :test_params, params: { path: ["hello", "world"] }
      assert_equal ["hello", "world"], @request.path_parameters[:path]
      assert_equal "hello/world", @request.path_parameters[:path].to_param
699 700 701 702
    end
  end

  def test_assert_realistic_path_parameters
703
    get :test_params, params: { id: 20, foo: Object.new }
704

705
    # All elements of path_parameters should use Symbol keys
706
    @request.path_parameters.each_key do |key|
707
      assert_kind_of Symbol, key
708 709 710 711
    end
  end

  def test_with_routing_places_routes_back
J
Joshua Peek 已提交
712 713
    assert @routes
    routes_id = @routes.object_id
714

715
    begin
716 717
      with_routing { raise "fail" }
      fail "Should not be here."
718
    rescue RuntimeError
719
    end
720

J
Joshua Peek 已提交
721 722
    assert @routes
    assert_equal routes_id, @routes.object_id
723
  end
724 725 726 727 728 729 730 731 732

  def test_remote_addr
    get :test_remote_addr
    assert_equal "0.0.0.0", @response.body

    @request.remote_addr = "192.0.0.1"
    get :test_remote_addr
    assert_equal "192.0.0.1", @response.body
  end
733

734
  def test_header_properly_reset_after_remote_http_request
735
    get :test_params, xhr: true
736 737
    assert_nil @request.env["HTTP_X_REQUESTED_WITH"]
    assert_nil @request.env["HTTP_ACCEPT"]
738 739
  end

740 741 742
  def test_deprecated_xhr_with_params
    assert_deprecated { xhr :get, :test_params, params: { id: 1 } }

743
    assert_equal({ "id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body))
744 745
  end

746
  def test_xhr_with_params
747
    get :test_params, params: { id: 1 }, xhr: true
748

749
    assert_equal({ "id"=>"1", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body))
750 751 752
  end

  def test_xhr_with_session
753 754
    get :set_session, xhr: true

755 756 757 758
    assert_equal "A wonder", session["string"], "A value stored in the session should be available by string key"
    assert_equal "A wonder", session[:string], "Test session hash should allow indifferent access"
    assert_equal "it works", session["symbol"], "Test session hash should allow indifferent access"
    assert_equal "it works", session[:symbol], "Test session hash should allow indifferent access"
759 760 761 762
  end

  def test_deprecated_xhr_with_session
    assert_deprecated { xhr :get, :set_session }
763

764 765 766 767
    assert_equal "A wonder", session["string"], "A value stored in the session should be available by string key"
    assert_equal "A wonder", session[:string], "Test session hash should allow indifferent access"
    assert_equal "it works", session["symbol"], "Test session hash should allow indifferent access"
    assert_equal "it works", session[:symbol], "Test session hash should allow indifferent access"
768 769 770 771 772 773 774 775 776 777
  end

  def test_deprecated_params_reset_between_post_requests
    assert_deprecated { post :no_op, foo: "bar" }
    assert_equal "bar", @request.params[:foo]

    post :no_op
    assert @request.params[:foo].blank?
  end

G
Guo Xiang Tan 已提交
778
  def test_params_reset_between_post_requests
779
    post :no_op, params: { foo: "bar" }
780
    assert_equal "bar", @request.params[:foo]
G
Guo Xiang Tan 已提交
781

782
    post :no_op
783
    assert @request.params[:foo].blank?
784 785
  end

786
  def test_filtered_parameters_reset_between_requests
787
    get :no_op, params: { foo: "bar" }
788 789
    assert_equal "bar", @request.filtered_parameters[:foo]

790
    get :no_op, params: { foo: "baz" }
791 792 793
    assert_equal "baz", @request.filtered_parameters[:foo]
  end

G
Guo Xiang Tan 已提交
794
  def test_path_params_reset_between_request
795
    get :test_params, params: { id: "foo" }
796
    assert_equal "foo", @request.path_parameters[:id]
G
Guo Xiang Tan 已提交
797

798
    get :test_params
799
    assert_nil @request.path_parameters[:id]
800 801
  end

A
Andrew White 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814
  def test_request_protocol_is_reset_after_request
    get :test_protocol
    assert_equal "http://", @response.body

    @request.env["HTTPS"] = "on"
    get :test_protocol
    assert_equal "https://", @response.body

    @request.env.delete("HTTPS")
    get :test_protocol
    assert_equal "http://", @response.body
  end

815
  def test_request_format
816 817
    get :test_format, params: { format: "html" }
    assert_equal "text/html", @response.body
818

819 820
    get :test_format, params: { format: "json" }
    assert_equal "application/json", @response.body
821

822 823
    get :test_format, params: { format: "xml" }
    assert_equal "application/xml", @response.body
824 825

    get :test_format
826
    assert_equal "text/html", @response.body
827 828
  end

829
  def test_request_format_kwarg
830 831
    get :test_format, format: "html"
    assert_equal "text/html", @response.body
832

833 834
    get :test_format, format: "json"
    assert_equal "application/json", @response.body
835

836 837
    get :test_format, format: "xml"
    assert_equal "application/xml", @response.body
838 839

    get :test_format
840
    assert_equal "text/html", @response.body
841 842 843
  end

  def test_request_format_kwarg_overrides_params
844 845
    get :test_format, format: "json", params: { format: "html" }
    assert_equal "application/json", @response.body
846 847
  end

848
  def test_should_have_knowledge_of_client_side_cookie_state_even_if_they_are_not_set
849
    cookies["foo"] = "bar"
850
    get :no_op
851
    assert_equal "bar", cookies["foo"]
852 853 854
  end

  def test_cookies_should_be_escaped_properly
855
    cookies["foo"] = "+"
856
    get :render_cookie
857
    assert_equal "+", @response.body
858 859 860
  end

  def test_should_detect_if_cookie_is_deleted
861
    cookies["foo"] = "bar"
862
    get :delete_cookie
863
    assert_nil cookies["foo"]
864 865
  end

866
  def test_multiple_mixed_method_process_should_scrub_rack_input
867
    post :test_params, params: { id: 1, foo: "an foo" }
868
    assert_equal({ "id"=>"1", "foo" => "an foo", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body))
869

870
    get :test_params, params: { bar: "an bar" }
871
    assert_equal({ "bar"=>"an bar", "controller"=>"test_case_test/test", "action"=>"test_params" }, ::JSON.parse(@response.body))
872 873
  end

874 875 876 877 878 879 880 881
  %w(controller response request).each do |variable|
    %w(get post put delete head process).each do |method|
      define_method("test_#{variable}_missing_for_#{method}_raises_error") do
        remove_instance_variable "@#{variable}"
        begin
          send(method, :test_remote_addr)
          assert false, "expected RuntimeError, got nothing"
        rescue RuntimeError => error
882
          assert_match(%r{@#{variable} is nil}, error.message)
883 884 885 886 887 888
        rescue => error
          assert false, "expected RuntimeError, got #{error.class}"
        end
      end
    end
  end
889

890
  FILES_DIR = File.dirname(__FILE__) + "/../fixtures/multipart"
891

892 893
  READ_BINARY = "rb:binary"
  READ_PLAIN = "r:binary"
894

895
  def test_test_uploaded_file
896
    filename = "mona_lisa.jpg"
897
    path = "#{FILES_DIR}/#{filename}"
898
    content_type = "image/png"
899
    expected = File.read(path)
900
    expected.force_encoding(Encoding::BINARY)
901

J
Joshua Peek 已提交
902
    file = Rack::Test::UploadedFile.new(path, content_type)
903 904 905
    assert_equal filename, file.original_filename
    assert_equal content_type, file.content_type
    assert_equal file.path, file.local_path
906
    assert_equal expected, file.read
907 908 909 910 911

    new_content_type = "new content_type"
    file.content_type = new_content_type
    assert_equal new_content_type, file.content_type

912
  end
J
Joshua Peek 已提交
913

914
  def test_fixture_path_is_accessed_from_self_instead_of_active_support_test_case
915
    TestCaseTest.stub :fixture_path, FILES_DIR do
916
      uploaded_file = fixture_file_upload("/mona_lisa.jpg", "image/png")
917 918
      assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
    end
919 920
  end

921
  def test_test_uploaded_file_with_binary
922
    filename = "mona_lisa.jpg"
923
    path = "#{FILES_DIR}/#{filename}"
924
    content_type = "image/png"
J
Joshua Peek 已提交
925

J
Joshua Peek 已提交
926
    binary_uploaded_file = Rack::Test::UploadedFile.new(path, content_type, :binary)
927
    assert_equal File.open(path, READ_BINARY).read, binary_uploaded_file.read
J
Joshua Peek 已提交
928

J
Joshua Peek 已提交
929
    plain_uploaded_file = Rack::Test::UploadedFile.new(path, content_type)
930
    assert_equal File.open(path, READ_PLAIN).read, plain_uploaded_file.read
931 932 933
  end

  def test_fixture_file_upload_with_binary
934
    filename = "mona_lisa.jpg"
935
    path = "#{FILES_DIR}/#{filename}"
936
    content_type = "image/jpg"
J
Joshua Peek 已提交
937

938
    binary_file_upload = fixture_file_upload(path, content_type, :binary)
939
    assert_equal File.open(path, READ_BINARY).read, binary_file_upload.read
J
Joshua Peek 已提交
940

941
    plain_file_upload = fixture_file_upload(path, content_type)
942
    assert_equal File.open(path, READ_PLAIN).read, plain_file_upload.read
943
  end
944

945 946 947 948 949
  def test_fixture_file_upload_should_be_able_access_to_tempfile
    file = fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
    assert file.respond_to?(:tempfile), "expected tempfile should respond on fixture file object, got nothing"
  end

950
  def test_fixture_file_upload
951 952 953 954
    post :test_file_upload,
      params: {
        file: fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")
      }
955
    assert_equal "159528", @response.body
956
  end
957

958
  def test_fixture_file_upload_relative_to_fixture_path
959 960 961 962
    TestCaseTest.stub :fixture_path, FILES_DIR do
      uploaded_file = fixture_file_upload("mona_lisa.jpg", "image/jpg")
      assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
    end
963 964 965 966 967 968 969
  end

  def test_fixture_file_upload_ignores_nil_fixture_path
    uploaded_file = fixture_file_upload("#{FILES_DIR}/mona_lisa.jpg", "image/jpg")
    assert_equal File.open("#{FILES_DIR}/mona_lisa.jpg", READ_PLAIN).read, uploaded_file.read
  end

970
  def test_deprecated_action_dispatch_uploaded_file_upload
971
    filename = "mona_lisa.jpg"
972 973
    path = "#{FILES_DIR}/#{filename}"
    assert_deprecated {
974
      post :test_file_upload, file: Rack::Test::UploadedFile.new(path, "image/jpg", true)
975
    }
976
    assert_equal "159528", @response.body
977 978
  end

979
  def test_action_dispatch_uploaded_file_upload
980
    filename = "mona_lisa.jpg"
981
    path = "#{FILES_DIR}/#{filename}"
982
    post :test_file_upload, params: {
983
      file: Rack::Test::UploadedFile.new(path, "image/jpg", true)
984
    }
985
    assert_equal "159528", @response.body
986 987
  end

988
  def test_test_uploaded_file_exception_when_file_doesnt_exist
989
    assert_raise(RuntimeError) { Rack::Test::UploadedFile.new("non_existent_file") }
990
  end
991

992 993 994 995 996
  def test_redirect_url_only_cares_about_location_header
    get :create
    assert_response :created

    # Redirect url doesn't care that it wasn't a :redirect response.
997
    assert_equal "created resource", @response.redirect_url
998 999 1000
    assert_equal @response.redirect_url, redirect_to_url

    # Must be a :redirect response.
1001
    assert_raise(ActiveSupport::TestCase::Assertion) do
1002
      assert_redirected_to "created resource"
1003 1004
    end
  end
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015

  def test_exception_in_action_reaches_test
    assert_raise(RuntimeError) do
      process :boom, method: "GET"
    end
  end

  def test_request_state_is_cleared_after_exception
    assert_raise(RuntimeError) do
      process :boom,
        method: "GET",
1016
        params: { q: "test1" }
1017 1018 1019 1020
    end

    process :test_query_string,
      method: "GET",
1021
      params: { q: "test2" }
1022 1023 1024

    assert_equal "q=test2", @response.body
  end
1025
end
1026

1027 1028 1029 1030
class ResponseDefaultHeadersTest < ActionController::TestCase
  class TestController < ActionController::Base
    def remove_header
      headers.delete params[:header]
1031
      head :ok, "C" => "3"
1032
    end
1033 1034 1035 1036 1037

    # Render a head response, but don't touch default headers
    def leave_alone
      head :ok
    end
1038 1039
  end

1040
  def before_setup
1041
    @original = ActionDispatch::Response.default_headers
1042
    @defaults = { "A" => "1", "B" => "2" }
1043
    ActionDispatch::Response.default_headers = @defaults
1044
    super
1045 1046 1047 1048 1049 1050 1051 1052 1053
  end

  teardown do
    ActionDispatch::Response.default_headers = @original
  end

  def setup
    super
    @controller = TestController.new
1054
    @request.env["PATH_INFO"] = nil
1055 1056
    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
1057
        ActiveSupport::Deprecation.silence do
1058
          get ":controller(/:action(/:id))"
1059
        end
1060 1061 1062 1063 1064
      end
    end
  end

  test "response contains default headers" do
1065 1066
    get :leave_alone

1067
    # Response headers start out with the defaults
1068
    assert_equal @defaults.merge("Content-Type" => "text/html"), response.headers
1069
  end
1070

1071
  test "response deletes a default header" do
1072
    get :remove_header, params: { header: "A" }
1073 1074 1075 1076
    assert_response :ok

    # After a request, the response in the test case doesn't have the
    # defaults merged on top again.
1077 1078 1079
    assert_not_includes response.headers, "A"
    assert_includes response.headers, "B"
    assert_includes response.headers, "C"
1080 1081 1082
  end
end

1083 1084 1085 1086 1087
module EngineControllerTests
  class Engine < ::Rails::Engine
    isolate_namespace EngineControllerTests

    routes.draw do
1088
      get "/" => "bar#index"
1089 1090 1091 1092 1093
    end
  end

  class BarController < ActionController::Base
    def index
1094
      render plain: "bar"
1095 1096 1097 1098 1099 1100 1101 1102
    end
  end

  class BarControllerTest < ActionController::TestCase
    tests BarController

    def test_engine_controller_route
      get :index
1103
      assert_equal @response.body, "bar"
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
    end
  end

  class BarControllerTestWithExplicitRouteSet < ActionController::TestCase
    tests BarController

    def setup
      @routes = Engine.routes
    end

    def test_engine_controller_route
      get :index
1116
      assert_equal @response.body, "bar"
1117 1118 1119 1120
    end
  end
end

1121
class InferringClassNameTest < ActionController::TestCase
1122 1123 1124 1125 1126
  def test_determine_controller_class
    assert_equal ContentController, determine_class("ContentControllerTest")
  end

  def test_determine_controller_class_with_nonsense_name
1127
    assert_nil determine_class("HelloGoodBye")
1128 1129 1130
  end

  def test_determine_controller_class_with_sensible_name_where_no_controller_exists
1131
    assert_nil determine_class("NoControllerWithThisNameTest")
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141
  end

  private
    def determine_class(name)
      ActionController::TestCase.determine_default_controller_class(name)
    end
end

class CrazyNameTest < ActionController::TestCase
  tests ContentController
1142

1143 1144 1145 1146
  def test_controller_class_can_be_set_manually_not_just_inferred
    assert_equal ContentController, self.class.controller_class
  end
end
1147

1148 1149 1150 1151 1152 1153 1154 1155 1156
class CrazySymbolNameTest < ActionController::TestCase
  tests :content

  def test_set_controller_class_using_symbol
    assert_equal ContentController, self.class.controller_class
  end
end

class CrazyStringNameTest < ActionController::TestCase
1157
  tests "content"
1158 1159 1160 1161 1162 1163

  def test_set_controller_class_using_string
    assert_equal ContentController, self.class.controller_class
  end
end

1164 1165
class NamedRoutesControllerTest < ActionController::TestCase
  tests ContentController
J
Joshua Peek 已提交
1166

1167 1168
  def test_should_be_able_to_use_named_routes_before_a_request_is_done
    with_routing do |set|
1169
      set.draw { resources :contents }
1170 1171
      assert_equal "http://test.host/contents/new", new_content_url
      assert_equal "http://test.host/contents/1", content_url(id: 1)
1172 1173 1174
    end
  end
end
A
Andrew White 已提交
1175 1176 1177 1178 1179

class AnonymousControllerTest < ActionController::TestCase
  def setup
    @controller = Class.new(ActionController::Base) do
      def index
1180
        render plain: params[:controller]
A
Andrew White 已提交
1181 1182 1183 1184 1185
      end
    end.new

    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
1186
        ActiveSupport::Deprecation.silence do
1187
          get ":controller(/:action(/:id))"
1188
        end
A
Andrew White 已提交
1189 1190 1191 1192 1193 1194
      end
    end
  end

  def test_controller_name
    get :index
1195
    assert_equal "anonymous", @response.body
A
Andrew White 已提交
1196
  end
1197
end
1198 1199 1200 1201 1202

class RoutingDefaultsTest < ActionController::TestCase
  def setup
    @controller = Class.new(ActionController::Base) do
      def post
1203
        render plain: request.fullpath
1204 1205 1206
      end

      def project
1207
        render plain: request.fullpath
1208 1209 1210 1211 1212
      end
    end.new

    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
1213 1214
        get "/posts/:id", to: "anonymous#post", bucket_type: "post"
        get "/projects/:id", to: "anonymous#project", defaults: { bucket_type: "project" }
1215 1216 1217 1218 1219
      end
    end
  end

  def test_route_option_can_be_passed_via_process
1220
    get :post, params: { id: 1, bucket_type: "post" }
1221
    assert_equal "/posts/1", @response.body
1222 1223 1224
  end

  def test_route_default_is_not_required_for_building_request_uri
1225
    get :project, params: { id: 2 }
1226
    assert_equal "/projects/2", @response.body
1227 1228
  end
end