Add tests for LCN integration setup (#48070)

This commit is contained in:
Andre Lengwenus 2021-06-28 18:08:09 +02:00 committed by GitHub
parent 540d6e9fa5
commit f2fe6c26ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 274 additions and 3 deletions

View File

@ -542,15 +542,12 @@ omit =
homeassistant/components/lastfm/sensor.py
homeassistant/components/launch_library/const.py
homeassistant/components/launch_library/sensor.py
homeassistant/components/lcn/__init__.py
homeassistant/components/lcn/binary_sensor.py
homeassistant/components/lcn/climate.py
homeassistant/components/lcn/const.py
homeassistant/components/lcn/cover.py
homeassistant/components/lcn/helpers.py
homeassistant/components/lcn/light.py
homeassistant/components/lcn/scene.py
homeassistant/components/lcn/schemas.py
homeassistant/components/lcn/sensor.py
homeassistant/components/lcn/services.py
homeassistant/components/lcn/switch.py

View File

@ -0,0 +1,97 @@
"""Test configuration and mocks for LCN component."""
import json
from unittest.mock import AsyncMock, 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.const import CONF_HOST
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()
send_command = AsyncMock(return_value=True)
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=30):
"""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):
"""Mock closing a connection to PCHK."""
@patch.object(pypck.connection, "ModuleConnection", MockModuleConnection)
@patch.object(pypck.connection, "GroupConnection", MockGroupConnection)
def get_address_conn(self, addr):
"""Get LCN address connection."""
return super().get_address_conn(addr, request_serials=False)
send_command = AsyncMock()
def create_config_entry(name):
"""Set up config entries with configuration data."""
fixture_filename = f"lcn/config_entry_{name}.json"
entry_data = json.loads(load_fixture(fixture_filename))
options = {}
title = entry_data[CONF_HOST]
unique_id = fixture_filename
entry = MockConfigEntry(
domain=DOMAIN,
title=title,
unique_id=unique_id,
data=entry_data,
options=options,
)
return entry
@pytest.fixture(name="entry")
def create_config_entry_pchk():
"""Return one specific config entry."""
return create_config_entry("pchk")
@pytest.fixture(name="entry2")
def create_config_entry_myhome():
"""Return one specific config entry."""
return create_config_entry("myhome")
async def init_integration(hass, entry):
"""Set up the LCN integration in Home Assistant."""
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
async def setup_component(hass):
"""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()

View File

@ -0,0 +1,106 @@
"""Test init of LCN integration."""
from unittest.mock import patch
from pypck.connection import (
PchkAuthenticationError,
PchkConnectionManager,
PchkLicenseError,
)
from homeassistant import config_entries
from homeassistant.components.lcn.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .conftest import MockPchkConnectionManager, init_integration, setup_component
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
async def test_async_setup_entry(hass, entry):
"""Test a successful setup entry and unload of entry."""
await init_integration(hass, entry)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state == ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.NOT_LOADED
assert not hass.data.get(DOMAIN)
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
async def test_async_setup_multiple_entries(hass, entry, entry2):
"""Test a successful setup and unload of multiple entries."""
for config_entry in (entry, entry2):
await init_integration(hass, config_entry)
assert config_entry.state == ConfigEntryState.LOADED
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
for config_entry in (entry, entry2):
assert await hass.config_entries.async_unload(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.NOT_LOADED
assert not hass.data.get(DOMAIN)
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
async def test_async_setup_entry_update(hass, entry):
"""Test a successful setup entry if entry with same id already exists."""
# setup first entry
entry.source = config_entries.SOURCE_IMPORT
# create dummy entity for LCN platform as an orphan
entity_registry = await er.async_get_registry(hass)
dummy_entity = entity_registry.async_get_or_create(
"switch", DOMAIN, "dummy", config_entry=entry
)
assert dummy_entity in entity_registry.entities.values()
# add entity to hass and setup (should cleanup dummy entity)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert dummy_entity not in entity_registry.entities.values()
async def test_async_setup_entry_raises_authentication_error(hass, entry):
"""Test that an authentication error is handled properly."""
with patch.object(
PchkConnectionManager, "async_connect", side_effect=PchkAuthenticationError
):
await init_integration(hass, entry)
assert entry.state == ConfigEntryState.SETUP_ERROR
async def test_async_setup_entry_raises_license_error(hass, entry):
"""Test that an authentication error is handled properly."""
with patch.object(
PchkConnectionManager, "async_connect", side_effect=PchkLicenseError
):
await init_integration(hass, entry)
assert entry.state == ConfigEntryState.SETUP_ERROR
async def test_async_setup_entry_raises_timeout_error(hass, entry):
"""Test that an authentication error is handled properly."""
with patch.object(PchkConnectionManager, "async_connect", side_effect=TimeoutError):
await init_integration(hass, entry)
assert entry.state == ConfigEntryState.SETUP_ERROR
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
async def test_async_setup_from_configuration_yaml(hass):
"""Test a successful setup using data from configuration.yaml."""
await async_setup_component(hass, "persistent_notification", {})
with patch("homeassistant.components.lcn.async_setup_entry") as async_setup_entry:
await setup_component(hass)
assert async_setup_entry.await_count == 2

31
tests/fixtures/lcn/config.json vendored Normal file
View File

@ -0,0 +1,31 @@
{
"lcn": {
"connections": [
{
"host": "192.168.2.41",
"port": 4114,
"username": "lcn",
"password": "lcn",
"sk_num_tries": 0,
"dim_mode": "steps200",
"name": "pchk"
},
{
"name": "myhome",
"host": "192.168.2.42",
"port": 4114,
"username": "lcn",
"password": "lcn",
"sk_num_tries": 0,
"dim_mode": "steps200"
}
],
"switches": [
{
"name": "Switch_Output1",
"address": "s0.m7",
"output": "output1"
}
]
}
}

View File

@ -0,0 +1,11 @@
{
"host": "myhome",
"ip_address": "192.168.2.42",
"port": 4114,
"username": "lcn",
"password": "lcn",
"sk_num_tries": 0,
"dim_mode": "STEPS200",
"devices": [],
"entities": []
}

View File

@ -0,0 +1,29 @@
{
"host": "pchk",
"ip_address": "192.168.2.41",
"port": 4114,
"username": "lcn",
"password": "lcn",
"sk_num_tries": 0,
"dim_mode": "STEPS200",
"devices": [
{
"address": [0, 7, false],
"name": "",
"hardware_serial": -1,
"software_serial": -1,
"hardware_type": -1
}
],
"entities": [
{
"address": [0, 7, false],
"name": "Switch_Output1",
"resource": "output1",
"domain": "switch",
"domain_data": {
"output": "OUTPUT1"
}
}
]
}