Files
core/tests/components/liebherr/test_switch.py
T

220 lines
6.3 KiB
Python

"""Test the Liebherr switch platform."""
import copy
from typing import Any
from unittest.mock import MagicMock, patch
from pyliebherrhomeapi import (
Device,
DeviceState,
DeviceType,
TemperatureControl,
TemperatureUnit,
ToggleControl,
ZonePosition,
)
from pyliebherrhomeapi.exceptions import LiebherrConnectionError
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from .conftest import MOCK_DEVICE, SSEStreamHelper
from tests.common import MockConfigEntry, snapshot_platform
@pytest.fixture
def platforms() -> list[Platform]:
"""Fixture to specify platforms to test."""
return [Platform.SWITCH]
@pytest.fixture(autouse=True)
def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
"""Make sure all entities are enabled."""
@pytest.mark.usefixtures("init_integration")
async def test_switches(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test all switch entities with multi-zone device."""
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize(
("entity_id", "service", "method", "kwargs"),
[
(
"switch.test_fridge_top_zone_supercool",
SERVICE_TURN_ON,
"set_super_cool",
{"device_id": "test_device_id", "zone_id": 1, "value": True},
),
(
"switch.test_fridge_top_zone_supercool",
SERVICE_TURN_OFF,
"set_super_cool",
{"device_id": "test_device_id", "zone_id": 1, "value": False},
),
(
"switch.test_fridge_bottom_zone_superfrost",
SERVICE_TURN_ON,
"set_super_frost",
{"device_id": "test_device_id", "zone_id": 2, "value": True},
),
(
"switch.test_fridge_partymode",
SERVICE_TURN_ON,
"set_party_mode",
{"device_id": "test_device_id", "value": True},
),
(
"switch.test_fridge_nightmode",
SERVICE_TURN_OFF,
"set_night_mode",
{"device_id": "test_device_id", "value": False},
),
],
)
@pytest.mark.usefixtures("init_integration")
async def test_switch_service_calls(
hass: HomeAssistant,
mock_liebherr_client: MagicMock,
entity_id: str,
service: str,
method: str,
kwargs: dict[str, Any],
) -> None:
"""Test switch turn on/off service calls."""
await hass.services.async_call(
SWITCH_DOMAIN,
service,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
getattr(mock_liebherr_client, method).assert_called_once_with(**kwargs)
@pytest.mark.parametrize(
("entity_id", "method"),
[
("switch.test_fridge_top_zone_supercool", "set_super_cool"),
("switch.test_fridge_partymode", "set_party_mode"),
],
)
@pytest.mark.usefixtures("init_integration")
async def test_switch_failure(
hass: HomeAssistant,
mock_liebherr_client: MagicMock,
entity_id: str,
method: str,
) -> None:
"""Test switch fails gracefully on connection error."""
getattr(mock_liebherr_client, method).side_effect = LiebherrConnectionError(
"Connection failed"
)
with pytest.raises(
HomeAssistantError,
match="An error occurred while communicating with the device",
):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
@pytest.mark.usefixtures("init_integration")
async def test_switch_when_control_missing(
hass: HomeAssistant,
mock_liebherr_client: MagicMock,
sse_helper: SSEStreamHelper,
) -> None:
"""Test switch entity behavior when toggle control is removed."""
entity_id = "switch.test_fridge_top_zone_supercool"
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_OFF
# Device stops reporting toggle controls
mock_liebherr_client.get_device_state.side_effect = lambda *a, **kw: DeviceState(
device=MOCK_DEVICE, controls=[]
)
await sse_helper.async_reconnect()
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNAVAILABLE
async def test_single_zone_switch(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
mock_liebherr_client: MagicMock,
mock_config_entry: MockConfigEntry,
platforms: list[Platform],
) -> None:
"""Test single zone device uses name without zone suffix."""
device = Device(
device_id="single_zone_id",
nickname="Single Zone Fridge",
device_type=DeviceType.FRIDGE,
device_name="K2601",
)
mock_liebherr_client.get_devices.return_value = [device]
single_zone_state = DeviceState(
device=device,
controls=[
TemperatureControl(
zone_id=1,
zone_position=ZonePosition.TOP,
name="Fridge",
type="fridge",
value=4,
target=4,
min=2,
max=8,
unit=TemperatureUnit.CELSIUS,
),
ToggleControl(
name="supercool",
type="ToggleControl",
zone_id=1,
zone_position=ZonePosition.TOP,
value=False,
),
],
)
mock_liebherr_client.get_device_state.side_effect = lambda *a, **kw: copy.deepcopy(
single_zone_state
)
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.components.liebherr.PLATFORMS", platforms):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)