test_case_test.rb 32.7 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5 6
require "abstract_unit"
require "controller/fake_controllers"
require "active_support/json/decoding"
require "rails/engine"
7

8
class TestCaseTest < ActionController::TestCase
S
Shuhei Kitagawa 已提交
9
  def self.fixture_path; end
10

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

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

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

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

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

37 38
    def reset_the_session
      reset_session
39
      render plain: "ignore me"
40 41
    end

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

47
    def render_body
48
      render plain: request.body.read
49 50
    end

51
    def test_params
52
      render plain: ::JSON.dump(params.to_unsafe_h)
53 54
    end

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

    def test_request_parameters
60
      render plain: request.request_parameters.inspect
61 62
    end

63
    def test_uri
64
      render plain: request.fullpath
65
    end
66

67
    def test_format
68
      render plain: request.format
69 70
    end

71
    def test_query_string
72
      render plain: request.query_string
73 74
    end

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

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

83
    def test_html_output
84
      render plain: <<HTML
85 86
<html>
  <body>
87
    <a href="/"><img src="/images/button.png" /></a>
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    <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 已提交
103

104
    def test_xml_output
M
Matthew Draper 已提交
105
      response.content_type = params[:response_as]
106
      render plain: <<XML
107 108
<?xml version="1.0" encoding="UTF-8"?>
<root>
M
Matthew Draper 已提交
109
  <area><p>area is an empty tag in HTML, so it won't contain this content</p></area>
110 111 112
</root>
XML
    end
113

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

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

122
    def test_file_upload
123
      render plain: params[:file].size
124
    end
125

126
    def test_send_file
B
bogdanvlviv 已提交
127
      send_file(__FILE__)
128 129
    end

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

    def redirect_to_different_controller
135
      redirect_to controller: "fail", id: 5
136 137
    end

138
    def create
139
      head :created, location: "/resource"
140 141
    end

142 143 144 145
    def render_cookie
      render plain: cookies["foo"]
    end

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

151 152 153 154 155 156 157 158
    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

159
    def boom
160
      raise "boom!"
161 162
    end

163 164 165
    private

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

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

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

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

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

199 200 201
  def test_assert_select_without_body
    get :test_without_body

202 203
    assert_select "body", 0
    assert_select "div.foo"
204 205 206 207 208
  end

  def test_assert_select_with_body
    get :test_with_body

209
    assert_select "body.foo"
210 211
  end

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

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

223 224 225 226
    assert_equal Rack::Utils.build_nested_query(params), @response.body
  end

  def test_params_round_trip
B
bogdanvlviv 已提交
227
    params = { "foo" => { "contents" => [{ "name" => "gorby", "id" => "123" }, { "name" => "puff", "d" => "true" }] } }
228 229 230 231
    post :test_params, params: params.dup

    controller_info = { "controller" => "test_case_test/test", "action" => "test_params" }
    assert_equal params.merge(controller_info), JSON.parse(@response.body)
232 233 234
  end

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

237 238
    post :render_body, params: params.dup

239
    assert_equal Rack::Utils.build_nested_query(params), @response.body
240 241
  end

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

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

252
  def test_document_body_with_put
253 254 255 256
    put :render_body, body: "document body"
    assert_equal "document body", @response.body
  end

257 258 259 260 261
  def test_head
    head :test_params
    assert_equal 200, @response.status
  end

262 263
  def test_process_without_flash
    process :set_flash
264
    assert_equal "><", flash["test"]
265 266
  end

267
  def test_process_with_flash
268 269 270
    process :set_flash,
      method: "GET",
      flash: { "test" => "value" }
271
    assert_equal ">value<", flash["test"]
272
  end
273

274
  def test_process_with_flash_now
275 276 277
    process :set_flash_now,
      method: "GET",
      flash: { "test_now" => "value_now" }
278
    assert_equal ">value_now<", flash["test_now"]
279 280
  end

281 282 283 284 285 286 287
  def test_process_delete_flash
    process :set_flash
    process :delete_flash
    assert_empty flash
    assert_empty session
  end

288 289
  def test_process_with_session
    process :set_session
290 291 292 293
    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"
294 295
  end

296
  def test_process_with_session_kwarg
297 298 299 300 301
    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]
302 303
  end

304
  def test_process_merges_session_arg
