diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 927b75024ab..5bae39233ad 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -14,7 +14,6 @@ import voluptuous as vol from homeassistant.bootstrap import prepare_setup_platform from homeassistant.config import load_yaml_config_file from homeassistant.exceptions import HomeAssistantError -import homeassistant.util as util from homeassistant.helpers import template import homeassistant.helpers.config_validation as cv from homeassistant.const import ( @@ -58,6 +57,25 @@ ATTR_RETAIN = 'retain' MAX_RECONNECT_WAIT = 300 # seconds +_HBMQTT_CONFIG_SCHEMA = vol.Schema(dict) + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Optional(CONF_CLIENT_ID): cv.string, + vol.Optional(CONF_KEEPALIVE, default=DEFAULT_KEEPALIVE): + vol.All(vol.Coerce(int), vol.Range(min=15)), + vol.Optional(CONF_BROKER): cv.string, + vol.Optional(CONF_PORT, default=DEFAULT_PORT): + vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)), + vol.Optional(CONF_USERNAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, + vol.Optional(CONF_CERTIFICATE): vol.IsFile, + vol.Optional(CONF_PROTOCOL, default=DEFAULT_PROTOCOL): + [PROTOCOL_31, PROTOCOL_311], + vol.Optional(CONF_EMBEDDED): _HBMQTT_CONFIG_SCHEMA, + }), +}) + # Service call validation schema def mqtt_topic(value): @@ -136,8 +154,8 @@ def setup(hass, config): # pylint: disable=too-many-locals conf = config.get(DOMAIN, {}) - client_id = util.convert(conf.get(CONF_CLIENT_ID), str) - keepalive = util.convert(conf.get(CONF_KEEPALIVE), int, DEFAULT_KEEPALIVE) + client_id = conf.get(CONF_CLIENT_ID) + keepalive = conf.get(CONF_KEEPALIVE) broker_config = _setup_server(hass, config) @@ -151,16 +169,11 @@ def setup(hass, config): if CONF_BROKER in conf: broker = conf[CONF_BROKER] - port = util.convert(conf.get(CONF_PORT), int, DEFAULT_PORT) - username = util.convert(conf.get(CONF_USERNAME), str) - password = util.convert(conf.get(CONF_PASSWORD), str) - certificate = util.convert(conf.get(CONF_CERTIFICATE), str) - protocol = util.convert(conf.get(CONF_PROTOCOL), str, DEFAULT_PROTOCOL) - - if protocol not in (PROTOCOL_31, PROTOCOL_311): - _LOGGER.error('Invalid protocol specified: %s. Allowed values: %s, %s', - protocol, PROTOCOL_31, PROTOCOL_311) - return False + port = conf[CONF_PORT] + username = conf.get(CONF_USERNAME) + password = conf.get(CONF_PASSWORD) + certificate = conf.get(CONF_CERTIFICATE) + protocol = conf[CONF_PROTOCOL] # For cloudmqtt.com, secured connection, auto fill in certificate if certificate is None and 19999 < port < 30000 and \ diff --git a/tests/common.py b/tests/common.py index 8f0c5543c1c..1c8a2454c12 100644 --- a/tests/common.py +++ b/tests/common.py @@ -4,6 +4,7 @@ from datetime import timedelta from unittest import mock from homeassistant import core as ha, loader +from homeassistant.bootstrap import _setup_component from homeassistant.helpers.entity import ToggleEntity from homeassistant.const import ( STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, EVENT_TIME_CHANGED, @@ -123,7 +124,7 @@ def mock_http_component(hass): @mock.patch('homeassistant.components.mqtt.MQTT') def mock_mqtt_component(hass, mock_mqtt): """Mock the MQTT component.""" - mqtt.setup(hass, { + _setup_component(hass, mqtt.DOMAIN, { mqtt.DOMAIN: { mqtt.CONF_BROKER: 'mock-broker', } diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index d57504562c1..f342284cdec 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -4,6 +4,7 @@ import unittest from unittest import mock import socket +from homeassistant.bootstrap import _setup_component import homeassistant.components.mqtt as mqtt from homeassistant.const import ( EVENT_CALL_SERVICE, ATTR_DOMAIN, ATTR_SERVICE, EVENT_HOMEASSISTANT_START, @@ -48,9 +49,11 @@ class TestMQTT(unittest.TestCase): """Test for setup failure if connection to broker is missing.""" with mock.patch('homeassistant.components.mqtt.MQTT', side_effect=socket.error()): - self.assertFalse(mqtt.setup(self.hass, {mqtt.DOMAIN: { - mqtt.CONF_BROKER: 'test-broker', - }})) + assert not _setup_component(self.hass, mqtt.DOMAIN, { + mqtt.DOMAIN: { + mqtt.CONF_BROKER: 'test-broker', + } + }) def test_publish_calls_service(self): """Test the publishing of call to services.""" @@ -211,7 +214,7 @@ class TestMQTTCallbacks(unittest.TestCase): # mock_mqtt_component(self.hass) with mock.patch('paho.mqtt.client.Client'): - mqtt.setup(self.hass, { + _setup_component(self.hass, mqtt.DOMAIN, { mqtt.DOMAIN: { mqtt.CONF_BROKER: 'mock-broker', } diff --git a/tests/components/mqtt/test_server.py b/tests/components/mqtt/test_server.py index d8710035916..1d0cd5d062e 100644 --- a/tests/components/mqtt/test_server.py +++ b/tests/components/mqtt/test_server.py @@ -1,6 +1,7 @@ """The tests for the MQTT component embedded server.""" from unittest.mock import MagicMock, patch +from homeassistant.bootstrap import _setup_component import homeassistant.components.mqtt as mqtt from tests.common import get_test_home_assistant @@ -27,15 +28,20 @@ class TestMQTT: password = 'super_secret' self.hass.config.api = MagicMock(api_password=password) - assert mqtt.setup(self.hass, {}) + assert _setup_component(self.hass, mqtt.DOMAIN, {}) assert mock_mqtt.called assert mock_mqtt.mock_calls[0][1][5] == 'homeassistant' assert mock_mqtt.mock_calls[0][1][6] == password - mock_mqtt.reset_mock() - + @patch('homeassistant.components.mqtt.MQTT') + @patch('asyncio.gather') + @patch('asyncio.new_event_loop') + def test_creating_config_no_http_pass(self, mock_new_loop, mock_gather, + mock_mqtt): + """Test if the MQTT server gets started and subscribe/publish msg.""" + self.hass.config.components.append('http') self.hass.config.api = MagicMock(api_password=None) - assert mqtt.setup(self.hass, {}) + assert _setup_component(self.hass, mqtt.DOMAIN, {}) assert mock_mqtt.called assert mock_mqtt.mock_calls[0][1][5] is None assert mock_mqtt.mock_calls[0][1][6] is None @@ -50,6 +56,6 @@ class TestMQTT: mock_gather.side_effect = BrokerException self.hass.config.api = MagicMock(api_password=None) - assert not mqtt.setup(self.hass, { - 'mqtt': {'embedded': {}} + assert not _setup_component(self.hass, mqtt.DOMAIN, { + mqtt.DOMAIN: {mqtt.CONF_EMBEDDED: {}} })