mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 02:49:40 +00:00
324 lines
9.9 KiB
Python
324 lines
9.9 KiB
Python
"""UniFi Network light platform tests."""
|
|
|
|
from copy import deepcopy
|
|
from unittest.mock import patch
|
|
|
|
from aiounifi.models.message import MessageKey
|
|
import pytest
|
|
from syrupy.assertion import SnapshotAssertion
|
|
|
|
from homeassistant.components.light import (
|
|
ATTR_BRIGHTNESS,
|
|
ATTR_RGB_COLOR,
|
|
DOMAIN as LIGHT_DOMAIN,
|
|
SERVICE_TURN_OFF,
|
|
SERVICE_TURN_ON,
|
|
)
|
|
from homeassistant.components.unifi.const import CONF_SITE_ID
|
|
from homeassistant.const import (
|
|
ATTR_ENTITY_ID,
|
|
CONF_HOST,
|
|
STATE_OFF,
|
|
STATE_ON,
|
|
STATE_UNAVAILABLE,
|
|
Platform,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
from .conftest import (
|
|
ConfigEntryFactoryType,
|
|
WebsocketMessageMock,
|
|
WebsocketStateManager,
|
|
)
|
|
|
|
from tests.common import MockConfigEntry, snapshot_platform
|
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
|
|
DEVICE_WITH_LED = {
|
|
"board_rev": 3,
|
|
"device_id": "mock-id",
|
|
"ip": "10.0.0.1",
|
|
"last_seen": 1562600145,
|
|
"mac": "10:00:00:00:01:01",
|
|
"model": "U6-Lite",
|
|
"name": "Device with LED",
|
|
"next_interval": 20,
|
|
"state": 1,
|
|
"type": "uap",
|
|
"version": "4.0.42.10433",
|
|
"led_override": "on",
|
|
"led_override_color": "#0000ff",
|
|
"led_override_color_brightness": 80,
|
|
"hw_caps": 2,
|
|
}
|
|
|
|
DEVICE_WITHOUT_LED = {
|
|
"board_rev": 2,
|
|
"device_id": "mock-id-2",
|
|
"ip": "10.0.0.2",
|
|
"last_seen": 1562600145,
|
|
"mac": "10:00:00:00:01:02",
|
|
"model": "US-8-60W",
|
|
"name": "Device without LED",
|
|
"next_interval": 20,
|
|
"state": 1,
|
|
"type": "usw",
|
|
"version": "4.0.42.10433",
|
|
"hw_caps": 0,
|
|
}
|
|
|
|
DEVICE_LED_OFF = {
|
|
"board_rev": 3,
|
|
"device_id": "mock-id-3",
|
|
"ip": "10.0.0.3",
|
|
"last_seen": 1562600145,
|
|
"mac": "10:00:00:00:01:03",
|
|
"model": "U6-Pro",
|
|
"name": "Device LED Off",
|
|
"next_interval": 20,
|
|
"state": 1,
|
|
"type": "uap",
|
|
"version": "4.0.42.10433",
|
|
"led_override": "off",
|
|
"led_override_color": "#ffffff",
|
|
"led_override_color_brightness": 0,
|
|
"hw_caps": 2,
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED, DEVICE_WITHOUT_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_lights(
|
|
hass: HomeAssistant,
|
|
aioclient_mock: AiohttpClientMocker,
|
|
config_entry_setup: MockConfigEntry,
|
|
) -> None:
|
|
"""Test lights."""
|
|
assert len(hass.states.async_entity_ids(LIGHT_DOMAIN)) == 1
|
|
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_ON
|
|
assert light_entity.attributes["brightness"] == 204
|
|
assert light_entity.attributes["rgb_color"] == (0, 0, 255)
|
|
|
|
assert hass.states.get("light.device_without_led_led") is None
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_LED_OFF]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_off_state(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test light off state."""
|
|
assert len(hass.states.async_entity_ids(LIGHT_DOMAIN)) == 1
|
|
|
|
light_entity = hass.states.get("light.device_led_off_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_OFF
|
|
assert light_entity.attributes.get("brightness") is None
|
|
assert light_entity.attributes.get("rgb_color") is None
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_turn_on_off(
|
|
hass: HomeAssistant,
|
|
aioclient_mock: AiohttpClientMocker,
|
|
config_entry_setup: MockConfigEntry,
|
|
) -> None:
|
|
"""Test turn on and off."""
|
|
aioclient_mock.clear_requests()
|
|
aioclient_mock.put(
|
|
f"https://{config_entry_setup.data[CONF_HOST]}:1234"
|
|
f"/api/s/{config_entry_setup.data[CONF_SITE_ID]}/rest/device/mock-id",
|
|
)
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_OFF,
|
|
{ATTR_ENTITY_ID: "light.device_with_led_led"},
|
|
blocking=True,
|
|
)
|
|
|
|
assert aioclient_mock.call_count == 1
|
|
call_data = aioclient_mock.mock_calls[0][2]
|
|
assert call_data["led_override"] == "off"
|
|
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_ON,
|
|
{ATTR_ENTITY_ID: "light.device_with_led_led"},
|
|
blocking=True,
|
|
)
|
|
|
|
assert aioclient_mock.call_count == 2
|
|
call_data = aioclient_mock.mock_calls[1][2]
|
|
assert call_data["led_override"] == "on"
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_set_brightness(
|
|
hass: HomeAssistant,
|
|
aioclient_mock: AiohttpClientMocker,
|
|
config_entry_setup: MockConfigEntry,
|
|
) -> None:
|
|
"""Test set brightness."""
|
|
aioclient_mock.clear_requests()
|
|
aioclient_mock.put(
|
|
f"https://{config_entry_setup.data[CONF_HOST]}:1234"
|
|
f"/api/s/{config_entry_setup.data[CONF_SITE_ID]}/rest/device/mock-id",
|
|
)
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_ON,
|
|
{
|
|
ATTR_ENTITY_ID: "light.device_with_led_led",
|
|
ATTR_BRIGHTNESS: 127,
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert aioclient_mock.call_count == 1
|
|
call_data = aioclient_mock.mock_calls[0][2]
|
|
assert call_data["led_override"] == "on"
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_set_rgb_color(
|
|
hass: HomeAssistant,
|
|
aioclient_mock: AiohttpClientMocker,
|
|
config_entry_setup: MockConfigEntry,
|
|
) -> None:
|
|
"""Test set RGB color."""
|
|
aioclient_mock.clear_requests()
|
|
aioclient_mock.put(
|
|
f"https://{config_entry_setup.data[CONF_HOST]}:1234"
|
|
f"/api/s/{config_entry_setup.data[CONF_SITE_ID]}/rest/device/mock-id",
|
|
)
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_ON,
|
|
{
|
|
ATTR_ENTITY_ID: "light.device_with_led_led",
|
|
ATTR_RGB_COLOR: (255, 0, 0),
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert aioclient_mock.call_count == 1
|
|
call_data = aioclient_mock.mock_calls[0][2]
|
|
assert call_data["led_override"] == "on"
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_set_brightness_and_color(
|
|
hass: HomeAssistant,
|
|
aioclient_mock: AiohttpClientMocker,
|
|
config_entry_setup: MockConfigEntry,
|
|
) -> None:
|
|
"""Test set brightness and color."""
|
|
aioclient_mock.clear_requests()
|
|
aioclient_mock.put(
|
|
f"https://{config_entry_setup.data[CONF_HOST]}:1234"
|
|
f"/api/s/{config_entry_setup.data[CONF_SITE_ID]}/rest/device/mock-id",
|
|
)
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_ON,
|
|
{
|
|
ATTR_ENTITY_ID: "light.device_with_led_led",
|
|
ATTR_RGB_COLOR: (0, 255, 0),
|
|
ATTR_BRIGHTNESS: 191,
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert aioclient_mock.call_count == 1
|
|
call_data = aioclient_mock.mock_calls[0][2]
|
|
assert call_data["led_override"] == "on"
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_state_update_via_websocket(
|
|
hass: HomeAssistant,
|
|
mock_websocket_message: WebsocketMessageMock,
|
|
) -> None:
|
|
"""Test state update via websocket."""
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_ON
|
|
assert light_entity.attributes["rgb_color"] == (0, 0, 255)
|
|
updated_device = deepcopy(DEVICE_WITH_LED)
|
|
updated_device["led_override"] = "off"
|
|
updated_device["led_override_color"] = "#ff0000"
|
|
updated_device["led_override_color_brightness"] = 100
|
|
|
|
mock_websocket_message(message=MessageKey.DEVICE, data=[updated_device])
|
|
await hass.async_block_till_done()
|
|
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_OFF
|
|
assert light_entity.attributes.get("rgb_color") is None
|
|
assert light_entity.attributes.get("brightness") is None
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_device_offline(
|
|
hass: HomeAssistant,
|
|
mock_websocket_message: WebsocketMessageMock,
|
|
) -> None:
|
|
"""Test device offline."""
|
|
assert len(hass.states.async_entity_ids(LIGHT_DOMAIN)) == 1
|
|
assert hass.states.get("light.device_with_led_led") is not None
|
|
|
|
offline_device = deepcopy(DEVICE_WITH_LED)
|
|
offline_device["state"] = 0
|
|
mock_websocket_message(message=MessageKey.DEVICE, data=[offline_device])
|
|
await hass.async_block_till_done()
|
|
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_ON
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
@pytest.mark.usefixtures("config_entry_setup")
|
|
async def test_light_device_unavailable(
|
|
hass: HomeAssistant,
|
|
mock_websocket_state: WebsocketStateManager,
|
|
) -> None:
|
|
"""Test device unavailable."""
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_ON
|
|
|
|
updated_device = deepcopy(DEVICE_WITH_LED)
|
|
updated_device["state"] = 0
|
|
|
|
await mock_websocket_state.disconnect()
|
|
await hass.async_block_till_done()
|
|
|
|
light_entity = hass.states.get("light.device_with_led_led")
|
|
assert light_entity is not None
|
|
assert light_entity.state == STATE_UNAVAILABLE
|
|
|
|
|
|
@pytest.mark.parametrize("device_payload", [[DEVICE_WITH_LED]])
|
|
async def test_light_platform_snapshot(
|
|
hass: HomeAssistant,
|
|
entity_registry: er.EntityRegistry,
|
|
config_entry_factory: ConfigEntryFactoryType,
|
|
snapshot: SnapshotAssertion,
|
|
) -> None:
|
|
"""Test platform snapshot."""
|
|
with patch("homeassistant.components.unifi.PLATFORMS", [Platform.LIGHT]):
|
|
config_entry = await config_entry_factory()
|
|
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
|