Continue on invalid platforms and new setup_component unit tests (#3736)

This commit is contained in:
Johann Kellerman 2016-10-08 20:27:35 +02:00 committed by Paulus Schoutsen
parent 1b26b5ad14
commit 7b40a641ec
23 changed files with 842 additions and 672 deletions

View File

@ -38,6 +38,7 @@ def setup_component(hass: core.HomeAssistant, domain: str,
config: Optional[Dict]=None) -> bool: config: Optional[Dict]=None) -> bool:
"""Setup a component and all its dependencies.""" """Setup a component and all its dependencies."""
if domain in hass.config.components: if domain in hass.config.components:
_LOGGER.debug('Component %s already set up.', domain)
return True return True
_ensure_loader_prepared(hass) _ensure_loader_prepared(hass)
@ -53,6 +54,7 @@ def setup_component(hass: core.HomeAssistant, domain: str,
for component in components: for component in components:
if not _setup_component(hass, component, config): if not _setup_component(hass, component, config):
_LOGGER.error('Component %s failed to setup', component)
return False return False
return True return True
@ -158,7 +160,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
p_validated = component.PLATFORM_SCHEMA(p_config) p_validated = component.PLATFORM_SCHEMA(p_config)
except vol.Invalid as ex: except vol.Invalid as ex:
log_exception(ex, domain, config) log_exception(ex, domain, config)
return None continue
# Not all platform components follow same pattern for platforms # Not all platform components follow same pattern for platforms
# So if p_name is None we are not going to validate platform # So if p_name is None we are not going to validate platform
@ -171,7 +173,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
p_name) p_name)
if platform is None: if platform is None:
return None continue
# Validate platform specific schema # Validate platform specific schema
if hasattr(platform, 'PLATFORM_SCHEMA'): if hasattr(platform, 'PLATFORM_SCHEMA'):
@ -180,7 +182,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
except vol.Invalid as ex: except vol.Invalid as ex:
log_exception(ex, '{}.{}'.format(domain, p_name), log_exception(ex, '{}.{}'.format(domain, p_name),
p_validated) p_validated)
return None continue
platforms.append(p_validated) platforms.append(p_validated)

View File

@ -7,9 +7,10 @@ from unittest.mock import patch
from io import StringIO from io import StringIO
import logging import logging
import threading import threading
from contextlib import contextmanager
from homeassistant import core as ha, loader from homeassistant import core as ha, loader
from homeassistant.bootstrap import setup_component from homeassistant.bootstrap import setup_component, prepare_setup_component
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.util.unit_system import METRIC_SYSTEM from homeassistant.util.unit_system import METRIC_SYSTEM
import homeassistant.util.dt as date_util import homeassistant.util.dt as date_util
@ -58,6 +59,8 @@ def get_test_home_assistant(num_threads=None):
stop_event = threading.Event() stop_event = threading.Event()
def run_loop(): def run_loop():
"""Run event loop."""
# pylint: disable=protected-access
loop._thread_ident = threading.get_ident() loop._thread_ident = threading.get_ident()
loop.run_forever() loop.run_forever()
loop.close() loop.close()
@ -70,6 +73,7 @@ def get_test_home_assistant(num_threads=None):
@asyncio.coroutine @asyncio.coroutine
def fake_stop(): def fake_stop():
"""Fake stop."""
yield None yield None
@patch.object(ha, 'async_create_timer') @patch.object(ha, 'async_create_timer')
@ -84,6 +88,7 @@ def get_test_home_assistant(num_threads=None):
hass.block_till_done() hass.block_till_done()
def stop_hass(): def stop_hass():
"""Stop hass."""
orig_stop() orig_stop()
stop_event.wait() stop_event.wait()
@ -112,6 +117,7 @@ def mock_service(hass, domain, service):
""" """
calls = [] calls = []
# pylint: disable=unnecessary-lambda
hass.services.register(domain, service, lambda call: calls.append(call)) hass.services.register(domain, service, lambda call: calls.append(call))
return calls return calls
@ -315,3 +321,41 @@ def patch_yaml_files(files_dict, endswith=True):
raise FileNotFoundError('File not found: {}'.format(fname)) raise FileNotFoundError('File not found: {}'.format(fname))
return patch.object(yaml, 'open', mock_open_f, create=True) return patch.object(yaml, 'open', mock_open_f, create=True)
@contextmanager
def assert_setup_component(count, domain=None):
"""Collect valid configuration from setup_component.
- count: The amount of valid platforms that should be setup
- domain: The domain to count is optional. It can be automatically
determined most of the time
Use as a context manager aroung bootstrap.setup_component
with assert_setup_component(0) as result_config:
setup_component(hass, start_config, domain)
# using result_config is optional
"""
config = {}
def mock_psc(hass, config_input, domain):
"""Mock the prepare_setup_component to capture config."""
res = prepare_setup_component(hass, config_input, domain)
config[domain] = None if res is None else res.get(domain)
_LOGGER.debug('Configuration for %s, Validated: %s, Original %s',
domain, config[domain], config_input.get(domain))
return res
assert isinstance(config, dict)
with patch('homeassistant.bootstrap.prepare_setup_component', mock_psc):
yield config
if domain is None:
assert len(config) == 1, ('assert_setup_component requires DOMAIN: {}'
.format(list(config.keys())))
domain = list(config.keys())[0]
res = config.get(domain)
res_len = 0 if res is None else len(res)
assert res_len == count, 'setup_component failed, expected {} got {}: {}' \
.format(count, res_len, res)

View File

@ -1,14 +1,15 @@
"""The tests the MQTT alarm control panel component.""" """The tests the MQTT alarm control panel component."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import setup_component
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN) STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN)
from homeassistant.components import alarm_control_panel from homeassistant.components import alarm_control_panel
from tests.common import ( from tests.common import (
mock_mqtt_component, fire_mqtt_message, get_test_home_assistant) mock_mqtt_component, fire_mqtt_message, get_test_home_assistant,
assert_setup_component)
CODE = 'HELLO_CODE' CODE = 'HELLO_CODE'
@ -16,7 +17,9 @@ CODE = 'HELLO_CODE'
class TestAlarmControlPanelMQTT(unittest.TestCase): class TestAlarmControlPanelMQTT(unittest.TestCase):
"""Test the manual alarm module.""" """Test the manual alarm module."""
def setUp(self): # pylint: disable=invalid-name # pylint: disable=invalid-name
def setUp(self):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
self.mock_publish = mock_mqtt_component(self.hass) self.mock_publish = mock_mqtt_component(self.hass)
@ -28,27 +31,30 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_fail_setup_without_state_topic(self): def test_fail_setup_without_state_topic(self):
"""Test for failing with no state topic.""" """Test for failing with no state topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, { with assert_setup_component(0) as config:
alarm_control_panel.DOMAIN: { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
'platform': 'mqtt', alarm_control_panel.DOMAIN: {
'command_topic': 'alarm/command' 'platform': 'mqtt',
} 'command_topic': 'alarm/command'
}) }
})
assert not config[alarm_control_panel.DOMAIN]
def test_fail_setup_without_command_topic(self): def test_fail_setup_without_command_topic(self):
"""Test failing with no command topic.""" """Test failing with no command topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, { with assert_setup_component(0):
alarm_control_panel.DOMAIN: { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
'platform': 'mqtt', alarm_control_panel.DOMAIN: {
'state_topic': 'alarm/state' 'platform': 'mqtt',
} 'state_topic': 'alarm/state'
}) }
})
def test_update_state_via_state_topic(self): def test_update_state_via_state_topic(self):
"""Test updating with via state topic.""" """Test updating with via state topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -72,7 +78,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_ignore_update_state_if_unknown_via_state_topic(self): def test_ignore_update_state_if_unknown_via_state_topic(self):
"""Test ignoring updates via state topic.""" """Test ignoring updates via state topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -93,7 +99,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_home_publishes_mqtt(self): def test_arm_home_publishes_mqtt(self):
"""Test publishing of MQTT messages while armed.""" """Test publishing of MQTT messages while armed."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -110,7 +116,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_home_not_publishes_mqtt_with_invalid_code(self): def test_arm_home_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -128,7 +134,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_away_publishes_mqtt(self): def test_arm_away_publishes_mqtt(self):
"""Test publishing of MQTT messages while armed.""" """Test publishing of MQTT messages while armed."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -145,7 +151,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_away_not_publishes_mqtt_with_invalid_code(self): def test_arm_away_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -163,7 +169,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_disarm_publishes_mqtt(self): def test_disarm_publishes_mqtt(self):
"""Test publishing of MQTT messages while disarmed.""" """Test publishing of MQTT messages while disarmed."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
@ -180,7 +186,7 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_disarm_not_publishes_mqtt_with_invalid_code(self): def test_disarm_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, { assert setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: { alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',

View File

@ -8,19 +8,22 @@ from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestAutomation(unittest.TestCase): class TestAutomation(unittest.TestCase):
"""Test the event automation.""" """Test the event automation."""
def setUp(self): # pylint: disable=invalid-name # pylint: disable=invalid-name
def setUp(self):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
self.hass.config.components.append('group') self.hass.config.components.append('group')
self.calls = [] self.calls = []
def record_call(service): def record_call(service):
"""Record call."""
self.calls.append(service) self.calls.append(service)
self.hass.services.register('test', 'automation', record_call) self.hass.services.register('test', 'automation', record_call)
@ -31,18 +34,19 @@ class TestAutomation(unittest.TestCase):
def test_service_data_not_a_dict(self): def test_service_data_not_a_dict(self):
"""Test service data not dict.""" """Test service data not dict."""
assert not setup_component(self.hass, automation.DOMAIN, { with assert_setup_component(0):
automation.DOMAIN: { assert not setup_component(self.hass, automation.DOMAIN, {
'trigger': { automation.DOMAIN: {
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
}, 'event_type': 'test_event',
'action': { },
'service': 'test.automation', 'action': {
'data': 100, 'service': 'test.automation',
'data': 100,
}
} }
} })
})
def test_service_specify_data(self): def test_service_specify_data(self):
"""Test service data.""" """Test service data."""
@ -70,7 +74,7 @@ class TestAutomation(unittest.TestCase):
self.hass.bus.fire('test_event') self.hass.bus.fire('test_event')
self.hass.block_till_done() self.hass.block_till_done()
assert len(self.calls) == 1 assert len(self.calls) == 1
assert 'event - test_event' == self.calls[0].data['some'] assert self.calls[0].data['some'] == 'event - test_event'
state = self.hass.states.get('automation.hello') state = self.hass.states.get('automation.hello')
assert state is not None assert state is not None
assert state.attributes.get('last_triggered') == time assert state.attributes.get('last_triggered') == time
@ -444,21 +448,22 @@ class TestAutomation(unittest.TestCase):
}) })
def test_reload_config_when_invalid_config(self, mock_load_yaml): def test_reload_config_when_invalid_config(self, mock_load_yaml):
"""Test the reload config service handling invalid config.""" """Test the reload config service handling invalid config."""
assert setup_component(self.hass, automation.DOMAIN, { with assert_setup_component(1):
automation.DOMAIN: { assert setup_component(self.hass, automation.DOMAIN, {
'alias': 'hello', automation.DOMAIN: {
'trigger': { 'alias': 'hello',
'platform': 'event', 'trigger': {
'event_type': 'test_event', 'platform': 'event',
}, 'event_type': 'test_event',
'action': { },
'service': 'test.automation', 'action': {
'data_template': { 'service': 'test.automation',
'event': '{{ trigger.event.event_type }}' 'data_template': {
'event': '{{ trigger.event.event_type }}'
}
} }
} }
} })
})
assert self.hass.states.get('automation.hello') is not None assert self.hass.states.get('automation.hello') is not None
self.hass.bus.fire('test_event') self.hass.bus.fire('test_event')
@ -470,11 +475,11 @@ class TestAutomation(unittest.TestCase):
automation.reload(self.hass) automation.reload(self.hass)
self.hass.block_till_done() self.hass.block_till_done()
assert self.hass.states.get('automation.hello') is not None assert self.hass.states.get('automation.hello') is None
self.hass.bus.fire('test_event') self.hass.bus.fire('test_event')
self.hass.block_till_done() self.hass.block_till_done()
assert len(self.calls) == 2 assert len(self.calls) == 1
def test_reload_config_handles_load_fails(self): def test_reload_config_handles_load_fails(self):
"""Test the reload config service.""" """Test the reload config service."""

