hass-core/tests/components/mqtt/test_discovery.py
Otto Winter b1c0cabe6c Fix MQTT retained message not being re-dispatched (#12004)
* Fix MQTT retained message not being re-dispatched

* Fix tests

* Use paho-mqtt for retained messages

* Improve code style

* Store list of subscribers

* Fix lint error

* Adhere to Home Assistant's logging standard

"Try to avoid brackets and additional quotes around the output to make it easier for users to parse the log."
 - https://home-assistant.io/developers/development_guidelines/

* Add reconnect tests

* Fix lint error

* Introduce Subscription

Tests still need to be updated

* Use namedtuple for MQTT messages

... And fix issues

Accessing the config manually at runtime isn't ideal

* Fix MQTT __init__.py tests

* Updated usage of Mocks
* Moved tests that were testing subscriptions out of the MQTTComponent test, because of how mock.patch was used
* Adjusted the remaining tests for the MQTT clients new behavior - e.g. self.progress was removed
* Updated the async_fire_mqtt_message helper

*  Update MQTT tests

* Re-introduce the MQTT subscriptions through the dispatcher for tests - quite ugly though...  🚧
* Update fixtures to use our new MQTT mock 🎨

* 📝 Update base code according to comments

* 🔨 Adjust MQTT test base

* 🔨 Update other MQTT tests

* 🍎 Fix carriage return in source files

Apparently test_mqtt_json.py and test_mqtt_template.py were written on Windows. In order to not mess up the diff, I'll just redo the carriage return.

* 🎨 Remove unused import

* 📝 Remove fire_mqtt_client_message

* 🐛 Fix using python 3.6 method

What's very interesting is that 3.4 didn't fail on travis...

* 🐛 Fix using assert directly
2018-02-11 09:17:58 -08:00

131 lines
4.6 KiB
Python

"""The tests for the MQTT discovery."""
import asyncio
from unittest.mock import patch
from homeassistant.components.mqtt.discovery import async_start, \
ALREADY_DISCOVERED
from tests.common import async_fire_mqtt_message, mock_coro
@asyncio.coroutine
def test_subscribing_config_topic(hass, mqtt_mock):
"""Test setting up discovery."""
hass_config = {}
discovery_topic = 'homeassistant'
yield from async_start(hass, discovery_topic, hass_config)
assert mqtt_mock.async_subscribe.called
call_args = mqtt_mock.async_subscribe.mock_calls[0][1]
assert call_args[0] == discovery_topic + '/#'
assert call_args[2] == 0
@asyncio.coroutine
@patch('homeassistant.components.mqtt.discovery.async_load_platform')
def test_invalid_topic(mock_load_platform, hass, mqtt_mock):
"""Test sending to invalid topic."""
mock_load_platform.return_value = mock_coro()
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/not_config',
'{}')
yield from hass.async_block_till_done()
assert not mock_load_platform.called
@asyncio.coroutine
@patch('homeassistant.components.mqtt.discovery.async_load_platform')
def test_invalid_json(mock_load_platform, hass, mqtt_mock, caplog):
"""Test sending in invalid JSON."""
mock_load_platform.return_value = mock_coro()
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config',
'not json')
yield from hass.async_block_till_done()
assert 'Unable to parse JSON' in caplog.text
assert not mock_load_platform.called
@asyncio.coroutine
@patch('homeassistant.components.mqtt.discovery.async_load_platform')
def test_only_valid_components(mock_load_platform, hass, mqtt_mock, caplog):
"""Test for a valid component."""
mock_load_platform.return_value = mock_coro()
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/climate/bla/config', '{}')
yield from hass.async_block_till_done()
assert 'Component climate is not supported' in caplog.text
assert not mock_load_platform.called
@asyncio.coroutine
def test_correct_config_discovery(hass, mqtt_mock, caplog):
"""Test sending in correct JSON."""
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config',
'{ "name": "Beer" }')
yield from hass.async_block_till_done()
state = hass.states.get('binary_sensor.beer')
assert state is not None
assert state.name == 'Beer'
assert ('binary_sensor', 'bla') in hass.data[ALREADY_DISCOVERED]
@asyncio.coroutine
def test_discover_fan(hass, mqtt_mock, caplog):
"""Test discovering an MQTT fan."""
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/fan/bla/config',
('{ "name": "Beer",'
' "command_topic": "test_topic" }'))
yield from hass.async_block_till_done()
state = hass.states.get('fan.beer')
assert state is not None
assert state.name == 'Beer'
assert ('fan', 'bla') in hass.data[ALREADY_DISCOVERED]
@asyncio.coroutine
def test_discovery_incl_nodeid(hass, mqtt_mock, caplog):
"""Test sending in correct JSON with optional node_id included."""
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/my_node_id/bla'
'/config', '{ "name": "Beer" }')
yield from hass.async_block_till_done()
state = hass.states.get('binary_sensor.beer')
assert state is not None
assert state.name == 'Beer'
assert ('binary_sensor', 'my_node_id_bla') in hass.data[ALREADY_DISCOVERED]
@asyncio.coroutine
def test_non_duplicate_discovery(hass, mqtt_mock, caplog):
"""Test for a non duplicate component."""
yield from async_start(hass, 'homeassistant', {})
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config',
'{ "name": "Beer" }')
async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config',
'{ "name": "Beer" }')
yield from hass.async_block_till_done()
state = hass.states.get('binary_sensor.beer')
state_duplicate = hass.states.get('binary_sensor.beer1')
assert state is not None
assert state.name == 'Beer'
assert state_duplicate is None
assert 'Component has already been discovered: ' \
'binary_sensor bla' in caplog.text