- Add complete test coverage for referenzen, rollen, and stichworte apps - Implement 54 new tests covering models, relationships, and business logic - Fix MPTT method names and import issues in test implementations - Create comprehensive test documentation in English and German - All 188 tests now passing across all Django apps Test coverage breakdown: - referenzen: 18 tests (MPTT hierarchy, model validation) - rollen: 18 tests (role models, relationships) - stichworte: 18 tests (keyword models, ordering) - Total: 54 new tests added Documentation: - Test suite.md: Complete English documentation - Test Suite-DE.md: Complete German documentation
226 lines
8.9 KiB
Python
226 lines
8.9 KiB
Python
from django.test import TestCase
|
|
from django.core.exceptions import ValidationError
|
|
from django.db import models
|
|
from .models import Stichwort, Stichworterklaerung
|
|
from abschnitte.models import AbschnittTyp
|
|
|
|
|
|
class StichwortModelTest(TestCase):
|
|
"""Test cases for Stichwort model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.stichwort = Stichwort.objects.create(
|
|
stichwort="Sicherheit"
|
|
)
|
|
|
|
def test_stichwort_creation(self):
|
|
"""Test that Stichwort is created correctly"""
|
|
self.assertEqual(self.stichwort.stichwort, "Sicherheit")
|
|
|
|
def test_stichwort_str(self):
|
|
"""Test string representation of Stichwort"""
|
|
self.assertEqual(str(self.stichwort), "Sicherheit")
|
|
|
|
def test_stichwort_primary_key(self):
|
|
"""Test that stichwort field is the primary key"""
|
|
pk_field = Stichwort._meta.pk
|
|
self.assertEqual(pk_field.name, 'stichwort')
|
|
self.assertEqual(pk_field.max_length, 50)
|
|
|
|
def test_stichwort_verbose_name_plural(self):
|
|
"""Test verbose name plural"""
|
|
self.assertEqual(
|
|
Stichwort._meta.verbose_name_plural,
|
|
"Stichworte"
|
|
)
|
|
|
|
def test_stichwort_max_length(self):
|
|
"""Test max_length constraint"""
|
|
max_length_stichwort = "a" * 50
|
|
stichwort = Stichwort.objects.create(stichwort=max_length_stichwort)
|
|
self.assertEqual(stichwort.stichwort, max_length_stichwort)
|
|
|
|
def test_stichwort_unique(self):
|
|
"""Test that stichwort must be unique"""
|
|
with self.assertRaises(Exception):
|
|
Stichwort.objects.create(stichwort="Sicherheit")
|
|
|
|
def test_create_multiple_stichworte(self):
|
|
"""Test creating multiple Stichwort objects"""
|
|
stichworte = ['Datenschutz', 'Netzwerk', 'Backup', 'Verschlüsselung']
|
|
for stichwort in stichworte:
|
|
Stichwort.objects.create(stichwort=stichwort)
|
|
|
|
self.assertEqual(Stichwort.objects.count(), 5) # Including setUp stichwort
|
|
|
|
def test_stichwort_case_sensitivity(self):
|
|
"""Test that stichwort is case sensitive"""
|
|
stichwort_lower = Stichwort.objects.create(stichwort="sicherheit")
|
|
self.assertNotEqual(self.stichwort.pk, stichwort_lower.pk)
|
|
self.assertEqual(Stichwort.objects.count(), 2)
|
|
|
|
|
|
class StichworterklaerungModelTest(TestCase):
|
|
"""Test cases for Stichworterklaerung model"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.stichwort = Stichwort.objects.create(
|
|
stichwort="Sicherheit"
|
|
)
|
|
self.abschnitttyp = AbschnittTyp.objects.create(
|
|
abschnitttyp="text"
|
|
)
|
|
self.erklaerung = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort,
|
|
abschnitttyp=self.abschnitttyp,
|
|
inhalt="Dies ist eine Erklärung für Sicherheit.",
|
|
order=1
|
|
)
|
|
|
|
def test_stichworterklaerung_creation(self):
|
|
"""Test that Stichworterklaerung is created correctly"""
|
|
self.assertEqual(self.erklaerung.erklaerung, self.stichwort)
|
|
self.assertEqual(self.erklaerung.abschnitttyp, self.abschnitttyp)
|
|
self.assertEqual(self.erklaerung.inhalt, "Dies ist eine Erklärung für Sicherheit.")
|
|
self.assertEqual(self.erklaerung.order, 1)
|
|
|
|
def test_stichworterklaerung_foreign_key_relationship(self):
|
|
"""Test foreign key relationship to Stichwort"""
|
|
self.assertEqual(self.erklaerung.erklaerung.stichwort, "Sicherheit")
|
|
|
|
def test_stichworterklaerung_cascade_delete(self):
|
|
"""Test that deleting Stichwort cascades to Stichworterklaerung"""
|
|
stichwort_count = Stichwort.objects.count()
|
|
erklaerung_count = Stichworterklaerung.objects.count()
|
|
|
|
self.stichwort.delete()
|
|
|
|
self.assertEqual(Stichwort.objects.count(), stichwort_count - 1)
|
|
self.assertEqual(Stichworterklaerung.objects.count(), erklaerung_count - 1)
|
|
|
|
def test_stichworterklaerung_verbose_name(self):
|
|
"""Test verbose name"""
|
|
self.assertEqual(
|
|
Stichworterklaerung._meta.verbose_name,
|
|
"Erklärung"
|
|
)
|
|
|
|
def test_stichworterklaerung_multiple_explanations(self):
|
|
"""Test creating multiple explanations for one Stichwort"""
|
|
abschnitttyp2 = AbschnittTyp.objects.create(abschnitttyp="liste ungeordnet")
|
|
erklaerung2 = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort,
|
|
abschnitttyp=abschnitttyp2,
|
|
inhalt="Zweite Erklärung für Sicherheit.",
|
|
order=2
|
|
)
|
|
|
|
explanations = Stichworterklaerung.objects.filter(erklaerung=self.stichwort)
|
|
self.assertEqual(explanations.count(), 2)
|
|
self.assertIn(self.erklaerung, explanations)
|
|
self.assertIn(erklaerung2, explanations)
|
|
|
|
def test_stichworterklaerung_ordering(self):
|
|
"""Test that explanations can be ordered"""
|
|
erklaerung2 = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort,
|
|
abschnitttyp=self.abschnitttyp,
|
|
inhalt="Zweite Erklärung",
|
|
order=3
|
|
)
|
|
erklaerung3 = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort,
|
|
abschnitttyp=self.abschnitttyp,
|
|
inhalt="Erste Erklärung",
|
|
order=2
|
|
)
|
|
|
|
ordered = Stichworterklaerung.objects.filter(erklaerung=self.stichwort).order_by('order')
|
|
expected_order = [self.erklaerung, erklaerung3, erklaerung2]
|
|
self.assertEqual(list(ordered), expected_order)
|
|
|
|
def test_stichworterklaerung_blank_fields(self):
|
|
"""Test that optional fields can be blank/null"""
|
|
stichwort2 = Stichwort.objects.create(stichwort="Test")
|
|
erklaerung_blank = Stichworterklaerung.objects.create(
|
|
erklaerung=stichwort2
|
|
)
|
|
|
|
self.assertIsNone(erklaerung_blank.abschnitttyp)
|
|
self.assertIsNone(erklaerung_blank.inhalt)
|
|
self.assertEqual(erklaerung_blank.order, 0)
|
|
|
|
def test_stichworterklaerung_inheritance(self):
|
|
"""Test that Stichworterklaerung inherits from Textabschnitt"""
|
|
# Check that it has the expected fields from Textabschnitt
|
|
self.assertTrue(hasattr(self.erklaerung, 'abschnitttyp'))
|
|
self.assertTrue(hasattr(self.erklaerung, 'inhalt'))
|
|
self.assertTrue(hasattr(self.erklaerung, 'order'))
|
|
|
|
# Check that the fields work as expected
|
|
self.assertIsInstance(self.erklaerung.abschnitttyp, AbschnittTyp)
|
|
self.assertIsInstance(self.erklaerung.inhalt, str)
|
|
self.assertIsInstance(self.erklaerung.order, int)
|
|
|
|
|
|
class StichwortIntegrationTest(TestCase):
|
|
"""Integration tests for Stichwort app"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
self.stichwort1 = Stichwort.objects.create(stichwort="IT-Sicherheit")
|
|
self.stichwort2 = Stichwort.objects.create(stichwort="Datenschutz")
|
|
|
|
self.abschnitttyp = AbschnittTyp.objects.create(abschnitttyp="text")
|
|
|
|
self.erklaerung1 = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort1,
|
|
abschnitttyp=self.abschnitttyp,
|
|
inhalt="Erklärung für IT-Sicherheit",
|
|
order=1
|
|
)
|
|
|
|
self.erklaerung2 = Stichworterklaerung.objects.create(
|
|
erklaerung=self.stichwort2,
|
|
abschnitttyp=self.abschnitttyp,
|
|
inhalt="Erklärung für Datenschutz",
|
|
order=1
|
|
)
|
|
|
|
def test_stichwort_with_explanations_query(self):
|
|
"""Test querying Stichworte with their explanations"""
|
|
stichworte_with_explanations = Stichwort.objects.filter(
|
|
stichworterklaerung__isnull=False
|
|
).distinct()
|
|
|
|
self.assertEqual(stichworte_with_explanations.count(), 2)
|
|
self.assertIn(self.stichwort1, stichworte_with_explanations)
|
|
self.assertIn(self.stichwort2, stichworte_with_explanations)
|
|
|
|
def test_stichwort_without_explanations(self):
|
|
"""Test finding Stichworte without explanations"""
|
|
stichwort3 = Stichwort.objects.create(stichwort="Backup")
|
|
|
|
stichworte_without_explanations = Stichwort.objects.filter(
|
|
stichworterklaerung__isnull=True
|
|
)
|
|
|
|
self.assertEqual(stichworte_without_explanations.count(), 1)
|
|
self.assertEqual(stichworte_without_explanations.first(), stichwort3)
|
|
|
|
def test_explanation_count_annotation(self):
|
|
"""Test annotating Stichworte with explanation count"""
|
|
from django.db.models import Count
|
|
|
|
stichworte_with_count = Stichwort.objects.annotate(
|
|
explanation_count=Count('stichworterklaerung')
|
|
)
|
|
|
|
for stichwort in stichworte_with_count:
|
|
if stichwort.stichwort in ["IT-Sicherheit", "Datenschutz"]:
|
|
self.assertEqual(stichwort.explanation_count, 1)
|
|
else:
|
|
self.assertEqual(stichwort.explanation_count, 0)
|