configuration_test.rb 57.5 KB
Newer Older
1 2
# frozen_string_literal: true

3
require "isolation/abstract_unit"
4 5
require "rack/test"
require "env_helpers"
6 7 8 9 10 11 12

class ::MyMailInterceptor
  def self.delivering_email(email); email; end
end

class ::MyOtherMailInterceptor < ::MyMailInterceptor; end

13 14 15 16 17 18
class ::MyPreviewMailInterceptor
  def self.previewing_email(email); email; end
end

class ::MyOtherPreviewMailInterceptor < ::MyPreviewMailInterceptor; end

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
class ::MyMailObserver
  def self.delivered_email(email); email; end
end

class ::MyOtherMailObserver < ::MyMailObserver; end

module ApplicationTests
  class ConfigurationTest < ActiveSupport::TestCase
    include ActiveSupport::Testing::Isolation
    include Rack::Test::Methods
    include EnvHelpers

    def new_app
      File.expand_path("#{app_path}/../new_app")
    end

    def copy_app
      FileUtils.cp_r(app_path, new_app)
    end

39 40 41 42 43 44 45 46 47 48
    def app(env = "development")
      @app ||= begin
        ENV["RAILS_ENV"] = env

        require "#{app_path}/config/environment"

        Rails.application
      ensure
        ENV.delete "RAILS_ENV"
      end
49 50 51 52
    end

    def setup
      build_app
53
      suppress_default_config
54 55 56 57 58 59 60
    end

    def teardown
      teardown_app
      FileUtils.rm_rf(new_app) if File.directory?(new_app)
    end

61
    def suppress_default_config
62 63 64 65 66 67 68 69
      FileUtils.mv("#{app_path}/config/environments", "#{app_path}/config/__environments__")
    end

    def restore_default_config
      FileUtils.rm_rf("#{app_path}/config/environments")
      FileUtils.mv("#{app_path}/config/__environments__", "#{app_path}/config/environments")
    end

70 71 72 73 74 75
    test "Rails.env does not set the RAILS_ENV environment variable which would leak out into rake tasks" do
      require "rails"

      switch_env "RAILS_ENV", nil do
        Rails.env = "development"
        assert_equal "development", Rails.env
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
        assert_nil ENV["RAILS_ENV"]
      end
    end

    test "Rails.env falls back to development if RAILS_ENV is blank and RACK_ENV is nil" do
      with_rails_env("") do
        assert_equal "development", Rails.env
      end
    end

    test "Rails.env falls back to development if RACK_ENV is blank and RAILS_ENV is nil" do
      with_rack_env("") do
        assert_equal "development", Rails.env
      end
    end

    test "By default logs tags are not set in development" do
      restore_default_config

      with_rails_env "development" do
        app "development"
        assert_predicate Rails.application.config.log_tags, :blank?
      end
    end

    test "By default logs are tagged with :request_id in production" do
      restore_default_config

      with_rails_env "production" do
        app "production"
        assert_equal [:request_id], Rails.application.config.log_tags
107 108 109
      end
    end

110
    test "lib dir is on LOAD_PATH during config" do
111
      app_file "lib/my_logger.rb", <<-RUBY
112 113 114 115 116 117 118 119
        require "logger"
        class MyLogger < ::Logger
        end
      RUBY
      add_to_top_of_config <<-RUBY
        require 'my_logger'
        config.logger = MyLogger.new STDOUT
      RUBY
120 121 122 123

      app "development"

      assert_equal "MyLogger", Rails.application.config.logger.class.name
124 125
    end

126 127 128 129 130 131 132
    test "a renders exception on pending migration" do
      add_to_config <<-RUBY
        config.active_record.migration_error    = :page_load
        config.consider_all_requests_local      = true
        config.action_dispatch.show_exceptions  = true
      RUBY

133 134
      app_file "db/migrate/20140708012246_create_user.rb", <<-RUBY
        class CreateUser < ActiveRecord::Migration::Current
135 136 137 138 139 140
          def change
            create_table :users
          end
        end
      RUBY

141
      app "development"
142

143 144 145 146 147 148 149 150 151
      ActiveRecord::Migrator.migrations_paths = ["#{app_path}/db/migrate"]

      begin
        get "/foo"
        assert_equal 500, last_response.status
        assert_match "ActiveRecord::PendingMigrationError", last_response.body
      ensure
        ActiveRecord::Migrator.migrations_paths = nil
      end
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    end

    test "Rails.groups returns available groups" do
      require "rails"

      Rails.env = "development"
      assert_equal [:default, "development"], Rails.groups
      assert_equal [:default, "development", :assets], Rails.groups(assets: [:development])
      assert_equal [:default, "development", :another, :assets], Rails.groups(:another, assets: %w(development))

      Rails.env = "test"
      assert_equal [:default, "test"], Rails.groups(assets: [:development])

      ENV["RAILS_GROUPS"] = "javascripts,stylesheets"
      assert_equal [:default, "test", "javascripts", "stylesheets"], Rails.groups
    end

    test "Rails.application is nil until app is initialized" do
170
      require "rails"
171
      assert_nil Rails.application
172
      app "development"
173 174 175 176
      assert_equal AppTemplate::Application.instance, Rails.application
    end

    test "Rails.application responds to all instance methods" do
177
      app "development"
178 179 180 181
      assert_equal Rails.application.routes_reloader, AppTemplate::Application.routes_reloader
    end

    test "Rails::Application responds to paths" do
182
      app "development"
183
      assert_equal ["#{app_path}/app/views"], AppTemplate::Application.paths["app/views"].expanded
184 185 186
    end

    test "the application root is set correctly" do
187
      app "development"
188 189 190 191
      assert_equal Pathname.new(app_path), Rails.application.root
    end

    test "the application root can be seen from the application singleton" do
192
      app "development"
193 194 195 196 197 198 199 200 201 202 203
      assert_equal Pathname.new(app_path), AppTemplate::Application.root
    end

    test "the application root can be set" do
      copy_app
      add_to_config <<-RUBY
        config.root = '#{new_app}'
      RUBY

      use_frameworks []

204 205
      app "development"

206 207 208 209 210 211 212 213 214
      assert_equal Pathname.new(new_app), Rails.application.root
    end

    test "the application root is Dir.pwd if there is no config.ru" do
      File.delete("#{app_path}/config.ru")

      use_frameworks []

      Dir.chdir("#{app_path}") do
215
        app "development"
216 217 218 219 220 221 222 223
        assert_equal Pathname.new("#{app_path}"), Rails.application.root
      end
    end

    test "Rails.root should be a Pathname" do
      add_to_config <<-RUBY
        config.root = "#{app_path}"
      RUBY
224 225 226

      app "development"