305 306 307 308
    session[:foo] = "bar"
    get :no_op, session: { bar: "baz" }
    assert_equal "bar", session[:foo]
    assert_equal "baz", session[:bar]
309 310 311
  end

  def test_merged_session_arg_is_retained_across_requests
312 313
    get :no_op, session: { foo: "bar" }
    assert_equal "bar", session[:foo]
314
    get :no_op
315
    assert_equal "bar", session[:foo]
316 317 318
  end

  def test_process_overwrites_existing_session_arg
319 320 321
    session[:foo] = "bar"
    get :no_op, session: { foo: "baz" }
    assert_equal "baz", session[:foo]
322 323
  end

324 325 326 327 328 329 330 331 332 333 334 335
  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

336 337 338 339 340 341
  def test_response_and_request_have_nice_accessors
    process :no_op
    assert_equal @response, response
    assert_equal @request, request
  end

342 343
  def test_process_with_request_uri_with_no_params
    process :test_uri
344
    assert_equal "/test_case_test/test/test_uri", @response.body
345 346
  end

347 348 349 350 351
  def test_process_with_symbol_method
    process :test_uri, method: :get
    assert_equal "/test_case_test/test/test_uri", @response.body
  end

352
  def test_process_with_request_uri_with_params
353 354 355 356
    process :test_uri,
      method: "GET",
      params: { id: 7 }

357
    assert_equal "/test_case_test/test/test_uri/7", @response.body
358
  end
359

360
  def test_process_with_request_uri_with_params_with_explicit_uri
361
    @request.env["PATH_INFO"] = "/explicit/uri"
362
    process :test_uri, method: "GET", params: { id: 7 }
363
    assert_equal "/explicit/uri", @response.body
364 365
  end

366
  def test_process_with_query_string
367 368
    process :test_query_string,
      method: "GET",
369
      params: { q: "test" }
370 371 372 373
    assert_equal "q=test", @response.body
  end

  def test_process_with_query_string_with_explicit_uri
374 375
    @request.env["PATH_INFO"] = "/explicit/uri"
    @request.env["QUERY_STRING"] = "q=test?extra=question"
376 377 378 379
    process :test_query_string
    assert_equal "q=test?extra=question", @response.body
  end

380
  def test_multiple_calls
381
    process :test_only_one_param, method: "GET", params: { left: true }
382
    assert_equal "OK", @response.body
383
    process :test_only_one_param, method: "GET", params: { right: true }
384
    assert_equal "OK", @response.body
385
  end
386

M
Matthew Draper 已提交
387 388
  def test_should_impose_childless_html_tags_in_html
    process :test_xml_output, params: { response_as: "text/html" }
389

M
Matthew Draper 已提交
390 391 392 393 394 395
    # <area> auto-closes, so the <p> becomes a sibling
    assert_select "root > area + p"
  end

  def test_should_not_impose_childless_html_tags_in_xml
    process :test_xml_output, params: { response_as: "application/xml" }
396

M
Matthew Draper 已提交
397 398
    # <area> is not special, so the <p> is its child
    assert_select "root > area > p"
399
  end
400

401
  def test_assert_generates
402
    assert_generates "controller/action/5", controller: "controller", action: "action", id: "5"
K
Koichi ITO 已提交
403 404 405
    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" }
406
    assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action", name: "bob" }, {}
407
  end
408

409
  def test_assert_routing
410
    assert_routing "content", controller: "content", action: "index"
411 412
  end

413 414
  def test_assert_routing_with_method
    with_routing do |set|
415
      set.draw { resources(:content) }
K
Koichi ITO 已提交
416
      assert_routing({ method: "post", path: "content" }, { controller: "content", action: "create" })
417 418 419
    end
  end

420
  def test_assert_routing_in_module
421 422 423
    with_routing do |set|
      set.draw do
        namespace :admin do
424
          get "user" => "user#index"
425 426 427
        end
      end

428
      assert_routing "admin/user", controller: "admin/user", action: "index"
429
    end
430
  end
431

432 433
  def test_assert_routing_with_glob
    with_routing do |set|
434
      set.draw { get("*path" => "pages#show") }
435
      assert_routing("/company/about", controller: "pages", action: "show", path: "company/about")
436 437
    end
  end
438

439
  def test_params_passing
440 441 442
    get :test_params, params: {
      page: {
        name: "Page name",
443 444 445
        month: "4",
        year: "2004",
        day: "6"
446 447
      }
    }
