Add tests

This commit is contained in:
G Johansson 2025-07-05 15:20:28 +00:00
parent ddaf021957
commit ec47ef7cdb
2 changed files with 215 additions and 13 deletions

View File

@ -4,10 +4,17 @@ from collections.abc import Generator
import pytest
from homeassistant.config_entries import ConfigFlow
from homeassistant.config_entries import ConfigEntry, ConfigFlow
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from tests.common import mock_config_flow, mock_platform
from tests.common import (
MockConfigEntry,
MockModule,
mock_config_flow,
mock_integration,
mock_platform,
)
class MockFlow(ConfigFlow):
@ -21,3 +28,41 @@ def config_flow_fixture(hass: HomeAssistant) -> Generator[None]:
with mock_config_flow("test", MockFlow):
yield
@pytest.fixture
def register_test_integration(
hass: HomeAssistant, config_flow_fixture: None
) -> Generator:
"""Provide a mocked integration for tests."""
config_entry = MockConfigEntry(domain="test")
config_entry.add_to_hass(hass)
async def help_async_setup_entry_init(
hass: HomeAssistant, config_entry: ConfigEntry
) -> bool:
"""Set up test config entry."""
await hass.config_entries.async_forward_entry_setups(
config_entry, [Platform.WATER_HEATER]
)
return True
async def help_async_unload_entry(
hass: HomeAssistant, config_entry: ConfigEntry
) -> bool:
"""Unload test config entry."""
return await hass.config_entries.async_unload_platforms(
config_entry, [Platform.WATER_HEATER]
)
mock_integration(
hass,
MockModule(
"test",
async_setup_entry=help_async_setup_entry_init,
async_unload_entry=help_async_unload_entry,
),
)
return config_entry

View File

