226 lines
7.7 KiB
Python
226 lines
7.7 KiB
Python
"""Tests for Intergas InComfort integration."""
|
|
|
|
from datetime import timedelta
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
from aiohttp import ClientResponseError, RequestInfo
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
from incomfortclient import InvalidGateway, InvalidHeaterList
|
|
import pytest
|
|
|
|
from homeassistant.components.incomfort import DOMAIN
|
|
from homeassistant.components.incomfort.coordinator import UPDATE_INTERVAL
|
|
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
|
from homeassistant.const import STATE_UNAVAILABLE
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import entity_registry as er
|
|
from homeassistant.helpers.device_registry import DeviceRegistry
|
|
|
|
from .conftest import MOCK_HEATER_STATUS
|
|
|
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
async def test_setup_platforms(
|
|
hass: HomeAssistant,
|
|
mock_incomfort: MagicMock,
|
|
entity_registry: er.EntityRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test the incomfort integration is set up correctly."""
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
@pytest.mark.parametrize(
|
|
"mock_heater_status", [MOCK_HEATER_STATUS | {"serial_no": "c01d00c0ffee"}]
|
|
)
|
|
async def test_stale_devices_cleanup(
|
|
hass: HomeAssistant,
|
|
device_registry: DeviceRegistry,
|
|
mock_incomfort: MagicMock,
|
|
entity_registry: er.EntityRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_heater_status: dict[str, Any],
|
|
) -> None:
|
|
"""Test the incomfort integration is cleaning up stale devices."""
|
|
# Setup an old heater with serial_no c01d00c0ffee
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
|
old_entries = device_registry.devices.get_devices_for_config_entry_id(
|
|
mock_config_entry.entry_id
|
|
)
|
|
assert len(old_entries) == 3
|
|
old_heater = device_registry.async_get_device({(DOMAIN, "c01d00c0ffee")})
|
|
assert old_heater is not None
|
|
assert old_heater.serial_number == "c01d00c0ffee"
|
|
old_climate = device_registry.async_get_device({(DOMAIN, "c01d00c0ffee_1")})
|
|
assert old_heater is not None
|
|
old_climate = device_registry.async_get_device({(DOMAIN, "c01d00c0ffee_1")})
|
|
assert old_climate is not None
|
|
|
|
mock_heater_status["serial_no"] = "c0ffeec0ffee"
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
new_entries = device_registry.devices.get_devices_for_config_entry_id(
|
|
mock_config_entry.entry_id
|
|
)
|
|
assert len(new_entries) == 3
|
|
new_heater = device_registry.async_get_device({(DOMAIN, "c0ffeec0ffee")})
|
|
assert new_heater is not None
|
|
assert new_heater.serial_number == "c0ffeec0ffee"
|
|
new_climate = device_registry.async_get_device({(DOMAIN, "c0ffeec0ffee_1")})
|
|
assert new_climate is not None
|
|
|
|
old_heater = device_registry.async_get_device({(DOMAIN, "c01d00c0ffee")})
|
|
assert old_heater is None
|
|
old_climate = device_registry.async_get_device({(DOMAIN, "c01d00c0ffee_1")})
|
|
assert old_climate is None
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
async def test_coordinator_updates(
|
|
hass: HomeAssistant,
|
|
mock_incomfort: MagicMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
mock_config_entry: ConfigEntry,
|
|
) -> None:
|
|
"""Test the incomfort coordinator is updating."""
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
state = hass.states.get("climate.thermostat_1")
|
|
assert state is not None
|
|
assert state.attributes["current_temperature"] == 21.4
|
|
mock_incomfort().mock_room_status["room_temp"] = 20.91
|
|
|
|
state = hass.states.get("sensor.boiler_pressure")
|
|
assert state is not None
|
|
assert state.state == "1.86"
|
|
mock_incomfort().mock_heater_status["pressure"] = 1.84
|
|
|
|
freezer.tick(timedelta(seconds=UPDATE_INTERVAL + 5))
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done(wait_background_tasks=True)
|
|
|
|
state = hass.states.get("climate.thermostat_1")
|
|
assert state is not None
|
|
assert state.attributes["current_temperature"] == 20.9
|
|
|
|
state = hass.states.get("sensor.boiler_pressure")
|
|
assert state is not None
|
|
assert state.state == "1.84"
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
@pytest.mark.parametrize(
|
|
"exc",
|
|
[
|
|
ClientResponseError(
|
|
RequestInfo(
|
|
url="http://example.com",
|
|
method="GET",
|
|
headers=[],
|
|
real_url="http://example.com",
|
|
),
|
|
None,
|
|
status=401,
|
|
),
|
|
InvalidHeaterList,
|
|
ClientResponseError(
|
|
RequestInfo(
|
|
url="http://example.com",
|
|
method="GET",
|
|
headers=[],
|
|
real_url="http://example.com",
|
|
),
|
|
None,
|
|
status=500,
|
|
),
|
|
TimeoutError,
|
|
],
|
|
)
|
|
async def test_coordinator_update_fails(
|
|
hass: HomeAssistant,
|
|
mock_incomfort: MagicMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
exc: Exception,
|
|
mock_config_entry: ConfigEntry,
|
|
) -> None:
|
|
"""Test the incomfort coordinator update fails."""
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
state = hass.states.get("sensor.boiler_pressure")
|
|
assert state is not None
|
|
assert state.state == "1.86"
|
|
|
|
with patch.object(
|
|
mock_incomfort().heaters.return_value[0], "update", side_effect=exc
|
|
):
|
|
freezer.tick(timedelta(seconds=UPDATE_INTERVAL + 5))
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done(wait_background_tasks=True)
|
|
|
|
state = hass.states.get("sensor.boiler_pressure")
|
|
assert state is not None
|
|
assert state.state == STATE_UNAVAILABLE
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
@pytest.mark.parametrize(
|
|
("exc", "config_entry_state"),
|
|
[
|
|
(
|
|
InvalidGateway,
|
|
ConfigEntryState.SETUP_ERROR,
|
|
),
|
|
(InvalidHeaterList, ConfigEntryState.SETUP_RETRY),
|
|
(
|
|
ClientResponseError(
|
|
RequestInfo(
|
|
url="http://example.com",
|
|
method="GET",
|
|
headers=[],
|
|
real_url="http://example.com",
|
|
),
|
|
None,
|
|
status=404,
|
|
),
|
|
ConfigEntryState.SETUP_ERROR,
|
|
),
|
|
(
|
|
ClientResponseError(
|
|
RequestInfo(
|
|
url="http://example.com",
|
|
method="GET",
|
|
headers=[],
|
|
real_url="http://example.com",
|
|
),
|
|
None,
|
|
status=500,
|
|
),
|
|
ConfigEntryState.SETUP_RETRY,
|
|
),
|
|
(TimeoutError, ConfigEntryState.SETUP_RETRY),
|
|
],
|
|
)
|
|
async def test_entry_setup_fails(
|
|
hass: HomeAssistant,
|
|
mock_incomfort: MagicMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
mock_config_entry: ConfigEntry,
|
|
exc: Exception,
|
|
config_entry_state: ConfigEntryState,
|
|
) -> None:
|
|
"""Test the incomfort coordinator entry setup fails."""
|
|
with patch(
|
|
"homeassistant.components.incomfort.async_connect_gateway",
|
|
AsyncMock(side_effect=exc),
|
|
):
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
state = hass.states.get("sensor.boiler_pressure")
|
|
assert state is None
|
|
assert mock_config_entry.state is config_entry_state
|