diff options
Diffstat (limited to 'railties/test/application')
-rw-r--r-- | railties/test/application/assets_test.rb | 1 | ||||
-rw-r--r-- | railties/test/application/bin_setup_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 56 | ||||
-rw-r--r-- | railties/test/application/content_security_policy_test.rb | 33 | ||||
-rw-r--r-- | railties/test/application/feature_policy_test.rb | 191 | ||||
-rw-r--r-- | railties/test/application/generators_test.rb | 10 | ||||
-rw-r--r-- | railties/test/application/initializers/frameworks_test.rb | 3 | ||||
-rw-r--r-- | railties/test/application/loading_test.rb | 10 | ||||
-rw-r--r-- | railties/test/application/middleware_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/rake/dbs_test.rb | 44 | ||||
-rw-r--r-- | railties/test/application/rake/multi_dbs_test.rb | 46 | ||||
-rw-r--r-- | railties/test/application/rake/notes_test.rb | 1 | ||||
-rw-r--r-- | railties/test/application/system_test_case_test.rb | 45 | ||||
-rw-r--r-- | railties/test/application/test_runner_test.rb | 18 | ||||
-rw-r--r-- | railties/test/application/zeitwerk_integration_test.rb | 9 |
15 files changed, 459 insertions, 12 deletions
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index a80581211b..a7dd233f3d 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -491,7 +491,6 @@ module ApplicationTests end private - def app_with_assets_in_view app_file "app/assets/javascripts/application.js", "//= require_tree ." app_file "app/assets/javascripts/xmlhr.js", "function f1() { alert(); }" diff --git a/railties/test/application/bin_setup_test.rb b/railties/test/application/bin_setup_test.rb index aa0da0931d..d84ab61cf9 100644 --- a/railties/test/application/bin_setup_test.rb +++ b/railties/test/application/bin_setup_test.rb @@ -31,7 +31,7 @@ module ApplicationTests Dir.chdir(app_path) do # SQLite3 seems to auto-create the database on first checkout. rails "db:system:change", "--to=postgresql" - rails "db:drop" + rails "db:drop", allow_failure: true app_file "db/schema.rb", "" diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 7c613585e0..38dda20bec 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1607,6 +1607,13 @@ module ApplicationTests assert_not_nil Rails::SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/] end + test "config.default_log_file returns a File instance" do + app "development" + + assert_instance_of File, app.config.default_log_file + assert_equal Rails.application.config.paths["log"].first, app.config.default_log_file.path + end + test "rake_tasks block works at instance level" do app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do @@ -1701,7 +1708,7 @@ module ApplicationTests app "development" ActiveSupport::Dependencies.autoload_paths.each do |path| assert_not_operator path, :ends_with?, "app/assets" - assert_not_operator path, :ends_with?, "app/javascript" + assert_not_operator path, :ends_with?, "app/#{Rails.configuration.webpacker_path}" end end @@ -1786,6 +1793,11 @@ module ApplicationTests assert_equal [X, D], C.descendants end + test "load_database_yaml returns blank hash if configuration file is blank" do + app_file "config/database.yml", "" + app "development" + assert_equal({}, Rails.application.config.load_database_yaml) + end test "raises with proper error message if no database configuration found" do FileUtils.rm("#{app_path}/config/database.yml") @@ -2429,6 +2441,33 @@ module ApplicationTests assert_nil ActiveStorage.queues[:purge] end + test "ActionDispatch::Response.return_only_media_type_on_content_type is false by default" do + app "development" + + assert_equal false, ActionDispatch::Response.return_only_media_type_on_content_type + end + + test "ActionDispatch::Response.return_only_media_type_on_content_type is true in the 5.x defaults" do + remove_from_config '.*config\.load_defaults.*\n' + add_to_config 'config.load_defaults "5.2"' + + app "development" + + assert_equal true, ActionDispatch::Response.return_only_media_type_on_content_type + end + + test "ActionDispatch::Response.return_only_media_type_on_content_type can be configured in the new framework defaults" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY + Rails.application.config.action_dispatch.return_only_media_type_on_content_type = true + RUBY + + app "development" + + assert_equal true, ActionDispatch::Response.return_only_media_type_on_content_type + end + test "ActionMailbox.logger is Rails.logger by default" do app "development" @@ -2554,6 +2593,21 @@ module ApplicationTests MESSAGE end + test "ActiveStorage.draw_routes can be configured via config.active_storage.draw_routes" do + app_file "config/environments/development.rb", <<-RUBY + Rails.application.configure do + config.active_storage.draw_routes = false + end + RUBY + + output = rails("routes") + assert_not_includes(output, "rails_service_blob") + assert_not_includes(output, "rails_blob_representation") + assert_not_includes(output, "rails_disk_service") + assert_not_includes(output, "update_rails_disk_service") + assert_not_includes(output, "rails_direct_uploads") + end + test "hosts include .localhost in development" do app "development" assert_includes Rails.application.config.hosts, ".localhost" diff --git a/railties/test/application/content_security_policy_test.rb b/railties/test/application/content_security_policy_test.rb index 0d28df16f8..0bb6ee917a 100644 --- a/railties/test/application/content_security_policy_test.rb +++ b/railties/test/application/content_security_policy_test.rb @@ -119,6 +119,38 @@ module ApplicationTests assert_policy "default-src 'self' https:", report_only: true end + test "global content security policy nonce directives in an initializer" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/content_security_policy.rb", <<-RUBY + Rails.application.config.content_security_policy do |p| + p.default_src :self, :https + p.script_src :self, :https + p.style_src :self, :https + end + + Rails.application.config.content_security_policy_nonce_generator = proc { "iyhD0Yc0W+c=" } + Rails.application.config.content_security_policy_nonce_directives = %w(script-src) + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_policy "default-src 'self' https:; script-src 'self' https: 'nonce-iyhD0Yc0W+c='; style-src 'self' https:" + end + test "override content security policy in a controller" do controller :pages, <<-RUBY class PagesController < ApplicationController @@ -204,7 +236,6 @@ module ApplicationTests end private - def assert_policy(expected, report_only: false) assert_equal 200, last_response.status diff --git a/railties/test/application/feature_policy_test.rb b/railties/test/application/feature_policy_test.rb new file mode 100644 index 0000000000..e751d782ee --- /dev/null +++ b/railties/test/application/feature_policy_test.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" +require "rack/test" + +module ApplicationTests + class FeaturePolicyTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + include Rack::Test::Methods + + def setup + build_app + end + + def teardown + teardown_app + end + + test "feature policy is not enabled by default" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_nil last_response.headers["Feature-Policy"] + end + + test "global feature policy in an initializer" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/feature_policy.rb", <<-RUBY + Rails.application.config.feature_policy do |p| + p.geolocation :none + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_policy "geolocation 'none'" + end + + test "override feature policy using same directive in a controller" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + feature_policy do |p| + p.geolocation "https://example.com" + end + + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/feature_policy.rb", <<-RUBY + Rails.application.config.feature_policy do |p| + p.geolocation :none + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_policy "geolocation https://example.com" + end + + test "override feature policy by unsetting a directive in a controller" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + feature_policy do |p| + p.geolocation nil + end + + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/feature_policy.rb", <<-RUBY + Rails.application.config.feature_policy do |p| + p.geolocation :none + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_equal 200, last_response.status + assert_nil last_response.headers["Feature-Policy"] + end + + test "override feature policy using different directives in a controller" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + feature_policy do |p| + p.geolocation nil + p.payment "https://secure.example.com" + p.autoplay :none + end + + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/feature_policy.rb", <<-RUBY + Rails.application.config.feature_policy do |p| + p.geolocation :none + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_policy "payment https://secure.example.com; autoplay 'none'" + end + + test "global feature policy added to rack app" do + app_file "config/initializers/feature_policy.rb", <<-RUBY + Rails.application.config.feature_policy do |p| + p.payment :none + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + app = ->(env) { + [200, { "Content-Type" => "text/html" }, ["<p>Hello, World!</p>"]] + } + root to: app + end + RUBY + + app("development") + + get "/" + assert_policy "payment 'none'" + end + + private + def assert_policy(expected) + assert_equal 200, last_response.status + assert_equal expected, last_response.headers["Feature-Policy"] + end + end +end diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb index e5e557d204..8ec26db772 100644 --- a/railties/test/application/generators_test.rb +++ b/railties/test/application/generators_test.rb @@ -198,5 +198,15 @@ module ApplicationTests assert_no_match "active_record:migration", output end end + + test "skip collision check" do + rails("generate", "model", "post", "title:string") + + output = rails("generate", "model", "post", "title:string", "body:string") + assert_match(/The name 'Post' is either already used in your application or reserved/, output) + + output = rails("generate", "model", "post", "title:string", "body:string", "--skip-collision-check") + assert_no_match(/The name 'Post' is either already used in your application or reserved/, output) + end end end diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index a35247fc43..05978e1d99 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -218,8 +218,9 @@ module ApplicationTests rails %w(generate model post title:string) rails %w(db:migrate db:schema:cache:dump) require "#{app_path}/config/environment" - ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test. assert ActiveRecord::Base.connection.schema_cache.data_sources("posts") + ensure + ActiveRecord::Base.connection.drop_table("posts", if_exists: true) # force drop posts table for test. end test "expire schema cache dump" do diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index 9c98489590..9ab400acfc 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -116,7 +116,7 @@ class LoadingTest < ActiveSupport::TestCase RUBY app_file "app/models/post.rb", <<-MODEL - class Post < ActiveRecord::Base + class Post < ApplicationRecord end MODEL @@ -133,11 +133,12 @@ class LoadingTest < ActiveSupport::TestCase require "#{rails_root}/config/environment" setup_ar! - assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort + initial = [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, ApplicationRecord, "primary::SchemaMigration"].collect(&:to_s).sort + assert_equal initial, ActiveRecord::Base.descendants.collect(&:to_s).sort get "/load" - assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, Post].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort + assert_equal [Post].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort - initial get "/unload" - assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort + assert_equal ["ActiveRecord::InternalMetadata", "ActiveRecord::SchemaMigration", "primary::SchemaMigration"], ActiveRecord::Base.descendants.collect(&:to_s).sort.uniq end test "initialize cant be called twice" do @@ -454,7 +455,6 @@ class LoadingTest < ActiveSupport::TestCase end private - def setup_ar! ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") ActiveRecord::Migration.verbose = false diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 54b2e95d75..e93f2f5aa4 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -46,6 +46,7 @@ module ApplicationTests "ActionDispatch::Session::CookieStore", "ActionDispatch::Flash", "ActionDispatch::ContentSecurityPolicy::Middleware", + "ActionDispatch::FeaturePolicy::Middleware", "Rack::Head", "Rack::ConditionalGet", "Rack::ETag", @@ -309,7 +310,6 @@ module ApplicationTests end private - def boot! require "#{app_path}/config/environment" end diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index e08cd09abd..c9931c45a6 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -40,6 +40,15 @@ module ApplicationTests end end + def db_create_with_warning(expected_database) + Dir.chdir(app_path) do + output = rails("db:create") + assert_match(/Rails couldn't infer whether you are using multiple databases/, output) + assert_match(/Created database/, output) + assert File.exist?(expected_database) + end + end + test "db:create and db:drop without database URL" do require "#{app_path}/config/environment" db_create_and_drop ActiveRecord::Base.configurations[Rails.env]["database"] @@ -86,6 +95,25 @@ module ApplicationTests db_create_and_drop("db/development.sqlite3", environment_loaded: false) end + test "db:create and db:drop show warning but doesn't raise errors when loading YAML with alias ERB" do + app_file "config/database.yml", <<-YAML + sqlite: &sqlite + adapter: sqlite3 + database: db/development.sqlite3 + + development: + <<: *<%= ENV["DB"] || "sqlite" %> + YAML + + app_file "config/environments/development.rb", <<-RUBY + Rails.application.configure do + config.database = "db/development.sqlite3" + end + RUBY + + db_create_with_warning("db/development.sqlite3") + end + test "db:create and db:drop don't raise errors when loading YAML containing conditional statements in ERB" do app_file "config/database.yml", <<-YAML development: @@ -602,6 +630,22 @@ module ApplicationTests assert_match(/CreateRecipes: migrated/, output) end end + + test "db:prepare does not touch schema when dumping is disabled" do + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "db:create", "db:migrate" + + app_file "db/schema.rb", "Not touched" + app_file "config/initializers/disable_dumping_schema.rb", <<-RUBY + Rails.application.config.active_record.dump_schema_after_migration = false + RUBY + + rails "db:prepare" + + assert_equal("Not touched", File.read("db/schema.rb").strip) + end + end end end end diff --git a/railties/test/application/rake/multi_dbs_test.rb b/railties/test/application/rake/multi_dbs_test.rb index 31ea2246a9..2606e64424 100644 --- a/railties/test/application/rake/multi_dbs_test.rb +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -299,10 +299,56 @@ module ApplicationTests db_migrate_and_schema_cache_dump_and_schema_cache_clear end + test "db:abort_if_pending_migrations works on all databases" do + require "#{app_path}/config/environment" + + app_file "db/animals_migrate/02_two_migration.rb", <<-MIGRATION + class TwoMigration < ActiveRecord::Migration::Current + end + MIGRATION + + output = rails("db:abort_if_pending_migrations", allow_failure: true) + assert_match(/You have 1 pending migration/, output) + end + + test "db:abort_if_pending_migrations:namespace works" do + require "#{app_path}/config/environment" + + app_file "db/animals_migrate/02_two_migration.rb", <<-MIGRATION + class TwoMigration < ActiveRecord::Migration::Current + end + MIGRATION + + output = rails("db:abort_if_pending_migrations:primary") + assert_no_match(/You have \d+ pending migration/, output) + output = rails("db:abort_if_pending_migrations:animals", allow_failure: true) + assert_match(/You have 1 pending migration/, output) + end + test "db:prepare works on all databases" do require "#{app_path}/config/environment" db_prepare end + + test "db:prepare setups missing database without clearing existing one" do + require "#{app_path}/config/environment" + Dir.chdir(app_path) do + # Bug not visible on SQLite3. Can be simplified when https://github.com/rails/rails/issues/36383 resolved + use_postgresql(multi_db: true) + generate_models_for_animals + + rails "db:create:animals", "db:migrate:animals", "db:create:primary", "db:migrate:primary", "db:schema:dump" + rails "db:drop:primary" + Dog.create! + output = rails("db:prepare") + + assert_match(/Created database/, output) + assert_equal 1, Dog.count + ensure + Dog.connection.disconnect! + rails "db:drop" rescue nil + end + end end end end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 60802ef7c4..47822e55b9 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -159,7 +159,6 @@ module ApplicationTests end private - def run_rake_notes(command = "bin/rake notes") Dir.chdir(app_path) do output = `#{command}` diff --git a/railties/test/application/system_test_case_test.rb b/railties/test/application/system_test_case_test.rb new file mode 100644 index 0000000000..d15a0d9210 --- /dev/null +++ b/railties/test/application/system_test_case_test.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" +require "rack/test" + +class SystemTestCaseTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app + end + + def teardown + teardown_app + end + + test "url helpers are delegated to a proxy class" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get 'foo', to: 'foo#index', as: 'test_foo' + end + RUBY + + app("test") + + assert_not_includes(ActionDispatch::SystemTestCase.runnable_methods, :test_foo_url) + end + + test "system tests set the Capybara host in the url_options by default" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get 'foo', to: 'foo#index', as: 'test_foo' + end + RUBY + + app("test") + system_test = ActionDispatch::SystemTestCase.new("my_test") + previous_app_host = ::Capybara.app_host + ::Capybara.app_host = "https://my_test_example.com" + + assert_equal("https://my_test_example.com/foo", system_test.test_foo_url) + ensure + ::Capybara.app_host = previous_app_host + end +end diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index 1ab45abcd0..7fc918898b 100644 --- a/railties/test/application/test_runner_test.rb +++ b/railties/test/application/test_runner_test.rb @@ -564,6 +564,24 @@ module ApplicationTests assert_no_match "create_table(:users)", output end + def test_run_in_parallel_with_process_worker_crash + exercise_parallelization_regardless_of_machine_core_count(with: :processes) + + file_name = app_file("test/models/parallel_test.rb", <<-RUBY) + require 'test_helper' + + class ParallelTest < ActiveSupport::TestCase + def test_crash + Kernel.exit 1 + end + end + RUBY + + output = run_test_command(file_name) + + assert_match %r{Queue not empty, but all workers have finished. This probably means that a worker crashed and 1 tests were missed.}, output + end + def test_run_in_parallel_with_threads exercise_parallelization_regardless_of_machine_core_count(with: :threads) diff --git a/railties/test/application/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb index 9146222f73..ff8c06b479 100644 --- a/railties/test/application/zeitwerk_integration_test.rb +++ b/railties/test/application/zeitwerk_integration_test.rb @@ -98,6 +98,15 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_nil deps.safe_constantize("Admin") end + test "autoloaded? and overridden class names" do + invalid_constant_name = Module.new do + def self.name + "primary::SchemaMigration" + end + end + assert_not deps.autoloaded?(invalid_constant_name) + end + test "unloadable constants (main)" do app_file "app/models/user.rb", "class User; end" app_file "app/models/post.rb", "class Post; end" |