mirror of
https://github.com/home-assistant/core.git
synced 2026-08-30 02:35:19 -05:00
369 lines
10 KiB
Python
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)
|