diff --git a/tests/test_microphone_monitor.py b/tests/test_microphone_monitor.py index f4d8f43..021cd14 100644 --- a/tests/test_microphone_monitor.py +++ b/tests/test_microphone_monitor.py @@ -65,3 +65,33 @@ async def test_on_device_removed_fires_when_device_disappears(): monitor.stop() assert removed == ["Mic B"] + + +@pytest.mark.asyncio +async def test_on_configured_missing_fires_immediately_at_start(): + monitor = PollMonitor(configured_device="Headset USB", interval=99.0) + missing_called = asyncio.Event() + + async def on_missing() -> None: + missing_called.set() + + monitor.on_configured_missing = on_missing + + with patch("sounddevice.query_devices", return_value=_fake_devices(["Mic A"])): + await monitor.start() + + assert missing_called.is_set() + monitor.stop() + + +@pytest.mark.asyncio +async def test_on_configured_missing_does_not_fire_when_device_present(): + monitor = PollMonitor(configured_device="Headset USB", interval=99.0) + missing_mock = AsyncMock() + monitor.on_configured_missing = missing_mock + + with patch("sounddevice.query_devices", return_value=_fake_devices(["Headset USB", "Mic A"])): + await monitor.start() + + missing_mock.assert_not_called() + monitor.stop() diff --git a/whisper_local/microphone/_poll.py b/whisper_local/microphone/_poll.py index 44c768f..a524e0a 100644 --- a/whisper_local/microphone/_poll.py +++ b/whisper_local/microphone/_poll.py @@ -32,6 +32,12 @@ class PollMonitor: async def start(self) -> None: self._known_devices = self._current_devices() + if ( + self.configured_device + and self.configured_device not in self._known_devices + and self.on_configured_missing + ): + await self.on_configured_missing() self._task = asyncio.create_task(self._loop()) def stop(self) -> None: