234 lines
9.7 KiB
Python
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()
|