mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Add validation to set_humidity action in humidifier (#125863)
This commit is contained in:
parent
dd10a833db
commit
4d63bf473d
@ -18,7 +18,8 @@ from homeassistant.const import (
|
||||
SERVICE_TURN_ON,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.deprecation import (
|
||||
all_with_deprecated_constants,
|
||||
@ -45,7 +46,13 @@ from .const import ( # noqa: F401
|
||||
DOMAIN,
|
||||
MODE_AUTO,
|
||||
MODE_AWAY,
|
||||
MODE_BABY,
|
||||
MODE_BOOST,
|
||||
MODE_COMFORT,
|
||||
MODE_ECO,
|
||||
MODE_HOME,
|
||||
MODE_NORMAL,
|
||||
MODE_SLEEP,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
SERVICE_SET_MODE,
|
||||
HumidifierAction,
|
||||
@ -108,7 +115,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
vol.Coerce(int), vol.Range(min=0, max=100)
|
||||
)
|
||||
},
|
||||
"async_set_humidity",
|
||||
async_service_humidity_set,
|
||||
)
|
||||
|
||||
return True
|
||||
@ -281,6 +288,33 @@ class HumidifierEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_AT
|
||||
return features
|
||||
|
||||
|
||||
async def async_service_humidity_set(
|
||||
entity: HumidifierEntity, service_call: ServiceCall
|
||||
) -> None:
|
||||
"""Handle set humidity service."""
|
||||
humidity = service_call.data[ATTR_HUMIDITY]
|
||||
min_humidity = entity.min_humidity
|
||||
max_humidity = entity.max_humidity
|
||||
_LOGGER.debug(
|
||||
"Check valid humidity %d in range %d - %d",
|
||||
humidity,
|
||||
min_humidity,
|
||||
max_humidity,
|
||||
)
|
||||
if humidity < min_humidity or humidity > max_humidity:
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="humidity_out_of_range",
|
||||
translation_placeholders={
|
||||
"humidity": str(humidity),
|
||||
"min_humidity": str(min_humidity),
|
||||
"max_humidity": str(max_humidity),
|
||||
},
|
||||
)
|
||||
|
||||
await entity.async_set_humidity(humidity)
|
||||
|
||||
|
||||
# As we import deprecated constants from the const module, we need to add these two functions
|
||||
# otherwise this module will be logged for using deprecated constants and not the custom component
|
||||
# These can be removed if no deprecated constant are in this module anymore
|
||||
|
@ -115,5 +115,10 @@
|
||||
"name": "[%key:common::action::toggle%]",
|
||||
"description": "Toggles the humidifier on/off."
|
||||
}
|
||||
},
|
||||
"exceptions": {
|
||||
"humidity_out_of_range": {
|
||||
"message": "Provided humidity {humidity} is not valid. Accepted range is {min_humidity} to {max_humidity}."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
69
tests/components/humidifier/conftest.py
Normal file
69
tests/components/humidifier/conftest.py
Normal file
@ -0,0 +1,69 @@
|
||||
"""Fixtures for Humidifier platform tests."""
|
||||
|
||||
from collections.abc import Generator
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.humidifier import DOMAIN as HUMIDIFIER_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
MockModule,
|
||||
mock_config_flow,
|
||||
mock_integration,
|
||||
mock_platform,
|
||||
)
|
||||
|
||||
|
||||
class MockFlow(ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_flow_fixture(hass: HomeAssistant) -> Generator[None]:
|
||||
"""Mock config flow."""
|
||||
mock_platform(hass, "test.config_flow")
|
||||
|
||||
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, [HUMIDIFIER_DOMAIN]
|
||||
)
|
||||
return True
|
||||
|
||||
async def help_async_unload_entry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> bool:
|
||||
"""Unload test config emntry."""
|
||||
return await hass.config_entries.async_unload_platforms(
|
||||
config_entry, [Platform.HUMIDIFIER]
|
||||
)
|
||||
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
"test",
|
||||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
)
|
||||
|
||||
return config_entry
|
@ -8,16 +8,28 @@ import pytest
|
||||
|
||||
from homeassistant.components import humidifier
|
||||
from homeassistant.components.humidifier import (
|
||||
ATTR_HUMIDITY,
|
||||
ATTR_MODE,
|
||||
DOMAIN as HUMIDIFIER_DOMAIN,
|
||||
MODE_ECO,
|
||||
MODE_NORMAL,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
HumidifierEntity,
|
||||
HumidifierEntityFeature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
|
||||
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
MockEntity,
|
||||
help_test_all,
|
||||
import_and_test_deprecated_constant_enum,
|
||||
setup_test_component_platform,
|
||||
)
|
||||
|
||||
|
||||
class MockHumidifierEntity(HumidifierEntity):
|
||||
class MockHumidifierEntity(MockEntity, HumidifierEntity):
|
||||
"""Mock Humidifier device to use in tests."""
|
||||
|
||||
@property
|
||||
@ -101,3 +113,70 @@ def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) ->
|
||||
assert "is using deprecated supported features values" not in caplog.text
|
||||
|
||||
assert entity.state_attributes[ATTR_MODE] == "mode1"
|
||||
|
||||
|
||||
async def test_humidity_validation(
|
||||
hass: HomeAssistant,
|
||||
register_test_integration: MockConfigEntry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test validation for humidity."""
|
||||
|
||||
class MockHumidifierEntityHumidity(MockEntity, HumidifierEntity):
|
||||
"""Mock climate class with mocked aux heater."""
|
||||
|
||||
_attr_supported_features = HumidifierEntityFeature.MODES
|
||||
_attr_available_modes = [MODE_NORMAL, MODE_ECO]
|
||||
_attr_mode = MODE_NORMAL
|
||||
_attr_target_humidity = 50
|
||||
_attr_min_humidity = 50
|
||||
_attr_max_humidity = 60
|
||||
|
||||
def set_humidity(self, humidity: int) -> None:
|
||||
"""Set new target humidity."""
|
||||
self._attr_target_humidity = humidity
|
||||
|
||||
test_humidifier = MockHumidifierEntityHumidity(
|
||||
name="Test",
|
||||
unique_id="unique_humidifier_test",
|
||||
)
|
||||
|
||||
setup_test_component_platform(
|
||||
hass, HUMIDIFIER_DOMAIN, entities=[test_humidifier], 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("humidifier.test")
|
||||
assert state.attributes.get(ATTR_HUMIDITY) == 50
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="Provided humidity 1 is not valid. Accepted range is 50 to 60",
|
||||
) as exc:
|
||||
await hass.services.async_call(
|
||||
HUMIDIFIER_DOMAIN,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
{
|
||||
"entity_id": "humidifier.test",
|
||||
ATTR_HUMIDITY: "1",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert exc.value.translation_key == "humidity_out_of_range"
|
||||
assert "Check valid humidity 1 in range 50 - 60" in caplog.text
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="Provided humidity 70 is not valid. Accepted range is 50 to 60",
|
||||
) as exc:
|
||||
await hass.services.async_call(
|
||||
HUMIDIFIER_DOMAIN,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
{
|
||||
"entity_id": "humidifier.test",
|
||||
ATTR_HUMIDITY: "70",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user