mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add check for invalid options with specific platforms (#140082)
This commit is contained in:
parent
99b5adaef1
commit
293d455cba
@ -1,5 +1,6 @@
|
|||||||
"""Template config validator."""
|
"""Template config validator."""
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -52,41 +53,63 @@ from .helpers import async_get_blueprints
|
|||||||
|
|
||||||
PACKAGE_MERGE_HINT = "list"
|
PACKAGE_MERGE_HINT = "list"
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_domains_do_not_have_trigger_or_action(*keys: str) -> Callable[[dict], dict]:
|
||||||
|
"""Validate that config does not contain trigger and action."""
|
||||||
|
domains = set(keys)
|
||||||
|
|
||||||
|
def validate(obj: dict):
|
||||||
|
options = set(obj.keys())
|
||||||
|
if found_domains := domains.intersection(options):
|
||||||
|
invalid = {CONF_TRIGGER, CONF_ACTION}
|
||||||
|
if found_invalid := invalid.intersection(set(obj.keys())):
|
||||||
|
raise vol.Invalid(
|
||||||
|
f"Unsupported option(s) found for domain {found_domains.pop()}, please remove ({', '.join(found_invalid)}) from your configuration",
|
||||||
|
)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
return validate
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SECTION_SCHEMA = vol.Schema(
|
CONFIG_SECTION_SCHEMA = vol.Schema(
|
||||||
{
|
vol.All(
|
||||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
{
|
||||||
vol.Optional(CONF_TRIGGER): cv.TRIGGER_SCHEMA,
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||||
vol.Optional(CONF_CONDITION): cv.CONDITIONS_SCHEMA,
|
vol.Optional(CONF_TRIGGER): cv.TRIGGER_SCHEMA,
|
||||||
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
|
vol.Optional(CONF_CONDITION): cv.CONDITIONS_SCHEMA,
|
||||||
vol.Optional(CONF_VARIABLES): cv.SCRIPT_VARIABLES_SCHEMA,
|
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
|
||||||
vol.Optional(NUMBER_DOMAIN): vol.All(
|
vol.Optional(CONF_VARIABLES): cv.SCRIPT_VARIABLES_SCHEMA,
|
||||||
cv.ensure_list, [number_platform.NUMBER_SCHEMA]
|
vol.Optional(NUMBER_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [number_platform.NUMBER_SCHEMA]
|
||||||
vol.Optional(SENSOR_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [sensor_platform.SENSOR_SCHEMA]
|
vol.Optional(SENSOR_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [sensor_platform.SENSOR_SCHEMA]
|
||||||
vol.Optional(CONF_SENSORS): cv.schema_with_slug_keys(
|
),
|
||||||
sensor_platform.LEGACY_SENSOR_SCHEMA
|
vol.Optional(CONF_SENSORS): cv.schema_with_slug_keys(
|
||||||
),
|
sensor_platform.LEGACY_SENSOR_SCHEMA
|
||||||
vol.Optional(BINARY_SENSOR_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [binary_sensor_platform.BINARY_SENSOR_SCHEMA]
|
vol.Optional(BINARY_SENSOR_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [binary_sensor_platform.BINARY_SENSOR_SCHEMA]
|
||||||
vol.Optional(CONF_BINARY_SENSORS): cv.schema_with_slug_keys(
|
),
|
||||||
binary_sensor_platform.LEGACY_BINARY_SENSOR_SCHEMA
|
vol.Optional(CONF_BINARY_SENSORS): cv.schema_with_slug_keys(
|
||||||
),
|
binary_sensor_platform.LEGACY_BINARY_SENSOR_SCHEMA
|
||||||
vol.Optional(SELECT_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [select_platform.SELECT_SCHEMA]
|
vol.Optional(SELECT_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [select_platform.SELECT_SCHEMA]
|
||||||
vol.Optional(BUTTON_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [button_platform.BUTTON_SCHEMA]
|
vol.Optional(BUTTON_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [button_platform.BUTTON_SCHEMA]
|
||||||
vol.Optional(IMAGE_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [image_platform.IMAGE_SCHEMA]
|
vol.Optional(IMAGE_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [image_platform.IMAGE_SCHEMA]
|
||||||
vol.Optional(WEATHER_DOMAIN): vol.All(
|
),
|
||||||
cv.ensure_list, [weather_platform.WEATHER_SCHEMA]
|
vol.Optional(WEATHER_DOMAIN): vol.All(
|
||||||
),
|
cv.ensure_list, [weather_platform.WEATHER_SCHEMA]
|
||||||
},
|
),
|
||||||
|
},
|
||||||
|
ensure_domains_do_not_have_trigger_or_action(BUTTON_DOMAIN),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
TEMPLATE_BLUEPRINT_INSTANCE_SCHEMA = vol.Schema(
|
TEMPLATE_BLUEPRINT_INSTANCE_SCHEMA = vol.Schema(
|
||||||
|
50
tests/components/template/test_config.py
Normal file
50
tests/components/template/test_config.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
"""Test Template config."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.template.config import CONFIG_SECTION_SCHEMA
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"config",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"trigger": {"trigger": "event", "event_type": "my_event"},
|
||||||
|
"button": {
|
||||||
|
"press": {
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {"caller": "{{ this.entity_id }}"},
|
||||||
|
},
|
||||||
|
"device_class": "restart",
|
||||||
|
"unique_id": "test",
|
||||||
|
"name": "test",
|
||||||
|
"icon": "mdi:test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"trigger": {"trigger": "event", "event_type": "my_event"},
|
||||||
|
"action": {
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {"caller": "{{ this.entity_id }}"},
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"press": {
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {"caller": "{{ this.entity_id }}"},
|
||||||
|
},
|
||||||
|
"device_class": "restart",
|
||||||
|
"unique_id": "test",
|
||||||
|
"name": "test",
|
||||||
|
"icon": "mdi:test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_invalid_schema(hass: HomeAssistant, config: dict) -> None:
|
||||||
|
"""Test invalid config schemas."""
|
||||||
|
with pytest.raises(vol.Invalid):
|
||||||
|
CONFIG_SECTION_SCHEMA(config)
|
Loading…
x
Reference in New Issue
Block a user