227 228 229 230 231 232 233
      assert_instance_of Pathname, Rails.root
    end

    test "Rails.public_path should be a Pathname" do
      add_to_config <<-RUBY
        config.paths["public"] = "somewhere"
      RUBY
234 235 236

      app "development"

237 238 239
      assert_instance_of Pathname, Rails.public_path
    end

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
    test "does not eager load controller actions in development" do
      app_file "app/controllers/posts_controller.rb", <<-RUBY
        class PostsController < ActionController::Base
          def index;end
          def show;end
        end
      RUBY

      app "development"

      assert_nil PostsController.instance_variable_get(:@action_methods)
    end

    test "eager loads controller actions in production" do
      app_file "app/controllers/posts_controller.rb", <<-RUBY
        class PostsController < ActionController::Base
          def index;end
          def show;end
        end
      RUBY

      add_to_config <<-RUBY
        config.eager_load = true
        config.cache_classes = true
      RUBY

      app "production"

      assert_equal %w(index show).to_set, PostsController.instance_variable_get(:@action_methods)
    end

    test "does not eager load mailer actions in development" do
      app_file "app/mailers/posts_mailer.rb", <<-RUBY
        class PostsMailer < ActionMailer::Base
          def noop_email;end
        end
      RUBY

      app "development"

      assert_nil PostsMailer.instance_variable_get(:@action_methods)
    end

    test "eager loads mailer actions in production" do
      app_file "app/mailers/posts_mailer.rb", <<-RUBY
        class PostsMailer < ActionMailer::Base
          def noop_email;end
        end
      RUBY

      add_to_config <<-RUBY
        config.eager_load = true
        config.cache_classes = true
      RUBY

      app "production"

      assert_equal %w(noop_email).to_set, PostsMailer.instance_variable_get(:@action_methods)
    end

300 301 302 303 304 305
    test "initialize an eager loaded, cache classes app" do
      add_to_config <<-RUBY
        config.eager_load = true
        config.cache_classes = true
      RUBY

306 307 308
      app "development"

      assert_equal :require, ActiveSupport::Dependencies.mechanism
309 310 311
    end

    test "application is always added to eager_load namespaces" do
312
      app "development"
313
      assert_includes Rails.application.config.eager_load_namespaces, AppTemplate::Application
314 315 316
    end

    test "the application can be eager loaded even when there are no frameworks" do
317 318 319
      FileUtils.rm_rf("#{app_path}/app/jobs/application_job.rb")
      FileUtils.rm_rf("#{app_path}/app/models/application_record.rb")
      FileUtils.rm_rf("#{app_path}/app/mailers/application_mailer.rb")
320 321 322 323 324 325 326 327 328
      FileUtils.rm_rf("#{app_path}/config/environments")
      add_to_config <<-RUBY
        config.eager_load = true
        config.cache_classes = true
      RUBY

      use_frameworks []

      assert_nothing_raised do
329
        app "development"
330 331 332 333 334 335 336 337 338 339 340
      end
    end

    test "filter_parameters should be able to set via config.filter_parameters" do
      add_to_config <<-RUBY
        config.filter_parameters += [ :foo, 'bar', lambda { |key, value|
          value = value.reverse if key =~ /baz/
        }]
      RUBY

      assert_nothing_raised do
341
        app "development"
342 343 344 345
      end
    end

    test "filter_parameters should be able to set via config.filter_parameters in an initializer" do
346
      app_file "config/initializers/filter_parameters_logging.rb", <<-RUBY
347 348 349
        Rails.application.config.filter_parameters += [ :password, :foo, 'bar' ]
      RUBY

350
      app "development"
351

352
      assert_equal [:password, :foo, "bar"], Rails.application.env_config["action_dispatch.parameter_filter"]
353 354 355 356 357 358 359 360 361 362 363 364 365
    end

    test "config.to_prepare is forwarded to ActionDispatch" do
      $prepared = false

      add_to_config <<-RUBY
        config.to_prepare do
          $prepared = true
        end
      RUBY

      assert !$prepared

366
      app "development"
367 368 369 370 371 372 373 374 375 376 377

      get "/"
      assert $prepared
    end

    def assert_utf8
      assert_equal Encoding::UTF_8, Encoding.default_external
      assert_equal Encoding::UTF_8, Encoding.default_internal
    end

    test "skipping config.encoding still results in 'utf-8' as the default" do
378
      app "development"
379 380 381 382 383 384 385 386
      assert_utf8
    end

    test "config.encoding sets the default encoding" do
      add_to_config <<-RUBY
        config.encoding = "utf-8"
      RUBY

387
      app "development"
388 389 390 391 392 393 394 395
      assert_utf8
    end

    test "config.paths.public sets Rails.public_path" do
      add_to_config <<-RUBY
        config.paths["public"] = "somewhere"
      RUBY

396
      app "development"
397 398 399
      assert_equal Pathname.new(app_path).join("somewhere"), Rails.public_path
    end

400
    test "In production mode, config.public_file_server.enabled is off by default" do
401 402 403
      restore_default_config

      with_rails_env "production" do
404 405
        app "production"
        assert_not app.config.public_file_server.enabled
406 407 408
      end
    end

409
    test "In production mode, config.public_file_server.enabled is enabled when RAILS_SERVE_STATIC_FILES is set" do
410 411 412 413
      restore_default_config

      with_rails_env "production" do
        switch_env "RAILS_SERVE_STATIC_FILES", "1" do
414 415
          app "production"
          assert app.config.public_file_server.enabled
416 417 418 419
        end
      end
    end

420
    test "In production mode, STDOUT logging is enabled when RAILS_LOG_TO_STDOUT is set" do
421 422 423
      restore_default_config

      with_rails_env "production" do
424 425 426
        switch_env "RAILS_LOG_TO_STDOUT", "1" do
          app "production"
          assert ActiveSupport::Logger.logger_outputs_to?(app.config.logger, STDOUT)
427 428 429 430
        end
      end
    end

431 432
    test "In production mode, config.public_file_server.enabled is disabled when RAILS_SERVE_STATIC_FILES is blank" do
      restore_default_config
433

434 435 436 437 438
      with_rails_env "production" do
        switch_env "RAILS_SERVE_STATIC_FILES", " " do
          app "production"
          assert_not app.config.public_file_server.enabled
        end
439 440 441
      end
    end

442
    test "Use key_generator when secret_key_base is set" do
443
      make_basic_app do |application|
444
        application.secrets.secret_key_base = "b3c631c314c0bbca50c1b2843150fe33"
445
        application.config.session_store :disabled
446 447 448 449 450
      end

      class ::OmgController < ActionController::Base
        def index
          cookies.signed[:some_key] = "some_value"