448
    parsed_params = ::JSON.parse(@response.body)
449
    assert_equal(
450
      {
451 452
        "controller" => "test_case_test/test", "action" => "test_params",
        "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" }
453
      },
454 455 456 457
      parsed_params
    )
  end

458
  def test_query_param_named_action
459
    get :test_query_parameters, params: { action: "foobar" }
460
    parsed_params = JSON.parse(@response.body)
461
    assert_equal({ "action" => "foobar" }, parsed_params)
462 463 464
  end

  def test_request_param_named_action
465
    post :test_request_parameters, params: { action: "foobar" }
466
    parsed_params = eval(@response.body)
467
    assert_equal({ "action" => "foobar" }, parsed_params)
468 469
  end

470 471 472 473
  def test_kwarg_params_passing_with_session_and_flash
    get :test_params, params: {
      page: {
        name: "Page name",
474 475 476
        month: "4",
        year: "2004",
        day: "6"
477
      }
478
    }, session: { "foo" => "bar" }, flash: { notice: "created" }
479

480
    parsed_params = ::JSON.parse(@response.body)
481
    assert_equal(
482 483
      { "controller" => "test_case_test/test", "action" => "test_params",
       "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
484 485
      parsed_params
    )
486

487 488
    assert_equal "bar", session[:foo]
    assert_equal "created", flash[:notice]
489 490
  end

491
  def test_params_passing_with_integer
492 493 494
    get :test_params, params: {
      page: { name: "Page name", month: 4, year: 2004, day: 6 }
    }
495
    parsed_params = ::JSON.parse(@response.body)
496
    assert_equal(
497 498
      { "controller" => "test_case_test/test", "action" => "test_params",
       "page" => { "name" => "Page name", "month" => "4", "year" => "2004", "day" => "6" } },
499 500 501 502
      parsed_params
    )
  end

503
  def test_params_passing_with_integers_when_not_html_request
504
    get :test_params, params: { format: "json", count: 999 }
505
    parsed_params = ::JSON.parse(@response.body)
506
    assert_equal(
507
      { "controller" => "test_case_test/test", "action" => "test_params",
508
       "format" => "json", "count" => "999" },
509 510 511 512 513
      parsed_params
    )
  end

  def test_params_passing_path_parameter_is_string_when_not_html_request
514
    get :test_params, params: { format: "json", id: 1 }
515
    parsed_params = ::JSON.parse(@response.body)
516
    assert_equal(
517
      { "controller" => "test_case_test/test", "action" => "test_params",
518
       "format" => "json", "id" => "1" },
519 520 521 522
      parsed_params
    )
  end

523 524
  def test_params_passing_with_frozen_values
    assert_nothing_raised do
525
      get :test_params, params: {
526
        frozen: "icy".freeze, frozens: ["icy".freeze].freeze, deepfreeze: { frozen: "icy".freeze }.freeze
527
      }
528
    end
529
    parsed_params = ::JSON.parse(@response.body)
530
    assert_equal(
531 532
      { "controller" => "test_case_test/test", "action" => "test_params",
       "frozen" => "icy", "frozens" => ["icy"], "deepfreeze" => { "frozen" => "icy" } },
533 534 535 536
      parsed_params
    )
  end

537
  def test_params_passing_doesnt_modify_in_place
538
    page = { name: "Page name", month: 4, year: 2004, day: 6 }
539
    get :test_params, params: { page: page }
540 541 542
    assert_equal 2004, page[:year]
  end

543
  test "set additional HTTP headers" do
544 545
    @request.headers["Referer"] = "http://nohost.com/home"
    @request.headers["Content-Type"] = "application/rss+xml"
546
    get :test_headers
547
    parsed_env = ActiveSupport::JSON.decode(@response.body)
548 549 550 551 552
    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
553 554
    @request.headers["HTTP_REFERER"] = "http://example.com/about"
    @request.headers["CONTENT_TYPE"] = "application/json"
555
    get :test_headers
556
    parsed_env = ActiveSupport::JSON.decode(@response.body)
557 558 559 560
    assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"]
    assert_equal "application/json", parsed_env["CONTENT_TYPE"]
  end

561 562 563 564 565 566 567 568 569
  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

570 571 572 573 574
  def test_using_as_json_sets_format_json
    post :render_body, params: { bool_value: true, str_value: "string", num_value: 2 }, as: :json
    assert_equal "json", @request.format
  end

575
  def test_mutating_content_type_headers_for_plain_text_files_sets_the_header
576 577
    @request.headers["Content-Type"] = "text/plain"
    post :render_body, params: { name: "foo.txt" }
578

579 580 581
    assert_equal "text/plain", @request.headers["Content-type"]
    assert_equal "foo.txt", @request.request_parameters[:name]
    assert_equal "render_body", @request.path_parameters[:action]
582 583 584
  end

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

588 589 590
    assert_equal "text/html", @request.headers["Content-type"]
    assert_equal "foo.html", @request.request_parameters[:name]
    assert_equal "render_body", @request.path_parameters[:action]
591 592 593 594
  end

  def test_mutating_content_type_headers_for_non_registered_mime_type_raises_an_error
    assert_raises(RuntimeError) do
595 596
      @request.headers["Content-Type"] = "type/fake"
      post :render_body, params: { name: "foo.fake" }
597 598 599
    end
  end

600
  def test_id_converted_to_string
601 602 603 604 605 606
    get :test_params, params: {
      id: 20, foo: Object.new
    }
    assert_kind_of String, @request.path_parameters[:id]
  end

607 608
  def test_array_path_parameter_handled_properly
    with_routing do |set|
609
      set.draw do
610
        get "file/*path", to: "test_case_test/test#test_params"
611 612

        ActiveSupport::Deprecation.silence do
613
          get ":controller/:action"
614
        end
615
      end
616

617 618 619
      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
620 621 622 623
    end
  end

  def test_assert_realistic_path_parameters
624
    get :test_params, params: { id: 20, foo: Object.new }
625

626
    # All elements of path_parameters should use Symbol keys
627
    @request.path_parameters.each_key do |key|
628
      assert_kind_of Symbol, key
629 630 631 632
    end
  end

  def test_with_routing_places_routes_back
J
Joshua Peek 已提交
633 634
    assert @routes
    routes_id = @routes.object_id
635

636
    begin
637 638
      with_routing { raise "fail" }
      fail "Should not be here."
639
    rescue RuntimeError
640
    end
641

J
Joshua Peek 已提交
642 643
    assert @routes
    assert_equal routes_id, @routes.object_id
644
  end
645 646 647 648 649 650 651 652 653

  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
654

655
  def test_header_properly_reset_after_remote_http_request
656
    get :test_params, xhr: true
657 658
    assert_nil @request.env["HTTP_X_REQUESTED_WITH"]
    assert_nil @request.env["HTTP_ACCEPT"]
659 660
  end

661
  def test_xhr_with_params
662
    get :test_params, params: { id: 1 }, xhr: true
663

664
    assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
665 666 667
  end

  def test_xhr_with_session
668 669
    get :set_session, xhr: true

670 671 672 673
    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"
674 675
  end

G
Guo Xiang Tan 已提交
676
  def test_params_reset_between_post_requests
677
    post :no_op, params: { foo: "bar" }
678
    assert_equal "bar", @request.params[:foo]
G
Guo Xiang Tan 已提交
679

680
    post :no_op
681
    assert_predicate @request.params[:foo], :blank?
682 683
  end

684
  def test_filtered_parameters_reset_between_requests
685
    get :no_op, params: { foo: "bar" }
686 687
    assert_equal "bar", @request.filtered_parameters[:foo]

688
    get :no_op, params: { foo: "baz" }
689 690 691
    assert_equal "baz", @request.filtered_parameters[:foo]
  end

692 693 694 695 696 697 698 699
  def test_raw_post_reset_between_post_requests
    post :no_op, params: { foo: "bar" }
    assert_equal "foo=bar", @request.raw_post

    post :no_op, params: { foo: "baz" }
    assert_equal "foo=baz", @request.raw_post
  end

700 701 702 703 704 705 706 707
  def test_content_length_reset_after_post_request
    post :no_op, params: { foo: "bar" }
    assert_not_equal 0, @request.content_length

    get :no_op
    assert_equal 0, @request.content_length
  end

708 709
  def test_path_is_kept_after_the_request
    get :test_params, params: { id: "foo" }
R
Rafael Mendonça França 已提交
710
    assert_equal "/test_case_test/test/test_params/foo", @request.path
711 712
  end

G
Guo Xiang Tan 已提交
713
  def test_path_params_reset_between_request
714
    get :test_params, params: { id: "foo" }
715
    assert_equal "foo", @request.path_parameters[:id]
G
Guo Xiang Tan 已提交
716

717
    get :test_params
718
    assert_nil @request.path_parameters[:id]
719 720
  end

A
Andrew White 已提交
721 722 723 724 725 726 727 728 729 730 731 732 733
  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

734
  def test_request_format
735 736
    get :test_format, params: { format: "html" }
    assert_equal "text/html", @response.body
737

738 739
    get :test_format, params: { format: "json" }
    assert_equal "application/json", @response.body
740

741 742
    get :test_format, params: { format: "xml" }
    assert_equal "application/xml", @response.body
743 744

    get :test_format
745
    assert_equal "text/html", @response.body
746 747
  end

748
  def test_request_format_kwarg
749 750
    get :test_format, format: "html"
    assert_equal "text/html", @response.body
751

752 753
    get :test_format, format: "json"
    assert_equal "application/json", @response.body
754

755 756
    get :test_format, format: "xml"
    assert_equal "application/xml", @response.body
757 758

    get :test_format
759
    assert_equal "text/html", @response.body
760 761 762
  end

  def test_request_format_kwarg_overrides_params
763 764
    get :test_format, format: "json", params: { format: "html" }
    assert_equal "application/json", @response.body
765 766
  end

767 768 769 770 771 772 773 774
  def test_request_format_kwarg_doesnt_mutate_params
    params = { foo: "bar" }.freeze

    assert_nothing_raised do
      get :test_format, format: "json", params: params
    end
  end

775
  def test_should_have_knowledge_of_client_side_cookie_state_even_if_they_are_not_set
776
    cookies["foo"] = "bar"
777
    get :no_op
778
    assert_equal "bar", cookies["foo"]
779 780 781
  end

  def test_cookies_should_be_escaped_properly
782
    cookies["foo"] = "+"
783
    get :render_cookie
784
    assert_equal "+", @response.body
785 786 787
  end

  def test_should_detect_if_cookie_is_deleted
788
    cookies["foo"] = "bar"
789
    get :delete_cookie
790
    assert_nil cookies["foo"]
791 792
  end

793
  def test_multiple_mixed_method_process_should_scrub_rack_input
794
    post :test_params, params: { id: 1, foo: "an foo" }
795
    assert_equal({ "id" => "1", "foo" => "an foo", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
796

797
    get :test_params, params: { bar: "an bar" }
798
    assert_equal({ "bar" => "an bar", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))
799 800
  end

801 802 803 804 805 806 807 808
  %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
809
          assert_match(%r{@#{variable} is nil}, error.message)
810 811 812 813 814 815
        rescue => error
          assert false, "expected RuntimeError, got #{error.class}"
        end
      end
    end
  end
816

B
bogdanvlviv 已提交
817
  FILES_DIR = File.expand_path("../fixtures/multipart", __dir__)
818

819 820
  READ_BINARY = "rb:binary"
  READ_PLAIN = "r:binary"
821

822
  def test_test_uploaded_file
823
    filename = "ruby_on_rails.jpg"
824
    path = "#{FILES_DIR}/#{filename}"
825
    content_type = "image/png"
826
    expected = File.read(path)
827
    expected.force_encoding(Encoding::BINARY)
828

J
Joshua Peek 已提交
829
    file = Rack::Test::UploadedFile.new(path, content_type)
830 831 832
    assert_equal filename, file.original_filename
    assert_equal content_type, file.content_type
    assert_equal file.path, file.local_path
833
    assert_equal expected, file.read
834 835 836 837

    new_content_type = "new content_type"
    file.content_type = new_content_type
    assert_equal new_content_type, file.content_type
838
  end
J
Joshua Peek 已提交
839

840
  def test_fixture_path_is_accessed_from_self_instead_of_active_support_test_case
841
    TestCaseTest.stub :fixture_path, FILES_DIR do
842 843
      uploaded_file = fixture_file_upload("/ruby_on_rails.jpg", "image/png")
      assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
844
    end
845 846
  end

847
  def test_test_uploaded_file_with_binary
848
    filename = "ruby_on_rails.jpg"
849
    path = "#{FILES_DIR}/#{filename}"
850
    content_type = "image/png"
J
Joshua Peek 已提交
851

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

J
Joshua Peek 已提交
855
    plain_uploaded_file = Rack::Test::UploadedFile.new(path, content_type)
856
    assert_equal File.open(path, READ_PLAIN).read, plain_uploaded_file.read
857 858 859
  end

  def test_fixture_file_upload_with_binary
860
    filename = "ruby_on_rails.jpg"
861
    path = "#{FILES_DIR}/#{filename}"
862
    content_type = "image/jpg"
J
Joshua Peek 已提交
863

864
    binary_file_upload = fixture_file_upload(path, content_type, :binary)
865
    assert_equal File.open(path, READ_BINARY).read, binary_file_upload.read
J
Joshua Peek 已提交
866

867
    plain_file_upload = fixture_file_upload(path, content_type)
868
    assert_equal File.open(path, READ_PLAIN).read, plain_file_upload.read
869
  end
870

871
  def test_fixture_file_upload_should_be_able_access_to_tempfile
872
    file = fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg")
D
Daniel Colson 已提交
873
    assert_respond_to file, :tempfile
874 875
  end

876
  def test_fixture_file_upload
877 878
    post :test_file_upload,
      params: {
879
        file: fixture_file_upload(FILES_DIR + "/ruby_on_rails.jpg", "image/jpg")
880
      }
881
    assert_equal "45142", @response.body
882
  end
883

884
  def test_fixture_file_upload_relative_to_fixture_path
885
    TestCaseTest.stub :fixture_path, FILES_DIR do
886 887
      uploaded_file = fixture_file_upload("ruby_on_rails.jpg", "image/jpg")
      assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
888
    end
889 890
  end

891
  def test_fixture_file_upload_ignores_fixture_path_given_full_path
B
bogdanvlviv 已提交
892
    TestCaseTest.stub :fixture_path, __dir__ do
893 894
      uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg")
      assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
895 896 897
    end
  end

898
  def test_fixture_file_upload_ignores_nil_fixture_path
899 900
    uploaded_file = fixture_file_upload("#{FILES_DIR}/ruby_on_rails.jpg", "image/jpg")
    assert_equal File.open("#{FILES_DIR}/ruby_on_rails.jpg", READ_PLAIN).read, uploaded_file.read
901 902
  end

903
  def test_action_dispatch_uploaded_file_upload
904
    filename = "ruby_on_rails.jpg"
905
    path = "#{FILES_DIR}/#{filename}"
906
    post :test_file_upload, params: {
907
      file: Rack::Test::UploadedFile.new(path, "image/jpg", true)
908
    }
909
    assert_equal "45142", @response.body
910 911
  end

912
  def test_test_uploaded_file_exception_when_file_doesnt_exist
913
    assert_raise(RuntimeError) { Rack::Test::UploadedFile.new("non_existent_file") }
914
  end
915

916 917 918 919 920
  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.
921
    assert_equal "/resource", @response.redirect_url
922 923 924
    assert_equal @response.redirect_url, redirect_to_url

    # Must be a :redirect response.
925
    assert_raise(ActiveSupport::TestCase::Assertion) do
926
      assert_redirected_to "/resource"
927 928
    end
  end
929 930 931 932 933 934 935 936 937 938 939

  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",
940
        params: { q: "test1" }
941 942 943 944
    end

    process :test_query_string,
      method: "GET",
945
      params: { q: "test2" }
946 947 948

    assert_equal "q=test2", @response.body
  end
949
end
950

951 952 953 954
class ResponseDefaultHeadersTest < ActionController::TestCase
  class TestController < ActionController::Base
    def remove_header
      headers.delete params[:header]
955
      head :ok, "C" => "3"
956
    end
957 958 959 960 961

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

964
  def before_setup
965
    @original = ActionDispatch::Response.default_headers
966
    @defaults = { "A" => "1", "B" => "2" }
967
    ActionDispatch::Response.default_headers = @defaults
968
    super
969 970 971 972 973 974 975 976 977
  end

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

  def setup
    super
    @controller = TestController.new
978
    @request.env["PATH_INFO"] = nil
979 980
    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
981
        ActiveSupport::Deprecation.silence do
982
          get ":controller(/:action(/:id))"
983
        end
984 985 986 987 988
      end
    end
  end

  test "response contains default headers" do
989 990
    get :leave_alone

991
    # Response headers start out with the defaults
992
    assert_equal @defaults.merge("Content-Type" => "text/html"), response.headers
993
  end
994

995
  test "response deletes a default header" do
996
    get :remove_header, params: { header: "A" }
997 998 999 1000
    assert_response :ok

    # After a request, the response in the test case doesn't have the
    # defaults merged on top again.
1001 1002 1003
    assert_not_includes response.headers, "A"
    assert_includes response.headers, "B"
    assert_includes response.headers, "C"
1004 1005 1006
  end
end

1007 1008 1009 1010 1011
module EngineControllerTests
  class Engine < ::Rails::Engine
    isolate_namespace EngineControllerTests

    routes.draw do
1012
      get "/" => "bar#index"
1013 1014 1015 1016 1017
    end
  end

  class BarController < ActionController::Base
    def index
1018
      render plain: "bar"
1019 1020 1021 1022 1023 1024 1025 1026
    end
  end

  class BarControllerTest < ActionController::TestCase
    tests BarController

    def test_engine_controller_route
      get :index
1027
      assert_equal @response.body, "bar"
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
    end
  end

  class BarControllerTestWithExplicitRouteSet < ActionController::TestCase
    tests BarController

    def setup
      @routes = Engine.routes
    end

    def test_engine_controller_route
      get :index
1040
      assert_equal @response.body, "bar"
1041 1042 1043 1044
    end
  end
end

1045
class InferringClassNameTest < ActionController::TestCase
1046 1047 1048 1049 1050
  def test_determine_controller_class
    assert_equal ContentController, determine_class("ContentControllerTest")
  end

  def test_determine_controller_class_with_nonsense_name
1051
    assert_nil determine_class("HelloGoodBye")
1052 1053 1054
  end

  def test_determine_controller_class_with_sensible_name_where_no_controller_exists
1055
    assert_nil determine_class("NoControllerWithThisNameTest")
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
  end

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

class CrazyNameTest < ActionController::TestCase
  tests ContentController
1066

1067 1068 1069 1070
  def test_controller_class_can_be_set_manually_not_just_inferred
    assert_equal ContentController, self.class.controller_class
  end
end
1071

1072 1073 1074 1075 1076 1077 1078 1079 1080
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
1081
  tests "content"
1082 1083 1084 1085 1086 1087

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

1088 1089
class NamedRoutesControllerTest < ActionController::TestCase
  tests ContentController
J
Joshua Peek 已提交
1090

1091 1092
  def test_should_be_able_to_use_named_routes_before_a_request_is_done
    with_routing do |set|
1093
      set.draw { resources :contents }
1094 1095
      assert_equal "http://test.host/contents/new", new_content_url
      assert_equal "http://test.host/contents/1", content_url(id: 1)
1096 1097 1098
    end
  end
end
A
Andrew White 已提交
1099 1100 1101 1102 1103

class AnonymousControllerTest < ActionController::TestCase
  def setup
    @controller = Class.new(ActionController::Base) do
      def index
1104
        render plain: params[:controller]
A
Andrew White 已提交
1105 1106 1107 1108 1109
      end
    end.new

    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
1110
        ActiveSupport::Deprecation.silence do
1111
          get ":controller(/:action(/:id))"
1112
        end
A
Andrew White 已提交
1113 1114 1115 1116 1117 1118
      end
    end
  end

  def test_controller_name
    get :index
1119
    assert_equal "anonymous", @response.body
A
Andrew White 已提交
1120
  end
1121
end
1122 1123 1124 1125 1126

class RoutingDefaultsTest < ActionController::TestCase
  def setup
    @controller = Class.new(ActionController::Base) do
      def post
1127
        render plain: request.fullpath
1128 1129 1130
      end

      def project
1131
        render plain: request.fullpath
1132 1133 1134 1135 1136
      end
    end.new

    @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
      r.draw do
1137 1138
        get "/posts/:id", to: "anonymous#post", bucket_type: "post"
        get "/projects/:id", to: "anonymous#project", defaults: { bucket_type: "project" }
1139 1140 1141 1142 1143
      end
    end
  end

  def test_route_option_can_be_passed_via_process
1144
    get :post, params: { id: 1, bucket_type: "post" }
1145
    assert_equal "/posts/1", @response.body
1146 1147 1148
  end

  def test_route_default_is_not_required_for_building_request_uri
1149
    get :project, params: { id: 2 }
1150
    assert_equal "/projects/2", @response.body
1151 1152
  end
end