Clean up tests for LCN (#125493)

* Remove patches on 3rd party module level

* Cleanup test_init

* Cleanup platform tests

* Cleanup test_services

* Cleanup test_websockets

* Cleanup test_device_trigger

* Cleanup test_events

* Remove unused fixture
This commit is contained in:
Andre Lengwenus 2024-09-08 09:20:57 +02:00 committed by GitHub
parent 03a6eb26be
commit 5e1b4b2d23
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 1715 additions and 1118 deletions

View file

@ -25,6 +25,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType
from . import PchkConnectionManager
from .const import CONF_DIM_MODE, CONF_SK_NUM_TRIES, DIM_MODES, DOMAIN
from .helpers import purge_device_registry, purge_entity_registry
@ -78,7 +79,7 @@ async def validate_connection(data: ConfigType) -> str | None:
_LOGGER.debug("Validating connection parameters to PCHK host '%s'", host_name)
connection = pypck.connection.PchkConnectionManager(
connection = PchkConnectionManager(
host, port, username, password, settings=settings
)

View file

@ -53,12 +53,20 @@ class MockPchkConnectionManager(PchkConnectionManager):
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)
@patch.object(pypck.connection, "ModuleConnection", MockModuleConnection)
def get_module_conn(self, addr, request_serials=False):
"""Get LCN module connection."""
return super().get_module_conn(addr, request_serials)
@patch.object(pypck.connection, "GroupConnection", MockGroupConnection)
def get_group_conn(self, addr):
"""Get LCN group connection."""
return super().get_group_conn(addr)
scan_modules = AsyncMock()
send_command = AsyncMock()
@ -119,15 +127,6 @@ async def init_integration(
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:
"""Set up the LCN component."""
fixture_filename = "lcn/config.json"

View file

@ -0,0 +1,139 @@
# serializer version: 1
# name: test_setup_lcn_binary_sensor[binary_sensor.binary_sensor1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.binary_sensor1',
'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': 'Binary_Sensor1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-binsensor1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_binary_sensor[binary_sensor.binary_sensor1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Binary_Sensor1',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.binary_sensor1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup_lcn_binary_sensor[binary_sensor.sensor_keylock-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.sensor_keylock',
'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': 'Sensor_KeyLock',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-a5',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_binary_sensor[binary_sensor.sensor_keylock-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_KeyLock',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.sensor_keylock',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup_lcn_binary_sensor[binary_sensor.sensor_lockregulator1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.sensor_lockregulator1',
'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': 'Sensor_LockRegulator1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-r1varsetpoint',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_binary_sensor[binary_sensor.sensor_lockregulator1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_LockRegulator1',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.sensor_lockregulator1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---

View file

@ -0,0 +1,97 @@
# serializer version: 1
# name: test_setup_lcn_cover[cover.cover_outputs-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'cover',
'entity_category': None,
'entity_id': 'cover.cover_outputs',
'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': 'Cover_Outputs',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': <CoverEntityFeature: 11>,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-outputs',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_cover[cover.cover_outputs-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'assumed_state': True,
'friendly_name': 'Cover_Outputs',
'supported_features': <CoverEntityFeature: 11>,
}),
'context': <ANY>,
'entity_id': 'cover.cover_outputs',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'open',
})
# ---
# name: test_setup_lcn_cover[cover.cover_relays-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'cover',
'entity_category': None,
'entity_id': 'cover.cover_relays',
'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': 'Cover_Relays',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': <CoverEntityFeature: 11>,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-motor1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_cover[cover.cover_relays-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'assumed_state': True,
'friendly_name': 'Cover_Relays',
'supported_features': <CoverEntityFeature: 11>,
}),
'context': <ANY>,
'entity_id': 'cover.cover_relays',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'open',
})
# ---

View file

@ -0,0 +1,167 @@
# serializer version: 1
# name: test_setup_lcn_light[light.light_output1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'supported_color_modes': list([
<ColorMode.BRIGHTNESS: 'brightness'>,
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'light',
'entity_category': None,
'entity_id': 'light.light_output1',
'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': 'Light_Output1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': <LightEntityFeature: 32>,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-output1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_light[light.light_output1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'brightness': None,
'color_mode': None,
'friendly_name': 'Light_Output1',
'supported_color_modes': list([
<ColorMode.BRIGHTNESS: 'brightness'>,
]),
'supported_features': <LightEntityFeature: 32>,
}),
'context': <ANY>,
'entity_id': 'light.light_output1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_light[light.light_output2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'supported_color_modes': list([
<ColorMode.ONOFF: 'onoff'>,
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'light',
'entity_category': None,
'entity_id': 'light.light_output2',
'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': 'Light_Output2',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': <LightEntityFeature: 32>,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-output2',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_light[light.light_output2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'color_mode': None,
'friendly_name': 'Light_Output2',
'supported_color_modes': list([
<ColorMode.ONOFF: 'onoff'>,
]),
'supported_features': <LightEntityFeature: 32>,
}),
'context': <ANY>,
'entity_id': 'light.light_output2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_light[light.light_relay1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'supported_color_modes': list([
<ColorMode.ONOFF: 'onoff'>,
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'light',
'entity_category': None,
'entity_id': 'light.light_relay1',
'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': 'Light_Relay1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_light[light.light_relay1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'color_mode': None,
'friendly_name': 'Light_Relay1',
'supported_color_modes': list([
<ColorMode.ONOFF: 'onoff'>,
]),
'supported_features': <LightEntityFeature: 0>,
}),
'context': <ANY>,
'entity_id': 'light.light_relay1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---

View file

@ -0,0 +1,187 @@
# serializer version: 1
# name: test_setup_lcn_sensor[sensor.sensor_led6-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.sensor_led6',
'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': 'Sensor_Led6',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-led6',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_led6-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_Led6',
}),
'context': <ANY>,
'entity_id': 'sensor.sensor_led6',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_logicop1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.sensor_logicop1',
'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': 'Sensor_LogicOp1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-logicop1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_logicop1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_LogicOp1',
}),
'context': <ANY>,
'entity_id': 'sensor.sensor_logicop1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_setpoint1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.sensor_setpoint1',
'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': 'Sensor_Setpoint1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-r1varsetpoint',
'unit_of_measurement': '°C',
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_setpoint1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_Setpoint1',
'unit_of_measurement': '°C',
}),
'context': <ANY>,
'entity_id': 'sensor.sensor_setpoint1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_var1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.sensor_var1',
'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': 'Sensor_Var1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-var1',
'unit_of_measurement': '°C',
})
# ---
# name: test_setup_lcn_sensor[sensor.sensor_var1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Sensor_Var1',
'unit_of_measurement': '°C',
}),
'context': <ANY>,
'entity_id': 'sensor.sensor_var1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---

View file