451
          render plain: cookies[:some_key]
452 453 454 455 456
        end
      end

      get "/"

457
      secret = app.key_generator.generate_key("signed cookie")
458
      verifier = ActiveSupport::MessageVerifier.new(secret)
459
      assert_equal "some_value", verifier.verify(last_response.body)
460 461
    end

Ondrej Sury's avatar
Ondrej Sury committed
462
    test "application verifier can be used in the entire application" do
463
      make_basic_app do |application|
464
        application.secrets.secret_key_base = "b3c631c314c0bbca50c1b2843150fe33"
465
        application.config.session_store :disabled
Ondrej Sury's avatar
Ondrej Sury committed
466 467 468 469
      end

      message = app.message_verifier(:sensitive_value).generate("some_value")

470
      assert_equal "some_value", Rails.application.message_verifier(:sensitive_value).verify(message)
Ondrej Sury's avatar
Ondrej Sury committed
471

472
      secret = app.key_generator.generate_key("sensitive_value")
Ondrej Sury's avatar
Ondrej Sury committed
473
      verifier = ActiveSupport::MessageVerifier.new(secret)
474
      assert_equal "some_value", verifier.verify(message)
Ondrej Sury's avatar
Ondrej Sury committed
475 476
    end

477
    test "application message verifier can be used when the key_generator is ActiveSupport::LegacyKeyGenerator" do
478 479
      app_file "config/initializers/secret_token.rb", <<-RUBY
        Rails.application.credentials.secret_key_base = nil
480 481 482
        Rails.application.config.secret_token = "b3c631c314c0bbca50c1b2843150fe33"
      RUBY

483
      app "production"
484

485
      assert_kind_of ActiveSupport::LegacyKeyGenerator, Rails.application.key_generator
486
      message = app.message_verifier(:sensitive_value).generate("some_value")
487
      assert_equal "some_value", Rails.application.message_verifier(:sensitive_value).verify(message)
488 489
    end

490 491
    test "config.secret_token is deprecated" do
      app_file "config/initializers/secret_token.rb", <<-RUBY
492 493
        Rails.application.config.secret_token = "b3c631c314c0bbca50c1b2843150fe33"
      RUBY
494 495 496 497 498 499 500 501 502 503 504 505

      app "production"

      assert_deprecated(/secret_token/) do
        app.secrets
      end
    end

    test "secrets.secret_token is deprecated" do
      app_file "config/secrets.yml", <<-YAML
        production:
          secret_token: "b3c631c314c0bbca50c1b2843150fe33"
506 507
      YAML

508 509 510 511 512 513 514 515
      app "production"

      assert_deprecated(/secret_token/) do
        app.secrets
      end
    end


516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
    test "application will generate secret_key_base in tmp file if blank in development" do
      app_file "config/initializers/secret_token.rb", <<-RUBY
        Rails.application.credentials.secret_key_base = nil
      RUBY

      app "development"

      assert_not_nil app.secrets.secret_key_base
      assert File.exist?(app_path("tmp/development_secret.txt"))
    end

    test "application will not generate secret_key_base in tmp file if blank in production" do
      app_file "config/initializers/secret_token.rb", <<-RUBY
        Rails.application.credentials.secret_key_base = nil
      RUBY

      assert_raises ArgumentError do
        app "production"
      end
    end

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
    test "raises when secret_key_base is blank" do
      app_file "config/initializers/secret_token.rb", <<-RUBY
        Rails.application.credentials.secret_key_base = nil
      RUBY

      error = assert_raise(ArgumentError) do
        app "production"
      end
      assert_match(/Missing `secret_key_base`./, error.message)
    end

    test "raise when secret_key_base is not a type of string" do
      add_to_config <<-RUBY
        Rails.application.credentials.secret_key_base = 123
      RUBY

      assert_raise(ArgumentError) do
        app "production"
555 556 557 558
      end
    end

    test "prefer secrets.secret_token over config.secret_token" do
559
      app_file "config/initializers/secret_token.rb", <<-RUBY
560 561
        Rails.application.config.secret_token = ""
      RUBY
562
      app_file "config/secrets.yml", <<-YAML
563 564 565 566
        development:
          secret_token: 3b7cd727ee24e8444053437c36cc66c3
      YAML

567 568 569
      app "development"

      assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secrets.secret_token
570 571
    end

Ondrej Sury's avatar
Ondrej Sury committed
572
    test "application verifier can build different verifiers" do
573 574
      make_basic_app do |application|
        application.config.session_store :disabled
Ondrej Sury's avatar
Ondrej Sury committed
575 576 577 578 579
      end

      default_verifier = app.message_verifier(:sensitive_value)
      text_verifier = app.message_verifier(:text)

580
      message = text_verifier.generate("some_value")
Ondrej Sury's avatar
Ondrej Sury committed
581

582
      assert_equal "some_value", text_verifier.verify(message)
Ondrej Sury's avatar
Ondrej Sury committed
583 584 585 586 587 588 589 590 591
      assert_raises ActiveSupport::MessageVerifier::InvalidSignature do
        default_verifier.verify(message)
      end

      assert_equal default_verifier.object_id, app.message_verifier(:sensitive_value).object_id
      assert_not_equal default_verifier.object_id, text_verifier.object_id
    end

    test "secrets.secret_key_base is used when config/secrets.yml is present" do
592
      app_file "config/secrets.yml", <<-YAML
Ondrej Sury's avatar
Ondrej Sury committed
593 594 595 596
        development:
          secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
      YAML

597 598
      app "development"
      assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secrets.secret_key_base
599
      assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secret_key_base
Ondrej Sury's avatar
Ondrej Sury committed
600 601 602 603
    end

    test "secret_key_base is copied from config to secrets when not set" do
      remove_file "config/secrets.yml"
604
      app_file "config/initializers/secret_token.rb", <<-RUBY
Ondrej Sury's avatar
Ondrej Sury committed
605 606 607
        Rails.application.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c3"
      RUBY

608 609
      app "development"
      assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secrets.secret_key_base
Ondrej Sury's avatar
Ondrej Sury committed
610 611
    end

612
    test "config.secret_token over-writes a blank secrets.secret_token" do
613
      app_file "config/initializers/secret_token.rb", <<-RUBY
614 615
        Rails.application.config.secret_token = "b3c631c314c0bbca50c1b2843150fe33"
      RUBY
616
      app_file "config/secrets.yml", <<-YAML
617 618 619 620 621
        development:
          secret_key_base:
          secret_token:
      YAML

622 623 624 625
      app "development"

      assert_equal "b3c631c314c0bbca50c1b2843150fe33", app.secrets.secret_token
      assert_equal "b3c631c314c0bbca50c1b2843150fe33", app.config.secret_token
