Skip to content

Commit acce7a5

Browse files
pskodrbennema1
authored andcommitted
test: added mitigation filter unit tests & fix finding reporter setup
:
1 parent 41d05c2 commit acce7a5

1 file changed

Lines changed: 138 additions & 24 deletions

File tree

unittests/test_filter_finding_mitigation.py

Lines changed: 138 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from dojo.filters import ApiFindingFilter, FindingFilterHelper
77
from dojo.models import (
8+
Dojo_User,
89
Engagement,
910
Finding,
1011
Product,
@@ -14,7 +15,7 @@
1415
)
1516

1617

17-
def _make_finding(title, mitigation, product):
18+
def _make_finding(title, mitigation, product, reporter):
1819
test_type, _ = Test_Type.objects.get_or_create(name="Unit Test")
1920
engagement = Engagement.objects.create(
2021
name="Test Engagement",
@@ -33,6 +34,7 @@ def _make_finding(title, mitigation, product):
3334
test=test,
3435
severity="Medium",
3536
mitigation=mitigation,
37+
reporter=reporter,
3638
verified=True,
3739
active=True,
3840
)
@@ -41,62 +43,174 @@ def _make_finding(title, mitigation, product):
4143
class MitigationFilterTestCase(TestCase):
4244
@classmethod
4345
def setUpTestData(cls):
46+
cls.reporter = Dojo_User.objects.create_user(
47+
username="mitigation-filter-api",
48+
email="mitigation-filter-api@example.com",
49+
password="password123", # noqa: S106
50+
)
4451
prod_type = Product_Type.objects.create(name="Test Type")
4552
product = Product.objects.create(
4653
name="Test Product",
4754
prod_type=prod_type,
4855
)
49-
cls.finding_with_mitigation = _make_finding("Finding A", "apply patch", product)
50-
cls.finding_null_mitigation = _make_finding("Finding B", None, product)
51-
cls.finding_empty_mitigation = _make_finding("Finding C", "", product)
56+
cls.finding_with_mitigation = _make_finding("Finding A", "apply patch", product, cls.reporter)
57+
cls.finding_upper_mitigation = _make_finding("Finding D", "APPLY PATCH", product, cls.reporter)
58+
cls.finding_whitespace_mitigation = _make_finding("Finding E", " ", product, cls.reporter)
59+
cls.finding_null_mitigation = _make_finding("Finding B", None, product, cls.reporter)
60+
cls.finding_empty_mitigation = _make_finding("Finding C", "", product, cls.reporter)
5261

5362
def _api_filter(self, params):
54-
qs = Finding.objects.all()
63+
qs = Finding.objects.filter(
64+
title__in=["Finding A", "Finding B", "Finding C", "Finding D", "Finding E"]
65+
)
5566
f = ApiFindingFilter(params, queryset=qs)
5667
return set(f.qs.values_list("id", flat=True))
5768

58-
def test_mitigation_icontains(self):
59-
# Filtering by mitigation text returns only findings whose mitigation contains that substring
60-
pass
69+
# --- mitigation icontains ---
70+
71+
def test_mitigation_icontains_lowercase(self):
72+
# Substring match: "patch" should hit "apply patch" and "APPLY PATCH"
73+
result = self._api_filter({"mitigation": "patch"})
74+
self.assertIn(self.finding_with_mitigation.id, result)
75+
self.assertIn(self.finding_upper_mitigation.id, result)
76+
self.assertNotIn(self.finding_null_mitigation.id, result)
77+
self.assertNotIn(self.finding_empty_mitigation.id, result)
78+
79+
def test_mitigation_icontains_uppercase(self):
80+
# Case-insensitive: uppercase query also matches lowercase stored value
81+
result = self._api_filter({"mitigation": "PATCH"})
82+
self.assertIn(self.finding_with_mitigation.id, result)
83+
self.assertIn(self.finding_upper_mitigation.id, result)
84+
85+
def test_mitigation_icontains_no_match(self):
86+
result = self._api_filter({"mitigation": "ZZZNOMATCH"})
87+
self.assertEqual(result, set())
88+
89+
def test_mitigation_icontains_partial(self):
90+
# Partial substring match
91+
result = self._api_filter({"mitigation": "apply"})
92+
self.assertIn(self.finding_with_mitigation.id, result)
93+
self.assertIn(self.finding_upper_mitigation.id, result)
94+
self.assertNotIn(self.finding_null_mitigation.id, result)
95+
self.assertNotIn(self.finding_empty_mitigation.id, result)
96+
97+
# --- mitigation_available=true ---
6198

6299
def test_mitigation_available_true(self):
63-
# mitigation_available=true returns only findings with a non-null, non-empty mitigation
64-
pass
100+
# Returns only findings with non-null, non-empty mitigation
101+
result = self._api_filter({"mitigation_available": "true"})
102+
self.assertIn(self.finding_with_mitigation.id, result)
103+
self.assertIn(self.finding_upper_mitigation.id, result)
104+
# Whitespace-only is NOT null and NOT empty string — current impl includes it
105+
self.assertIn(self.finding_whitespace_mitigation.id, result)
106+
self.assertNotIn(self.finding_null_mitigation.id, result)
107+
self.assertNotIn(self.finding_empty_mitigation.id, result)
108+
109+
# --- mitigation_available=false ---
65110

66111
def test_mitigation_available_false(self):
67-
# mitigation_available=false returns only findings with a null or empty mitigation
68-
pass
112+
# Returns findings where mitigation is null OR empty string
113+
result = self._api_filter({"mitigation_available": "false"})
114+
self.assertIn(self.finding_null_mitigation.id, result)
115+
self.assertIn(self.finding_empty_mitigation.id, result)
116+
self.assertNotIn(self.finding_with_mitigation.id, result)
117+
self.assertNotIn(self.finding_upper_mitigation.id, result)
69118

