Skip to content

Commit f364104

Browse files
committed
handle the validation error in admin
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 515c710 commit f364104

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

vulnerabilities/triage/forms.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#
88

99
from django import forms
10+
from django.core.exceptions import ValidationError
1011

1112
from dje.forms import DataspacedAdminForm
1213
from vulnerabilities.models import VulnerabilityAnalysisContentMixin
@@ -35,6 +36,13 @@ class Meta:
3536
"is_reachable",
3637
]
3738

39+
def clean(self):
40+
main_fields = ["state", "justification", "responses", "detail"]
41+
if not any(self.cleaned_data.get(field_name) for field_name in main_fields):
42+
raise ValidationError(
43+
"At least one of state, justification, responses or detail must be provided."
44+
)
45+
3846

3947
class TriageRulesetForm(DataspacedAdminForm):
4048
recommended_action = forms.ChoiceField(

vulnerabilities/triage/tests/test_forms.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,33 @@
99
from django.test import TestCase
1010

1111
from dje.models import Dataspace
12+
from vulnerabilities.triage.forms import AnalysisPresetForm
1213
from vulnerabilities.triage.forms import TriageRulesetForm
14+
from vulnerabilities.triage.models import AnalysisPreset
1315
from vulnerabilities.triage.models import TriageRuleset
1416

1517

18+
class AnalysisPresetFormTestCase(TestCase):
19+
def setUp(self):
20+
self.dataspace = Dataspace.objects.create(name="nexB")
21+
22+
def test_rejects_a_preset_with_no_content_field_set(self):
23+
# Mirrors VulnerabilityAnalysisForm.clean: is_reachable alone is not enough content
24+
# to apply, and must be caught here rather than crash in AnalysisPreset.save().
25+
data = {"name": "No content", "is_reachable": True}
26+
form = AnalysisPresetForm(data=data, instance=AnalysisPreset(dataspace=self.dataspace))
27+
self.assertFalse(form.is_valid())
28+
msg = "At least one of state, justification, responses or detail must be provided."
29+
self.assertEqual({"__all__": [msg]}, form.errors)
30+
31+
def test_accepts_a_preset_with_detail_only(self):
32+
data = {"name": "Detail only", "detail": "Some detail"}
33+
form = AnalysisPresetForm(data=data, instance=AnalysisPreset(dataspace=self.dataspace))
34+
self.assertTrue(form.is_valid(), form.errors)
35+
preset = form.save()
36+
self.assertEqual("Some detail", preset.detail)
37+
38+
1639
class TriageRulesetFormTestCase(TestCase):
1740
def setUp(self):
1841
self.dataspace = Dataspace.objects.create(name="nexB")

0 commit comments

Comments
 (0)