core/tests/components/switcher_kis/test_switch.py

342 lines
10 KiB
Python

"""Test the Switcher switch platform."""
from unittest.mock import patch
from aioswitcher.api import Command, ShutterChildLock, SwitcherBaseResponse
from aioswitcher.device import DeviceState
import pytest
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_ON,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util import slugify
from . import init_integration
from .consts import (
DUMMY_DUAL_SHUTTER_SINGLE_LIGHT_DEVICE as DEVICE3,
DUMMY_PLUG_DEVICE,
DUMMY_SHUTTER_DEVICE as DEVICE,
DUMMY_SINGLE_SHUTTER_DUAL_LIGHT_DEVICE as DEVICE2,
DUMMY_TOKEN as TOKEN,
DUMMY_USERNAME as USERNAME,
DUMMY_WATER_HEATER_DEVICE,
)
ENTITY_ID = f"{SWITCH_DOMAIN}.{slugify(DEVICE.name)}_child_lock"
ENTITY_ID2 = f"{SWITCH_DOMAIN}.{slugify(DEVICE2.name)}_child_lock"
ENTITY_ID3 = f"{SWITCH_DOMAIN}.{slugify(DEVICE3.name)}_child_lock_1"
ENTITY_ID3_2 = f"{SWITCH_DOMAIN}.{slugify(DEVICE3.name)}_child_lock_2"
@pytest.mark.parametrize("mock_bridge", [[DUMMY_WATER_HEATER_DEVICE]], indirect=True)
async def test_switch(
hass: HomeAssistant, mock_bridge, mock_api, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test the switch."""
await init_integration(hass)
assert mock_bridge
device = DUMMY_WATER_HEATER_DEVICE
entity_id = f"{SWITCH_DOMAIN}.{slugify(device.name)}"
# Test initial state - on
state = hass.states.get(entity_id)
assert state.state == STATE_ON
# Test state change on --> off
monkeypatch.setattr(device, "device_state", DeviceState.OFF)
mock_bridge.mock_callbacks([DUMMY_WATER_HEATER_DEVICE])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test turning on
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.control_device",
) as mock_control_device:
await hass.services.async_call(
SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True
)
assert mock_api.call_count == 2
mock_control_device.assert_called_once_with(Command.ON)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
# Test turning off
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.control_device"
) as mock_control_device:
await hass.services.async_call(
SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True
)
assert mock_api.call_count == 4
mock_control_device.assert_called_once_with(Command.OFF)
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
@pytest.mark.parametrize("mock_bridge", [[DUMMY_PLUG_DEVICE]], indirect=True)
async def test_switch_control_fail(
hass: HomeAssistant,
mock_bridge,
mock_api,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test switch control fail."""
await init_integration(hass)
assert mock_bridge
device = DUMMY_PLUG_DEVICE
entity_id = f"{SWITCH_DOMAIN}.{slugify(device.name)}"
# Test initial state - off
monkeypatch.setattr(device, "device_state", DeviceState.OFF)
mock_bridge.mock_callbacks([DUMMY_PLUG_DEVICE])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test exception during turn on
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.control_device",
side_effect=RuntimeError("fake error"),
) as mock_control_device:
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
assert mock_api.call_count == 2
mock_control_device.assert_called_once_with(Command.ON)
state = hass.states.get(entity_id)
assert state.state == STATE_UNAVAILABLE
# Make device available again
mock_bridge.mock_callbacks([DUMMY_PLUG_DEVICE])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test error response during turn on
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.control_device",
return_value=SwitcherBaseResponse(None),
) as mock_control_device:
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
assert mock_api.call_count == 4
mock_control_device.assert_called_once_with(Command.ON)
state = hass.states.get(entity_id)
assert state.state == STATE_UNAVAILABLE
@pytest.mark.parametrize(
(
"device",
"entity_id",
"cover_id",
"child_lock_state",
),
[
(
DEVICE,
ENTITY_ID,
0,
[ShutterChildLock.OFF],
),
(
DEVICE2,
ENTITY_ID2,
0,
[ShutterChildLock.OFF],
),
(
DEVICE3,
ENTITY_ID3,
0,
[ShutterChildLock.OFF, ShutterChildLock.ON],
),
(
DEVICE3,
ENTITY_ID3_2,
1,
[ShutterChildLock.ON, ShutterChildLock.OFF],
),
],
)
@pytest.mark.parametrize("mock_bridge", [[DEVICE, DEVICE2, DEVICE3]], indirect=True)
async def test_child_lock_switch(
hass: HomeAssistant,
mock_bridge,
mock_api,
monkeypatch: pytest.MonkeyPatch,
device,
entity_id: str,
cover_id: int,
child_lock_state: list[ShutterChildLock],
) -> None:
"""Test the switch."""
await init_integration(hass, USERNAME, TOKEN)
assert mock_bridge
# Test initial state - on
state = hass.states.get(entity_id)
assert state.state == STATE_ON
# Test state change on --> off
monkeypatch.setattr(device, "child_lock", child_lock_state)
mock_bridge.mock_callbacks([device])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test turning on child lock
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.set_shutter_child_lock",
) as mock_control_device:
await hass.services.async_call(
SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True
)
assert mock_api.call_count == 2
mock_control_device.assert_called_once_with(ShutterChildLock.ON, cover_id)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
# Test turning off
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.set_shutter_child_lock"
) as mock_control_device:
await hass.services.async_call(
SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True
)
assert mock_api.call_count == 4
mock_control_device.assert_called_once_with(ShutterChildLock.OFF, cover_id)
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
@pytest.mark.parametrize(
(
"device",
"entity_id",
"cover_id",
"child_lock_state",
),
[
(
DEVICE,
ENTITY_ID,
0,
[ShutterChildLock.OFF],
),
(
DEVICE2,
ENTITY_ID2,
0,
[ShutterChildLock.OFF],
),
(
DEVICE3,
ENTITY_ID3,
0,
[ShutterChildLock.OFF, ShutterChildLock.ON],
),
(
DEVICE3,
ENTITY_ID3_2,
1,
[ShutterChildLock.ON, ShutterChildLock.OFF],
),
],
)
@pytest.mark.parametrize("mock_bridge", [[DEVICE, DEVICE2, DEVICE3]], indirect=True)
async def test_child_lock_control_fail(
hass: HomeAssistant,
mock_bridge,
mock_api,
monkeypatch: pytest.MonkeyPatch,
device,
entity_id: str,
cover_id: int,
child_lock_state: list[ShutterChildLock],
) -> None:
"""Test switch control fail."""
await init_integration(hass, USERNAME, TOKEN)
assert mock_bridge
# Test initial state - off
monkeypatch.setattr(device, "child_lock", child_lock_state)
mock_bridge.mock_callbacks([device])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test exception during turn on
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.set_shutter_child_lock",
side_effect=RuntimeError("fake error"),
) as mock_control_device:
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
assert mock_api.call_count == 2
mock_control_device.assert_called_once_with(ShutterChildLock.ON, cover_id)
state = hass.states.get(entity_id)
assert state.state == STATE_UNAVAILABLE
# Make device available again
mock_bridge.mock_callbacks([device])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_OFF
# Test error response during turn on
with patch(
"homeassistant.components.switcher_kis.entity.SwitcherApi.set_shutter_child_lock",
return_value=SwitcherBaseResponse(None),
) as mock_control_device:
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
assert mock_api.call_count == 4
mock_control_device.assert_called_once_with(ShutterChildLock.ON, cover_id)
state = hass.states.get(entity_id)
assert state.state == STATE_UNAVAILABLE