core/tests/components/wled/test_number.py

153 lines
5.0 KiB
Python
Raw Normal View History

"""Tests for the WLED number platform."""
import json
from unittest.mock import MagicMock
2023-08-25 13:59:30 +00:00
from freezegun.api import FrozenDateTimeFactory
import pytest
2023-03-06 00:49:01 +00:00
from syrupy.assertion import SnapshotAssertion
from wled import Device as WLEDDevice, WLEDConnectionError, WLEDError
from homeassistant.components.number import (
ATTR_VALUE,
DOMAIN as NUMBER_DOMAIN,
SERVICE_SET_VALUE,
)
from homeassistant.components.wled.const import SCAN_INTERVAL
2023-03-06 00:49:01 +00:00
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
2022-05-24 14:30:41 +00:00
from homeassistant.exceptions import HomeAssistantError
2023-03-06 00:49:01 +00:00
from homeassistant.helpers import device_registry as dr, entity_registry as er
2023-02-20 12:00:02 +00:00
from tests.common import async_fire_time_changed, load_fixture
pytestmark = pytest.mark.usefixtures("init_integration")
2023-03-06 00:49:01 +00:00
@pytest.mark.parametrize(
("entity_id", "value", "called_arg"),
[
("number.wled_rgb_light_segment_1_speed", 42, "speed"),
("number.wled_rgb_light_segment_1_intensity", 42, "intensity"),
],
)
async def test_numbers(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_wled: MagicMock,
entity_id: str,
value: int,
called_arg: str,
) -> None:
"""Test the creation and values of the WLED numbers."""
2023-03-06 00:49:01 +00:00
assert (state := hass.states.get(entity_id))
assert state == snapshot
2023-03-06 00:49:01 +00:00
assert (entity_entry := entity_registry.async_get(state.entity_id))
assert entity_entry == snapshot
2023-03-06 00:49:01 +00:00
assert entity_entry.device_id
assert (device_entry := device_registry.async_get(entity_entry.device_id))
assert device_entry == snapshot
2023-03-06 00:49:01 +00:00
# Test a regular state change service call
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
2023-03-06 00:49:01 +00:00
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value},
blocking=True,
)
2023-03-06 00:49:01 +00:00
assert mock_wled.segment.call_count == 1
mock_wled.segment.assert_called_with(segment_id=1, **{called_arg: value})
2023-03-06 00:49:01 +00:00
# Test with WLED error
mock_wled.segment.side_effect = WLEDError
2022-05-24 14:30:41 +00:00
with pytest.raises(HomeAssistantError, match="Invalid response from WLED API"):
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
2023-03-06 00:49:01 +00:00
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value},
2022-05-24 14:30:41 +00:00
blocking=True,
)
2023-03-06 00:49:01 +00:00
assert mock_wled.segment.call_count == 2
2023-03-06 00:49:01 +00:00
# Ensure the entity is still available
assert (state := hass.states.get(entity_id))
assert state.state != STATE_UNAVAILABLE
2023-03-06 00:49:01 +00:00
# Test when a connection error occurs
mock_wled.segment.side_effect = WLEDConnectionError
2022-05-24 14:30:41 +00:00
with pytest.raises(HomeAssistantError, match="Error communicating with WLED API"):
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
2023-03-06 00:49:01 +00:00
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value},
2022-05-24 14:30:41 +00:00
blocking=True,
)
2023-03-06 00:49:01 +00:00
assert mock_wled.segment.call_count == 3
2023-03-06 00:49:01 +00:00
# Ensure the entity became unavailable after the connection error
assert (state := hass.states.get(entity_id))
assert state.state == STATE_UNAVAILABLE
2023-02-20 12:00:02 +00:00
@pytest.mark.parametrize("device_fixture", ["rgb_single_segment"])
2023-03-06 00:49:01 +00:00
@pytest.mark.parametrize(
("entity_id_segment0", "state_segment0", "entity_id_segment1", "state_segment1"),
[
(
"number.wled_rgb_light_speed",
"32",
"number.wled_rgb_light_segment_1_speed",
"16",
),
(
"number.wled_rgb_light_intensity",
"128",
"number.wled_rgb_light_segment_1_intensity",
"64",
),
],
)
async def test_speed_dynamically_handle_segments(
hass: HomeAssistant,
2023-08-25 13:59:30 +00:00
freezer: FrozenDateTimeFactory,
mock_wled: MagicMock,
2023-03-06 00:49:01 +00:00
entity_id_segment0: str,
entity_id_segment1: str,
state_segment0: str,
state_segment1: str,
) -> None:
"""Test if a new/deleted segment is dynamically added/removed."""
2023-03-06 00:49:01 +00:00
assert (segment0 := hass.states.get(entity_id_segment0))
assert segment0.state == state_segment0
assert not hass.states.get(entity_id_segment1)
# Test adding a segment dynamically...
return_value = mock_wled.update.return_value
mock_wled.update.return_value = WLEDDevice(
json.loads(load_fixture("wled/rgb.json"))
)
2023-08-25 13:59:30 +00:00
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
2023-03-06 00:49:01 +00:00
assert (segment0 := hass.states.get(entity_id_segment0))
assert segment0.state == state_segment0
assert (segment1 := hass.states.get(entity_id_segment1))
assert segment1.state == state_segment1
# Test remove segment again...
mock_wled.update.return_value = return_value
2023-08-25 13:59:30 +00:00
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
2023-03-06 00:49:01 +00:00
assert (segment0 := hass.states.get(entity_id_segment0))
assert segment0.state == state_segment0
assert (segment1 := hass.states.get(entity_id_segment1))
assert segment1.state == STATE_UNAVAILABLE