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
This commit is contained in:
Otto Winter 2018-02-11 18:17:58 +01:00 committed by Paulus Schoutsen
parent 17e5740a0c
commit b1c0cabe6c
15 changed files with 1531 additions and 1490 deletions

View file

@ -492,16 +492,18 @@ class TestLightMQTT(unittest.TestCase):
light.turn_on(self.hass, 'light.test')
self.hass.block_till_done()
self.assertEqual(('test_light_rgb/set', 'on', 2, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light_rgb/set', 'on', 2, False)
self.mock_publish.async_publish.reset_mock()
state = self.hass.states.get('light.test')
self.assertEqual(STATE_ON, state.state)
light.turn_off(self.hass, 'light.test')
self.hass.block_till_done()
self.assertEqual(('test_light_rgb/set', 'off', 2, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light_rgb/set', 'off', 2, False)
self.mock_publish.async_publish.reset_mock()
state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state)
@ -512,7 +514,7 @@ class TestLightMQTT(unittest.TestCase):
white_value=80)
self.hass.block_till_done()
self.mock_publish().async_publish.assert_has_calls([
self.mock_publish.async_publish.assert_has_calls([
mock.call('test_light_rgb/set', 'on', 2, False),
mock.call('test_light_rgb/rgb/set', '75,75,75', 2, False),
mock.call('test_light_rgb/brightness/set', 50, 2, False),
@ -550,7 +552,7 @@ class TestLightMQTT(unittest.TestCase):
light.turn_on(self.hass, 'light.test', rgb_color=[255, 128, 64])
self.hass.block_till_done()
self.mock_publish().async_publish.assert_has_calls([
self.mock_publish.async_publish.assert_has_calls([
mock.call('test_light_rgb/set', 'on', 0, False),
mock.call('test_light_rgb/rgb/set', '#ff8040', 0, False),
], any_order=True)
@ -701,16 +703,17 @@ class TestLightMQTT(unittest.TestCase):
# Should get the following MQTT messages.
# test_light/set: 'ON'
# test_light/bright: 50
self.assertEqual(('test_light/set', 'ON', 0, False),
self.mock_publish.mock_calls[-4][1])
self.assertEqual(('test_light/bright', 50, 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_has_calls([
mock.call('test_light/set', 'ON', 0, False),
mock.call('test_light/bright', 50, 0, False),
], any_order=True)
self.mock_publish.async_publish.reset_mock()
light.turn_off(self.hass, 'light.test')
self.hass.block_till_done()
self.assertEqual(('test_light/set', 'OFF', 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light/set', 'OFF', 0, False)
def test_on_command_last(self):
"""Test on command being sent after brightness."""
@ -733,16 +736,17 @@ class TestLightMQTT(unittest.TestCase):
# Should get the following MQTT messages.
# test_light/bright: 50
# test_light/set: 'ON'
self.assertEqual(('test_light/bright', 50, 0, False),
self.mock_publish.mock_calls[-4][1])
self.assertEqual(('test_light/set', 'ON', 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_has_calls([
mock.call('test_light/bright', 50, 0, False),
mock.call('test_light/set', 'ON', 0, False),
], any_order=True)
self.mock_publish.async_publish.reset_mock()
light.turn_off(self.hass, 'light.test')
self.hass.block_till_done()
self.assertEqual(('test_light/set', 'OFF', 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light/set', 'OFF', 0, False)
def test_on_command_brightness(self):
"""Test on command being sent as only brightness."""
@ -767,21 +771,24 @@ class TestLightMQTT(unittest.TestCase):
# Should get the following MQTT messages.
# test_light/bright: 255
self.assertEqual(('test_light/bright', 255, 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light/bright', 255, 0, False)
self.mock_publish.async_publish.reset_mock()
light.turn_off(self.hass, 'light.test')
self.hass.block_till_done()
self.assertEqual(('test_light/set', 'OFF', 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light/set', 'OFF', 0, False)
self.mock_publish.async_publish.reset_mock()
# Turn on w/ brightness
light.turn_on(self.hass, 'light.test', brightness=50)
self.hass.block_till_done()
self.assertEqual(('test_light/bright', 50, 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_called_once_with(
'test_light/bright', 50, 0, False)
self.mock_publish.async_publish.reset_mock()
light.turn_off(self.hass, 'light.test')
self.hass.block_till_done()
@ -791,10 +798,10 @@ class TestLightMQTT(unittest.TestCase):
light.turn_on(self.hass, 'light.test', rgb_color=[75, 75, 75])
self.hass.block_till_done()
self.assertEqual(('test_light/rgb', '75,75,75', 0, False),
self.mock_publish.mock_calls[-4][1])
self.assertEqual(('test_light/bright', 50, 0, False),
self.mock_publish.mock_calls[-2][1])
self.mock_publish.async_publish.assert_has_calls([
mock.call('test_light/rgb', '75,75,75', 0, False),
mock.call('test_light/bright', 50, 0, False)
], any_order=True)
def test_default_availability_payload(self):
"""Test availability by default payload with defined topic."""