core/tests/components/sonos/test_switch.py

152 lines
6.0 KiB
Python
Raw Normal View History

"""Tests for the Sonos Alarm switch platform."""
from copy import copy
from datetime import timedelta
from unittest.mock import patch
from homeassistant.components.sonos.const import DATA_SONOS_DISCOVERY_MANAGER
from homeassistant.components.sonos.switch import (
ATTR_DURATION,
ATTR_ID,
ATTR_INCLUDE_LINKED_ZONES,
ATTR_PLAY_MODE,
ATTR_RECURRENCE,
ATTR_VOLUME,
)
from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY
from homeassistant.const import ATTR_TIME, STATE_OFF, STATE_ON
from homeassistant.helpers import entity_registry as ent_reg
from homeassistant.util import dt
from .conftest import SonosMockEvent
from tests.common import async_fire_time_changed
async def test_entity_registry(hass, async_autosetup_sonos):
"""Test sonos device with alarm registered in the device registry."""
entity_registry = ent_reg.async_get(hass)
assert "media_player.zone_a" in entity_registry.entities
assert "switch.sonos_alarm_14" in entity_registry.entities
assert "switch.sonos_zone_a_status_light" in entity_registry.entities
assert "switch.sonos_zone_a_night_sound" in entity_registry.entities
assert "switch.sonos_zone_a_speech_enhancement" in entity_registry.entities
assert "switch.sonos_zone_a_subwoofer_enabled" in entity_registry.entities
assert "switch.sonos_zone_a_surround_enabled" in entity_registry.entities
assert "switch.sonos_zone_a_touch_controls" in entity_registry.entities
async def test_switch_attributes(hass, async_autosetup_sonos, soco):
"""Test for correct Sonos switch states."""
entity_registry = ent_reg.async_get(hass)
alarm = entity_registry.entities["switch.sonos_alarm_14"]
alarm_state = hass.states.get(alarm.entity_id)
assert alarm_state.state == STATE_ON
assert alarm_state.attributes.get(ATTR_TIME) == "07:00:00"
assert alarm_state.attributes.get(ATTR_ID) == "14"
assert alarm_state.attributes.get(ATTR_DURATION) == "02:00:00"
assert alarm_state.attributes.get(ATTR_RECURRENCE) == "DAILY"
assert alarm_state.attributes.get(ATTR_VOLUME) == 0.25
assert alarm_state.attributes.get(ATTR_PLAY_MODE) == "SHUFFLE_NOREPEAT"
assert not alarm_state.attributes.get(ATTR_INCLUDE_LINKED_ZONES)
night_sound = entity_registry.entities["switch.sonos_zone_a_night_sound"]
night_sound_state = hass.states.get(night_sound.entity_id)
assert night_sound_state.state == STATE_ON
speech_enhancement = entity_registry.entities[
"switch.sonos_zone_a_speech_enhancement"
]
speech_enhancement_state = hass.states.get(speech_enhancement.entity_id)
assert speech_enhancement_state.state == STATE_ON
crossfade = entity_registry.entities["switch.sonos_zone_a_crossfade"]
crossfade_state = hass.states.get(crossfade.entity_id)
assert crossfade_state.state == STATE_ON
# Ensure switches are disabled
status_light = entity_registry.entities["switch.sonos_zone_a_status_light"]
assert hass.states.get(status_light.entity_id) is None
touch_controls = entity_registry.entities["switch.sonos_zone_a_touch_controls"]
assert hass.states.get(touch_controls.entity_id) is None
sub_switch = entity_registry.entities["switch.sonos_zone_a_subwoofer_enabled"]
sub_switch_state = hass.states.get(sub_switch.entity_id)
assert sub_switch_state.state == STATE_OFF
surround_switch = entity_registry.entities["switch.sonos_zone_a_surround_enabled"]
surround_switch_state = hass.states.get(surround_switch.entity_id)
assert surround_switch_state.state == STATE_ON
# Enable disabled switches
for entity in (status_light, touch_controls):
entity_registry.async_update_entity(
entity_id=entity.entity_id, disabled_by=None
)
await hass.async_block_till_done()
# Fire event to cancel poll timer and avoid triggering errors during time jump
service = soco.contentDirectory
empty_event = SonosMockEvent(soco, service, {})
subscription = service.subscribe.return_value
subscription.callback(event=empty_event)
await hass.async_block_till_done()
# Mock shutdown calls during config entry reload
with patch.object(hass.data[DATA_SONOS_DISCOVERY_MANAGER], "async_shutdown") as m:
async_fire_time_changed(
hass,
dt.utcnow() + timedelta(seconds=RELOAD_AFTER_UPDATE_DELAY + 1),
)
await hass.async_block_till_done()
assert m.called
status_light_state = hass.states.get(status_light.entity_id)
assert status_light_state.state == STATE_ON
touch_controls = entity_registry.entities["switch.sonos_zone_a_touch_controls"]
touch_controls_state = hass.states.get(touch_controls.entity_id)
assert touch_controls_state.state == STATE_ON
async def test_alarm_create_delete(
hass, async_setup_sonos, soco, alarm_clock, alarm_clock_extended, alarm_event
):
"""Test for correct creation and deletion of alarms during runtime."""
entity_registry = ent_reg.async_get(hass)
one_alarm = copy(alarm_clock.ListAlarms.return_value)
two_alarms = copy(alarm_clock_extended.ListAlarms.return_value)
await async_setup_sonos()
assert "switch.sonos_alarm_14" in entity_registry.entities
assert "switch.sonos_alarm_15" not in entity_registry.entities
subscription = alarm_clock.subscribe.return_value
sub_callback = subscription.callback
alarm_clock.ListAlarms.return_value = two_alarms
alarm_event.variables["alarm_list_version"] = two_alarms["CurrentAlarmListVersion"]
sub_callback(event=alarm_event)
await hass.async_block_till_done()
assert "switch.sonos_alarm_14" in entity_registry.entities
assert "switch.sonos_alarm_15" in entity_registry.entities
one_alarm["CurrentAlarmListVersion"] = alarm_event.increment_variable(
"alarm_list_version"
)
alarm_clock.ListAlarms.return_value = one_alarm
sub_callback(event=alarm_event)
await hass.async_block_till_done()
assert "switch.sonos_alarm_14" in entity_registry.entities
assert "switch.sonos_alarm_15" not in entity_registry.entities