From 928d9ec117f34a07e67b1047c532b694380f5a2b Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 1 May 2020 00:15:53 +0200 Subject: [PATCH] Fix not condition validation and entity/device extraction (#34959) --- homeassistant/helpers/condition.py | 6 +- tests/helpers/test_condition.py | 97 +++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 5 deletions(-) diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index 61704e2d23a..535de0304a0 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -536,7 +536,7 @@ async def async_validate_condition_config( ) -> ConfigType: """Validate config.""" condition = config[CONF_CONDITION] - if condition in ("and", "or"): + if condition in ("and", "not", "or"): conditions = [] for sub_cond in config["conditions"]: sub_cond = await async_validate_condition_config(hass, sub_cond) @@ -563,7 +563,7 @@ def async_extract_entities(config: ConfigType) -> Set[str]: config = to_process.popleft() condition = config[CONF_CONDITION] - if condition in ("and", "or"): + if condition in ("and", "not", "or"): to_process.extend(config["conditions"]) continue @@ -585,7 +585,7 @@ def async_extract_devices(config: ConfigType) -> Set[str]: config = to_process.popleft() condition = config[CONF_CONDITION] - if condition in ("and", "or"): + if condition in ("and", "not", "or"): to_process.extend(config["conditions"]) continue diff --git a/tests/helpers/test_condition.py b/tests/helpers/test_condition.py index cadce628c10..03c3965fad7 100644 --- a/tests/helpers/test_condition.py +++ b/tests/helpers/test_condition.py @@ -1,10 +1,31 @@ """Test the condition helper.""" from unittest.mock import patch +import pytest + +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import condition from homeassistant.util import dt +async def test_invalid_condition(hass): + """Test if invalid condition raises.""" + with pytest.raises(HomeAssistantError): + await condition.async_from_config( + hass, + { + "condition": "invalid", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature", + "state": "100", + }, + ], + }, + ) + + async def test_and_condition(hass): """Test the 'and' condition.""" test = await condition.async_from_config( @@ -261,9 +282,46 @@ async def test_extract_entities(): "entity_id": "sensor.temperature_2", "below": 110, }, + { + "condition": "not", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature_3", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature_4", + "below": 110, + }, + ], + }, + { + "condition": "or", + "conditions": [ + { + "condition": "state", + "entity_id": "sensor.temperature_5", + "state": "100", + }, + { + "condition": "numeric_state", + "entity_id": "sensor.temperature_6", + "below": 110, + }, + ], + }, ], } - ) == {"sensor.temperature", "sensor.temperature_2"} + ) == { + "sensor.temperature", + "sensor.temperature_2", + "sensor.temperature_3", + "sensor.temperature_4", + "sensor.temperature_5", + "sensor.temperature_6", + } async def test_extract_devices(): @@ -274,6 +332,41 @@ async def test_extract_devices(): "conditions": [ {"condition": "device", "device_id": "abcd", "domain": "light"}, {"condition": "device", "device_id": "qwer", "domain": "switch"}, + { + "condition": "state", + "entity_id": "sensor.not_a_device", + "state": "100", + }, + { + "condition": "not", + "conditions": [ + { + "condition": "device", + "device_id": "abcd_not", + "domain": "light", + }, + { + "condition": "device", + "device_id": "qwer_not", + "domain": "switch", + }, + ], + }, + { + "condition": "or", + "conditions": [ + { + "condition": "device", + "device_id": "abcd_or", + "domain": "light", + }, + { + "condition": "device", + "device_id": "qwer_or", + "domain": "switch", + }, + ], + }, ], } - ) == {"abcd", "qwer"} + ) == {"abcd", "qwer", "abcd_not", "qwer_not", "abcd_or", "qwer_or"}