From 30def802fc6a54881a2dba6886df655d9739bd97 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 13 Jul 2021 04:42:35 -0400 Subject: [PATCH] Validate tone is valid when processing siren.turn_on service call (#52953) * Validate tone is valid when processing siren.turn_on service call * Better message --- homeassistant/components/siren/__init__.py | 16 +++++++++++++--- tests/components/demo/test_siren.py | 10 ++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/siren/__init__.py b/homeassistant/components/siren/__init__.py index f571f87c93e..e5e03088a49 100644 --- a/homeassistant/components/siren/__init__.py +++ b/homeassistant/components/siren/__init__.py @@ -51,14 +51,24 @@ class SirenTurnOnServiceParameters(TypedDict, total=False): volume_level: float -def filter_turn_on_params( +def process_turn_on_params( siren: SirenEntity, params: SirenTurnOnServiceParameters ) -> SirenTurnOnServiceParameters: - """Filter out params not supported by the siren.""" + """ + Process turn_on service params. + + Filters out unsupported params and validates the rest. + """ supported_features = siren.supported_features or 0 if not supported_features & SUPPORT_TONES: params.pop(ATTR_TONE, None) + elif ATTR_TONE in params and ( + not siren.available_tones + or (tone := params[ATTR_TONE]) not in siren.available_tones + ): + raise ValueError(f"Tone {tone} is not a valid tone for this device") + if not supported_features & SUPPORT_DURATION: params.pop(ATTR_DURATION, None) if not supported_features & SUPPORT_VOLUME_SET: @@ -84,7 +94,7 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: if k in (ATTR_TONE, ATTR_DURATION, ATTR_VOLUME_LEVEL) } await siren.async_turn_on( - **filter_turn_on_params(siren, cast(SirenTurnOnServiceParameters, data)) + **process_turn_on_params(siren, cast(SirenTurnOnServiceParameters, data)) ) component.async_register_entity_service( diff --git a/tests/components/demo/test_siren.py b/tests/components/demo/test_siren.py index 117343d2958..9af31b53c74 100644 --- a/tests/components/demo/test_siren.py +++ b/tests/components/demo/test_siren.py @@ -5,6 +5,7 @@ import pytest from homeassistant.components.siren.const import ( ATTR_AVAILABLE_TONES, + ATTR_TONE, ATTR_VOLUME_LEVEL, DOMAIN, ) @@ -56,6 +57,15 @@ async def test_turn_on(hass): state = hass.states.get(ENTITY_SIREN) assert state.state == STATE_ON + # Test that an invalid tone will raise a ValueError + with pytest.raises(ValueError): + await hass.services.async_call( + DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: ENTITY_SIREN_WITH_ALL_FEATURES, ATTR_TONE: "invalid_tone"}, + blocking=True, + ) + async def test_turn_off(hass): """Test turn off device."""