diff options
Diffstat (limited to 'activestorage/test/models')
-rw-r--r-- | activestorage/test/models/attachments_test.rb | 220 | ||||
-rw-r--r-- | activestorage/test/models/blob_test.rb | 56 | ||||
-rw-r--r-- | activestorage/test/models/filename/parameters_test.rb | 32 | ||||
-rw-r--r-- | activestorage/test/models/filename_test.rb | 56 | ||||
-rw-r--r-- | activestorage/test/models/preview_test.rb | 40 | ||||
-rw-r--r-- | activestorage/test/models/representation_test.rb | 41 | ||||
-rw-r--r-- | activestorage/test/models/variant_test.rb | 34 |
7 files changed, 479 insertions, 0 deletions
diff --git a/activestorage/test/models/attachments_test.rb b/activestorage/test/models/attachments_test.rb new file mode 100644 index 0000000000..47f2bd7911 --- /dev/null +++ b/activestorage/test/models/attachments_test.rb @@ -0,0 +1,220 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::AttachmentsTest < ActiveSupport::TestCase + include ActiveJob::TestHelper + + setup { @user = User.create!(name: "DHH") } + + teardown { ActiveStorage::Blob.all.each(&:purge) } + + test "attach existing blob" do + @user.avatar.attach create_blob(filename: "funky.jpg") + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "attach existing blob from a signed ID" do + @user.avatar.attach create_blob(filename: "funky.jpg").signed_id + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "attach new blob from a Hash" do + @user.avatar.attach io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" + assert_equal "town.jpg", @user.avatar.filename.to_s + end + + test "attach new blob from an UploadedFile" do + file = file_fixture "racecar.jpg" + @user.avatar.attach Rack::Test::UploadedFile.new file + assert_equal "racecar.jpg", @user.avatar.filename.to_s + end + + test "replace attached blob" do + @user.avatar.attach create_blob(filename: "funky.jpg") + + perform_enqueued_jobs do + assert_no_difference -> { ActiveStorage::Blob.count } do + @user.avatar.attach create_blob(filename: "town.jpg") + end + end + + assert_equal "town.jpg", @user.avatar.filename.to_s + end + + test "replace attached blob unsuccessfully" do + @user.avatar.attach create_blob(filename: "funky.jpg") + + perform_enqueued_jobs do + assert_raises do + @user.avatar.attach nil + end + end + + assert_equal "funky.jpg", @user.reload.avatar.filename.to_s + assert ActiveStorage::Blob.service.exist?(@user.avatar.key) + end + + test "access underlying associations of new blob" do + @user.avatar.attach create_blob(filename: "funky.jpg") + assert_equal @user, @user.avatar_attachment.record + assert_equal @user.avatar_attachment.blob, @user.avatar_blob + assert_equal "funky.jpg", @user.avatar_attachment.blob.filename.to_s + end + + test "analyze newly-attached blob" do + perform_enqueued_jobs do + @user.avatar.attach create_file_blob + end + + assert_equal 4104, @user.avatar.reload.metadata[:width] + assert_equal 2736, @user.avatar.metadata[:height] + end + + test "analyze attached blob only once" do + blob = create_file_blob + + perform_enqueued_jobs do + @user.avatar.attach blob + end + + assert blob.reload.analyzed? + + @user.avatar.attachment.destroy + + assert_no_enqueued_jobs do + @user.reload.avatar.attach blob + end + end + + test "purge attached blob" do + @user.avatar.attach create_blob(filename: "funky.jpg") + avatar_key = @user.avatar.key + + @user.avatar.purge + assert_not @user.avatar.attached? + assert_not ActiveStorage::Blob.service.exist?(avatar_key) + end + + test "purge attached blob later when the record is destroyed" do + @user.avatar.attach create_blob(filename: "funky.jpg") + avatar_key = @user.avatar.key + + perform_enqueued_jobs do + @user.destroy + + assert_nil ActiveStorage::Blob.find_by(key: avatar_key) + assert_not ActiveStorage::Blob.service.exist?(avatar_key) + end + end + + test "find with attached blob" do + records = %w[alice bob].map do |name| + User.create!(name: name).tap do |user| + user.avatar.attach create_blob(filename: "#{name}.jpg") + end + end + + users = User.where(id: records.map(&:id)).with_attached_avatar.all + + assert_equal "alice.jpg", users.first.avatar.filename.to_s + assert_equal "bob.jpg", users.second.avatar.filename.to_s + end + + + test "attach existing blobs" do + @user.highlights.attach create_blob(filename: "funky.jpg"), create_blob(filename: "wonky.jpg") + + assert_equal "funky.jpg", @user.highlights.first.filename.to_s + assert_equal "wonky.jpg", @user.highlights.second.filename.to_s + end + + test "attach new blobs" do + @user.highlights.attach( + { io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" }, + { io: StringIO.new("IT"), filename: "country.jpg", content_type: "image/jpg" }) + + assert_equal "town.jpg", @user.highlights.first.filename.to_s + assert_equal "country.jpg", @user.highlights.second.filename.to_s + end + + test "find attached blobs" do + @user.highlights.attach( + { io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" }, + { io: StringIO.new("IT"), filename: "country.jpg", content_type: "image/jpg" }) + + highlights = User.where(id: @user.id).with_attached_highlights.first.highlights + + assert_equal "town.jpg", highlights.first.filename.to_s + assert_equal "country.jpg", highlights.second.filename.to_s + end + + test "access underlying associations of new blobs" do + @user.highlights.attach( + { io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" }, + { io: StringIO.new("IT"), filename: "country.jpg", content_type: "image/jpg" }) + + assert_equal @user, @user.highlights_attachments.first.record + assert_equal @user.highlights_attachments.collect(&:blob).sort, @user.highlights_blobs.sort + assert_equal "town.jpg", @user.highlights_attachments.first.blob.filename.to_s + end + + test "analyze newly-attached blobs" do + perform_enqueued_jobs do + @user.highlights.attach( + create_file_blob(filename: "racecar.jpg", content_type: "image/jpeg"), + create_file_blob(filename: "video.mp4", content_type: "video/mp4")) + end + + assert_equal 4104, @user.highlights.first.metadata[:width] + assert_equal 2736, @user.highlights.first.metadata[:height] + + assert_equal 640, @user.highlights.second.metadata[:width] + assert_equal 480, @user.highlights.second.metadata[:height] + end + + test "analyze attached blobs only once" do + blobs = [ + create_file_blob(filename: "racecar.jpg", content_type: "image/jpeg"), + create_file_blob(filename: "video.mp4", content_type: "video/mp4") + ] + + perform_enqueued_jobs do + @user.highlights.attach(blobs) + end + + assert blobs.each(&:reload).all?(&:analyzed?) + + @user.highlights.attachments.destroy_all + + assert_no_enqueued_jobs do + @user.highlights.attach(blobs) + end + end + + test "purge attached blobs" do + @user.highlights.attach create_blob(filename: "funky.jpg"), create_blob(filename: "wonky.jpg") + highlight_keys = @user.highlights.collect(&:key) + + @user.highlights.purge + assert_not @user.highlights.attached? + assert_not ActiveStorage::Blob.service.exist?(highlight_keys.first) + assert_not ActiveStorage::Blob.service.exist?(highlight_keys.second) + end + + test "purge attached blobs later when the record is destroyed" do + @user.highlights.attach create_blob(filename: "funky.jpg"), create_blob(filename: "wonky.jpg") + highlight_keys = @user.highlights.collect(&:key) + + perform_enqueued_jobs do + @user.destroy + + assert_nil ActiveStorage::Blob.find_by(key: highlight_keys.first) + assert_not ActiveStorage::Blob.service.exist?(highlight_keys.first) + + assert_nil ActiveStorage::Blob.find_by(key: highlight_keys.second) + assert_not ActiveStorage::Blob.service.exist?(highlight_keys.second) + end + end +end diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb new file mode 100644 index 0000000000..6e815997ba --- /dev/null +++ b/activestorage/test/models/blob_test.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::BlobTest < ActiveSupport::TestCase + test "create after upload sets byte size and checksum" do + data = "Hello world!" + blob = create_blob data: data + + assert_equal data, blob.download + assert_equal data.length, blob.byte_size + assert_equal Digest::MD5.base64digest(data), blob.checksum + end + + test "text?" do + blob = create_blob data: "Hello world!" + assert blob.text? + assert_not blob.audio? + end + + test "download yields chunks" do + blob = create_blob data: "a" * 75.kilobytes + chunks = [] + + blob.download do |chunk| + chunks << chunk + end + + assert_equal 2, chunks.size + assert_equal "a" * 64.kilobytes, chunks.first + assert_equal "a" * 11.kilobytes, chunks.second + end + + test "urls expiring in 5 minutes" do + blob = create_blob + + freeze_time do + assert_equal expected_url_for(blob), blob.service_url + assert_equal expected_url_for(blob, disposition: :attachment), blob.service_url(disposition: :attachment) + end + end + + test "purge removes from external service" do + blob = create_blob + + blob.purge + assert_not ActiveStorage::Blob.service.exist?(blob.key) + end + + private + def expected_url_for(blob, disposition: :inline) + query_string = { content_type: blob.content_type, disposition: "#{disposition}; #{blob.filename.parameters}" }.to_param + "/rails/active_storage/disk/#{ActiveStorage.verifier.generate(blob.key, expires_in: 5.minutes, purpose: :blob_key)}/#{blob.filename}?#{query_string}" + end +end diff --git a/activestorage/test/models/filename/parameters_test.rb b/activestorage/test/models/filename/parameters_test.rb new file mode 100644 index 0000000000..431be00639 --- /dev/null +++ b/activestorage/test/models/filename/parameters_test.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "test_helper" + +class ActiveStorage::Filename::ParametersTest < ActiveSupport::TestCase + test "parameterizing a Latin filename" do + filename = ActiveStorage::Filename.new("racecar.jpg") + + assert_equal %(filename="racecar.jpg"), filename.parameters.ascii + assert_equal "filename*=UTF-8''racecar.jpg", filename.parameters.utf8 + assert_equal "#{filename.parameters.ascii}; #{filename.parameters.utf8}", filename.parameters.combined + assert_equal filename.parameters.combined, filename.parameters.to_s + end + + test "parameterizing a Latin filename with accented characters" do + filename = ActiveStorage::Filename.new("råcëçâr.jpg") + + assert_equal %(filename="racecar.jpg"), filename.parameters.ascii + assert_equal "filename*=UTF-8''r%C3%A5c%C3%AB%C3%A7%C3%A2r.jpg", filename.parameters.utf8 + assert_equal "#{filename.parameters.ascii}; #{filename.parameters.utf8}", filename.parameters.combined + assert_equal filename.parameters.combined, filename.parameters.to_s + end + + test "parameterizing a non-Latin filename" do + filename = ActiveStorage::Filename.new("автомобиль.jpg") + + assert_equal %(filename="%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F.jpg"), filename.parameters.ascii + assert_equal "filename*=UTF-8''%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D0%B1%D0%B8%D0%BB%D1%8C.jpg", filename.parameters.utf8 + assert_equal "#{filename.parameters.ascii}; #{filename.parameters.utf8}", filename.parameters.combined + assert_equal filename.parameters.combined, filename.parameters.to_s + end +end diff --git a/activestorage/test/models/filename_test.rb b/activestorage/test/models/filename_test.rb new file mode 100644 index 0000000000..88405e41c0 --- /dev/null +++ b/activestorage/test/models/filename_test.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "test_helper" + +class ActiveStorage::FilenameTest < ActiveSupport::TestCase + test "base" do + assert_equal "racecar", ActiveStorage::Filename.new("racecar.jpg").base + assert_equal "race.car", ActiveStorage::Filename.new("race.car.jpg").base + assert_equal "racecar", ActiveStorage::Filename.new("racecar").base + end + + test "extension with delimiter" do + assert_equal ".jpg", ActiveStorage::Filename.new("racecar.jpg").extension_with_delimiter + assert_equal ".jpg", ActiveStorage::Filename.new("race.car.jpg").extension_with_delimiter + assert_equal "", ActiveStorage::Filename.new("racecar").extension_with_delimiter + end + + test "extension without delimiter" do + assert_equal "jpg", ActiveStorage::Filename.new("racecar.jpg").extension_without_delimiter + assert_equal "jpg", ActiveStorage::Filename.new("race.car.jpg").extension_without_delimiter + assert_equal "", ActiveStorage::Filename.new("racecar").extension_without_delimiter + end + + test "sanitize" do + "%$|:;/\t\r\n\\".each_char do |character| + filename = ActiveStorage::Filename.new("foo#{character}bar.pdf") + assert_equal "foo-bar.pdf", filename.sanitized + assert_equal "foo-bar.pdf", filename.to_s + end + end + + test "sanitize transcodes to valid UTF-8" do + { "\xF6".dup.force_encoding(Encoding::ISO8859_1) => "ö", + "\xC3".dup.force_encoding(Encoding::ISO8859_1) => "Ã", + "\xAD" => "�", + "\xCF" => "�", + "\x00" => "", + }.each do |actual, expected| + assert_equal expected, ActiveStorage::Filename.new(actual).sanitized + end + end + + test "strips RTL override chars used to spoof unsafe executables as docs" do + # Would be displayed in Windows as "evilexe.pdf" due to the right-to-left + # (RTL) override char! + assert_equal "evil-fdp.exe", ActiveStorage::Filename.new("evil\u{202E}fdp.exe").sanitized + end + + test "compare case-insensitively" do + assert_operator ActiveStorage::Filename.new("foobar.pdf"), :==, ActiveStorage::Filename.new("FooBar.PDF") + end + + test "compare sanitized" do + assert_operator ActiveStorage::Filename.new("foo-bar.pdf"), :==, ActiveStorage::Filename.new("foo\tbar.pdf") + end +end diff --git a/activestorage/test/models/preview_test.rb b/activestorage/test/models/preview_test.rb new file mode 100644 index 0000000000..bcd8442f4b --- /dev/null +++ b/activestorage/test/models/preview_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::PreviewTest < ActiveSupport::TestCase + test "previewing a PDF" do + blob = create_file_blob(filename: "report.pdf", content_type: "application/pdf") + preview = blob.preview(resize: "640x280").processed + + assert preview.image.attached? + assert_equal "report.png", preview.image.filename.to_s + assert_equal "image/png", preview.image.content_type + + image = read_image(preview.image) + assert_equal 612, image.width + assert_equal 792, image.height + end + + test "previewing an MP4 video" do + blob = create_file_blob(filename: "video.mp4", content_type: "video/mp4") + preview = blob.preview(resize: "640x280").processed + + assert preview.image.attached? + assert_equal "video.png", preview.image.filename.to_s + assert_equal "image/png", preview.image.content_type + + image = read_image(preview.image) + assert_equal 640, image.width + assert_equal 480, image.height + end + + test "previewing an unpreviewable blob" do + blob = create_file_blob + + assert_raises ActiveStorage::Blob::UnpreviewableError do + blob.preview resize: "640x280" + end + end +end diff --git a/activestorage/test/models/representation_test.rb b/activestorage/test/models/representation_test.rb new file mode 100644 index 0000000000..29fe61aee4 --- /dev/null +++ b/activestorage/test/models/representation_test.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::RepresentationTest < ActiveSupport::TestCase + test "representing an image" do + blob = create_file_blob + representation = blob.representation(resize: "100x100").processed + + image = read_image(representation.image) + assert_equal 100, image.width + assert_equal 67, image.height + end + + test "representing a PDF" do + blob = create_file_blob(filename: "report.pdf", content_type: "application/pdf") + representation = blob.representation(resize: "640x280").processed + + image = read_image(representation.image) + assert_equal 612, image.width + assert_equal 792, image.height + end + + test "representing an MP4 video" do + blob = create_file_blob(filename: "video.mp4", content_type: "video/mp4") + representation = blob.representation(resize: "640x280").processed + + image = read_image(representation.image) + assert_equal 640, image.width + assert_equal 480, image.height + end + + test "representing an unrepresentable blob" do + blob = create_blob + + assert_raises ActiveStorage::Blob::UnrepresentableError do + blob.representation resize: "100x100" + end + end +end diff --git a/activestorage/test/models/variant_test.rb b/activestorage/test/models/variant_test.rb new file mode 100644 index 0000000000..b7d20ab55a --- /dev/null +++ b/activestorage/test/models/variant_test.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::VariantTest < ActiveSupport::TestCase + setup do + @blob = create_file_blob filename: "racecar.jpg" + end + + test "resized variation" do + variant = @blob.variant(resize: "100x100").processed + assert_match(/racecar\.jpg/, variant.service_url) + + image = read_image(variant) + assert_equal 100, image.width + assert_equal 67, image.height + end + + test "resized and monochrome variation" do + variant = @blob.variant(resize: "100x100", monochrome: true).processed + assert_match(/racecar\.jpg/, variant.service_url) + + image = read_image(variant) + assert_equal 100, image.width + assert_equal 67, image.height + assert_match(/Gray/, image.colorspace) + end + + test "service_url doesn't grow in length despite long variant options" do + variant = @blob.variant(font: "a" * 10_000).processed + assert_operator variant.service_url.length, :<, 500 + end +end |