Files
aza/AzA march 2026/_test_doku_prompt_system.py
2026-06-10 22:55:03 +02:00

234 lines
9.7 KiB
Python

# -*- coding: utf-8 -*-
"""Automatisierte Tests für Doku-Prompt-System."""
from __future__ import annotations
import json
import os
import tempfile
import unittest
from unittest.mock import patch
class TestDokuPromptSystem(unittest.TestCase):
def setUp(self):
self._tmpdir = tempfile.mkdtemp()
self._orig_path_fn = None
def tearDown(self):
import shutil
shutil.rmtree(self._tmpdir, ignore_errors=True)
def _patch_templates_path(self):
import aza_doku_vorlagen as dv
path = os.path.join(self._tmpdir, "aza_document_templates.json")
dv._templates_json_path = lambda: path # type: ignore
return path, dv
def test_doc_types_order(self):
from aza_doku_vorlagen import DOC_TYPES
labels = [l for _, l in DOC_TYPES]
self.assertEqual(labels[0], "Krankengeschichte")
self.assertEqual(labels[1], "Verlauf")
self.assertEqual(labels[-1], "Eigenes Dokument")
self.assertEqual(len(DOC_TYPES), 8)
def test_verlauf_default_present(self):
from aza_doku_vorlagen import AZA_DEFAULT_TEMPLATES, VERLAUF_DEFAULT_PROMPT
self.assertIn("verlauf", AZA_DEFAULT_TEMPLATES)
self.assertIn("Verlaufsbericht", VERLAUF_DEFAULT_PROMPT)
def test_migration_v1_to_v2(self):
path, dv = self._patch_templates_path()
old = {
"schema_version": 1,
"active": {"kg": "aza_default", "brief": "aza_default"},
"templates": {
"kg": [{"id": "aza_default", "name": "AzA-Grundvorlage", "is_system": True,
"content": "KG alt", "created_at": "t", "updated_at": "t"}],
"brief": [{"id": "aza_default", "name": "AzA-Grundvorlage", "is_system": True,
"content": "Brief alt", "created_at": "t", "updated_at": "t"}],
},
}
with open(path, "w", encoding="utf-8") as f:
json.dump(old, f)
data = dv._load()
self.assertEqual(data["schema_version"], 2)
self.assertEqual(data["templates"]["kg"][0]["content"], "KG alt")
self.assertIn("verlauf", data["templates"])
self.assertIn("eigenes_dokument", data["templates"])
def test_sanitize_strips_script(self):
from aza_doku_vorlagen import sanitize_prompt_text
s = sanitize_prompt_text("<script>alert(1)</script>Verlauf")
self.assertNotIn("script", s.lower())
self.assertIn("Verlauf", s)
def test_dynamic_button_labels(self):
from aza_doku_vorlagen import DOC_TYPE_CREATE_LABELS, DOC_TYPE_COPY_LABELS
self.assertEqual(DOC_TYPE_CREATE_LABELS["verlauf"], "Verlauf erstellen")
self.assertEqual(DOC_TYPE_COPY_LABELS["brief"], "Brief kopieren")
def test_get_active_no_override_for_default(self):
path, dv = self._patch_templates_path()
dv._save(dv._default_structure())
from aza_text_windows_mixin import _get_doku_vorlage_for
self.assertEqual(_get_doku_vorlage_for("kg"), "")
self.assertEqual(_get_doku_vorlage_for("verlauf"), "")
def test_get_active_user_template(self):
path, dv = self._patch_templates_path()
data = dv._default_structure()
data["templates"]["verlauf"].append({
"id": "user_test", "name": "Mein Verlauf", "is_system": False,
"content": "Custom Verlauf", "created_at": "t", "updated_at": "t",
"revision": 1,
})
data["active"]["verlauf"] = "user_test"
dv._save(data)
from aza_text_windows_mixin import _get_doku_vorlage_for
self.assertEqual(_get_doku_vorlage_for("verlauf"), "Custom Verlauf")
def test_copy_public_template(self):
path, dv = self._patch_templates_path()
dv._save(dv._default_structure())
new_id = dv.copy_public_template_as_own(
"brief", content="Pub", title="Pub Brief", source_author="Dr. X", source_server_id="s1",
)
self.assertTrue(new_id)
data = dv._load()
tpl = next(t for t in data["templates"]["brief"] if t["id"] == new_id)
self.assertEqual(tpl["content"], "Pub")
self.assertEqual(tpl["source_author"], "Dr. X")
def test_atomic_save(self):
path, dv = self._patch_templates_path()
dv._save(dv._default_structure())
self.assertTrue(os.path.isfile(path))
self.assertFalse(os.path.isfile(path + ".tmp"))
def test_merge_sync_newest_revision(self):
from aza_doku_prompt_sync import merge_server_doku_items_local
data = {
"schema_version": 2,
"active": {"kg": "aza_default"},
"templates": {"kg": []},
"sync_meta": {"conflicts": []},
}
server_items = [{
"id": "user_1_kg", "item_type": "doku_prompt", "trigger": "kg",
"content": json.dumps({
"doc_type": "kg", "name": "Sync KG", "content": "Synced",
"revision": 2, "updated_at": "2026-01-02T00:00:00+00:00",
}),
}]
data, changed = merge_server_doku_items_local(data, server_items)
self.assertTrue(changed)
self.assertEqual(data["templates"]["kg"][0]["content"], "Synced")
def test_sync_serialization_private_only(self):
from aza_doku_prompt_sync import local_private_templates_to_sync_items
path, dv = self._patch_templates_path()
data = dv._default_structure()
data["templates"]["verlauf"].append({
"id": "user_v1", "name": "Privat", "is_system": False,
"content": "Verlauf privat", "created_at": "t", "updated_at": "t", "revision": 3,
})
dv._save(data)
items = local_private_templates_to_sync_items(dv._load())
self.assertEqual(len(items), 1)
self.assertEqual(items[0]["item_type"], "doku_prompt")
self.assertEqual(items[0]["trigger"], "verlauf")
payload = json.loads(items[0]["content"])
self.assertEqual(payload["content"], "Verlauf privat")
self.assertEqual(payload["revision"], 3)
def test_merge_conflict_keeps_local_when_newer(self):
from aza_doku_prompt_sync import merge_server_doku_items_local
data = {
"schema_version": 2,
"active": {"kg": "user_1_kg"},
"templates": {"kg": [{
"id": "user_1_kg", "name": "Lokal", "is_system": False,
"content": "Lokal neu", "revision": 5,
"updated_at": "2026-06-10T12:00:00+00:00",
"created_at": "t",
}]},
"sync_meta": {"conflicts": []},
}
server_items = [{
"id": "user_1_kg", "item_type": "doku_prompt", "trigger": "kg",
"content": json.dumps({
"doc_type": "kg", "name": "Server alt", "content": "Server alt",
"revision": 2, "updated_at": "2026-01-01T00:00:00+00:00",
}),
}]
merged, changed = merge_server_doku_items_local(data, server_items)
self.assertEqual(merged["templates"]["kg"][0]["content"], "Lokal neu")
self.assertTrue(len(merged["sync_meta"]["conflicts"]) >= 1)
def test_publish_payload_fields(self):
from aza_doku_prompt_sync import PublishDokuPromptIn
p = PublishDokuPromptIn(
doc_type="verlauf", title="Test", content="Prompt ohne Patientendaten",
description="Demo", author_display="Dr. Test",
)
self.assertEqual(p.doc_type, "verlauf")
d = p.model_dump()
self.assertNotIn("patient_name", d)
self.assertNotIn("transcript", d)
def test_load_all_templates_alias(self):
path, dv = self._patch_templates_path()
dv._save(dv._default_structure())
self.assertEqual(dv._load_all_templates()["schema_version"], 2)
def test_active_per_doc_type(self):
path, dv = self._patch_templates_path()
data = dv._default_structure()
for dt, _ in dv.DOC_TYPES:
self.assertIn(dt, data["active"])
self.assertIn(dt, data["templates"])
def test_no_patient_fields_in_template_schema(self):
path, dv = self._patch_templates_path()
data = dv._default_structure()
blob = json.dumps(data).lower()
for forbidden in ("patient_name", "transcript", "geburtsdatum", "sozialversicherung"):
self.assertNotIn(forbidden, blob)
def test_office_shell_kg_section_markers(self):
path = os.path.join(os.path.dirname(__file__), "aza_office_shell_v1.py")
with open(path, encoding="utf-8") as f:
src = f.read()
self.assertIn('"Doku-Prompt"', src)
self.assertIn("DocTypePicker", src)
self.assertIn("app._doc_type_picker", src)
self.assertNotIn("app._doc_type_combo", src)
self.assertNotIn('("Doku-Prompt", "_open_doku_vorlage_fenster")', src)
self.assertNotIn('actions, "Kommentare"', src)
self.assertIn('"autotext"', src)
self.assertIn('"folder"', src)
self.assertIn('"library"', src)
def test_main_doc_type_persistence(self):
import tempfile
import aza_persistence as ap
with tempfile.TemporaryDirectory() as td:
cfg = os.path.join(td, "autotext.json")
with patch.object(ap, "_autotext_config_path", return_value=cfg):
self.assertEqual(ap.load_main_doc_type(), "kg")
ap.save_main_doc_type("verlauf")
self.assertEqual(ap.load_main_doc_type(), "verlauf")
ap.save_main_doc_type("invalid_type")
self.assertEqual(ap.load_main_doc_type(), "kg")
ap.save_main_doc_type("brief")
data = ap.load_autotext()
self.assertEqual(data.get("main_doc_type"), "brief")
if __name__ == "__main__":
unittest.main()