From f15dc002b6d2443aca049ac9a8f7155958625152 Mon Sep 17 00:00:00 2001 From: Jino Tesauro Date: Wed, 4 Feb 2026 16:36:07 -0600 Subject: [PATCH 1/3] added testing to ensure duplicate findings are deleted in the correct order --- unittests/test_duplication_loops.py | 35 ++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) mode change 100644 => 100755 unittests/test_duplication_loops.py diff --git a/unittests/test_duplication_loops.py b/unittests/test_duplication_loops.py old mode 100644 new mode 100755 index 3b1666eee04..a44103b4d34 --- a/unittests/test_duplication_loops.py +++ b/unittests/test_duplication_loops.py @@ -5,7 +5,8 @@ from dojo.finding.deduplication import set_duplicate from dojo.management.commands.fix_loop_duplicates import fix_loop_duplicates -from dojo.models import Engagement, Finding, Product, User, copy_model_util +from dojo.models import Engagement, Finding, Product, System_Settings, User, copy_model_util +from dojo.tasks import _async_dupe_delete_impl # noqa: PLC2701 from .dojo_test_case import DojoTestCase, versioned_fixtures @@ -374,6 +375,38 @@ def test_list_relations_for_three_reverse(self): self.assertEqual(self.finding_c.duplicate_finding_set().count(), 2) self.assertEqual(self.finding_b.duplicate_finding_set().count(), 2) + # Test that Delete Duplicate Findings & Maximum Duplicate is correctly deleting olding finding first based off of finding date value + def test_delete_duplicate_order(self): + # Turn on delete duplicates and set the maximum dedupe value to 1 + system_settings = System_Settings.objects.get() + system_settings.delete_duplicates = True + system_settings.max_dupes = 1 + system_settings.save() + + # Add dates to finding b and c + self.finding_b.date = "2024-01-01" + self.finding_c.date = "2023-01-01" + # Make findings b and c duplicates of a + set_duplicate(self.finding_b, self.finding_a) + set_duplicate(self.finding_c, self.finding_a) + + # Perform delete dedupe logic + _async_dupe_delete_impl() + + # Finding C (2023) should be deleted + self.assertFalse( + Finding.objects.filter(id=self.finding_c.id).exists(), + "The oldest duplicate (Finding c) should have been deleted.", + ) + # Finding b (2024) should exist + self.assertTrue( + Finding.objects.filter(id=self.finding_b.id).exists(), + "The newest duplicate (Finding B) should still exist.", + ) + # Finding A should now only have 2 duplicate in its set + self.finding_a.refresh_from_db() + self.assertEqual(self.finding_a.duplicate_finding_set().count(), 1) + def test_delete_all_engagements(self): # make sure there is no exception when deleting all engagements for engagement in Engagement.objects.all().order_by("id"): From 8d675b8e8cb78b7e5cf2c421737c09cc2614114f Mon Sep 17 00:00:00 2001 From: Jino Tesauro Date: Wed, 4 Feb 2026 16:38:54 -0600 Subject: [PATCH 2/3] fix ruff issues --- unittests/test_duplication_loops.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 unittests/test_duplication_loops.py diff --git a/unittests/test_duplication_loops.py b/unittests/test_duplication_loops.py old mode 100755 new mode 100644 From f7e65239b42eb7a619dcd461ff72377c4cca0adf Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:58:09 -0700 Subject: [PATCH 3/3] Update unittests/test_duplication_loops.py --- unittests/test_duplication_loops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/test_duplication_loops.py b/unittests/test_duplication_loops.py index a44103b4d34..a2afbeb37f9 100644 --- a/unittests/test_duplication_loops.py +++ b/unittests/test_duplication_loops.py @@ -403,7 +403,7 @@ def test_delete_duplicate_order(self): Finding.objects.filter(id=self.finding_b.id).exists(), "The newest duplicate (Finding B) should still exist.", ) - # Finding A should now only have 2 duplicate in its set + # Finding A should now only have 1 duplicate in its set self.finding_a.refresh_from_db() self.assertEqual(self.finding_a.duplicate_finding_set().count(), 1)