Add tests for LCN climate and scene platform (#124466)
* Add tests for LCN climate and scene platform * Add type hints * Add snapshots for test_climate * Add snapshots for test_scene * Replace await_called assertion with snapshots * Remove snapshots for simple status changes * Test platform setup using snapshot_platform * Fix type hints * Patch homeassistant.components.lcn context instead of pypck module * Fix side effects caused by patching PchkConnectionManager in lcn platform context
This commit is contained in:
parent
ea7b2ecec0
commit
20639b0f02
10 changed files with 656 additions and 59 deletions
|
@ -7,6 +7,7 @@ from functools import partial
|
|||
import logging
|
||||
|
||||
import pypck
|
||||
from pypck.connection import PchkConnectionManager
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import (
|
||||
|
@ -87,7 +88,7 @@ async def async_setup_entry(
|
|||
}
|
||||
|
||||
# connect to PCHK
|
||||
lcn_connection = pypck.connection.PchkConnectionManager(
|
||||
lcn_connection = PchkConnectionManager(
|
||||
config_entry.data[CONF_IP_ADDRESS],
|
||||
config_entry.data[CONF_PORT],
|
||||
config_entry.data[CONF_USERNAME],
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
"""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 import PchkConnectionManager
|
||||
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
|
||||
|
@ -76,11 +75,10 @@ def create_config_entry(name: str) -> MockConfigEntry:
|
|||
options = {}
|
||||
|
||||
title = entry_data[CONF_HOST]
|
||||
unique_id = fixture_filename
|
||||
return MockConfigEntry(
|
||||
entry_id=fixture_filename,
|
||||
domain=DOMAIN,
|
||||
title=title,
|
||||
unique_id=unique_id,
|
||||
data=entry_data,
|
||||
options=options,
|
||||
)
|
||||
|
@ -98,10 +96,9 @@ def create_config_entry_myhome() -> MockConfigEntry:
|
|||
return create_config_entry("myhome")
|
||||
|
||||
|
||||
@pytest.fixture(name="lcn_connection")
|
||||
async def init_integration(
|
||||
hass: HomeAssistant, entry: MockConfigEntry
|
||||
) -> AsyncGenerator[MockPchkConnectionManager]:
|
||||
) -> 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
|
||||
|
@ -113,12 +110,22 @@ async def init_integration(
|
|||
|
||||
entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"pypck.connection.PchkConnectionManager",
|
||||
"homeassistant.components.lcn.PchkConnectionManager",
|
||||
side_effect=lcn_connection_factory,
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
yield lcn_connection
|
||||
|
||||
return lcn_connection
|
||||
|
||||
|
||||
@pytest.fixture(name="lcn_connection")
|
||||
async def init_lcn_connection(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> MockPchkConnectionManager:
|
||||
"""Set up the LCN integration in Home Assistantand yield connection object."""
|
||||
return await init_integration(hass, entry)
|
||||
|
||||
|
||||
async def setup_component(hass: HomeAssistant) -> None:
|
||||
|
|
|
@ -91,6 +91,35 @@
|
|||
"motor": "motor1"
|
||||
}
|
||||
],
|
||||
"climates": [
|
||||
{
|
||||
"name": "Climate1",
|
||||
"address": "s0.m7",
|
||||
"source": "var1",
|
||||
"setpoint": "r1varsetpoint",
|
||||
"lockable": true,
|
||||
"min_temp": 0,
|
||||
"max_temp": 40,
|
||||
"unit_of_measurement": "°C"
|
||||
}
|
||||
],
|
||||
"scenes": [
|
||||
{
|
||||
"name": "Romantic",
|
||||
"address": "s0.m7",
|
||||
"register": 0,
|
||||
"scene": 0,
|
||||
"outputs": ["output1", "output2", "relay1"]
|
||||
},
|
||||
{
|
||||
"name": "Romantic Transition",
|
||||
"address": "s0.m7",
|
||||
"register": 0,
|
||||
"scene": 1,
|
||||
"outputs": ["output1", "output2", "relay1"],
|
||||
"transition": 10
|
||||
}
|
||||
],
|
||||
"binary_sensors": [
|
||||
{
|
||||
"name": "Sensor_LockRegulator1",
|
||||
|
|
|
@ -121,6 +121,44 @@
|
|||
"reverse_time": "RT1200"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Climate1",
|
||||
"resource": "var1.r1varsetpoint",
|
||||
"domain": "climate",
|
||||
"domain_data": {
|
||||
"source": "VAR1",
|
||||
"setpoint": "R1VARSETPOINT",
|
||||
"lockable": true,
|
||||
"min_temp": 0.0,
|
||||
"max_temp": 40.0,
|
||||
"unit_of_measurement": "°C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Romantic",
|
||||
"resource": "0.0",
|
||||
"domain": "scene",
|
||||
"domain_data": {
|
||||
"register": 0,
|
||||
"scene": 0,
|
||||
"outputs": ["OUTPUT1", "OUTPUT2", "RELAY1"],
|
||||
"transition": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Romantic Transition",
|
||||
"resource": "0.1",
|
||||
"domain": "scene",
|
||||
"domain_data": {
|
||||
"register": 0,
|
||||
"scene": 1,
|
||||
"outputs": ["OUTPUT1", "OUTPUT2", "RELAY1"],
|
||||
"transition": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"address": [0, 7, false],
|
||||
"name": "Sensor_LockRegulator1",
|
||||
|
|
63
tests/components/lcn/snapshots/test_climate.ambr
Normal file
63
tests/components/lcn/snapshots/test_climate.ambr
Normal file
|
@ -0,0 +1,63 @@
|
|||
# serializer version: 1
|
||||
# name: test_setup_lcn_climate[climate.climate1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 40.0,
|
||||
'min_temp': 0.0,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.climate1',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Climate1',
|
||||
'platform': 'lcn',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 385>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-var1.r1varsetpoint',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_lcn_climate[climate.climate1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': None,
|
||||
'friendly_name': 'Climate1',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 40.0,
|
||||
'min_temp': 0.0,
|
||||
'supported_features': <ClimateEntityFeature: 385>,
|
||||
'temperature': None,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.climate1',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
93
tests/components/lcn/snapshots/test_scene.ambr
Normal file
93
tests/components/lcn/snapshots/test_scene.ambr
Normal file
|
@ -0,0 +1,93 @@
|
|||
# serializer version: 1
|
||||
# name: test_setup_lcn_scene[scene.romantic-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'scene',
|
||||
'entity_category': None,
|
||||
'entity_id': 'scene.romantic',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Romantic',
|
||||
'platform': 'lcn',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-0.0',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_lcn_scene[scene.romantic-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Romantic',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'scene.romantic',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_lcn_scene[scene.romantic_transition-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'scene',
|
||||
'entity_category': None,
|
||||
'entity_id': 'scene.romantic_transition',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Romantic Transition',
|
||||
'platform': 'lcn',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'lcn/config_entry_pchk.json-m000007-0.1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_lcn_scene[scene.romantic_transition-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Romantic Transition',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'scene.romantic_transition',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
287
tests/components/lcn/test_climate.py
Normal file
287
tests/components/lcn/test_climate.py
Normal file
|
@ -0,0 +1,287 @@
|
|||
"""Test for the LCN climate platform."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from pypck.inputs import ModStatusVar, Unknown
|
||||
from pypck.lcn_addr import LcnAddr
|
||||
from pypck.lcn_defs import Var, VarUnit, VarValue
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
# pylint: disable=hass-component-root-import
|
||||
from homeassistant.components.climate import DOMAIN as DOMAIN_CLIMATE
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_CURRENT_TEMPERATURE,
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_TARGET_TEMP_HIGH,
|
||||
ATTR_TARGET_TEMP_LOW,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.components.lcn.helpers import get_device_connection
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_TEMPERATURE,
|
||||
STATE_UNAVAILABLE,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
|
||||
|
||||
from tests.common import snapshot_platform
|
||||
|
||||
|
||||
async def test_setup_lcn_climate(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the setup of climate."""
|
||||
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.CLIMATE]):
|
||||
await init_integration(hass, entry)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
||||
|
||||
|
||||
async def test_set_hvac_mode_heat(hass: HomeAssistant, entry: MockConfigEntry) -> None:
|
||||
"""Test the hvac mode is set to heat."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "lock_regulator") as lock_regulator:
|
||||
state = hass.states.get("climate.climate1")
|
||||
state.state = HVACMode.OFF
|
||||
|
||||
# command failed
|
||||
lock_regulator.return_value = False
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
lock_regulator.assert_awaited_with(0, False)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state != HVACMode.HEAT
|
||||
|
||||
# command success
|
||||
lock_regulator.reset_mock(return_value=True)
|
||||
lock_regulator.return_value = True
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
lock_regulator.assert_awaited_with(0, False)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.HEAT
|
||||
|
||||
|
||||
async def test_set_hvac_mode_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
|
||||
"""Test the hvac mode is set off."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "lock_regulator") as lock_regulator:
|
||||
state = hass.states.get("climate.climate1")
|
||||
state.state = HVACMode.HEAT
|
||||
|
||||
# command failed
|
||||
lock_regulator.return_value = False
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.OFF},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
lock_regulator.assert_awaited_with(0, True)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state != HVACMode.OFF
|
||||
|
||||
# command success
|
||||
lock_regulator.reset_mock(return_value=True)
|
||||
lock_regulator.return_value = True
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_HVAC_MODE: HVACMode.OFF},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
lock_regulator.assert_awaited_with(0, True)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.OFF
|
||||
|
||||
|
||||
async def test_set_temperature(hass: HomeAssistant, entry: MockConfigEntry) -> None:
|
||||
"""Test the temperature is set."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "var_abs") as var_abs:
|
||||
state = hass.states.get("climate.climate1")
|
||||
state.state = HVACMode.HEAT
|
||||
|
||||
# wrong temperature set via service call with high/low attributes
|
||||
var_abs.return_value = False
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{
|
||||
ATTR_ENTITY_ID: "climate.climate1",
|
||||
ATTR_TARGET_TEMP_LOW: 24.5,
|
||||
ATTR_TARGET_TEMP_HIGH: 25.5,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
var_abs.assert_not_awaited()
|
||||
|
||||
# command failed
|
||||
var_abs.reset_mock(return_value=True)
|
||||
var_abs.return_value = False
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_TEMPERATURE: 25.5},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
var_abs.assert_awaited_with(Var.R1VARSETPOINT, 25.5, VarUnit.CELSIUS)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.attributes[ATTR_TEMPERATURE] != 25.5
|
||||
|
||||
# command success
|
||||
var_abs.reset_mock(return_value=True)
|
||||
var_abs.return_value = True
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN_CLIMATE,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: "climate.climate1", ATTR_TEMPERATURE: 25.5},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
var_abs.assert_awaited_with(Var.R1VARSETPOINT, 25.5, VarUnit.CELSIUS)
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.attributes[ATTR_TEMPERATURE] == 25.5
|
||||
|
||||
|
||||
async def test_pushed_current_temperature_status_change(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the climate changes its current temperature on status received."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
device_connection = get_device_connection(hass, (0, 7, False), entry)
|
||||
address = LcnAddr(0, 7, False)
|
||||
|
||||
temperature = VarValue.from_celsius(25.5)
|
||||
|
||||
inp = ModStatusVar(address, Var.VAR1, temperature)
|
||||
await device_connection.async_process_input(inp)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.HEAT
|
||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 25.5
|
||||
assert state.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
async def test_pushed_setpoint_status_change(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the climate changes its setpoint on status received."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
device_connection = get_device_connection(hass, (0, 7, False), entry)
|
||||
address = LcnAddr(0, 7, False)
|
||||
|
||||
temperature = VarValue.from_celsius(25.5)
|
||||
|
||||
inp = ModStatusVar(address, Var.R1VARSETPOINT, temperature)
|
||||
await device_connection.async_process_input(inp)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.HEAT
|
||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert state.attributes[ATTR_TEMPERATURE] == 25.5
|
||||
|
||||
|
||||
async def test_pushed_lock_status_change(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the climate changes its setpoint on status received."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
device_connection = get_device_connection(hass, (0, 7, False), entry)
|
||||
address = LcnAddr(0, 7, False)
|
||||
|
||||
temperature = VarValue(0x8000)
|
||||
|
||||
inp = ModStatusVar(address, Var.R1VARSETPOINT, temperature)
|
||||
await device_connection.async_process_input(inp)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.OFF
|
||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert state.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
async def test_pushed_wrong_input(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the climate handles wrong input correctly."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
device_connection = get_device_connection(hass, (0, 7, False), entry)
|
||||
|
||||
await device_connection.async_process_input(Unknown("input"))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state.attributes[ATTR_CURRENT_TEMPERATURE] is None
|
||||
assert state.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
async def test_unload_config_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the climate is removed when the config entry is unloaded."""
|
||||
await init_integration(hass, entry)
|
||||
|
||||
await hass.config_entries.async_forward_entry_unload(entry, DOMAIN_CLIMATE)
|
||||
state = hass.states.get("climate.climate1")
|
||||
assert state.state == STATE_UNAVAILABLE
|
|
@ -32,7 +32,9 @@ async def test_async_setup_entry(hass: HomeAssistant, entry, lcn_connection) ->
|
|||
async def test_async_setup_multiple_entries(hass: HomeAssistant, entry, entry2) -> None:
|
||||
"""Test a successful setup and unload of multiple entries."""
|
||||
hass.http = Mock()
|
||||
with patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager):
|
||||
with patch(
|
||||
"homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager
|
||||
):
|
||||
for config_entry in (entry, entry2):
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
|
64
tests/components/lcn/test_scene.py
Normal file
64
tests/components/lcn/test_scene.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
"""Test for the LCN scene platform."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from pypck.lcn_defs import OutputPort, RelayPort
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.scene import DOMAIN as DOMAIN_SCENE
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
SERVICE_TURN_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
|
||||
|
||||
from tests.common import snapshot_platform
|
||||
|
||||
|
||||
async def test_setup_lcn_scene(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the setup of switch."""
|
||||
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.SCENE]):
|
||||
await init_integration(hass, entry)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
||||
|
||||
|
||||
async def test_scene_activate(
|
||||
hass: HomeAssistant,
|
||||
entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the scene is activated."""
|
||||
await init_integration(hass, entry)
|
||||
with patch.object(MockModuleConnection, "activate_scene") as activate_scene:
|
||||
await hass.services.async_call(
|
||||
DOMAIN_SCENE,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "scene.romantic"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
state = hass.states.get("scene.romantic")
|
||||
assert state is not None
|
||||
|
||||
activate_scene.assert_awaited_with(
|
||||
0, 0, [OutputPort.OUTPUT1, OutputPort.OUTPUT2], [RelayPort.RELAY1], None
|
||||
)
|
||||
|
||||
|
||||
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
|
||||
"""Test the scene is removed when the config entry is unloaded."""
|
||||
await init_integration(hass, entry)
|
||||
await hass.config_entries.async_forward_entry_unload(entry, DOMAIN_SCENE)
|
||||
|
||||
state = hass.states.get("scene.romantic")
|
||||
assert state.state == STATE_UNAVAILABLE
|
|
@ -32,16 +32,21 @@ from homeassistant.const import (
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .conftest import MockModuleConnection, MockPchkConnectionManager, setup_component
|
||||
from .conftest import (
|
||||
MockConfigEntry,
|
||||
MockModuleConnection,
|
||||
MockPchkConnectionManager,
|
||||
init_integration,
|
||||
)
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_output_abs(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test output_abs service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "dim_output") as dim_output:
|
||||
await hass.services.async_call(
|
||||
|
@ -59,13 +64,13 @@ async def test_service_output_abs(
|
|||
assert dim_output.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_output_rel(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test output_rel service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "rel_output") as rel_output:
|
||||
await hass.services.async_call(
|
||||
|
@ -82,13 +87,13 @@ async def test_service_output_rel(
|
|||
assert rel_output.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_output_toggle(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test output_toggle service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "toggle_output") as toggle_output:
|
||||
await hass.services.async_call(
|
||||
|
@ -105,11 +110,13 @@ async def test_service_output_toggle(
|
|||
assert toggle_output.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_relays(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_relays(
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test relays service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "control_relays") as control_relays:
|
||||
await hass.services.async_call(
|
||||
|
@ -122,11 +129,13 @@ async def test_service_relays(hass: HomeAssistant, snapshot: SnapshotAssertion)
|
|||
assert control_relays.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_led(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_led(
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test led service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "control_led") as control_led:
|
||||
await hass.services.async_call(
|
||||
|
@ -139,13 +148,13 @@ async def test_service_led(hass: HomeAssistant, snapshot: SnapshotAssertion) ->
|
|||
assert control_led.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_var_abs(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test var_abs service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "var_abs") as var_abs:
|
||||
await hass.services.async_call(
|
||||
|
@ -163,13 +172,13 @@ async def test_service_var_abs(
|
|||
assert var_abs.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_var_rel(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test var_rel service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "var_rel") as var_rel:
|
||||
await hass.services.async_call(
|
||||
|
@ -188,13 +197,13 @@ async def test_service_var_rel(
|
|||
assert var_rel.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_var_reset(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test var_reset service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "var_reset") as var_reset:
|
||||
await hass.services.async_call(
|
||||
|
@ -207,13 +216,13 @@ async def test_service_var_reset(
|
|||
assert var_reset.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_lock_regulator(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test lock_regulator service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "lock_regulator") as lock_regulator:
|
||||
await hass.services.async_call(
|
||||
|
@ -230,13 +239,13 @@ async def test_service_lock_regulator(
|
|||
assert lock_regulator.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_send_keys(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test send_keys service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "send_keys") as send_keys:
|
||||
await hass.services.async_call(
|
||||
|
@ -254,13 +263,13 @@ async def test_service_send_keys(
|
|||
assert send_keys.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_send_keys_hit_deferred(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test send_keys (hit_deferred) service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
keys = [[False] * 8 for i in range(4)]
|
||||
keys[0][0] = True
|
||||
|
@ -306,13 +315,13 @@ async def test_service_send_keys_hit_deferred(
|
|||
)
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_lock_keys(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test lock_keys service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "lock_keys") as lock_keys:
|
||||
await hass.services.async_call(
|
||||
|
@ -325,13 +334,13 @@ async def test_service_lock_keys(
|
|||
assert lock_keys.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_lock_keys_tab_a_temporary(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test lock_keys (tab_a_temporary) service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
# success
|
||||
with patch.object(
|
||||
|
@ -372,13 +381,13 @@ async def test_service_lock_keys_tab_a_temporary(
|
|||
)
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_dyn_text(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test dyn_text service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "dyn_text") as dyn_text:
|
||||
await hass.services.async_call(
|
||||
|
@ -391,11 +400,13 @@ async def test_service_dyn_text(
|
|||
assert dyn_text.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_pck(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_pck(
|
||||
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test pck service."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "pck") as pck:
|
||||
await hass.services.async_call(
|
||||
|
@ -408,11 +419,13 @@ async def test_service_pck(hass: HomeAssistant, snapshot: SnapshotAssertion) ->
|
|||
assert pck.await_args.args == snapshot()
|
||||
|
||||
|
||||
@patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_called_with_invalid_host_id(hass: HomeAssistant) -> None:
|
||||
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
|
||||
async def test_service_called_with_invalid_host_id(
|
||||
hass: HomeAssistant, entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Test service was called with non existing host id."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await setup_component(hass)
|
||||
await init_integration(hass, entry)
|
||||
|
||||
with patch.object(MockModuleConnection, "pck") as pck, pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
|
|
Loading…
Add table
Reference in a new issue