diff options
Diffstat (limited to 'railties/test/application')
-rw-r--r-- | railties/test/application/assets_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/bin_setup_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 26 | ||||
-rw-r--r-- | railties/test/application/content_security_policy_test.rb | 32 | ||||
-rw-r--r-- | railties/test/application/current_attributes_integration_test.rb | 4 | ||||
-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/middleware_test.rb | 1 | ||||
-rw-r--r-- | railties/test/application/rake/dbs_test.rb | 44 | ||||
-rw-r--r-- | railties/test/application/rake/multi_dbs_test.rb | 19 | ||||
-rw-r--r-- | railties/test/application/rake_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/system_test_case_test.rb | 45 | ||||
-rw-r--r-- | railties/test/application/zeitwerk_integration_test.rb | 38 |
13 files changed, 407 insertions, 9 deletions
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index a7dd233f3d..651897d8f3 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -311,7 +311,7 @@ module ApplicationTests manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first assets = ActiveSupport::JSON.decode(File.read(manifest)) - assert asset_path = assets["assets"].find { |(k, _)| k && k =~ /.png/ }[1] + assert asset_path = assets["assets"].find { |(k, _)| /.png/.match?(k) }[1] # Load app env app "development" 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 f6bec3242a..b44edbc7d3 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -456,7 +456,7 @@ module ApplicationTests 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/ + value = value.reverse if /baz/.match?(key) }] RUBY @@ -790,7 +790,7 @@ module ApplicationTests end get "/" - assert last_response.body =~ /csrf\-param/ + assert_match(/csrf\-param/, last_response.body) end test "default form builder specified as a string" do @@ -1708,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 @@ -1793,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") @@ -2588,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 3338bcb47d..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 diff --git a/railties/test/application/current_attributes_integration_test.rb b/railties/test/application/current_attributes_integration_test.rb index 146e96facc..f4ff5b8077 100644 --- a/railties/test/application/current_attributes_integration_test.rb +++ b/railties/test/application/current_attributes_integration_test.rb @@ -18,7 +18,7 @@ class CurrentAttributesIntegrationTest < ActiveSupport::TestCase def customer=(customer) super - Time.zone = customer.try(:time_zone) + Time.zone = customer&.time_zone end end RUBY @@ -53,7 +53,7 @@ class CurrentAttributesIntegrationTest < ActiveSupport::TestCase RUBY app_file "app/views/customers/index.html.erb", <<-RUBY - <%= Current.customer.try(:name) || 'noone' %>,<%= Time.zone.name %> + <%= Current.customer&.name || 'noone' %>,<%= Time.zone.name %> RUBY require "#{app_path}/config/environment" 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/middleware_test.rb b/railties/test/application/middleware_test.rb index 54c84e2e7c..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", 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 2606e64424..c5f8904f4e 100644 --- a/railties/test/application/rake/multi_dbs_test.rb +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -349,6 +349,25 @@ module ApplicationTests rails "db:drop" rescue nil end end + + test "db:seed uses primary database connection" do + @old_rails_env = ENV["RAILS_ENV"] + @old_rack_env = ENV["RACK_ENV"] + ENV.delete "RAILS_ENV" + ENV.delete "RACK_ENV" + + db_migrate_and_schema_dump_and_load "schema" + + app_file "db/seeds.rb", <<-RUBY + print Book.connection.pool.spec.config[:database] + RUBY + + output = rails("db:seed") + assert_equal output, "db/development.sqlite3" + ensure + ENV["RAILS_ENV"] = @old_rails_env + ENV["RACK_ENV"] = @old_rack_env + end end end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index fe56e3d076..e8456e8c19 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -162,7 +162,6 @@ module ApplicationTests rails "generate", "scaffold", "user", "username:string", "password:string" with_rails_env("test") do rails("db:migrate") - rails("webpacker:compile") end output = rails("test") @@ -194,7 +193,6 @@ module ApplicationTests rails "generate", "scaffold", "LineItems", "product:references", "cart:belongs_to" with_rails_env("test") do rails("db:migrate") - rails("webpacker:compile") end output = rails("test") 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/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb index 9146222f73..d03fa3d0c6 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" @@ -141,6 +150,35 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_empty deps.autoloaded_constants end + [true, false].each do |add_aps_to_lp| + test "require_dependency looks autoload paths up (#{add_aps_to_lp})" do + add_to_config "config.add_autoload_paths_to_load_path = #{add_aps_to_lp}" + app_file "app/models/user.rb", "class User; end" + boot + + assert require_dependency("user") + end + + test "require_dependency handles absolute paths correctly (#{add_aps_to_lp})" do + add_to_config "config.add_autoload_paths_to_load_path = #{add_aps_to_lp}" + app_file "app/models/user.rb", "class User; end" + boot + + assert require_dependency("#{app_path}/app/models/user.rb") + end + + test "require_dependency supports arguments that repond to to_path (#{add_aps_to_lp})" do + add_to_config "config.add_autoload_paths_to_load_path = #{add_aps_to_lp}" + app_file "app/models/user.rb", "class User; end" + boot + + user = Object.new + def user.to_path; "user"; end + + assert require_dependency(user) + end + end + test "eager loading loads the application code" do $zeitwerk_integration_test_user = false $zeitwerk_integration_test_post = false |