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("homeassistant.components.evohome.ev1.EvohomeClient", return_value=None),
patch("evohomeasync2.broker.Broker.get", mock_get_factory(install)), 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}) assert await async_setup_component(hass, DOMAIN, {DOMAIN: config})
await hass.async_block_till_done() await hass.async_block_till_done()
@ -150,6 +157,19 @@ async def setup_evohome(
assert isinstance(mock_client.call_args.kwargs["session"], ClientSession) 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 yield mock_client

View File

@ -2,18 +2,8 @@
# name: test_set_operation_mode[default] # name: test_set_operation_mode[default]
list([ list([
tuple( tuple(
dict({
'mode': <ZoneMode.TEMPORARY_OVERRIDE: 'TemporaryOverride'>,
'state': <DhwState.OFF: 'Off'>,
'untilTime': '2024-07-10T12:00:00Z',
}),
), ),
tuple( 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 unittest.mock import patch
from evohomeasync2 import EvohomeClient
from freezegun.api import FrozenDateTimeFactory from freezegun.api import FrozenDateTimeFactory
import pytest import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
from homeassistant.components.evohome import DOMAIN from homeassistant.components.water_heater import (
from homeassistant.components.evohome.coordinator import EvoBroker ATTR_AWAY_MODE,
from homeassistant.components.evohome.water_heater import EvoDHW ATTR_OPERATION_MODE,
from homeassistant.const import Platform 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.core import HomeAssistant
from homeassistant.helpers import entity_registry as er from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_component import EntityComponent
from .conftest import setup_evohome
from .const import TEST_INSTALLS_WITH_DHW from .const import TEST_INSTALLS_WITH_DHW
DHW_ENTITY_ID = "water_heater.domestic_hot_water"
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]
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_set_operation_mode( async def test_set_operation_mode(
hass: HomeAssistant, hass: HomeAssistant,
config: dict[str, str], evohome: EvohomeClient,
install: str,
freezer: FrozenDateTimeFactory, freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion, snapshot: SnapshotAssertion,
) -> None: ) -> 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") freezer.move_to("2024-07-10T11:55:00Z")
results = [] results = []
async for _ in setup_evohome(hass, config, install=install): # SERVICE_SET_OPERATION_MODE: auto
dhw = get_dhw_entity(hass) 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 assert mock_fcn.await_count == 1
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn: assert mock_fcn.await_args.args == ()
await dhw.async_set_operation_mode("auto") assert mock_fcn.await_args.kwargs == {}
assert mock_fcn.await_count == 1 # SERVICE_SET_OPERATION_MODE: off (until next scheduled setpoint)
assert mock_fcn.await_args.args == ( with patch("evohomeasync2.hotwater.HotWater.set_off") as mock_fcn:
{ await hass.services.async_call(
"mode": "FollowSchedule", Platform.WATER_HEATER,
"state": None, SERVICE_SET_OPERATION_MODE,
"untilTime": None, {
}, ATTR_ENTITY_ID: DHW_ENTITY_ID,
) ATTR_OPERATION_MODE: "off",
assert mock_fcn.await_args.kwargs == {} },
blocking=True,
)
# set_operation_mode(off): TemporaryOverride, advanced assert mock_fcn.await_count == 1
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn: assert mock_fcn.await_args.args == ()
await dhw.async_set_operation_mode("off") results.append(mock_fcn.await_args.args)
assert mock_fcn.await_count == 1 # SERVICE_SET_OPERATION_MODE: on (until next scheduled setpoint)
assert install != "default" or mock_fcn.await_args.args == ( with patch("evohomeasync2.hotwater.HotWater.set_on") as mock_fcn:
{ await hass.services.async_call(
"mode": "TemporaryOverride", Platform.WATER_HEATER,
"state": "Off", SERVICE_SET_OPERATION_MODE,
"untilTime": "2024-07-10T12:00:00Z", # varies by install {
}, ATTR_ENTITY_ID: DHW_ENTITY_ID,
) ATTR_OPERATION_MODE: "on",
assert mock_fcn.await_args.kwargs == {} },
blocking=True,
)
results.append(mock_fcn.await_args.args) assert mock_fcn.await_count == 1
assert mock_fcn.await_args.args == ()
# set_operation_mode(on): TemporaryOverride, advanced results.append(mock_fcn.await_args.args)
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 results == snapshot assert results == snapshot
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_away_mode_off( async def test_set_away_mode(hass: HomeAssistant, evohome: EvohomeClient) -> None:
hass: HomeAssistant, """Test SERVICE_SET_AWAY_MODE of a evohome HotWater entity."""
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): # set_away_mode: off
dhw = get_dhw_entity(hass) 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 assert mock_fcn.await_count == 1
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn: assert mock_fcn.await_args.args == ()
await dhw.async_turn_away_mode_off() assert mock_fcn.await_args.kwargs == {}
assert mock_fcn.await_count == 1 # set_away_mode: off
assert mock_fcn.await_args.args == ( with patch("evohomeasync2.hotwater.HotWater.set_off") as mock_fcn:
{ await hass.services.async_call(
"mode": "FollowSchedule", Platform.WATER_HEATER,
"state": None, SERVICE_SET_AWAY_MODE,
"untilTime": None, {
}, ATTR_ENTITY_ID: DHW_ENTITY_ID,
) ATTR_AWAY_MODE: "on",
assert mock_fcn.await_args.kwargs == {} },
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) @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_away_mode_on( async def test_turn_off(hass: HomeAssistant, evohome: EvohomeClient) -> None:
hass: HomeAssistant, """Test SERVICE_TURN_OFF of a evohome HotWater entity."""
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): # Entity water_heater.domestic_hot_water does not support this service
dhw = get_dhw_entity(hass) with pytest.raises(HomeAssistantError):
await hass.services.async_call(
# turn_away_mode_on(): PermanentOverride, Off Platform.WATER_HEATER,
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn: SERVICE_TURN_OFF,
await dhw.async_turn_away_mode_on() {
ATTR_ENTITY_ID: DHW_ENTITY_ID,
assert mock_fcn.await_count == 1 },
assert mock_fcn.await_args.args == ( blocking=True,
{ )
"mode": "PermanentOverride",
"state": "Off",
"untilTime": None,
},
)
assert mock_fcn.await_args.kwargs == {}
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
async def test_turn_off( async def test_turn_on(hass: HomeAssistant, evohome: EvohomeClient) -> None:
hass: HomeAssistant, """Test SERVICE_TURN_ON of a evohome HotWater entity."""
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): # Entity water_heater.domestic_hot_water does not support this service
dhw = get_dhw_entity(hass) with pytest.raises(HomeAssistantError):
await hass.services.async_call(
# turn_off(): PermanentOverride, Off Platform.WATER_HEATER,
with patch("evohomeasync2.hotwater.HotWater._set_mode") as mock_fcn: SERVICE_TURN_ON,
await dhw.async_turn_off() {
ATTR_ENTITY_ID: DHW_ENTITY_ID,
assert mock_fcn.await_count == 1 },
assert mock_fcn.await_args.args == ( blocking=True,
{ )
"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 == {}