626 627
    end

Ondrej Sury's avatar
Ondrej Sury committed
628
    test "custom secrets saved in config/secrets.yml are loaded in app secrets" do
629
      app_file "config/secrets.yml", <<-YAML
Ondrej Sury's avatar
Ondrej Sury committed
630 631 632 633 634 635
        development:
          secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
          aws_access_key_id: myamazonaccesskeyid
          aws_secret_access_key: myamazonsecretaccesskey
      YAML

636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
      app "development"

      assert_equal "myamazonaccesskeyid", app.secrets.aws_access_key_id
      assert_equal "myamazonsecretaccesskey", app.secrets.aws_secret_access_key
    end

    test "shared secrets saved in config/secrets.yml are loaded in app secrets" do
      app_file "config/secrets.yml", <<-YAML
        shared:
          api_key: 3b7cd727
      YAML

      app "development"

      assert_equal "3b7cd727", app.secrets.api_key
    end

    test "shared secrets will yield to environment specific secrets" do
      app_file "config/secrets.yml", <<-YAML
        shared:
          api_key: 3b7cd727

        development:
          api_key: abc12345
      YAML

      app "development"

      assert_equal "abc12345", app.secrets.api_key
Ondrej Sury's avatar
Ondrej Sury committed
665 666 667
    end

    test "blank config/secrets.yml does not crash the loading process" do
668
      app_file "config/secrets.yml", <<-YAML
Ondrej Sury's avatar
Ondrej Sury committed
669
      YAML
670 671

      app "development"
Ondrej Sury's avatar
Ondrej Sury committed
672 673 674 675

      assert_nil app.secrets.not_defined
    end

676
    test "config.secret_key_base over-writes a blank secrets.secret_key_base" do
677
      app_file "config/initializers/secret_token.rb", <<-RUBY
678 679
        Rails.application.config.secret_key_base = "iaminallyoursecretkeybase"
      RUBY
680
      app_file "config/secrets.yml", <<-YAML
681 682 683
        development:
          secret_key_base:
      YAML
684 685

      app "development"
686 687 688 689 690

      assert_equal "iaminallyoursecretkeybase", app.secrets.secret_key_base
    end

    test "uses ActiveSupport::LegacyKeyGenerator as app.key_generator when secrets.secret_key_base is blank" do
691 692
      app_file "config/initializers/secret_token.rb", <<-RUBY
        Rails.application.credentials.secret_key_base = nil
693 694 695
        Rails.application.config.secret_token = "b3c631c314c0bbca50c1b2843150fe33"
      RUBY

696 697 698 699 700
      app "production"

      assert_equal "b3c631c314c0bbca50c1b2843150fe33", app.config.secret_token
      assert_nil app.credentials.secret_key_base
      assert_kind_of ActiveSupport::LegacyKeyGenerator, app.key_generator
701 702
    end

703 704
    test "that nested keys are symbolized the same as parents for hashes more than one level deep" do
      app_file "config/secrets.yml", <<-YAML
705
        development:
706 707 708 709
          smtp_settings:
            address: "smtp.example.com"
            user_name: "postmaster@example.com"
            password: "697361616320736c6f616e2028656c6f7265737429"
710 711
      YAML

712 713 714 715 716 717 718 719 720 721 722 723 724
      app "development"

      assert_equal "697361616320736c6f616e2028656c6f7265737429", app.secrets.smtp_settings[:password]
    end

    test "require_master_key aborts app boot when missing key" do
      skip "can't run without fork" unless Process.respond_to?(:fork)

      remove_file "config/master.key"
      add_to_config "config.require_master_key = true"

      error = capture(:stderr) do
        Process.wait(Process.fork { app "development" })
725
      end
726 727 728 729 730 731 732 733 734 735 736

      assert_equal 1, $?.exitstatus
      assert_match(/Missing.*RAILS_MASTER_KEY/, error)
    end

    test "credentials does not raise error when require_master_key is false and master key does not exist" do
      remove_file "config/master.key"
      add_to_config "config.require_master_key = false"
      app "development"

      assert_not app.credentials.secret_key_base
737 738
    end

739 740 741 742 743 744 745 746 747 748 749 750 751
    test "protect from forgery is the default in a new app" do
      make_basic_app

      class ::OmgController < ActionController::Base
        def index
          render inline: "<%= csrf_meta_tags %>"
        end
      end

      get "/"
      assert last_response.body =~ /csrf\-param/
    end

752
    test "default form builder specified as a string" do
753
      app_file "config/initializers/form_builder.rb", <<-RUBY
754 755 756 757 758 759 760 761
      class CustomFormBuilder < ActionView::Helpers::FormBuilder
        def text_field(attribute, *args)
          label(attribute) + super(attribute, *args)
        end
      end
      Rails.configuration.action_view.default_form_builder = "CustomFormBuilder"
      RUBY

762
      app_file "app/models/post.rb", <<-RUBY
763 764 765 766 767 768
      class Post
        include ActiveModel::Model
        attr_accessor :name
      end
      RUBY

769
      app_file "app/controllers/posts_controller.rb", <<-RUBY
770 771 772 773 774 775 776 777 778 779 780 781 782
      class PostsController < ApplicationController
        def index
          render inline: "<%= begin; form_for(Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

783
      app "development"
784 785 786 787 788

      get "/posts"
      assert_match(/label/, last_response.body)
    end

