Skip to content

Commit

Permalink
Merge pull request #249 from networktocode/fix-natural-deletion-order
Browse files Browse the repository at this point in the history
Fixes natural deletion order flag
  • Loading branch information
Kircheneer authored Nov 16, 2023
2 parents 94b5500 + a5f035a commit 8243ddb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
4 changes: 3 additions & 1 deletion diffsync/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,13 @@ def sync_diff_element(self, element: DiffElement, parent_model: Optional["DiffSy
natural_deletion_order = bool(dst_model.model_flags & DiffSyncModelFlags.NATURAL_DELETION_ORDER)
skip_children = bool(dst_model.model_flags & DiffSyncModelFlags.SKIP_CHILDREN_ON_DELETE)

# Recurse through children to delete if we are supposed to delete the current diff element
changed = False
if natural_deletion_order and self.action == DiffSyncActions.DELETE and not skip_children:
for child in element.get_children():
changed |= self.sync_diff_element(child, parent_model=dst_model)

# Sync the current model - this will delete the current model if self.action is DELETE
changed, modified_model = self.sync_model(src_model=src_model, dst_model=dst_model, ids=ids, attrs=attrs)
dst_model = modified_model or dst_model

Expand All @@ -396,7 +398,7 @@ def sync_diff_element(self, element: DiffElement, parent_model: Optional["DiffSy

self.incr_elements_processed()

if not natural_deletion_order:
if not natural_deletion_order or self.action is not DiffSyncActions.DELETE:
for child in element.get_children():
changed |= self.sync_diff_element(child, parent_model=dst_model)

Expand Down
64 changes: 64 additions & 0 deletions tests/unit/test_diffsync_model_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,67 @@ def load(self):
source.remove(source.get("parent", {"name": "Test-Parent"}), remove_children=True)
source.sync_to(destination)
assert call_order == ["Test-Child", "Test-Parent"]


def test_natural_deletion_order_with_noop_parent():
"""Test whether children are recursed through when natural deletion order is set and the parent has no changes."""
call_order = []

class ChildModel(DiffSyncModel):
"""Test child model that reports when its update method is called."""

_modelname = "child"
_identifiers = ("name",)
_attributes = ("attribute",)

name: str
attribute: str

def update(self, attrs):
call_order.append("Update on child")
return super().update(attrs)

class ParentModel(DiffSyncModel):
"""Test parent model."""

_modelname = "parent"
_identifiers = ("name",)
_attributes = ("attribute",)
_children = {"child": "children"}

name: str
attribute: str
children: List[ChildModel] = []

class Adapter(DiffSync):
"""Test adapter."""

top_level = ["parent"]

parent = ParentModel
child = ChildModel

def load(self, is_source=False) -> None:
"""Test load method. Generate a difference with the is_source parameter."""
parent = self.parent(name="Test Parent", attribute="This doesn't change")
parent.model_flags |= DiffSyncModelFlags.NATURAL_DELETION_ORDER
self.add(parent)
if is_source:
child = self.child(name="Test Child", attribute="Attribute from source")
child.model_flags |= DiffSyncModelFlags.NATURAL_DELETION_ORDER
parent.add_child(child)
self.add(child)
else:
child = self.child(name="Test Child", attribute="Attribute from destination")
child.model_flags |= DiffSyncModelFlags.NATURAL_DELETION_ORDER
parent.add_child(child)
self.add(child)

source_adapter = Adapter()
source_adapter.load(is_source=True)
destination_adapter = Adapter()
destination_adapter.load()

source_adapter.sync_to(destination_adapter)

assert "Update on child" in call_order

0 comments on commit 8243ddb

Please sign in to comment.