@@ -162,3 +162,67 @@ def load(self):
162162 source .remove (source .get ("parent" , {"name" : "Test-Parent" }), remove_children = True )
163163 source .sync_to (destination )
164164 assert call_order == ["Test-Child" , "Test-Parent" ]
165+
166+
167+ def test_natural_deletion_order_with_noop_parent ():
168+ """Test whether children are recursed through when natural deletion order is set and the parent has no changes."""
169+ call_order = []
170+
171+ class ChildModel (DiffSyncModel ):
172+ """Test child model that reports when its update method is called."""
173+
174+ _modelname = "child"
175+ _identifiers = ("name" ,)
176+ _attributes = ("attribute" ,)
177+
178+ name : str
179+ attribute : str
180+
181+ def update (self , attrs ):
182+ call_order .append ("Update on child" )
183+ return super ().update (attrs )
184+
185+ class ParentModel (DiffSyncModel ):
186+ """Test parent model."""
187+
188+ _modelname = "parent"
189+ _identifiers = ("name" ,)
190+ _attributes = ("attribute" ,)
191+ _children = {"child" : "children" }
192+
193+ name : str
194+ attribute : str
195+ children : List [ChildModel ] = []
196+
197+ class Adapter (DiffSync ):
198+ """Test adapter."""
199+
200+ top_level = ["parent" ]
201+
202+ parent = ParentModel
203+ child = ChildModel
204+
205+ def load (self , is_source = False ) -> None :
206+ """Test load method. Generate a difference with the is_source parameter."""
207+ parent = self .parent (name = "Test Parent" , attribute = "This doesn't change" )
208+ parent .model_flags |= DiffSyncModelFlags .NATURAL_DELETION_ORDER
209+ self .add (parent )
210+ if is_source :
211+ child = self .child (name = "Test Child" , attribute = "Attribute from source" )
212+ child .model_flags |= DiffSyncModelFlags .NATURAL_DELETION_ORDER
213+ parent .add_child (child )
214+ self .add (child )
215+ else :
216+ child = self .child (name = "Test Child" , attribute = "Attribute from destination" )
217+ child .model_flags |= DiffSyncModelFlags .NATURAL_DELETION_ORDER
218+ parent .add_child (child )
219+ self .add (child )
220+
221+ source_adapter = Adapter ()
222+ source_adapter .load (is_source = True )
223+ destination_adapter = Adapter ()
224+ destination_adapter .load ()
225+
226+ source_adapter .sync_to (destination_adapter )
227+
228+ assert "Update on child" in call_order
0 commit comments