789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
    test "form_with can be configured with form_with_generates_ids" do
      app_file "config/initializers/form_builder.rb", <<-RUBY
      Rails.configuration.action_view.form_with_generates_ids = false
      RUBY

      app_file "app/models/post.rb", <<-RUBY
      class Post
        include ActiveModel::Model
        attr_accessor :name
      end
      RUBY

      app_file "app/controllers/posts_controller.rb", <<-RUBY
      class PostsController < ApplicationController
        def index
          render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

      app "development"

      get "/posts"

      assert_no_match(/id=('|")post_name('|")/, last_response.body)
    end

    test "form_with outputs ids by default" do
      app_file "app/models/post.rb", <<-RUBY
      class Post
        include ActiveModel::Model
        attr_accessor :name
      end
      RUBY

      app_file "app/controllers/posts_controller.rb", <<-RUBY
      class PostsController < ApplicationController
        def index
          render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

      app "development"

      get "/posts"

      assert_match(/id=('|")post_name('|")/, last_response.body)
    end

    test "form_with can be configured with form_with_generates_remote_forms" do
      app_file "config/initializers/form_builder.rb", <<-RUBY
      Rails.configuration.action_view.form_with_generates_remote_forms = false
      RUBY

      app_file "app/models/post.rb", <<-RUBY
      class Post
        include ActiveModel::Model
        attr_accessor :name
      end
      RUBY

      app_file "app/controllers/posts_controller.rb", <<-RUBY
      class PostsController < ApplicationController
        def index
          render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

      app "development"

      get "/posts"
      assert_no_match(/data-remote/, last_response.body)
    end

    test "form_with generates remote forms by default" do
      app_file "app/models/post.rb", <<-RUBY
      class Post
        include ActiveModel::Model
        attr_accessor :name
      end
      RUBY

      app_file "app/controllers/posts_controller.rb", <<-RUBY
      class PostsController < ApplicationController
        def index
          render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

      app "development"

      get "/posts"
      assert_match(/data-remote/, last_response.body)
    end

911
    test "default method for update can be changed" do
912
      app_file "app/models/post.rb", <<-RUBY
913
      class Post
914
        include ActiveModel::Model
915 916 917 918 919
        def to_key; [1]; end
        def persisted?; true; end
      end
      RUBY

920 921
      token = "cf50faa3fe97702ca1ae"

922
      app_file "app/controllers/posts_controller.rb", <<-RUBY
923 924 925 926 927 928
      class PostsController < ApplicationController
        def show
          render inline: "<%= begin; form_for(Post.new) {}; rescue => e; e.to_s; end %>"
        end

        def update
929
          render plain: "update"
930
        end
931 932 933

        private

934
        def form_authenticity_token(*args); token; end # stub the authenticity token
935 936 937 938 939 940 941 942 943
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

944
      app "development"
945

946
      params = { authenticity_token: token }
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964

      get "/posts/1"
      assert_match(/patch/, last_response.body)

      patch "/posts/1", params
      assert_match(/update/, last_response.body)

      patch "/posts/1", params
      assert_equal 200, last_response.status

      put "/posts/1", params
      assert_match(/update/, last_response.body)

      put "/posts/1", params
      assert_equal 200, last_response.status
    end

    test "request forgery token param can be changed" do
965
      make_basic_app do |application|
966
        application.config.action_controller.request_forgery_protection_token = "_xsrf_token_here"
967 968 969 970 971 972 973 974 975
      end

      class ::OmgController < ActionController::Base
        def index
          render inline: "<%= csrf_meta_tags %>"
        end
      end

      get "/"
976
      assert_match "_xsrf_token_here", last_response.body
977 978 979 980 981 982 983 984
    end

    test "sets ActionDispatch.test_app" do
      make_basic_app
      assert_equal Rails.application, ActionDispatch.test_app
    end

    test "sets ActionDispatch::Response.default_charset" do
985 986
      make_basic_app do |application|
        application.config.action_dispatch.default_charset = "utf-16"
987 988 989 990 991 992 993 994 995 996
      end

      assert_equal "utf-16", ActionDispatch::Response.default_charset
    end

    test "registers interceptors with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.interceptors = MyMailInterceptor
      RUBY

997
      app "development"
998

999
      require "mail"
1000 1001
      _ = ActionMailer::Base

1002
      assert_equal [::MyMailInterceptor], ::Mail.class_variable_get(:@@delivery_interceptors)
1003 1004 1005 1006 1007 1008 1009
    end

    test "registers multiple interceptors with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.interceptors = [MyMailInterceptor, "MyOtherMailInterceptor"]
      RUBY

1010
      app "development"
1011

1012
      require "mail"
1013 1014
      _ = ActionMailer::Base

1015
      assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.class_variable_get(:@@delivery_interceptors)
1016 1017
    end

1018 1019 1020 1021 1022
    test "registers preview interceptors with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.preview_interceptors = MyPreviewMailInterceptor
      RUBY

1023
      app "development"
1024

1025
      require "mail"
1026 1027
      _ = ActionMailer::Base

1028
      assert_equal [ActionMailer::InlinePreviewInterceptor, ::MyPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
1029 1030 1031 1032 1033 1034 1035
    end

    test "registers multiple preview interceptors with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.preview_interceptors = [MyPreviewMailInterceptor, "MyOtherPreviewMailInterceptor"]
      RUBY

1036 1037
      app "development"

1038
      require "mail"
1039 1040 1041 1042 1043 1044 1045 1046 1047
      _ = ActionMailer::Base

      assert_equal [ActionMailer::InlinePreviewInterceptor, MyPreviewMailInterceptor, MyOtherPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
    end

    test "default preview interceptor can be removed" do
      app_file "config/initializers/preview_interceptors.rb", <<-RUBY
        ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
      RUBY
1048

1049 1050 1051
      app "development"

      require "mail"
1052 1053
      _ = ActionMailer::Base

1054
      assert_equal [], ActionMailer::Base.preview_interceptors
1055 1056
    end

1057 1058 1059 1060 1061
    test "registers observers with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.observers = MyMailObserver
      RUBY

1062
      app "development"
1063

1064
      require "mail"
1065 1066
      _ = ActionMailer::Base

1067
      assert_equal [::MyMailObserver], ::Mail.class_variable_get(:@@delivery_notification_observers)
1068 1069 1070 1071 1072 1073 1074
    end

    test "registers multiple observers with ActionMailer" do
      add_to_config <<-RUBY
        config.action_mailer.observers = [MyMailObserver, "MyOtherMailObserver"]
      RUBY

1075 1076
      app "development"

1077
      require "mail"
1078 1079 1080 1081 1082 1083 1084 1085 1086
      _ = ActionMailer::Base

      assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.class_variable_get(:@@delivery_notification_observers)
    end

    test "allows setting the queue name for the ActionMailer::DeliveryJob" do
      add_to_config <<-RUBY
        config.action_mailer.deliver_later_queue_name = 'test_default'
      RUBY
1087

1088 1089 1090
      app "development"

      require "mail"
1091 1092
      _ = ActionMailer::Base

1093
      assert_equal "test_default", ActionMailer::Base.class_variable_get(:@@deliver_later_queue_name)
1094 1095 1096 1097 1098
    end

    test "valid timezone is setup correctly" do
      add_to_config <<-RUBY
        config.root = "#{app_path}"
1099
        config.time_zone = "Wellington"
1100 1101
      RUBY

1102
      app "development"
1103 1104 1105 1106 1107 1108 1109

      assert_equal "Wellington", Rails.application.config.time_zone
    end

    test "raises when an invalid timezone is defined in the config" do
      add_to_config <<-RUBY
        config.root = "#{app_path}"
1110
        config.time_zone = "That big hill over yonder hill"
1111 1112 1113
      RUBY

      assert_raise(ArgumentError) do
1114
        app "development"
1115 1116 1117 1118 1119 1120
      end
    end

    test "valid beginning of week is setup correctly" do
      add_to_config <<-RUBY
        config.root = "#{app_path}"
1121
        config.beginning_of_week = :wednesday
1122 1123
      RUBY

1124
      app "development"
1125 1126 1127 1128 1129 1130 1131

      assert_equal :wednesday, Rails.application.config.beginning_of_week
    end

    test "raises when an invalid beginning of week is defined in the config" do
      add_to_config <<-RUBY
        config.root = "#{app_path}"
1132
        config.beginning_of_week = :invalid
1133 1134 1135
      RUBY

      assert_raise(ArgumentError) do
1136
        app "development"
1137 1138 1139 1140 1141
      end
    end

    test "config.action_view.cache_template_loading with cache_classes default" do
      add_to_config "config.cache_classes = true"
1142 1143 1144

      app "development"
      require "action_view/base"
1145

Ondrej Sury's avatar
Ondrej Sury committed
1146
      assert_equal true, ActionView::Resolver.caching?
1147 1148 1149 1150
    end

    test "config.action_view.cache_template_loading without cache_classes default" do
      add_to_config "config.cache_classes = false"
1151 1152 1153

      app "development"
      require "action_view/base"
1154

Ondrej Sury's avatar
Ondrej Sury committed
1155
      assert_equal false, ActionView::Resolver.caching?
1156 1157 1158 1159 1160 1161 1162
    end

    test "config.action_view.cache_template_loading = false" do
      add_to_config <<-RUBY
        config.cache_classes = true
        config.action_view.cache_template_loading = false
      RUBY
1163 1164 1165

      app "development"
      require "action_view/base"
1166

Ondrej Sury's avatar
Ondrej Sury committed
1167
      assert_equal false, ActionView::Resolver.caching?
1168 1169 1170 1171 1172 1173 1174
    end

    test "config.action_view.cache_template_loading = true" do
      add_to_config <<-RUBY
        config.cache_classes = false
        config.action_view.cache_template_loading = true
      RUBY
1175 1176 1177

      app "development"
      require "action_view/base"
1178

Ondrej Sury's avatar
Ondrej Sury committed
1179 1180 1181 1182 1183 1184 1185 1186
      assert_equal true, ActionView::Resolver.caching?
    end

    test "config.action_view.cache_template_loading with cache_classes in an environment" do
      build_app(initializers: true)
      add_to_env_config "development", "config.cache_classes = false"

      # These requires are to emulate an engine loading Action View before the application
1187 1188 1189
      require "action_view"
      require "action_view/railtie"
      require "action_view/base"
Ondrej Sury's avatar
Ondrej Sury committed
1190

1191
      app "development"
Ondrej Sury's avatar
Ondrej Sury committed
1192 1193

      assert_equal false, ActionView::Resolver.caching?
1194 1195 1196
    end

    test "config.action_dispatch.show_exceptions is sent in env" do
1197 1198
      make_basic_app do |application|
        application.config.action_dispatch.show_exceptions = true
1199 1200 1201 1202
      end

      class ::OmgController < ActionController::Base
        def index
1203
          render plain: request.env["action_dispatch.show_exceptions"]
1204 1205 1206 1207
        end
      end

      get "/"
1208
      assert_equal "true", last_response.body
1209 1210 1211
    end

    test "config.action_controller.wrap_parameters is set in ActionController::Base" do
1212
      app_file "config/initializers/wrap_parameters.rb", <<-RUBY
1213 1214 1215
        ActionController::Base.wrap_parameters format: [:json]
      RUBY

1216
      app_file "app/models/post.rb", <<-RUBY
1217 1218 1219 1220 1221 1222 1223
      class Post
        def self.attribute_names
          %w(title)
        end
      end
      RUBY

1224
      app_file "app/controllers/application_controller.rb", <<-RUBY
1225 1226 1227 1228 1229
      class ApplicationController < ActionController::Base
        protect_from_forgery with: :reset_session # as we are testing API here
      end
      RUBY

1230
      app_file "app/controllers/posts_controller.rb", <<-RUBY
1231 1232
      class PostsController < ApplicationController
        def create
1233
          render plain: params[:post].inspect
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
      RUBY

1244
      app "development"
1245 1246

      post "/posts.json", '{ "title": "foo", "name": "bar" }', "CONTENT_TYPE" => "application/json"
1247
      assert_equal '<ActionController::Parameters {"title"=>"foo"} permitted: false>', last_response.body
1248 1249 1250
    end

    test "config.action_controller.permit_all_parameters = true" do
1251
      app_file "app/controllers/posts_controller.rb", <<-RUBY
1252 1253
      class PostsController < ActionController::Base
        def create
1254
          render plain: params[:post].permitted? ? "permitted" : "forbidden"
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
        config.action_controller.permit_all_parameters = true
      RUBY

1266
      app "development"
1267

1268 1269
      post "/posts", post: { "title" => "zomg" }
      assert_equal "permitted", last_response.body
1270 1271 1272
    end

    test "config.action_controller.action_on_unpermitted_parameters = :raise" do
1273
      app_file "app/controllers/posts_controller.rb", <<-RUBY
1274 1275
      class PostsController < ActionController::Base
        def create
1276
          render plain: params.require(:post).permit(:name)
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
        config.action_controller.action_on_unpermitted_parameters = :raise
      RUBY

1288 1289 1290 1291
      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
1292 1293 1294

      assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters

1295
      post "/posts", post: { "title" => "zomg" }
1296 1297 1298
      assert_match "We're sorry, but something went wrong", last_response.body
    end

1299
    test "config.action_controller.always_permitted_parameters are: controller, action by default" do
1300 1301 1302 1303 1304
      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }

1305 1306 1307 1308 1309 1310 1311
      assert_equal %w(controller action), ActionController::Parameters.always_permitted_parameters
    end

    test "config.action_controller.always_permitted_parameters = ['controller', 'action', 'format']" do
      add_to_config <<-RUBY
        config.action_controller.always_permitted_parameters = %w( controller action format )
      RUBY
1312 1313 1314 1315 1316 1317

      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }

1318 1319 1320
      assert_equal %w( controller action format ), ActionController::Parameters.always_permitted_parameters
    end

1321 1322
    test "config.action_controller.always_permitted_parameters = ['controller','action','format'] does not raise exception" do
      app_file "app/controllers/posts_controller.rb", <<-RUBY
1323 1324
      class PostsController < ActionController::Base
        def create
1325
          render plain: params.permit(post: [:title])
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
        end
      end
      RUBY

      add_to_config <<-RUBY
        routes.prepend do
          resources :posts
        end
        config.action_controller.always_permitted_parameters = %w( controller action format )
        config.action_controller.action_on_unpermitted_parameters = :raise
      RUBY

1338 1339 1340 1341
      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
1342 1343 1344

      assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters

1345
      post "/posts", post: { "title" => "zomg" }, format: "json"
1346 1347 1348
      assert_equal 200, last_response.status
    end

1349 1350
    test "config.action_controller.action_on_unpermitted_parameters is :log by default in development" do
      app "development"
1351

1352 1353
      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
1354 1355 1356 1357

      assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
    end

1358 1359
    test "config.action_controller.action_on_unpermitted_parameters is :log by default in test" do
      app "test"
1360

1361 1362
      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
1363 1364 1365 1366

      assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
    end

1367 1368
    test "config.action_controller.action_on_unpermitted_parameters is false by default in production" do
      app "production"
1369

1370 1371
      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
1372 1373 1374 1375

      assert_equal false, ActionController::Parameters.action_on_unpermitted_parameters
    end

1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
    test "config.action_controller.default_protect_from_forgery is true by default" do
      app "development"

      assert_equal true, ActionController::Base.default_protect_from_forgery
      assert_includes ActionController::Base.__callbacks[:process_action].map(&:filter), :verify_authenticity_token
    end

    test "config.action_controller.permit_all_parameters can be configured in an initializer" do
      app_file "config/initializers/permit_all_parameters.rb", <<-RUBY
        Rails.application.config.action_controller.permit_all_parameters = true
      RUBY

      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
      assert_equal true, ActionController::Parameters.permit_all_parameters
    end

    test "config.action_controller.always_permitted_parameters can be configured in an initializer" do
      app_file "config/initializers/always_permitted_parameters.rb", <<-RUBY
        Rails.application.config.action_controller.always_permitted_parameters = []
      RUBY

      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
      assert_equal [], ActionController::Parameters.always_permitted_parameters
    end

    test "config.action_controller.action_on_unpermitted_parameters can be configured in an initializer" do
      app_file "config/initializers/action_on_unpermitted_parameters.rb", <<-RUBY
        Rails.application.config.action_controller.action_on_unpermitted_parameters = :raise
      RUBY

      app "development"

      force_lazy_load_hooks { ActionController::Base }
      force_lazy_load_hooks { ActionController::API }
      assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
    end

1419
    test "config.action_dispatch.ignore_accept_header" do
1420 1421
      make_basic_app do |application|
        application.config.action_dispatch.ignore_accept_header = true
1422 1423 1424 1425 1426
      end

      class ::OmgController < ActionController::Base
        def index
          respond_to do |format|
1427 1428
            format.html { render plain: "HTML" }
            format.xml { render plain: "XML" }
1429 1430 1431 1432
          end
        end
      end

1433 1434
      get "/", {}, { "HTTP_ACCEPT" => "application/xml" }
      assert_equal "HTML", last_response.body
1435

1436 1437
      get "/", { format: :xml }, { "HTTP_ACCEPT" => "application/xml" }
      assert_equal "XML", last_response.body
1438 1439 1440 1441 1442
    end

    test "Rails.application#env_config exists and include some existing parameters" do
      make_basic_app

1443 1444 1445 1446 1447
      assert_equal app.env_config["action_dispatch.parameter_filter"],  app.config.filter_parameters
      assert_equal app.env_config["action_dispatch.show_exceptions"],   app.config.action_dispatch.show_exceptions
      assert_equal app.env_config["action_dispatch.logger"],            Rails.logger
      assert_equal app.env_config["action_dispatch.backtrace_cleaner"], Rails.backtrace_cleaner
      assert_equal app.env_config["action_dispatch.key_generator"],     Rails.application.key_generator
1448 1449 1450 1451 1452 1453 1454 1455 1456
    end

    test "config.colorize_logging default is true" do
      make_basic_app
      assert app.config.colorize_logging
    end

    test "config.session_store with :active_record_store with activerecord-session_store gem" do
      begin
1457
        make_basic_app do |application|
1458
          ActionDispatch::Session::ActiveRecordStore = Class.new(ActionDispatch::Session::CookieStore)
1459
          application.config.session_store :active_record_store
1460 1461 1462 1463 1464 1465 1466
        end
      ensure
        ActionDispatch::Session.send :remove_const, :ActiveRecordStore
      end
    end

    test "config.session_store with :active_record_store without activerecord-session_store gem" do
1467
      e = assert_raise RuntimeError do
1468 1469
        make_basic_app do |application|
          application.config.session_store :active_record_store
1470 1471
        end
      end
1472
      assert_match(/activerecord-session_store/, e.message)
1473
    end
1474

1475 1476 1477
    test "default session store initializer does not overwrite the user defined session store even if it is disabled" do
      make_basic_app do |application|
        application.config.session_store :disabled
1478 1479
      end

1480
      assert_nil app.config.session_store
1481 1482
    end

1483 1484 1485 1486 1487 1488
    test "default session store initializer sets session store to cookie store" do
      session_options = { key: "_myapp_session", cookie_only: true }
      make_basic_app

      assert_equal ActionDispatch::Session::CookieStore, app.config.session_store
      assert_equal session_options, app.config.session_options
1489 1490
    end

1491
    test "config.log_level with custom logger" do
1492 1493 1494
      make_basic_app do |application|
        application.config.logger = Logger.new(STDOUT)
        application.config.log_level = :info
1495 1496 1497
      end
      assert_equal Logger::INFO, Rails.logger.level
    end
Ondrej Sury's avatar
Ondrej Sury committed
1498 1499 1500 1501

    test "respond_to? accepts include_private" do
      make_basic_app

1502
      assert_not_respond_to Rails.configuration, :method_missing
Ondrej Sury's avatar
Ondrej Sury committed
1503 1504 1505 1506 1507 1508
      assert Rails.configuration.respond_to?(:method_missing, true)
    end

    test "config.active_record.dump_schema_after_migration is false on production" do
      build_app

1509
      app "production"
Ondrej Sury's avatar
Ondrej Sury committed
1510 1511 1512 1513

      assert_not ActiveRecord::Base.dump_schema_after_migration
    end

1514 1515
    test "config.active_record.dump_schema_after_migration is true by default in development" do
      app "development"
Ondrej Sury's avatar
Ondrej Sury committed
1516 1517 1518 1519

      assert ActiveRecord::Base.dump_schema_after_migration
    end

1520 1521 1522 1523 1524 1525
    test "config.active_record.verbose_query_logs is false by default in development" do
      app "development"

      assert_not ActiveRecord::Base.verbose_query_logs
    end

1526 1527 1528 1529 1530 1531 1532 1533 1534
    test "config.annotations wrapping SourceAnnotationExtractor::Annotation class" do
      make_basic_app do |application|
        application.config.annotations.register_extensions("coffee") do |tag|
          /#\s*(#{tag}):?\s*(.*)$/
        end
      end

      assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/]
    end
Ondrej Sury's avatar
Ondrej Sury committed
1535

1536
    test "rake_tasks block works at instance level" do
Ondrej Sury's avatar
Ondrej Sury committed
1537 1538
      app_file "config/environments/development.rb", <<-RUBY
        Rails.application.configure do
1539 1540
          config.ran_block = false

Ondrej Sury's avatar
Ondrej Sury committed
1541
          rake_tasks do
1542
            config.ran_block = true
Ondrej Sury's avatar
Ondrej Sury committed
1543 1544 1545 1546
          end
        end
      RUBY

1547
      app "development"
1548
      assert_not Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1549

1550 1551 1552
      require "rake"
      require "rake/testtask"
      require "rdoc/task"
Ondrej Sury's avatar
Ondrej Sury committed
1553 1554

      Rails.application.load_tasks
1555
      assert Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1556 1557 1558 1559 1560
    end

    test "generators block works at instance level" do
      app_file "config/environments/development.rb", <<-RUBY
        Rails.application.configure do
1561 1562
          config.ran_block = false

Ondrej Sury's avatar
Ondrej Sury committed
1563
          generators do
1564
            config.ran_block = true
Ondrej Sury's avatar
Ondrej Sury committed
1565 1566 1567 1568
          end
        end
      RUBY

1569
      app "development"
1570
      assert_not Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1571 1572

      Rails.application.load_generators
1573
      assert Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1574 1575 1576 1577 1578
    end

    test "console block works at instance level" do
      app_file "config/environments/development.rb", <<-RUBY
        Rails.application.configure do
1579 1580
          config.ran_block = false

Ondrej Sury's avatar
Ondrej Sury committed
1581
          console do
1582
            config.ran_block = true
Ondrej Sury's avatar
Ondrej Sury committed
1583 1584 1585 1586
          end
        end
      RUBY

1587
      app "development"
1588
      assert_not Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1589 1590

      Rails.application.load_console
1591
      assert Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1592 1593 1594 1595 1596
    end

    test "runner block works at instance level" do
      app_file "config/environments/development.rb", <<-RUBY
        Rails.application.configure do
1597 1598
          config.ran_block = false

Ondrej Sury's avatar
Ondrej Sury committed
1599
          runner do
1600
            config.ran_block = true
Ondrej Sury's avatar
Ondrej Sury committed
1601 1602 1603 1604
          end
        end
      RUBY

1605
      app "development"
1606
      assert_not Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1607 1608

      Rails.application.load_runner
1609
      assert Rails.configuration.ran_block
Ondrej Sury's avatar
Ondrej Sury committed
1610 1611 1612
    end

    test "loading the first existing database configuration available" do
1613
      app_file "config/environments/development.rb", <<-RUBY
Ondrej Sury's avatar
Ondrej Sury committed
1614 1615

      Rails.application.configure do
1616
        config.paths.add 'config/database', with: 'config/nonexistent.yml'
Ondrej Sury's avatar
Ondrej Sury committed
1617 1618 1619 1620
        config.paths['config/database'] << 'config/database.yml'
        end
      RUBY

1621
      app "development"
Ondrej Sury's avatar
Ondrej Sury committed
1622

1623 1624 1625
      assert_kind_of Hash, Rails.application.config.database_configuration
    end

1626
    test "raises with proper error message if no database configuration found" do
1627 1628
      FileUtils.rm("#{app_path}/config/database.yml")
      err = assert_raises RuntimeError do
1629
        app "development"
1630 1631
        Rails.application.config.database_configuration
      end
1632
      assert_match "config/database", err.message
1633 1634
    end

1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
    test "loads database.yml using shared keys" do
      app_file "config/database.yml", <<-YAML
        shared:
          username: bobby
          adapter: sqlite3

        development:
          database: 'dev_db'
      YAML

      app "development"

      ar_config = Rails.application.config.database_configuration
      assert_equal "sqlite3", ar_config["development"]["adapter"]
      assert_equal "bobby",   ar_config["development"]["username"]
      assert_equal "dev_db",  ar_config["development"]["database"]
    end

    test "loads database.yml using shared keys for undefined environments" do
      app_file "config/database.yml", <<-YAML
        shared:
          username: bobby
          adapter: sqlite3
          database: 'dev_db'
      YAML

      app "development"

      ar_config = Rails.application.config.database_configuration
      assert_equal "sqlite3", ar_config["development"]["adapter"]
      assert_equal "bobby",   ar_config["development"]["username"]
      assert_equal "dev_db",  ar_config["development"]["database"]
    end

    test "config.action_mailer.show_previews defaults to true in development" do
      app "development"
1671 1672 1673 1674

      assert Rails.application.config.action_mailer.show_previews
    end

1675 1676
    test "config.action_mailer.show_previews defaults to false in production" do
      app "production"
1677 1678 1679 1680

      assert_equal false, Rails.application.config.action_mailer.show_previews
    end

1681
    test "config.action_mailer.show_previews can be set in the configuration file" do
1682 1683 1684
      add_to_config <<-RUBY
        config.action_mailer.show_previews = true
      RUBY
1685 1686

      app "production"
1687 1688 1689 1690 1691

      assert_equal true, Rails.application.config.action_mailer.show_previews
    end

    test "config_for loads custom configuration from yaml files" do
1692
      app_file "config/custom.yml", <<-RUBY
1693 1694 1695 1696 1697 1698 1699 1700
      development:
        key: 'custom key'
      RUBY

      add_to_config <<-RUBY
        config.my_custom_config = config_for('custom')
      RUBY

1701
      app "development"
1702

1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718
      assert_equal "custom key", Rails.application.config.my_custom_config["key"]
    end

    test "config_for uses the Pathname object if it is provided" do
      app_file "config/custom.yml", <<-RUBY
      development:
        key: 'custom key'
      RUBY

      add_to_config <<-RUBY
        config.my_custom_config = config_for(Pathname.new(Rails.root.join("config/custom.yml")))
      RUBY

      app "development"

      assert_equal "custom key", Rails.application.config.my_custom_config["key"]
1719 1720 1721 1722 1723 1724 1725 1726
    end

    test "config_for raises an exception if the file does not exist" do
      add_to_config <<-RUBY
        config.my_custom_config = config_for('custom')
      RUBY

      exception = assert_raises(RuntimeError) do
1727
        app "development"
1728 1729 1730 1731 1732 1733
      end

      assert_equal "Could not load configuration. No such file - #{app_path}/config/custom.yml", exception.message
    end

    test "config_for without the environment configured returns an empty hash" do
1734
      app_file "config/custom.yml", <<-RUBY
1735 1736 1737 1738 1739