@ -1,203 +0,0 @@
# serializer version: 1
# name: test_service_dyn_text
tuple(
0,
'text in row 1',
)
# ---
# name: test_service_led
tuple(
<LedPort.LED6: 5>,
<LedStatus.BLINK: 'B'>,
)
# ---
# name: test_service_lock_keys
tuple(
0,
list([
<KeyLockStateModifier.OFF: '0'>,
<KeyLockStateModifier.OFF: '0'>,
<KeyLockStateModifier.ON: '1'>,
<KeyLockStateModifier.ON: '1'>,
<KeyLockStateModifier.TOGGLE: 'U'>,
<KeyLockStateModifier.TOGGLE: 'U'>,
<KeyLockStateModifier.NOCHANGE: '-'>,
<KeyLockStateModifier.NOCHANGE: '-'>,
]),
)
# ---
# name: test_service_lock_keys_tab_a_temporary
tuple(
10,
<TimeUnit.SECONDS: 'S'>,
list([
<KeyLockStateModifier.OFF: '0'>,
<KeyLockStateModifier.OFF: '0'>,
<KeyLockStateModifier.ON: '1'>,
<KeyLockStateModifier.ON: '1'>,
<KeyLockStateModifier.TOGGLE: 'U'>,
<KeyLockStateModifier.TOGGLE: 'U'>,
<KeyLockStateModifier.NOCHANGE: '-'>,
<KeyLockStateModifier.NOCHANGE: '-'>,
]),
)
# ---
# name: test_service_lock_regulator
tuple(
0,
True,
)
# ---
# name: test_service_output_abs
tuple(
0,
100,
9,
)
# ---
# name: test_service_output_rel
tuple(
0,
25,
)
# ---
# name: test_service_output_toggle
tuple(
0,
9,
)
# ---
# name: test_service_pck
tuple(
'PIN4',
)
# ---
# name: test_service_relays
tuple(
list([
<RelayStateModifier.OFF: '0'>,
<RelayStateModifier.OFF: '0'>,
<RelayStateModifier.ON: '1'>,
<RelayStateModifier.ON: '1'>,
<RelayStateModifier.TOGGLE: 'U'>,
<RelayStateModifier.TOGGLE: 'U'>,
<RelayStateModifier.NOCHANGE: '-'>,
<RelayStateModifier.NOCHANGE: '-'>,
]),
)
# ---
# name: test_service_send_keys
tuple(
list([
list([
True,
False,
False,
False,
True,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
True,
]),
]),
<SendKeyCommand.HIT: 'K'>,
)
# ---
# name: test_service_send_keys_hit_deferred
tuple(
list([
list([
True,
False,
False,
False,
True,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
False,
]),
list([
False,
False,
False,
False,
False,
False,
False,
True,
]),
]),
5,
<TimeUnit.SECONDS: 'S'>,
)
# ---
# name: test_service_var_abs
tuple(
<Var.VAR1ORTVAR: 0>,
75.0,
<VarUnit.PERCENT: '%'>,
)
# ---
# name: test_service_var_rel
tuple(
<Var.VAR1ORTVAR: 0>,
10.0,
<VarUnit.PERCENT: '%'>,
<RelVarRef.CURRENT: 1>,
)
# ---
# name: test_service_var_reset
tuple(
<Var.VAR1ORTVAR: 0>,
)
# ---

View file

@ -0,0 +1,231 @@
# serializer version: 1
# name: test_setup_lcn_switch[switch.switch_group5-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.switch_group5',
'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': 'Switch_Group5',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-g000005-relay1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_switch[switch.switch_group5-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Switch_Group5',
}),
'context': <ANY>,
'entity_id': 'switch.switch_group5',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_switch[switch.switch_output1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.switch_output1',
'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': 'Switch_Output1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-output1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_switch[switch.switch_output1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Switch_Output1',
}),
'context': <ANY>,
'entity_id': 'switch.switch_output1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_switch[switch.switch_output2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.switch_output2',
'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': 'Switch_Output2',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-output2',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_switch[switch.switch_output2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Switch_Output2',
}),
'context': <ANY>,
'entity_id': 'switch.switch_output2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_switch[switch.switch_relay1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.switch_relay1',
'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': 'Switch_Relay1',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay1',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_switch[switch.switch_relay1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Switch_Relay1',
}),
'context': <ANY>,
'entity_id': 'switch.switch_relay1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_setup_lcn_switch[switch.switch_relay2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.switch_relay2',
'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': 'Switch_Relay2',
'platform': 'lcn',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'lcn/config_entry_pchk.json-m000007-relay2',
'unit_of_measurement': None,
})
# ---
# name: test_setup_lcn_switch[switch.switch_relay2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Switch_Relay2',
}),
'context': <ANY>,
'entity_id': 'switch.switch_relay2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---

View file