View File

@ -4,10 +4,11 @@ from unittest.mock import MagicMock
import requests_mock import requests_mock
from homeassistant import core as ha from homeassistant.bootstrap import setup_component
from homeassistant.components.binary_sensor import sleepiq from homeassistant.components.binary_sensor import sleepiq
from tests.components.test_sleepiq import mock_responses from tests.components.test_sleepiq import mock_responses
from tests.common import get_test_home_assistant
class TestSleepIQBinarySensorSetup(unittest.TestCase): class TestSleepIQBinarySensorSetup(unittest.TestCase):
@ -22,7 +23,7 @@ class TestSleepIQBinarySensorSetup(unittest.TestCase):
def setUp(self): def setUp(self):
"""Initialize values for this testcase class.""" """Initialize values for this testcase class."""
self.hass = ha.HomeAssistant() self.hass = get_test_home_assistant()
self.username = 'foo' self.username = 'foo'
self.password = 'bar' self.password = 'bar'
self.config = { self.config = {
@ -35,6 +36,9 @@ class TestSleepIQBinarySensorSetup(unittest.TestCase):
"""Test for successfully setting up the SleepIQ platform.""" """Test for successfully setting up the SleepIQ platform."""
mock_responses(mock) mock_responses(mock)
setup_component(self.hass, 'sleepiq', {
'sleepiq': self.config})
sleepiq.setup_platform(self.hass, sleepiq.setup_platform(self.hass,
self.config, self.config,
self.add_devices, self.add_devices,

View File

@ -9,12 +9,15 @@ from homeassistant.components.binary_sensor import template
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template as template_hlpr from homeassistant.helpers import template as template_hlpr
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestBinarySensorTemplate(unittest.TestCase): class TestBinarySensorTemplate(unittest.TestCase):
"""Test for Binary sensor template platform.""" """Test for Binary sensor template platform."""
hass = None
# pylint: disable=invalid-name
def setup_method(self, method): def setup_method(self, method):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
@ -47,53 +50,53 @@ class TestBinarySensorTemplate(unittest.TestCase):
def test_setup_no_sensors(self): def test_setup_no_sensors(self):
""""Test setup with no sensors.""" """"Test setup with no sensors."""
result = bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert bootstrap.setup_component(self.hass, 'sensor', {
'platform': 'template' 'sensor': {
} 'platform': 'template'
}) }
self.assertFalse(result) })
def test_setup_invalid_device(self): def test_setup_invalid_device(self):
""""Test the setup with invalid devices.""" """"Test the setup with invalid devices."""
result = bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert bootstrap.setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'foo bar': {}, 'sensors': {
}, 'foo bar': {},
} },
}) }
self.assertFalse(result) })
def test_setup_invalid_sensor_class(self): def test_setup_invalid_sensor_class(self):
""""Test setup with invalid sensor class.""" """"Test setup with invalid sensor class."""
result = bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert bootstrap.setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test': { 'sensors': {
'value_template': '{{ foo }}', 'test': {
'sensor_class': 'foobarnotreal', 'value_template': '{{ foo }}',
'sensor_class': 'foobarnotreal',
},
}, },
}, }
} })
})
self.assertFalse(result)
def test_setup_invalid_missing_template(self): def test_setup_invalid_missing_template(self):
""""Test setup with invalid and missing template.""" """"Test setup with invalid and missing template."""
result = bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert bootstrap.setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test': { 'sensors': {
'sensor_class': 'motion', 'test': {
}, 'sensor_class': 'motion',
},
}
} }
} })
})
self.assertFalse(result)
def test_attributes(self): def test_attributes(self):
""""Test the attributes.""" """"Test the attributes."""
@ -107,7 +110,9 @@ class TestBinarySensorTemplate(unittest.TestCase):
vs.update() vs.update()
self.assertFalse(vs.is_on) self.assertFalse(vs.is_on)
# pylint: disable=protected-access
vs._template = template_hlpr.Template("{{ 2 > 1 }}", self.hass) vs._template = template_hlpr.Template("{{ 2 > 1 }}", self.hass)
vs.update() vs.update()
self.assertTrue(vs.is_on) self.assertTrue(vs.is_on)

View File

