core/tests/components/test_mqtt_eventstream.py

206 lines
7.1 KiB
Python
Raw Normal View History

2016-03-09 09:25:50 +00:00
"""The tests for the MQTT eventstream component."""
2016-01-10 04:18:46 +00:00
import json
from unittest.mock import ANY, patch
from homeassistant.setup import setup_component
2016-01-10 04:18:46 +00:00
import homeassistant.components.mqtt_eventstream as eventstream
from homeassistant.const import EVENT_STATE_CHANGED
2016-11-04 04:58:18 +00:00
from homeassistant.core import State, callback
from homeassistant.helpers.json import JSONEncoder
2016-01-10 04:18:46 +00:00
import homeassistant.util.dt as dt_util
from tests.common import (
get_test_home_assistant,
mock_mqtt_component,
fire_mqtt_message,
mock_state_change_event,
fire_time_changed
)
class TestMqttEventStream:
2016-03-09 09:25:50 +00:00
"""Test the MQTT eventstream module."""
2016-01-10 04:18:46 +00:00
def setup_method(self):
2018-08-19 20:29:08 +00:00
"""Set up things to be run when tests are started."""
2016-01-10 04:18:46 +00:00
self.hass = get_test_home_assistant()
self.mock_mqtt = mock_mqtt_component(self.hass)
def teardown_method(self):
2016-03-09 09:25:50 +00:00
"""Stop everything that was started."""
2016-01-10 04:18:46 +00:00
self.hass.stop()
def add_eventstream(self, sub_topic=None, pub_topic=None,
ignore_event=None):
2016-03-09 09:25:50 +00:00
"""Add a mqtt_eventstream component."""
2016-01-10 04:18:46 +00:00
config = {}
if sub_topic:
config['subscribe_topic'] = sub_topic
if pub_topic:
config['publish_topic'] = pub_topic
if ignore_event:
config['ignore_event'] = ignore_event
return setup_component(self.hass, eventstream.DOMAIN, {
eventstream.DOMAIN: config})
2016-01-10 04:18:46 +00:00
def test_setup_succeeds(self):
"""Test the success of the setup."""
assert self.add_eventstream()
2016-01-10 04:18:46 +00:00
def test_setup_with_pub(self):
"""Test the setup with subscription."""
2016-01-10 04:18:46 +00:00
# Should start off with no listeners for all events
assert self.hass.bus.listeners.get('*') is None
2016-01-10 04:18:46 +00:00
assert self.add_eventstream(pub_topic='bar')
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
# Verify that the event handler has been added as a listener
assert self.hass.bus.listeners.get('*') == 1
2016-01-10 04:18:46 +00:00
@patch('homeassistant.components.mqtt.async_subscribe')
2016-01-10 04:18:46 +00:00
def test_subscribe(self, mock_sub):
"""Test the subscription."""
2016-01-10 04:18:46 +00:00
sub_topic = 'foo'
assert self.add_eventstream(sub_topic=sub_topic)
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
# Verify that the this entity was subscribed to the topic
mock_sub.assert_called_with(self.hass, sub_topic, ANY)
@patch('homeassistant.components.mqtt.async_publish')
2016-04-16 07:55:35 +00:00
@patch('homeassistant.core.dt_util.utcnow')
def test_state_changed_event_sends_message(self, mock_utcnow, mock_pub):
"""Test the sending of a new message if event changed."""
2016-04-16 07:55:35 +00:00
now = dt_util.as_utc(dt_util.now())
2016-01-10 04:18:46 +00:00
e_id = 'fake.entity'
pub_topic = 'bar'
2016-04-16 07:55:35 +00:00
mock_utcnow.return_value = now
2016-01-10 04:18:46 +00:00
# Add the eventstream component for publishing events
assert self.add_eventstream(pub_topic=pub_topic)
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
# Reset the mock because it will have already gotten calls for the
# mqtt_eventstream state change on initialization, etc.
mock_pub.reset_mock()
# Set a state of an entity
mock_state_change_event(self.hass, State(e_id, 'on'))
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
# The order of the JSON is indeterminate,
# so first just check that publish was called
mock_pub.assert_called_with(self.hass, pub_topic, ANY)
assert mock_pub.called
2016-01-10 04:18:46 +00:00
# Get the actual call to publish and make sure it was the one
# we were looking for
msg = mock_pub.call_args[0][2]
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
2016-04-16 07:55:35 +00:00
"last_updated": now.isoformat(),
2016-01-10 04:18:46 +00:00
"state": "on",
"entity_id": e_id,
"attributes": {},
"last_changed": now.isoformat(),
2016-01-10 04:18:46 +00:00
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}
# Verify that the message received was that expected
result = json.loads(msg)
result['event_data']['new_state'].pop('context')
assert result == event
2016-01-10 04:18:46 +00:00
@patch('homeassistant.components.mqtt.async_publish')
2016-01-10 04:18:46 +00:00
def test_time_event_does_not_send_message(self, mock_pub):
"""Test the sending of a new message if time event."""
assert self.add_eventstream(pub_topic='bar')
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
# Reset the mock because it will have already gotten calls for the
# mqtt_eventstream state change on initialization, etc.
mock_pub.reset_mock()
fire_time_changed(self.hass, dt_util.utcnow())
assert not mock_pub.called
2016-01-10 04:18:46 +00:00
def test_receiving_remote_event_fires_hass_event(self):
"""Test the receiving of the remotely fired event."""
2016-01-10 04:18:46 +00:00
sub_topic = 'foo'
assert self.add_eventstream(sub_topic=sub_topic)
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
calls = []
2016-11-04 04:58:18 +00:00
@callback
def listener(_):
calls.append(1)
self.hass.bus.listen_once('test_event', listener)
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
payload = json.dumps(
{'event_type': 'test_event', 'event_data': {}},
cls=JSONEncoder
)
fire_mqtt_message(self.hass, sub_topic, payload)
self.hass.block_till_done()
2016-01-10 04:18:46 +00:00
assert 1 == len(calls)
@patch('homeassistant.components.mqtt.async_publish')
def test_ignored_event_doesnt_send_over_stream(self, mock_pub):
"""Test the ignoring of sending events if defined."""
assert self.add_eventstream(pub_topic='bar',
ignore_event=['state_changed'])
self.hass.block_till_done()
e_id = 'entity.test_id'
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
"state": "on",
"entity_id": e_id,
"attributes": {},
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}
# Reset the mock because it will have already gotten calls for the
# mqtt_eventstream state change on initialization, etc.
mock_pub.reset_mock()
# Set a state of an entity
mock_state_change_event(self.hass, State(e_id, 'on'))
self.hass.block_till_done()
assert not mock_pub.called
@patch('homeassistant.components.mqtt.async_publish')
def test_wrong_ignored_event_sends_over_stream(self, mock_pub):
"""Test the ignoring of sending events if defined."""
assert self.add_eventstream(pub_topic='bar',
ignore_event=['statee_changed'])
self.hass.block_till_done()
e_id = 'entity.test_id'
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
"state": "on",
"entity_id": e_id,
"attributes": {},
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}
# Reset the mock because it will have already gotten calls for the
# mqtt_eventstream state change on initialization, etc.
mock_pub.reset_mock()
# Set a state of an entity
mock_state_change_event(self.hass, State(e_id, 'on'))
self.hass.block_till_done()
assert mock_pub.called