70119
def test_mitigation_available_false_handles_null(self):
71-
# mitigation_available=false includes findings where mitigation is NULL
72-
pass
120+
# NULL mitigation is explicitly captured by the false branch
121+
result = self._api_filter({"mitigation_available": "false"})
122+
self.assertIn(self.finding_null_mitigation.id, result)
73123

74124
def test_mitigation_available_false_handles_empty_string(self):
75-
# mitigation_available=false includes findings where mitigation is an empty string
76-
pass
125+
# Empty-string mitigation is explicitly captured by the false branch
126+
result = self._api_filter({"mitigation_available": "false"})
127+
self.assertIn(self.finding_empty_mitigation.id, result)
128+
129+
def test_mitigation_available_false_excludes_whitespace(self):
130+
# Whitespace-only mitigation (" ") is NOT null and NOT empty-string,
131+
# so the false branch does NOT include it — document current behavior.
132+
result = self._api_filter({"mitigation_available": "false"})
133+
self.assertNotIn(self.finding_whitespace_mitigation.id, result)
134+
135+
# --- no filter parameter ---
136+
137+
def test_no_filter_returns_full_set(self):
138+
# Baseline: no params → all five findings returned
139+
result = self._api_filter({})
140+
expected = {
141+
self.finding_with_mitigation.id,
142+
self.finding_upper_mitigation.id,
143+
self.finding_whitespace_mitigation.id,
144+
self.finding_null_mitigation.id,
145+
self.finding_empty_mitigation.id,
146+
}
147+
self.assertEqual(result, expected)
148+
149+
# --- combined filters (intersection) ---
150+
151+
def test_combined_mitigation_text_and_available_true(self):
152+
# "patch" icontains AND mitigation_available=true → only the two "patch" findings
153+
result = self._api_filter({"mitigation": "patch", "mitigation_available": "true"})
154+
self.assertEqual(
155+
result,
156+
{self.finding_with_mitigation.id, self.finding_upper_mitigation.id},
157+
)
158+
159+
def test_combined_mitigation_text_and_available_false(self):
160+
# text filter AND mitigation_available=false → empty: false branch returns null/empty,
161+
# icontains on null/empty returns nothing matching "patch"
162+
result = self._api_filter({"mitigation": "patch", "mitigation_available": "false"})
163+
self.assertEqual(result, set())
77164

78165

79166
class MitigationUIFilterTestCase(TestCase):
80167
@classmethod
81168
def setUpTestData(cls):
169+
cls.reporter = Dojo_User.objects.create_user(
170+
username="mitigation-filter-ui",
171+
email="mitigation-filter-ui@example.com",
172+
password="password123", # noqa: S106
173+
)
82174
prod_type = Product_Type.objects.create(name="UI Test Type")
83175
product = Product.objects.create(
84176
name="UI Test Product",
85177
prod_type=prod_type,
86178
)
87-
cls.finding_with_mitigation = _make_finding("UI Finding A", "upgrade to v2", product)
88-
cls.finding_null_mitigation = _make_finding("UI Finding B", None, product)
89-
cls.finding_empty_mitigation = _make_finding("UI Finding C", "", product)
179+
cls.finding_with_mitigation = _make_finding("UI Finding A", "upgrade to v2", product, cls.reporter)
180+
cls.finding_whitespace_mitigation = _make_finding("UI Finding D", " ", product, cls.reporter)
181+
cls.finding_null_mitigation = _make_finding("UI Finding B", None, product, cls.reporter)
182+
cls.finding_empty_mitigation = _make_finding("UI Finding C", "", product, cls.reporter)
90183

91184
def _ui_filter(self, params):
92-
qs = Finding.objects.all()
185+
qs = Finding.objects.filter(
186+
title__in=["UI Finding A", "UI Finding B", "UI Finding C", "UI Finding D"]
187+
)
93188
f = FindingFilterHelper(params, queryset=qs)
94189
return set(f.qs.values_list("id", flat=True))
95190

96191
def test_mitigation_available_true(self):
97-
# mitigation_available=true returns only findings with a non-null, non-empty mitigation
98-
pass
192+
# True branch: excludes null and empty string; whitespace-only is included
193+
result = self._ui_filter({"mitigation_available": "true"})
194+
self.assertIn(self.finding_with_mitigation.id, result)
195+
self.assertIn(self.finding_whitespace_mitigation.id, result)
196+
self.assertNotIn(self.finding_null_mitigation.id, result)
197+
self.assertNotIn(self.finding_empty_mitigation.id, result)
99198

100199
def test_mitigation_available_false(self):
101-
# mitigation_available=false returns only findings with a null or empty mitigation
102-
pass
200+
# False branch: returns null and empty string, excludes non-empty
201+
result = self._ui_filter({"mitigation_available": "false"})
202+
self.assertIn(self.finding_null_mitigation.id, result)
203+
self.assertIn(self.finding_empty_mitigation.id, result)
204+
self.assertNotIn(self.finding_with_mitigation.id, result)
205+
# Whitespace-only is not null/empty → not in false branch
206+
self.assertNotIn(self.finding_whitespace_mitigation.id, result)
207+
208+
def test_no_filter_returns_full_set(self):
209+
result = self._ui_filter({})
210+
expected = {
211+
self.finding_with_mitigation.id,
212+
self.finding_whitespace_mitigation.id,
213+
self.finding_null_mitigation.id,
214+
self.finding_empty_mitigation.id,
215+
}
216+
self.assertEqual(result, expected)

0 commit comments

Comments
 (0)