@ -11,8 +11,13 @@ import voluptuous as vol
from homeassistant.components import water_heater
from homeassistant.components.water_heater import (
ATTR_CURRENT_TEMPERATURE,
ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW,
ATTR_TEMPERATURE,
DOMAIN,
SERVICE_SET_OPERATION_MODE,
SERVICE_SET_TEMPERATURE,
SET_TEMPERATURE_SCHEMA,
WaterHeaterEntity,
WaterHeaterEntityDescription,
@ -22,17 +27,18 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from tests.common import (
MockConfigEntry,
MockEntity,
MockModule,
MockPlatform,
async_mock_service,
import_and_test_deprecated_constant,
mock_integration,
mock_platform,
setup_test_component_platform,
)
@ -40,14 +46,13 @@ async def test_set_temp_schema_no_req(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test the set temperature schema with missing required data."""
domain = "climate"
service = "test_set_temperature"
schema = cv.make_entity_service_schema(SET_TEMPERATURE_SCHEMA)
calls = async_mock_service(hass, domain, service, schema)
schema = SET_TEMPERATURE_SCHEMA
calls = async_mock_service(hass, DOMAIN, service, schema)
data = {"hvac_mode": "off", "entity_id": ["climate.test_id"]}
data = {"hvac_mode": "off", "entity_id": ["water_heater.test_id"]}
with pytest.raises(vol.Invalid):
await hass.services.async_call(domain, service, data)
await hass.services.async_call(DOMAIN, service, data)
await hass.async_block_till_done()
assert len(calls) == 0
@ -57,24 +62,23 @@ async def test_set_temp_schema(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test the set temperature schema with ok required data."""
domain = "water_heater"
service = "test_set_temperature"
schema = cv.make_entity_service_schema(SET_TEMPERATURE_SCHEMA)
calls = async_mock_service(hass, domain, service, schema)
schema = SET_TEMPERATURE_SCHEMA
calls = async_mock_service(hass, DOMAIN, service, schema)
data = {
"temperature": 20.0,
"operation_mode": "gas",
"entity_id": ["water_heater.test_id"],
}
await hass.services.async_call(domain, service, data)
await hass.services.async_call(DOMAIN, service, data)
await hass.async_block_till_done()
assert len(calls) == 1
assert calls[-1].data == data
class MockWaterHeaterEntity(WaterHeaterEntity):
class MockWaterHeaterEntity(MockEntity, WaterHeaterEntity):
"""Mock water heater device to use in tests."""
_attr_operation_list: list[str] | None = ["off", "heat_pump", "gas"]
@ -237,3 +241,156 @@ def test_deprecated_constants(
replacement,
"2026.1",
)
async def test_target_temp(
hass: HomeAssistant, register_test_integration: MockConfigEntry
) -> None:
"""Test set temp service with target temperature."""
class MockWaterHeaterEntityTemp(MockWaterHeaterEntity):
"""Mock Water heater class."""
_attr_target_temperature = 15
_attr_current_temperature = 15
_attr_supported_features = (
WaterHeaterEntityFeature.ON_OFF
| WaterHeaterEntityFeature.TARGET_TEMPERATURE
)
def set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if ATTR_TEMPERATURE in kwargs:
self._attr_target_temperature = kwargs[ATTR_TEMPERATURE]
if ATTR_TARGET_TEMP_HIGH in kwargs:
self._attr_target_temperature_high = kwargs[ATTR_TARGET_TEMP_HIGH]
self._attr_target_temperature_low = kwargs[ATTR_TARGET_TEMP_LOW]
test_heater = MockWaterHeaterEntityTemp(
name="Test",
unique_id="unique_heater_test",
)
setup_test_component_platform(
hass, DOMAIN, entities=[test_heater], from_config_entry=True
)
await hass.config_entries.async_setup(register_test_integration.entry_id)
await hass.async_block_till_done()
state = hass.states.get("water_heater.test")
assert state.attributes.get(ATTR_CURRENT_TEMPERATURE) == 15
assert state.attributes.get(ATTR_TEMPERATURE) == 15
assert state.attributes.get(ATTR_TARGET_TEMP_HIGH) is None
assert state.attributes.get(ATTR_TARGET_TEMP_LOW) is None
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "water_heater.test",
ATTR_TEMPERATURE: "20",
},
blocking=True,
)
state = hass.states.get("water_heater.test")
assert state.attributes.get(ATTR_TEMPERATURE) == 20
with pytest.raises(
ServiceValidationError,
match="Set temperature action was used with the target temperature low/high parameter but the entity does not support it",
) as exc:
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "water_heater.test",
ATTR_TARGET_TEMP_HIGH: "20",
ATTR_TARGET_TEMP_LOW: "15",
},
blocking=True,
)
assert (
str(exc.value)
== "Set temperature action was used with the target temperature low/high parameter but the entity does not support it"
)
assert (
exc.value.translation_key == "missing_target_temperature_range_entity_feature"
)
async def test_target_temp_range(
hass: HomeAssistant, register_test_integration: MockConfigEntry
) -> None:
"""Test set temp service with target temperature range."""
class MockWaterHeaterEntityTemp(MockWaterHeaterEntity):
"""Mock Water heater class."""
_attr_target_temperature = 15
_attr_target_temperature_low = 10
_attr_target_temperature_high = 20
_attr_current_temperature = 15
_attr_supported_features = (
WaterHeaterEntityFeature.ON_OFF
| WaterHeaterEntityFeature.TARGET_TEMPERATURE_RANGE
)
def set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if ATTR_TEMPERATURE in kwargs:
self._attr_target_temperature = kwargs[ATTR_TEMPERATURE]
if ATTR_TARGET_TEMP_HIGH in kwargs:
self._attr_target_temperature_high = kwargs[ATTR_TARGET_TEMP_HIGH]
self._attr_target_temperature_low = kwargs[ATTR_TARGET_TEMP_LOW]
test_heater = MockWaterHeaterEntityTemp(
name="Test",
unique_id="unique_heater_test",
)
setup_test_component_platform(
hass, DOMAIN, entities=[test_heater], from_config_entry=True
)
await hass.config_entries.async_setup(register_test_integration.entry_id)
await hass.async_block_till_done()
state = hass.states.get("water_heater.test")
assert state.attributes.get(ATTR_CURRENT_TEMPERATURE) == 15
assert state.attributes.get(ATTR_TEMPERATURE) == 15
assert state.attributes.get(ATTR_TARGET_TEMP_HIGH) == 20
assert state.attributes.get(ATTR_TARGET_TEMP_LOW) == 10
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "water_heater.test",
ATTR_TARGET_TEMP_HIGH: "20",
ATTR_TARGET_TEMP_LOW: "15",
},
blocking=True,
)
state = hass.states.get("water_heater.test")
assert state.attributes.get(ATTR_TARGET_TEMP_HIGH) == 20
assert state.attributes.get(ATTR_TARGET_TEMP_LOW) == 15
with pytest.raises(
ServiceValidationError,
match="Set temperature action was used with the target temperature parameter but the entity does not support it",
) as exc:
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "water_heater.test",
ATTR_TEMPERATURE: "15",
},
blocking=True,
)
assert (
str(exc.value)
== "Set temperature action was used with the target temperature parameter but the entity does not support it"
)
assert exc.value.translation_key == "missing_target_temperature_entity_feature"