mirror of https://github.com/home-assistant/core
658 lines
23 KiB
Python
658 lines
23 KiB
Python
"""The tests for the MQTT statestream component."""
|
|
|
|
from unittest.mock import ANY, call
|
|
|
|
import pytest
|
|
|
|
import homeassistant.components.mqtt_statestream as statestream
|
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
|
from homeassistant.core import CoreState, HomeAssistant, State
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from tests.common import MockEntity, MockEntityPlatform, mock_state_change_event
|
|
from tests.typing import MqttMockHAClient
|
|
|
|
|
|
async def add_statestream(
|
|
hass: HomeAssistant,
|
|
base_topic=None,
|
|
publish_attributes=None,
|
|
publish_timestamps=None,
|
|
publish_include=None,
|
|
publish_exclude=None,
|
|
) -> bool:
|
|
"""Add a mqtt_statestream component."""
|
|
config = {}
|
|
if base_topic:
|
|
config["base_topic"] = base_topic
|
|
if publish_attributes:
|
|
config["publish_attributes"] = publish_attributes
|
|
if publish_timestamps:
|
|
config["publish_timestamps"] = publish_timestamps
|
|
if publish_include:
|
|
config["include"] = publish_include
|
|
if publish_exclude:
|
|
config["exclude"] = publish_exclude
|
|
return await async_setup_component(
|
|
hass, statestream.DOMAIN, {statestream.DOMAIN: config}
|
|
)
|
|
|
|
|
|
async def test_fails_with_no_base(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Setup should fail if no base_topic is set."""
|
|
assert await add_statestream(hass) is False
|
|
|
|
|
|
async def test_setup_succeeds_without_attributes(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test the success of the setup with a valid base_topic."""
|
|
assert await add_statestream(hass, base_topic="pub")
|
|
|
|
|
|
async def test_setup_and_stop_waits_for_ha(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test the success of the setup with a valid base_topic."""
|
|
e_id = "fake.entity"
|
|
|
|
# HA is not running
|
|
hass.set_state(CoreState.not_running)
|
|
|
|
assert await add_statestream(hass, base_topic="pub")
|
|
await hass.async_block_till_done()
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was not published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_not_called()
|
|
|
|
# HA is starting up
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
# Change a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "off"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "off", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
mqtt_mock.reset_mock()
|
|
|
|
# HA is shutting down
|
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
|
await hass.async_block_till_done()
|
|
|
|
# Change a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was not published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_not_called()
|
|
|
|
|
|
# We use xfail with this test because there is an unhandled exception
|
|
# in a background task in this test.
|
|
# The exception is raised by mqtt.async_publish.
|
|
@pytest.mark.xfail
|
|
async def test_startup_no_mqtt(
|
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
|
) -> None:
|
|
"""Test startup without MQTT support."""
|
|
e_id = "fake.entity"
|
|
|
|
assert await add_statestream(hass, base_topic="pub")
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
assert "MQTT is not enabled" in caplog.text
|
|
|
|
|
|
async def test_setup_succeeds_with_attributes(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test setup with a valid base_topic and publish_attributes."""
|
|
assert await add_statestream(hass, base_topic="pub", publish_attributes=True)
|
|
|
|
|
|
async def test_state_changed_event_sends_message(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test the sending of a new message if event changed."""
|
|
e_id = "fake.entity"
|
|
base_topic = "pub"
|
|
|
|
# Add the statestream component for publishing state updates
|
|
assert await add_statestream(hass, base_topic=base_topic)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Create a test entity and add it to hass
|
|
platform = MockEntityPlatform(hass)
|
|
entity = MockEntity(unique_id="1234")
|
|
await platform.async_add_entities([entity])
|
|
await hass.async_block_till_done()
|
|
|
|
mqtt_mock.async_publish.assert_called_with(
|
|
"pub/test_domain/test_platform_1234/state", "unknown", 1, True
|
|
)
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
state = hass.states.get("test_domain.test_platform_1234")
|
|
assert state is not None
|
|
|
|
# Now remove it, nothing should be published
|
|
hass.states.async_remove("test_domain.test_platform_1234")
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
mqtt_mock.async_publish.assert_not_called()
|
|
|
|
|
|
async def test_state_changed_event_sends_message_and_timestamp(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test the sending of a message and timestamps if event changed."""
|
|
e_id = "another.entity"
|
|
base_topic = "pub"
|
|
|
|
# Add the statestream component for publishing state updates
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_attributes=None, publish_timestamps=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
calls = [
|
|
call.async_publish("pub/another/entity/state", "on", 1, True),
|
|
call.async_publish("pub/another/entity/last_changed", ANY, 1, True),
|
|
call.async_publish("pub/another/entity/last_updated", ANY, 1, True),
|
|
]
|
|
|
|
mqtt_mock.async_publish.assert_has_calls(calls, any_order=True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_attr_sends_message(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test the sending of a new message if attribute changed."""
|
|
e_id = "fake.entity"
|
|
base_topic = "pub"
|
|
|
|
# Add the statestream component for publishing state updates
|
|
assert await add_statestream(hass, base_topic=base_topic, publish_attributes=True)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
test_attributes = {"testing": "YES", "list": ["a", "b", "c"], "bool": False}
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State(e_id, "off", attributes=test_attributes))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
calls = [
|
|
call.async_publish("pub/fake/entity/state", "off", 1, True),
|
|
call.async_publish("pub/fake/entity/testing", '"YES"', 1, True),
|
|
call.async_publish("pub/fake/entity/list", '["a", "b", "c"]', 1, True),
|
|
call.async_publish("pub/fake/entity/bool", "false", 1, True),
|
|
]
|
|
|
|
mqtt_mock.async_publish.assert_has_calls(calls, any_order=True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_include_domain(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on included domain works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"domains": ["fake"]}
|
|
excl = {}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake2.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_include_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on included entity works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"entities": ["fake.entity"]}
|
|
excl = {}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_exclude_domain(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on excluded domain works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {}
|
|
excl = {"domains": ["fake2"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake2.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_exclude_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on excluded entity works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {}
|
|
excl = {"entities": ["fake.entity2"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_exclude_domain_include_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test filtering with excluded domain and included entity."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"entities": ["fake.entity"]}
|
|
excl = {"domains": ["fake"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_include_domain_exclude_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test filtering with included domain and excluded entity."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"domains": ["fake"]}
|
|
excl = {"entities": ["fake.entity2"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow fake.* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_include_globs(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on included glob works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"entity_globs": ["*.included_*"]}
|
|
excl = {}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow *.included_* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity with included glob
|
|
mock_state_change_event(hass, State("fake2.included_entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake2/included_entity/state
|
|
mqtt_mock.async_publish.assert_called_with(
|
|
"pub/fake2/included_entity/state", "on", 1, True
|
|
)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake2.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_exclude_globs(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test that filtering on excluded globs works as expected."""
|
|
base_topic = "pub"
|
|
|
|
incl = {}
|
|
excl = {"entity_globs": ["*.excluded_*"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to allow *.excluded_* items
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included by glob
|
|
mock_state_change_event(hass, State("fake.excluded_entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_exclude_domain_globs_include_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test filtering with excluded domain and glob and included entity."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"entities": ["fake.entity"]}
|
|
excl = {"domains": ["fake"], "entity_globs": ["*.excluded_*"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to exclude with include filter
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that doesn't match any filters
|
|
mock_state_change_event(hass, State("fake2.included_entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with(
|
|
"pub/fake2/included_entity/state", "on", 1, True
|
|
)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included by domain
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included by glob
|
|
mock_state_change_event(hass, State("fake.excluded_entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
|
|
async def test_state_changed_event_include_domain_globs_exclude_entity(
|
|
hass: HomeAssistant, mqtt_mock: MqttMockHAClient
|
|
) -> None:
|
|
"""Test filtering with included domain and glob and excluded entity."""
|
|
base_topic = "pub"
|
|
|
|
incl = {"domains": ["fake"], "entity_globs": ["*.included_*"]}
|
|
excl = {"entities": ["fake.entity2"]}
|
|
|
|
# Add the statestream component for publishing state updates
|
|
# Set the filter to include with exclude filter
|
|
assert await add_statestream(
|
|
hass, base_topic=base_topic, publish_include=incl, publish_exclude=excl
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Reset the mock because it will have already gotten calls for the
|
|
# mqtt_statestream state change on initialization, etc.
|
|
mqtt_mock.async_publish.reset_mock()
|
|
|
|
# Set a state of an entity included by domain
|
|
mock_state_change_event(hass, State("fake.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with("pub/fake/entity/state", "on", 1, True)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity included by glob
|
|
mock_state_change_event(hass, State("fake.included_entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
# Make sure 'on' was published to pub/fake/entity/state
|
|
mqtt_mock.async_publish.assert_called_with(
|
|
"pub/fake/included_entity/state", "on", 1, True
|
|
)
|
|
assert mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that shouldn't be included
|
|
mock_state_change_event(hass, State("fake.entity2", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|
|
|
|
mqtt_mock.async_publish.reset_mock()
|
|
# Set a state of an entity that doesn't match any filters
|
|
mock_state_change_event(hass, State("fake2.entity", "on"))
|
|
await hass.async_block_till_done()
|
|
await hass.async_block_till_done()
|
|
|
|
assert not mqtt_mock.async_publish.called
|