-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a custom attachment asset publish listener
We want to separate out the catch-all logic we currently have around asset updates. The `AttachmentUpdater` service listener was listening on all possible events, making it hard to understand which specific updates need to happen in which case. Additionally, in the `MetadataWorker` that it enqueues, the update and delete logic fired together. These changes are being made in the context of a bug that causes assets to remain live when a new draft attachment gets replaced and deleted. The issue was that the `deleted?` method on the replaced `AttachmentData` evaluated to true when attempting to update the asset to live after deleting the attachment. By separating the publish logic we are confident in removing the `deleted?` on update. We also removed the deletion call from the attachment controller's destroy method, so that the only delete calls to Asset Manager now happen from the publish listener, at the point of publish.
- Loading branch information
1 parent
3bfffae
commit d3ad536
Showing
10 changed files
with
161 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
app/services/service_listeners/attachment_asset_publisher.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module ServiceListeners | ||
class AttachmentAssetPublisher | ||
def self.call(attachable:) | ||
Attachment.includes(:attachment_data).where(attachable: attachable.attachables).find_each do |attachment| | ||
next unless attachment.attachment_data | ||
|
||
PublishAttachmentAssetJob.perform_async(attachment.attachment_data.id) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class PublishAttachmentAssetJob < WorkerBase | ||
sidekiq_options queue: "asset_manager" | ||
|
||
def perform(attachment_data_id) | ||
attachment_data = AttachmentData.find(attachment_data_id) | ||
|
||
asset_attributes = { | ||
"draft" => false, | ||
} | ||
|
||
unless attachment_data.replaced? | ||
asset_attributes.merge!({ "parent_document_url" => attachment_data.attachable_url }) | ||
end | ||
|
||
# We need to delete first, because if we delete after updating, and the delete request fails, | ||
# we will have a live asset. Asset Manager should let us update the deleted asset, | ||
# in line with recent changes that now permit the update of a deleted draft asset. | ||
# At this point in time, the asset is still in draft in Asset Manager, since the draft: false update | ||
# has not yet been sent, as we do not send it from anywhere else in the code. | ||
attachment_data.assets.each do |asset| | ||
AssetManager::AssetDeleter.call(asset.asset_manager_id) if attachment_data.deleted? | ||
AssetManager::AssetUpdater.call(asset.asset_manager_id, asset_attributes) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
test/unit/app/services/service_listeners/attachment_asset_publisher_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require "test_helper" | ||
|
||
module ServiceListeners | ||
class AttachmentAssetPublisherTest < ActiveSupport::TestCase | ||
extend Minitest::Spec::DSL | ||
|
||
describe ServiceListeners::AttachmentAssetPublisher do | ||
let(:edition) { create(:published_news_article) } | ||
let(:attachment) { create(:file_attachment, attachable: edition, attachment_data: create(:attachment_data, attachable: edition)) } | ||
|
||
it "sets the expected attributes" do | ||
expected_attribute_hash = { | ||
"draft" => false, | ||
"parent_document_url" => edition.public_url(draft: false), | ||
} | ||
|
||
AssetManager::AssetUpdater.expects(:call).with(attachment.attachment_data.assets.first.asset_manager_id, expected_attribute_hash) | ||
|
||
ServiceListeners::AttachmentAssetPublisher.call(attachable: edition) | ||
PublishAttachmentAssetJob.drain | ||
end | ||
|
||
it "deletes the asset if the attachment is deleted" do | ||
stub_asset(attachment.attachment_data.assets.first.asset_manager_id) | ||
attachment.destroy! | ||
|
||
AssetManager::AssetDeleter.expects(:call).with(attachment.attachment_data.assets.first.asset_manager_id) | ||
|
||
ServiceListeners::AttachmentAssetPublisher.call(attachable: edition) | ||
PublishAttachmentAssetJob.drain | ||
end | ||
|
||
def stub_asset(asset_manger_id, attributes = {}) | ||
url_id = "http://asset-manager/assets/#{asset_manger_id}" | ||
Services.asset_manager.stubs(:asset) | ||
.with(asset_manger_id) | ||
.returns(attributes.merge(id: url_id).stringify_keys) | ||
end | ||
end | ||
end | ||
end |
38 changes: 38 additions & 0 deletions
38
test/unit/app/sidekiq/publish_attachment_asset_job_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
require "test_helper" | ||
|
||
class PublishAttachmentAssetJobTest < ActiveSupport::TestCase | ||
extend Minitest::Spec::DSL | ||
|
||
describe PublishAttachmentAssetJob do | ||
let(:attachable) { create(:draft_news_article) } | ||
let(:attachment_data) { create(:attachment_data, attachable:) } | ||
let(:asset_manager_id) { attachment_data.assets.first.asset_manager_id } | ||
let(:worker) { PublishAttachmentAssetJob.new } | ||
|
||
it "it deletes and updates the asset if attachment data is deleted" do | ||
attachment = create(:file_attachment, attachable: attachable, attachment_data: attachment_data) | ||
attachment.destroy! | ||
|
||
AssetManager::AssetDeleter.expects(:call).with(asset_manager_id) | ||
AssetManager::AssetUpdater.expects(:call).with(asset_manager_id, { "draft" => false, "parent_document_url" => attachment_data.attachable_url }) | ||
|
||
worker.perform(attachment_data.id) | ||
end | ||
|
||
it "only updates the asset if attachment data is not deleted" do | ||
AssetManager::AssetUpdater.expects(:call).with(asset_manager_id, { "draft" => false, "parent_document_url" => attachment_data.attachable_url }) | ||
|
||
worker.perform(attachment_data.id) | ||
end | ||
|
||
context "attachment data is replaced" do | ||
it "does not set the parent_document_url" do | ||
attachment_data.update!(replaced_by: create(:attachment_data, attachable:)) | ||
|
||
AssetManager::AssetUpdater.expects(:call).with(asset_manager_id, { "draft" => false }) | ||
|
||
worker.perform(attachment_data.id) | ||
end | ||
end | ||
end | ||
end |