@@ -2533,3 +2533,39 @@ 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+ entity = publishing_api .create_publishable_entity (
2549+ self .learning_package_1 .id ,
2550+ "entity_for_bulk_publish_check" ,
2551+ created = self .now ,
2552+ created_by = None ,
2553+ )
2554+ publishing_api .create_publishable_entity_version (
2555+ entity .id ,
2556+ version_num = 1 ,
2557+ title = "Entity v1" ,
2558+ created = self .now ,
2559+ created_by = None ,
2560+ )
2561+
2562+ with pytest .raises (ValidationError , match = "Cannot publish while in bulk_draft_changes_for()." ):
2563+ with publishing_api .bulk_draft_changes_for (self .learning_package_1 .id ):
2564+ publishing_api .publish_all_drafts (self .learning_package_1 .id )
2565+
2566+ with pytest .raises (ValidationError , match = "Cannot publish while in bulk_draft_changes_for()." ):
2567+ with publishing_api .bulk_draft_changes_for (self .learning_package_1 .id ):
2568+ publishing_api .publish_from_drafts (
2569+ self .learning_package_1 .id ,
2570+ Draft .objects .filter (entity__learning_package_id = self .learning_package_1 .id ),
2571+ )
0 commit comments