diff --git a/app/services/hyrax/listeners/member_cleanup_listener.rb b/app/services/hyrax/listeners/member_cleanup_listener.rb index 48bbfc3cc5..d884cd927b 100644 --- a/app/services/hyrax/listeners/member_cleanup_listener.rb +++ b/app/services/hyrax/listeners/member_cleanup_listener.rb @@ -3,7 +3,7 @@ module Hyrax module Listeners ## - # Listens for object deleted events and cleans up associated members + # Listens for resource deleted events and cleans up associated members class MemberCleanupListener # Called when 'object.deleted' event is published # @param [Dry::Events::Event] event @@ -16,7 +16,7 @@ def on_object_deleted(event) begin Hyrax.persister.delete(resource: file_set) Hyrax.publisher - .publish('object.deleted', object: file_set, id: file_set.id, user: user) + .publish('object.deleted', object: file_set, id: file_set.id, user: event[:user]) rescue StandardError # we don't uncaught errors looping filesets Hyrax.logger.warn "Failed to delete #{file_set.class}:#{file_set.id} " \ "during cleanup for resource: #{event[:object]}. " \ @@ -24,6 +24,26 @@ def on_object_deleted(event) end end end + + # Called when 'collection.deleted' event is published + # @param [Dry::Events::Event] event + # @return [void] + def on_collection_deleted(event) + return unless event.payload.key?(:collection) # legacy callback + return if event[:collection].is_a?(ActiveFedora::Base) # handled by legacy code + + Hyrax.custom_queries.find_members_of(collection: event[:collection]).each do |resource| + begin + resource.member_of_collection_ids -= [event[:collection].id] + Hyrax.persister.save(resource: resource) + Hyrax.publisher + .publish('collection.membership.updated', collection: event[:collection], user: event[:user]) + rescue StandardError + Hyrax.logger.warn "Failed to remove collection reference from #{work.class}:#{work.id} " \ + "during cleanup for collection: #{event[:collection]}. " + end + end + end end end end diff --git a/spec/services/hyrax/listeners/member_cleanup_listener_spec.rb b/spec/services/hyrax/listeners/member_cleanup_listener_spec.rb new file mode 100644 index 0000000000..965d428f82 --- /dev/null +++ b/spec/services/hyrax/listeners/member_cleanup_listener_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'hyrax/specs/spy_listener' + +RSpec.describe Hyrax::Listeners::MemberCleanupListener do + subject(:listener) { described_class.new } + let(:data) { { collection: collection, user: user } } + let(:event) { Dry::Events::Event.new(event_type, data) } + let(:user) { FactoryBot.create(:user) } + let(:spy_listener) { Hyrax::Specs::SpyListener.new } + + before { Hyrax.publisher.subscribe(spy_listener) } + after { Hyrax.publisher.unsubscribe(spy_listener) } + + describe '#on_object_deleted' do + let(:data) { { object: work, user: user } } + let(:event_type) { :on_object_deleted } + let(:work) { FactoryBot.valkyrie_create(:hyrax_work, member_ids: [file_set.id]) } + let(:file_set) { FactoryBot.valkyrie_create(:hyrax_file_set) } + + it 'removes child file set objects' do + expect { listener.on_object_deleted(event) } + .to change { Hyrax.custom_queries.find_child_filesets(resource: event[:object]).size } + .from(1) + .to(0) + end + + it 'publishes events' do + listener.on_object_deleted(event) + expect(spy_listener.object_deleted&.payload) + .to include(id: file_set.id, object: file_set, user: user) + end + end + + describe '#on_collection_deleted' do + let(:collection) { FactoryBot.valkyrie_create(:hyrax_collection) } + let(:data) { { collection: collection, user: user } } + let(:event_type) { :on_collection_deleted } + let(:work) { FactoryBot.valkyrie_create(:monograph, member_of_collection_ids: [collection.id]) } + + before do + work + end + + it 'removes collection references from member objects' do + expect { listener.on_collection_deleted(event) } + .to change { Hyrax.custom_queries.find_members_of(collection: event[:collection]).size } + .from(1) + .to(0) + end + + it 'publishes events' do + listener.on_collection_deleted(event) + expect(spy_listener.collection_membership_updated&.payload) + .to include(collection: collection, user: user) + end + end +end