mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Allow nested schema validation in event automation trigger (#126771)
* Allow nested schema validation in event automation trigger * Fix rfxtrx device trigger * Don't create nested voluptuous schemas * Fix editing mistake * Fix format --------- Co-authored-by: Erik Montnemery <erik@montnemery.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
c14d17f88c
commit
3dc7b75e4b
@ -75,14 +75,18 @@ async def async_attach_trigger(
|
|||||||
event_data.update(
|
event_data.update(
|
||||||
template.render_complex(config[CONF_EVENT_DATA], variables, limited=True)
|
template.render_complex(config[CONF_EVENT_DATA], variables, limited=True)
|
||||||
)
|
)
|
||||||
# Build the schema or a an items view if the schema is simple
|
|
||||||
# and does not contain sub-dicts. We explicitly do not check for
|
# For performance reasons, we want to avoid using a voluptuous schema here
|
||||||
# list like the context data below since lists are a special case
|
# unless required. Thus, if possible, we try to use a simple items comparison
|
||||||
# only for context data. (see test test_event_data_with_list)
|
# For that, we explicitly do not check for list like the context data below
|
||||||
|
# since lists are a special case only used for context data, see test
|
||||||
|
# test_event_data_with_list. Otherwise, we build a volutupus schema, see test
|
||||||
|
# test_event_data_with_list_nested
|
||||||
if any(isinstance(value, dict) for value in event_data.values()):
|
if any(isinstance(value, dict) for value in event_data.values()):
|
||||||
event_data_schema = vol.Schema(
|
event_data_schema = vol.Schema(
|
||||||
{vol.Required(key): value for key, value in event_data.items()},
|
event_data,
|
||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
required=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Use a simple items comparison if possible
|
# Use a simple items comparison if possible
|
||||||
|
@ -97,7 +97,7 @@ async def async_attach_trigger(
|
|||||||
if config[CONF_TYPE] == CONF_TYPE_COMMAND:
|
if config[CONF_TYPE] == CONF_TYPE_COMMAND:
|
||||||
event_data["values"] = {"Command": config[CONF_SUBTYPE]}
|
event_data["values"] = {"Command": config[CONF_SUBTYPE]}
|
||||||
elif config[CONF_TYPE] == CONF_TYPE_STATUS:
|
elif config[CONF_TYPE] == CONF_TYPE_STATUS:
|
||||||
event_data["values"] = {"Status": config[CONF_SUBTYPE]}
|
event_data["values"] = {"Sensor Status": config[CONF_SUBTYPE]}
|
||||||
|
|
||||||
event_config = event_trigger.TRIGGER_SCHEMA(
|
event_config = event_trigger.TRIGGER_SCHEMA(
|
||||||
{
|
{
|
||||||
|
@ -517,6 +517,51 @@ async def test_event_data_with_list(
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(service_calls) == 1
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
# don't match if property doesn't exist at all
|
||||||
|
hass.bus.async_fire("test_event", {"other_attr": [1, 2]})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_event_data_with_list_nested(
|
||||||
|
hass: HomeAssistant, service_calls: list[ServiceCall]
|
||||||
|
) -> None:
|
||||||
|
"""Test the (non)firing of event when the data schema has nested lists."""
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
automation.DOMAIN,
|
||||||
|
{
|
||||||
|
automation.DOMAIN: {
|
||||||
|
"trigger": {
|
||||||
|
"platform": "event",
|
||||||
|
"event_type": "test_event",
|
||||||
|
"event_data": {"service_data": {"some_attr": [1, 2]}},
|
||||||
|
"context": {},
|
||||||
|
},
|
||||||
|
"action": {"service": "test.automation"},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
hass.bus.async_fire("test_event", {"service_data": {"some_attr": [1, 2]}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
# don't match a single value
|
||||||
|
hass.bus.async_fire("test_event", {"service_data": {"some_attr": 1}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
# don't match a containing list
|
||||||
|
hass.bus.async_fire("test_event", {"service_data": {"some_attr": [1, 2, 3]}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
# don't match if property doesn't exist at all
|
||||||
|
hass.bus.async_fire("test_event", {"service_data": {"other_attr": [1, 2]}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(service_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"event_type", ["state_reported", ["test_event", "state_reported"]]
|
"event_type", ["state_reported", ["test_event", "state_reported"]]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user