Files
core/tests/components/lcn/conftest.py
2025-11-18 11:39:23 +01:00

142 lines
4.7 KiB
Python

"""Test configuration and mocks for LCN component."""
import json
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
import pypck
from pypck import lcn_defs
from pypck.device import DeviceConnection, Serials
import pytest
from homeassistant.components.lcn import PchkConnectionManager
from homeassistant.components.lcn.config_flow import LcnFlowHandler
from homeassistant.components.lcn.const import DOMAIN
from homeassistant.components.lcn.helpers import AddressType, generate_unique_id
from homeassistant.const import CONF_ADDRESS, CONF_DEVICES, CONF_ENTITIES, CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from tests.common import MockConfigEntry, load_fixture
LATEST_CONFIG_ENTRY_VERSION = (LcnFlowHandler.VERSION, LcnFlowHandler.MINOR_VERSION)
class MockDeviceConnection(DeviceConnection):
"""Fake a LCN module connection."""
request_name = AsyncMock(return_value="TestModule")
request_serials = AsyncMock(
return_value=Serials(
hardware_serial=0x1A20A1234,
manu=0x01,
software_serial=0x190B11,
hardware_type=lcn_defs.HardwareType.UPP,
)
)
send_command = AsyncMock(return_value=True)
request_status_output = AsyncMock()
request_status_relays = AsyncMock()
request_status_motor_position = AsyncMock()
request_status_binary_sensors = AsyncMock()
request_status_variable = AsyncMock()
request_status_led_and_logic_ops = AsyncMock()
request_status_locked_keys = AsyncMock()
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Construct ModuleConnection instance."""
super().__init__(*args, **kwargs)
self._serials_known.set()
class MockPchkConnectionManager(PchkConnectionManager):
"""Fake connection handler."""
async def async_connect(self, timeout: int = 30) -> None:
"""Mock establishing a connection to PCHK."""
self.authentication_completed_future.set_result(True)
self.license_error_future.set_result(True)
self.segment_scan_completed_event.set()
async def async_close(self) -> None:
"""Mock closing a connection to PCHK."""
@patch.object(pypck.connection, "DeviceConnection", MockDeviceConnection)
def get_device_connection(self, addr):
"""Get LCN device connection."""
return super().get_device_connection(addr)
scan_modules = AsyncMock()
send_command = AsyncMock()
def create_config_entry(
name: str, version: tuple[int, int] = LATEST_CONFIG_ENTRY_VERSION
) -> MockConfigEntry:
"""Set up config entries with configuration data."""
fixture_filename = f"lcn/config_entry_{name}.json"
entry_data = json.loads(load_fixture(fixture_filename))
for device in entry_data[CONF_DEVICES]:
device[CONF_ADDRESS] = tuple(device[CONF_ADDRESS])
for entity in entry_data[CONF_ENTITIES]:
entity[CONF_ADDRESS] = tuple(entity[CONF_ADDRESS])
options = {}
title = entry_data[CONF_HOST]
return MockConfigEntry(
entry_id=fixture_filename.replace(".", "_"),
domain=DOMAIN,
title=title,
data=entry_data,
options=options,
version=version[0],
minor_version=version[1],
)
@pytest.fixture(name="entry")
def create_config_entry_pchk() -> MockConfigEntry:
"""Return one specific config entry."""
return create_config_entry("pchk")
@pytest.fixture(name="entry2")
def create_config_entry_myhome() -> MockConfigEntry:
"""Return one specific config entry."""
return create_config_entry("myhome")
async def init_integration(
hass: HomeAssistant, entry: MockConfigEntry
) -> MockPchkConnectionManager:
"""Set up the LCN integration in Home Assistant."""
hass.http = Mock() # needs to be mocked as hass.http.register_static_path is called when registering the frontend
lcn_connection = None
def lcn_connection_factory(*args, **kwargs):
nonlocal lcn_connection
lcn_connection = MockPchkConnectionManager(*args, **kwargs)
return lcn_connection
entry.add_to_hass(hass)
with patch(
"homeassistant.components.lcn.PchkConnectionManager",
side_effect=lcn_connection_factory,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return lcn_connection
def get_device(
hass: HomeAssistant, entry: MockConfigEntry, address: AddressType
) -> dr.DeviceEntry:
"""Get LCN device for specified address."""
device_registry = dr.async_get(hass)
identifiers = {(DOMAIN, generate_unique_id(entry.entry_id, address))}
device = device_registry.async_get_device(identifiers=identifiers)
assert device
return device