@ -1,12 +1,14 @@
"""The test for the Trend sensor platform.""" """The test for the Trend sensor platform."""
import homeassistant.bootstrap as bootstrap import homeassistant.bootstrap as bootstrap
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestTrendBinarySensor: class TestTrendBinarySensor:
"""Test the Trend sensor.""" """Test the Trend sensor."""
hass = None
def setup_method(self, method): def setup_method(self, method):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
@ -189,41 +191,46 @@ class TestTrendBinarySensor:
state = self.hass.states.get('binary_sensor.test_trend_sensor') state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off' assert state.state == 'off'
def test_invalid_name_does_not_create(self): def test_invalid_name_does_not_create(self): \
# pylint: disable=invalid-name
"""Test invalid name.""" """Test invalid name."""
assert not bootstrap.setup_component(self.hass, 'binary_sensor', { with assert_setup_component(0):
'binary_sensor': { assert bootstrap.setup_component(self.hass, 'binary_sensor', {
'platform': 'template', 'binary_sensor': {
'sensors': { 'platform': 'template',
'test INVALID sensor': { 'sensors': {
'entity_id': 'test INVALID sensor': {
"sensor.test_state" 'entity_id':
"sensor.test_state"
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_invalid_sensor_does_not_create(self): def test_invalid_sensor_does_not_create(self): \
# pylint: disable=invalid-name
"""Test invalid sensor.""" """Test invalid sensor."""
assert not bootstrap.setup_component(self.hass, 'binary_sensor', { with assert_setup_component(0):
'binary_sensor': { assert bootstrap.setup_component(self.hass, 'binary_sensor', {
'platform': 'template', 'binary_sensor': {
'sensors': { 'platform': 'template',
'test_trend_sensor': { 'sensors': {
'not_entity_id': 'test_trend_sensor': {
"sensor.test_state" 'not_entity_id':
"sensor.test_state"
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_no_sensors_does_not_create(self): def test_no_sensors_does_not_create(self):
"""Test no sensors.""" """Test no sensors."""
assert not bootstrap.setup_component(self.hass, 'binary_sensor', { with assert_setup_component(0):
'binary_sensor': { assert bootstrap.setup_component(self.hass, 'binary_sensor', {
'platform': 'trend' 'binary_sensor': {
} 'platform': 'trend'
}) }
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []

View File

@ -8,7 +8,7 @@ from werkzeug.test import EnvironBuilder
from homeassistant.bootstrap import setup_component from homeassistant.bootstrap import setup_component
from homeassistant.components.http import request_class from homeassistant.components.http import request_class
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestLocalCamera(unittest.TestCase): class TestLocalCamera(unittest.TestCase):
@ -28,21 +28,21 @@ class TestLocalCamera(unittest.TestCase):
"""Test that it loads image from disk.""" """Test that it loads image from disk."""
self.hass.wsgi = mock.MagicMock() self.hass.wsgi = mock.MagicMock()
with NamedTemporaryFile() as fp: with NamedTemporaryFile() as fptr:
fp.write('hello'.encode('utf-8')) fptr.write('hello'.encode('utf-8'))
fp.flush() fptr.flush()
assert setup_component(self.hass, 'camera', { assert setup_component(self.hass, 'camera', {
'camera': { 'camera': {
'name': 'config_test', 'name': 'config_test',
'platform': 'local_file', 'platform': 'local_file',
'file_path': fp.name, 'file_path': fptr.name,
}}) }})
image_view = self.hass.wsgi.mock_calls[0][1][0] image_view = self.hass.wsgi.mock_calls[0][1][0]
builder = EnvironBuilder(method='GET') builder = EnvironBuilder(method='GET')
Request = request_class() Request = request_class() # pylint: disable=invalid-name
request = Request(builder.get_environ()) request = Request(builder.get_environ())
request.authenticated = True request.authenticated = True
resp = image_view.get(request, 'camera.config_test') resp = image_view.get(request, 'camera.config_test')
@ -54,16 +54,17 @@ class TestLocalCamera(unittest.TestCase):
"""Test local file will not setup when file is not readable.""" """Test local file will not setup when file is not readable."""
self.hass.wsgi = mock.MagicMock() self.hass.wsgi = mock.MagicMock()
with NamedTemporaryFile() as fp: with NamedTemporaryFile() as fptr:
fp.write('hello'.encode('utf-8')) fptr.write('hello'.encode('utf-8'))
fp.flush() fptr.flush()
with mock.patch('os.access', return_value=False): with mock.patch('os.access', return_value=False), \
assert not setup_component(self.hass, 'camera', { assert_setup_component(0):
assert setup_component(self.hass, 'camera', {
'camera': { 'camera': {
'name': 'config_test', 'name': 'config_test',
'platform': 'local_file', 'platform': 'local_file',
'file_path': fp.name, 'file_path': fptr.name,
}}) }})
assert [] == self.hass.states.all() assert [] == self.hass.states.all()

View File

@ -16,7 +16,7 @@ from homeassistant.const import (
from homeassistant.util.unit_system import METRIC_SYSTEM from homeassistant.util.unit_system import METRIC_SYSTEM
from homeassistant.components import climate from homeassistant.components import climate
from tests.common import get_test_home_assistant from tests.common import assert_setup_component, get_test_home_assistant
ENTITY = 'climate.test' ENTITY = 'climate.test'
@ -44,8 +44,9 @@ class TestSetupClimateGenericThermostat(unittest.TestCase):
'name': 'test', 'name': 'test',
'target_sensor': ENT_SENSOR 'target_sensor': ENT_SENSOR
} }
self.assertFalse(setup_component(self.hass, 'climate', { with assert_setup_component(0):
'climate': config})) setup_component(self.hass, 'climate', {
'climate': config})
def test_valid_conf(self): def test_valid_conf(self):
"""Test set up genreic_thermostat with valid config values.""" """Test set up genreic_thermostat with valid config values."""

View File

@ -5,14 +5,15 @@ from unittest import mock
import voluptuous as vol import voluptuous as vol
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import setup_component
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.components.device_tracker.asuswrt import ( from homeassistant.components.device_tracker.asuswrt import (
CONF_PROTOCOL, CONF_MODE, CONF_PUB_KEY, PLATFORM_SCHEMA, DOMAIN) CONF_PROTOCOL, CONF_MODE, CONF_PUB_KEY, PLATFORM_SCHEMA, DOMAIN)
from homeassistant.const import (CONF_PLATFORM, CONF_PASSWORD, CONF_USERNAME, from homeassistant.const import (CONF_PLATFORM, CONF_PASSWORD, CONF_USERNAME,
CONF_HOST) CONF_HOST)
from tests.common import get_test_home_assistant, get_test_config_dir from tests.common import (
get_test_home_assistant, get_test_config_dir, assert_setup_component)
FAKEFILE = None FAKEFILE = None
@ -32,6 +33,7 @@ def teardown_module():
class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase): class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase):
"""Tests for the ASUSWRT device tracker platform.""" """Tests for the ASUSWRT device tracker platform."""
hass = None hass = None
def setup_method(self, _): def setup_method(self, _):
@ -49,12 +51,13 @@ class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase):
def test_password_or_pub_key_required(self): \ def test_password_or_pub_key_required(self): \
# pylint: disable=invalid-name # pylint: disable=invalid-name
"""Test creating an AsusWRT scanner without a pass or pubkey.""" """Test creating an AsusWRT scanner without a pass or pubkey."""
self.assertFalse(_setup_component( with assert_setup_component(0):
self.hass, DOMAIN, {DOMAIN: { assert setup_component(
CONF_PLATFORM: 'asuswrt', self.hass, DOMAIN, {DOMAIN: {
CONF_HOST: 'fake_host', CONF_PLATFORM: 'asuswrt',
CONF_USERNAME: 'fake_user' CONF_HOST: 'fake_host',
}})) CONF_USERNAME: 'fake_user'
}})
@mock.patch( @mock.patch(
'homeassistant.components.device_tracker.asuswrt.AsusWrtDeviceScanner', 'homeassistant.components.device_tracker.asuswrt.AsusWrtDeviceScanner',
@ -70,7 +73,10 @@ class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase):
CONF_PASSWORD: 'fake_pass' CONF_PASSWORD: 'fake_pass'
} }
} }
self.assertIsNotNone(_setup_component(self.hass, DOMAIN, conf_dict))
with assert_setup_component(1):
assert setup_component(self.hass, DOMAIN, conf_dict)
conf_dict[DOMAIN][CONF_MODE] = 'router' conf_dict[DOMAIN][CONF_MODE] = 'router'
conf_dict[DOMAIN][CONF_PROTOCOL] = 'ssh' conf_dict[DOMAIN][CONF_PROTOCOL] = 'ssh'
asuswrt_mock.assert_called_once_with(conf_dict[DOMAIN]) asuswrt_mock.assert_called_once_with(conf_dict[DOMAIN])
@ -90,7 +96,8 @@ class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase):
} }
} }
self.assertIsNotNone(_setup_component(self.hass, DOMAIN, conf_dict)) with assert_setup_component(1):
assert setup_component(self.hass, DOMAIN, conf_dict)
conf_dict[DOMAIN][CONF_MODE] = 'router' conf_dict[DOMAIN][CONF_MODE] = 'router'
conf_dict[DOMAIN][CONF_PROTOCOL] = 'ssh' conf_dict[DOMAIN][CONF_PROTOCOL] = 'ssh'
@ -163,6 +170,7 @@ class TestComponentsDeviceTrackerASUSWRT(unittest.TestCase):
update_mock.start() update_mock.start()
self.addCleanup(update_mock.stop) self.addCleanup(update_mock.stop)
self.assertFalse(_setup_component(self.hass, DOMAIN, with assert_setup_component(0):
{DOMAIN: conf_dict})) assert setup_component(self.hass, DOMAIN,
{DOMAIN: conf_dict})
ssh.login.assert_not_called() ssh.login.assert_not_called()

View File

@ -17,7 +17,7 @@ from homeassistant.exceptions import HomeAssistantError
from tests.common import ( from tests.common import (
get_test_home_assistant, fire_time_changed, fire_service_discovered, get_test_home_assistant, fire_time_changed, fire_service_discovered,
patch_yaml_files) patch_yaml_files, assert_setup_component)
TEST_PLATFORM = {device_tracker.DOMAIN: {CONF_PLATFORM: 'test'}} TEST_PLATFORM = {device_tracker.DOMAIN: {CONF_PLATFORM: 'test'}}
@ -336,6 +336,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
@patch('homeassistant.components.device_tracker.log_exception') @patch('homeassistant.components.device_tracker.log_exception')
def test_config_failure(self, mock_ex): def test_config_failure(self, mock_ex):
"""Test that the device tracker see failures.""" """Test that the device tracker see failures."""
assert not setup_component(self.hass, device_tracker.DOMAIN, with assert_setup_component(0, device_tracker.DOMAIN):
{device_tracker.DOMAIN: { setup_component(self.hass, device_tracker.DOMAIN,
device_tracker.CONF_CONSIDER_HOME: -1}}) {device_tracker.DOMAIN: {
device_tracker.CONF_CONSIDER_HOME: -1}})

View File

@ -1,18 +1,21 @@
"""The tests for the MQTT Garge door platform.""" """The tests for the MQTT Garge door platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import setup_component
from homeassistant.const import STATE_OPEN, STATE_CLOSED, ATTR_ASSUMED_STATE from homeassistant.const import STATE_OPEN, STATE_CLOSED, ATTR_ASSUMED_STATE
import homeassistant.components.garage_door as garage_door import homeassistant.components.garage_door as garage_door
from tests.common import ( from tests.common import (
mock_mqtt_component, fire_mqtt_message, get_test_home_assistant) mock_mqtt_component, fire_mqtt_message, get_test_home_assistant,
assert_setup_component)
class TestGarageDoorMQTT(unittest.TestCase): class TestGarageDoorMQTT(unittest.TestCase):
"""Test the MQTT Garage door.""" """Test the MQTT Garage door."""
def setUp(self): # pylint: disable=invalid-name # pylint: disable=invalid-name
def setUp(self):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
self.mock_publish = mock_mqtt_component(self.hass) self.mock_publish = mock_mqtt_component(self.hass)
@ -24,29 +27,31 @@ class TestGarageDoorMQTT(unittest.TestCase):
def test_fail_setup_if_no_command_topic(self): def test_fail_setup_if_no_command_topic(self):
"""Test if command fails with command topic.""" """Test if command fails with command topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert not _setup_component(self.hass, garage_door.DOMAIN, { with assert_setup_component(0):
garage_door.DOMAIN: { assert setup_component(self.hass, garage_door.DOMAIN, {
'platform': 'mqtt', garage_door.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'state_topic': '/home/garage_door/door' 'name': 'test',
} 'state_topic': '/home/garage_door/door'
}) }
})
self.assertIsNone(self.hass.states.get('garage_door.test')) self.assertIsNone(self.hass.states.get('garage_door.test'))
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self):
"""Test the controlling state via topic.""" """Test the controlling state via topic."""
assert _setup_component(self.hass, garage_door.DOMAIN, { with assert_setup_component(1):
garage_door.DOMAIN: { assert setup_component(self.hass, garage_door.DOMAIN, {
'platform': 'mqtt', garage_door.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'state_topic': 'state-topic', 'name': 'test',
'command_topic': 'command-topic', 'state_topic': 'state-topic',
'state_open': 1, 'command_topic': 'command-topic',
'state_closed': 0, 'state_open': 1,
'service_open': 1, 'state_closed': 0,
'service_close': 0 'service_open': 1,
} 'service_close': 0
}) }
})
state = self.hass.states.get('garage_door.test') state = self.hass.states.get('garage_door.test')
self.assertEqual(STATE_CLOSED, state.state) self.assertEqual(STATE_CLOSED, state.state)
@ -66,18 +71,19 @@ class TestGarageDoorMQTT(unittest.TestCase):
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self):
"""Test the sending MQTT commands in optimistic mode.""" """Test the sending MQTT commands in optimistic mode."""
assert _setup_component(self.hass, garage_door.DOMAIN, { with assert_setup_component(1):
garage_door.DOMAIN: { assert setup_component(self.hass, garage_door.DOMAIN, {
'platform': 'mqtt', garage_door.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'command_topic': 'command-topic', 'name': 'test',
'state_open': 'beer state open', 'command_topic': 'command-topic',
'state_closed': 'beer state closed', 'state_open': 'beer state open',
'service_open': 'beer open', 'state_closed': 'beer state closed',
'service_close': 'beer close', 'service_open': 'beer open',
'qos': '2' 'service_close': 'beer close',
} 'qos': '2'
}) }
})
state = self.hass.states.get('garage_door.test') state = self.hass.states.get('garage_door.test')
self.assertEqual(STATE_CLOSED, state.state) self.assertEqual(STATE_CLOSED, state.state)
@ -101,19 +107,20 @@ class TestGarageDoorMQTT(unittest.TestCase):
def test_controlling_state_via_topic_and_json_message(self): def test_controlling_state_via_topic_and_json_message(self):
"""Test the controlling state via topic and JSON message.""" """Test the controlling state via topic and JSON message."""
assert _setup_component(self.hass, garage_door.DOMAIN, { with assert_setup_component(1):
garage_door.DOMAIN: { assert setup_component(self.hass, garage_door.DOMAIN, {
'platform': 'mqtt', garage_door.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'state_topic': 'state-topic', 'name': 'test',
'command_topic': 'command-topic', 'state_topic': 'state-topic',
'state_open': 'beer open', 'command_topic': 'command-topic',
'state_closed': 'beer closed', 'state_open': 'beer open',
'service_open': 'beer service open', 'state_closed': 'beer closed',
'service_close': 'beer service close', 'service_open': 'beer service open',
'value_template': '{{ value_json.val }}' 'service_close': 'beer service close',
} 'value_template': '{{ value_json.val }}'
}) }
})
state = self.hass.states.get('garage_door.test') state = self.hass.states.get('garage_door.test')
self.assertEqual(STATE_CLOSED, state.state) self.assertEqual(STATE_CLOSED, state.state)

View File

@ -75,17 +75,20 @@ light:
""" """
import unittest import unittest
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import setup_component
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
import homeassistant.components.light as light import homeassistant.components.light as light
from tests.common import ( from tests.common import (
get_test_home_assistant, mock_mqtt_component, fire_mqtt_message) assert_setup_component, get_test_home_assistant, mock_mqtt_component,
fire_mqtt_message)
class TestLightMQTT(unittest.TestCase): class TestLightMQTT(unittest.TestCase):
"""Test the MQTT light.""" """Test the MQTT light."""
def setUp(self): # pylint: disable=invalid-name # pylint: disable=invalid-name
def setUp(self):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
self.mock_publish = mock_mqtt_component(self.hass) self.mock_publish = mock_mqtt_component(self.hass)
@ -97,25 +100,28 @@ class TestLightMQTT(unittest.TestCase):
def test_fail_setup_if_no_command_topic(self): def test_fail_setup_if_no_command_topic(self):
"""Test if command fails with command topic.""" """Test if command fails with command topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert not _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(0):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, {
'platform': 'mqtt', light.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
} 'name': 'test',
}) }
})
self.assertIsNone(self.hass.states.get('light.test')) self.assertIsNone(self.hass.states.get('light.test'))
def test_no_color_or_brightness_or_color_temp_if_no_topics(self): def test_no_color_or_brightness_or_color_temp_if_no_topics(self): \
# pylint: disable=invalid-name
"""Test if there is no color and brightness if no topic.""" """Test if there is no color and brightness if no topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, {
'platform': 'mqtt', light.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'state_topic': 'test_light_rgb/status', 'name': 'test',
'command_topic': 'test_light_rgb/set', 'state_topic': 'test_light_rgb/status',
} 'command_topic': 'test_light_rgb/set',
}) }
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -132,26 +138,28 @@ class TestLightMQTT(unittest.TestCase):
self.assertIsNone(state.attributes.get('brightness')) self.assertIsNone(state.attributes.get('brightness'))
self.assertIsNone(state.attributes.get('color_temp')) self.assertIsNone(state.attributes.get('color_temp'))
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self): \
# pylint: disable=invalid-name
"""Test the controlling of the state via topic.""" """Test the controlling of the state via topic."""
config = {light.DOMAIN: {
'platform': 'mqtt',
'name': 'test',
'state_topic': 'test_light_rgb/status',
'command_topic': 'test_light_rgb/set',
'brightness_state_topic': 'test_light_rgb/brightness/status',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'rgb_state_topic': 'test_light_rgb/rgb/status',
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
'qos': '0',
'payload_on': 1,
'payload_off': 0
}}
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, config)
'platform': 'mqtt',
'name': 'test',
'state_topic': 'test_light_rgb/status',
'command_topic': 'test_light_rgb/set',
'brightness_state_topic': 'test_light_rgb/brightness/status',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'rgb_state_topic': 'test_light_rgb/rgb/status',
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
'qos': '0',
'payload_on': 1,
'payload_off': 0
}
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -206,20 +214,21 @@ class TestLightMQTT(unittest.TestCase):
def test_controlling_scale(self): def test_controlling_scale(self):
"""Test the controlling scale.""" """Test the controlling scale."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, {
'platform': 'mqtt', light.DOMAIN: {
'name': 'test', 'platform': 'mqtt',
'state_topic': 'test_scale/status', 'name': 'test',
'command_topic': 'test_scale/set', 'state_topic': 'test_scale/status',
'brightness_state_topic': 'test_scale/brightness/status', 'command_topic': 'test_scale/set',
'brightness_command_topic': 'test_scale/brightness/set', 'brightness_state_topic': 'test_scale/brightness/status',
'brightness_scale': '99', 'brightness_command_topic': 'test_scale/brightness/set',
'qos': 0, 'brightness_scale': '99',
'payload_on': 'on', 'qos': 0,
'payload_off': 'off' 'payload_on': 'on',
} 'payload_off': 'off'
}) }
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -250,24 +259,26 @@ class TestLightMQTT(unittest.TestCase):
self.assertEqual(255, self.assertEqual(255,
light_state.attributes['brightness']) light_state.attributes['brightness'])
def test_controlling_state_via_topic_with_templates(self): def test_controlling_state_via_topic_with_templates(self): \
# pylint: disable=invalid-name
"""Test the setting og the state with a template.""" """Test the setting og the state with a template."""
config = {light.DOMAIN: {
'platform': 'mqtt',
'name': 'test',
'state_topic': 'test_light_rgb/status',
'command_topic': 'test_light_rgb/set',
'brightness_state_topic': 'test_light_rgb/brightness/status',
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
'rgb_state_topic': 'test_light_rgb/rgb/status',
'state_value_template': '{{ value_json.hello }}',
'brightness_value_template': '{{ value_json.hello }}',
'color_temp_value_template': '{{ value_json.hello }}',
'rgb_value_template': '{{ value_json.hello | join(",") }}',
}}
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, config)
'platform': 'mqtt',
'name': 'test',
'state_topic': 'test_light_rgb/status',
'command_topic': 'test_light_rgb/set',
'brightness_state_topic': 'test_light_rgb/brightness/status',
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
'rgb_state_topic': 'test_light_rgb/rgb/status',
'state_value_template': '{{ value_json.hello }}',
'brightness_value_template': '{{ value_json.hello }}',
'color_temp_value_template': '{{ value_json.hello }}',
'rgb_value_template': '{{ value_json.hello | join(",") }}',
}
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -290,22 +301,24 @@ class TestLightMQTT(unittest.TestCase):
self.assertEqual([1, 2, 3], state.attributes.get('rgb_color')) self.assertEqual([1, 2, 3], state.attributes.get('rgb_color'))
self.assertEqual(300, state.attributes.get('color_temp')) self.assertEqual(300, state.attributes.get('color_temp'))
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self): \
# pylint: disable=invalid-name
"""Test the sending of command in optimistic mode.""" """Test the sending of command in optimistic mode."""
config = {light.DOMAIN: {
'platform': 'mqtt',
'name': 'test',
'command_topic': 'test_light_rgb/set',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
'qos': 2,
'payload_on': 'on',
'payload_off': 'off'
}}
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, config)
'platform': 'mqtt',
'name': 'test',
'command_topic': 'test_light_rgb/set',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
'qos': 2,
'payload_on': 'on',
'payload_off': 'off'
}
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -352,16 +365,17 @@ class TestLightMQTT(unittest.TestCase):
def test_show_brightness_if_only_command_topic(self): def test_show_brightness_if_only_command_topic(self):
"""Test the brightness if only a command topic is present.""" """Test the brightness if only a command topic is present."""
config = {light.DOMAIN: {
'platform': 'mqtt',
'name': 'test',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'command_topic': 'test_light_rgb/set',
'state_topic': 'test_light_rgb/status',
}}
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, config)
'platform': 'mqtt',
'name': 'test',
'brightness_command_topic': 'test_light_rgb/brightness/set',
'command_topic': 'test_light_rgb/set',
'state_topic': 'test_light_rgb/status',
}
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -376,16 +390,17 @@ class TestLightMQTT(unittest.TestCase):
def test_show_color_temp_only_if_command_topic(self): def test_show_color_temp_only_if_command_topic(self):
"""Test the color temp only if a command topic is present.""" """Test the color temp only if a command topic is present."""
config = {light.DOMAIN: {
'platform': 'mqtt',
'name': 'test',
'color_temp_command_topic': 'test_light_rgb/brightness/set',
'command_topic': 'test_light_rgb/set',
'state_topic': 'test_light_rgb/status'
}}
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(1):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, config)
'platform': 'mqtt',
'name': 'test',
'color_temp_command_topic': 'test_light_rgb/brightness/set',
'command_topic': 'test_light_rgb/set',
'state_topic': 'test_light_rgb/status'
}
})
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)

View File

@ -30,11 +30,12 @@ light:
import json import json
import unittest import unittest
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import _setup_component, setup_component
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
import homeassistant.components.light as light import homeassistant.components.light as light
from tests.common import ( from tests.common import (
get_test_home_assistant, mock_mqtt_component, fire_mqtt_message) get_test_home_assistant, mock_mqtt_component, fire_mqtt_message,
assert_setup_component)
class TestLightMQTTJSON(unittest.TestCase): class TestLightMQTTJSON(unittest.TestCase):
@ -49,18 +50,21 @@ class TestLightMQTTJSON(unittest.TestCase):
"""Stop everything that was started.""" """Stop everything that was started."""
self.hass.stop() self.hass.stop()
def test_fail_setup_if_no_command_topic(self): def test_fail_setup_if_no_command_topic(self): \
# pylint: disable=invalid-name
"""Test if setup fails with no command topic.""" """Test if setup fails with no command topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert not _setup_component(self.hass, light.DOMAIN, { with assert_setup_component(0):
light.DOMAIN: { assert setup_component(self.hass, light.DOMAIN, {
'platform': 'mqtt_json', light.DOMAIN: {
'name': 'test', 'platform': 'mqtt_json',
} 'name': 'test',
}) }
})
self.assertIsNone(self.hass.states.get('light.test')) self.assertIsNone(self.hass.states.get('light.test'))
def test_no_color_or_brightness_if_no_config(self): def test_no_color_or_brightness_if_no_config(self): \
# pylint: disable=invalid-name
"""Test if there is no color and brightness if they aren't defined.""" """Test if there is no color and brightness if they aren't defined."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { assert _setup_component(self.hass, light.DOMAIN, {
@ -85,7 +89,8 @@ class TestLightMQTTJSON(unittest.TestCase):
self.assertIsNone(state.attributes.get('rgb_color')) self.assertIsNone(state.attributes.get('rgb_color'))
self.assertIsNone(state.attributes.get('brightness')) self.assertIsNone(state.attributes.get('brightness'))
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self): \
# pylint: disable=invalid-name
"""Test the controlling of the state via topic.""" """Test the controlling of the state via topic."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { assert _setup_component(self.hass, light.DOMAIN, {
@ -108,10 +113,9 @@ class TestLightMQTTJSON(unittest.TestCase):
# Turn on the light, full white # Turn on the light, full white
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"color":{"r":255,"g":255,"b":255},' + '"color":{"r":255,"g":255,"b":255},'
'"brightness":255}' '"brightness":255}')
)
self.hass.block_till_done() self.hass.block_till_done()
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
@ -127,9 +131,8 @@ class TestLightMQTTJSON(unittest.TestCase):
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"brightness":100}' '"brightness":100}')
)
self.hass.block_till_done() self.hass.block_till_done()
light_state = self.hass.states.get('light.test') light_state = self.hass.states.get('light.test')
@ -138,16 +141,16 @@ class TestLightMQTTJSON(unittest.TestCase):
light_state.attributes['brightness']) light_state.attributes['brightness'])
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"color":{"r":125,"g":125,"b":125}}' '"color":{"r":125,"g":125,"b":125}}')
)
self.hass.block_till_done() self.hass.block_till_done()
light_state = self.hass.states.get('light.test') light_state = self.hass.states.get('light.test')
self.assertEqual([125, 125, 125], self.assertEqual([125, 125, 125],
light_state.attributes.get('rgb_color')) light_state.attributes.get('rgb_color'))
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self): \
# pylint: disable=invalid-name
"""Test the sending of command in optimistic mode.""" """Test the sending of command in optimistic mode."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { assert _setup_component(self.hass, light.DOMAIN, {
@ -202,7 +205,8 @@ class TestLightMQTTJSON(unittest.TestCase):
self.assertEqual((75, 75, 75), state.attributes['rgb_color']) self.assertEqual((75, 75, 75), state.attributes['rgb_color'])
self.assertEqual(50, state.attributes['brightness']) self.assertEqual(50, state.attributes['brightness'])
def test_flash_short_and_long(self): def test_flash_short_and_long(self): \
# pylint: disable=invalid-name
"""Test for flash length being sent when included.""" """Test for flash length being sent when included."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { assert _setup_component(self.hass, light.DOMAIN, {
@ -285,7 +289,8 @@ class TestLightMQTTJSON(unittest.TestCase):
self.assertEqual(10, message_json["transition"]) self.assertEqual(10, message_json["transition"])
self.assertEqual("OFF", message_json["state"]) self.assertEqual("OFF", message_json["state"])
def test_invalid_color_and_brightness_values(self): def test_invalid_color_and_brightness_values(self): \
# pylint: disable=invalid-name
"""Test that invalid color/brightness values are ignored.""" """Test that invalid color/brightness values are ignored."""
self.hass.config.components = ['mqtt'] self.hass.config.components = ['mqtt']
assert _setup_component(self.hass, light.DOMAIN, { assert _setup_component(self.hass, light.DOMAIN, {
@ -308,10 +313,9 @@ class TestLightMQTTJSON(unittest.TestCase):
# Turn on the light # Turn on the light
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"color":{"r":255,"g":255,"b":255},' + '"color":{"r":255,"g":255,"b":255},'
'"brightness": 255}' '"brightness": 255}')
)
self.hass.block_till_done() self.hass.block_till_done()
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
@ -321,9 +325,8 @@ class TestLightMQTTJSON(unittest.TestCase):
# Bad color values # Bad color values
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"color":{"r":"bad","g":"val","b":"test"}}' '"color":{"r":"bad","g":"val","b":"test"}}')
)
self.hass.block_till_done() self.hass.block_till_done()
# Color should not have changed # Color should not have changed
@ -333,9 +336,8 @@ class TestLightMQTTJSON(unittest.TestCase):
# Bad brightness values # Bad brightness values
fire_mqtt_message(self.hass, 'test_light_rgb', fire_mqtt_message(self.hass, 'test_light_rgb',
'{"state":"ON",' + '{"state":"ON",'
'"brightness": "badValue"}' '"brightness": "badValue"}')
)
self.hass.block_till_done() self.hass.block_till_done()
# Brightness should not have changed # Brightness should not have changed

