From c31b7509c50c8f1682ad1f5467175115570c7ee4 Mon Sep 17 00:00:00 2001 From: Laura Ghiorghisor Date: Wed, 27 Nov 2024 18:09:48 +0000 Subject: [PATCH] wip tests --- lib/tasks/assets.rake | 10 ++ spec/lib/tasks/assets_spec.rb | 221 ++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 76a325d7..86a04ae4 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -50,4 +50,14 @@ namespace :assets do end end end + + desc "Bulk fix assets" + namespace :bulk_fix do + task :update_replacement_draft, %i[csv_path] => :environment do |_t, args| + csv_path = args.fetch(:csv_path) + CSV.foreach(csv_path, headers: false) do |row| + puts row[1] + end + end + end end diff --git a/spec/lib/tasks/assets_spec.rb b/spec/lib/tasks/assets_spec.rb index 4a23934b..620248df 100644 --- a/spec/lib/tasks/assets_spec.rb +++ b/spec/lib/tasks/assets_spec.rb @@ -29,4 +29,225 @@ expect { task.invoke("foo") }.to raise_error(Mongoid::Errors::DocumentNotFound) end end + + context "bulk_fix" do + let(:asset_id) { "abc123def456ghi789"} + let(:filepath) { "/stub/filename.csv" } + + before do + task.reenable # without this, calling `invoke` does nothing after first test + allow(CSV).to receive(:foreach).and_return( + [["abc123def456ghi789"]] + ) + end + + # TODO: add batch parameter tests + + # 80k assets in this category - we're updating their replacements (replacements are expected to be in draft and deleted) + describe "assets:bulk_fix:update_replacement_draft" do + let(:task) { Rake::Task["assets:bulk_fix:update_replacement_draft"] } + + it "changes draft state for asset replacement if the replacement is both in draft and deleted" do + replacement = FactoryBot.create(:asset, draft: true, deleted_at: Time.now, replacement_id: nil) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Replacement #{replacement.id} draft updated to false." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.draft }.to eq false + end + + it "skips the asset, if the replacement is in draft and deleted, but has a further replacement" do + double_replacement = FactoryBot.create(:asset) + replacement = FactoryBot.create(:asset, draft: true, deleted_at: Time.now, replacement_id: double_replacement) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} has a further replacement." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.draft }.to eq true + end + + it "skips the asset, if the replacement is in draft, but not deleted" do + replacement = FactoryBot.create(:asset, draft: true, deleted_at: nil, replacement_id: nil) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} is not deleted." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.draft }.to eq true + end + + it "skips the asset, if the replacement is deleted, but not in draft" do + replacement = FactoryBot.create(:asset, draft: false, deleted_at: Time.now, replacement_id: nil) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} is not in draft." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.draft }.to eq true + end + + it "skips the asset and print exception if asset is not found" do + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. No asset found." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset and print exception if replacement asset is not found" do + replacement = FactoryBot.create(:asset) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement.id) + replacement.delete + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. No replacement asset found." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + end + + # 30k assets in this category - we're updating the assets themselves (these are the ones that have AD not deleted and not replaced in WH) + # TODO: can we check if the asset is live by curling the URL? + describe "assets:bulk_fix:delete_and_update_draft" do + let(:task) { Rake::Task["assets:bulk_fix:delete_and_update_draft"] } + + it "deletes the asset and updates the draft state if the asset is not deleted, and draft is true" do + FactoryBot.create(:asset, id: asset_id, deleted_at: nil, draft: true) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Asset deleted, draft updated to false." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { asset.reload.deleted_at }.to not_be_nil + expect { asset.reload.draft }.to eq false + end + + it "only deletes the asset if the asset is not deleted, and draft is false " do + asset = FactoryBot.create(:asset, id: asset_id, deleted_at: nil, draft: false) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Asset deleted, draft remains false." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { asset.reload.deleted_at }.to not_be_nil + expect { asset.reload.draft }.to eq false + end + + it "only updates the draft state, if the asset is already deleted and draft is true" do + FactoryBot.create(:asset, id: asset_id, deleted_at: Time.zone.now, draft: true) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Asset draft updated, asset already deleted." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { asset.reload.draft }.to eq false + end + + # TODO: do we want to skip assets that have a replacement? we expect none + it "does not change any state if the asset is replaced" do + FactoryBot.create(:asset, id: asset_id, replacement_id: FactoryBot.create(:asset)) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Asset has a replacement." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset and print exception if asset is not found" do + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. No asset found." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + end + + #16k assets in this category - we're updating their replacements (replacements are expected to be in draft but not deleted and not replaced) + describe "assets:bulk_fix:delete_and_update_replacement_draft" do + let(:task) { Rake::Task["assets:bulk_fix:delete_and_update_draft"] } + + it "deletes the asset replacement and updates the draft state if the asset is not deleted, and draft is true, and asset is not further replaced" do + replacement = FactoryBot.create(:asset, draft: true, deleted_at: nil, replacement_id: nil) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Replacement #{replacement.id} deleted and draft state updated." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.deleted_at }.to not_be_nil + expect { replacement.reload.draft }.to eq false + end + + it "skips the asset, if the asset replacement is already deleted" do + replacement = FactoryBot.create(:asset, draft: true, deleted_at: true, replacement_id: nil) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} already deleted." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset, if the asset replacement is further replaced" do + replacement = FactoryBot.create(:asset, draft: true, deleted_at: true, replacement_id: FactoryBot.create(:asset)) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} has a replacement." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset, if the asset replacement is not in draft" do + replacement = FactoryBot.create(:asset, draft: false, deleted_at: true, replacement_id: FactoryBot.create(:asset)) + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. Replacement #{replacement.id} is not in draft." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset and print exception if asset is not found" do + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. No asset found." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + + it "skips the asset and print exception if asset replacement is not found" do + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - SKIPPED. No asset replacement found." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + end + end + + # TODO: This category has 16k assets, for which we'd need to extract the corresponding replacement value (i.e. the end of the line AD's corresponding asset variant's ID). + # TODO: We can do that as a separate task, and then run this task. Or we can do it all in one task. + describe "assets:bulk_fix:update_replacement" do + let(:task) { Rake::Task["assets:bulk_fix:update_replacement"] } + + it "sets a replacement value for the asset" do + FactoryBot.create(:asset, id: asset_id, replacement_id: replacement) + + expected_output = <<~OUTPUT + "Asset ID: #{asset_id} - OK. Asset replacement updated." + OUTPUT + expect { task.invoke(filepath) }.to output(expected_output).to_stdout + expect { replacement.reload.replacement_id }.to not_be_nil + end + + it "skips the asset and print exception if asset is not found" do + expect { task.invoke("foo") }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it "skips the asset and print exception if replacement is not found" do + expect { task.invoke("foo") }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + end end