from django.test import TestCase, TransactionTestCase from django.core.management import call_command from django.conf import settings from django.core.files.storage import default_storage from unittest.mock import patch, Mock, MagicMock from io import StringIO import os import hashlib import tempfile import shutil from .models import AbschnittTyp, Textabschnitt from .utils import render_textabschnitte, md_table_to_html from diagramm_proxy.diagram_cache import ( get_cached_diagram, compute_hash, get_cache_path, clear_cache ) class AbschnittTypModelTest(TestCase): """Test cases for AbschnittTyp model""" def setUp(self): """Set up test data""" self.abschnitttyp = AbschnittTyp.objects.create( abschnitttyp="text" ) def test_abschnitttyp_creation(self): """Test that AbschnittTyp is created correctly""" self.assertEqual(self.abschnitttyp.abschnitttyp, "text") def test_abschnitttyp_str(self): """Test string representation of AbschnittTyp""" self.assertEqual(str(self.abschnitttyp), "text") def test_abschnitttyp_verbose_name_plural(self): """Test verbose name plural""" self.assertEqual( AbschnittTyp._meta.verbose_name_plural, "Abschnitttypen" ) def test_abschnitttyp_primary_key(self): """Test that abschnitttyp field is the primary key""" pk_field = AbschnittTyp._meta.pk self.assertEqual(pk_field.name, 'abschnitttyp') def test_create_multiple_abschnitttypen(self): """Test creating multiple AbschnittTyp objects""" types = ['liste ungeordnet', 'liste geordnet', 'tabelle', 'diagramm', 'code'] for typ in types: AbschnittTyp.objects.create(abschnitttyp=typ) self.assertEqual(AbschnittTyp.objects.count(), 6) # Including setUp type class TextabschnittModelTest(TestCase): """Test cases for Textabschnitt abstract model using VorgabeLangtext""" def setUp(self): """Set up test data""" from dokumente.models import Dokumententyp, Dokument, Vorgabe, VorgabeLangtext, Thema from datetime import date self.typ_text = AbschnittTyp.objects.create(abschnitttyp="text") self.typ_code = AbschnittTyp.objects.create(abschnitttyp="code") # Create required dokumente objects self.dokumententyp = Dokumententyp.objects.create( name="Test Type", verantwortliche_ve="TEST" ) self.dokument = Dokument.objects.create( nummer="TEST-001", name="Test Doc", dokumententyp=self.dokumententyp, aktiv=True ) self.thema = Thema.objects.create(name="Test Thema") self.vorgabe = Vorgabe.objects.create( dokument=self.dokument, nummer=1, order=1, thema=self.thema, titel="Test Vorgabe", gueltigkeit_von=date.today() ) def test_textabschnitt_creation(self): """Test that Textabschnitt can be instantiated via concrete model""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="Test content", order=1 ) self.assertEqual(abschnitt.abschnitttyp, self.typ_text) self.assertEqual(abschnitt.inhalt, "Test content") self.assertEqual(abschnitt.order, 1) def test_textabschnitt_default_order(self): """Test that order defaults to 0""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="Test" ) self.assertEqual(abschnitt.order, 0) def test_textabschnitt_blank_fields(self): """Test that abschnitttyp and inhalt can be blank/null""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe ) self.assertIsNone(abschnitt.abschnitttyp) self.assertIsNone(abschnitt.inhalt) def test_textabschnitt_ordering(self): """Test that Textabschnitte can be ordered""" from dokumente.models import VorgabeLangtext abschnitt1 = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="First", order=2 ) abschnitt2 = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="Second", order=1 ) abschnitt3 = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="Third", order=3 ) ordered = VorgabeLangtext.objects.filter(abschnitt=self.vorgabe).order_by('order') self.assertEqual(list(ordered), [abschnitt2, abschnitt1, abschnitt3]) def test_textabschnitt_foreign_key_protection(self): """Test that AbschnittTyp is protected from deletion""" from dokumente.models import VorgabeLangtext from django.db.models import ProtectedError abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="Test" ) # Try to delete the AbschnittTyp with self.assertRaises(ProtectedError): self.typ_text.delete() class RenderTextabschnitteTest(TestCase): """Test cases for render_textabschnitte function""" def setUp(self): """Set up test data""" from dokumente.models import Dokumententyp, Dokument, Vorgabe, VorgabeLangtext, Thema from datetime import date self.typ_text = AbschnittTyp.objects.create(abschnitttyp="text") self.typ_unordered = AbschnittTyp.objects.create(abschnitttyp="liste ungeordnet") self.typ_ordered = AbschnittTyp.objects.create(abschnitttyp="liste geordnet") self.typ_table = AbschnittTyp.objects.create(abschnitttyp="tabelle") self.typ_code = AbschnittTyp.objects.create(abschnitttyp="code") self.typ_diagram = AbschnittTyp.objects.create(abschnitttyp="diagramm") # Create required dokumente objects self.dokumententyp = Dokumententyp.objects.create( name="Test Type", verantwortliche_ve="TEST" ) self.dokument = Dokument.objects.create( nummer="TEST-001", name="Test Doc", dokumententyp=self.dokumententyp, aktiv=True ) self.thema = Thema.objects.create(name="Test Thema") self.vorgabe = Vorgabe.objects.create( dokument=self.dokument, nummer=1, order=1, thema=self.thema, titel="Test Vorgabe", gueltigkeit_von=date.today() ) def test_render_empty_queryset(self): """Test rendering an empty queryset""" from dokumente.models import VorgabeLangtext result = render_textabschnitte(VorgabeLangtext.objects.none()) self.assertEqual(result, []) def test_render_text_markdown(self): """Test rendering plain text with markdown""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="# Heading\n\nThis is **bold** text.", order=1 ) result = render_textabschnitte(VorgabeLangtext.objects.filter(abschnitt=self.vorgabe)) self.assertEqual(len(result), 1) typ, html = result[0] self.assertEqual(typ, "text") self.assertIn("

Heading

", html) self.assertIn("bold", html) def test_render_text_with_footnotes(self): """Test rendering text with footnotes""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_text, inhalt="This is text[^1].\n\n[^1]: This is a footnote.", order=1 ) result = render_textabschnitte(VorgabeLangtext.objects.filter(abschnitt=self.vorgabe)) typ, html = result[0] self.assertIn("footnote", html.lower()) def test_render_unordered_list(self): """Test rendering unordered list""" from dokumente.models import VorgabeLangtext abschnitt = VorgabeLangtext.objects.create( abschnitt=self.vorgabe, abschnitttyp=self.typ_unordered, inhalt="Item 1\nItem 2\nItem 3", order=1 ) result = render_textabschnitte(VorgabeLangtext.objects.filter(abschnitt=self.vorgabe)) typ, html = result[0] self.assertEqual(typ, "liste ungeordnet") self.assertIn("