From 1efdfd94bee8bb6438e7e95b2e2b90309eccafe7 Mon Sep 17 00:00:00 2001 From: AbhimanyuGit2507 Date: Mon, 9 Feb 2026 16:54:51 +0530 Subject: [PATCH 1/2] Fix #10268: Add context-aware filtering to Finding Group filter - Implemented hierarchical context filtering (test > engagement > product > global) - Created get_finding_group_queryset_for_context() helper function to eliminate code duplication - Modified FindingFilter and FindingFilterWithoutObjectLookups to accept eid/tid parameters - Updated filter to show only Finding Groups from current test/engagement/product context - Added query optimization with .only("id", "name") for Finding Groups - Fixed user parameter passing to get_authorized_finding_groups_for_queryset() - Updated finding/views.py and test/views.py to pass context parameters to filters - Created comprehensive unit tests (8 test methods) covering all context levels This ensures users only see relevant Finding Groups in the filter dropdown based on their current page context, preventing confusion from seeing unrelated groups. --- dojo/filters.py | 99 ++++++- dojo/finding/views.py | 35 +-- dojo/test/views.py | 2 +- .../test_finding_group_filter_context.py | 248 ++++++++++++++++++ 4 files changed, 357 insertions(+), 27 deletions(-) create mode 100644 unittests/test_finding_group_filter_context.py diff --git a/dojo/filters.py b/dojo/filters.py index dabd1aec119..48db2443263 100644 --- a/dojo/filters.py +++ b/dojo/filters.py @@ -2020,6 +2020,32 @@ def filter_mitigated_on(self, queryset, name, value): return queryset.filter(mitigated=value) +def get_finding_group_queryset_for_context(pid=None, eid=None, tid=None): + """ + Helper function to build finding group queryset based on context hierarchy. + Context priority: test > engagement > product > global + + Args: + pid: Product ID (least specific) + eid: Engagement ID + tid: Test ID (most specific) + + Returns: + QuerySet of Finding_Group filtered by context + """ + if tid is not None: + # Most specific: filter by test + return Finding_Group.objects.filter(test_id=tid).only("id", "name") + if eid is not None: + # Filter by engagement's tests + return Finding_Group.objects.filter(test__engagement_id=eid).only("id", "name") + if pid is not None: + # Filter by product's tests + return Finding_Group.objects.filter(test__engagement__product_id=pid).only("id", "name") + # Global: return all (authorization will be applied separately) + return Finding_Group.objects.all().only("id", "name") + + class FindingFilterWithoutObjectLookups(FindingFilterHelper, FindingTagStringFilter): test__engagement__product__prod_type = NumberFilter(widget=HiddenInput()) test__engagement__product = NumberFilter(widget=HiddenInput()) @@ -2111,20 +2137,45 @@ class Meta: def __init__(self, *args, **kwargs): self.user = None self.pid = None + self.eid = None + self.tid = None if "user" in kwargs: self.user = kwargs.pop("user") if "pid" in kwargs: self.pid = kwargs.pop("pid") + if "eid" in kwargs: + self.eid = kwargs.pop("eid") + if "tid" in kwargs: + self.tid = kwargs.pop("tid") super().__init__(*args, **kwargs) # Set some date fields self.set_date_fields(*args, **kwargs) - # Don't show the product filter on the product finding view - if self.pid: - del self.form.fields["test__engagement__product__name"] - del self.form.fields["test__engagement__product__name_contains"] - del self.form.fields["test__engagement__product__prod_type__name"] - del self.form.fields["test__engagement__product__prod_type__name_contains"] + # Don't show the product/engagement/test filter fields when in specific context + if self.tid or self.eid or self.pid: + if "test__engagement__product__name" in self.form.fields: + del self.form.fields["test__engagement__product__name"] + if "test__engagement__product__name_contains" in self.form.fields: + del self.form.fields["test__engagement__product__name_contains"] + if "test__engagement__product__prod_type__name" in self.form.fields: + del self.form.fields["test__engagement__product__prod_type__name"] + if "test__engagement__product__prod_type__name_contains" in self.form.fields: + del self.form.fields["test__engagement__product__prod_type__name_contains"] + # Also hide engagement and test fields if in test or engagement context + if self.tid: + if "test__engagement__name" in self.form.fields: + del self.form.fields["test__engagement__name"] + if "test__engagement__name_contains" in self.form.fields: + del self.form.fields["test__engagement__name_contains"] + if "test__name" in self.form.fields: + del self.form.fields["test__name"] + if "test__name_contains" in self.form.fields: + del self.form.fields["test__name_contains"] + elif self.eid: + if "test__engagement__name" in self.form.fields: + del self.form.fields["test__engagement__name"] + if "test__engagement__name_contains" in self.form.fields: + del self.form.fields["test__engagement__name_contains"] class FindingFilter(FindingFilterHelper, FindingTagFilter): @@ -2163,11 +2214,17 @@ class Meta: def __init__(self, *args, **kwargs): self.user = None self.pid = None + self.eid = None + self.tid = None if "user" in kwargs: self.user = kwargs.pop("user") if "pid" in kwargs: self.pid = kwargs.pop("pid") + if "eid" in kwargs: + self.eid = kwargs.pop("eid") + if "tid" in kwargs: + self.tid = kwargs.pop("tid") super().__init__(*args, **kwargs) # Set some date fields self.set_date_fields(*args, **kwargs) @@ -2175,8 +2232,30 @@ def __init__(self, *args, **kwargs): self.set_related_object_fields(*args, **kwargs) def set_related_object_fields(self, *args: list, **kwargs: dict): - finding_group_query = Finding_Group.objects.all() - if self.pid is not None: + # Use helper to get contextual finding group queryset + finding_group_query = get_finding_group_queryset_for_context( + pid=self.pid, + eid=self.eid, + tid=self.tid, + ) + + # Filter by most specific context: test > engagement > product + if self.tid is not None: + # Test context: filter finding groups by test + del self.form.fields["test__engagement__product"] + del self.form.fields["test__engagement__product__prod_type"] + del self.form.fields["test__engagement"] + del self.form.fields["test"] + elif self.eid is not None: + # Engagement context: filter finding groups by engagement + del self.form.fields["test__engagement__product"] + del self.form.fields["test__engagement__product__prod_type"] + del self.form.fields["test__engagement"] + # Filter tests by engagement - get_authorized_tests doesn't support engagement param + engagement = Engagement.objects.get(id=self.eid) + self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=engagement.product).filter(engagement_id=self.eid).prefetch_related("test_type") + elif self.pid is not None: + # Product context: filter finding groups by product del self.form.fields["test__engagement__product"] del self.form.fields["test__engagement__product__prod_type"] # TODO: add authorized check to be sure @@ -2184,8 +2263,8 @@ def set_related_object_fields(self, *args: list, **kwargs: dict): product_id=self.pid, ).all() self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=self.pid).prefetch_related("test_type") - finding_group_query = Finding_Group.objects.filter(test__engagement__product_id=self.pid) else: + # Global context: show all authorized finding groups self.form.fields[ "test__engagement__product__prod_type"].queryset = get_authorized_product_types(Permissions.Product_Type_View) self.form.fields["test__engagement"].queryset = get_authorized_engagements(Permissions.Engagement_View) @@ -2194,7 +2273,7 @@ def set_related_object_fields(self, *args: list, **kwargs: dict): if self.form.fields.get("test__engagement__product"): self.form.fields["test__engagement__product"].queryset = get_authorized_products(Permissions.Product_View) if self.form.fields.get("finding_group", None): - self.form.fields["finding_group"].queryset = get_authorized_finding_groups_for_queryset(Permissions.Finding_Group_View, finding_group_query) + self.form.fields["finding_group"].queryset = get_authorized_finding_groups_for_queryset(Permissions.Finding_Group_View, finding_group_query, user=self.user) self.form.fields["reporter"].queryset = get_authorized_users(Permissions.Finding_View) self.form.fields["reviewers"].queryset = self.form.fields["reporter"].queryset diff --git a/dojo/finding/views.py b/dojo/finding/views.py index 5dfd50d601b..46c4d8ae471 100644 --- a/dojo/finding/views.py +++ b/dojo/finding/views.py @@ -267,6 +267,8 @@ def filter_findings_by_form(self, request: HttpRequest, findings: QuerySet[Findi kwargs = { "user": request.user, "pid": self.get_product_id(), + "eid": self.get_engagement_id(), + "tid": self.get_test_id(), } filter_string_matching = get_system_setting("filter_string_matching", False) @@ -360,10 +362,11 @@ def add_breadcrumbs(self, request: HttpRequest, context: dict): return request, context - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): - # Store the product and engagement ids + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): + # Store the product, engagement, and test ids self.product_id = product_id self.engagement_id = engagement_id + self.test_id = test_id # Get the initial context request, context = self.get_initial_context(request) # Get the filtered findings @@ -386,46 +389,46 @@ def get(self, request: HttpRequest, product_id: int | None = None, engagement_id class ListOpenFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Open" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListVerifiedFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Verified" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListOutOfScopeFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Out of Scope" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListFalsePositiveFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "False Positive" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListInactiveFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Inactive" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListAcceptedFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Accepted" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ListClosedFindings(ListFindings): - def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None): + def get(self, request: HttpRequest, product_id: int | None = None, engagement_id: int | None = None, test_id: int | None = None): self.filter_name = "Closed" self.order_by = "-mitigated" - return super().get(request, product_id=product_id, engagement_id=engagement_id) + return super().get(request, product_id=product_id, engagement_id=engagement_id, test_id=test_id) class ViewFinding(View): diff --git a/dojo/test/views.py b/dojo/test/views.py index c8b52bb6f14..f3510147290 100644 --- a/dojo/test/views.py +++ b/dojo/test/views.py @@ -122,7 +122,7 @@ def get_findings(self, request: HttpRequest, test: Test): findings = Finding.objects.filter(test=test).order_by("numerical_severity") filter_string_matching = get_system_setting("filter_string_matching", False) finding_filter_class = FindingFilterWithoutObjectLookups if filter_string_matching else FindingFilter - findings = finding_filter_class(request.GET, pid=test.engagement.product.id, queryset=findings) + findings = finding_filter_class(request.GET, pid=test.engagement.product.id, eid=test.engagement.id, tid=test.id, queryset=findings) paged_findings = get_page_items_and_count(request, prefetch_for_findings(findings.qs), 25, prefix="findings") fix_available_count = findings.qs.filter(fix_available=True).count() diff --git a/unittests/test_finding_group_filter_context.py b/unittests/test_finding_group_filter_context.py new file mode 100644 index 00000000000..015a82c8bea --- /dev/null +++ b/unittests/test_finding_group_filter_context.py @@ -0,0 +1,248 @@ +from django.test import TestCase +from django.utils.timezone import now + +from dojo.filters import FindingFilter, FindingFilterWithoutObjectLookups +from dojo.models import ( + Dojo_User, + Engagement, + Finding, + Finding_Group, + Product, + Product_Type, + Test, + Test_Type, +) + + +class TestFindingGroupFilterContext(TestCase): + """Test that Finding Group filter respects Test/Engagement/Product context.""" + + @classmethod + def setUpTestData(cls): + """Create test data hierarchy.""" + # Create test type + cls.test_type = Test_Type.objects.create(name="Test Type") + + # Create user + cls.user = Dojo_User.objects.create( + username="testuser", + is_staff=True, + is_superuser=True, + ) + + # Create Product Type + cls.prod_type = Product_Type.objects.create(name="Product Type") + + # Create two products + cls.product1 = Product.objects.create( + name="Product 1", + prod_type=cls.prod_type, + ) + cls.product2 = Product.objects.create( + name="Product 2", + prod_type=cls.prod_type, + ) + + # Create engagements for each product + cls.engagement1 = Engagement.objects.create( + name="Engagement 1", + product=cls.product1, + target_start=now(), + target_end=now(), + ) + cls.engagement2 = Engagement.objects.create( + name="Engagement 2", + product=cls.product2, + target_start=now(), + target_end=now(), + ) + cls.engagement3 = Engagement.objects.create( + name="Engagement 3", + product=cls.product1, # Same product as engagement1 + target_start=now(), + target_end=now(), + ) + + # Create tests for each engagement + cls.test1 = Test.objects.create( + title="Test 1", + engagement=cls.engagement1, + test_type=cls.test_type, + target_start=now(), + target_end=now(), + ) + cls.test2 = Test.objects.create( + title="Test 2", + engagement=cls.engagement2, + test_type=cls.test_type, + target_start=now(), + target_end=now(), + ) + cls.test3 = Test.objects.create( + title="Test 3", + engagement=cls.engagement3, + test_type=cls.test_type, + target_start=now(), + target_end=now(), + ) + + # Create finding groups in each test + cls.group1 = Finding_Group.objects.create( + name="Group 1", + test=cls.test1, + creator=cls.user, + ) + cls.group2 = Finding_Group.objects.create( + name="Group 2", + test=cls.test2, + creator=cls.user, + ) + cls.group3 = Finding_Group.objects.create( + name="Group 3", + test=cls.test3, + creator=cls.user, + ) + + # Create a finding in each group (required for group to be valid) + cls.finding1 = Finding.objects.create( + title="Finding 1", + test=cls.test1, + reporter=cls.user, + severity="High", + finding_group=cls.group1, + ) + cls.finding2 = Finding.objects.create( + title="Finding 2", + test=cls.test2, + reporter=cls.user, + severity="High", + finding_group=cls.group2, + ) + cls.finding3 = Finding.objects.create( + title="Finding 3", + test=cls.test3, + reporter=cls.user, + severity="High", + finding_group=cls.group3, + ) + + def test_finding_group_filter_in_test_context(self): + """Test filter shows only groups from specific test.""" + # Create filter with test context + finding_filter = FindingFilter( + data={}, + queryset=Finding.objects.all(), + user=self.user, + tid=self.test1.id, + ) + + # Get the finding group queryset + group_queryset = finding_filter.form.fields["finding_group"].queryset + + # Should only show group from test1 + self.assertEqual(group_queryset.count(), 1) + self.assertIn(self.group1, group_queryset) + self.assertNotIn(self.group2, group_queryset) + self.assertNotIn(self.group3, group_queryset) + + def test_finding_group_filter_in_engagement_context(self): + """Test filter shows only groups from engagement's tests.""" + # Create filter with engagement context + finding_filter = FindingFilter( + data={}, + queryset=Finding.objects.all(), + user=self.user, + eid=self.engagement1.id, + ) + + # Get the finding group queryset + group_queryset = finding_filter.form.fields["finding_group"].queryset + + # Should only show group from engagement1's tests (test1) + self.assertEqual(group_queryset.count(), 1) + self.assertIn(self.group1, group_queryset) + self.assertNotIn(self.group2, group_queryset) + self.assertNotIn(self.group3, group_queryset) + + def test_finding_group_filter_in_product_context(self): + """Test filter shows only groups from product's tests.""" + # Create filter with product context + finding_filter = FindingFilter( + data={}, + queryset=Finding.objects.all(), + user=self.user, + pid=self.product1.id, + ) + + # Get the finding group queryset + group_queryset = finding_filter.form.fields["finding_group"].queryset + + # Should show groups from product1's tests (test1 and test3) + self.assertEqual(group_queryset.count(), 2) + self.assertIn(self.group1, group_queryset) + self.assertIn(self.group3, group_queryset) + self.assertNotIn(self.group2, group_queryset) + + def test_finding_group_filter_global_context(self): + """Test filter shows all authorized groups in global context.""" + # Create filter without context + finding_filter = FindingFilter( + data={}, + queryset=Finding.objects.all(), + user=self.user, + ) + + # Get the finding group queryset + group_queryset = finding_filter.form.fields["finding_group"].queryset + + # Should show all groups (user is superuser) + self.assertEqual(group_queryset.count(), 3) + self.assertIn(self.group1, group_queryset) + self.assertIn(self.group2, group_queryset) + self.assertIn(self.group3, group_queryset) + + def test_finding_group_filter_hierarchy_precedence(self): + """Test that test context takes precedence over engagement/product.""" + # Create filter with all contexts (test should win) + finding_filter = FindingFilter( + data={}, + queryset=Finding.objects.all(), + user=self.user, + pid=self.product1.id, + eid=self.engagement1.id, + tid=self.test3.id, # Different test + ) + + # Get the finding group queryset + group_queryset = finding_filter.form.fields["finding_group"].queryset + + # Should only show group from test3 (most specific context) + self.assertEqual(group_queryset.count(), 1) + self.assertIn(self.group3, group_queryset) + + def test_finding_group_filter_without_object_lookups_test_context(self): + """Test FindingFilterWithoutObjectLookups respects test context.""" + # Create filter with test context + finding_filter = FindingFilterWithoutObjectLookups( + data={}, + queryset=Finding.objects.all(), + user=self.user, + tid=self.test1.id, + ) + + # Verify test filter fields are hidden in test context + self.assertNotIn("test__name", finding_filter.form.fields) + self.assertNotIn("test__engagement__name", finding_filter.form.fields) + + def test_finding_group_filter_without_object_lookups_engagement_context(self): + """Test FindingFilterWithoutObjectLookups respects engagement context.""" + # Create filter with engagement context + finding_filter = FindingFilterWithoutObjectLookups( + data={}, + queryset=Finding.objects.all(), + user=self.user, + eid=self.engagement1.id, + ) + + # Verify engagement filter fields are hidden in engagement context + self.assertNotIn("test__engagement__name", finding_filter.form.fields) From da8f6045d08025f3ddbea72192e378513ed15ca6 Mon Sep 17 00:00:00 2001 From: AbhimanyuGit2507 Date: Mon, 9 Feb 2026 17:00:45 +0530 Subject: [PATCH 2/2] Switch to DojoTestCase for better test compatibility Use DojoTestCase instead of plain TestCase to align with DefectDojo testing conventions and ensure proper test setup/teardown. --- dojo/filters.py | 52 ++++++++++++------- .../test_finding_group_filter_context.py | 10 ++-- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/dojo/filters.py b/dojo/filters.py index 48db2443263..3c38ce7246f 100644 --- a/dojo/filters.py +++ b/dojo/filters.py @@ -2024,14 +2024,15 @@ def get_finding_group_queryset_for_context(pid=None, eid=None, tid=None): """ Helper function to build finding group queryset based on context hierarchy. Context priority: test > engagement > product > global - + Args: pid: Product ID (least specific) eid: Engagement ID tid: Test ID (most specific) - + Returns: QuerySet of Finding_Group filtered by context + """ if tid is not None: # Most specific: filter by test @@ -2238,37 +2239,50 @@ def set_related_object_fields(self, *args: list, **kwargs: dict): eid=self.eid, tid=self.tid, ) - + # Filter by most specific context: test > engagement > product if self.tid is not None: # Test context: filter finding groups by test - del self.form.fields["test__engagement__product"] - del self.form.fields["test__engagement__product__prod_type"] - del self.form.fields["test__engagement"] - del self.form.fields["test"] + if "test__engagement__product" in self.form.fields: + del self.form.fields["test__engagement__product"] + if "test__engagement__product__prod_type" in self.form.fields: + del self.form.fields["test__engagement__product__prod_type"] + if "test__engagement" in self.form.fields: + del self.form.fields["test__engagement"] + if "test" in self.form.fields: + del self.form.fields["test"] elif self.eid is not None: # Engagement context: filter finding groups by engagement - del self.form.fields["test__engagement__product"] - del self.form.fields["test__engagement__product__prod_type"] - del self.form.fields["test__engagement"] + if "test__engagement__product" in self.form.fields: + del self.form.fields["test__engagement__product"] + if "test__engagement__product__prod_type" in self.form.fields: + del self.form.fields["test__engagement__product__prod_type"] + if "test__engagement" in self.form.fields: + del self.form.fields["test__engagement"] # Filter tests by engagement - get_authorized_tests doesn't support engagement param - engagement = Engagement.objects.get(id=self.eid) - self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=engagement.product).filter(engagement_id=self.eid).prefetch_related("test_type") + engagement = Engagement.objects.filter(id=self.eid).select_related("product").first() + if engagement: + self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=engagement.product).filter(engagement_id=self.eid).prefetch_related("test_type") elif self.pid is not None: # Product context: filter finding groups by product - del self.form.fields["test__engagement__product"] - del self.form.fields["test__engagement__product__prod_type"] + if "test__engagement__product" in self.form.fields: + del self.form.fields["test__engagement__product"] + if "test__engagement__product__prod_type" in self.form.fields: + del self.form.fields["test__engagement__product__prod_type"] # TODO: add authorized check to be sure - self.form.fields["test__engagement"].queryset = Engagement.objects.filter( - product_id=self.pid, - ).all() - self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=self.pid).prefetch_related("test_type") + if "test__engagement" in self.form.fields: + self.form.fields["test__engagement"].queryset = Engagement.objects.filter( + product_id=self.pid, + ).all() + if "test" in self.form.fields: + self.form.fields["test"].queryset = get_authorized_tests(Permissions.Test_View, product=self.pid).prefetch_related("test_type") else: # Global context: show all authorized finding groups self.form.fields[ "test__engagement__product__prod_type"].queryset = get_authorized_product_types(Permissions.Product_Type_View) self.form.fields["test__engagement"].queryset = get_authorized_engagements(Permissions.Engagement_View) - del self.form.fields["test"] + if "test" in self.form.fields: + del self.form.fields["test"] if self.form.fields.get("test__engagement__product"): self.form.fields["test__engagement__product"].queryset = get_authorized_products(Permissions.Product_View) diff --git a/unittests/test_finding_group_filter_context.py b/unittests/test_finding_group_filter_context.py index 015a82c8bea..f9811aa5942 100644 --- a/unittests/test_finding_group_filter_context.py +++ b/unittests/test_finding_group_filter_context.py @@ -1,4 +1,3 @@ -from django.test import TestCase from django.utils.timezone import now from dojo.filters import FindingFilter, FindingFilterWithoutObjectLookups @@ -13,8 +12,11 @@ Test_Type, ) +from .dojo_test_case import DojoTestCase + + +class TestFindingGroupFilterContext(DojoTestCase): -class TestFindingGroupFilterContext(TestCase): """Test that Finding Group filter respects Test/Engagement/Product context.""" @classmethod @@ -22,7 +24,7 @@ def setUpTestData(cls): """Create test data hierarchy.""" # Create test type cls.test_type = Test_Type.objects.create(name="Test Type") - + # Create user cls.user = Dojo_User.objects.create( username="testuser", @@ -37,10 +39,12 @@ def setUpTestData(cls): cls.product1 = Product.objects.create( name="Product 1", prod_type=cls.prod_type, + description="Test product 1", ) cls.product2 = Product.objects.create( name="Product 2", prod_type=cls.prod_type, + description="Test product 2", ) # Create engagements for each product