From a033ef0f95252ed3378683845aed3ff717eaeb72 Mon Sep 17 00:00:00 2001 From: Joostlek Date: Wed, 25 Sep 2024 14:46:38 +0200 Subject: [PATCH 1/4] Add check for missing trigger --- .../components/device_automation/__init__.py | 2 +- homeassistant/helpers/config_validation.py | 6 ++++-- tests/helpers/test_config_validation.py | 15 +++++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/device_automation/__init__.py b/homeassistant/components/device_automation/__init__.py index 2c6e80e5f49c5..a75a4216475bd 100644 --- a/homeassistant/components/device_automation/__init__.py +++ b/homeassistant/components/device_automation/__init__.py @@ -484,7 +484,7 @@ async def websocket_device_automation_get_condition_capabilities( # The frontend responds with `trigger` as key, while the # `DEVICE_TRIGGER_BASE_SCHEMA` expects `platform1` as key. vol.Required("trigger"): vol.All( - cv._backward_compat_trigger_schema, # noqa: SLF001 + cv._trigger_pre_validator, # noqa: SLF001 DEVICE_TRIGGER_BASE_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), ), } diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 8b190abad923f..111247f25612e 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1771,7 +1771,7 @@ def STATE_CONDITION_SCHEMA(value: Any) -> dict[str, Any]: ) -def _backward_compat_trigger_schema(value: Any | None) -> Any: +def _trigger_pre_validator(value: Any | None) -> Any: """Rewrite trigger `trigger` to `platform`. `platform` has been renamed to `trigger` in user documentation and in the automation @@ -1790,6 +1790,8 @@ def _backward_compat_trigger_schema(value: Any | None) -> Any: ) value = dict(value) value[CONF_PLATFORM] = value.pop(CONF_TRIGGER) + elif CONF_PLATFORM not in value: + raise vol.Invalid("Missing 'trigger' key in trigger.") return value @@ -1831,7 +1833,7 @@ def _base_trigger_validator(value: Any) -> Any: TRIGGER_SCHEMA = vol.All( ensure_list, _base_trigger_list_flatten, - [vol.All(_backward_compat_trigger_schema, _base_trigger_validator)], + [vol.All(_trigger_pre_validator, _base_trigger_validator)], ) _SCRIPT_DELAY_SCHEMA = vol.Schema( diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index 4fd87d6d2fe51..25440456b8538 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -1911,16 +1911,19 @@ async def test_nested_trigger_list_extra() -> None: async def test_trigger_backwards_compatibility() -> None: """Test triggers with backwards compatibility.""" - assert cv._backward_compat_trigger_schema("str") == "str" - assert cv._backward_compat_trigger_schema({"platform": "abc"}) == { - "platform": "abc" - } - assert cv._backward_compat_trigger_schema({"trigger": "abc"}) == {"platform": "abc"} + assert cv._trigger_pre_validator("str") == "str" + assert cv._trigger_pre_validator({"platform": "abc"}) == {"platform": "abc"} + assert cv._trigger_pre_validator({"trigger": "abc"}) == {"platform": "abc"} with pytest.raises( vol.Invalid, match="Cannot specify both 'platform' and 'trigger'. Please use 'trigger' only.", ): - cv._backward_compat_trigger_schema({"trigger": "abc", "platform": "def"}) + cv._trigger_pre_validator({"trigger": "abc", "platform": "def"}) + with pytest.raises( + vol.Invalid, + match="Missing 'trigger' key in trigger.", + ): + cv._trigger_pre_validator({}) async def test_is_entity_service_schema( From e87e54559bfaef32c7bba836996d2bdc3867339e Mon Sep 17 00:00:00 2001 From: Joostlek Date: Wed, 25 Sep 2024 15:06:04 +0200 Subject: [PATCH 2/4] Fix --- homeassistant/helpers/config_validation.py | 2 +- tests/helpers/test_config_validation.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 111247f25612e..129649e3ba3ac 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1791,7 +1791,7 @@ def _trigger_pre_validator(value: Any | None) -> Any: value = dict(value) value[CONF_PLATFORM] = value.pop(CONF_TRIGGER) elif CONF_PLATFORM not in value: - raise vol.Invalid("Missing 'trigger' key in trigger.") + raise vol.Invalid("required key not provided", ["trigger"]) return value diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index 25440456b8538..cf3fbefb6ed6e 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -1921,7 +1921,7 @@ async def test_trigger_backwards_compatibility() -> None: cv._trigger_pre_validator({"trigger": "abc", "platform": "def"}) with pytest.raises( vol.Invalid, - match="Missing 'trigger' key in trigger.", + match="required key not provided @ data['trigger']", ): cv._trigger_pre_validator({}) From e92fc0b58248e56a98a5a9c4422267e7e9265549 Mon Sep 17 00:00:00 2001 From: Joostlek Date: Wed, 25 Sep 2024 15:22:39 +0200 Subject: [PATCH 3/4] Fix --- homeassistant/helpers/config_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 129649e3ba3ac..98a2cd719314a 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1791,7 +1791,7 @@ def _trigger_pre_validator(value: Any | None) -> Any: value = dict(value) value[CONF_PLATFORM] = value.pop(CONF_TRIGGER) elif CONF_PLATFORM not in value: - raise vol.Invalid("required key not provided", ["trigger"]) + raise vol.Invalid("required key not provided", [CONF_TRIGGER]) return value From 91b8b4cabb11e51145f081dd43bd91eb7a3f2f72 Mon Sep 17 00:00:00 2001 From: Joostlek Date: Wed, 25 Sep 2024 15:45:11 +0200 Subject: [PATCH 4/4] Escape --- tests/helpers/test_config_validation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index cf3fbefb6ed6e..7202cef6f5f4a 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -6,6 +6,7 @@ from functools import partial import logging import os +import re from socket import _GLOBAL_DEFAULT_TIMEOUT import threading from typing import Any @@ -1921,7 +1922,7 @@ async def test_trigger_backwards_compatibility() -> None: cv._trigger_pre_validator({"trigger": "abc", "platform": "def"}) with pytest.raises( vol.Invalid, - match="required key not provided @ data['trigger']", + match=re.escape("required key not provided @ data['trigger']"), ): cv._trigger_pre_validator({})