core/tests/components/axis/test_light.py

220 lines
6.2 KiB
Python

"""Axis light platform tests."""
from typing import Any
from unittest.mock import patch
from axis.models.api import CONTEXT
import pytest
import respx
from syrupy import SnapshotAssertion
from homeassistant.components.light import ATTR_BRIGHTNESS, DOMAIN as LIGHT_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import ConfigEntryFactoryType, RtspEventMock
from .const import DEFAULT_HOST, NAME
from tests.common import snapshot_platform
API_DISCOVERY_LIGHT_CONTROL = {
"id": "light-control",
"version": "1.1",
"name": "Light Control",
}
@pytest.fixture
def light_control_items() -> list[dict[str, Any]]:
"""Available lights."""
return [
{
"lightID": "led0",
"lightType": "IR",
"enabled": True,
"synchronizeDayNightMode": True,
"lightState": False,
"automaticIntensityMode": False,
"automaticAngleOfIlluminationMode": False,
"nrOfLEDs": 1,
"error": False,
"errorInfo": "",
}
]
@pytest.fixture(autouse=True)
def light_control_fixture(light_control_items: list[dict[str, Any]]) -> None:
"""Light control mock response."""
data = {
"apiVersion": "1.1",
"context": CONTEXT,
"method": "getLightInformation",
"data": {"items": light_control_items},
}
respx.post(
f"http://{DEFAULT_HOST}:80/axis-cgi/lightcontrol.cgi",
json={
"apiVersion": "1.1",
"context": CONTEXT,
"method": "getLightInformation",
},
).respond(
json=data,
)
@pytest.mark.parametrize("api_discovery_items", [API_DISCOVERY_LIGHT_CONTROL])
@pytest.mark.parametrize("light_control_items", [[]])
@pytest.mark.usefixtures("config_entry_setup")
async def test_no_light_entity_without_light_control_representation(
hass: HomeAssistant,
mock_rtsp_event: RtspEventMock,
) -> None:
"""Verify no lights entities get created without light control representation."""
mock_rtsp_event(
topic="tns1:Device/tnsaxis:Light/Status",
data_type="state",
data_value="ON",
source_name="id",
source_idx="0",
)
await hass.async_block_till_done()
assert not hass.states.async_entity_ids(LIGHT_DOMAIN)
@pytest.mark.parametrize("api_discovery_items", [API_DISCOVERY_LIGHT_CONTROL])
async def test_lights(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
config_entry_factory: ConfigEntryFactoryType,
mock_rtsp_event: RtspEventMock,
snapshot: SnapshotAssertion,
) -> None:
"""Test that lights are loaded properly."""
# Add light
respx.post(
f"http://{DEFAULT_HOST}:80/axis-cgi/lightcontrol.cgi",
json={
"apiVersion": "1.1",
"context": CONTEXT,
"method": "getCurrentIntensity",
"params": {"lightID": "led0"},
},
).respond(
json={
"apiVersion": "1.1",
"context": "Axis library",
"method": "getCurrentIntensity",
"data": {"intensity": 100},
},
)
respx.post(
f"http://{DEFAULT_HOST}:80/axis-cgi/lightcontrol.cgi",
json={
"apiVersion": "1.1",
"context": CONTEXT,
"method": "getValidIntensity",
"params": {"lightID": "led0"},
},
).respond(
json={
"apiVersion": "1.1",
"context": "Axis library",
"method": "getValidIntensity",
"data": {"ranges": [{"low": 0, "high": 150}]},
},
)
with patch("homeassistant.components.axis.PLATFORMS", [Platform.LIGHT]):
config_entry = await config_entry_factory()
mock_rtsp_event(
topic="tns1:Device/tnsaxis:Light/Status",
data_type="state",
data_value="ON",
source_name="id",
source_idx="0",
)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
entity_id = f"{LIGHT_DOMAIN}.{NAME}_ir_light_0"
# Turn on, set brightness, light already on
with (
patch("axis.interfaces.vapix.LightHandler.activate_light") as mock_activate,
patch(
"axis.interfaces.vapix.LightHandler.set_manual_intensity"
) as mock_set_intensity,
):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 50},
blocking=True,
)
mock_activate.assert_not_awaited()
mock_set_intensity.assert_called_once_with("led0", 29)
# Turn off
with patch(
"axis.interfaces.vapix.LightHandler.deactivate_light"
) as mock_deactivate:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_deactivate.assert_called_once()
# Event turn off light
mock_rtsp_event(
topic="tns1:Device/tnsaxis:Light/Status",
data_type="state",
data_value="OFF",
source_name="id",
source_idx="0",
)
await hass.async_block_till_done()
light_0 = hass.states.get(entity_id)
assert light_0.state == STATE_OFF
# Turn on, set brightness
with (
patch("axis.interfaces.vapix.LightHandler.activate_light") as mock_activate,
patch(
"axis.interfaces.vapix.LightHandler.set_manual_intensity"
) as mock_set_intensity,
):
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_activate.assert_called_once()
mock_set_intensity.assert_not_called()
# Turn off, light already off
with patch(
"axis.interfaces.vapix.LightHandler.deactivate_light"
) as mock_deactivate:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_deactivate.assert_not_called()