@ -1,68 +1,46 @@
"""Test for the LCN binary sensor platform."""
from unittest.mock import patch
from pypck.inputs import ModStatusBinSensors, ModStatusKeyLocks, ModStatusVar
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import Var, VarValue
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.lcn.helpers import get_device_connection
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import MockConfigEntry, init_integration
from tests.common import snapshot_platform
BINARY_SENSOR_LOCKREGULATOR1 = "binary_sensor.sensor_lockregulator1"
BINARY_SENSOR_SENSOR1 = "binary_sensor.binary_sensor1"
BINARY_SENSOR_KEYLOCK = "binary_sensor.sensor_keylock"
async def test_setup_lcn_binary_sensor(hass: HomeAssistant, lcn_connection) -> None:
"""Test the setup of binary sensor."""
for entity_id in (
BINARY_SENSOR_LOCKREGULATOR1,
BINARY_SENSOR_SENSOR1,
BINARY_SENSOR_KEYLOCK,
):
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_entity_state(hass: HomeAssistant, lcn_connection) -> None:
"""Test state of entity."""
state = hass.states.get(BINARY_SENSOR_LOCKREGULATOR1)
assert state
state = hass.states.get(BINARY_SENSOR_SENSOR1)
assert state
state = hass.states.get(BINARY_SENSOR_KEYLOCK)
assert state
async def test_entity_attributes(
hass: HomeAssistant, entity_registry: er.EntityRegistry, entry, lcn_connection
async def test_setup_lcn_binary_sensor(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the attributes of an entity."""
"""Test the setup of binary sensor."""
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.BINARY_SENSOR]):
await init_integration(hass, entry)
entity_setpoint1 = entity_registry.async_get(BINARY_SENSOR_LOCKREGULATOR1)
assert entity_setpoint1
assert entity_setpoint1.unique_id == f"{entry.entry_id}-m000007-r1varsetpoint"
assert entity_setpoint1.original_name == "Sensor_LockRegulator1"
entity_binsensor1 = entity_registry.async_get(BINARY_SENSOR_SENSOR1)
assert entity_binsensor1
assert entity_binsensor1.unique_id == f"{entry.entry_id}-m000007-binsensor1"
assert entity_binsensor1.original_name == "Binary_Sensor1"
entity_keylock = entity_registry.async_get(BINARY_SENSOR_KEYLOCK)
assert entity_keylock
assert entity_keylock.unique_id == f"{entry.entry_id}-m000007-a5"
assert entity_keylock.original_name == "Sensor_KeyLock"
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_pushed_lock_setpoint_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant,
entry: MockConfigEntry,
) -> None:
"""Test the lock setpoint sensor changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -86,9 +64,11 @@ async def test_pushed_lock_setpoint_status_change(
async def test_pushed_binsensor_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the binary port sensor changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
states = [False] * 8
@ -114,9 +94,11 @@ async def test_pushed_binsensor_status_change(
async def test_pushed_keylock_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the keylock sensor changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
states = [[False] * 8 for i in range(4)]
@ -141,8 +123,10 @@ async def test_pushed_keylock_status_change(
assert state.state == STATE_ON
async def test_unload_config_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the binary sensor is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
assert hass.states.get(BINARY_SENSOR_LOCKREGULATOR1).state == STATE_UNAVAILABLE
assert hass.states.get(BINARY_SENSOR_SENSOR1).state == STATE_UNAVAILABLE

View file

@ -282,6 +282,6 @@ async def test_unload_config_entry(
"""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)
await hass.config_entries.async_unload(entry.entry_id)
state = hass.states.get("climate.climate1")
assert state.state == STATE_UNAVAILABLE

View file

@ -48,7 +48,7 @@ async def test_step_import(
"""Test for import step."""
with (
patch("pypck.connection.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.async_setup", return_value=True),
patch("homeassistant.components.lcn.async_setup_entry", return_value=True),
):
@ -76,7 +76,7 @@ async def test_step_import_existing_host(
mock_entry = MockConfigEntry(domain=DOMAIN, data=mock_data)
mock_entry.add_to_hass(hass)
# Initialize a config flow with different data but same host address
with patch("pypck.connection.PchkConnectionManager.async_connect"):
with patch("homeassistant.components.lcn.PchkConnectionManager.async_connect"):
imported_data = IMPORT_DATA.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=imported_data
@ -105,7 +105,8 @@ async def test_step_import_error(
) -> None:
"""Test for error in import is handled correctly."""
with patch(
"pypck.connection.PchkConnectionManager.async_connect", side_effect=error
"homeassistant.components.lcn.PchkConnectionManager.async_connect",
side_effect=error,
):
data = IMPORT_DATA.copy()
data.update({CONF_HOST: "pchk"})
@ -132,7 +133,7 @@ async def test_show_form(hass: HomeAssistant) -> None:
async def test_step_user(hass: HomeAssistant) -> None:
"""Test for user step."""
with (
patch("pypck.connection.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.async_setup", return_value=True),
patch("homeassistant.components.lcn.async_setup_entry", return_value=True),
):
@ -156,7 +157,7 @@ async def test_step_user_existing_host(
"""Test for user defined host already exists."""
entry.add_to_hass(hass)
with patch("pypck.connection.PchkConnectionManager.async_connect"):
with patch("homeassistant.components.lcn.PchkConnectionManager.async_connect"):
config_data = entry.data.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=config_data
@ -179,7 +180,8 @@ async def test_step_user_error(
) -> None:
"""Test for error in user step is handled correctly."""
with patch(
"pypck.connection.PchkConnectionManager.async_connect", side_effect=error
"homeassistant.components.lcn.PchkConnectionManager.async_connect",
side_effect=error,
):
data = CONNECTION_DATA.copy()
data.update({CONF_HOST: "pchk"})
@ -197,7 +199,7 @@ async def test_step_reconfigure(hass: HomeAssistant, entry: MockConfigEntry) ->
old_entry_data = entry.data.copy()
with (
patch("pypck.connection.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.PchkConnectionManager.async_connect"),
patch("homeassistant.components.lcn.async_setup", return_value=True),
patch("homeassistant.components.lcn.async_setup_entry", return_value=True),
):
@ -235,7 +237,8 @@ async def test_step_reconfigure_error(
"""Test for error in reconfigure step is handled correctly."""
entry.add_to_hass(hass)
with patch(
"pypck.connection.PchkConnectionManager.async_connect", side_effect=error
"homeassistant.components.lcn.PchkConnectionManager.async_connect",
side_effect=error,
):
data = {**CONNECTION_DATA, CONF_HOST: "pchk"}
result = await hass.config_entries.flow.async_init(
@ -256,8 +259,12 @@ async def test_validate_connection() -> None:
data = CONNECTION_DATA.copy()
with (
patch("pypck.connection.PchkConnectionManager.async_connect") as async_connect,
patch("pypck.connection.PchkConnectionManager.async_close") as async_close,
patch(
"homeassistant.components.lcn.PchkConnectionManager.async_connect"
) as async_connect,
patch(
"homeassistant.components.lcn.PchkConnectionManager.async_close"
) as async_close,
):
result = await validate_connection(data=data)

View file

@ -5,6 +5,7 @@ from unittest.mock import patch
from pypck.inputs import ModStatusOutput, ModStatusRelays
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import MotorReverseTime, MotorStateModifier
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.cover import DOMAIN as DOMAIN_COVER
from homeassistant.components.lcn.helpers import get_device_connection
@ -18,318 +19,319 @@ from homeassistant.const import (
STATE_OPEN,
STATE_OPENING,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import MockModuleConnection
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
from tests.common import snapshot_platform
COVER_OUTPUTS = "cover.cover_outputs"
COVER_RELAYS = "cover.cover_relays"
async def test_setup_lcn_cover(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_setup_lcn_cover(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the setup of cover."""
for entity_id in (
COVER_OUTPUTS,
COVER_RELAYS,
):
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_OPEN
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.COVER]):
await init_integration(hass, entry)
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_entity_attributes(
hass: HomeAssistant, entity_registry: er.EntityRegistry, entry, lcn_connection
) -> None:
"""Test the attributes of an entity."""
entity_outputs = entity_registry.async_get(COVER_OUTPUTS)
assert entity_outputs
assert entity_outputs.unique_id == f"{entry.entry_id}-m000007-outputs"
assert entity_outputs.original_name == "Cover_Outputs"
entity_relays = entity_registry.async_get(COVER_RELAYS)
assert entity_relays
assert entity_relays.unique_id == f"{entry.entry_id}-m000007-motor1"
assert entity_relays.original_name == "Cover_Relays"
@patch.object(MockModuleConnection, "control_motors_outputs")
async def test_outputs_open(
control_motors_outputs, hass: HomeAssistant, lcn_connection
) -> None:
async def test_outputs_open(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the outputs cover opens."""
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_CLOSED
await init_integration(hass, entry)
# command failed
control_motors_outputs.return_value = False
with patch.object(
MockModuleConnection, "control_motors_outputs"
) as control_motors_outputs:
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_CLOSED
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(
MotorStateModifier.UP, MotorReverseTime.RT1200
)
# command failed
control_motors_outputs.return_value = False
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state != STATE_OPENING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
control_motors_outputs.assert_awaited_with(
MotorStateModifier.UP, MotorReverseTime.RT1200
)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(
MotorStateModifier.UP, MotorReverseTime.RT1200
)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state != STATE_OPENING
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_OPENING
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
control_motors_outputs.assert_awaited_with(
MotorStateModifier.UP, MotorReverseTime.RT1200
)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_OPENING
@patch.object(MockModuleConnection, "control_motors_outputs")
async def test_outputs_close(
control_motors_outputs, hass: HomeAssistant, lcn_connection
) -> None:
async def test_outputs_close(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the outputs cover closes."""
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_OPEN
await init_integration(hass, entry)
# command failed
control_motors_outputs.return_value = False
with patch.object(
MockModuleConnection, "control_motors_outputs"
) as control_motors_outputs:
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_OPEN
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(
MotorStateModifier.DOWN, MotorReverseTime.RT1200
)
# command failed
control_motors_outputs.return_value = False
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state != STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
control_motors_outputs.assert_awaited_with(
MotorStateModifier.DOWN, MotorReverseTime.RT1200
)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(
MotorStateModifier.DOWN, MotorReverseTime.RT1200
)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state != STATE_CLOSING
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_CLOSING
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
control_motors_outputs.assert_awaited_with(
MotorStateModifier.DOWN, MotorReverseTime.RT1200
)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_CLOSING
@patch.object(MockModuleConnection, "control_motors_outputs")
async def test_outputs_stop(
control_motors_outputs, hass: HomeAssistant, lcn_connection
) -> None:
async def test_outputs_stop(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the outputs cover stops."""
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_CLOSING
await init_integration(hass, entry)
# command failed
control_motors_outputs.return_value = False
with patch.object(
MockModuleConnection, "control_motors_outputs"
) as control_motors_outputs:
state = hass.states.get(COVER_OUTPUTS)
state.state = STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(MotorStateModifier.STOP)
# command failed
control_motors_outputs.return_value = False
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
control_motors_outputs.assert_awaited_with(MotorStateModifier.STOP)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_outputs.assert_awaited_with(MotorStateModifier.STOP)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state == STATE_CLOSING
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state not in (STATE_CLOSING, STATE_OPENING)
# command success
control_motors_outputs.reset_mock(return_value=True)
control_motors_outputs.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_OUTPUTS},
blocking=True,
)
control_motors_outputs.assert_awaited_with(MotorStateModifier.STOP)
state = hass.states.get(COVER_OUTPUTS)
assert state is not None
assert state.state not in (STATE_CLOSING, STATE_OPENING)
@patch.object(MockModuleConnection, "control_motors_relays")
async def test_relays_open(
control_motors_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relays_open(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relays cover opens."""
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.UP
await init_integration(hass, entry)
state = hass.states.get(COVER_RELAYS)
state.state = STATE_CLOSED
with patch.object(
MockModuleConnection, "control_motors_relays"
) as control_motors_relays:
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.UP
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
state.state = STATE_CLOSED
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state != STATE_OPENING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
control_motors_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state != STATE_OPENING
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_OPENING
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_OPENING
@patch.object(MockModuleConnection, "control_motors_relays")
async def test_relays_close(
control_motors_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relays_close(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relays cover closes."""
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.DOWN
await init_integration(hass, entry)
state = hass.states.get(COVER_RELAYS)
state.state = STATE_OPEN
with patch.object(
MockModuleConnection, "control_motors_relays"
) as control_motors_relays:
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.DOWN
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
state.state = STATE_OPEN
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state != STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
control_motors_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state != STATE_CLOSING
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_CLOSING
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_CLOSING
@patch.object(MockModuleConnection, "control_motors_relays")
async def test_relays_stop(
control_motors_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relays_stop(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relays cover stops."""
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.STOP
await init_integration(hass, entry)
state = hass.states.get(COVER_RELAYS)
state.state = STATE_CLOSING
with patch.object(
MockModuleConnection, "control_motors_relays"
) as control_motors_relays:
states = [MotorStateModifier.NOCHANGE] * 4
states[0] = MotorStateModifier.STOP
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
state.state = STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
# command failed
control_motors_relays.return_value = False
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_CLOSING
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
control_motors_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
await hass.async_block_till_done()
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state == STATE_CLOSING
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state not in (STATE_CLOSING, STATE_OPENING)
# command success
control_motors_relays.reset_mock(return_value=True)
control_motors_relays.return_value = True
await hass.services.async_call(
DOMAIN_COVER,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: COVER_RELAYS},
blocking=True,
)
control_motors_relays.assert_awaited_with(states)
state = hass.states.get(COVER_RELAYS)
assert state is not None
assert state.state not in (STATE_CLOSING, STATE_OPENING)
async def test_pushed_outputs_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the outputs cover changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -365,9 +367,11 @@ async def test_pushed_outputs_status_change(
async def test_pushed_relays_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the relays cover changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
states = [False] * 8
@ -406,8 +410,10 @@ async def test_pushed_relays_status_change(
assert state.state == STATE_CLOSING
async def test_unload_config_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the cover is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
assert hass.states.get(COVER_OUTPUTS).state == STATE_UNAVAILABLE
assert hass.states.get(COVER_RELAYS).state == STATE_UNAVAILABLE

View file

@ -15,15 +15,17 @@ from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.setup import async_setup_component
from .conftest import get_device
from .conftest import MockConfigEntry, get_device, init_integration
from tests.common import async_get_device_automations
async def test_get_triggers_module_device(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get the expected triggers from a LCN module device."""
await init_integration(hass, entry)
device = get_device(hass, entry, (0, 7, False))
expected_triggers = [
@ -50,9 +52,11 @@ async def test_get_triggers_module_device(
async def test_get_triggers_non_module_device(
hass: HomeAssistant, device_registry: dr.DeviceRegistry, entry, lcn_connection
hass: HomeAssistant, device_registry: dr.DeviceRegistry, entry: MockConfigEntry
) -> None:
"""Test we get the expected triggers from a LCN non-module device."""
await init_integration(hass, entry)
not_included_types = ("transmitter", "transponder", "fingerprint", "send_keys")
host_device = device_registry.async_get_device(
@ -72,9 +76,10 @@ async def test_get_triggers_non_module_device(
async def test_if_fires_on_transponder_event(
hass: HomeAssistant, service_calls: list[ServiceCall], entry, lcn_connection
hass: HomeAssistant, service_calls: list[ServiceCall], entry: MockConfigEntry
) -> None:
"""Test for transponder event triggers firing."""
lcn_connection = await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -119,9 +124,10 @@ async def test_if_fires_on_transponder_event(
async def test_if_fires_on_fingerprint_event(
hass: HomeAssistant, service_calls: list[ServiceCall], entry, lcn_connection
hass: HomeAssistant, service_calls: list[ServiceCall], entry: MockConfigEntry
) -> None:
"""Test for fingerprint event triggers firing."""
lcn_connection = await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -166,9 +172,10 @@ async def test_if_fires_on_fingerprint_event(
async def test_if_fires_on_codelock_event(
hass: HomeAssistant, service_calls: list[ServiceCall], entry, lcn_connection
hass: HomeAssistant, service_calls: list[ServiceCall], entry: MockConfigEntry
) -> None:
"""Test for codelock event triggers firing."""
lcn_connection = await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -213,9 +220,10 @@ async def test_if_fires_on_codelock_event(
async def test_if_fires_on_transmitter_event(
hass: HomeAssistant, service_calls: list[ServiceCall], entry, lcn_connection
hass: HomeAssistant, service_calls: list[ServiceCall], entry: MockConfigEntry
) -> None:
"""Test for transmitter event triggers firing."""
lcn_connection = await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -269,9 +277,10 @@ async def test_if_fires_on_transmitter_event(
async def test_if_fires_on_send_keys_event(
hass: HomeAssistant, service_calls: list[ServiceCall], entry, lcn_connection
hass: HomeAssistant, service_calls: list[ServiceCall], entry: MockConfigEntry
) -> None:
"""Test for send_keys event triggers firing."""
lcn_connection = await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -318,9 +327,10 @@ async def test_if_fires_on_send_keys_event(
async def test_get_transponder_trigger_capabilities(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get the expected capabilities from a transponder device trigger."""
await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -341,9 +351,10 @@ async def test_get_transponder_trigger_capabilities(
async def test_get_fingerprint_trigger_capabilities(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get the expected capabilities from a fingerprint device trigger."""
await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -364,9 +375,10 @@ async def test_get_fingerprint_trigger_capabilities(
async def test_get_transmitter_trigger_capabilities(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get the expected capabilities from a transmitter device trigger."""
await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -397,9 +409,10 @@ async def test_get_transmitter_trigger_capabilities(
async def test_get_send_keys_trigger_capabilities(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get the expected capabilities from a send_keys device trigger."""
await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)
@ -435,9 +448,10 @@ async def test_get_send_keys_trigger_capabilities(
async def test_unknown_trigger_capabilities(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test we get empty capabilities if trigger is unknown."""
await init_integration(hass, entry)
address = (0, 7, False)
device = get_device(hass, entry, address)

View file

@ -3,10 +3,11 @@
from pypck.inputs import Input, ModSendKeysHost, ModStatusAccessControl
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import AccessControlPeriphery, KeyAction, SendKeyCommand
import pytest
from homeassistant.core import HomeAssistant
from .conftest import MockConfigEntry, init_integration
from tests.common import async_capture_events
LCN_TRANSPONDER = "lcn_transponder"
@ -15,8 +16,11 @@ LCN_TRANSMITTER = "lcn_transmitter"
LCN_SEND_KEYS = "lcn_send_keys"
async def test_fire_transponder_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_fire_transponder_event(
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the transponder event is fired."""
lcn_connection = await init_integration(hass, entry)
events = async_capture_events(hass, LCN_TRANSPONDER)
inp = ModStatusAccessControl(
@ -33,8 +37,11 @@ async def test_fire_transponder_event(hass: HomeAssistant, lcn_connection) -> No
assert events[0].data["code"] == "aabbcc"
async def test_fire_fingerprint_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_fire_fingerprint_event(
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the fingerprint event is fired."""
lcn_connection = await init_integration(hass, entry)
events = async_capture_events(hass, LCN_FINGERPRINT)
inp = ModStatusAccessControl(
@ -51,8 +58,9 @@ async def test_fire_fingerprint_event(hass: HomeAssistant, lcn_connection) -> No
assert events[0].data["code"] == "aabbcc"
async def test_fire_codelock_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_fire_codelock_event(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the codelock event is fired."""
lcn_connection = await init_integration(hass, entry)
events = async_capture_events(hass, "lcn_codelock")
inp = ModStatusAccessControl(
@ -69,8 +77,11 @@ async def test_fire_codelock_event(hass: HomeAssistant, lcn_connection) -> None:
assert events[0].data["code"] == "aabbcc"
async def test_fire_transmitter_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_fire_transmitter_event(
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the transmitter event is fired."""
lcn_connection = await init_integration(hass, entry)
events = async_capture_events(hass, LCN_TRANSMITTER)
inp = ModStatusAccessControl(
@ -93,8 +104,9 @@ async def test_fire_transmitter_event(hass: HomeAssistant, lcn_connection) -> No
assert events[0].data["action"] == "hit"
async def test_fire_sendkeys_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_fire_sendkeys_event(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the send_keys event is fired."""
lcn_connection = await init_integration(hass, entry)
events = async_capture_events(hass, LCN_SEND_KEYS)
inp = ModSendKeysHost(
@ -122,9 +134,10 @@ async def test_fire_sendkeys_event(hass: HomeAssistant, lcn_connection) -> None:
async def test_dont_fire_on_non_module_input(
hass: HomeAssistant, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test for no event is fired if a non-module input is received."""
lcn_connection = await init_integration(hass, entry)
inp = Input()
for event_name in (
@ -139,16 +152,16 @@ async def test_dont_fire_on_non_module_input(
assert len(events) == 0
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_dont_fire_on_unknown_module(hass: HomeAssistant, lcn_connection) -> None:
async def test_dont_fire_on_unknown_module(
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test for no event is fired if an input from an unknown module is received."""
lcn_connection = await init_integration(hass, entry)
inp = ModStatusAccessControl(
LcnAddr(0, 10, False), # unknown module
periphery=AccessControlPeriphery.FINGERPRINT,
code="aabbcc",
)
events = async_capture_events(hass, LCN_FINGERPRINT)
await lcn_connection.async_process_input(inp)
await hass.async_block_till_done()

View file

@ -2,11 +2,8 @@
from unittest.mock import Mock, patch
from pypck.connection import (
PchkAuthenticationError,
PchkConnectionManager,
PchkLicenseError,
)
from pypck.connection import PchkAuthenticationError, PchkLicenseError
import pytest
from homeassistant import config_entries
from homeassistant.components.lcn.const import DOMAIN
@ -14,11 +11,18 @@ from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from .conftest import MockPchkConnectionManager, setup_component
from .conftest import (
MockConfigEntry,
MockPchkConnectionManager,
init_integration,
setup_component,
)
async def test_async_setup_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_async_setup_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""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 is ConfigEntryState.LOADED
@ -29,16 +33,16 @@ async def test_async_setup_entry(hass: HomeAssistant, entry, lcn_connection) ->
assert not hass.data.get(DOMAIN)
async def test_async_setup_multiple_entries(hass: HomeAssistant, entry, entry2) -> None:
async def test_async_setup_multiple_entries(
hass: HomeAssistant, entry: MockConfigEntry, entry2
) -> None:
"""Test a successful setup and unload of multiple entries."""
hass.http = Mock()
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)
await hass.async_block_till_done()
await init_integration(hass, config_entry)
assert config_entry.state is ConfigEntryState.LOADED
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
@ -56,7 +60,7 @@ async def test_async_setup_entry_update(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
entry,
entry: MockConfigEntry,
) -> None:
"""Test a successful setup entry if entry with same id already exists."""
# setup first entry
@ -79,7 +83,10 @@ async def test_async_setup_entry_update(
assert dummy_device in device_registry.devices.values()
# setup new entry with same data via import step (should cleanup dummy device)
with patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager):
with patch(
"homeassistant.components.lcn.config_flow.validate_connection",
return_value=None,
):
await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=entry.data
)
@ -88,12 +95,16 @@ async def test_async_setup_entry_update(
assert dummy_entity not in entity_registry.entities.values()
@pytest.mark.parametrize(
"exception", [PchkAuthenticationError, PchkLicenseError, TimeoutError]
)
async def test_async_setup_entry_raises_authentication_error(
hass: HomeAssistant, entry
hass: HomeAssistant, entry: MockConfigEntry, exception: Exception
) -> None:
"""Test that an authentication error is handled properly."""
with patch.object(
PchkConnectionManager, "async_connect", side_effect=PchkAuthenticationError
with patch(
"homeassistant.components.lcn.PchkConnectionManager.async_connect",
side_effect=exception,
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
@ -102,36 +113,13 @@ async def test_async_setup_entry_raises_authentication_error(
assert entry.state is ConfigEntryState.SETUP_ERROR
async def test_async_setup_entry_raises_license_error(
hass: HomeAssistant, entry
) -> None:
"""Test that an authentication error is handled properly."""
with patch.object(
PchkConnectionManager, "async_connect", side_effect=PchkLicenseError
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.SETUP_ERROR
async def test_async_setup_entry_raises_timeout_error(
hass: HomeAssistant, entry
) -> None:
"""Test that an authentication error is handled properly."""
with patch.object(PchkConnectionManager, "async_connect", side_effect=TimeoutError):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.SETUP_ERROR
async def test_async_setup_from_configuration_yaml(hass: HomeAssistant) -> None:
"""Test a successful setup using data from configuration.yaml."""
with (
patch("pypck.connection.PchkConnectionManager", MockPchkConnectionManager),
patch(
"homeassistant.components.lcn.config_flow.validate_connection",
return_value=None,
),
patch("homeassistant.components.lcn.async_setup_entry") as async_setup_entry,
):
await setup_component(hass)

View file

@ -5,297 +5,278 @@ from unittest.mock import patch
from pypck.inputs import ModStatusOutput, ModStatusRelays
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import RelayStateModifier
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.lcn.helpers import get_device_connection
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_SUPPORTED_COLOR_MODES,
ATTR_TRANSITION,
DOMAIN as DOMAIN_LIGHT,
ColorMode,
LightEntityFeature,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_SUPPORTED_FEATURES,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import MockModuleConnection
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
from tests.common import snapshot_platform
LIGHT_OUTPUT1 = "light.light_output1"
LIGHT_OUTPUT2 = "light.light_output2"
LIGHT_RELAY1 = "light.light_relay1"
async def test_setup_lcn_light(hass: HomeAssistant, lcn_connection) -> None:
async def test_setup_lcn_light(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the setup of light."""
for entity_id in (
LIGHT_OUTPUT1,
LIGHT_OUTPUT2,
LIGHT_RELAY1,
):
state = hass.states.get(entity_id)
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.LIGHT]):
await init_integration(hass, entry)
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_output_turn_on(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the output light turns on."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "dim_output") as dim_output:
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 100, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state != STATE_ON
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 100, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_ON
async def test_output_turn_on_with_attributes(
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the output light turns on."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "dim_output") as dim_output:
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: LIGHT_OUTPUT1,
ATTR_BRIGHTNESS: 50,
ATTR_TRANSITION: 2,
},
blocking=True,
)
dim_output.assert_awaited_with(0, 19, 6)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_ON
async def test_output_turn_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the output light turns off."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "dim_output") as dim_output:
state = hass.states.get(LIGHT_OUTPUT1)
state.state = STATE_ON
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 0, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state != STATE_OFF
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 0, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_OFF
async def test_entity_state(hass: HomeAssistant, lcn_connection) -> None:
"""Test state of entity."""
state = hass.states.get(LIGHT_OUTPUT1)
assert state
assert state.attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.BRIGHTNESS]
state = hass.states.get(LIGHT_OUTPUT2)
assert state
assert state.attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.ONOFF]
async def test_entity_attributes(
hass: HomeAssistant, entity_registry: er.EntityRegistry, entry, lcn_connection
) -> None:
"""Test the attributes of an entity."""
entity_output = entity_registry.async_get(LIGHT_OUTPUT1)
assert entity_output
assert entity_output.unique_id == f"{entry.entry_id}-m000007-output1"
assert entity_output.original_name == "Light_Output1"
entity_relay = entity_registry.async_get(LIGHT_RELAY1)
assert entity_relay
assert entity_relay.unique_id == f"{entry.entry_id}-m000007-relay1"
assert entity_relay.original_name == "Light_Relay1"
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_on(dim_output, hass: HomeAssistant, lcn_connection) -> None:
"""Test the output light turns on."""
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 100, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state != STATE_ON
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 100, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_ON
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_on_with_attributes(
dim_output, hass: HomeAssistant, lcn_connection
) -> None:
"""Test the output light turns on."""
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: LIGHT_OUTPUT1,
ATTR_BRIGHTNESS: 50,
ATTR_TRANSITION: 2,
},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 19, 6)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_ON
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_off(dim_output, hass: HomeAssistant, lcn_connection) -> None:
"""Test the output light turns off."""
state = hass.states.get(LIGHT_OUTPUT1)
state.state = STATE_ON
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 0, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state != STATE_OFF
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 0, 9)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_OFF
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_off_with_attributes(
dim_output, hass: HomeAssistant, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the output light turns off."""
dim_output.return_value = True
await init_integration(hass, entry)
state = hass.states.get(LIGHT_OUTPUT1)
state.state = STATE_ON
with patch.object(MockModuleConnection, "dim_output") as dim_output:
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: LIGHT_OUTPUT1,
ATTR_TRANSITION: 2,
},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 0, 6)
state = hass.states.get(LIGHT_OUTPUT1)
state.state = STATE_ON
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_OFF
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: LIGHT_OUTPUT1,
ATTR_TRANSITION: 2,
},
blocking=True,
)
dim_output.assert_awaited_with(0, 0, 6)
state = hass.states.get(LIGHT_OUTPUT1)
assert state is not None
assert state.state == STATE_OFF
@patch.object(MockModuleConnection, "control_relays")
async def test_relay_turn_on(
control_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relay_turn_on(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relay light turns on."""
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.ON
await init_integration(hass, entry)
# command failed
control_relays.return_value = False
with patch.object(MockModuleConnection, "control_relays") as control_relays:
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.ON
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
# command failed
control_relays.return_value = False
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state != STATE_ON
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
control_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state != STATE_ON
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state == STATE_ON
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
control_relays.assert_awaited_with(states)
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state == STATE_ON
@patch.object(MockModuleConnection, "control_relays")
async def test_relay_turn_off(
control_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relay_turn_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relay light turns off."""
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.OFF
await init_integration(hass, entry)
state = hass.states.get(LIGHT_RELAY1)
state.state = STATE_ON
with patch.object(MockModuleConnection, "control_relays") as control_relays:
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.OFF
# command failed
control_relays.return_value = False
state = hass.states.get(LIGHT_RELAY1)
state.state = STATE_ON
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
# command failed
control_relays.return_value = False
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state != STATE_OFF
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
control_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state != STATE_OFF
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state == STATE_OFF
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
await hass.services.async_call(
DOMAIN_LIGHT,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: LIGHT_RELAY1},
blocking=True,
)
control_relays.assert_awaited_with(states)
state = hass.states.get(LIGHT_RELAY1)
assert state is not None
assert state.state == STATE_OFF
async def test_pushed_output_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the output light changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -320,9 +301,11 @@ async def test_pushed_output_status_change(
async def test_pushed_relay_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the relay light changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
states = [False] * 8
@ -348,7 +331,9 @@ async def test_pushed_relay_status_change(
assert state.state == STATE_OFF
async def test_unload_config_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the light is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
assert hass.states.get(LIGHT_OUTPUT1).state == STATE_UNAVAILABLE

View file

@ -58,7 +58,7 @@ async def test_scene_activate(
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)
await hass.config_entries.async_unload(entry.entry_id)
state = hass.states.get("scene.romantic")
assert state.state == STATE_UNAVAILABLE

View file

@ -1,85 +1,46 @@
"""Test for the LCN sensor platform."""
from unittest.mock import patch
from pypck.inputs import ModStatusLedsAndLogicOps, ModStatusVar
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import LedStatus, LogicOpStatus, Var, VarValue
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.lcn.helpers import get_device_connection
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
UnitOfTemperature,
)
from homeassistant.const import STATE_UNAVAILABLE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import MockConfigEntry, init_integration
from tests.common import snapshot_platform
SENSOR_VAR1 = "sensor.sensor_var1"
SENSOR_SETPOINT1 = "sensor.sensor_setpoint1"
SENSOR_LED6 = "sensor.sensor_led6"
SENSOR_LOGICOP1 = "sensor.sensor_logicop1"
async def test_setup_lcn_sensor(hass: HomeAssistant, entry, lcn_connection) -> None:
"""Test the setup of sensor."""
for entity_id in (
SENSOR_VAR1,
SENSOR_SETPOINT1,
SENSOR_LED6,
SENSOR_LOGICOP1,
):
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_entity_state(hass: HomeAssistant, lcn_connection) -> None:
"""Test state of entity."""
state = hass.states.get(SENSOR_VAR1)
assert state
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfTemperature.CELSIUS
state = hass.states.get(SENSOR_SETPOINT1)
assert state
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfTemperature.CELSIUS
state = hass.states.get(SENSOR_LED6)
assert state
state = hass.states.get(SENSOR_LOGICOP1)
assert state
async def test_entity_attributes(
hass: HomeAssistant, entity_registry: er.EntityRegistry, entry, lcn_connection
async def test_setup_lcn_sensor(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the attributes of an entity."""
"""Test the setup of sensor."""
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.SENSOR]):
await init_integration(hass, entry)
entity_var1 = entity_registry.async_get(SENSOR_VAR1)
assert entity_var1
assert entity_var1.unique_id == f"{entry.entry_id}-m000007-var1"
assert entity_var1.original_name == "Sensor_Var1"
entity_r1varsetpoint = entity_registry.async_get(SENSOR_SETPOINT1)
assert entity_r1varsetpoint
assert entity_r1varsetpoint.unique_id == f"{entry.entry_id}-m000007-r1varsetpoint"
assert entity_r1varsetpoint.original_name == "Sensor_Setpoint1"
entity_led6 = entity_registry.async_get(SENSOR_LED6)
assert entity_led6
assert entity_led6.unique_id == f"{entry.entry_id}-m000007-led6"
assert entity_led6.original_name == "Sensor_Led6"
entity_logicop1 = entity_registry.async_get(SENSOR_LOGICOP1)
assert entity_logicop1
assert entity_logicop1.unique_id == f"{entry.entry_id}-m000007-logicop1"
assert entity_logicop1.original_name == "Sensor_LogicOp1"
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_pushed_variable_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the variable sensor changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -103,9 +64,11 @@ async def test_pushed_variable_status_change(
async def test_pushed_ledlogicop_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the led and logicop sensor changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -129,8 +92,10 @@ async def test_pushed_ledlogicop_status_change(
assert state.state == "all"
async def test_unload_config_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the sensor is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
assert hass.states.get(SENSOR_VAR1).state == STATE_UNAVAILABLE
assert hass.states.get(SENSOR_SETPOINT1).state == STATE_UNAVAILABLE

View file

@ -2,8 +2,8 @@
from unittest.mock import patch
import pypck
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.lcn import DOMAIN
from homeassistant.components.lcn.const import (
@ -41,9 +41,7 @@ from .conftest import (
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_output_abs(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_output_abs(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test output_abs service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -61,13 +59,11 @@ async def test_service_output_abs(
blocking=True,
)
assert dim_output.await_args.args == snapshot()
dim_output.assert_awaited_with(0, 100, 9)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_output_rel(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_output_rel(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test output_rel service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -84,12 +80,12 @@ async def test_service_output_rel(
blocking=True,
)
assert rel_output.await_args.args == snapshot()
rel_output.assert_awaited_with(0, 25)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_output_toggle(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test output_toggle service."""
await async_setup_component(hass, "persistent_notification", {})
@ -107,13 +103,11 @@ async def test_service_output_toggle(
blocking=True,
)
assert toggle_output.await_args.args == snapshot()
toggle_output.assert_awaited_with(0, 9)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_relays(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_relays(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test relays service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -126,13 +120,14 @@ async def test_service_relays(
blocking=True,
)
assert control_relays.await_args.args == snapshot()
states = ["OFF", "OFF", "ON", "ON", "TOGGLE", "TOGGLE", "NOCHANGE", "NOCHANGE"]
relay_states = [pypck.lcn_defs.RelayStateModifier[state] for state in states]
control_relays.assert_awaited_with(relay_states)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_led(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_led(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test led service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -145,13 +140,14 @@ async def test_service_led(
blocking=True,
)
assert control_led.await_args.args == snapshot()
led = pypck.lcn_defs.LedPort["LED6"]
led_state = pypck.lcn_defs.LedStatus["BLINK"]
control_led.assert_awaited_with(led, led_state)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_var_abs(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_var_abs(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test var_abs service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -169,13 +165,13 @@ async def test_service_var_abs(
blocking=True,
)
assert var_abs.await_args.args == snapshot()
var_abs.assert_awaited_with(
pypck.lcn_defs.Var["VAR1"], 75, pypck.lcn_defs.VarUnit.parse("%")
)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_var_rel(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_var_rel(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test var_rel service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -194,13 +190,16 @@ async def test_service_var_rel(
blocking=True,
)
assert var_rel.await_args.args == snapshot()
var_rel.assert_awaited_with(
pypck.lcn_defs.Var["VAR1"],
10,
pypck.lcn_defs.VarUnit.parse("%"),
pypck.lcn_defs.RelVarRef["CURRENT"],
)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_var_reset(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_var_reset(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test var_reset service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -213,12 +212,12 @@ async def test_service_var_reset(
blocking=True,
)
assert var_reset.await_args.args == snapshot()
var_reset.assert_awaited_with(pypck.lcn_defs.Var["VAR1"])
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_lock_regulator(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test lock_regulator service."""
await async_setup_component(hass, "persistent_notification", {})
@ -236,13 +235,11 @@ async def test_service_lock_regulator(
blocking=True,
)
assert lock_regulator.await_args.args == snapshot()
lock_regulator.assert_awaited_with(0, True)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_send_keys(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_send_keys(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test send_keys service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -260,12 +257,12 @@ async def test_service_send_keys(
keys[0][4] = True
keys[3][7] = True
assert send_keys.await_args.args == snapshot()
send_keys.assert_awaited_with(keys, pypck.lcn_defs.SendKeyCommand["HIT"])
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_send_keys_hit_deferred(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test send_keys (hit_deferred) service."""
await async_setup_component(hass, "persistent_notification", {})
@ -292,7 +289,9 @@ async def test_service_send_keys_hit_deferred(
blocking=True,
)
assert send_keys_hit_deferred.await_args.args == snapshot()
send_keys_hit_deferred.assert_awaited_with(
keys, 5, pypck.lcn_defs.TimeUnit.parse("S")
)
# wrong key action
with (
@ -316,9 +315,7 @@ async def test_service_send_keys_hit_deferred(
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_lock_keys(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_lock_keys(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test lock_keys service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -331,12 +328,15 @@ async def test_service_lock_keys(
blocking=True,
)
assert lock_keys.await_args.args == snapshot()
states = ["OFF", "OFF", "ON", "ON", "TOGGLE", "TOGGLE", "NOCHANGE", "NOCHANGE"]
lock_states = [pypck.lcn_defs.KeyLockStateModifier[state] for state in states]
lock_keys.assert_awaited_with(0, lock_states)
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_lock_keys_tab_a_temporary(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test lock_keys (tab_a_temporary) service."""
await async_setup_component(hass, "persistent_notification", {})
@ -358,7 +358,12 @@ async def test_service_lock_keys_tab_a_temporary(
blocking=True,
)
assert lock_keys_tab_a_temporary.await_args.args == snapshot()
states = ["OFF", "OFF", "ON", "ON", "TOGGLE", "TOGGLE", "NOCHANGE", "NOCHANGE"]
lock_states = [pypck.lcn_defs.KeyLockStateModifier[state] for state in states]
lock_keys_tab_a_temporary.assert_awaited_with(
10, pypck.lcn_defs.TimeUnit.parse("S"), lock_states
)
# wrong table
with (
@ -382,9 +387,7 @@ async def test_service_lock_keys_tab_a_temporary(
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_dyn_text(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_dyn_text(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test dyn_text service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -397,13 +400,11 @@ async def test_service_dyn_text(
blocking=True,
)
assert dyn_text.await_args.args == snapshot()
dyn_text.assert_awaited_with(0, "text in row 1")
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)
async def test_service_pck(
hass: HomeAssistant, entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None:
async def test_service_pck(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test pck service."""
await async_setup_component(hass, "persistent_notification", {})
await init_integration(hass, entry)
@ -416,7 +417,7 @@ async def test_service_pck(
blocking=True,
)
assert pck.await_args.args == snapshot()
pck.assert_awaited_with("PIN4")
@patch("homeassistant.components.lcn.PchkConnectionManager", MockPchkConnectionManager)

View file

@ -5,6 +5,7 @@ from unittest.mock import patch
from pypck.inputs import ModStatusOutput, ModStatusRelays
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import RelayStateModifier
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.lcn.helpers import get_device_connection
from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH
@ -15,11 +16,14 @@ from homeassistant.const import (
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import MockModuleConnection
from .conftest import MockConfigEntry, MockModuleConnection, init_integration
from tests.common import snapshot_platform
SWITCH_OUTPUT1 = "switch.switch_output1"
SWITCH_OUTPUT2 = "switch.switch_output2"
@ -27,197 +31,185 @@ SWITCH_RELAY1 = "switch.switch_relay1"
SWITCH_RELAY2 = "switch.switch_relay2"
async def test_setup_lcn_switch(hass: HomeAssistant, lcn_connection) -> None:
async def test_setup_lcn_switch(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the setup of switch."""
for entity_id in (
SWITCH_OUTPUT1,
SWITCH_OUTPUT2,
SWITCH_RELAY1,
SWITCH_RELAY2,
):
state = hass.states.get(entity_id)
assert state is not None
with patch("homeassistant.components.lcn.PLATFORMS", [Platform.SWITCH]):
await init_integration(hass, entry)
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
async def test_output_turn_on(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the output switch turns on."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "dim_output") as dim_output:
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 100, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_OFF
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 100, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_ON
async def test_output_turn_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the output switch turns off."""
await init_integration(hass, entry)
with patch.object(MockModuleConnection, "dim_output") as dim_output:
state = hass.states.get(SWITCH_OUTPUT1)
state.state = STATE_ON
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 0, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_ON
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
dim_output.assert_awaited_with(0, 0, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_OFF
async def test_entity_attributes(
hass: HomeAssistant, entity_registry: er.EntityRegistry, entry, lcn_connection
) -> None:
"""Test the attributes of an entity."""
entity_output = entity_registry.async_get(SWITCH_OUTPUT1)
assert entity_output
assert entity_output.unique_id == f"{entry.entry_id}-m000007-output1"
assert entity_output.original_name == "Switch_Output1"
entity_relay = entity_registry.async_get(SWITCH_RELAY1)
assert entity_relay
assert entity_relay.unique_id == f"{entry.entry_id}-m000007-relay1"
assert entity_relay.original_name == "Switch_Relay1"
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_on(dim_output, hass: HomeAssistant, lcn_connection) -> None:
"""Test the output switch turns on."""
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 100, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_OFF
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 100, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_ON
@patch.object(MockModuleConnection, "dim_output")
async def test_output_turn_off(dim_output, hass: HomeAssistant, lcn_connection) -> None:
"""Test the output switch turns off."""
state = hass.states.get(SWITCH_OUTPUT1)
state.state = STATE_ON
# command failed
dim_output.return_value = False
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 0, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_ON
# command success
dim_output.reset_mock(return_value=True)
dim_output.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_OUTPUT1},
blocking=True,
)
await hass.async_block_till_done()
dim_output.assert_awaited_with(0, 0, 0)
state = hass.states.get(SWITCH_OUTPUT1)
assert state.state == STATE_OFF
@patch.object(MockModuleConnection, "control_relays")
async def test_relay_turn_on(
control_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relay_turn_on(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relay switch turns on."""
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.ON
await init_integration(hass, entry)
# command failed
control_relays.return_value = False
with patch.object(MockModuleConnection, "control_relays") as control_relays:
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.ON
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
# command failed
control_relays.return_value = False
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_OFF
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
control_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_OFF
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_ON
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
control_relays.assert_awaited_with(states)
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_ON
@patch.object(MockModuleConnection, "control_relays")
async def test_relay_turn_off(
control_relays, hass: HomeAssistant, lcn_connection
) -> None:
async def test_relay_turn_off(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the relay switch turns off."""
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.OFF
await init_integration(hass, entry)
state = hass.states.get(SWITCH_RELAY1)
state.state = STATE_ON
with patch.object(MockModuleConnection, "control_relays") as control_relays:
states = [RelayStateModifier.NOCHANGE] * 8
states[0] = RelayStateModifier.OFF
# command failed
control_relays.return_value = False
state = hass.states.get(SWITCH_RELAY1)
state.state = STATE_ON
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
# command failed
control_relays.return_value = False
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_ON
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
control_relays.assert_awaited_with(states)
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
await hass.async_block_till_done()
control_relays.assert_awaited_with(states)
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_ON
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_OFF
# command success
control_relays.reset_mock(return_value=True)
control_relays.return_value = True
await hass.services.async_call(
DOMAIN_SWITCH,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: SWITCH_RELAY1},
blocking=True,
)
control_relays.assert_awaited_with(states)
state = hass.states.get(SWITCH_RELAY1)
assert state.state == STATE_OFF
async def test_pushed_output_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the output switch changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
@ -239,9 +231,11 @@ async def test_pushed_output_status_change(
async def test_pushed_relay_status_change(
hass: HomeAssistant, entry, lcn_connection
hass: HomeAssistant, entry: MockConfigEntry
) -> None:
"""Test the relay switch changes its state on status received."""
await init_integration(hass, entry)
device_connection = get_device_connection(hass, (0, 7, False), entry)
address = LcnAddr(0, 7, False)
states = [False] * 8
@ -265,7 +259,9 @@ async def test_pushed_relay_status_change(
assert state.state == STATE_OFF
async def test_unload_config_entry(hass: HomeAssistant, entry, lcn_connection) -> None:
async def test_unload_config_entry(hass: HomeAssistant, entry: MockConfigEntry) -> None:
"""Test the switch is removed when the config entry is unloaded."""
await init_integration(hass, entry)
await hass.config_entries.async_unload(entry.entry_id)
assert hass.states.get(SWITCH_OUTPUT1).state == STATE_UNAVAILABLE

View file

@ -1,8 +1,11 @@
"""LCN Websocket Tests."""
from typing import Any
from pypck.lcn_addr import LcnAddr
import pytest
from homeassistant.components.lcn import AddressType
from homeassistant.components.lcn.const import CONF_DOMAIN_DATA
from homeassistant.components.lcn.helpers import get_device_config, get_resource
from homeassistant.const import (
@ -16,6 +19,8 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from .conftest import MockConfigEntry, init_integration
from tests.typing import WebSocketGenerator
DEVICES_PAYLOAD = {CONF_TYPE: "lcn/devices", "entry_id": ""}
@ -52,11 +57,12 @@ ENTITIES_DELETE_PAYLOAD = {
async def test_lcn_devices_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/devices command."""
client = await hass_ws_client(hass)
await init_integration(hass, entry)
client = await hass_ws_client(hass)
await client.send_json_auto_id({**DEVICES_PAYLOAD, "entry_id": entry.entry_id})
res = await client.receive_json()
@ -79,11 +85,12 @@ async def test_lcn_devices_command(
async def test_lcn_entities_command(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entry,
lcn_connection,
entry: MockConfigEntry,
payload,
) -> None:
"""Test lcn/entities command."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{
@ -107,10 +114,11 @@ async def test_lcn_entities_command(
async def test_lcn_devices_scan_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/devices/scan command."""
# add new module which is not stored in config_entry
lcn_connection = await init_integration(hass, entry)
lcn_connection.get_address_conn(LcnAddr(0, 10, False))
client = await hass_ws_client(hass)
@ -129,9 +137,11 @@ async def test_lcn_devices_scan_command(
async def test_lcn_devices_add_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/devices/add command."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
assert get_device_config((0, 10, False), entry) is None
@ -144,9 +154,11 @@ async def test_lcn_devices_add_command(
async def test_lcn_devices_delete_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/devices/delete command."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
assert get_device_config((0, 7, False), entry)
@ -160,9 +172,11 @@ async def test_lcn_devices_delete_command(
async def test_lcn_entities_add_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/entities/add command."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
entity_config = {
@ -185,9 +199,11 @@ async def test_lcn_entities_add_command(
async def test_lcn_entities_delete_command(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry, lcn_connection
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, entry: MockConfigEntry
) -> None:
"""Test lcn/entities/delete command."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
assert (
@ -239,12 +255,14 @@ async def test_lcn_entities_delete_command(
async def test_lcn_command_host_error(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
lcn_connection,
payload,
entity_id,
result,
entry: MockConfigEntry,
payload: dict[str, str],
entity_id: str,
result: bool,
) -> None:
"""Test lcn commands for unknown host."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
await client.send_json_auto_id({**payload, "entry_id": entity_id})
@ -265,13 +283,14 @@ async def test_lcn_command_host_error(
async def test_lcn_command_address_error(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entry,
lcn_connection,
payload,
address,
result,
entry: MockConfigEntry,
payload: dict[str, Any],
address: AddressType,
result: bool,
) -> None:
"""Test lcn commands for address error."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{**payload, "entry_id": entry.entry_id, CONF_ADDRESS: address}
@ -285,10 +304,11 @@ async def test_lcn_command_address_error(
async def test_lcn_entities_add_existing_error(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entry,
lcn_connection,
entry: MockConfigEntry,
) -> None:
"""Test lcn commands for address error."""
await init_integration(hass, entry)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{