From 45a45d8e95079d3d751680827546cb510cbe1113 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Fri, 8 May 2026 11:27:42 -0700 Subject: [PATCH] fix: don't emit COLLECTION_CHANGED when entities restored into deleted collections --- .../applets/collections/tasks.py | 1 + .../applets/collections/test_signals.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/openedx_content/applets/collections/tasks.py b/src/openedx_content/applets/collections/tasks.py index 6b5a43d9e..b0f822d95 100644 --- a/src/openedx_content/applets/collections/tasks.py +++ b/src/openedx_content/applets/collections/tasks.py @@ -36,6 +36,7 @@ def emit_collections_changed_for_entity_changes_task( affected_cpes = ( CollectionPublishableEntity.objects.filter(entity_id__in=all_entity_ids) + .filter(collection__enabled=True) # Don't send events for soft-deleted collections .select_related("collection__learning_package") .order_by("collection_id", "entity_id") ) diff --git a/tests/openedx_content/applets/collections/test_signals.py b/tests/openedx_content/applets/collections/test_signals.py index 7c5c5fab4..c7bed1446 100644 --- a/tests/openedx_content/applets/collections/test_signals.py +++ b/tests/openedx_content/applets/collections/test_signals.py @@ -534,6 +534,34 @@ def test_entity_draft_restored_multiple_collections(lp1: LearningPackage) -> Non ) +def test_entity_draft_restored_skips_soft_deleted_collections(lp1: LearningPackage) -> None: + """ + Test that COLLECTION_CHANGED is NOT emitted for soft-deleted collections + when an entity's draft is restored, even if the entity is still a member + of those collections. + """ + col1 = api.create_collection(lp1.id, "col1", title="Collection 1", created_by=None) + api.create_collection(lp1.id, "col2-deleted", title="Collection 2", created_by=None) + entity = _create_entity_with_version(lp1.id, "entity1") + api.add_to_collection(lp1.id, "col1", PublishableEntity.objects.filter(id=entity.id)) + api.add_to_collection(lp1.id, "col2-deleted", PublishableEntity.objects.filter(id=entity.id)) + api.soft_delete_draft(entity.id) + api.delete_collection(lp1.id, "col2-deleted") # soft-delete col2 + + with capture_events(signals=[COLLECTION_CHANGED], expected_count=1) as captured: + api.create_publishable_entity_version( + entity.id, version_num=2, title="entity1 v2", created=now_time, created_by=None + ) + + # Only the still-enabled collection (col1) should receive an event. + event = captured[0] + assert event.kwargs["change"] == CollectionChangeData( + collection_id=col1.id, + collection_code="col1", + entities_added=[entity.id], + ) + + def test_entity_draft_restored_aborted(lp1: LearningPackage) -> None: """ Test that no COLLECTION_CHANGED is emitted when the