Switch to using a fixture for evohome WaterHeater tests (#127701)

Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: thecem <46648579+thecem@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
This commit is contained in:
David Bonnes 2024-10-24 15:01:29 +01:00 committed by GitHub
parent dcc7ee98b3
commit 77a91f5a8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 136 additions and 171 deletions

View File

@ -138,7 +138,14 @@ async def setup_evohome(
patch("homeassistant.components.evohome.ev1.EvohomeClient", return_value=None),
patch("evohomeasync2.broker.Broker.get", mock_get_factory(install)),
):
mock_client.side_effect = EvohomeClient
evo: EvohomeClient | None = None
def evohome_client(*args, **kwargs) -> EvohomeClient:
nonlocal evo
evo = EvohomeClient(*args, **kwargs)
return evo
mock_client.side_effect = evohome_client
assert await async_setup_component(hass, DOMAIN, {DOMAIN: config})
await hass.async_block_till_done()
@ -150,6 +157,19 @@ async def setup_evohome(
assert isinstance(mock_client.call_args.kwargs["session"], ClientSession)
assert mock_client.account_info is not None
assert evo and evo.account_info is not None
mock_client.return_value = evo
yield mock_client
@pytest.fixture
async def evohome(
hass: HomeAssistant,
config: dict[str, str],
install: str,
) -> AsyncGenerator[MagicMock]:
"""Return the mocked evohome client for this install fixture."""
async for mock_client in setup_evohome(hass, config, install=install):
yield mock_client

View File

@ -2,18 +2,8 @@
# name: test_set_operation_mode[default]
list([
tuple(
dict({
'mode': <ZoneMode.TEMPORARY_OVERRIDE: 'TemporaryOverride'>,
'state': <DhwState.OFF: 'Off'>,
'untilTime': '2024-07-10T12:00:00Z',
}),
),
tuple(
dict({
'mode': <ZoneMode.TEMPORARY_OVERRIDE: 'TemporaryOverride'>,
'state': <DhwState.ON: 'On'>,
'untilTime': '2024-07-10T12:00:00Z',
}),
),
])
# ---

View File

@ -7,203 +7,158 @@ from __future__ import annotations
from unittest.mock import patch
from evohomeasync2 import EvohomeClient
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.evohome import DOMAIN
from homeassistant.components.evohome.coordinator import EvoBroker
from homeassistant.components.evohome.water_heater import EvoDHW
from homeassistant.const import Platform
from homeassistant.components.water_heater import (
ATTR_AWAY_MODE,
ATTR_OPERATION_MODE,
SERVICE_SET_AWAY_MODE,
SERVICE_SET_OPERATION_MODE,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.exceptions import HomeAssistantError
from .conftest import setup_evohome
from .const import TEST_INSTALLS_WITH_DHW
def get_dhw_entity(hass: HomeAssistant) -> EvoDHW | None:
"""Return the DHW entity of the evohome system."""
broker: EvoBroker = hass.data[DOMAIN]["broker"]
if (dhw := broker.tcs.hotwater) is None:
return None
entity_registry = er.async_get(hass)
entity_id = entity_registry.async_get_entity_id(
Platform.WATER_HEATER, DOMAIN, dhw._id
)
component: EntityComponent = hass.data.get(Platform.WATER_HEATER) # type: ignore[assignment]
return next(e for e in component.entities if e.entity_id == entity_id) # type: ignore[return-value]
DHW_ENTITY_ID = "water_heater.domestic_hot_water"
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_set_operation_mode(
hass: HomeAssistant,
config: dict[str, str],
install: str,
evohome: EvohomeClient,
freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion,
) -> None:
"""Test water_heater services of a evohome-compatible DHW zone."""
"""Test SERVICE_SET_OPERATION_MODE of a evohome HotWater entity."""
freezer.move_to("2024-07-10T11:55:00Z")
results = []
async for _ in setup_evohome(hass, config, install=install):
dhw = get_dhw_entity(hass)
# SERVICE_SET_OPERATION_MODE: auto
with patch("evohomeasync2.hotwater.HotWater.reset_mode") as mock_fcn:
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_SET_OPERATION_MODE,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
ATTR_OPERATION_MODE: "auto",
},
blocking=True,
)
# set_operation_mode(auto): FollowSchedule
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_set_operation_mode("auto")
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
assert mock_fcn.await_args.kwargs == {}
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == (
{
"mode": "FollowSchedule",
"state": None,
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
# SERVICE_SET_OPERATION_MODE: off (until next scheduled setpoint)
with patch("evohomeasync2.hotwater.HotWater.set_off") as mock_fcn:
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_SET_OPERATION_MODE,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
ATTR_OPERATION_MODE: "off",
},
blocking=True,
)
# set_operation_mode(off): TemporaryOverride, advanced
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_set_operation_mode("off")
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
results.append(mock_fcn.await_args.args)
assert mock_fcn.await_count == 1
assert install != "default" or mock_fcn.await_args.args == (
{
"mode": "TemporaryOverride",
"state": "Off",
"untilTime": "2024-07-10T12:00:00Z", # varies by install
},
)
assert mock_fcn.await_args.kwargs == {}
# SERVICE_SET_OPERATION_MODE: on (until next scheduled setpoint)
with patch("evohomeasync2.hotwater.HotWater.set_on") as mock_fcn:
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_SET_OPERATION_MODE,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
ATTR_OPERATION_MODE: "on",
},
blocking=True,
)
results.append(mock_fcn.await_args.args)
# set_operation_mode(on): TemporaryOverride, advanced
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_set_operation_mode("on")
assert mock_fcn.await_count == 1
assert install != "default" or mock_fcn.await_args.args == (
{
"mode": "TemporaryOverride",
"state": "On",
"untilTime": "2024-07-10T12:00:00Z", # varies by install
},
)
assert mock_fcn.await_args.kwargs == {}
results.append(mock_fcn.await_args.args)
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
results.append(mock_fcn.await_args.args)
assert results == snapshot
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_away_mode_off(
hass: HomeAssistant,
config: dict[str, str],
install: str,
) -> None:
"""Test water_heater services of a evohome-compatible DHW zone."""
async def test_set_away_mode(hass: HomeAssistant, evohome: EvohomeClient) -> None:
"""Test SERVICE_SET_AWAY_MODE of a evohome HotWater entity."""
async for _ in setup_evohome(hass, config, install=install):
dhw = get_dhw_entity(hass)
# set_away_mode: off
with patch("evohomeasync2.hotwater.HotWater.reset_mode") as mock_fcn:
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_SET_AWAY_MODE,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
ATTR_AWAY_MODE: "off",
},
blocking=True,
)
# turn_away_mode_off(): FollowSchedule
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_turn_away_mode_off()
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
assert mock_fcn.await_args.kwargs == {}
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == (
{
"mode": "FollowSchedule",
"state": None,
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
# set_away_mode: off
with patch("evohomeasync2.hotwater.HotWater.set_off") as mock_fcn:
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_SET_AWAY_MODE,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
ATTR_AWAY_MODE: "on",
},
blocking=True,
)
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
assert mock_fcn.await_args.kwargs == {}
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_away_mode_on(
hass: HomeAssistant,
config: dict[str, str],
install: str,
) -> None:
"""Test water_heater services of a evohome-compatible DHW zone."""
async def test_turn_off(hass: HomeAssistant, evohome: EvohomeClient) -> None:
"""Test SERVICE_TURN_OFF of a evohome HotWater entity."""
async for _ in setup_evohome(hass, config, install=install):
dhw = get_dhw_entity(hass)
# turn_away_mode_on(): PermanentOverride, Off
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_turn_away_mode_on()
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == (
{
"mode": "PermanentOverride",
"state": "Off",
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
# Entity water_heater.domestic_hot_water does not support this service
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_TURN_OFF,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
},
blocking=True,
)
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_off(
hass: HomeAssistant,
config: dict[str, str],
install: str,
) -> None:
"""Test water_heater services of a evohome-compatible DHW zone."""
async def test_turn_on(hass: HomeAssistant, evohome: EvohomeClient) -> None:
"""Test SERVICE_TURN_ON of a evohome HotWater entity."""
async for _ in setup_evohome(hass, config, install=install):
dhw = get_dhw_entity(hass)
# turn_off(): PermanentOverride, Off
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_turn_off()
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == (
{
"mode": "PermanentOverride",
"state": "Off",
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_on(
hass: HomeAssistant,
config: dict[str, str],
install: str,
) -> None:
"""Test water_heater services of a evohome-compatible DHW zone."""
async for _ in setup_evohome(hass, config, install=install):
dhw = get_dhw_entity(hass)
# turn_on(): PermanentOverride, On
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn:
await dhw.async_turn_on()
assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == (
{
"mode": "PermanentOverride",
"state": "On",
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
# Entity water_heater.domestic_hot_water does not support this service
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
Platform.WATER_HEATER,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: DHW_ENTITY_ID,
},
blocking=True,
)