161 lines
5.0 KiB
Python
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()
|