Add tests for sonos switch alarms on and off (#146314)

* fix: add tests for switch on/off

* fix: simplify

* fix: simplify

* fix: comment

* fix: comment
This commit is contained in:
Pete Sage 2025-06-08 05:45:20 -04:00 committed by GitHub
parent 4a5e261709
commit fd30dd0aee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 77 additions and 34 deletions

View File

@ -85,6 +85,16 @@ class SonosMockService:
self.subscribe = AsyncMock(return_value=SonosMockSubscribe(ip_address))
class SonosMockAlarmClock(SonosMockService):
"""Mock a Sonos AlarmClock Service used in callbacks."""
def __init__(self, return_value: dict[str, str], ip_address="192.168.42.2") -> None:
"""Initialize the instance."""
super().__init__("AlarmClock", ip_address)
self.ListAlarms = Mock(return_value=return_value)
self.UpdateAlarm = Mock()
class SonosMockEvent:
"""Mock a sonos Event used in callbacks."""
@ -593,43 +603,39 @@ def music_library_fixture(
@pytest.fixture(name="alarm_clock")
def alarm_clock_fixture():
def alarm_clock_fixture() -> SonosMockAlarmClock:
"""Create alarmClock fixture."""
alarm_clock = SonosMockService("AlarmClock")
# pylint: disable-next=attribute-defined-outside-init
alarm_clock.ListAlarms = Mock()
alarm_clock.ListAlarms.return_value = {
"CurrentAlarmListVersion": "RINCON_test:14",
"CurrentAlarmList": "<Alarms>"
'<Alarm ID="14" StartTime="07:00:00" Duration="02:00:00" Recurrence="DAILY" '
'Enabled="1" RoomUUID="RINCON_test" ProgramURI="x-rincon-buzzer:0" '
'ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" Volume="25" '
'IncludeLinkedZones="0"/>'
"</Alarms>",
}
return alarm_clock
return SonosMockAlarmClock(
{
"CurrentAlarmListVersion": "RINCON_test:14",
"CurrentAlarmList": "<Alarms>"
'<Alarm ID="14" StartTime="07:00:00" Duration="02:00:00" Recurrence="DAILY" '
'Enabled="1" RoomUUID="RINCON_test" ProgramURI="x-rincon-buzzer:0" '
'ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" Volume="25" '
'IncludeLinkedZones="0"/>'
"</Alarms>",
}
)
@pytest.fixture(name="alarm_clock_extended")
def alarm_clock_fixture_extended():
def alarm_clock_fixture_extended() -> SonosMockAlarmClock:
"""Create alarmClock fixture."""
alarm_clock = SonosMockService("AlarmClock")
# pylint: disable-next=attribute-defined-outside-init
alarm_clock.ListAlarms = Mock()
alarm_clock.ListAlarms.return_value = {
"CurrentAlarmListVersion": "RINCON_test:15",
"CurrentAlarmList": "<Alarms>"
'<Alarm ID="14" StartTime="07:00:00" Duration="02:00:00" Recurrence="DAILY" '
'Enabled="1" RoomUUID="RINCON_test" ProgramURI="x-rincon-buzzer:0" '
'ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" Volume="25" '
'IncludeLinkedZones="0"/>'
'<Alarm ID="15" StartTime="07:00:00" Duration="02:00:00" '
'Recurrence="DAILY" Enabled="1" RoomUUID="RINCON_test" '
'ProgramURI="x-rincon-buzzer:0" ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" '
'Volume="25" IncludeLinkedZones="0"/>'
"</Alarms>",
}
return alarm_clock
return SonosMockAlarmClock(
{
"CurrentAlarmListVersion": "RINCON_test:15",
"CurrentAlarmList": "<Alarms>"
'<Alarm ID="14" StartTime="07:00:00" Duration="02:00:00" Recurrence="DAILY" '
'Enabled="1" RoomUUID="RINCON_test" ProgramURI="x-rincon-buzzer:0" '
'ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" Volume="25" '
'IncludeLinkedZones="0"/>'
'<Alarm ID="15" StartTime="07:00:00" Duration="02:00:00" '
'Recurrence="DAILY" Enabled="1" RoomUUID="RINCON_test" '
'ProgramURI="x-rincon-buzzer:0" ProgramMetaData="" PlayMode="SHUFFLE_NOREPEAT" '
'Volume="25" IncludeLinkedZones="0"/>'
"</Alarms>",
}
)
@pytest.fixture(name="speaker_model")

View File

@ -4,6 +4,8 @@ from copy import copy
from datetime import timedelta
from unittest.mock import patch
import pytest
from homeassistant.components.sonos.const import DATA_SONOS_DISCOVERY_MANAGER
from homeassistant.components.sonos.switch import (
ATTR_DURATION,
@ -13,13 +15,21 @@ from homeassistant.components.sonos.switch import (
ATTR_RECURRENCE,
ATTR_VOLUME,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY
from homeassistant.const import ATTR_TIME, STATE_OFF, STATE_ON
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_TIME,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from .conftest import SonosMockEvent
from .conftest import MockSoCo, SonosMockEvent
from tests.common import async_fire_time_changed
@ -132,6 +142,33 @@ async def test_switch_attributes(
assert touch_controls_state.state == STATE_ON
@pytest.mark.parametrize(
("service", "expected_result"),
[
(SERVICE_TURN_OFF, "0"),
(SERVICE_TURN_ON, "1"),
],
)
async def test_switch_alarm_turn_on(
hass: HomeAssistant,
async_setup_sonos,
soco: MockSoCo,
service: str,
expected_result: str,
) -> None:
"""Test enabling and disabling of alarm."""
await async_setup_sonos()
await hass.services.async_call(
SWITCH_DOMAIN, service, {ATTR_ENTITY_ID: "switch.sonos_alarm_14"}, blocking=True
)
assert soco.alarmClock.UpdateAlarm.call_count == 1
call_args = soco.alarmClock.UpdateAlarm.call_args[0]
assert call_args[0][0] == ("ID", "14")
assert call_args[0][4] == ("Enabled", expected_result)
async def test_alarm_create_delete(
hass: HomeAssistant,
async_setup_sonos,