Skip to content

Commit 4804c98

Browse files
authored
fix: Call LIBRARY_CONTAINER_PUBLISHED for parent of containers (#37622)
Calls `LIBRARY_CONTAINER_PUBLISHED` when publishing a container that is child of another container.
1 parent d2f6bb9 commit 4804c98

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

openedx/core/djangoapps/content_libraries/tasks.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ def send_events_after_publish(publish_log_pk: int, library_key_str: str) -> None
127127
elif hasattr(record.entity, "container"):
128128
container_key = api.library_container_locator(library_key, record.entity.container)
129129
affected_containers.add(container_key)
130+
131+
try:
132+
# We do need to notify listeners that the parent container(s) have changed,
133+
# e.g. so the search index can update the "has_unpublished_changes"
134+
for parent_container in api.get_containers_contains_item(container_key):
135+
affected_containers.add(parent_container.container_key)
136+
except api.ContentLibraryContainerNotFound:
137+
# The deleted children remains in the entity, so, in this case, the container may not be found.
138+
pass
130139
else:
131140
log.warning(
132141
f"PublishableEntity {record.entity.pk} / {record.entity.key} was modified during publish operation "

openedx/core/djangoapps/content_libraries/tests/test_events.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,53 @@ def test_publish_container(self) -> None:
449449
c2_after = self._get_container(container2["id"])
450450
assert c2_after["has_unpublished_changes"]
451451

452+
def test_publish_child_container(self):
453+
"""
454+
Test the events that get emitted when we publish the changes to a container that is child of another container
455+
"""
456+
# Create some containers
457+
unit = self._create_container(self.lib1_key, "unit", display_name="Alpha Unit", slug=None)
458+
subsection = self._create_container(self.lib1_key, "subsection", display_name="Bravo Subsection", slug=None)
459+
460+
# Add one container as child
461+
self._add_container_children(subsection["id"], children_ids=[unit["id"]])
462+
463+
# At first everything is unpublished:
464+
c1_before = self._get_container(unit["id"])
465+
assert c1_before["has_unpublished_changes"]
466+
c2_before = self._get_container(subsection["id"])
467+
assert c2_before["has_unpublished_changes"]
468+
469+
# clear event log after the initial mock data setup is complete:
470+
self.clear_events()
471+
472+
# Now publish only the unit
473+
self._publish_container(unit["id"])
474+
475+
# Now it is published:
476+
c1_after = self._get_container(unit["id"])
477+
assert c1_after["has_unpublished_changes"] is False
478+
479+
# And publish events were emitted:
480+
self.expect_new_events(
481+
{ # An event for the unit being published:
482+
"signal": LIBRARY_CONTAINER_PUBLISHED,
483+
"library_container": LibraryContainerData(
484+
container_key=LibraryContainerLocator.from_string(unit["id"]),
485+
),
486+
},
487+
{ # An event for parent (subsection):
488+
"signal": LIBRARY_CONTAINER_PUBLISHED,
489+
"library_container": LibraryContainerData(
490+
container_key=LibraryContainerLocator.from_string(subsection["id"]),
491+
),
492+
},
493+
)
494+
495+
# note that subsection is still unpublished
496+
c2_after = self._get_container(subsection["id"])
497+
assert c2_after["has_unpublished_changes"]
498+
452499
def test_restore_unit(self) -> None:
453500
"""
454501
Test restoring a deleted unit via the "restore" API.

0 commit comments

Comments
 (0)