"""Tests for outlook_handlers — COM bridge mocked via unittest.mock. We patch the module-level `_outlook_session` to return a fake (app, ns) pair made of MagicMocks so we never need a live Outlook install. """ import importlib import sys from unittest.mock import MagicMock, patch def _fresh_module(): if 'outlook_handlers' in sys.modules: del sys.modules['outlook_handlers'] return importlib.import_module('outlook_handlers') def _make_inbox_with_unread(count): """Build a fake Inbox object whose UnReadItemCount is `count`.""" inbox = MagicMock() inbox.UnReadItemCount = count return inbox def test_unread_count_speaks_singular_for_one(): mod = _fresh_module() spoken = [] mod.set_speak(lambda t: spoken.append(t)) app = MagicMock() ns = MagicMock() ns.GetDefaultFolder.return_value = _make_inbox_with_unread(1) with patch.object(mod, '_outlook_session', return_value=(app, ns)): mod.do_outlook_unread_count({}, '') assert spoken, "expected the handler to speak" assert "Одно" in spoken[0] def test_unread_count_zero_says_no_unread(): mod = _fresh_module() spoken = [] mod.set_speak(lambda t: spoken.append(t)) app = MagicMock() ns = MagicMock() ns.GetDefaultFolder.return_value = _make_inbox_with_unread(0) with patch.object(mod, '_outlook_session', return_value=(app, ns)): mod.do_outlook_unread_count({}, '') assert spoken assert "нет" in spoken[0].lower() def test_unread_count_plural_count(): mod = _fresh_module() spoken = [] mod.set_speak(lambda t: spoken.append(t)) ns = MagicMock() ns.GetDefaultFolder.return_value = _make_inbox_with_unread(7) with patch.object(mod, '_outlook_session', return_value=(MagicMock(), ns)): mod.do_outlook_unread_count({}, '') assert "7" in spoken[0] def test_unavailable_outlook_says_so(): mod = _fresh_module() spoken = [] mod.set_speak(lambda t: spoken.append(t)) with patch.object(mod, '_outlook_session', return_value=(None, None)): mod.do_outlook_unread_count({}, '') assert spoken assert "Outlook" in spoken[0] def test_extract_recipient_strips_trigger(): mod = _fresh_module() assert mod._extract_recipient("отправь письмо Дмитрию") == "Дмитрию" assert mod._extract_recipient("email this to Bob") == "Bob" assert mod._extract_recipient("Bob") == "Bob" assert mod._extract_recipient("") == "" def test_send_clipboard_no_recipient_prompts_for_name(): mod = _fresh_module() spoken = [] mod.set_speak(lambda t: spoken.append(t)) # No trigger and no recipient in the voice -> _extract_recipient returns "" mod.do_outlook_send_clipboard({}, "") assert spoken assert "имя" in spoken[0].lower() or "name" in spoken[0].lower() def test_strip_html_basic(): mod = _fresh_module() assert mod._strip_html("Hi there") == "Hi there" assert mod._strip_html("") == ""