Validation for 'Thema' on Vorgabe added
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/vui) (push) Successful in 14s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/vui-data-loader) (push) Successful in 4s
SonarQube Scan / SonarQube Trigger (push) Successful in 54s

This commit is contained in:
2025-12-08 14:41:02 +01:00
parent 74d2f15d6a
commit 753c00bc45
5 changed files with 144 additions and 2 deletions

View File

@@ -25,7 +25,7 @@ spec:
mountPath: /data mountPath: /data
containers: containers:
- name: web - name: web
image: git.baumann.gr/adebaumann/vui:0.971 image: git.baumann.gr/adebaumann/vui:0.972
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- containerPort: 8000 - containerPort: 8000

View File

@@ -94,10 +94,18 @@ class EinleitungInline(NestedStackedInline):
class VorgabeForm(forms.ModelForm): class VorgabeForm(forms.ModelForm):
referenzen = TreeNodeMultipleChoiceField(queryset=Referenz.objects.all(), required=False) referenzen = TreeNodeMultipleChoiceField(queryset=Referenz.objects.all(), required=False)
class Meta: class Meta:
model = Vorgabe model = Vorgabe
fields = '__all__' fields = '__all__'
def clean_thema(self):
"""Validate that thema is provided."""
thema = self.cleaned_data.get('thema')
if not thema:
raise forms.ValidationError('Thema ist ein Pflichtfeld. Bitte wählen Sie ein Thema aus.')
return thema
class VorgabeInline(SortableInlineAdminMixin, NestedStackedInline): class VorgabeInline(SortableInlineAdminMixin, NestedStackedInline):
model = Vorgabe model = Vorgabe
form = VorgabeForm form = VorgabeForm

View File

@@ -169,6 +169,12 @@ class Vorgabe(models.Model):
""" """
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
# Check that thema is provided
if not self.thema_id:
raise ValidationError({
'thema': 'Thema ist ein Pflichtfeld. Bitte wählen Sie ein Thema aus.'
})
# Check for conflicts with existing Vorgaben # Check for conflicts with existing Vorgaben
conflicts = self.find_conflicts() conflicts = self.find_conflicts()
if conflicts: if conflicts:

View File

@@ -761,6 +761,134 @@ class VorgabeSanityCheckTest(TestCase):
self.assertIn("intersecting validity periods", report) self.assertIn("intersecting validity periods", report)
class VorgabeThemaValidationTest(TestCase):
"""Test cases for Vorgabe Thema validation"""
def setUp(self):
"""Set up test data for Thema validation tests"""
self.dokumententyp = Dokumententyp.objects.create(
name="Standard IT-Sicherheit",
verantwortliche_ve="SR-SUR-SEC"
)
self.dokument = Dokument.objects.create(
nummer="R0066",
dokumententyp=self.dokumententyp,
name="IT Security Standard",
aktiv=True
)
self.thema = Thema.objects.create(name="Organisation")
def test_vorgabe_with_thema_passes_validation(self):
"""Test that Vorgabe with a valid Thema passes clean() validation"""
vorgabe = Vorgabe(
order=1,
nummer=1,
dokument=self.dokument,
thema=self.thema,
titel="Test Vorgabe",
gueltigkeit_von=date.today()
)
# Should not raise any exception
try:
vorgabe.clean()
except Exception as e:
self.fail(f"clean() raised {e} unexpectedly!")
def test_vorgabe_without_thema_fails_validation(self):
"""Test that Vorgabe without Thema fails clean() validation"""
from django.core.exceptions import ValidationError
vorgabe = Vorgabe(
order=1,
nummer=1,
dokument=self.dokument,
thema=None, # No Thema
titel="Test Vorgabe",
gueltigkeit_von=date.today()
)
with self.assertRaises(ValidationError) as context:
vorgabe.clean()
# Check that the error message is about thema
self.assertIn('thema', context.exception.message_dict)
self.assertIn('Thema ist ein Pflichtfeld', str(context.exception))
def test_vorgabe_form_with_thema_is_valid(self):
"""Test that VorgabeForm with Thema is valid"""
from dokumente.admin import VorgabeForm
form_data = {
'order': 1,
'nummer': 1,
'dokument': self.dokument.pk,
'thema': self.thema.pk,
'titel': 'Test Vorgabe',
'gueltigkeit_von': date.today(),
}
form = VorgabeForm(data=form_data)
self.assertTrue(form.is_valid(), f"Form errors: {form.errors}")
def test_vorgabe_form_without_thema_is_invalid(self):
"""Test that VorgabeForm without Thema is invalid"""
from dokumente.admin import VorgabeForm
form_data = {
'order': 1,
'nummer': 1,
'dokument': self.dokument.pk,
'thema': '', # Empty/missing Thema
'titel': 'Test Vorgabe',
'gueltigkeit_von': date.today(),
}
form = VorgabeForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn('thema', form.errors)
def test_vorgabe_form_thema_error_message_is_german(self):
"""Test that VorgabeForm shows German error message for missing Thema"""
from dokumente.admin import VorgabeForm
form_data = {
'order': 1,
'nummer': 1,
'dokument': self.dokument.pk,
'thema': '', # Empty/missing Thema
'titel': 'Test Vorgabe',
'gueltigkeit_von': date.today(),
}
form = VorgabeForm(data=form_data)
form.is_valid()
# Check that the error message is in German
thema_errors = form.errors.get('thema', [])
error_messages = ' '.join(thema_errors)
self.assertTrue(
'Pflichtfeld' in error_messages or 'pflichtfeld' in error_messages.lower(),
f"Expected German error message about Pflichtfeld, got: {thema_errors}"
)
def test_vorgabe_model_clean_error_message_is_german(self):
"""Test that Vorgabe.clean() shows German error message for missing Thema"""
from django.core.exceptions import ValidationError
vorgabe = Vorgabe(
order=1,
nummer=1,
dokument=self.dokument,
thema=None,
titel="Test Vorgabe",
gueltigkeit_von=date.today()
)
with self.assertRaises(ValidationError) as context:
vorgabe.clean()
# Check error message is in German
error_str = str(context.exception)
self.assertIn('Thema ist ein Pflichtfeld', error_str)
class SanityCheckManagementCommandTest(TestCase): class SanityCheckManagementCommandTest(TestCase):
"""Test cases for sanity_check_vorgaben management command""" """Test cases for sanity_check_vorgaben management command"""

View File

@@ -219,7 +219,7 @@
</p> </p>
</div> </div>
<div class="col-sm-6 text-right"> <div class="col-sm-6 text-right">
<p class="text-muted">Version {{ version|default:"0.971" }}</p> <p class="text-muted">Version {{ version|default:"0.972" }}</p>
</div> </div>
</div> </div>
</div> </div>