# -*- coding: utf-8 -*- """Tests: Aufgaben-Editor Diktat/Antwort/Zuweisung (Backend + empfang.html-Invarianten).""" from __future__ import annotations import re import unittest from pathlib import Path from unittest.mock import patch ROOT = Path(__file__).resolve().parent class TaskAssigneeBackendTests(unittest.TestCase): def test_assignee_user_id_resolves_display_name(self): from empfang_routes import _apply_task_assignee_from_body target = {"assignee": "", "assignee_user_id": ""} users = [ { "user_id": "u_test_1", "display_name": "André M. Surovy", "role": "arzt", "login_name": "ams", "email": "", "has_password_hash": True, "specialty": "", "title": "", } ] with patch("empfang_routes._practice_users", return_value=users): _apply_task_assignee_from_body( target, {"assignee_user_id": "u_test_1"}, "prac_test" ) self.assertEqual(target["assignee_user_id"], "u_test_1") self.assertEqual(target["assignee"], "André M. Surovy") def test_unknown_assignee_user_id_raises(self): from empfang_routes import _apply_task_assignee_from_body from fastapi import HTTPException target = {"assignee": "Alt", "assignee_user_id": "u_old"} with patch("empfang_routes._practice_users", return_value=[]): with self.assertRaises(HTTPException) as ctx: _apply_task_assignee_from_body( target, {"assignee_user_id": "u_unknown"}, "prac_test" ) self.assertEqual(ctx.exception.status_code, 400) def test_legacy_assignee_name_resolves_user_id_on_create(self): from empfang_routes import _apply_task_assignee_from_body target = {"assignee": "", "assignee_user_id": ""} users = [ { "user_id": "u_z", "display_name": "Zeno", "role": "", "login_name": "zeno", "email": "", "has_password_hash": True, "specialty": "", "title": "", } ] with patch("empfang_routes._practice_users", return_value=users): _apply_task_assignee_from_body( target, {"assignee": "Zeno"}, "prac_test", allow_legacy_name=True, ) self.assertEqual(target["assignee_user_id"], "u_z") self.assertEqual(target["assignee"], "Zeno") class EmpfangHtmlInvariantTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.html = (ROOT / "web" / "empfang.html").read_text(encoding="utf-8") def test_no_assign_prompt(self): self.assertNotIn("prompt('Zuweisen an", self.html) self.assertNotIn('prompt("Zuweisen an', self.html) def test_task_editor_buttons_present(self): self.assertIn('id="task-editor-dictate-btn"', self.html) self.assertIn('onclick="taskEditorAppendReply()"', self.html) self.assertIn('onclick="taskEditorReassign()"', self.html) self.assertIn('id="task-editor-reply"', self.html) def test_assignee_picker_modal(self): self.assertIn('id="task-assignee-picker-overlay"', self.html) self.assertIn("openTaskAssigneePicker", self.html) self.assertIn("assignee_user_id", self.html) def test_reply_format_helper(self): self.assertIn("formatTaskReplyBlock", self.html) self.assertIn("': '", self.html) self.assertIn("_taskReplyInFlight", self.html) self.assertIn("formatTaskReplyTimestamp", self.html) def test_dictation_finalize_before_close(self): self.assertIn("stopAndFinalizeTaskEditorDictation", self.html) self.assertIn("fetchTranscribeDictationBlob", self.html) class EmpfangHtmlJsSyntaxTests(unittest.TestCase): def test_inline_script_brace_balance(self): html = (ROOT / "web" / "empfang.html").read_text(encoding="utf-8") scripts = re.findall(r"]*)>([\s\S]*?)", html, flags=re.I) self.assertTrue(scripts, "Kein inline script gefunden") combined = "\n".join(scripts) self.assertEqual(combined.count("{"), combined.count("}")) self.assertNotIn("function function", combined) if __name__ == "__main__": unittest.main()