From 753c00bc4594f0232e736b5d9aca6feebeada42f Mon Sep 17 00:00:00 2001
From: "Adrian A. Baumann"
Date: Mon, 8 Dec 2025 14:41:02 +0100
Subject: [PATCH] Validation for 'Thema' on Vorgabe added
---
argocd/deployment.yaml | 2 +-
dokumente/admin.py | 8 +++
dokumente/models.py | 6 ++
dokumente/tests.py | 128 ++++++++++++++++++++++++++++++++++++++
pages/templates/base.html | 2 +-
5 files changed, 144 insertions(+), 2 deletions(-)
diff --git a/argocd/deployment.yaml b/argocd/deployment.yaml
index 2fbc5a9..356e373 100644
--- a/argocd/deployment.yaml
+++ b/argocd/deployment.yaml
@@ -25,7 +25,7 @@ spec:
mountPath: /data
containers:
- name: web
- image: git.baumann.gr/adebaumann/vui:0.971
+ image: git.baumann.gr/adebaumann/vui:0.972
imagePullPolicy: Always
ports:
- containerPort: 8000
diff --git a/dokumente/admin.py b/dokumente/admin.py
index 4a0e923..7613da5 100644
--- a/dokumente/admin.py
+++ b/dokumente/admin.py
@@ -94,9 +94,17 @@ class EinleitungInline(NestedStackedInline):
class VorgabeForm(forms.ModelForm):
referenzen = TreeNodeMultipleChoiceField(queryset=Referenz.objects.all(), required=False)
+
class Meta:
model = Vorgabe
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):
model = Vorgabe
diff --git a/dokumente/models.py b/dokumente/models.py
index 38d66e2..1019a8b 100644
--- a/dokumente/models.py
+++ b/dokumente/models.py
@@ -169,6 +169,12 @@ class Vorgabe(models.Model):
"""
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
conflicts = self.find_conflicts()
if conflicts:
diff --git a/dokumente/tests.py b/dokumente/tests.py
index a8fa968..3883439 100644
--- a/dokumente/tests.py
+++ b/dokumente/tests.py
@@ -761,6 +761,134 @@ class VorgabeSanityCheckTest(TestCase):
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):
"""Test cases for sanity_check_vorgaben management command"""
diff --git a/pages/templates/base.html b/pages/templates/base.html
index d75aa3d..f910596 100644
--- a/pages/templates/base.html
+++ b/pages/templates/base.html
@@ -219,7 +219,7 @@
-
Version {{ version|default:"0.971" }}
+
Version {{ version|default:"0.972" }}