core/tests/components/screenlogic/test_init.py

287 lines
8.4 KiB
Python
Raw Normal View History

"""Tests for ScreenLogic integration init."""
from dataclasses import dataclass
from unittest.mock import DEFAULT, patch
import pytest
from screenlogicpy import ScreenLogicGateway
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN
from homeassistant.components.screenlogic import DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.util import slugify
from . import (
DATA_MIN_MIGRATION,
DATA_MISSING_VALUES_CHEM_CHLOR,
GATEWAY_DISCOVERY_IMPORT_PATH,
MOCK_ADAPTER_MAC,
MOCK_ADAPTER_NAME,
stub_async_connect,
)
from tests.common import MockConfigEntry
@dataclass
class EntityMigrationData:
"""Class to organize minimum entity data."""
old_name: str
old_key: str
new_name: str
new_key: str
domain: str
TEST_MIGRATING_ENTITIES = [
EntityMigrationData(
"Chemistry Alarm",
"chem_alarm",
"Active Alert",
"active_alert",
BINARY_SENSOR_DOMAIN,
),
EntityMigrationData(
"Pool Low Pump Current Watts",
"currentWatts_0",
"Pool Low Pump Watts Now",
"pump_0_watts_now",
SENSOR_DOMAIN,
),
EntityMigrationData(
"SCG Status",
"scg_status",
"Chlorinator",
"scg_state",
BINARY_SENSOR_DOMAIN,
),
EntityMigrationData(
"Non-Migrating Sensor",
"nonmigrating",
"Non-Migrating Sensor",
"nonmigrating",
SENSOR_DOMAIN,
),
EntityMigrationData(
"Cyanuric Acid",
"chem_cya",
"Cyanuric Acid",
"chem_cya",
SENSOR_DOMAIN,
),
EntityMigrationData(
"Old Sensor",
"old_sensor",
"Old Sensor",
"old_sensor",
SENSOR_DOMAIN,
),
EntityMigrationData(
"Pump Sensor Missing Index",
"currentWatts",
"Pump Sensor Missing Index",
"currentWatts",
SENSOR_DOMAIN,
),
]
2024-04-14 05:15:10 +00:00
def _migration_connect(*args, **kwargs):
return stub_async_connect(DATA_MIN_MIGRATION, *args, **kwargs)
@pytest.mark.parametrize(
("entity_def", "ent_data"),
[
(
{
"domain": ent_data.domain,
"platform": DOMAIN,
"unique_id": f"{MOCK_ADAPTER_MAC}_{ent_data.old_key}",
"suggested_object_id": f"{MOCK_ADAPTER_NAME} {ent_data.old_name}",
"disabled_by": None,
"has_entity_name": True,
"original_name": ent_data.old_name,
},
ent_data,
)
for ent_data in TEST_MIGRATING_ENTITIES
],
ids=[ent_data.old_name for ent_data in TEST_MIGRATING_ENTITIES],
)
async def test_async_migrate_entries(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
mock_config_entry: MockConfigEntry,
entity_def: dict,
ent_data: EntityMigrationData,
) -> None:
"""Test migration to new entity names."""
mock_config_entry.add_to_hass(hass)
device: dr.DeviceEntry = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, MOCK_ADAPTER_MAC)},
)
TEST_EXISTING_ENTRY = {
"domain": SENSOR_DOMAIN,
"platform": DOMAIN,
"unique_id": f"{MOCK_ADAPTER_MAC}_cya",
"suggested_object_id": f"{MOCK_ADAPTER_NAME} CYA",
"disabled_by": None,
"has_entity_name": True,
"original_name": "CYA",
}
entity_registry.async_get_or_create(
**TEST_EXISTING_ENTRY, device_id=device.id, config_entry=mock_config_entry
)
entity: er.RegistryEntry = entity_registry.async_get_or_create(
**entity_def, device_id=device.id, config_entry=mock_config_entry
)
old_eid = f"{ent_data.domain}.{slugify(f'{MOCK_ADAPTER_NAME} {ent_data.old_name}')}"
old_uid = f"{MOCK_ADAPTER_MAC}_{ent_data.old_key}"
new_eid = f"{ent_data.domain}.{slugify(f'{MOCK_ADAPTER_NAME} {ent_data.new_name}')}"
new_uid = f"{MOCK_ADAPTER_MAC}_{ent_data.new_key}"
assert entity.unique_id == old_uid
assert entity.entity_id == old_eid
with (
patch(
GATEWAY_DISCOVERY_IMPORT_PATH,
return_value={},
),
patch.multiple(
ScreenLogicGateway,
2024-04-14 05:15:10 +00:00
async_connect=_migration_connect,
is_connected=True,
_async_connected_request=DEFAULT,
),
):
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
entity_migrated = entity_registry.async_get(new_eid)
assert entity_migrated
assert entity_migrated.entity_id == new_eid
assert entity_migrated.unique_id == new_uid
assert entity_migrated.original_name == ent_data.new_name
async def test_entity_migration_data(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test ENTITY_MIGRATION data guards."""
mock_config_entry.add_to_hass(hass)
device: dr.DeviceEntry = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, MOCK_ADAPTER_MAC)},
)
TEST_EXISTING_ENTRY = {
"domain": SENSOR_DOMAIN,
"platform": DOMAIN,
"unique_id": f"{MOCK_ADAPTER_MAC}_missing_device",
"suggested_object_id": f"{MOCK_ADAPTER_NAME} Missing Migration Device",
"disabled_by": None,
"has_entity_name": True,
"original_name": "EMissing Migration Device",
}
original_entity: er.RegistryEntry = entity_registry.async_get_or_create(
**TEST_EXISTING_ENTRY, device_id=device.id, config_entry=mock_config_entry
)
old_eid = original_entity.entity_id
old_uid = original_entity.unique_id
assert old_uid == f"{MOCK_ADAPTER_MAC}_missing_device"
assert (
old_eid
== f"{SENSOR_DOMAIN}.{slugify(f'{MOCK_ADAPTER_NAME} Missing Migration Device')}"
)
# This patch simulates bad data being added to ENTITY_MIGRATIONS
with (
patch.dict(
"homeassistant.components.screenlogic.data.ENTITY_MIGRATIONS",
{
"missing_device": {
"new_key": "state",
"old_name": "Missing Migration Device",
"new_name": "Bad ENTITY_MIGRATIONS Entry",
},
},
),
patch(
GATEWAY_DISCOVERY_IMPORT_PATH,
return_value={},
),
patch.multiple(
ScreenLogicGateway,
2024-04-14 05:15:10 +00:00
async_connect=_migration_connect,
is_connected=True,
_async_connected_request=DEFAULT,
),
):
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
entity_migrated = entity_registry.async_get(
slugify(f"{MOCK_ADAPTER_NAME} Bad ENTITY_MIGRATIONS Entry")
)
assert entity_migrated is None
entity_not_migrated = entity_registry.async_get(old_eid)
assert entity_not_migrated == original_entity
async def test_platform_setup(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test setup for platforms that define expected data."""
2024-04-14 05:15:10 +00:00
def stub_connect(*args, **kwargs):
return stub_async_connect(DATA_MISSING_VALUES_CHEM_CHLOR, *args, **kwargs)
device_prefix = slugify(MOCK_ADAPTER_NAME)
tested_entity_ids = [
f"{BINARY_SENSOR_DOMAIN}.{device_prefix}_active_alert",
f"{SENSOR_DOMAIN}.{device_prefix}_air_temperature",
f"{NUMBER_DOMAIN}.{device_prefix}_pool_chlorinator_setpoint",
]
mock_config_entry.add_to_hass(hass)
with (
patch(
GATEWAY_DISCOVERY_IMPORT_PATH,
return_value={},
),
patch.multiple(
ScreenLogicGateway,
async_connect=stub_connect,
is_connected=True,
_async_connected_request=DEFAULT,
),
):
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
for entity_id in tested_entity_ids:
assert hass.states.get(entity_id) is not None