@@ -1679,3 +1679,82 @@ async def async_pipeline_from_audio_stream(
16791679 # Stop the satellite
16801680 await hass .config_entries .async_unload (entry .entry_id )
16811681 await hass .async_block_till_done ()
1682+
1683+
1684+ async def test_ask_question (
1685+ hass : HomeAssistant ,
1686+ entity_registry : er .EntityRegistry ,
1687+ tmp_path : Path ,
1688+ ) -> None :
1689+ """Test the internal ask question flow."""
1690+ assert await async_setup_component (hass , assist_pipeline .DOMAIN , {})
1691+
1692+ wav_path = tmp_path / "test.wav"
1693+ with wave .open (str (wav_path ), "wb" ) as wav_file :
1694+ wav_file .setframerate (SAMPLE_RATE )
1695+ wav_file .setsampwidth (SAMPLE_WIDTH )
1696+ wav_file .setnchannels (SAMPLE_CHANNELS )
1697+ wav_file .writeframes (bytes (SAMPLE_RATE * 2 ))
1698+
1699+ # This is the announcement object our mock will return.
1700+ # It bypasses TTS and points directly to our local file.
1701+ fake_announcement = assist_satellite .AssistSatelliteAnnouncement (
1702+ message = "Are you sure?" ,
1703+ media_id = str (wav_path ),
1704+ original_media_id = "" ,
1705+ tts_token = None ,
1706+ media_id_source = "url" ,
1707+ )
1708+
1709+ with (
1710+ patch (
1711+ "homeassistant.components.wyoming.data.load_wyoming_info" ,
1712+ return_value = SATELLITE_INFO ,
1713+ ),
1714+ patch (
1715+ "homeassistant.components.wyoming.assist_satellite.AsyncTcpClient" ,
1716+ SatelliteAsyncTcpClient (responses = [], block_until_inject = True ),
1717+ ) as mock_client ,
1718+ patch (
1719+ "homeassistant.components.wyoming.assist_satellite.WyomingAssistSatellite._resolve_announcement_media_id" ,
1720+ return_value = fake_announcement ,
1721+ ) as mock_resolve ,
1722+ ):
1723+ entry = await setup_config_entry (hass )
1724+ satellite_entity = hass .data [DOMAIN ][entry .entry_id ].device .assist_satellite
1725+ assert satellite_entity is not None
1726+
1727+ async with asyncio .timeout (1 ):
1728+ await mock_client .connect_event .wait ()
1729+ await mock_client .run_satellite_event .wait ()
1730+
1731+ ask_task = hass .async_create_background_task (
1732+ satellite_entity .async_internal_ask_question (
1733+ question = "Are you sure?" ,
1734+ answers = [
1735+ {"id" : "yes" , "sentences" : ["yes" ]},
1736+ {"id" : "no" , "sentences" : ["no" ]},
1737+ ],
1738+ ),
1739+ "wyoming_satellite_ask_question" ,
1740+ )
1741+
1742+ # Announcement should play
1743+ async with asyncio .timeout (2 ):
1744+ await mock_client .tts_audio_start_event .wait ()
1745+ await mock_client .tts_audio_chunk_event .wait ()
1746+ await mock_client .tts_audio_stop_event .wait ()
1747+ mock_client .inject_event (Played ().event ())
1748+
1749+ # Satellite should be waiting for a response
1750+ async with asyncio .timeout (2 ):
1751+ # Simulate user saying "yes"
1752+ mock_client .inject_event (Transcript (text = "yes" ).event ())
1753+ mock_client .inject_event (AudioStop ().event ())
1754+
1755+ result = await ask_task
1756+ assert result is not None
1757+ assert result .id == "yes"
1758+ assert result .sentence == "yes"
1759+
1760+ mock_resolve .assert_called_once ()
0 commit comments