# -*- coding: utf-8 -*- """Gezielte Tests: weiße Empfang-Hülle (Navigation/Handoff) + Logo8-Icon.""" from __future__ import annotations import json import time import unittest from pathlib import Path from unittest.mock import patch import aza_empfang_webview as ew from aza_empfang_shell_surface import ( append_empfang_shell_debug_log, consume_shell_peer_refresh_signal, empfang_shell_debug_log_path, shell_peer_refresh_signal_path, touch_shell_peer_refresh_signal, ) class ShellStableReloadUrlTests(unittest.TestCase): def test_desktop_shell_reload_url_has_markers_no_token(self): url = ew._shell_stable_reload_url( "https://empfang.example/empfang/shell/launch?token=SECRET", ew._MODE_DESKTOP_SHELL, ) self.assertIn("desktop_shell=1", url) self.assertIn("shell_source=aza_desktop", url) self.assertNotIn("token=", url) self.assertNotIn("SECRET", url) def test_redact_url_strips_query(self): red = ew._shell_redact_url_for_log( "https://empfang.example/empfang/shell/launch?token=abc&x=1" ) self.assertEqual(red, "https://empfang.example/empfang/shell/launch") self.assertNotIn("token", red) class ShellPeerRefreshSignalTests(unittest.TestCase): def test_touch_and_consume_advances_ts(self): path = shell_peer_refresh_signal_path() try: if path.is_file(): path.unlink() except OSError: pass touch_shell_peer_refresh_signal(source="test") ts1 = consume_shell_peer_refresh_signal(0.0) self.assertGreater(ts1, 0.0) ts2 = consume_shell_peer_refresh_signal(ts1) self.assertEqual(ts2, 0.0) touch_shell_peer_refresh_signal(source="test2") ts3 = consume_shell_peer_refresh_signal(ts1) self.assertGreater(ts3, ts1) class ShellHealthReloadLimitTests(unittest.TestCase): def test_reload_respects_limit(self): api = ew.EmpfangWebviewApi(mode=ew._MODE_DESKTOP_SHELL) api._shell_reload_target_url = "https://empfang.example/empfang/?desktop_shell=1" api._window = type("W", (), {"load_url": lambda self, u: None})() with patch.object(ew.threading, "Thread") as mock_thread: mock_thread.return_value.start = lambda: None with patch.object(api, "_shell_debug"): r1 = api.shell_reload_current() r2 = api.shell_reload_current() r3 = api.shell_reload_current() self.assertTrue(r1.get("ok")) self.assertTrue(r2.get("ok")) self.assertFalse(r3.get("ok")) self.assertEqual(r3.get("reason"), "limit") class ShellDebugLogTests(unittest.TestCase): def test_debug_log_no_secrets(self): path = empfang_shell_debug_log_path() append_empfang_shell_debug_log("action=test_probe dom=blank bridge=no") self.assertTrue(path.is_file()) text = path.read_text(encoding="utf-8") self.assertIn("action=test_probe", text) self.assertNotIn("token=", text.lower()) class Logo8AssetTests(unittest.TestCase): def test_chat_logo8_ico_exists_with_sizes(self): root = Path(__file__).resolve().parent ico = root / "assets" / "aza_chat_logo8.ico" self.assertTrue(ico.is_file(), "assets/aza_chat_logo8.ico fehlt") from PIL import Image img = Image.open(ico) sizes = img.info.get("sizes") or set() for need in ((16, 16), (32, 32), (256, 256)): self.assertIn(need, sizes, f"ICO ohne Größe {need}") def test_empfang_shell_spec_uses_logo8(self): spec = (Path(__file__).resolve().parent / "AZA_EmpfangShell.spec").read_text( encoding="utf-8" ) self.assertIn("aza_chat_logo8.ico", spec) self.assertNotIn("aza_main.ico", spec) def test_office_spec_unchanged_icon(self): spec = (Path(__file__).resolve().parent / "aza_desktop.spec").read_text( encoding="utf-8" ) self.assertNotIn("aza_chat_logo8.ico", spec) class ShellApiPeerRefreshTests(unittest.TestCase): def test_consume_peer_refresh_signal_api(self): api = ew.EmpfangWebviewApi(mode=ew._MODE_DESKTOP_SHELL) touch_shell_peer_refresh_signal(source="unittest") time.sleep(0.01) r = api.consume_peer_refresh_signal() self.assertTrue(r.get("pending")) r2 = api.consume_peer_refresh_signal() self.assertFalse(r2.get("pending")) if __name__ == "__main__": unittest.main(verbosity=2)