diff options
9 files changed, 76 insertions, 18 deletions
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index a6223964e5..6fa5be54cb 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -268,14 +268,14 @@ class BaseTest < ActiveSupport::TestCase end test "accessing inline attachments after mail was called works" do - class LateInlineAttachmentMailer < ActionMailer::Base + class LateInlineAttachmentAccessorMailer < ActionMailer::Base def welcome mail body: "yay", from: "welcome@example.com", to: "to@example.com" attachments.inline["invoice.pdf"] end end - assert_nothing_raised { LateInlineAttachmentMailer.welcome.message } + assert_nothing_raised { LateInlineAttachmentAccessorMailer.welcome.message } end test "adding inline attachments while rendering mail works" do diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 4d9acc911b..d699e2e21b 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -265,6 +265,8 @@ db_namespace = namespace :db do end abort %{Run `rails db:migrate` to update your database then try again.} end + ensure + ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym) end namespace :abort_if_pending_migrations do diff --git a/activestorage/lib/active_storage/service/azure_storage_service.rb b/activestorage/lib/active_storage/service/azure_storage_service.rb index 8d77e9b20f..0648da70b5 100644 --- a/activestorage/lib/active_storage/service/azure_storage_service.rb +++ b/activestorage/lib/active_storage/service/azure_storage_service.rb @@ -17,10 +17,12 @@ module ActiveStorage @container = container end - def upload(key, io, checksum: nil, content_type: nil, **) + def upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, **) instrument :upload, key: key, checksum: checksum do handle_errors do - blobs.create_block_blob(container, key, IO.try_convert(io) || io, content_md5: checksum, content_type: content_type) + content_disposition = content_disposition_with(filename: filename, type: disposition) if disposition && filename + + blobs.create_block_blob(container, key, IO.try_convert(io) || io, content_md5: checksum, content_type: content_type, content_disposition: content_disposition) end end end diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb index e4bd57048a..a73f6ab526 100644 --- a/activestorage/lib/active_storage/service/s3_service.rb +++ b/activestorage/lib/active_storage/service/s3_service.rb @@ -20,12 +20,14 @@ module ActiveStorage @upload_options = upload end - def upload(key, io, checksum: nil, content_type: nil, **) + def upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, **) instrument :upload, key: key, checksum: checksum do + content_disposition = content_disposition_with(filename: filename, type: disposition) if disposition && filename + if io.size < multipart_upload_threshold - upload_with_single_part key, io, checksum: checksum, content_type: content_type + upload_with_single_part key, io, checksum: checksum, content_type: content_type, content_disposition: content_disposition else - upload_with_multipart key, io, content_type: content_type + upload_with_multipart key, io, content_type: content_type, content_disposition: content_disposition end end end @@ -103,16 +105,16 @@ module ActiveStorage MAXIMUM_UPLOAD_PARTS_COUNT = 10000 MINIMUM_UPLOAD_PART_SIZE = 5.megabytes - def upload_with_single_part(key, io, checksum: nil, content_type: nil) - object_for(key).put(body: io, content_md5: checksum, content_type: content_type, **upload_options) + def upload_with_single_part(key, io, checksum: nil, content_type: nil, content_disposition: nil) + object_for(key).put(body: io, content_md5: checksum, content_type: content_type, content_disposition: content_disposition, **upload_options) rescue Aws::S3::Errors::BadDigest raise ActiveStorage::IntegrityError end - def upload_with_multipart(key, io, content_type: nil) + def upload_with_multipart(key, io, content_type: nil, content_disposition: nil) part_size = [ io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE ].max - object_for(key).upload_stream(content_type: content_type, part_size: part_size, **upload_options) do |out| + object_for(key).upload_stream(content_type: content_type, content_disposition: content_disposition, part_size: part_size, **upload_options) do |out| IO.copy_stream(io, out) end end diff --git a/activestorage/test/service/azure_storage_service_test.rb b/activestorage/test/service/azure_storage_service_test.rb index fc7b86ccb0..9eea1b94c8 100644 --- a/activestorage/test/service/azure_storage_service_test.rb +++ b/activestorage/test/service/azure_storage_service_test.rb @@ -23,6 +23,21 @@ if SERVICE_CONFIGURATIONS[:azure] @service.delete key end + test "upload with content disposition" do + key = SecureRandom.base58(24) + data = "Foobar" + + @service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), filename: ActiveStorage::Filename.new("test.txt"), disposition: :inline) + + assert_equal("inline; filename=\"test.txt\"; filename*=UTF-8''test.txt", @service.blobs.get_blob_properties(@service.container, key).properties[:content_disposition]) + + url = @service.url(key, expires_in: 2.minutes, disposition: :attachment, content_type: nil, filename: ActiveStorage::Filename.new("test.html")) + response = Net::HTTP.get_response(URI(url)) + assert_match(/attachment;.*test\.html/, response["Content-Disposition"]) + ensure + @service.delete key + end + test "signed URL generation" do url = @service.url(@key, expires_in: 5.minutes, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png") diff --git a/activestorage/test/service/s3_service_test.rb b/activestorage/test/service/s3_service_test.rb index b9120770e6..3dd1b59681 100644 --- a/activestorage/test/service/s3_service_test.rb +++ b/activestorage/test/service/s3_service_test.rb @@ -77,6 +77,23 @@ if SERVICE_CONFIGURATIONS[:s3] @service.delete key end + test "upload with content disposition" do + key = SecureRandom.base58(24) + data = "Something else entirely!" + + @service.upload( + key, + StringIO.new(data), + checksum: Digest::MD5.base64digest(data), + filename: ActiveStorage::Filename.new("cool_data.txt"), + disposition: :attachment + ) + + assert_equal("attachment; filename=\"cool_data.txt\"; filename*=UTF-8''cool_data.txt", @service.bucket.object(key).content_disposition) + ensure + @service.delete key + end + test "uploading a large object in multiple parts" do service = build_service(upload: { multipart_threshold: 5.megabytes }) diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb index 3ba2d93ed8..1899a1212d 100644 --- a/activesupport/lib/active_support/inflector/transliterate.rb +++ b/activesupport/lib/active_support/inflector/transliterate.rb @@ -60,6 +60,7 @@ module ActiveSupport # Transliteration is restricted to UTF-8, US-ASCII and GB18030 strings # Other encodings will raise an ArgumentError. def transliterate(string, replacement = "?", locale: nil) + string = string.dup if string.frozen? raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String) allowed_encodings = [Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030] diff --git a/activesupport/test/transliterate_test.rb b/activesupport/test/transliterate_test.rb index 2e02b5e938..f13c5efa47 100644 --- a/activesupport/test/transliterate_test.rb +++ b/activesupport/test/transliterate_test.rb @@ -59,19 +59,19 @@ class TransliterateTest < ActiveSupport::TestCase end def test_transliterate_handles_strings_with_valid_utf8_encodings - string = String.new("A", encoding: Encoding::UTF_8) + string = String.new("A", encoding: Encoding::UTF_8).freeze assert_equal "A", ActiveSupport::Inflector.transliterate(string) end def test_transliterate_handles_strings_with_valid_us_ascii_encodings - string = String.new("A", encoding: Encoding::US_ASCII) + string = String.new("A", encoding: Encoding::US_ASCII).freeze transcoded = ActiveSupport::Inflector.transliterate(string) assert_equal "A", transcoded assert_equal Encoding::US_ASCII, transcoded.encoding end def test_transliterate_handles_strings_with_valid_gb18030_encodings - string = String.new("A", encoding: Encoding::GB18030) + string = String.new("A", encoding: Encoding::GB18030).freeze transcoded = ActiveSupport::Inflector.transliterate(string) assert_equal "A", transcoded assert_equal Encoding::GB18030, transcoded.encoding @@ -84,7 +84,7 @@ class TransliterateTest < ActiveSupport::TestCase Encoding::GB18030 ] incompatible_encodings.each do |encoding| - string = String.new("", encoding: encoding) + string = String.new("", encoding: encoding).freeze exception = assert_raises ArgumentError do ActiveSupport::Inflector.transliterate(string) end @@ -93,17 +93,17 @@ class TransliterateTest < ActiveSupport::TestCase end def test_transliterate_handles_strings_with_invalid_utf8_bytes - string = String.new("\255", encoding: Encoding::UTF_8) + string = String.new("\255", encoding: Encoding::UTF_8).freeze assert_equal "?", ActiveSupport::Inflector.transliterate(string) end def test_transliterate_handles_strings_with_invalid_us_ascii_bytes - string = String.new("\255", encoding: Encoding::US_ASCII) + string = String.new("\255", encoding: Encoding::US_ASCII).freeze assert_equal "?", ActiveSupport::Inflector.transliterate(string) end def test_transliterate_handles_strings_with_invalid_gb18030_bytes - string = String.new("\255", encoding: Encoding::GB18030) + string = String.new("\255", encoding: Encoding::GB18030).freeze assert_equal "?", ActiveSupport::Inflector.transliterate(string) 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 |