core/tests/components/wled/test_switch.py

260 lines
8.4 KiB
Python

"""Tests for the WLED switch platform."""
import json
from unittest.mock import MagicMock
import pytest
from wled import Device as WLEDDevice, WLEDConnectionError, WLEDError
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.components.wled.const import (
ATTR_DURATION,
ATTR_FADE,
ATTR_TARGET_BRIGHTNESS,
ATTR_UDP_PORT,
SCAN_INTERVAL,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_ICON,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity import EntityCategory
import homeassistant.util.dt as dt_util
from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture
async def test_switch_state(
hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test the creation and values of the WLED switches."""
entity_registry = er.async_get(hass)
state = hass.states.get("switch.wled_rgb_light_nightlight")
assert state
assert state.attributes.get(ATTR_DURATION) == 60
assert state.attributes.get(ATTR_ICON) == "mdi:weather-night"
assert state.attributes.get(ATTR_TARGET_BRIGHTNESS) == 0
assert state.attributes.get(ATTR_FADE)
assert state.state == STATE_OFF
entry = entity_registry.async_get("switch.wled_rgb_light_nightlight")
assert entry
assert entry.unique_id == "aabbccddeeff_nightlight"
assert entry.entity_category is EntityCategory.CONFIG
state = hass.states.get("switch.wled_rgb_light_sync_send")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:upload-network-outline"
assert state.attributes.get(ATTR_UDP_PORT) == 21324
assert state.state == STATE_OFF
entry = entity_registry.async_get("switch.wled_rgb_light_sync_send")
assert entry
assert entry.unique_id == "aabbccddeeff_sync_send"
assert entry.entity_category is EntityCategory.CONFIG
state = hass.states.get("switch.wled_rgb_light_sync_receive")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:download-network-outline"
assert state.attributes.get(ATTR_UDP_PORT) == 21324
assert state.state == STATE_ON
entry = entity_registry.async_get("switch.wled_rgb_light_sync_receive")
assert entry
assert entry.unique_id == "aabbccddeeff_sync_receive"
assert entry.entity_category is EntityCategory.CONFIG
state = hass.states.get("switch.wled_rgb_light_reverse")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:swap-horizontal-bold"
assert state.state == STATE_OFF
entry = entity_registry.async_get("switch.wled_rgb_light_reverse")
assert entry
assert entry.unique_id == "aabbccddeeff_reverse_0"
assert entry.entity_category is EntityCategory.CONFIG
async def test_switch_change_state(
hass: HomeAssistant, init_integration: MockConfigEntry, mock_wled: MagicMock
) -> None:
"""Test the change of state of the WLED switches."""
# Nightlight
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.nightlight.call_count == 1
mock_wled.nightlight.assert_called_with(on=True)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.nightlight.call_count == 2
mock_wled.nightlight.assert_called_with(on=False)
# Sync send
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.sync.call_count == 1
mock_wled.sync.assert_called_with(send=True)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.sync.call_count == 2
mock_wled.sync.assert_called_with(send=False)
# Sync receive
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.sync.call_count == 3
mock_wled.sync.assert_called_with(receive=False)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.sync.call_count == 4
mock_wled.sync.assert_called_with(receive=True)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_reverse"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.segment.call_count == 1
mock_wled.segment.assert_called_with(segment_id=0, reverse=True)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_reverse"},
blocking=True,
)
await hass.async_block_till_done()
assert mock_wled.segment.call_count == 2
mock_wled.segment.assert_called_with(segment_id=0, reverse=False)
async def test_switch_error(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_wled: MagicMock,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test error handling of the WLED switches."""
mock_wled.nightlight.side_effect = WLEDError
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("switch.wled_rgb_light_nightlight")
assert state
assert state.state == STATE_OFF
assert "Invalid response from API" in caplog.text
async def test_switch_connection_error(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_wled: MagicMock,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test error handling of the WLED switches."""
mock_wled.nightlight.side_effect = WLEDConnectionError
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("switch.wled_rgb_light_nightlight")
assert state
assert state.state == STATE_UNAVAILABLE
assert "Error communicating with API" in caplog.text
@pytest.mark.parametrize("mock_wled", ["wled/rgb_single_segment.json"], indirect=True)
async def test_switch_dynamically_handle_segments(
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_wled: MagicMock,
) -> None:
"""Test if a new/deleted segment is dynamically added/removed."""
segment0 = hass.states.get("switch.wled_rgb_light_reverse")
segment1 = hass.states.get("switch.wled_rgb_light_segment_1_reverse")
assert segment0
assert segment0.state == STATE_OFF
assert not 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"))
)
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
segment0 = hass.states.get("switch.wled_rgb_light_reverse")
segment1 = hass.states.get("switch.wled_rgb_light_segment_1_reverse")
assert segment0
assert segment0.state == STATE_OFF
assert segment1
assert segment1.state == STATE_ON
# Test remove segment again...
mock_wled.update.return_value = return_value
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
segment0 = hass.states.get("switch.wled_rgb_light_reverse")
segment1 = hass.states.get("switch.wled_rgb_light_segment_1_reverse")
assert segment0
assert segment0.state == STATE_OFF
assert segment1
assert segment1.state == STATE_UNAVAILABLE