Skip to content

Commit

Permalink
Add rake task to update missing replacement links
Browse files Browse the repository at this point in the history
We've identified a bug where if the user replaces an attachments on a new draft,
without having saved the edition draft first, the supposedly replaced original
asset remains live, because it fails to redirect to its replacement.

Rerunning the updater on the original attachment's AttachmentData should send
the correct `replacement_id` field to `asset-manager`, and fix the data.

This is only a data patch solution.
A fix for the issue will be implemented separately.
  • Loading branch information
lauraghiorghisor-tw committed Dec 5, 2024
1 parent 98a0fa6 commit 0e38a08
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
21 changes: 21 additions & 0 deletions lib/tasks/attachments/fix_missing_asset_replacement_links.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
desc "Fix missing replacement links"
task :fix_missing_asset_replacement_links, %i[csv_path] => :environment do |_, args|
csv_path = args[:csv_path]

CSV.foreach(csv_path, headers: false) do |row|
attachment_data_id = row[0]
attachment_data = AttachmentData.find(attachment_data_id)

if attachment_data.replaced_by_id.nil?
puts "ERROR - ad: #{attachment_data.id} does not have a replacement."
next
end

begin
AssetManager::AttachmentUpdater.replace(attachment_data)
puts "OK - ad: #{attachment_data_id}" << "\n"
rescue StandardError => e
puts "ERROR - ad: #{attachment_data_id}, message: #{e.message || JSON.parse(e&.http_body)['_response_info']['status']}" << "\n"
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require "test_helper"
require "rake"

class FixMissingAssetReplacementLinksTest < ActiveSupport::TestCase
extend Minitest::Spec::DSL

describe "fix_missing_asset_replacement_links" do
let(:task) { Rake::Task["fix_missing_asset_replacement_links"] }
let(:file) { Tempfile.new("read_assets_file") }
let(:filepath) { file.path }
let(:attachable) { create(:news_article) }
let(:attachment_data) { create(:attachment_data, id: 123_456, attachable:) }
let(:replacement_data) { create(:attachment_data, attachable:) }
let(:replacement_data2) { create(:attachment_data, attachable:) }
let(:original_asset) { attachment_data.assets.original.first }
let(:thumbnail_asset) { attachment_data.assets.thumbnail.first }
let(:replacement_original_asset) { replacement_data.assets.original.first }
let(:replacement_thumbnail_asset) { replacement_data.assets.thumbnail.first }

teardown { task.reenable }

before do
csv_file = <<~CSV
123456
CSV
file.write(csv_file)
file.close

original_asset.asset_manager_id = "1592008029c8c3e4dc76256c"
original_asset.save!
thumbnail_asset.asset_manager_id = "1592008029c8c3e4dc76256d"
thumbnail_asset.save!
replacement_original_asset.asset_manager_id = "2592008029c8c3e4dc76256c"
replacement_original_asset.save!
replacement_thumbnail_asset.asset_manager_id = "2592008029c8c3e4dc76256d"
replacement_thumbnail_asset.save!

attachment_data.replaced_by = replacement_data
replacement_data.replaced_by = replacement_data2
attachment_data.save!
replacement_data.save!
replacement_data2.save!
end

test "it outputs AttachmentData ID and sends correct load" do
Services.asset_manager.stubs(:asset).with(original_asset.asset_manager_id).returns("id" => "http://asset-manager/assets/#{original_asset.asset_manager_id}", "name" => "original.pdf")
Services.asset_manager.stubs(:asset).with(thumbnail_asset.asset_manager_id).returns("id" => "http://asset-manager/assets/#{thumbnail_asset.asset_manager_id}", "name" => "thumbnail.pdf.png")

expected_output = <<~OUTPUT
OK - ad: #{attachment_data.id}
OUTPUT

Services.asset_manager.expects(:update_asset)
.at_least_once
.with(original_asset.asset_manager_id, { "replacement_id" => replacement_original_asset.asset_manager_id })

Services.asset_manager.expects(:update_asset)
.at_least_once
.with(thumbnail_asset.asset_manager_id, { "replacement_id" => replacement_thumbnail_asset.asset_manager_id })

output, _err = capture_io { task.invoke(filepath) }
assert_equal expected_output, output
end

test "it logs if no replacement is found" do
attachment_data.replaced_by_id = nil
attachment_data.save!

expected_output = <<~OUTPUT
ERROR - ad: #{attachment_data.id} does not have a replacement.
OUTPUT

output, _err = capture_io { task.invoke(filepath) }
assert_equal output, expected_output
end

test "it logs error if update fails" do
error = GdsApi::HTTPClientError.new(404, "Not found")
Services.asset_manager.expects(:asset).with(original_asset.asset_manager_id).raises(error)

expected_output = <<~OUTPUT
ERROR - ad: #{attachment_data.id}, message: Not found
OUTPUT

output, _err = capture_io { task.invoke(filepath) }
assert_equal expected_output, output
end
end
end

0 comments on commit 0e38a08

Please sign in to comment.