Files

369 lines
10 KiB
Python

"""Tests for the Hot Spring light platform."""
from unittest.mock import MagicMock
from hotspring import (
HotSpringConnectionError,
HotSpringError,
LightColor,
LightWheelMode,
LightZone,
Spa,
)
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_RGB_COLOR,
DOMAIN as LIGHT_DOMAIN,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from . import setup_with_selected_platforms
from tests.common import MockConfigEntry, snapshot_platform
ENTITY_ID = "light.connectedspa_ddeeff_light_zone_1"
async def test_light_state(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the light entity state."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_turn_on_default(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test turning on light with default settings."""
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == "off"
assert state.attributes.get(ATTR_BRIGHTNESS) is None
def _set_light_brightness(zone: int, brightness: int) -> None:
device_fixture.light_zones[0].intensity = brightness
device_fixture.light_zones[0].is_on = brightness > 0
mock_hotspring.set_light_brightness.side_effect = _set_light_brightness
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
mock_hotspring.set_light_brightness.assert_called_once_with(1, 5)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == "on"
assert state.attributes.get(ATTR_BRIGHTNESS) == 255
async def test_turn_on_with_brightness(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test turning on light with brightness."""
def _set_light_brightness(zone: int, brightness: int) -> None:
device_fixture.light_zones[0].intensity = brightness
device_fixture.light_zones[0].is_on = brightness > 0
mock_hotspring.set_light_brightness.side_effect = _set_light_brightness
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_BRIGHTNESS: 153,
},
blocking=True,
)
mock_hotspring.set_light_brightness.assert_called_once_with(1, 3)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == "on"
assert state.attributes.get(ATTR_BRIGHTNESS) == 153
async def test_turn_on_with_rgb_color_when_off(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
) -> None:
"""Test turning on light with rgb color when light is off."""
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_RGB_COLOR: (120, 200, 50),
},
blocking=True,
)
mock_hotspring.set_light_rgb.assert_called_once_with(1, 120, 200, 50)
mock_hotspring.set_light_brightness.assert_called_once_with(1, 5)
async def test_turn_on_with_rgb_color_when_on(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test setting rgb color when light is already on."""
device_fixture.light_zones = [
LightZone(
zone_id=1,
is_enabled=True,
is_on=True,
color=LightColor.BLUE,
light_wheel=LightWheelMode.OFF,
intensity=3,
loop_speed=0,
),
]
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_RGB_COLOR: (120, 200, 50),
},
blocking=True,
)
mock_hotspring.set_light_rgb.assert_called_once_with(1, 120, 200, 50)
mock_hotspring.set_light_brightness.assert_not_called()
async def test_turn_on_with_rgb_color_and_brightness(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
) -> None:
"""Test turning on light with rgb color and brightness."""
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_RGB_COLOR: (120, 200, 50),
ATTR_BRIGHTNESS: 102,
},
blocking=True,
)
mock_hotspring.set_light_rgb.assert_called_once_with(1, 120, 200, 50)
mock_hotspring.set_light_brightness.assert_called_once_with(1, 2)
async def test_rgb_color_active_custom(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test rgb_color property returns custom RGB values when active."""
device_fixture.light_zones = [
LightZone(
zone_id=1,
is_enabled=True,
is_on=True,
color=LightColor.CUSTOM,
light_wheel=LightWheelMode.OFF,
intensity=3,
loop_speed=0,
c_red=120,
c_green=200,
c_blue=50,
rgb_state="active",
),
]
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.attributes.get("rgb_color") == (120, 200, 50)
async def test_rgb_color_all_zero(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test rgb_color property returns (0, 0, 0) when rgb_state is active."""
device_fixture.light_zones = [
LightZone(
zone_id=1,
is_enabled=True,
is_on=True,
color=LightColor.CUSTOM,
light_wheel=LightWheelMode.OFF,
intensity=3,
loop_speed=0,
c_red=0,
c_green=0,
c_blue=0,
rgb_state="active",
),
]
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.attributes.get("rgb_color") == (0, 0, 0)
async def test_turn_off(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
) -> None:
"""Test turning off light."""
device_fixture.light_zones = [
LightZone(
zone_id=1,
is_enabled=True,
is_on=True,
color=LightColor.BLUE,
light_wheel=LightWheelMode.OFF,
intensity=5,
loop_speed=0,
),
]
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
def _turn_off_light(zone: int) -> None:
device_fixture.light_zones[0].intensity = 0
device_fixture.light_zones[0].is_on = False
mock_hotspring.turn_off_light.side_effect = _turn_off_light
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == "on"
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
mock_hotspring.turn_off_light.assert_called_once_with(1)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == "off"
@pytest.mark.parametrize(
("exception", "match"),
[
(
HotSpringConnectionError,
"An error occurred while communicating with the Hot Spring API",
),
(HotSpringError, "Invalid response received from the Hot Spring API"),
],
)
async def test_turn_on_error(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
exception: type[Exception],
match: str,
) -> None:
"""Test exception handling when turning on light."""
mock_hotspring.set_light_brightness.side_effect = exception
with pytest.raises(HomeAssistantError, match=match):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
@pytest.mark.parametrize(
("exception", "match"),
[
(
HotSpringConnectionError,
"An error occurred while communicating with the Hot Spring API",
),
(HotSpringError, "Invalid response received from the Hot Spring API"),
],
)
async def test_turn_off_error(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_hotspring: MagicMock,
exception: type[Exception],
match: str,
) -> None:
"""Test exception handling when turning off light."""
mock_hotspring.turn_off_light.side_effect = exception
with pytest.raises(HomeAssistantError, match=match):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
async def test_disabled_zone_not_added(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_hotspring: MagicMock,
device_fixture: Spa,
entity_registry: er.EntityRegistry,
) -> None:
"""Test disabled light zones are not added to entity registry."""
device_fixture.light_zones = [
LightZone(
zone_id=1,
is_enabled=False,
is_on=False,
color=LightColor.UNKNOWN,
light_wheel=LightWheelMode.OFF,
intensity=0,
loop_speed=0,
),
]
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.LIGHT])
assert not entity_registry.async_is_registered(ENTITY_ID)