core/tests/components/sensibo/test_init.py

182 lines
6.0 KiB
Python

"""Test for Sensibo integration setup."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pysensibo.model import SensiboData
import pytest
from homeassistant.components.sensibo.const import DOMAIN
from homeassistant.components.sensibo.util import NoUsernameError
from homeassistant.config_entries import SOURCE_USER, ConfigEntry, ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.setup import async_setup_component
from . import ENTRY_CONFIG
from tests.common import MockConfigEntry, async_fire_time_changed
from tests.typing import WebSocketGenerator
async def test_load_unload_entry(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test setup and unload config entry."""
entry = MockConfigEntry(
domain=DOMAIN,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="firstnamelastname",
version=2,
)
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.LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.NOT_LOADED
async def test_migrate_entry(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test migrate entry unique id."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="someother",
version=1,
)
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.LOADED
assert entry.version == 2
assert entry.unique_id == "firstnamelastname"
async def test_migrate_entry_fails(hass: HomeAssistant, mock_client: MagicMock) -> None:
"""Test migrate entry fails."""
entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="someother",
version=1,
)
entry.add_to_hass(hass)
mock_client.async_get_me.side_effect = NoUsernameError("No username returned")
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.MIGRATION_ERROR
assert entry.version == 1
assert entry.unique_id == "someother"
async def test_device_remove_devices(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
load_int: ConfigEntry,
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test we can only remove a device that no longer exists."""
assert await async_setup_component(hass, "config", {})
entity = entity_registry.entities["climate.hallway"]
device_entry = device_registry.async_get(entity.device_id)
client = await hass_ws_client(hass)
response = await client.remove_device(device_entry.id, load_int.entry_id)
assert not response["success"]
dead_device_entry = device_registry.async_get_or_create(
config_entry_id=load_int.entry_id,
identifiers={(DOMAIN, "remove-device-id")},
)
response = await client.remove_device(dead_device_entry.id, load_int.entry_id)
assert response["success"]
@pytest.mark.parametrize(
("entity_id", "device_ids"),
[
# Device is ABC999111
("climate.hallway", ["ABC999111"]),
("binary_sensor.hallway_filter_clean_required", ["ABC999111"]),
("number.hallway_temperature_calibration", ["ABC999111"]),
("sensor.hallway_filter_last_reset", ["ABC999111"]),
("update.hallway_firmware", ["ABC999111"]),
# Device is AABBCC belonging to device ABC999111
("binary_sensor.hallway_motion_sensor_motion", ["ABC999111", "AABBCC"]),
],
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_automatic_device_addition_and_removal(
hass: HomeAssistant,
load_int: ConfigEntry,
mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any], dict[str, Any]],
entity_registry: er.EntityRegistry,
device_registry: dr.DeviceRegistry,
freezer: FrozenDateTimeFactory,
entity_id: str,
device_ids: list[str],
) -> None:
"""Test for automatic device addition and removal."""
state = hass.states.get(entity_id)
assert state
assert entity_registry.async_get(entity_id)
for device_id in device_ids:
assert device_registry.async_get_device(identifiers={(DOMAIN, device_id)})
# Remove one of the devices
new_device_list = [
device for device in get_data[2]["result"] if device["id"] != device_ids[0]
]
mock_client.async_get_devices.return_value = {
"status": "success",
"result": new_device_list,
}
new_data = {k: v for k, v in get_data[0].parsed.items() if k != device_ids[0]}
new_raw = mock_client.async_get_devices.return_value["result"]
mock_client.async_get_devices_data.return_value = SensiboData(new_raw, new_data)
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert not state
assert not entity_registry.async_get(entity_id)
for device_id in device_ids:
assert not device_registry.async_get_device(identifiers={(DOMAIN, device_id)})
# Add the device back
mock_client.async_get_devices.return_value = get_data[2]
mock_client.async_get_devices_data.return_value = get_data[0]
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert entity_registry.async_get(entity_id)
for device_id in device_ids:
assert device_registry.async_get_device(identifiers={(DOMAIN, device_id)})