From 4d9bac6f9cab428cc52e0337704f19b4effccb3c Mon Sep 17 00:00:00 2001 From: Johann Kellerman Date: Sat, 8 Oct 2016 23:40:50 +0200 Subject: [PATCH] Coerce device IDs from known_devices to be slugs (#3764) * Slugify & consider_home test fix [due to load valid PR] * undo schema change * Fix slugify error --- .../components/device_tracker/__init__.py | 8 +++++--- homeassistant/helpers/config_validation.py | 14 ++++++++++++-- tests/components/device_tracker/test_init.py | 19 +++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/device_tracker/__init__.py b/homeassistant/components/device_tracker/__init__.py index a05b57cff33..3fa8361a44d 100644 --- a/homeassistant/components/device_tracker/__init__.py +++ b/homeassistant/components/device_tracker/__init__.py @@ -46,6 +46,7 @@ CONF_TRACK_NEW = 'track_new_devices' DEFAULT_TRACK_NEW = True CONF_CONSIDER_HOME = 'consider_home' +DEFAULT_CONSIDER_HOME = 180 CONF_SCAN_INTERVAL = 'interval_seconds' DEFAULT_SCAN_INTERVAL = 12 @@ -119,8 +120,9 @@ def setup(hass: HomeAssistantType, config: ConfigType): return False else: conf = conf[0] if len(conf) > 0 else {} - consider_home = conf[CONF_CONSIDER_HOME] - track_new = conf[CONF_TRACK_NEW] + consider_home = conf.get(CONF_CONSIDER_HOME, + timedelta(seconds=DEFAULT_CONSIDER_HOME)) + track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) devices = load_config(yaml_path, hass, consider_home) @@ -415,7 +417,7 @@ def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta): for dev_id, device in devices.items(): try: device = dev_schema(device) - device['dev_id'] = cv.slug(dev_id) + device['dev_id'] = cv.slugify(dev_id) except vol.Invalid as exp: log_exception(exp, dev_id, devices) else: diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 7236debbe88..1d368a37d3c 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -17,7 +17,7 @@ from homeassistant.const import ( from homeassistant.core import valid_entity_id from homeassistant.exceptions import TemplateError import homeassistant.util.dt as dt_util -from homeassistant.util import slugify +from homeassistant.util import slugify as util_slugify from homeassistant.helpers import template as template_helper # pylint: disable=invalid-name @@ -218,12 +218,22 @@ def slug(value): if value is None: raise vol.Invalid('Slug should not be None') value = str(value) - slg = slugify(value) + slg = util_slugify(value) if value == slg: return value raise vol.Invalid('invalid slug {} (try {})'.format(value, slg)) +def slugify(value): + """Coerce a value to a slug.""" + if value is None: + raise vol.Invalid('Slug should not be None') + slg = util_slugify(str(value)) + if len(slg) > 0: + return slg + raise vol.Invalid('Unable to slugify {}'.format(value)) + + def string(value: Any) -> str: """Coerce value to string, except for None.""" if value is not None: diff --git a/tests/components/device_tracker/test_init.py b/tests/components/device_tracker/test_init.py index 80967543f0d..8b904ca6e8e 100644 --- a/tests/components/device_tracker/test_init.py +++ b/tests/components/device_tracker/test_init.py @@ -60,12 +60,27 @@ class TestComponentsDeviceTracker(unittest.TestCase): """Test when known devices contains invalid data.""" files = {'empty.yaml': '', 'nodict.yaml': '100', - 'allok.yaml': 'my_device:\n name: Device'} + 'badkey.yaml': '@:\n name: Device', + 'noname.yaml': 'my_device:\n', + 'allok.yaml': 'My Device:\n name: Device', + 'oneok.yaml': ('My Device!:\n name: Device\n' + 'bad_device:\n nme: Device')} args = {'hass': self.hass, 'consider_home': timedelta(seconds=60)} with patch_yaml_files(files): assert device_tracker.load_config('empty.yaml', **args) == [] assert device_tracker.load_config('nodict.yaml', **args) == [] - assert len(device_tracker.load_config('allok.yaml', **args)) == 1 + assert device_tracker.load_config('noname.yaml', **args) == [] + assert device_tracker.load_config('badkey.yaml', **args) == [] + + res = device_tracker.load_config('allok.yaml', **args) + assert len(res) == 1 + assert res[0].name == 'Device' + assert res[0].dev_id == 'my_device' + + res = device_tracker.load_config('oneok.yaml', **args) + assert len(res) == 1 + assert res[0].name == 'Device' + assert res[0].dev_id == 'my_device' def test_reading_yaml_config(self): """Test the rendering of the YAML configuration."""