View File

@ -5,7 +5,7 @@ from homeassistant.bootstrap import setup_component
import homeassistant.components.notify as notify import homeassistant.components.notify as notify
from homeassistant.components.notify import group from homeassistant.components.notify import group
from tests.common import get_test_home_assistant from tests.common import assert_setup_component, get_test_home_assistant
class TestNotifyGroup(unittest.TestCase): class TestNotifyGroup(unittest.TestCase):
@ -15,15 +15,16 @@ class TestNotifyGroup(unittest.TestCase):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
self.events = [] self.events = []
self.assertTrue(setup_component(self.hass, notify.DOMAIN, { with assert_setup_component(2):
'notify': [{ setup_component(self.hass, notify.DOMAIN, {
'name': 'demo1', 'notify': [{
'platform': 'demo' 'name': 'demo1',
}, { 'platform': 'demo'
'name': 'demo2', }, {
'platform': 'demo' 'name': 'demo2',
}] 'platform': 'demo'
})) }]
})
self.service = group.get_service(self.hass, {'services': [ self.service = group.get_service(self.hass, {'services': [
{'service': 'demo1'}, {'service': 'demo1'},

View File

@ -57,12 +57,12 @@ class TestDarkSkySetup(unittest.TestCase):
@requests_mock.Mocker() @requests_mock.Mocker()
@patch('forecastio.api.get_forecast', wraps=forecastio.api.get_forecast) @patch('forecastio.api.get_forecast', wraps=forecastio.api.get_forecast)
def test_setup(self, m, mock_get_forecast): def test_setup(self, mock_req, mock_get_forecast):
"""Test for successfully setting up the forecast.io platform.""" """Test for successfully setting up the forecast.io platform."""
uri = ('https://api.darksky.net\/forecast\/(\w+)\/' uri = (r'https://api.(darksky.net|forecast.io)\/forecast\/(\w+)\/'
'(-?\d+\.?\d*),(-?\d+\.?\d*)') r'(-?\d+\.?\d*),(-?\d+\.?\d*)')
m.get(re.compile(uri), mock_req.get(re.compile(uri),
text=load_fixture('darksky.json')) text=load_fixture('darksky.json'))
darksky.setup_platform(self.hass, self.config, MagicMock()) darksky.setup_platform(self.hass, self.config, MagicMock())
self.assertTrue(mock_get_forecast.called) self.assertTrue(mock_get_forecast.called)
self.assertEqual(mock_get_forecast.call_count, 1) self.assertEqual(mock_get_forecast.call_count, 1)

View File

@ -4,10 +4,10 @@ from unittest.mock import MagicMock
import requests_mock import requests_mock
from homeassistant import core as ha
from homeassistant.components.sensor import sleepiq from homeassistant.components.sensor import sleepiq
from tests.components.test_sleepiq import mock_responses from tests.components.test_sleepiq import mock_responses
from tests.common import get_test_home_assistant
class TestSleepIQSensorSetup(unittest.TestCase): class TestSleepIQSensorSetup(unittest.TestCase):
@ -22,7 +22,7 @@ class TestSleepIQSensorSetup(unittest.TestCase):
def setUp(self): def setUp(self):
"""Initialize values for this testcase class.""" """Initialize values for this testcase class."""
self.hass = ha.HomeAssistant() self.hass = get_test_home_assistant()
self.username = 'foo' self.username = 'foo'
self.password = 'bar' self.password = 'bar'
self.config = { self.config = {

View File

@ -1,12 +1,15 @@
"""The test for the Template sensor platform.""" """The test for the Template sensor platform."""
import homeassistant.bootstrap as bootstrap from homeassistant.bootstrap import setup_component
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestTemplateSensor: class TestTemplateSensor:
"""Test the Template sensor.""" """Test the Template sensor."""
hass = None
# pylint: disable=invalid-name
def setup_method(self, method): def setup_method(self, method):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
@ -17,17 +20,18 @@ class TestTemplateSensor:
def test_template(self): def test_template(self):
"""Test template.""" """Test template."""
assert bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(1):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test_template_sensor': { 'sensors': {
'value_template': 'test_template_sensor': {
"It {{ states.sensor.test_state.state }}." 'value_template':
"It {{ states.sensor.test_state.state }}."
}
} }
} }
} })
})
state = self.hass.states.get('sensor.test_template_sensor') state = self.hass.states.get('sensor.test_template_sensor')
assert state.state == 'It .' assert state.state == 'It .'
@ -39,83 +43,89 @@ class TestTemplateSensor:
def test_template_syntax_error(self): def test_template_syntax_error(self):
"""Test templating syntax error.""" """Test templating syntax error."""
assert not bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test_template_sensor': { 'sensors': {
'value_template': 'test_template_sensor': {
"{% if rubbish %}" 'value_template':
"{% if rubbish %}"
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_template_attribute_missing(self): def test_template_attribute_missing(self):
"""Test missing attribute template.""" """Test missing attribute template."""
assert bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(1):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test_template_sensor': { 'sensors': {
'value_template': 'test_template_sensor': {
"It {{ states.sensor.test_state.attributes.missing }}." 'value_template': 'It {{ states.sensor.test_state'
'.attributes.missing }}.'
}
} }
} }
} })
})
state = self.hass.states.get('sensor.test_template_sensor') state = self.hass.states.get('sensor.test_template_sensor')
assert state.state == 'unknown' assert state.state == 'unknown'
def test_invalid_name_does_not_create(self): def test_invalid_name_does_not_create(self):
"""Test invalid name.""" """Test invalid name."""
assert not bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test INVALID sensor': { 'sensors': {
'value_template': 'test INVALID sensor': {
"{{ states.sensor.test_state.state }}" 'value_template':
"{{ states.sensor.test_state.state }}"
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_invalid_sensor_does_not_create(self): def test_invalid_sensor_does_not_create(self):
"""Test invalid sensor.""" """Test invalid sensor."""
assert not bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test_template_sensor': 'invalid' 'sensors': {
'test_template_sensor': 'invalid'
}
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_no_sensors_does_not_create(self): def test_no_sensors_does_not_create(self):
"""Test no sensors.""" """Test no sensors."""
assert not bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template' 'sensor': {
} 'platform': 'template'
}) }
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_missing_template_does_not_create(self): def test_missing_template_does_not_create(self):
"""Test missing template.""" """Test missing template."""
assert not bootstrap.setup_component(self.hass, 'sensor', { with assert_setup_component(0):
'sensor': { assert setup_component(self.hass, 'sensor', {
'platform': 'template', 'sensor': {
'sensors': { 'platform': 'template',
'test_template_sensor': { 'sensors': {
'not_value_template': 'test_template_sensor': {
"{{ states.sensor.test_state.state }}" 'not_value_template':
"{{ states.sensor.test_state.state }}"
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []

View File

@ -1,6 +1,6 @@
"""The tests for the Flux switch platform.""" """The tests for the Flux switch platform."""
import unittest
from datetime import timedelta from datetime import timedelta
import unittest
from unittest.mock import patch from unittest.mock import patch
from homeassistant.bootstrap import setup_component from homeassistant.bootstrap import setup_component
@ -8,8 +8,10 @@ from homeassistant.components import switch, light
from homeassistant.const import CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON from homeassistant.const import CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON
import homeassistant.loader as loader import homeassistant.loader as loader
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import get_test_home_assistant
from tests.common import fire_time_changed, mock_service from tests.common import (
assert_setup_component, get_test_home_assistant, fire_time_changed,
mock_service)
class TestSwitchFlux(unittest.TestCase): class TestSwitchFlux(unittest.TestCase):
@ -50,21 +52,23 @@ class TestSwitchFlux(unittest.TestCase):
def test_valid_config_no_name(self): def test_valid_config_no_name(self):
"""Test configuration.""" """Test configuration."""
assert setup_component(self.hass, 'switch', { with assert_setup_component(1, 'switch'):
'switch': { assert setup_component(self.hass, 'switch', {
'platform': 'flux', 'switch': {
'lights': ['light.desk', 'light.lamp'] 'platform': 'flux',
} 'lights': ['light.desk', 'light.lamp']
}) }
})
def test_invalid_config_no_lights(self): def test_invalid_config_no_lights(self):
"""Test configuration.""" """Test configuration."""
assert not setup_component(self.hass, 'switch', { with assert_setup_component(0, 'switch'):
'switch': { assert setup_component(self.hass, 'switch', {
'platform': 'flux', 'switch': {
'name': 'flux' 'platform': 'flux',
} 'name': 'flux'
}) }
})
def test_flux_when_switch_is_off(self): def test_flux_when_switch_is_off(self):
"""Test the flux switch when it is off.""" """Test the flux switch when it is off."""

View File

@ -6,12 +6,16 @@ from homeassistant.const import (
STATE_ON, STATE_ON,
STATE_OFF) STATE_OFF)
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant, assert_setup_component
class TestTemplateSwitch: class TestTemplateSwitch:
"""Test the Template switch.""" """Test the Template switch."""
hass = None
calls = None
# pylint: disable=invalid-name
def setup_method(self, method): def setup_method(self, method):
"""Setup things to be run when tests are started.""" """Setup things to be run when tests are started."""
self.hass = get_test_home_assistant() self.hass = get_test_home_assistant()
@ -29,25 +33,26 @@ class TestTemplateSwitch:
def test_template_state_text(self): def test_template_state_text(self):
""""Test the state text of a template.""" """"Test the state text of a template."""
assert bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(1):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{{ states.switch.test_state.state }}", 'value_template':
'turn_on': { "{{ states.switch.test_state.state }}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
state = self.hass.states.set('switch.test_state', STATE_ON) state = self.hass.states.set('switch.test_state', STATE_ON)
self.hass.block_till_done() self.hass.block_till_done()
@ -63,188 +68,197 @@ class TestTemplateSwitch:
def test_template_state_boolean_on(self): def test_template_state_boolean_on(self):
"""Test the setting of the state with boolean on.""" """Test the setting of the state with boolean on."""
assert bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(1):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{{ 1 == 1 }}", 'value_template':
'turn_on': { "{{ 1 == 1 }}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
state = self.hass.states.get('switch.test_template_switch') state = self.hass.states.get('switch.test_template_switch')
assert state.state == STATE_ON assert state.state == STATE_ON
def test_template_state_boolean_off(self): def test_template_state_boolean_off(self):
"""Test the setting of the state with off.""" """Test the setting of the state with off."""
assert bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(1):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{{ 1 == 2 }}", 'value_template':
'turn_on': { "{{ 1 == 2 }}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
state = self.hass.states.get('switch.test_template_switch') state = self.hass.states.get('switch.test_template_switch')
assert state.state == STATE_OFF assert state.state == STATE_OFF
def test_template_syntax_error(self): def test_template_syntax_error(self):
"""Test templating syntax error.""" """Test templating syntax error."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{% if rubbish %}", 'value_template':
'turn_on': { "{% if rubbish %}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_invalid_name_does_not_create(self): def test_invalid_name_does_not_create(self):
"""Test invalid name.""" """Test invalid name."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test INVALID switch': { 'switches': {
'value_template': 'test INVALID switch': {
"{{ rubbish }", 'value_template':
'turn_on': { "{{ rubbish }",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_invalid_switch_does_not_create(self): def test_invalid_switch_does_not_create(self):
"""Test invalid switch.""" """Test invalid switch."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': 'Invalid' 'switches': {
'test_template_switch': 'Invalid'
}
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_no_switches_does_not_create(self): def test_no_switches_does_not_create(self):
"""Test if there are no switches no creation.""" """Test if there are no switches no creation."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template' 'switch': {
} 'platform': 'template'
}) }
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_missing_template_does_not_create(self): def test_missing_template_does_not_create(self):
"""Test missing template.""" """Test missing template."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'not_value_template': 'test_template_switch': {
"{{ states.switch.test_state.state }}", 'not_value_template':
'turn_on': { "{{ states.switch.test_state.state }}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_missing_on_does_not_create(self): def test_missing_on_does_not_create(self):
"""Test missing on.""" """Test missing on."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{{ states.switch.test_state.state }}", 'value_template':
'not_on': { "{{ states.switch.test_state.state }}",
'service': 'switch.turn_on', 'not_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'turn_off': { },
'service': 'switch.turn_off', 'turn_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_missing_off_does_not_create(self): def test_missing_off_does_not_create(self):
"""Test missing off.""" """Test missing off."""
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'template', 'switch': {
'switches': { 'platform': 'template',
'test_template_switch': { 'switches': {
'value_template': 'test_template_switch': {
"{{ states.switch.test_state.state }}", 'value_template':
'turn_on': { "{{ states.switch.test_state.state }}",
'service': 'switch.turn_on', 'turn_on': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_on',
}, 'entity_id': 'switch.test_state'
'not_off': { },
'service': 'switch.turn_off', 'not_off': {
'entity_id': 'switch.test_state' 'service': 'switch.turn_off',
}, 'entity_id': 'switch.test_state'
},
}
} }
} }
} })
})
assert self.hass.states.all() == [] assert self.hass.states.all() == []
def test_on_action(self): def test_on_action(self):

View File

@ -4,7 +4,7 @@ import unittest
from unittest import mock from unittest import mock
from homeassistant.bootstrap import _setup_component from homeassistant.bootstrap import setup_component
from homeassistant.const import ( from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_UNIT_OF_MEASUREMENT,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -16,7 +16,7 @@ from homeassistant.const import (
from homeassistant.util.unit_system import METRIC_SYSTEM from homeassistant.util.unit_system import METRIC_SYSTEM
from homeassistant.components import thermostat from homeassistant.components import thermostat
from tests.common import get_test_home_assistant from tests.common import assert_setup_component, get_test_home_assistant
ENTITY = 'thermostat.test' ENTITY = 'thermostat.test'
@ -44,12 +44,13 @@ class TestSetupThermostatHeatControl(unittest.TestCase):
'name': 'test', 'name': 'test',
'target_sensor': ENT_SENSOR 'target_sensor': ENT_SENSOR
} }
self.assertFalse(_setup_component(self.hass, 'thermostat', { with assert_setup_component(0):
'thermostat': config})) setup_component(self.hass, 'thermostat', {
'thermostat': config})
def test_valid_conf(self): def test_valid_conf(self):
"""Test set up heat_control with valid config values.""" """Test set up heat_control with valid config values."""
self.assertTrue(_setup_component(self.hass, 'thermostat', self.assertTrue(setup_component(self.hass, 'thermostat',
{'thermostat': { {'thermostat': {
'platform': 'heat_control', 'platform': 'heat_control',
'name': 'test', 'name': 'test',

View File

@ -89,14 +89,18 @@ class TestCheckConfig(unittest.TestCase):
with patch_yaml_files(files): with patch_yaml_files(files):
res = check_config.check(get_test_config_dir('platform.yaml')) res = check_config.check(get_test_config_dir('platform.yaml'))
change_yaml_files(res) change_yaml_files(res)
self.assertDictEqual({ self.assertDictEqual(
'components': {'mqtt': {'keepalive': 60, 'port': 1883, {'mqtt': {'keepalive': 60, 'port': 1883, 'protocol': '3.1.1'},
'protocol': '3.1.1'}}, 'light': []},
'except': {'light.mqtt_json': {'platform': 'mqtt_json'}}, res['components']
'secret_cache': {}, )
'secrets': {}, self.assertDictEqual(
'yaml_files': ['.../platform.yaml'] {'light.mqtt_json': {'platform': 'mqtt_json'}},
}, res) res['except']
)
self.assertDictEqual({}, res['secret_cache'])
self.assertDictEqual({}, res['secrets'])
self.assertListEqual(['.../platform.yaml'], res['yaml_files'])
def test_component_platform_not_found(self, mock_get_loop): def test_component_platform_not_found(self, mock_get_loop):
"""Test errors if component or platform not found.""" """Test errors if component or platform not found."""
@ -107,25 +111,23 @@ class TestCheckConfig(unittest.TestCase):
with patch_yaml_files(files): with patch_yaml_files(files):
res = check_config.check(get_test_config_dir('badcomponent.yaml')) res = check_config.check(get_test_config_dir('badcomponent.yaml'))
change_yaml_files(res) change_yaml_files(res)
self.assertDictEqual({ self.assertDictEqual({}, res['components'])
'components': {}, self.assertDictEqual({check_config.ERROR_STR:
'except': {check_config.ERROR_STR: ['Component not found: beer']},
['Component not found: beer']}, res['except'])
'secret_cache': {}, self.assertDictEqual({}, res['secret_cache'])
'secrets': {}, self.assertDictEqual({}, res['secrets'])
'yaml_files': ['.../badcomponent.yaml'] self.assertListEqual(['.../badcomponent.yaml'], res['yaml_files'])
}, res)
res = check_config.check(get_test_config_dir('badplatform.yaml')) res = check_config.check(get_test_config_dir('badplatform.yaml'))
change_yaml_files(res) change_yaml_files(res)
self.assertDictEqual({ self.assertDictEqual({'light': []}, res['components'])
'components': {}, self.assertDictEqual({check_config.ERROR_STR:
'except': {check_config.ERROR_STR: ['Platform not found: light.beer']},
['Platform not found: light.beer']}, res['except'])
'secret_cache': {}, self.assertDictEqual({}, res['secret_cache'])
'secrets': {}, self.assertDictEqual({}, res['secrets'])
'yaml_files': ['.../badplatform.yaml'] self.assertListEqual(['.../badplatform.yaml'], res['yaml_files'])
}, res)
def test_secrets(self, mock_get_loop): def test_secrets(self, mock_get_loop):
"""Test secrets config checking method.""" """Test secrets config checking method."""

View File

@ -3,6 +3,7 @@
import tempfile import tempfile
from unittest import mock from unittest import mock
import threading import threading
import logging
import voluptuous as vol import voluptuous as vol
@ -10,14 +11,22 @@ from homeassistant import bootstrap, loader
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA from homeassistant.helpers.config_validation import PLATFORM_SCHEMA
from tests.common import get_test_home_assistant, MockModule, MockPlatform from tests.common import \
get_test_home_assistant, MockModule, MockPlatform, assert_setup_component
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
_LOGGER = logging.getLogger(__name__)
class TestBootstrap: class TestBootstrap:
"""Test the bootstrap utils.""" """Test the bootstrap utils."""
hass = None
backup_cache = None
# pylint: disable=invalid-name, no-self-use
def setup_method(self, method): def setup_method(self, method):
"""Setup the test.""" """Setup the test."""
self.backup_cache = loader._COMPONENT_CACHE self.backup_cache = loader._COMPONENT_CACHE
@ -110,59 +119,72 @@ class TestBootstrap:
loader.set_component( loader.set_component(
'platform_conf.whatever', MockPlatform('whatever')) 'platform_conf.whatever', MockPlatform('whatever'))
assert not bootstrap._setup_component(self.hass, 'platform_conf', { with assert_setup_component(0):
'platform_conf': { assert bootstrap._setup_component(self.hass, 'platform_conf', {
'hello': 'world', 'platform_conf': {
'invalid': 'extra', 'hello': 'world',
} 'invalid': 'extra',
}) }
})
assert not bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': {
'platform': 'whatever',
'hello': 'world',
},
'platform_conf 2': {
'invalid': True
}
})
assert not bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': {
'platform': 'not_existing',
'hello': 'world',
}
})
assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': {
'platform': 'whatever',
'hello': 'world',
}
})
self.hass.config.components.remove('platform_conf') self.hass.config.components.remove('platform_conf')
assert bootstrap._setup_component(self.hass, 'platform_conf', { with assert_setup_component(1):
'platform_conf': [{ assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform': 'whatever', 'platform_conf': {
'hello': 'world', 'platform': 'whatever',
}] 'hello': 'world',
}) },
'platform_conf 2': {
'invalid': True
}
})
self.hass.config.components.remove('platform_conf') self.hass.config.components.remove('platform_conf')
# Any falsey paltform config will be ignored (None, {}, etc) with assert_setup_component(0):
assert bootstrap._setup_component(self.hass, 'platform_conf', { assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': None 'platform_conf': {
}) 'platform': 'not_existing',
'hello': 'world',
}
})
self.hass.config.components.remove('platform_conf') self.hass.config.components.remove('platform_conf')
assert bootstrap._setup_component(self.hass, 'platform_conf', { with assert_setup_component(1):
'platform_conf': {} assert bootstrap._setup_component(self.hass, 'platform_conf', {
}) 'platform_conf': {
'platform': 'whatever',
'hello': 'world',
}
})
self.hass.config.components.remove('platform_conf')
with assert_setup_component(1):
assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': [{
'platform': 'whatever',
'hello': 'world',
}]
})
self.hass.config.components.remove('platform_conf')
# Any falsey platform config will be ignored (None, {}, etc)
with assert_setup_component(0) as config:
assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': None
})
assert 'platform_conf' in self.hass.config.components
assert not config['platform_conf'] # empty
assert bootstrap._setup_component(self.hass, 'platform_conf', {
'platform_conf': {}
})
assert 'platform_conf' in self.hass.config.components
assert not config['platform_conf'] # empty
def test_component_not_found(self): def test_component_not_found(self):
"""setup_component should not crash if component doesn't exist.""" """setup_component should not crash if component doesn't exist."""
@ -170,7 +192,6 @@ class TestBootstrap:
def test_component_not_double_initialized(self): def test_component_not_double_initialized(self):
"""Test we do not setup a component twice.""" """Test we do not setup a component twice."""
mock_setup = mock.MagicMock(return_value=True) mock_setup = mock.MagicMock(return_value=True)
loader.set_component('comp', MockModule('comp', setup=mock_setup)) loader.set_component('comp', MockModule('comp', setup=mock_setup))
@ -195,15 +216,13 @@ class TestBootstrap:
assert 'comp' not in self.hass.config.components assert 'comp' not in self.hass.config.components
def test_component_not_setup_twice_if_loaded_during_other_setup(self): def test_component_not_setup_twice_if_loaded_during_other_setup(self):
""" """Test component setup while waiting for lock is not setup twice."""
Test component that gets setup while waiting for lock is not setup
twice.
"""
loader.set_component('comp', MockModule('comp')) loader.set_component('comp', MockModule('comp'))
result = [] result = []
def setup_component(): def setup_component():
"""Setup the component."""
result.append(bootstrap.setup_component(self.hass, 'comp')) result.append(bootstrap.setup_component(self.hass, 'comp'))
with bootstrap._SETUP_LOCK: with bootstrap._SETUP_LOCK:
@ -258,7 +277,6 @@ class TestBootstrap:
def test_component_setup_with_validation_and_dependency(self): def test_component_setup_with_validation_and_dependency(self):
"""Test all config is passed to dependencies.""" """Test all config is passed to dependencies."""
def config_check_setup(hass, config): def config_check_setup(hass, config):
"""Setup method that tests config is passed in.""" """Setup method that tests config is passed in."""
if config.get('comp_a', {}).get('valid', False): if config.get('comp_a', {}).get('valid', False):
@ -283,36 +301,48 @@ class TestBootstrap:
def test_platform_specific_config_validation(self): def test_platform_specific_config_validation(self):
"""Test platform that specifies config.""" """Test platform that specifies config."""
platform_schema = PLATFORM_SCHEMA.extend({ platform_schema = PLATFORM_SCHEMA.extend({
'valid': True, 'valid': True,
}, extra=vol.PREVENT_EXTRA) }, extra=vol.PREVENT_EXTRA)
mock_setup = mock.MagicMock()
loader.set_component( loader.set_component(
'switch.platform_a', 'switch.platform_a',
MockPlatform(platform_schema=platform_schema)) MockPlatform(platform_schema=platform_schema,
setup_platform=mock_setup))
assert not bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'platform_a', 'switch': {
'invalid': True 'platform': 'platform_a',
} 'invalid': True
}) }
})
assert mock_setup.call_count == 0
assert not bootstrap.setup_component(self.hass, 'switch', { self.hass.config.components.remove('switch')
'switch': {
'platform': 'platform_a',
'valid': True,
'invalid_extra': True,
}
})
assert bootstrap.setup_component(self.hass, 'switch', { with assert_setup_component(0):
'switch': { assert bootstrap.setup_component(self.hass, 'switch', {
'platform': 'platform_a', 'switch': {
'valid': True 'platform': 'platform_a',
} 'valid': True,
}) 'invalid_extra': True,
}
})
assert mock_setup.call_count == 0
self.hass.config.components.remove('switch')
with assert_setup_component(1):
assert bootstrap.setup_component(self.hass, 'switch', {
'switch': {
'platform': 'platform_a',
'valid': True
}
})
assert mock_setup.call_count == 1
def test_disable_component_if_invalid_return(self): def test_disable_component_if_invalid_return(self):
"""Test disabling component if invalid return.""" """Test disabling component if invalid return."""