From 3810c3cbaf2037f3474ed19c0b9bfd19e1a308a8 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Wed, 25 Sep 2024 16:44:14 +0200 Subject: [PATCH] Improve trigger schema validation to ask for `trigger` instead of `platform` (#126750) * Add check for missing trigger * Fix * Fix * Escape --- .../components/device_automation/__init__.py | 2 +- homeassistant/helpers/config_validation.py | 6 ++++-- tests/helpers/test_config_validation.py | 16 ++++++++++------ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/device_automation/__init__.py b/homeassistant/components/device_automation/__init__.py index 2c6e80e5f49..a75a4216475 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 8b190abad92..98a2cd71931 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1771,7 +1771,7 @@ CONDITION_ACTION_SCHEMA: vol.Schema = vol.Schema( ) -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("required key not provided", [CONF_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 4fd87d6d2fe..7202cef6f5f 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -6,6 +6,7 @@ import enum from functools import partial import logging import os +import re from socket import _GLOBAL_DEFAULT_TIMEOUT import threading from typing import Any @@ -1911,16 +1912,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=re.escape("required key not provided @ data['trigger']"), + ): + cv._trigger_pre_validator({}) async def test_is_entity_service_schema(