From 67243091ce23ca017441d70db636a83d9b133762 Mon Sep 17 00:00:00 2001 From: David Bonnes Date: Sun, 5 Apr 2026 21:53:49 +0000 Subject: [PATCH 1/5] Use fixtures for all evohome entity_ids --- tests/components/evohome/conftest.py | 52 +++++++++++++++---- tests/components/evohome/test_water_heater.py | 27 ++++------ 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index ca960cefb2244..42ed5cfabe94b 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -8,7 +8,7 @@ from typing import Any from unittest.mock import MagicMock, patch -from evohomeasync2 import EvohomeClient +from evohomeasync2 import EvohomeClient, HotWater from evohomeasync2.auth import AbstractTokenManager, Auth from evohomeasync2.control_system import ControlSystem from evohomeasync2.zone import Zone @@ -18,8 +18,9 @@ from homeassistant.components.evohome.const import DOMAIN from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component -from homeassistant.util import dt as dt_util, slugify +from homeassistant.util import dt as dt_util from homeassistant.util.json import JsonArrayType, JsonObjectType from .const import ACCESS_TOKEN, REFRESH_TOKEN, SESSION_ID, USERNAME @@ -210,20 +211,53 @@ async def evohome( @pytest.fixture -def ctl_id(evohome: MagicMock) -> str: - """Return the entity_id of the evohome integration's controller.""" +def ctl_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str: + """Return the entity_id of evohome's controller (a Climate entity).""" evo: EvohomeClient = evohome.return_value - ctl: ControlSystem = evo.tcs + tcs: ControlSystem = evo.tcs - return f"{Platform.CLIMATE}.{slugify(ctl.location.name)}" + return entity_id(Platform.CLIMATE, tcs.id) @pytest.fixture -def zone_id(evohome: MagicMock) -> str: - """Return the entity_id of the evohome integration's first zone.""" +def zone_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str: + """Return the entity_id of evohome's first zone (a Climate entity).""" evo: EvohomeClient = evohome.return_value + ctl: ControlSystem = evo.tcs + zone: Zone = evo.tcs.zones[0] - return f"{Platform.CLIMATE}.{slugify(zone.name)}" + return entity_id(Platform.CLIMATE, f"{zone.id}z" if zone.id == ctl.id else zone.id) + + +@pytest.fixture +def dhw_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str: + """Return the entity_id of Evohome's DHW controller (a WaterHeater entity).""" + + evo: EvohomeClient = evohome.return_value + dhw: HotWater | None = evo.tcs.hotwater + + if dhw is None: + pytest.skip("Fixture has no DHW zone") + + return entity_id(Platform.WATER_HEATER, dhw.id) + + +@pytest.fixture +def entity_id(hass: HomeAssistant) -> Callable[[Platform, str], str]: + """Return a helper to lookup an entity_id from platform and unique_id.""" + + entity_registry = er.async_get(hass) + + def get_entity_id(platform: Platform, unique_id: str) -> str: + """Return an entity_id from the entity registry.""" + + entity = entity_registry.async_get_entity_id(platform, DOMAIN, unique_id) + assert entity is not None, ( + f"Entity not found for platform={platform}: {unique_id}" + ) + return entity + + return get_entity_id diff --git a/tests/components/evohome/test_water_heater.py b/tests/components/evohome/test_water_heater.py index ba2e33e85b880..7d0123f2962eb 100644 --- a/tests/components/evohome/test_water_heater.py +++ b/tests/components/evohome/test_water_heater.py @@ -24,8 +24,6 @@ from .conftest import setup_evohome from .const import TEST_INSTALLS_WITH_DHW -DHW_ENTITY_ID = "water_heater.domestic_hot_water" - @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) async def test_setup_platform( @@ -49,9 +47,9 @@ async def test_setup_platform( @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) -@pytest.mark.usefixtures("evohome") async def test_set_operation_mode( hass: HomeAssistant, + dhw_id: str, freezer: FrozenDateTimeFactory, snapshot: SnapshotAssertion, ) -> None: @@ -66,7 +64,7 @@ async def test_set_operation_mode( WATER_HEATER_DOMAIN, SERVICE_SET_OPERATION_MODE, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, ATTR_OPERATION_MODE: "auto", }, blocking=True, @@ -80,7 +78,7 @@ async def test_set_operation_mode( WATER_HEATER_DOMAIN, SERVICE_SET_OPERATION_MODE, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, ATTR_OPERATION_MODE: "off", }, blocking=True, @@ -100,7 +98,7 @@ async def test_set_operation_mode( WATER_HEATER_DOMAIN, SERVICE_SET_OPERATION_MODE, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, ATTR_OPERATION_MODE: "on", }, blocking=True, @@ -118,8 +116,7 @@ async def test_set_operation_mode( @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) -@pytest.mark.usefixtures("evohome") -async def test_set_away_mode(hass: HomeAssistant) -> None: +async def test_set_away_mode(hass: HomeAssistant, dhw_id: str) -> None: """Test SERVICE_SET_AWAY_MODE of an evohome DHW zone.""" # set_away_mode: off @@ -128,7 +125,7 @@ async def test_set_away_mode(hass: HomeAssistant) -> None: WATER_HEATER_DOMAIN, SERVICE_SET_AWAY_MODE, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, ATTR_AWAY_MODE: "off", }, blocking=True, @@ -142,7 +139,7 @@ async def test_set_away_mode(hass: HomeAssistant) -> None: WATER_HEATER_DOMAIN, SERVICE_SET_AWAY_MODE, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, ATTR_AWAY_MODE: "on", }, blocking=True, @@ -152,8 +149,7 @@ async def test_set_away_mode(hass: HomeAssistant) -> None: @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) -@pytest.mark.usefixtures("evohome") -async def test_turn_off(hass: HomeAssistant) -> None: +async def test_turn_off(hass: HomeAssistant, dhw_id: str) -> None: """Test SERVICE_TURN_OFF of an evohome DHW zone.""" # turn_off @@ -162,7 +158,7 @@ async def test_turn_off(hass: HomeAssistant) -> None: WATER_HEATER_DOMAIN, SERVICE_TURN_OFF, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, }, blocking=True, ) @@ -171,8 +167,7 @@ async def test_turn_off(hass: HomeAssistant) -> None: @pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW) -@pytest.mark.usefixtures("evohome") -async def test_turn_on(hass: HomeAssistant) -> None: +async def test_turn_on(hass: HomeAssistant, dhw_id: str) -> None: """Test SERVICE_TURN_ON of an evohome DHW zone.""" # turn_on @@ -181,7 +176,7 @@ async def test_turn_on(hass: HomeAssistant) -> None: WATER_HEATER_DOMAIN, SERVICE_TURN_ON, { - ATTR_ENTITY_ID: DHW_ENTITY_ID, + ATTR_ENTITY_ID: dhw_id, }, blocking=True, ) From 0132ca932b62b3ff61408aacf71852fa96f5fbe9 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Mon, 6 Apr 2026 12:02:44 +0200 Subject: [PATCH 2/5] Apply suggestion from @joostlek --- tests/components/evohome/conftest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index 42ed5cfabe94b..6fa2488f12d1e 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -246,11 +246,9 @@ def dhw_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str @pytest.fixture -def entity_id(hass: HomeAssistant) -> Callable[[Platform, str], str]: +def entity_id(hass: HomeAssistant, entity_registry: er.EntityRegistry) -> Callable[[Platform, str], str]: """Return a helper to lookup an entity_id from platform and unique_id.""" - entity_registry = er.async_get(hass) - def get_entity_id(platform: Platform, unique_id: str) -> str: """Return an entity_id from the entity registry.""" From 97ec15cef88ffb5325679bf2586406d4c5b44160 Mon Sep 17 00:00:00 2001 From: David Bonnes Date: Mon, 6 Apr 2026 22:09:10 +0100 Subject: [PATCH 3/5] Update tests/components/evohome/conftest.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/components/evohome/conftest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index 6fa2488f12d1e..ff90391ccdc77 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -239,8 +239,7 @@ def dhw_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str evo: EvohomeClient = evohome.return_value dhw: HotWater | None = evo.tcs.hotwater - if dhw is None: - pytest.skip("Fixture has no DHW zone") + assert dhw is not None, "Fixture has no DHW zone" return entity_id(Platform.WATER_HEATER, dhw.id) From 36b880b10ce1ab98cb6baae5345ecd67832a5a6c Mon Sep 17 00:00:00 2001 From: David Bonnes Date: Mon, 6 Apr 2026 22:10:26 +0100 Subject: [PATCH 4/5] Update tests/components/evohome/conftest.py Co-authored-by: Martin Hjelmare --- tests/components/evohome/conftest.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index ff90391ccdc77..3decf83fe7af7 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -245,7 +245,10 @@ def dhw_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str @pytest.fixture -def entity_id(hass: HomeAssistant, entity_registry: er.EntityRegistry) -> Callable[[Platform, str], str]: +def entity_id( + hass: HomeAssistant, + entity registry: er.EntityRegistry, +) -> Callable[[Platform, str], str]: """Return a helper to lookup an entity_id from platform and unique_id.""" def get_entity_id(platform: Platform, unique_id: str) -> str: From 334bcd378ba441fa05592573a8b95992027dbf16 Mon Sep 17 00:00:00 2001 From: David Bonnes Date: Mon, 6 Apr 2026 21:14:43 +0000 Subject: [PATCH 5/5] remove unreferenced fixture --- tests/components/evohome/conftest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index 3decf83fe7af7..9e35b3a87244c 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -246,8 +246,7 @@ def dhw_id(evohome: MagicMock, entity_id: Callable[[Platform, str], str]) -> str @pytest.fixture def entity_id( - hass: HomeAssistant, - entity registry: er.EntityRegistry, + entity_registry: er.EntityRegistry, ) -> Callable[[Platform, str], str]: """Return a helper to lookup an entity_id from platform and unique_id."""