"""Tests for common SonosSpeaker behavior.""" from unittest.mock import patch from homeassistant.components.sonos.const import DATA_SONOS, SCAN_INTERVAL from homeassistant.core import HomeAssistant from homeassistant.util import dt as dt_util from tests.common import async_fire_time_changed async def test_fallback_to_polling( hass: HomeAssistant, async_autosetup_sonos, soco, caplog ): """Test that polling fallback works.""" speaker = list(hass.data[DATA_SONOS].discovered.values())[0] assert speaker.soco is soco assert speaker._subscriptions caplog.clear() # Ensure subscriptions are cancelled and polling methods are called when subscriptions time out with patch("homeassistant.components.sonos.media.SonosMedia.poll_media"), patch( "homeassistant.components.sonos.speaker.SonosSpeaker.subscription_address" ): async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) await hass.async_block_till_done() assert not speaker._subscriptions assert speaker.subscriptions_failed assert "falling back to polling" in caplog.text assert "Activity on Zone A from SonosSpeaker.update_volume" in caplog.text async def test_subscription_creation_fails(hass: HomeAssistant, async_setup_sonos): """Test that subscription creation failures are handled.""" with patch( "homeassistant.components.sonos.speaker.SonosSpeaker._subscribe", side_effect=ConnectionError("Took too long"), ): await async_setup_sonos() speaker = list(hass.data[DATA_SONOS].discovered.values())[0] assert not speaker._subscriptions with patch.object(speaker, "_resub_cooldown_expires_at", None): speaker.speaker_activity("discovery") await hass.async_block_till_done() assert speaker._subscriptions