Files
cthulhu/tests/test_mako_notification_monitor.py

161 lines
5.0 KiB
Python

import sys
import unittest
from pathlib import Path
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cthulhu import notification_presenter
from cthulhu.mako_notification_monitor import MakoNotificationMonitor
class _FakeScript:
def __init__(self):
self.speechGenerator = mock.Mock()
self.speechGenerator.voice.return_value = object()
self.speakMessage = mock.Mock()
self.displayBrailleMessage = mock.Mock()
class _FakeScriptManager:
def __init__(self, script):
self._script = script
def get_default_script(self):
return self._script
class _FakeApp:
def __init__(self, script):
self._script_manager = _FakeScriptManager(script)
def getScriptManager(self):
return self._script_manager
class MakoNotificationMonitorTests(unittest.TestCase):
def setUp(self):
self.presenter = notification_presenter.NotificationPresenter()
self.script = _FakeScript()
self.app = _FakeApp(self.script)
presenter_patcher = mock.patch(
"cthulhu.mako_notification_monitor.notification_presenter.getPresenter",
return_value=self.presenter,
)
self.addCleanup(presenter_patcher.stop)
presenter_patcher.start()
self.monitor = MakoNotificationMonitor(self.app)
self.monitor._generation = 1
def test_initial_seed_does_not_announce_existing_notifications(self):
self.monitor._sync_notifications(
[
{
"id": 10,
"app-name": "discord",
"summary": "hello",
"body": "world",
"actions": {"default": "View"},
}
],
announce_new=False,
)
self.assertEqual(self.monitor._known_ids, {10})
self.assertEqual(self.presenter._notifications, [])
self.script.speakMessage.assert_not_called()
self.script.displayBrailleMessage.assert_not_called()
def test_new_notification_is_spoken_and_saved(self):
self.monitor._sync_notifications(
[
{
"id": 10,
"app-name": "discord",
"summary": "old",
"body": "",
"actions": {},
}
],
announce_new=False,
)
self.monitor._sync_notifications(
[
{
"id": 10,
"app-name": "discord",
"summary": "old",
"body": "",
"actions": {},
},
{
"id": 11,
"app-name": "discord",
"summary": "new summary",
"body": "new body",
"actions": {"default": "View"},
},
],
announce_new=True,
)
self.assertEqual(len(self.presenter._notifications), 1)
entry = self.presenter._notifications[0]
self.assertEqual(entry.notification_id, 11)
self.assertTrue(entry.live)
self.assertEqual(entry.source, "mako")
self.assertEqual(entry.actions, {"default": "View"})
self.assertEqual(entry.message, "Notification new summary new body")
self.script.speakMessage.assert_called_once()
self.script.displayBrailleMessage.assert_called_once()
def test_removed_notification_is_marked_not_live(self):
self.monitor._sync_notifications(
[
{
"id": 11,
"app-name": "discord",
"summary": "new summary",
"body": "new body",
"actions": {"default": "View"},
},
],
announce_new=True,
)
self.assertTrue(self.presenter._notifications[0].live)
self.monitor._sync_notifications([], announce_new=False)
self.assertFalse(self.presenter._notifications[0].live)
self.assertEqual(self.monitor._known_ids, set())
def test_parse_notification_strips_markup_and_normalizes_actions(self):
parsed = self.monitor._parse_notification(
{
"id": 22,
"app-name": "Crash Reporting System",
"summary": "<b>Service Crash</b>",
"body": "<html><tt>/usr/bin/python3.14</tt> crashed</html>",
"desktop-entry": "crash-handler",
"urgency": 2,
"actions": {"1": "<b>Details</b>"},
}
)
self.assertEqual(parsed["notification_id"], 22)
self.assertEqual(parsed["summary"], "Service Crash")
self.assertEqual(parsed["body"], "/usr/bin/python3.14 crashed")
self.assertEqual(parsed["actions"], {"1": "Details"})
self.assertEqual(
parsed["message"],
"Notification Service Crash /usr/bin/python3.14 crashed",
)
if __name__ == "__main__":
unittest.main()