diff --git a/.gitignore b/.gitignore index 658ad279292..881411c54ea 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ config/custom_components/* !config/custom_components/hello_world.py !config/custom_components/mqtt_example.py +tests/config/home-assistant.log + # Hide sublime text stuff *.sublime-project *.sublime-workspace diff --git a/homeassistant/components/conversation.py b/homeassistant/components/conversation.py index 2d439a7ac4a..fd2ad60d211 100644 --- a/homeassistant/components/conversation.py +++ b/homeassistant/components/conversation.py @@ -10,7 +10,7 @@ import re from homeassistant import core from homeassistant.const import ( - ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF) + ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF) DOMAIN = "conversation" DEPENDENCIES = [] @@ -44,7 +44,7 @@ def setup(hass, config): entity_ids = [ state.entity_id for state in hass.states.all() - if state.attributes.get(ATTR_FRIENDLY_NAME, "").lower() == name] + if state.name.lower() == name] if not entity_ids: logger.error( diff --git a/homeassistant/config.py b/homeassistant/config.py index 78da7f2a0d1..511ef9ad0db 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -54,7 +54,7 @@ def ensure_config_exists(config_dir, detect_location=True): config_path = find_config_file(config_dir) if config_path is None: - print("Unable to find configuration. Creating default one at", + print("Unable to find configuration. Creating default one in", config_dir) config_path = create_default_config(config_dir, detect_location) diff --git a/homeassistant/core.py b/homeassistant/core.py index c04e9a9ab63..b35ad123011 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -761,8 +761,10 @@ def create_timer(hass, interval=TIMER_INTERVAL): hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_timer) -def create_worker_pool(worker_count=MIN_WORKER_THREAD): +def create_worker_pool(worker_count=None): """ Creates a worker pool to be used. """ + if worker_count is None: + worker_count = MIN_WORKER_THREAD def job_handler(job): """ Called whenever a job is available to do. """ diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000000..c39a22e0b57 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,2 @@ +import logging +logging.disable(logging.CRITICAL) diff --git a/tests/common.py b/tests/common.py index be6aa623a25..72be8c5b735 100644 --- a/tests/common.py +++ b/tests/common.py @@ -8,7 +8,7 @@ import os from datetime import timedelta from unittest import mock -import homeassistant.core as ha +from homeassistant import core as ha, loader import homeassistant.util.location as location_util import homeassistant.util.dt as dt_util from homeassistant.helpers.entity import ToggleEntity @@ -38,6 +38,9 @@ def get_test_home_assistant(num_threads=None): hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 + # if not loader.PREPARED: + loader. prepare(hass) + return hass diff --git a/tests/components/automation/test_time.py b/tests/components/automation/test_time.py index 0f11a2a67c5..05c5ade1d53 100644 --- a/tests/components/automation/test_time.py +++ b/tests/components/automation/test_time.py @@ -21,7 +21,6 @@ class TestAutomationTime(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name self.hass = ha.HomeAssistant() - loader.prepare(self.hass) self.calls = [] def record_call(service): diff --git a/tests/components/test_api.py b/tests/components/test_api.py index 93b1cd06abe..b267e6b3c1c 100644 --- a/tests/components/test_api.py +++ b/tests/components/test_api.py @@ -7,6 +7,7 @@ Tests Home Assistant HTTP component does what it should do. # pylint: disable=protected-access,too-many-public-methods import unittest import json +from unittest.mock import patch import requests @@ -35,7 +36,9 @@ def _url(path=""): return HTTP_BASE_URL + path -def setUpModule(): # pylint: disable=invalid-name +@patch('homeassistant.components.http.util.get_local_ip', + return_value='127.0.0.1') +def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global hass diff --git a/tests/components/test_conversation.py b/tests/components/test_conversation.py index 40bcabff705..243fe128b28 100644 --- a/tests/components/test_conversation.py +++ b/tests/components/test_conversation.py @@ -6,13 +6,13 @@ Tests Conversation component. """ # pylint: disable=too-many-public-methods,protected-access import unittest +from unittest.mock import patch import homeassistant.components as core_components -import homeassistant.components.conversation as conversation -import homeassistant.components.demo as demo -import homeassistant.components.light as light +from homeassistant.components import conversation +from homeassistant.const import ATTR_ENTITY_ID -from common import get_test_home_assistant +from tests.common import get_test_home_assistant class TestConversation(unittest.TestCase): @@ -20,77 +20,92 @@ class TestConversation(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name """ Start up ha for testing """ + self.ent_id = 'light.kitchen_lights' self.hass = get_test_home_assistant(3) - demo.setup(self.hass, {demo.DOMAIN: {}}) - core_components.setup(self.hass, {}) + self.hass.states.set(self.ent_id, 'on') + self.assertTrue(core_components.setup(self.hass, {})) + self.assertTrue( + conversation.setup(self.hass, {conversation.DOMAIN: {}})) def tearDown(self): # pylint: disable=invalid-name """ Stop down stuff we started. """ self.hass.stop() - def test_setup_and_turn_on(self): + def test_turn_on(self): """ Setup and perform good turn on requests """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) + calls = [] - light.turn_off(self.hass, 'light.kitchen_lights') + def record_call(service): + calls.append(service) + + self.hass.services.register('light', 'turn_on', record_call) event_data = {conversation.ATTR_TEXT: 'turn kitchen lights on'} - self.hass.services.call( - conversation.DOMAIN, 'process', event_data, True) + self.assertTrue(self.hass.services.call( + conversation.DOMAIN, 'process', event_data, True)) - self.assertTrue( - light.is_on(self.hass, 'light.kitchen_lights')) + call = calls[-1] + self.assertEqual('light', call.domain) + self.assertEqual('turn_on', call.service) + self.assertEqual([self.ent_id], call.data[ATTR_ENTITY_ID]) - def test_setup_and_turn_off(self): + def test_turn_off(self): """ Setup and perform good turn off requests """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) + calls = [] - light.turn_on(self.hass, 'light.kitchen_lights') + def record_call(service): + calls.append(service) + + self.hass.services.register('light', 'turn_off', record_call) event_data = {conversation.ATTR_TEXT: 'turn kitchen lights off'} - self.hass.services.call( - conversation.DOMAIN, 'process', event_data, True) + self.assertTrue(self.hass.services.call( + conversation.DOMAIN, 'process', event_data, True)) - self.assertFalse( - light.is_on(self.hass, 'light.kitchen_lights')) + call = calls[-1] + self.assertEqual('light', call.domain) + self.assertEqual('turn_off', call.service) + self.assertEqual([self.ent_id], call.data[ATTR_ENTITY_ID]) - def test_setup_and_bad_request_format(self): + @patch('homeassistant.components.conversation.logging.Logger.error') + @patch('homeassistant.core.ServiceRegistry.call') + def test_bad_request_format(self, mock_logger, mock_call): """ Setup and perform a badly formatted request """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) - event_data = { conversation.ATTR_TEXT: 'what is the answer to the ultimate question of life, ' + 'the universe and everything'} self.assertTrue(self.hass.services.call( conversation.DOMAIN, 'process', event_data, True)) + self.assertTrue(mock_logger.called) + self.assertFalse(mock_call.called) - def test_setup_and_bad_request_entity(self): + @patch('homeassistant.components.conversation.logging.Logger.error') + @patch('homeassistant.core.ServiceRegistry.call') + def test_bad_request_entity(self, mock_logger, mock_call): """ Setup and perform requests with bad entity id """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) - event_data = {conversation.ATTR_TEXT: 'turn something off'} self.assertTrue(self.hass.services.call( conversation.DOMAIN, 'process', event_data, True)) + self.assertTrue(mock_logger.called) + self.assertFalse(mock_call.called) - def test_setup_and_bad_request_command(self): + @patch('homeassistant.components.conversation.logging.Logger.error') + @patch('homeassistant.core.ServiceRegistry.call') + def test_bad_request_command(self, mock_logger, mock_call): """ Setup and perform requests with bad command """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) - - event_data = {conversation.ATTR_TEXT: 'turn kitchen over'} + event_data = {conversation.ATTR_TEXT: 'turn kitchen lights over'} self.assertTrue(self.hass.services.call( conversation.DOMAIN, 'process', event_data, True)) + self.assertTrue(mock_logger.called) + self.assertFalse(mock_call.called) - def test_setup_and_bad_request_notext(self): + @patch('homeassistant.components.conversation.logging.Logger.error') + @patch('homeassistant.core.ServiceRegistry.call') + def test_bad_request_notext(self, mock_logger, mock_call): """ Setup and perform requests with bad command with no text """ - self.assertTrue( - conversation.setup(self.hass, {conversation.DOMAIN: {}})) - event_data = {} self.assertTrue(self.hass.services.call( conversation.DOMAIN, 'process', event_data, True)) + self.assertTrue(mock_logger.called) + self.assertFalse(mock_call.called) diff --git a/tests/components/test_device_sun_light_trigger.py b/tests/components/test_device_sun_light_trigger.py index 05b2bf11bea..1f4dbf765ff 100644 --- a/tests/components/test_device_sun_light_trigger.py +++ b/tests/components/test_device_sun_light_trigger.py @@ -15,8 +15,8 @@ from homeassistant.components import ( from tests.common import ( - get_test_home_assistant, ensure_sun_risen, ensure_sun_set, - trigger_device_tracker_scan) + get_test_config_dir, get_test_home_assistant, ensure_sun_risen, + ensure_sun_set, trigger_device_tracker_scan) KNOWN_DEV_PATH = None @@ -26,13 +26,8 @@ def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global KNOWN_DEV_PATH - hass = get_test_home_assistant() - - loader.prepare(hass) - KNOWN_DEV_PATH = hass.config.path( - device_tracker.KNOWN_DEVICES_FILE) - - hass.stop() + KNOWN_DEV_PATH = os.path.join(get_test_config_dir(), + device_tracker.KNOWN_DEVICES_FILE) with open(KNOWN_DEV_PATH, 'w') as fil: fil.write('device,name,track,picture\n') diff --git a/tests/components/test_device_tracker.py b/tests/components/test_device_tracker.py index 66fd97c4730..08ac641d19f 100644 --- a/tests/components/test_device_tracker.py +++ b/tests/components/test_device_tracker.py @@ -7,7 +7,6 @@ Tests the device tracker compoments. # pylint: disable=protected-access,too-many-public-methods import unittest from datetime import timedelta -import logging import os import homeassistant.core as ha @@ -21,18 +20,12 @@ import homeassistant.components.device_tracker as device_tracker from tests.common import get_test_home_assistant -def setUpModule(): # pylint: disable=invalid-name - """ Setup to ignore group errors. """ - logging.disable(logging.CRITICAL) - - class TestComponentsDeviceTracker(unittest.TestCase): """ Tests homeassistant.components.device_tracker module. """ def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = get_test_home_assistant() - loader.prepare(self.hass) self.known_dev_path = self.hass.config.path( device_tracker.KNOWN_DEVICES_FILE) diff --git a/tests/components/test_frontend.py b/tests/components/test_frontend.py index 65fcb5b6091..e8c0c53d13e 100644 --- a/tests/components/test_frontend.py +++ b/tests/components/test_frontend.py @@ -7,6 +7,7 @@ Tests Home Assistant HTTP component does what it should do. # pylint: disable=protected-access,too-many-public-methods import re import unittest +from unittest.mock import patch import requests @@ -34,7 +35,9 @@ def _url(path=""): return HTTP_BASE_URL + path -def setUpModule(): # pylint: disable=invalid-name +@patch('homeassistant.components.http.util.get_local_ip', + return_value='127.0.0.1') +def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global hass diff --git a/tests/components/test_init.py b/tests/components/test_init.py index 0074b75e148..4ff334c1b1e 100644 --- a/tests/components/test_init.py +++ b/tests/components/test_init.py @@ -20,7 +20,6 @@ class TestComponentsCore(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = ha.HomeAssistant() - loader.prepare(self.hass) self.assertTrue(comps.setup(self.hass, {})) self.hass.states.set('light.Bowl', STATE_ON) diff --git a/tests/components/test_light.py b/tests/components/test_light.py index e56dcbb02ad..515b79b6fc0 100644 --- a/tests/components/test_light.py +++ b/tests/components/test_light.py @@ -23,7 +23,6 @@ class TestLight(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() - loader.prepare(self.hass) def tearDown(self): # pylint: disable=invalid-name """ Stop down stuff we started. """ diff --git a/tests/components/test_media_player.py b/tests/components/test_media_player.py index 1fd406dc026..28d39206c47 100644 --- a/tests/components/test_media_player.py +++ b/tests/components/test_media_player.py @@ -5,7 +5,6 @@ tests.test_component_media_player Tests media_player component. """ # pylint: disable=too-many-public-methods,protected-access -import logging import unittest import homeassistant.core as ha @@ -18,11 +17,6 @@ import homeassistant.components.media_player as media_player from tests.common import mock_service -def setUpModule(): # pylint: disable=invalid-name - """ Setup to ignore media_player errors. """ - logging.disable(logging.CRITICAL) - - class TestMediaPlayer(unittest.TestCase): """ Test the media_player module. """ diff --git a/tests/components/test_sun.py b/tests/components/test_sun.py index 9d2ae38fdd6..366b483d3ff 100644 --- a/tests/components/test_sun.py +++ b/tests/components/test_sun.py @@ -77,7 +77,7 @@ class TestSun(unittest.TestCase): """ Test if the state changes at next setting/rising. """ self.hass.config.latitude = '32.87336' self.hass.config.longitude = '117.22743' - sun.setup(self.hass, {}) + sun.setup(self.hass, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}}) if sun.is_on(self.hass): test_state = sun.STATE_BELOW_HORIZON diff --git a/tests/components/test_switch.py b/tests/components/test_switch.py index 642c7f45aa9..afa96290aa0 100644 --- a/tests/components/test_switch.py +++ b/tests/components/test_switch.py @@ -19,7 +19,6 @@ class TestSwitch(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() - loader.prepare(self.hass) platform = loader.get_component('switch.test') diff --git a/tests/helpers/test_init.py b/tests/helpers/test_init.py index c1af6ba8ccc..1e3d8b98b1a 100644 --- a/tests/helpers/test_init.py +++ b/tests/helpers/test_init.py @@ -21,7 +21,6 @@ class TestComponentsCore(unittest.TestCase): def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = get_test_home_assistant() - loader.prepare(self.hass) self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF) diff --git a/tests/test_config.py b/tests/test_config.py index f683fac890c..c986d7551c6 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -49,13 +49,15 @@ class TestConfig(unittest.TestCase): self.assertEqual(YAML_PATH, config_util.find_config_file(CONFIG_DIR)) - def test_ensure_config_exists_creates_config(self): + @mock.patch('builtins.print') + def test_ensure_config_exists_creates_config(self, mock_print): """ Test that calling ensure_config_exists creates a new config file if none exists. """ config_util.ensure_config_exists(CONFIG_DIR, False) self.assertTrue(os.path.isfile(YAML_PATH)) + self.assertTrue(mock_print.called) def test_ensure_config_exists_uses_existing_config(self): """ Test that calling ensure_config_exists uses existing config. """ @@ -100,11 +102,12 @@ class TestConfig(unittest.TestCase): self.assertEqual({'hello': 'world'}, config_util.load_config_file(YAML_PATH)) - def test_create_default_config_detect_location(self): + @mock.patch('homeassistant.util.location.detect_location_info', + mock_detect_location_info) + @mock.patch('builtins.print') + def test_create_default_config_detect_location(self, mock_print): """ Test that detect location sets the correct config keys. """ - with mock.patch('homeassistant.util.location.detect_location_info', - mock_detect_location_info): - config_util.ensure_config_exists(CONFIG_DIR) + config_util.ensure_config_exists(CONFIG_DIR) config = config_util.load_config_file(YAML_PATH) @@ -121,11 +124,15 @@ class TestConfig(unittest.TestCase): } self.assertEqual(expected_values, ha_conf) + self.assertTrue(mock_print.called) - def test_create_default_config_returns_none_if_write_error(self): + @mock.patch('builtins.print') + def test_create_default_config_returns_none_if_write_error(self, + mock_print): """ Test that writing default config to non existing folder returns None. """ self.assertIsNone( config_util.create_default_config( os.path.join(CONFIG_DIR, 'non_existing_dir/'), False)) + self.assertTrue(mock_print.called) diff --git a/tests/test_loader.py b/tests/test_loader.py index 03bd7e7419c..67b8e8d11a6 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -17,7 +17,6 @@ class TestLoader(unittest.TestCase): """ Test the loader module. """ def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() - loader.prepare(self.hass) def tearDown(self): # pylint: disable=invalid-name """ Stop down stuff we started. """ diff --git a/tests/test_remote.py b/tests/test_remote.py index b075f05be5d..31ccad8f7aa 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -8,6 +8,7 @@ Uses port 8125 as a port that nothing runs on """ # pylint: disable=protected-access,too-many-public-methods import unittest +from unittest.mock import patch import homeassistant.core as ha import homeassistant.bootstrap as bootstrap @@ -29,7 +30,9 @@ def _url(path=""): return HTTP_BASE_URL + path -def setUpModule(): # pylint: disable=invalid-name +@patch('homeassistant.components.http.util.get_local_ip', + return_value='127.0.0.1') +def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name """ Initalizes a Home Assistant server and Slave instance. """ global hass, slave, master_api, broken_api