hass-core/tests/components/lcn/conftest.py
Andre Lengwenus c276cfc371
Add custom panel for LCN configuration (#108664)
* Add LCN panel using lcn-frontend module

* Move panel from sidebar to integration configuration

* Change OptionFlow to reconfigure step

* Change OptionFlow to reconfigure step

* Remove deprecation warning

* Fix docstring

* Add tests for lcn websockets

* Remove deepcopy

* Bump lcn-frontend to 0.1.3

* Add tests for lcn websockets

* Remove websocket command lcn/hosts

* Websocket scan tests cover modules not stored in config_entry

* Add comment to mock of hass.http

* Add a decorater to ensure the config_entry exists and return it

* Use entry_id instead of host_id

* Bump lcn-frontend to 0.1.5

* Use auto_id for websocket client send_json

* Create issues on yaml import errors

* Remove low level key deprecation warnings

* Method renaming

* Change issue id in issue creation

* Update tests for issue creation
2024-08-21 11:33:47 +02:00

141 lines
4.7 KiB
Python

"""Test configuration and mocks for LCN component."""
from collections.abc import AsyncGenerator
import json
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
import pypck
from pypck.connection import PchkConnectionManager
import pypck.module
from pypck.module import GroupConnection, ModuleConnection
import pytest
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 homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry, load_fixture
class MockModuleConnection(ModuleConnection):
"""Fake a LCN module connection."""
status_request_handler = AsyncMock()
activate_status_request_handler = AsyncMock()
cancel_status_request_handler = AsyncMock()
request_name = AsyncMock(return_value="TestModule")
send_command = AsyncMock(return_value=True)
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Construct ModuleConnection instance."""
super().__init__(*args, **kwargs)
self.serials_request_handler.serial_known.set()
class MockGroupConnection(GroupConnection):
"""Fake a LCN group connection."""
send_command = AsyncMock(return_value=True)
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, "ModuleConnection", MockModuleConnection)
@patch.object(pypck.connection, "GroupConnection", MockGroupConnection)
def get_address_conn(self, addr, request_serials=False):
"""Get LCN address connection."""
return super().get_address_conn(addr, request_serials)
scan_modules = AsyncMock()
send_command = AsyncMock()
def create_config_entry(name: str) -> 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]
unique_id = fixture_filename
return MockConfigEntry(
domain=DOMAIN,
title=title,
unique_id=unique_id,
data=entry_data,
options=options,
)
@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")
@pytest.fixture(name="lcn_connection")
async def init_integration(
hass: HomeAssistant, entry: MockConfigEntry
) -> AsyncGenerator[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(
"pypck.connection.PchkConnectionManager",
side_effect=lcn_connection_factory,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
yield lcn_connection
async def setup_component(hass: HomeAssistant) -> None:
"""Set up the LCN component."""
fixture_filename = "lcn/config.json"
config_data = json.loads(load_fixture(fixture_filename))
await async_setup_component(hass, DOMAIN, config_data)
await hass.async_block_till_done()
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