""" Tests for engine.ntfy module. """ import time from unittest.mock import MagicMock, patch from engine.events import NtfyMessageEvent from engine.ntfy import NtfyPoller class TestNtfyPollerInit: """Tests for NtfyPoller initialization.""" def test_init_sets_defaults(self): """Default values are set correctly.""" poller = NtfyPoller("http://example.com/topic") assert poller.topic_url == "http://example.com/topic" assert poller.reconnect_delay == 5 assert poller.display_secs == 30 def test_init_custom_values(self): """Custom values are set correctly.""" poller = NtfyPoller( "http://example.com/topic", reconnect_delay=10, display_secs=60 ) assert poller.reconnect_delay == 10 assert poller.display_secs == 60 class TestNtfyPollerStart: """Tests for NtfyPoller.start method.""" @patch("engine.ntfy.threading.Thread") def test_start_creates_daemon_thread(self, mock_thread): """start() creates and starts a daemon thread.""" mock_thread_instance = MagicMock() mock_thread.return_value = mock_thread_instance poller = NtfyPoller("http://example.com/topic") result = poller.start() assert result is True mock_thread.assert_called_once() args, kwargs = mock_thread.call_args assert kwargs.get("daemon") is True mock_thread_instance.start.assert_called_once() class TestNtfyPollerGetActiveMessage: """Tests for NtfyPoller.get_active_message method.""" def test_returns_none_when_no_message(self): """Returns None when no message has been received.""" poller = NtfyPoller("http://example.com/topic") result = poller.get_active_message() assert result is None class TestNtfyPollerDismiss: """Tests for NtfyPoller.dismiss method.""" def test_dismiss_clears_message(self): """dismiss() clears the current message.""" poller = NtfyPoller("http://example.com/topic") with patch.object(poller, "_lock"): poller._message = ("Title", "Body", time.monotonic()) poller.dismiss() assert poller._message is None class TestNtfyPollerEventEmission: """Tests for NtfyPoller event emission.""" def test_subscribe_adds_callback(self): """subscribe() adds a callback.""" poller = NtfyPoller("http://example.com/topic") def callback(e): return None poller.subscribe(callback) assert callback in poller._subscribers def test_unsubscribe_removes_callback(self): """unsubscribe() removes a callback.""" poller = NtfyPoller("http://example.com/topic") def callback(e): return None poller.subscribe(callback) poller.unsubscribe(callback) assert callback not in poller._subscribers def test_emit_calls_subscribers(self): """_emit() calls all subscribers.""" poller = NtfyPoller("http://example.com/topic") received = [] def callback(event): received.append(event) poller.subscribe(callback) event = NtfyMessageEvent(title="Test", body="Body") poller._emit(event) assert len(received) == 1 assert received[0].title == "Test" def test_emit_handles_subscriber_exception(self): """_emit() handles exceptions in subscribers gracefully.""" poller = NtfyPoller("http://example.com/topic") def bad_callback(event): raise RuntimeError("test") poller.subscribe(bad_callback) event = NtfyMessageEvent(title="Test", body="Body") poller._emit(event)