diff options
Diffstat (limited to 'activestorage/test/models/attached/one_test.rb')
-rw-r--r-- | activestorage/test/models/attached/one_test.rb | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/activestorage/test/models/attached/one_test.rb b/activestorage/test/models/attached/one_test.rb new file mode 100644 index 0000000000..561c3e9d23 --- /dev/null +++ b/activestorage/test/models/attached/one_test.rb @@ -0,0 +1,513 @@ +# frozen_string_literal: true + +require "test_helper" +require "database/setup" + +class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase + include ActiveJob::TestHelper + + setup do + @user = User.create!(name: "Josh") + end + + teardown { ActiveStorage::Blob.all.each(&:delete) } + + test "attaching an existing blob to an existing record" do + @user.avatar.attach create_blob(filename: "funky.jpg") + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "attaching an existing blob from a signed ID to an existing record" do + @user.avatar.attach create_blob(filename: "funky.jpg").signed_id + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "attaching a new blob from a Hash to an existing record" 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 "attaching a new blob from an uploaded file to an existing record" do + @user.avatar.attach fixture_file_upload("racecar.jpg") + assert_equal "racecar.jpg", @user.avatar.filename.to_s + end + + test "attaching an existing blob to an existing, changed record" do + @user.name = "Tina" + assert @user.changed? + + @user.avatar.attach create_blob(filename: "funky.jpg") + assert_equal "funky.jpg", @user.avatar.filename.to_s + assert_not @user.avatar.persisted? + assert @user.will_save_change_to_name? + + @user.save! + assert_equal "funky.jpg", @user.reload.avatar.filename.to_s + end + + test "attaching an existing blob from a signed ID to an existing, changed record" do + @user.name = "Tina" + assert @user.changed? + + @user.avatar.attach create_blob(filename: "funky.jpg").signed_id + assert_equal "funky.jpg", @user.avatar.filename.to_s + assert_not @user.avatar.persisted? + assert @user.will_save_change_to_name? + + @user.save! + assert_equal "funky.jpg", @user.reload.avatar.filename.to_s + end + + test "attaching a new blob from a Hash to an existing, changed record" do + @user.name = "Tina" + assert @user.changed? + + @user.avatar.attach io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" + assert_equal "town.jpg", @user.avatar.filename.to_s + assert_not @user.avatar.persisted? + assert @user.will_save_change_to_name? + + @user.save! + assert_equal "town.jpg", @user.reload.avatar.filename.to_s + end + + test "attaching a new blob from an uploaded file to an existing, changed record" do + @user.name = "Tina" + assert @user.changed? + + @user.avatar.attach fixture_file_upload("racecar.jpg") + assert_equal "racecar.jpg", @user.avatar.filename.to_s + assert_not @user.avatar.persisted? + assert @user.will_save_change_to_name? + + @user.save! + assert_equal "racecar.jpg", @user.reload.avatar.filename.to_s + end + + test "updating an existing record to attach an existing blob" do + @user.update! avatar: create_blob(filename: "funky.jpg") + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "updating an existing record to attach an existing blob from a signed ID" do + @user.update! avatar: create_blob(filename: "funky.jpg").signed_id + assert_equal "funky.jpg", @user.avatar.filename.to_s + end + + test "successfully updating an existing record to attach a new blob from an uploaded file" do + @user.avatar = fixture_file_upload("racecar.jpg") + assert_equal "racecar.jpg", @user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(@user.avatar.key) + + @user.save! + assert ActiveStorage::Blob.service.exist?(@user.avatar.key) + end + + test "unsuccessfully updating an existing record to attach a new blob from an uploaded file" do + assert_not @user.update(name: "", avatar: fixture_file_upload("racecar.jpg")) + assert_equal "racecar.jpg", @user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(@user.avatar.key) + end + + test "successfully replacing an existing, dependent attachment on an existing record" do + create_blob(filename: "funky.jpg").tap do |old_blob| + @user.avatar.attach old_blob + + perform_enqueued_jobs do + @user.avatar.attach create_blob(filename: "town.jpg") + end + + assert_equal "town.jpg", @user.avatar.filename.to_s + assert_not ActiveStorage::Blob.exists?(old_blob.id) + assert_not ActiveStorage::Blob.service.exist?(old_blob.key) + end + end + + test "replacing an existing, independent attachment on an existing record" do + @user.cover_photo.attach create_blob(filename: "funky.jpg") + + assert_no_enqueued_jobs only: ActiveStorage::PurgeJob do + @user.cover_photo.attach create_blob(filename: "town.jpg") + end + + assert_equal "town.jpg", @user.cover_photo.filename.to_s + end + + test "replacing an attached blob on an existing record with itself" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + + assert_no_changes -> { @user.reload.avatar_attachment.id } do + assert_no_enqueued_jobs do + @user.avatar.attach blob + end + end + + assert_equal "funky.jpg", @user.avatar.filename.to_s + assert ActiveStorage::Blob.service.exist?(@user.avatar.key) + end + end + + test "successfully updating an existing record to replace an existing, dependent attachment" do + create_blob(filename: "funky.jpg").tap do |old_blob| + @user.avatar.attach old_blob + + perform_enqueued_jobs do + @user.update! avatar: create_blob(filename: "town.jpg") + end + + assert_equal "town.jpg", @user.avatar.filename.to_s + assert_not ActiveStorage::Blob.exists?(old_blob.id) + assert_not ActiveStorage::Blob.service.exist?(old_blob.key) + end + end + + test "successfully updating an existing record to replace an existing, independent attachment" do + @user.cover_photo.attach create_blob(filename: "funky.jpg") + + assert_no_enqueued_jobs only: ActiveStorage::PurgeJob do + @user.update! cover_photo: create_blob(filename: "town.jpg") + end + + assert_equal "town.jpg", @user.cover_photo.filename.to_s + end + + test "unsuccessfully updating an existing record to replace an existing attachment" do + @user.avatar.attach create_blob(filename: "funky.jpg") + + assert_no_enqueued_jobs do + assert_not @user.update(name: "", avatar: fixture_file_upload("racecar.jpg")) + end + + assert_equal "racecar.jpg", @user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(@user.avatar.key) + end + + test "updating an existing record to replace an attached blob with itself" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + + assert_no_enqueued_jobs do + assert_no_changes -> { @user.reload.avatar_attachment.id } do + @user.update! avatar: blob + end + end + end + end + + test "removing a dependent attachment from an existing record" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + + assert_enqueued_with job: ActiveStorage::PurgeJob, args: [ blob ] do + @user.avatar.attach nil + end + + assert_not @user.avatar.attached? + end + end + + test "removing an independent attachment from an existing record" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.cover_photo.attach blob + + assert_no_enqueued_jobs only: ActiveStorage::PurgeJob do + @user.cover_photo.attach nil + end + + assert_not @user.cover_photo.attached? + end + end + + test "updating an existing record to remove a dependent attachment" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + + assert_enqueued_with job: ActiveStorage::PurgeJob, args: [ blob ] do + @user.update! avatar: nil + end + + assert_not @user.avatar.attached? + end + end + + test "updating an existing record to remove an independent attachment" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.cover_photo.attach blob + + assert_no_enqueued_jobs only: ActiveStorage::PurgeJob do + @user.update! cover_photo: nil + end + + assert_not @user.cover_photo.attached? + end + end + + test "analyzing a new blob from an uploaded file after attaching it to an existing record" do + perform_enqueued_jobs do + @user.avatar.attach fixture_file_upload("racecar.jpg") + end + + assert @user.avatar.reload.analyzed? + assert_equal 4104, @user.avatar.metadata[:width] + assert_equal 2736, @user.avatar.metadata[:height] + end + + test "analyzing a new blob from an uploaded file after attaching it to an existing record via update" do + perform_enqueued_jobs do + @user.update! avatar: fixture_file_upload("racecar.jpg") + end + + assert @user.avatar.reload.analyzed? + assert_equal 4104, @user.avatar.metadata[:width] + assert_equal 2736, @user.avatar.metadata[:height] + end + + test "analyzing a directly-uploaded blob after attaching it to an existing record" do + perform_enqueued_jobs do + @user.avatar.attach directly_upload_file_blob(filename: "racecar.jpg") + end + + assert @user.avatar.reload.analyzed? + assert_equal 4104, @user.avatar.metadata[:width] + assert_equal 2736, @user.avatar.metadata[:height] + end + + test "analyzing a directly-uploaded blob after attaching it to an existing record via updates" do + perform_enqueued_jobs do + @user.update! avatar: directly_upload_file_blob(filename: "racecar.jpg") + end + + assert @user.avatar.reload.analyzed? + assert_equal 4104, @user.avatar.metadata[:width] + assert_equal 2736, @user.avatar.metadata[:height] + end + + test "attaching an existing blob to a new record" do + User.new(name: "Jason").tap do |user| + user.avatar.attach create_blob(filename: "funky.jpg") + assert user.new_record? + assert_equal "funky.jpg", user.avatar.filename.to_s + + user.save! + assert_equal "funky.jpg", user.reload.avatar.filename.to_s + end + end + + test "attaching an existing blob from a signed ID to a new record" do + User.new(name: "Jason").tap do |user| + user.avatar.attach create_blob(filename: "funky.jpg").signed_id + assert user.new_record? + assert_equal "funky.jpg", user.avatar.filename.to_s + + user.save! + assert_equal "funky.jpg", user.reload.avatar.filename.to_s + end + end + + test "attaching a new blob from a Hash to a new record" do + User.new(name: "Jason").tap do |user| + user.avatar.attach io: StringIO.new("STUFF"), filename: "town.jpg", content_type: "image/jpg" + assert user.new_record? + assert user.avatar.attachment.new_record? + assert user.avatar.blob.new_record? + assert_equal "town.jpg", user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(user.avatar.key) + + user.save! + assert user.avatar.attachment.persisted? + assert user.avatar.blob.persisted? + assert_equal "town.jpg", user.reload.avatar.filename.to_s + assert ActiveStorage::Blob.service.exist?(user.avatar.key) + end + end + + test "attaching a new blob from an uploaded file to a new record" do + User.new(name: "Jason").tap do |user| + user.avatar.attach fixture_file_upload("racecar.jpg") + assert user.new_record? + assert user.avatar.attachment.new_record? + assert user.avatar.blob.new_record? + assert_equal "racecar.jpg", user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(user.avatar.key) + + user.save! + assert user.avatar.attachment.persisted? + assert user.avatar.blob.persisted? + assert_equal "racecar.jpg", user.reload.avatar.filename.to_s + assert ActiveStorage::Blob.service.exist?(user.avatar.key) + end + end + + test "creating a record with an existing blob attached" do + user = User.create!(name: "Jason", avatar: create_blob(filename: "funky.jpg")) + assert_equal "funky.jpg", user.reload.avatar.filename.to_s + end + + test "creating a record with an existing blob from a signed ID attached" do + user = User.create!(name: "Jason", avatar: create_blob(filename: "funky.jpg").signed_id) + assert_equal "funky.jpg", user.reload.avatar.filename.to_s + end + + test "creating a record with a new blob from an uploaded file attached" do + User.new(name: "Jason", avatar: fixture_file_upload("racecar.jpg")).tap do |user| + assert user.new_record? + assert user.avatar.attachment.new_record? + assert user.avatar.blob.new_record? + assert_equal "racecar.jpg", user.avatar.filename.to_s + assert_not ActiveStorage::Blob.service.exist?(user.avatar.key) + + user.save! + assert_equal "racecar.jpg", user.reload.avatar.filename.to_s + end + end + + test "creating a record with an unexpected object attached" do + error = assert_raises(ArgumentError) { User.create!(name: "Jason", avatar: :foo) } + assert_equal "Could not find or build blob: expected attachable, got :foo", error.message + end + + test "analyzing a new blob from an uploaded file after attaching it to a new record" do + perform_enqueued_jobs do + user = User.create!(name: "Jason", avatar: fixture_file_upload("racecar.jpg")) + assert user.avatar.reload.analyzed? + assert_equal 4104, user.avatar.metadata[:width] + assert_equal 2736, user.avatar.metadata[:height] + end + end + + test "analyzing a directly-uploaded blob after attaching it to a new record" do + perform_enqueued_jobs do + user = User.create!(name: "Jason", avatar: directly_upload_file_blob(filename: "racecar.jpg")) + assert user.avatar.reload.analyzed? + assert_equal 4104, user.avatar.metadata[:width] + assert_equal 2736, user.avatar.metadata[:height] + end + end + + test "detaching" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + assert @user.avatar.attached? + + perform_enqueued_jobs do + @user.avatar.detach + end + + assert_not @user.avatar.attached? + assert ActiveStorage::Blob.exists?(blob.id) + assert ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "purging" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + assert @user.avatar.attached? + + @user.avatar.purge + assert_not @user.avatar.attached? + assert_not ActiveStorage::Blob.exists?(blob.id) + assert_not ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "purging an attachment with a shared blob" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + assert @user.avatar.attached? + + another_user = User.create!(name: "John") + another_user.avatar.attach blob + assert another_user.avatar.attached? + + @user.avatar.purge + assert_not @user.avatar.attached? + assert ActiveStorage::Blob.exists?(blob.id) + assert ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "purging later" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + assert @user.avatar.attached? + + perform_enqueued_jobs do + @user.avatar.purge_later + end + + assert_not @user.avatar.attached? + assert_not ActiveStorage::Blob.exists?(blob.id) + assert_not ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "purging an attachment later with shared blob" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + assert @user.avatar.attached? + + another_user = User.create!(name: "John") + another_user.avatar.attach blob + assert another_user.avatar.attached? + + perform_enqueued_jobs do + @user.avatar.purge_later + end + + assert_not @user.avatar.attached? + assert ActiveStorage::Blob.exists?(blob.id) + assert ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "purging dependent attachment later on destroy" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.avatar.attach blob + + perform_enqueued_jobs do + @user.destroy! + end + + assert_not ActiveStorage::Blob.exists?(blob.id) + assert_not ActiveStorage::Blob.service.exist?(blob.key) + end + end + + test "not purging independent attachment on destroy" do + create_blob(filename: "funky.jpg").tap do |blob| + @user.cover_photo.attach blob + + assert_no_enqueued_jobs do + @user.destroy! + end + end + end + + test "clearing change on reload" do + @user.avatar = create_blob(filename: "funky.jpg") + assert @user.avatar.attached? + + @user.reload + assert_not @user.avatar.attached? + end + + test "overriding attached reader" do + @user.avatar.attach create_blob(filename: "funky.jpg") + + assert_equal "funky.jpg", @user.avatar.filename.to_s + + begin + User.class_eval do + def avatar + super.filename.to_s.reverse + end + end + + assert_equal "gpj.yknuf", @user.avatar + ensure + User.send(:remove_method, :avatar) + end + end +end |