mirror of https://github.com/home-assistant/core
324 lines
9.2 KiB
Python
324 lines
9.2 KiB
Python
"""LCN Websocket Tests."""
|
|
|
|
from typing import Any
|
|
|
|
from pypck.lcn_addr import LcnAddr
|
|
import pytest
|
|
|
|
from homeassistant.components.lcn import AddressType
|
|
from homeassistant.components.lcn.const import CONF_DOMAIN_DATA
|
|
from homeassistant.components.lcn.helpers import get_device_config, get_resource
|
|
from homeassistant.const import (
|
|
CONF_ADDRESS,
|
|
CONF_DEVICES,
|
|
CONF_DOMAIN,
|
|
CONF_ENTITIES,
|
|
CONF_NAME,
|
|
CONF_RESOURCE,
|
|
CONF_TYPE,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .conftest import MockConfigEntry, init_integration
|
|
|
|
from tests.typing import WebSocketGenerator
|
|
|
|
DEVICES_PAYLOAD = {CONF_TYPE: "lcn/devices", "entry_id": ""}
|
|
ENTITIES_PAYLOAD = {
|
|
CONF_TYPE: "lcn/entities",
|
|
"entry_id": "",
|
|
}
|
|
SCAN_PAYLOAD = {CONF_TYPE: "lcn/devices/scan", "entry_id": ""}
|
|
DEVICES_ADD_PAYLOAD = {
|
|
CONF_TYPE: "lcn/devices/add",
|
|
"entry_id": "",
|
|
CONF_ADDRESS: (0, 10, False),
|
|
}
|
|
DEVICES_DELETE_PAYLOAD = {
|
|
CONF_TYPE: "lcn/devices/delete",
|
|
"entry_id": "",
|
|
CONF_ADDRESS: (0, 7, False),
|
|
}
|
|
ENTITIES_ADD_PAYLOAD = {
|
|
CONF_TYPE: "lcn/entities/add",
|
|
"entry_id": "",
|
|
CONF_ADDRESS: (0, 7, False),
|
|
CONF_NAME: "test_switch",
|
|
CONF_DOMAIN: "switch",
|
|
CONF_DOMAIN_DATA: {"output": "RELAY5"},
|
|
}
|
|
ENTITIES_DELETE_PAYLOAD = {
|
|
CONF_TYPE: "lcn/entities/delete",
|
|
"entry_id": "",
|
|
CONF_ADDRESS: (0, 7, False),
|
|
CONF_DOMAIN: "switch",
|
|
CONF_RESOURCE: "relay1",
|
|
}
|
|
|
|
|
|
async def test_lcn_devices_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/devices command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id({**DEVICES_PAYLOAD, "entry_id": entry.entry_id})
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
assert len(res["result"]) == len(entry.data[CONF_DEVICES])
|
|
assert all(
|
|
{**result, CONF_ADDRESS: tuple(result[CONF_ADDRESS])}
|
|
in entry.data[CONF_DEVICES]
|
|
for result in res["result"]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"payload",
|
|
[
|
|
ENTITIES_PAYLOAD,
|
|
{**ENTITIES_PAYLOAD, CONF_ADDRESS: (0, 7, False)},
|
|
],
|
|
)
|
|
async def test_lcn_entities_command(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
entry: MockConfigEntry,
|
|
payload,
|
|
) -> None:
|
|
"""Test lcn/entities command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id(
|
|
{
|
|
**payload,
|
|
"entry_id": entry.entry_id,
|
|
}
|
|
)
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
entities = [
|
|
entity
|
|
for entity in entry.data[CONF_ENTITIES]
|
|
if CONF_ADDRESS not in payload or entity[CONF_ADDRESS] == payload[CONF_ADDRESS]
|
|
]
|
|
assert len(res["result"]) == len(entities)
|
|
assert all(
|
|
{**result, CONF_ADDRESS: tuple(result[CONF_ADDRESS])} in entities
|
|
for result in res["result"]
|
|
)
|
|
|
|
|
|
async def test_lcn_devices_scan_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/devices/scan command."""
|
|
# add new module which is not stored in config_entry
|
|
lcn_connection = await init_integration(hass, entry)
|
|
lcn_connection.get_address_conn(LcnAddr(0, 10, False))
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id({**SCAN_PAYLOAD, "entry_id": entry.entry_id})
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
|
|
lcn_connection.scan_modules.assert_awaited()
|
|
assert len(res["result"]) == len(entry.data[CONF_DEVICES])
|
|
assert all(
|
|
{**result, CONF_ADDRESS: tuple(result[CONF_ADDRESS])}
|
|
in entry.data[CONF_DEVICES]
|
|
for result in res["result"]
|
|
)
|
|
|
|
|
|
async def test_lcn_devices_add_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/devices/add command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
assert get_device_config((0, 10, False), entry) is None
|
|
|
|
await client.send_json_auto_id({**DEVICES_ADD_PAYLOAD, "entry_id": entry.entry_id})
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
|
|
assert get_device_config((0, 10, False), entry)
|
|
|
|
|
|
async def test_lcn_devices_delete_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/devices/delete command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
assert get_device_config((0, 7, False), entry)
|
|
|
|
await client.send_json_auto_id(
|
|
{**DEVICES_DELETE_PAYLOAD, "entry_id": entry.entry_id}
|
|
)
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
assert get_device_config((0, 7, False), entry) is None
|
|
|
|
|
|
async def test_lcn_entities_add_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/entities/add command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
|
|
entity_config = {
|
|
key: ENTITIES_ADD_PAYLOAD[key]
|
|
for key in (CONF_ADDRESS, CONF_NAME, CONF_DOMAIN, CONF_DOMAIN_DATA)
|
|
}
|
|
|
|
resource = get_resource(
|
|
ENTITIES_ADD_PAYLOAD[CONF_DOMAIN], ENTITIES_ADD_PAYLOAD[CONF_DOMAIN_DATA]
|
|
).lower()
|
|
|
|
assert {**entity_config, CONF_RESOURCE: resource} not in entry.data[CONF_ENTITIES]
|
|
|
|
await client.send_json_auto_id({**ENTITIES_ADD_PAYLOAD, "entry_id": entry.entry_id})
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
|
|
assert {**entity_config, CONF_RESOURCE: resource} in entry.data[CONF_ENTITIES]
|
|
|
|
|
|
async def test_lcn_entities_delete_command(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test lcn/entities/delete command."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
|
|
assert (
|
|
len(
|
|
[
|
|
entity
|
|
for entity in entry.data[CONF_ENTITIES]
|
|
if entity[CONF_ADDRESS] == ENTITIES_DELETE_PAYLOAD[CONF_ADDRESS]
|
|
and entity[CONF_DOMAIN] == ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN]
|
|
and entity[CONF_RESOURCE] == ENTITIES_DELETE_PAYLOAD[CONF_RESOURCE]
|
|
]
|
|
)
|
|
== 1
|
|
)
|
|
|
|
await client.send_json_auto_id(
|
|
{**ENTITIES_DELETE_PAYLOAD, "entry_id": entry.entry_id}
|
|
)
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
|
|
assert (
|
|
len(
|
|
[
|
|
entity
|
|
for entity in entry.data[CONF_ENTITIES]
|
|
if entity[CONF_ADDRESS] == ENTITIES_DELETE_PAYLOAD[CONF_ADDRESS]
|
|
and entity[CONF_DOMAIN] == ENTITIES_DELETE_PAYLOAD[CONF_DOMAIN]
|
|
and entity[CONF_RESOURCE] == ENTITIES_DELETE_PAYLOAD[CONF_RESOURCE]
|
|
]
|
|
)
|
|
== 0
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("payload", "entity_id", "result"),
|
|
[
|
|
(DEVICES_PAYLOAD, "12345", False),
|
|
(ENTITIES_PAYLOAD, "12345", False),
|
|
(SCAN_PAYLOAD, "12345", False),
|
|
(DEVICES_ADD_PAYLOAD, "12345", False),
|
|
(DEVICES_DELETE_PAYLOAD, "12345", False),
|
|
(ENTITIES_ADD_PAYLOAD, "12345", False),
|
|
(ENTITIES_DELETE_PAYLOAD, "12345", False),
|
|
],
|
|
)
|
|
async def test_lcn_command_host_error(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
entry: MockConfigEntry,
|
|
payload: dict[str, str],
|
|
entity_id: str,
|
|
result: bool,
|
|
) -> None:
|
|
"""Test lcn commands for unknown host."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id({**payload, "entry_id": entity_id})
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
assert res["result"] == result
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("payload", "address", "result"),
|
|
[
|
|
(DEVICES_ADD_PAYLOAD, (0, 7, False), False), # device already existing
|
|
(DEVICES_DELETE_PAYLOAD, (0, 42, False), False),
|
|
(ENTITIES_ADD_PAYLOAD, (0, 42, False), False),
|
|
(ENTITIES_DELETE_PAYLOAD, (0, 42, 0), False),
|
|
],
|
|
)
|
|
async def test_lcn_command_address_error(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
entry: MockConfigEntry,
|
|
payload: dict[str, Any],
|
|
address: AddressType,
|
|
result: bool,
|
|
) -> None:
|
|
"""Test lcn commands for address error."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id(
|
|
{**payload, "entry_id": entry.entry_id, CONF_ADDRESS: address}
|
|
)
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
assert res["result"] == result
|
|
|
|
|
|
async def test_lcn_entities_add_existing_error(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test lcn commands for address error."""
|
|
await init_integration(hass, entry)
|
|
|
|
client = await hass_ws_client(hass)
|
|
await client.send_json_auto_id(
|
|
{
|
|
**ENTITIES_ADD_PAYLOAD,
|
|
"entry_id": entry.entry_id,
|
|
CONF_DOMAIN_DATA: {"output": "RELAY1"},
|
|
}
|
|
)
|
|
|
|
res = await client.receive_json()
|
|
assert res["success"], res
|
|
assert res["result"] is False
|