def test_unmatch_snapshot_tree_last_match(self): """ Tests the simplest case of unmatching a building where the child snapshot created from the original matching has not since been matched with another building (no children). """ self._add_additional_fake_buildings() # simulate matching bs1 and bs2 to have a child of bs3 self.bs1.children.add(self.bs3) self.bs2.children.add(self.bs3) canon = self.bs1.canonical_building canon2 = self.bs2.canonical_building canon2.active = False canon2.save() self.bs3.canonical_building = canon self.bs3.save() canon.canonical_snapshot = self.bs3 canon.save() # unmatch bs2 from bs1 seed_models.unmatch_snapshot_tree(self.bs2.pk) canon = seed_models.CanonicalBuilding.objects.get(pk=canon.pk) canon2 = seed_models.CanonicalBuilding.objects.get(pk=canon2.pk) bs1 = seed_models.BuildingSnapshot.objects.get(pk=self.bs1.pk) bs2 = seed_models.BuildingSnapshot.objects.get(pk=self.bs2.pk) self.assertEqual(canon.canonical_snapshot, bs1) self.assertEqual(bs1.children.count(), 0) self.assertEqual(canon2.active, True)
def test_unmatch_snapshot_tree_inactive_canonical_building(self): """Make sure that old CanonicalBuildings get activated where needed.""" self._add_additional_fake_buildings() can = self.bs1.canonical_building can.active = False can.save() new_can = seed_models.CanonicalBuilding.objects.create( canonical_snapshot=self.bs2 ) self.bs2.canonical_building = new_can self.bs2.save() self.bs1.children.add(self.bs2) self.bs3.children.add(self.bs2) seed_models.unmatch_snapshot_tree(self.bs1.pk) refreshed_can = seed_models.CanonicalBuilding.objects.get(pk=can.pk) refreshed_bs1 = seed_models.BuildingSnapshot.objects.get( pk=self.bs1.pk ) # Our unmerged snapshot reactivates its canonical building self.assertEqual(refreshed_can.canonical_snapshot, self.bs1) self.assertEqual(refreshed_bs1.canonical_building, refreshed_can) # Newly remerged snapshot gets the original CanonicalBuilding refreshed_bs3 = seed_models.BuildingSnapshot.objects.get( pk=self.bs3.pk ) self.assertEqual(refreshed_bs3.canonical_building, new_can)
def test_unmatch_snapshot_tree_prior_match(self): """ Tests the more complicated case of unmatching a building after more buildings have been matched to the snapshot resulting from the original match. """ self._add_additional_fake_buildings() # simulate matching bs1 and bs2 to have a child of bs3 self.bs1.children.add(self.bs3) self.bs2.children.add(self.bs3) canon = self.bs1.canonical_building canon2 = self.bs2.canonical_building canon2.active = False canon2.save() self.bs3.canonical_building = canon self.bs3.save() canon.canonical_snapshot = self.bs3 canon.save() # now simulate matching bs4 and bs3 to have a child of bs5 self.bs3.children.add(self.bs5) self.bs4.children.add(self.bs5) self.bs5.canonical_building = canon self.bs5.save() canon.canonical_snapshot = self.bs5 canon.save() # simulating the following tree: # b1 b2 # \ / # b3 b4 # \ / # b5 # unmatch bs2 from bs1 seed_models.unmatch_snapshot_tree(self.bs2.pk) canon = seed_models.CanonicalBuilding.objects.get(pk=canon.pk) canon2 = seed_models.CanonicalBuilding.objects.get(pk=canon2.pk) # bs3, and bs5 should be deleted deleted_pks = [self.bs3.pk, self.bs5.pk] bs_manager = seed_models.BuildingSnapshot.objects theoretically_empty_set = bs_manager.filter(pk__in=deleted_pks) self.assertEqual(theoretically_empty_set.count(), 0) bs2 = bs_manager.get(pk=self.bs2.pk) self.assertEqual(bs2.has_children, False) self.assertEqual(canon2.active, True)
def test_unmatch_snapshot_tree_common_case(self): """Make sure it works for the general purpose.""" self._add_additional_fake_buildings() # Setup the typical situation in which our CanonicalSnapshot has # two parents. And we've decided that we don't like the match. can = self.bs1.canonical_building self.bs1.children.add(self.bs3) self.bs2.children.add(self.bs3) can.canonical_snapshot = self.bs3 can.save() self.bs3.canonical_building = can self.bs3.save() # We try to unmerge the child, since that's what we're looking at. seed_models.unmatch_snapshot_tree(self.bs3.pk) # Our child has been deleted, even though it's a leaf node. self.assertEqual( list(seed_models.BuildingSnapshot.objects.filter(pk=self.bs3.pk)), [] ) # Both parents are not leaf nodes themselves. self.assertEqual(self.bs1.children.count(), 0) self.assertEqual(self.bs2.children.count(), 0) refreshed_bs1 = seed_models.BuildingSnapshot.objects.get( pk=self.bs1.pk ) refreshed_bs2 = seed_models.BuildingSnapshot.objects.get( pk=self.bs2.pk ) # Both of our parents have canonical_buildings. self.assertNotEqual(refreshed_bs1.canonical_building, None) self.assertNotEqual(refreshed_bs2.canonical_building, None) # That are not the same... self.assertNotEqual( refreshed_bs1.canonical_building, refreshed_bs2.canonical_building ) # Make sure that our canonical snapshot references are updated. self.assertEqual( refreshed_bs1.canonical_building.canonical_snapshot, refreshed_bs1 ) self.assertEqual( refreshed_bs2.canonical_building.canonical_snapshot, refreshed_bs2 )
def test_unmatch_snapshot_tree_retains_canonical_snapshot(self): """ TODO: """ self.bs3 = util.make_fake_snapshot( self.import_file1, self.bs1_data, bs_type=seed_models.COMPOSITE_BS, is_canon=True, ) self.bs4 = util.make_fake_snapshot( self.import_file1, self.bs2_data, bs_type=seed_models.COMPOSITE_BS, is_canon=True, ) # simulate matching bs1 and bs2 to have a child of bs3 seed_models.save_snapshot_match(self.bs2.pk, self.bs1.tip.pk) seed_models.save_snapshot_match(self.bs3.pk, self.bs1.tip.pk) seed_models.save_snapshot_match(self.bs4.pk, self.bs1.tip.pk) tip_pk = self.bs1.tip.pk # simulating the following tree: # b1 b2 # \ / # b3 b4 # \ / # b5 # unmatch bs3 from bs4 seed_models.unmatch_snapshot_tree(self.bs4.pk) # tip should be deleted self.assertFalse( seed_models.BuildingSnapshot.objects.filter(pk=tip_pk).exists()) canon_bs4 = seed_models.CanonicalBuilding.objects.get( pk=self.bs4.canonical_building_id) # both of their canons should be active self.assertTrue(canon_bs4.active) # both cannons should have a canonical_snapshot self.assertEqual(canon_bs4.canonical_snapshot, self.bs4)
def test_unmatch_snapshot_tree_several_ancestors(self): """Test the effects of unmatching several ancestors.""" self._add_additional_fake_buildings() can = self.bs1.canonical_building self.bs1.children.add(self.bs2) self.bs2.children.add(self.bs5) # These two should remain when self.bs1 is unmerged. # Note that these two are not direct parents for bs5. self.bs3.children.add(self.bs2) self.bs4.children.add(self.bs5) self.bs5.canonical_building = can self.bs5.save() can.canonical_snapshot = self.bs5 can.save() seed_models.unmatch_snapshot_tree(self.bs1.pk) refreshed_can = seed_models.CanonicalBuilding.objects.get(pk=can.pk) expected_snapshot_parents = [self.bs3, self.bs4] # Make certain that the parents of the now canonical snapshot are # the "remaining ancestors" from our winnowing of ancesors. for parent in refreshed_can.canonical_snapshot.parents.all(): self.assertTrue(parent in expected_snapshot_parents) refreshed_bs1 = seed_models.BuildingSnapshot.objects.get( pk=self.bs1.pk ) refreshed_bs1_can = refreshed_bs1.canonical_building self.assertNotEqual(refreshed_bs1_can, refreshed_can) self.assertNotEqual(refreshed_bs1_can, None) self.assertEqual(refreshed_bs1_can.canonical_snapshot, refreshed_bs1) # Ensure that bs2 and bs5 were deleted. self.assertEqual( list(seed_models.BuildingSnapshot.objects.filter( pk__in=(self.bs2.pk, self.bs5.pk) )), [] )
def test_unmatch_snapshot_tree_retains_canonical_snapshot(self): """ TODO: """ self.bs3 = util.make_fake_snapshot( self.import_file1, self.bs1_data, bs_type=seed_models.COMPOSITE_BS, is_canon=True, ) self.bs4 = util.make_fake_snapshot( self.import_file1, self.bs2_data, bs_type=seed_models.COMPOSITE_BS, is_canon=True, ) # simulate matching bs1 and bs2 to have a child of bs3 seed_models.save_snapshot_match(self.bs2.pk, self.bs1.tip.pk) seed_models.save_snapshot_match(self.bs3.pk, self.bs1.tip.pk) seed_models.save_snapshot_match(self.bs4.pk, self.bs1.tip.pk) tip_pk = self.bs1.tip.pk # simulating the following tree: # b1 b2 # \ / # b3 b4 # \ / # b5 # unmatch bs3 from bs4 seed_models.unmatch_snapshot_tree(self.bs4.pk) # tip should be deleted self.assertFalse(seed_models.BuildingSnapshot.objects.filter(pk=tip_pk).exists()) canon_bs4 = seed_models.CanonicalBuilding.objects.get(pk=self.bs4.canonical_building_id) # both of their canons should be active self.assertTrue(canon_bs4.active) # both cannons should have a canonical_snapshot self.assertEqual(canon_bs4.canonical_snapshot, self.bs4)
def test_unmatch_snapshot_tree_single_ancestor(self): """Test experimental unmatch_snapshot_tree functionality.""" self._add_additional_fake_buildings() can = self.bs1.canonical_building # Make our child relationships. self.bs1.children.add(self.bs3) self.bs3.children.add(self.bs5) # Bs4 will be our outlier self.bs4.children.add(self.bs5) self.bs5.canonical_building = can self.bs5.save() can.canonical_snapshot = self.bs5 can.save() seed_models.unmatch_snapshot_tree(self.bs1.pk) refreshed_can = seed_models.CanonicalBuilding.objects.get(pk=can.pk) # Tests that if there's only one remainting ancestor, it just becomes # the canonical snapshot. self.assertEqual(refreshed_can.canonical_snapshot, self.bs4)