diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 7ec6d177178..bd5d85230c5 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -6,6 +6,7 @@ import re from datetime import (timedelta, datetime as datetime_sys, time as time_sys, date as date_sys) from socket import _GLOBAL_DEFAULT_TIMEOUT +from numbers import Number from typing import Any, Union, TypeVar, Callable, Sequence, Dict, Optional from urllib.parse import urlparse from uuid import UUID @@ -81,14 +82,17 @@ def has_at_most_one_key(*keys: str) -> Callable: def boolean(value: Any) -> bool: """Validate and coerce a boolean value.""" + if isinstance(value, bool): + return value if isinstance(value, str): - value = value.lower() + value = value.lower().strip() if value in ('1', 'true', 'yes', 'on', 'enable'): return True if value in ('0', 'false', 'no', 'off', 'disable'): return False - raise vol.Invalid('invalid boolean value {}'.format(value)) - return bool(value) + elif isinstance(value, Number): + return value != 0 + raise vol.Invalid('invalid boolean value {}'.format(value)) def isdevice(value): diff --git a/tests/components/demo/test_climate.py b/tests/components/demo/test_climate.py index 3166b2d3158..444b053fc19 100644 --- a/tests/components/demo/test_climate.py +++ b/tests/components/demo/test_climate.py @@ -203,7 +203,8 @@ class TestDemoClimate(unittest.TestCase): """Test setting the away mode without required attribute.""" state = self.hass.states.get(ENTITY_CLIMATE) assert 'on' == state.attributes.get('away_mode') - common.set_away_mode(self.hass, None, ENTITY_CLIMATE) + with pytest.raises(vol.Invalid): + common.set_away_mode(self.hass, None, ENTITY_CLIMATE) self.hass.block_till_done() assert 'on' == state.attributes.get('away_mode') @@ -246,7 +247,8 @@ class TestDemoClimate(unittest.TestCase): """Test setting the auxiliary heater without required attribute.""" state = self.hass.states.get(ENTITY_CLIMATE) assert 'off' == state.attributes.get('aux_heat') - common.set_aux_heat(self.hass, None, ENTITY_CLIMATE) + with pytest.raises(vol.Invalid): + common.set_aux_heat(self.hass, None, ENTITY_CLIMATE) self.hass.block_till_done() assert 'off' == state.attributes.get('aux_heat') diff --git a/tests/components/demo/test_media_player.py b/tests/components/demo/test_media_player.py index 808e3ee2102..fae4215f954 100644 --- a/tests/components/demo/test_media_player.py +++ b/tests/components/demo/test_media_player.py @@ -90,7 +90,8 @@ class TestDemoMediaPlayer(unittest.TestCase): assert False is state.attributes.get('is_volume_muted') - common.mute_volume(self.hass, None, entity_id) + with pytest.raises(vol.Invalid): + common.mute_volume(self.hass, None, entity_id) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert False is state.attributes.get('is_volume_muted') diff --git a/tests/components/demo/test_water_heater.py b/tests/components/demo/test_water_heater.py index d8c9c71935b..e336e879f91 100644 --- a/tests/components/demo/test_water_heater.py +++ b/tests/components/demo/test_water_heater.py @@ -95,7 +95,8 @@ class TestDemowater_heater(unittest.TestCase): """Test setting the away mode without required attribute.""" state = self.hass.states.get(ENTITY_WATER_HEATER) assert 'off' == state.attributes.get('away_mode') - common.set_away_mode(self.hass, None, ENTITY_WATER_HEATER) + with pytest.raises(vol.Invalid): + common.set_away_mode(self.hass, None, ENTITY_WATER_HEATER) self.hass.block_till_done() assert 'off' == state.attributes.get('away_mode') diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index 4b65904b8b2..6124699d88e 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -17,11 +17,14 @@ def test_boolean(): """Test boolean validation.""" schema = vol.Schema(cv.boolean) - for value in ('T', 'negative', 'lock'): + for value in ( + None, 'T', 'negative', 'lock', 'tr ue', + [], [1, 2], {'one': 'two'}, test_boolean): with pytest.raises(vol.MultipleInvalid): schema(value) - for value in ('true', 'On', '1', 'YES', 'enable', 1, True): + for value in ('true', 'On', '1', 'YES', ' true ', + 'enable', 1, 50, True, 0.1): assert schema(value) for value in ('false', 'Off', '0', 'NO', 'disable', 0, False):