mirror of https://github.com/home-assistant/core
231 lines
7.9 KiB
Python
231 lines
7.9 KiB
Python
"""Test the Insteon Scenes APIs."""
|
|
|
|
from collections.abc import Generator
|
|
import os
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
from pyinsteon.constants import ResponseStatus
|
|
import pyinsteon.managers.scene_manager
|
|
import pytest
|
|
|
|
from homeassistant.components.insteon.api import async_load_api, scenes
|
|
from homeassistant.components.insteon.const import ID, TYPE
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.util.json import JsonArrayType
|
|
|
|
from .mock_devices import MockDevices
|
|
|
|
from tests.common import load_json_array_fixture
|
|
from tests.typing import MockHAClientWebSocket, WebSocketGenerator
|
|
|
|
|
|
@pytest.fixture(name="scene_data", scope="module")
|
|
def aldb_data_fixture() -> JsonArrayType:
|
|
"""Load the controller state fixture data."""
|
|
return load_json_array_fixture("insteon/scene_data.json")
|
|
|
|
|
|
@pytest.fixture(name="remove_json")
|
|
def remove_insteon_devices_json(hass: HomeAssistant) -> Generator[None]:
|
|
"""Fixture to remove insteon_devices.json at the end of the test."""
|
|
yield
|
|
file = os.path.join(hass.config.config_dir, "insteon_devices.json")
|
|
if os.path.exists(file):
|
|
os.remove(file)
|
|
|
|
|
|
def _scene_to_array(scene: dict[str, Any]) -> list[dict[str, Any]]:
|
|
"""Convert a scene object to a dictionary."""
|
|
scene_list = []
|
|
for device, links in scene["devices"].items():
|
|
for link in links:
|
|
link_dict = {}
|
|
link_dict["address"] = device.id
|
|
link_dict["data1"] = link.data1
|
|
link_dict["data2"] = link.data2
|
|
link_dict["data3"] = link.data3
|
|
scene_list.append(link_dict)
|
|
return scene_list
|
|
|
|
|
|
async def _setup(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, scene_data: JsonArrayType
|
|
) -> tuple[MockHAClientWebSocket, MockDevices]:
|
|
"""Set up tests."""
|
|
ws_client = await hass_ws_client(hass)
|
|
devices = MockDevices()
|
|
await devices.async_load()
|
|
async_load_api(hass)
|
|
for device in scene_data:
|
|
addr = device["address"]
|
|
aldb = device["aldb"]
|
|
devices.fill_aldb(addr, aldb)
|
|
return ws_client, devices
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
async def test_get_scenes(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, scene_data: JsonArrayType
|
|
) -> None:
|
|
"""Test getting all Insteon scenes."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
with patch.object(pyinsteon.managers.scene_manager, "devices", devices):
|
|
await ws_client.send_json({ID: 1, TYPE: "insteon/scenes/get"})
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert len(result) == 1
|
|
assert len(result["20"]) == 3
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
async def test_get_scene(
|
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, scene_data: JsonArrayType
|
|
) -> None:
|
|
"""Test getting an Insteon scene."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
with patch.object(pyinsteon.managers.scene_manager, "devices", devices):
|
|
await ws_client.send_json({ID: 1, TYPE: "insteon/scene/get", "scene_id": 20})
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert len(result["devices"]) == 3
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
@pytest.mark.usefixtures("remove_json")
|
|
async def test_save_scene(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
scene_data: JsonArrayType,
|
|
) -> None:
|
|
"""Test saving an Insteon scene."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
mock_add_or_update_scene = AsyncMock(return_value=(20, ResponseStatus.SUCCESS))
|
|
|
|
with (
|
|
patch.object(pyinsteon.managers.scene_manager, "devices", devices),
|
|
patch.object(scenes, "async_add_or_update_scene", mock_add_or_update_scene),
|
|
):
|
|
scene = await pyinsteon.managers.scene_manager.async_get_scene(20)
|
|
scene["devices"]["1a1a1a"] = []
|
|
links = _scene_to_array(scene)
|
|
await ws_client.send_json(
|
|
{
|
|
ID: 1,
|
|
TYPE: "insteon/scene/save",
|
|
"scene_id": 20,
|
|
"name": "Some scene name",
|
|
"links": links,
|
|
}
|
|
)
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert result["result"]
|
|
assert result["scene_id"] == 20
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
@pytest.mark.usefixtures("remove_json")
|
|
async def test_save_new_scene(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
scene_data: JsonArrayType,
|
|
) -> None:
|
|
"""Test saving a new Insteon scene."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
mock_add_or_update_scene = AsyncMock(return_value=(21, ResponseStatus.SUCCESS))
|
|
|
|
with (
|
|
patch.object(pyinsteon.managers.scene_manager, "devices", devices),
|
|
patch.object(scenes, "async_add_or_update_scene", mock_add_or_update_scene),
|
|
):
|
|
scene = await pyinsteon.managers.scene_manager.async_get_scene(20)
|
|
scene["devices"]["1a1a1a"] = []
|
|
links = _scene_to_array(scene)
|
|
await ws_client.send_json(
|
|
{
|
|
ID: 1,
|
|
TYPE: "insteon/scene/save",
|
|
"scene_id": -1,
|
|
"name": "Some scene name",
|
|
"links": links,
|
|
}
|
|
)
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert result["result"]
|
|
assert result["scene_id"] == 21
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
@pytest.mark.usefixtures("remove_json")
|
|
async def test_save_scene_error(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
scene_data: JsonArrayType,
|
|
) -> None:
|
|
"""Test saving an Insteon scene with error."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
mock_add_or_update_scene = AsyncMock(return_value=(20, ResponseStatus.FAILURE))
|
|
|
|
with (
|
|
patch.object(pyinsteon.managers.scene_manager, "devices", devices),
|
|
patch.object(scenes, "async_add_or_update_scene", mock_add_or_update_scene),
|
|
):
|
|
scene = await pyinsteon.managers.scene_manager.async_get_scene(20)
|
|
scene["devices"]["1a1a1a"] = []
|
|
links = _scene_to_array(scene)
|
|
await ws_client.send_json(
|
|
{
|
|
ID: 1,
|
|
TYPE: "insteon/scene/save",
|
|
"scene_id": 20,
|
|
"name": "Some scene name",
|
|
"links": links,
|
|
}
|
|
)
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert not result["result"]
|
|
assert result["scene_id"] == 20
|
|
|
|
|
|
# This tests needs to be adjusted to remove lingering tasks
|
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
|
@pytest.mark.usefixtures("remove_json")
|
|
async def test_delete_scene(
|
|
hass: HomeAssistant,
|
|
hass_ws_client: WebSocketGenerator,
|
|
scene_data: JsonArrayType,
|
|
) -> None:
|
|
"""Test delete an Insteon scene."""
|
|
ws_client, devices = await _setup(hass, hass_ws_client, scene_data)
|
|
|
|
mock_delete_scene = AsyncMock(return_value=ResponseStatus.SUCCESS)
|
|
|
|
with (
|
|
patch.object(pyinsteon.managers.scene_manager, "devices", devices),
|
|
patch.object(scenes, "async_delete_scene", mock_delete_scene),
|
|
):
|
|
await ws_client.send_json(
|
|
{
|
|
ID: 1,
|
|
TYPE: "insteon/scene/delete",
|
|
"scene_id": 20,
|
|
}
|
|
)
|
|
msg = await ws_client.receive_json()
|
|
result = msg["result"]
|
|
assert result["result"]
|
|
assert result["scene_id"] == 20
|