Skip to content

Commit 0d00d50

Browse files
fix: don't allow publishing within a draft change log context (#580)
1 parent 44ff4e5 commit 0d00d50

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

  • src/openedx_content/applets/publishing
  • tests/openedx_content/applets/publishing

src/openedx_content/applets/publishing/api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ def publish_from_drafts(
474474
By default, this will also publish all dependencies (e.g. unpinned children)
475475
of the Drafts that are passed in.
476476
"""
477+
if DraftChangeLogContext.get_active_draft_change_log(learning_package_id) is not None:
478+
raise ValidationError(
479+
f"Cannot publish learning package {learning_package_id} while in bulk_draft_changes_for()."
480+
)
477481
if published_at is None:
478482
published_at = datetime.now(tz=timezone.utc)
479483

tests/openedx_content/applets/publishing/test_api.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,3 +2533,47 @@ def test_create_version_rejects_cross_package_dependencies(self) -> None:
25332533
created_by=None,
25342534
dependencies=[entity_in_lp2.id],
25352535
)
2536+
2537+
def test_publish_functions_rejected_inside_bulk_draft_changes_for(self) -> None:
2538+
"""
2539+
publish_all_drafts() and publish_from_drafts() must not be callable
2540+
from within a bulk_draft_changes_for() context.
2541+
2542+
bulk_draft_changes_for() opens a DraftChangeLog for accumulating draft
2543+
edits; running a publish inside it mixes draft-change bookkeeping with
2544+
publish bookkeeping in the same atomic block, which corrupts the
2545+
ordering of DraftChangeLog vs. PublishLog records and can leave Drafts
2546+
and Published rows out of sync if the outer context later raises.
2547+
"""
2548+
lp1_id = self.learning_package_1.id
2549+
entity = publishing_api.create_publishable_entity(
2550+
self.learning_package_1.id,
2551+
"entity_for_bulk_publish_check",
2552+
created=self.now,
2553+
created_by=None,
2554+
)
2555+
publishing_api.create_publishable_entity_version(
2556+
entity.id,
2557+
version_num=1,
2558+
title="Entity v1",
2559+
created=self.now,
2560+
created_by=None,
2561+
)
2562+
2563+
with pytest.raises(
2564+
ValidationError,
2565+
match=f"Cannot publish learning package {lp1_id} while in bulk_draft_changes_for()."
2566+
):
2567+
with publishing_api.bulk_draft_changes_for(lp1_id):
2568+
publishing_api.publish_all_drafts(lp1_id)
2569+
2570+
with pytest.raises(
2571+
ValidationError,
2572+
match=f"Cannot publish learning package {lp1_id} while in bulk_draft_changes_for()."
2573+
):
2574+
with publishing_api.bulk_draft_changes_for(lp1_id):
2575+
publishing_api.publish_from_drafts(lp1_id, Draft.objects.filter(entity__learning_package_id=lp1_id))
2576+
2577+
# But we CAN publish if the bulk_draft_changes_for is a different learning package:
2578+
with publishing_api.bulk_draft_changes_for(self.learning_package_2.id):
2579+
publishing_api.publish_all_drafts(lp1_id)

0 commit comments

Comments
 (0)