1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-08 17:49:37 +01:00
Files
core/tests/components/hyperion/__init__.py
T

198 lines
6.1 KiB
Python

"""Tests for the Hyperion integration."""
from types import TracebackType
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
from hyperion import const
from homeassistant.components.hyperion import get_hyperion_unique_id
from homeassistant.components.hyperion.const import CONF_PRIORITY, DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry
TEST_HOST = "test"
TEST_PORT = const.DEFAULT_PORT_JSON + 1
TEST_PORT_UI = const.DEFAULT_PORT_UI + 1
TEST_INSTANCE = 1
TEST_ID = "default"
TEST_SYSINFO_ID = "f9aab089-f85a-55cf-b7c1-222a72faebe9"
TEST_SYSINFO_VERSION = "2.0.0-alpha.9"
TEST_PRIORITY = 180
TEST_ENTITY_ID_1 = "light.test_instance_1"
TEST_ENTITY_ID_2 = "light.test_instance_2"
TEST_ENTITY_ID_3 = "light.test_instance_3"
TEST_TITLE = f"{TEST_HOST}:{TEST_PORT}"
TEST_TOKEN = "sekr1t"
TEST_CONFIG_ENTRY_ID = "74565ad414754616000674c87bdc876c"
TEST_CONFIG_ENTRY_OPTIONS: dict[str, Any] = {CONF_PRIORITY: TEST_PRIORITY}
TEST_INSTANCE_1: dict[str, Any] = {
"friendly_name": "Test instance 1",
"instance": 1,
"running": True,
}
TEST_INSTANCE_2: dict[str, Any] = {
"friendly_name": "Test instance 2",
"instance": 2,
"running": True,
}
TEST_INSTANCE_3: dict[str, Any] = {
"friendly_name": "Test instance 3",
"instance": 3,
"running": True,
}
TEST_AUTH_REQUIRED_RESP: dict[str, Any] = {
"command": "authorize-tokenRequired",
"info": {
"required": True,
},
"success": True,
"tan": 1,
}
TEST_AUTH_NOT_REQUIRED_RESP = {
**TEST_AUTH_REQUIRED_RESP,
"info": {"required": False},
}
class AsyncContextManagerMock(Mock):
"""An async context manager mock for Hyperion."""
async def __aenter__(self) -> AsyncContextManagerMock | None:
"""Enter context manager and connect the client."""
result = await self.async_client_connect()
return self if result else None
async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc: BaseException | None,
traceback: TracebackType | None,
) -> None:
"""Leave context manager and disconnect the client."""
await self.async_client_disconnect()
def create_mock_client() -> Mock:
"""Create a mock Hyperion client."""
mock_client = AsyncContextManagerMock()
# pylint: disable=attribute-defined-outside-init
mock_client.async_client_connect = AsyncMock(return_value=True)
mock_client.async_client_disconnect = AsyncMock(return_value=True)
mock_client.async_is_auth_required = AsyncMock(
return_value=TEST_AUTH_NOT_REQUIRED_RESP
)
mock_client.async_login = AsyncMock(
return_value={"command": "authorize-login", "success": True, "tan": 0}
)
mock_client.async_sysinfo_id = AsyncMock(return_value=TEST_SYSINFO_ID)
mock_client.async_sysinfo_version = AsyncMock(return_value=TEST_SYSINFO_VERSION)
mock_client.async_client_switch_instance = AsyncMock(return_value=True)
mock_client.async_client_login = AsyncMock(return_value=True)
mock_client.async_get_serverinfo = AsyncMock(
return_value={
"command": "serverinfo",
"success": True,
"tan": 0,
"info": {"fake": "data"},
}
)
mock_client.priorities = []
mock_client.adjustment = None
mock_client.effects = None
mock_client.instances = [
{"friendly_name": "Test instance 1", "instance": 0, "running": True}
]
mock_client.remote_url = f"http://{TEST_HOST}:{TEST_PORT_UI}"
return mock_client
def add_test_config_entry(
hass: HomeAssistant,
data: dict[str, Any] | None = None,
options: dict[str, Any] | None = None,
) -> MockConfigEntry:
"""Add a test config entry."""
config_entry = MockConfigEntry(
entry_id=TEST_CONFIG_ENTRY_ID,
domain=DOMAIN,
data=data
or {
CONF_HOST: TEST_HOST,
CONF_PORT: TEST_PORT,
},
title=f"Hyperion {TEST_SYSINFO_ID}",
unique_id=TEST_SYSINFO_ID,
options=options or TEST_CONFIG_ENTRY_OPTIONS,
)
config_entry.add_to_hass(hass)
return config_entry
async def setup_test_config_entry(
hass: HomeAssistant,
config_entry: ConfigEntry | None = None,
hyperion_client: Mock | None = None,
options: dict[str, Any] | None = None,
) -> ConfigEntry:
"""Add a test Hyperion entity to hass."""
config_entry = config_entry or add_test_config_entry(hass, options=options)
hyperion_client = hyperion_client or create_mock_client()
# pylint: disable-next=attribute-defined-outside-init
hyperion_client.instances = [TEST_INSTANCE_1]
with patch(
"homeassistant.components.hyperion.client.HyperionClient",
return_value=hyperion_client,
):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry
def call_registered_callback(
client: AsyncMock, key: str, *args: Any, **kwargs: Any
) -> None:
"""Call Hyperion entity callbacks that were registered with the client."""
for call in client.add_callbacks.call_args_list:
if key in call[0][0]:
call[0][0][key](*args, **kwargs)
def register_test_entity(
hass: HomeAssistant, domain: str, type_name: str, entity_id: str
) -> None:
"""Register a test entity."""
unique_id = get_hyperion_unique_id(TEST_SYSINFO_ID, TEST_INSTANCE, type_name)
entity_id = entity_id.split(".")[1]
entity_registry = er.async_get(hass)
entity_registry.async_get_or_create(
domain,
DOMAIN,
unique_id,
suggested_object_id=entity_id,
disabled_by=None,
)
async def async_call_registered_callback(
client: AsyncMock, key: str, *args: Any, **kwargs: Any
) -> None:
"""Call Hyperion entity callbacks that were registered with the client."""
for call in client.add_callbacks.call_args_list:
if key in call[0][0]:
await call[0][0][key](*args, **kwargs)