diff --git a/cms/lib/xblock/test/test_upstream_sync.py b/cms/lib/xblock/test/test_upstream_sync.py index c65c0fcb203c..94ee69e5f1f3 100644 --- a/cms/lib/xblock/test/test_upstream_sync.py +++ b/cms/lib/xblock/test/test_upstream_sync.py @@ -533,15 +533,19 @@ def test_sever_upstream_link(self): """ Does sever_upstream_link correctly disconnect a block from its upstream? """ - # Start with a course block that is linked+synced to a content library block. + # Start with a course block that is linked+synced to a content library block + # and has a customizred title. downstream = BlockFactory.create(category='html', parent=self.unit, upstream=str(self.upstream_key)) sync_from_upstream_block(downstream, self.user) + downstream.display_name = "Downstream Title" + save_xblock_with_callback(downstream, self.user) # (sanity checks) assert downstream.upstream == str(self.upstream_key) assert downstream.upstream_version == 2 assert downstream.upstream_display_name == "Upstream Title V2" - assert downstream.display_name == "Upstream Title V2" + assert downstream.display_name == "Downstream Title" + assert downstream.downstream_customized == ["display_name"] assert downstream.data == "Upstream content V2" assert downstream.copied_from_block is None @@ -552,14 +556,21 @@ def test_sever_upstream_link(self): assert downstream.upstream is None assert downstream.upstream_version is None assert downstream.upstream_display_name is None + assert downstream.downstream_customized == [] - # BUT, the content which was synced into the upstream remains. - assert downstream.display_name == "Upstream Title V2" + # BUT, the content remains. + assert downstream.display_name == "Downstream Title" assert downstream.data == "Upstream content V2" # AND, we have recorded the old upstream as our copied_from_block. assert downstream.copied_from_block == str(self.upstream_key) + # Finally... unlike an upstream-linked block, our unlinked block should not + # have its downstream_customized updated when the title changes. + downstream.display_name = "Downstream Title II" + save_xblock_with_callback(downstream, self.user) + assert downstream.downstream_customized == [] + def test_sync_library_block_tags(self): upstream_lib_block_key = libs.create_library_block(self.library.key, "html", "upstream").usage_key upstream_lib_block = xblock.load_block(upstream_lib_block_key, self.user) diff --git a/cms/lib/xblock/upstream_sync.py b/cms/lib/xblock/upstream_sync.py index ca23f9eb5e70..da9a60b422bc 100644 --- a/cms/lib/xblock/upstream_sync.py +++ b/cms/lib/xblock/upstream_sync.py @@ -386,6 +386,7 @@ def sever_upstream_link(downstream: XBlock) -> list[XBlock]: downstream.copied_from_block = downstream.upstream downstream.upstream = None downstream.upstream_version = None + downstream.downstream_customized = [] for _, fetched_upstream_field in downstream.get_customizable_fields().items(): # Downstream-only fields don't have an upstream fetch field if fetched_upstream_field is None: @@ -527,6 +528,10 @@ def editor_saved(self, user, old_metadata, old_content): Update `downstream_customized` when a customizable field is modified. """ super().editor_saved(user, old_metadata, old_content) + if not self.upstream: + # If a block does not have an upstream, then we do not need to track its + # customizations. + return customizable_fields = self.get_customizable_fields() new_data = ( self.get_explicitly_set_fields_by_scope(Scope.settings)