diff --git a/homeassistant/core.py b/homeassistant/core.py index 60485a678b0..dbc8769bb6f 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -973,6 +973,8 @@ _FilterableJobType = tuple[ class EventBus: """Allow the firing of and listening for events.""" + __slots__ = ("_listeners", "_match_all_listeners", "_hass") + def __init__(self, hass: HomeAssistant) -> None: """Initialize a new event bus.""" self._listeners: dict[str, list[_FilterableJobType]] = {} diff --git a/tests/components/datadog/test_init.py b/tests/components/datadog/test_init.py index c42d532b800..76956874e73 100644 --- a/tests/components/datadog/test_init.py +++ b/tests/components/datadog/test_init.py @@ -1,15 +1,13 @@ """The tests for the Datadog component.""" from unittest import mock -from unittest.mock import MagicMock, patch +from unittest.mock import patch import homeassistant.components.datadog as datadog from homeassistant.const import ( EVENT_LOGBOOK_ENTRY, - EVENT_STATE_CHANGED, STATE_OFF, STATE_ON, ) -import homeassistant.core as ha from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -27,7 +25,6 @@ async def test_invalid_config(hass: HomeAssistant) -> None: async def test_datadog_setup_full(hass: HomeAssistant) -> None: """Test setup with all data.""" config = {datadog.DOMAIN: {"host": "host", "port": 123, "rate": 1, "prefix": "foo"}} - hass.bus.listen = MagicMock() with patch("homeassistant.components.datadog.initialize") as mock_init, patch( "homeassistant.components.datadog.statsd" @@ -37,15 +34,9 @@ async def test_datadog_setup_full(hass: HomeAssistant) -> None: assert mock_init.call_count == 1 assert mock_init.call_args == mock.call(statsd_host="host", statsd_port=123) - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_LOGBOOK_ENTRY - assert hass.bus.listen.call_args_list[1][0][0] == EVENT_STATE_CHANGED - async def test_datadog_setup_defaults(hass: HomeAssistant) -> None: """Test setup with defaults.""" - hass.bus.listen = mock.MagicMock() - with patch("homeassistant.components.datadog.initialize") as mock_init, patch( "homeassistant.components.datadog.statsd" ): @@ -63,13 +54,10 @@ async def test_datadog_setup_defaults(hass: HomeAssistant) -> None: assert mock_init.call_count == 1 assert mock_init.call_args == mock.call(statsd_host="host", statsd_port=8125) - assert hass.bus.listen.called async def test_logbook_entry(hass: HomeAssistant) -> None: """Test event listener.""" - hass.bus.listen = mock.MagicMock() - with patch("homeassistant.components.datadog.initialize"), patch( "homeassistant.components.datadog.statsd" ) as mock_statsd: @@ -79,16 +67,14 @@ async def test_logbook_entry(hass: HomeAssistant) -> None: {datadog.DOMAIN: {"host": "host", "rate": datadog.DEFAULT_RATE}}, ) - assert hass.bus.listen.called - handler_method = hass.bus.listen.call_args_list[0][0][1] - event = { "domain": "automation", "entity_id": "sensor.foo.bar", "message": "foo bar biz", "name": "triggered something", } - handler_method(mock.MagicMock(data=event)) + hass.bus.async_fire(EVENT_LOGBOOK_ENTRY, event) + await hass.async_block_till_done() assert mock_statsd.event.call_count == 1 assert mock_statsd.event.call_args == mock.call( @@ -102,8 +88,6 @@ async def test_logbook_entry(hass: HomeAssistant) -> None: async def test_state_changed(hass: HomeAssistant) -> None: """Test event listener.""" - hass.bus.listen = mock.MagicMock() - with patch("homeassistant.components.datadog.initialize"), patch( "homeassistant.components.datadog.statsd" ) as mock_statsd: @@ -119,9 +103,6 @@ async def test_state_changed(hass: HomeAssistant) -> None: }, ) - assert hass.bus.listen.called - handler_method = hass.bus.listen.call_args_list[1][0][1] - valid = {"1": 1, "1.0": 1.0, STATE_ON: 1, STATE_OFF: 0} attributes = {"elevation": 3.2, "temperature": 5.0, "up": True, "down": False} @@ -129,12 +110,12 @@ async def test_state_changed(hass: HomeAssistant) -> None: for in_, out in valid.items(): state = mock.MagicMock( domain="sensor", - entity_id="sensor.foo.bar", + entity_id="sensor.foobar", state=in_, attributes=attributes, ) - handler_method(mock.MagicMock(data={"new_state": state})) - + hass.states.async_set(state.entity_id, state.state, state.attributes) + await hass.async_block_till_done() assert mock_statsd.gauge.call_count == 5 for attribute, value in attributes.items(): @@ -160,7 +141,6 @@ async def test_state_changed(hass: HomeAssistant) -> None: mock_statsd.gauge.reset_mock() for invalid in ("foo", "", object): - handler_method( - mock.MagicMock(data={"new_state": ha.State("domain.test", invalid, {})}) - ) + hass.states.async_set("domain.test", invalid, {}) + await hass.async_block_till_done() assert not mock_statsd.gauge.called diff --git a/tests/components/ffmpeg/test_init.py b/tests/components/ffmpeg/test_init.py index 521ac732e5b..0c6ce300d01 100644 --- a/tests/components/ffmpeg/test_init.py +++ b/tests/components/ffmpeg/test_init.py @@ -8,7 +8,11 @@ from homeassistant.components.ffmpeg import ( SERVICE_START, SERVICE_STOP, ) -from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.const import ( + ATTR_ENTITY_ID, + EVENT_HOMEASSISTANT_START, + EVENT_HOMEASSISTANT_STOP, +) from homeassistant.core import HomeAssistant, callback from homeassistant.setup import async_setup_component, setup_component @@ -54,7 +58,7 @@ class MockFFmpegDev(ffmpeg.FFmpegBase): self.hass = hass self.entity_id = entity_id - self.ffmpeg = MagicMock + self.ffmpeg = MagicMock() self.called_stop = False self.called_start = False self.called_restart = False @@ -104,12 +108,18 @@ async def test_setup_component_test_register(hass: HomeAssistant) -> None: with assert_setup_component(1): await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - hass.bus.async_listen_once = MagicMock() ffmpeg_dev = MockFFmpegDev(hass) + ffmpeg_dev._async_stop_ffmpeg = AsyncMock() + ffmpeg_dev._async_start_ffmpeg = AsyncMock() await ffmpeg_dev.async_added_to_hass() - assert hass.bus.async_listen_once.called - assert hass.bus.async_listen_once.call_count == 2 + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() + assert len(ffmpeg_dev._async_start_ffmpeg.mock_calls) == 2 + + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) + await hass.async_block_till_done() + assert len(ffmpeg_dev._async_stop_ffmpeg.mock_calls) == 2 async def test_setup_component_test_register_no_startup(hass: HomeAssistant) -> None: @@ -117,12 +127,18 @@ async def test_setup_component_test_register_no_startup(hass: HomeAssistant) -> with assert_setup_component(1): await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - hass.bus.async_listen_once = MagicMock() ffmpeg_dev = MockFFmpegDev(hass, False) + ffmpeg_dev._async_stop_ffmpeg = AsyncMock() + ffmpeg_dev._async_start_ffmpeg = AsyncMock() await ffmpeg_dev.async_added_to_hass() - assert hass.bus.async_listen_once.called - assert hass.bus.async_listen_once.call_count == 1 + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() + assert len(ffmpeg_dev._async_start_ffmpeg.mock_calls) == 1 + + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) + await hass.async_block_till_done() + assert len(ffmpeg_dev._async_stop_ffmpeg.mock_calls) == 2 async def test_setup_component_test_service_start(hass: HomeAssistant) -> None: diff --git a/tests/components/google_pubsub/test_init.py b/tests/components/google_pubsub/test_init.py index 38c3da79524..0a1d4741268 100644 --- a/tests/components/google_pubsub/test_init.py +++ b/tests/components/google_pubsub/test_init.py @@ -8,8 +8,7 @@ import pytest import homeassistant.components.google_pubsub as google_pubsub from homeassistant.components.google_pubsub import DateTimeJSONEncoder as victim -from homeassistant.const import EVENT_STATE_CHANGED -from homeassistant.core import HomeAssistant, split_entity_id +from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component GOOGLE_PUBSUB_PATH = "homeassistant.components.google_pubsub" @@ -60,9 +59,8 @@ def mock_is_file_fixture(): @pytest.fixture(autouse=True) -def mock_bus_and_json(hass, monkeypatch): +def mock_json(hass, monkeypatch): """Mock the event bus listener and os component.""" - hass.bus.listen = mock.MagicMock() monkeypatch.setattr( f"{GOOGLE_PUBSUB_PATH}.json.dumps", mock.Mock(return_value=mock.MagicMock()) ) @@ -80,8 +78,6 @@ async def test_minimal_config(hass: HomeAssistant, mock_client) -> None: } assert await async_setup_component(hass, google_pubsub.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED assert mock_client.from_service_account_json.call_count == 1 assert mock_client.from_service_account_json.call_args[0][0] == os.path.join( hass.config.config_dir, "creds" @@ -107,27 +103,12 @@ async def test_full_config(hass: HomeAssistant, mock_client) -> None: } assert await async_setup_component(hass, google_pubsub.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED assert mock_client.from_service_account_json.call_count == 1 assert mock_client.from_service_account_json.call_args[0][0] == os.path.join( hass.config.config_dir, "creds" ) -def make_event(entity_id): - """Make a mock event for test.""" - domain = split_entity_id(entity_id)[0] - state = mock.MagicMock( - state="not blank", - domain=domain, - entity_id=entity_id, - object_id="entity", - attributes={}, - ) - return mock.MagicMock(data={"new_state": state}, time_fired=12345) - - async def _setup(hass, filter_config): """Shared set up for filtering tests.""" config = { @@ -140,12 +121,11 @@ async def _setup(hass, filter_config): } assert await async_setup_component(hass, google_pubsub.DOMAIN, config) await hass.async_block_till_done() - return hass.bus.listen.call_args_list[0][0][1] async def test_allowlist(hass: HomeAssistant, mock_client) -> None: """Test an allowlist only config.""" - handler_method = await _setup( + await _setup( hass, { "include_domains": ["light"], @@ -165,8 +145,8 @@ async def test_allowlist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = publish_client.publish.call_count == 1 assert test.should_pass == was_called @@ -175,7 +155,7 @@ async def test_allowlist(hass: HomeAssistant, mock_client) -> None: async def test_denylist(hass: HomeAssistant, mock_client) -> None: """Test a denylist only config.""" - handler_method = await _setup( + await _setup( hass, { "exclude_domains": ["climate"], @@ -195,8 +175,8 @@ async def test_denylist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = publish_client.publish.call_count == 1 assert test.should_pass == was_called @@ -205,7 +185,7 @@ async def test_denylist(hass: HomeAssistant, mock_client) -> None: async def test_filtered_allowlist(hass: HomeAssistant, mock_client) -> None: """Test an allowlist config with a filtering denylist.""" - handler_method = await _setup( + await _setup( hass, { "include_domains": ["light"], @@ -226,8 +206,8 @@ async def test_filtered_allowlist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = publish_client.publish.call_count == 1 assert test.should_pass == was_called @@ -236,7 +216,7 @@ async def test_filtered_allowlist(hass: HomeAssistant, mock_client) -> None: async def test_filtered_denylist(hass: HomeAssistant, mock_client) -> None: """Test a denylist config with a filtering allowlist.""" - handler_method = await _setup( + await _setup( hass, { "include_entities": ["climate.included", "sensor.excluded_test"], @@ -257,8 +237,8 @@ async def test_filtered_denylist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = publish_client.publish.call_count == 1 assert test.should_pass == was_called diff --git a/tests/components/influxdb/test_init.py b/tests/components/influxdb/test_init.py index 683c69807b2..a1234b7a470 100644 --- a/tests/components/influxdb/test_init.py +++ b/tests/components/influxdb/test_init.py @@ -2,14 +2,13 @@ from dataclasses import dataclass import datetime from http import HTTPStatus -from unittest.mock import MagicMock, Mock, call, patch +from unittest.mock import ANY, MagicMock, Mock, call, patch import pytest import homeassistant.components.influxdb as influxdb from homeassistant.components.influxdb.const import DEFAULT_BUCKET from homeassistant.const import ( - EVENT_STATE_CHANGED, PERCENTAGE, STATE_OFF, STATE_ON, @@ -39,7 +38,6 @@ class FilterTest: @pytest.fixture(autouse=True) def mock_batch_timeout(hass, monkeypatch): """Mock the event bus listener and the batch timeout for tests.""" - hass.bus.listen = MagicMock() monkeypatch.setattr( f"{INFLUX_PATH}.InfluxThread.batch_timeout", Mock(return_value=0), @@ -129,8 +127,6 @@ async def test_setup_config_full( assert await async_setup_component(hass, influxdb.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED assert get_write_api(mock_client).call_count == 1 @@ -263,8 +259,6 @@ async def test_setup_config_ssl( assert await async_setup_component(hass, influxdb.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED assert expected_client_args.items() <= mock_client.call_args.kwargs.items() @@ -285,8 +279,6 @@ async def test_setup_minimal_config( assert await async_setup_component(hass, influxdb.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED assert get_write_api(mock_client).call_count == 1 @@ -347,7 +339,6 @@ async def _setup(hass, mock_influx_client, config_ext, get_write_api): # A call is made to the write API during setup to test the connection. # Therefore we reset the write API mock here before the test begins. get_write_api(mock_influx_client).reset_mock() - return hass.bus.listen.call_args_list[0][0][1] @pytest.mark.parametrize( @@ -372,7 +363,7 @@ async def test_event_listener( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) # map of HA State to valid influxdb [state, value] fields valid = { @@ -394,19 +385,11 @@ async def test_event_listener( "updated_at": datetime.datetime(2017, 1, 1, 0, 0), "multi_periods": "0.120.240.2023873", } - state = MagicMock( - state=in_, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": "foobars", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": { "longitude": 1.1, "latitude": 2.2, @@ -427,7 +410,8 @@ async def test_event_listener( if out[1] is not None: body[0]["fields"]["value"] = out[1] - handler_method(event) + hass.states.async_set("fake.entity_id", in_, attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -458,30 +442,23 @@ async def test_event_listener_no_units( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener for missing units.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) - for unit in (None, ""): + for unit in ("",): if unit: attrs = {"unit_of_measurement": unit} else: attrs = {} - state = MagicMock( - state=1, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { - "measurement": "fake.entity-id", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "measurement": "fake.entity_id", + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set("fake.entity_id", 1, attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -512,26 +489,19 @@ async def test_event_listener_inf( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener with large or invalid numbers.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) attrs = {"bignumstring": "9" * 999, "nonumstring": "nan"} - state = MagicMock( - state=8, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { - "measurement": "fake.entity-id", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "measurement": "fake.entity_id", + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": {"value": 8}, } ] - handler_method(event) + hass.states.async_set("fake.entity_id", 8, attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -561,26 +531,19 @@ async def test_event_listener_states( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener against ignored states.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) - for state_state in (1, "unknown", "", "unavailable", None): - state = MagicMock( - state=state_state, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + for state_state in (1, "unknown", "", "unavailable"): body = [ { - "measurement": "fake.entity-id", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "measurement": "fake.entity_id", + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set("fake.entity_id", state_state) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -592,27 +555,20 @@ async def test_event_listener_states( write_api.reset_mock() -def execute_filter_test(hass, tests, handler_method, write_api, get_mock_call): +async def execute_filter_test(hass: HomeAssistant, tests, write_api, get_mock_call): """Execute all tests for a given filtering test.""" for test in tests: domain, entity_id = split_entity_id(test.id) - state = MagicMock( - state=1, - domain=domain, - entity_id=test.id, - object_id=entity_id, - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": test.id, "tags": {"domain": domain, "entity_id": entity_id}, - "time": 12345, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set(test.id, 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() if test.should_pass: @@ -647,14 +603,14 @@ async def test_event_listener_denylist( """Test the event listener against a denylist.""" config = {"exclude": {"entities": ["fake.denylisted"]}, "include": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.ok", True), FilterTest("fake.denylisted", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -681,14 +637,14 @@ async def test_event_listener_denylist_domain( """Test the event listener against a domain denylist.""" config = {"exclude": {"domains": ["another_fake"]}, "include": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.ok", True), FilterTest("another_fake.denylisted", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -715,14 +671,14 @@ async def test_event_listener_denylist_glob( """Test the event listener against a glob denylist.""" config = {"exclude": {"entity_globs": ["*.excluded_*"]}, "include": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.ok", True), FilterTest("fake.excluded_entity", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -749,14 +705,14 @@ async def test_event_listener_allowlist( """Test the event listener against an allowlist.""" config = {"include": {"entities": ["fake.included"]}, "exclude": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.included", True), FilterTest("fake.excluded", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -783,14 +739,14 @@ async def test_event_listener_allowlist_domain( """Test the event listener against a domain allowlist.""" config = {"include": {"domains": ["fake"]}, "exclude": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.ok", True), FilterTest("another_fake.excluded", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -817,14 +773,14 @@ async def test_event_listener_allowlist_glob( """Test the event listener against a glob allowlist.""" config = {"include": {"entity_globs": ["*.included_*"]}, "exclude": {}} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ FilterTest("fake.included_entity", True), FilterTest("fake.denied", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -862,7 +818,7 @@ async def test_event_listener_filtered_allowlist( }, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ @@ -874,7 +830,7 @@ async def test_event_listener_filtered_allowlist( FilterTest("fake.excluded_entity", False), FilterTest("another_fake.included_entity", True), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -904,7 +860,7 @@ async def test_event_listener_filtered_denylist( "exclude": {"domains": ["another_fake"], "entity_globs": "*.excluded_*"}, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) tests = [ @@ -914,7 +870,7 @@ async def test_event_listener_filtered_denylist( FilterTest("another_fake.denied", False), FilterTest("fake.excluded_entity", False), ] - execute_filter_test(hass, tests, handler_method, write_api, get_mock_call) + await execute_filter_test(hass, tests, write_api, get_mock_call) @pytest.mark.parametrize( @@ -939,7 +895,7 @@ async def test_event_listener_invalid_type( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener when an attribute has an invalid type.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) # map of HA State to valid influxdb [state, value] fields valid = { @@ -957,19 +913,11 @@ async def test_event_listener_invalid_type( "latitude": "2.2", "invalid_attribute": ["value1", "value2"], } - state = MagicMock( - state=in_, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": "foobars", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": { "longitude": 1.1, "latitude": 2.2, @@ -982,7 +930,8 @@ async def test_event_listener_invalid_type( if out[1] is not None: body[0]["fields"]["value"] = out[1] - handler_method(event) + hass.states.async_set("fake.entity_id", in_, attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1015,25 +964,17 @@ async def test_event_listener_default_measurement( """Test the event listener with a default measurement.""" config = {"default_measurement": "state"} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) - - state = MagicMock( - state=1, - domain="fake", - entity_id="fake.ok", - object_id="ok", - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + await _setup(hass, mock_client, config, get_write_api) body = [ { "measurement": "state", "tags": {"domain": "fake", "entity_id": "ok"}, - "time": 12345, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set("fake.ok", 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1065,26 +1006,19 @@ async def test_event_listener_unit_of_measurement_field( """Test the event listener for unit of measurement field.""" config = {"override_measurement": "state"} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) attrs = {"unit_of_measurement": "foobars"} - state = MagicMock( - state="foo", - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": "state", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": {"state": "foo", "unit_of_measurement_str": "foobars"}, } ] - handler_method(event) + hass.states.async_set("fake.entity_id", "foo", attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1116,17 +1050,9 @@ async def test_event_listener_tags_attributes( """Test the event listener when some attributes should be tags.""" config = {"tags_attributes": ["friendly_fake"]} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) attrs = {"friendly_fake": "tag_str", "field_fake": "field_str"} - state = MagicMock( - state=1, - domain="fake", - entity_id="fake.something", - object_id="something", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": "fake.something", @@ -1135,11 +1061,12 @@ async def test_event_listener_tags_attributes( "entity_id": "something", "friendly_fake": "tag_str", }, - "time": 12345, + "time": ANY, "fields": {"value": 1, "field_fake_str": "field_str"}, } ] - handler_method(event) + hass.states.async_set("fake.something", 1, attrs) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1179,7 +1106,7 @@ async def test_event_listener_component_override_measurement( "component_config_domain": {"climate": {"override_measurement": "hvac"}}, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) test_components = [ {"domain": "sensor", "id": "fake_humidity", "res": "humidity"}, @@ -1188,23 +1115,16 @@ async def test_event_listener_component_override_measurement( {"domain": "other", "id": "just_fake", "res": "other.just_fake"}, ] for comp in test_components: - state = MagicMock( - state=1, - domain=comp["domain"], - entity_id=f"{comp['domain']}.{comp['id']}", - object_id=comp["id"], - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": comp["res"], "tags": {"domain": comp["domain"], "entity_id": comp["id"]}, - "time": 12345, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set(f"{comp['domain']}.{comp['id']}", 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1246,7 +1166,7 @@ async def test_event_listener_component_measurement_attr( "component_config_domain": {"climate": {"override_measurement": "hvac"}}, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) test_components = [ { @@ -1261,23 +1181,16 @@ async def test_event_listener_component_measurement_attr( {"domain": "other", "id": "just_fake", "attrs": {}, "res": "other"}, ] for comp in test_components: - state = MagicMock( - state=1, - domain=comp["domain"], - entity_id=f"{comp['domain']}.{comp['id']}", - object_id=comp["id"], - attributes=comp["attrs"], - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": comp["res"], "tags": {"domain": comp["domain"], "entity_id": comp["id"]}, - "time": 12345, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set(f"{comp['domain']}.{comp['id']}", 1, comp["attrs"]) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1321,7 +1234,7 @@ async def test_event_listener_ignore_attributes( }, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) test_components = [ { @@ -1342,30 +1255,27 @@ async def test_event_listener_ignore_attributes( ] for comp in test_components: entity_id = f"{comp['domain']}.{comp['id']}" - state = MagicMock( - state=1, - domain=comp["domain"], - entity_id=entity_id, - object_id=comp["id"], - attributes={ - "ignore": 1, - "id_ignore": 1, - "glob_ignore": 1, - "domain_ignore": 1, - }, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) fields = {"value": 1} fields.update(comp["attrs"]) body = [ { "measurement": entity_id, "tags": {"domain": comp["domain"], "entity_id": comp["id"]}, - "time": 12345, + "time": ANY, "fields": fields, } ] - handler_method(event) + hass.states.async_set( + entity_id, + 1, + { + "ignore": 1, + "id_ignore": 1, + "glob_ignore": 1, + "domain_ignore": 1, + }, + ) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1401,25 +1311,17 @@ async def test_event_listener_ignore_attributes_overlapping_entities( "component_config_domain": {"sensor": {"ignore_attributes": ["ignore"]}}, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) - - state = MagicMock( - state=1, - domain="sensor", - entity_id="sensor.fake", - object_id="fake", - attributes={"ignore": 1}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + await _setup(hass, mock_client, config, get_write_api) body = [ { "measurement": "units", "tags": {"domain": "sensor", "entity_id": "fake"}, - "time": 12345, + "time": ANY, "fields": {"value": 1}, } ] - handler_method(event) + hass.states.async_set("sensor.fake", 1, {"ignore": 1}) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1452,22 +1354,14 @@ async def test_event_listener_scheduled_write( """Test the event listener retries after a write failure.""" config = {"max_retries": 1} config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) - - state = MagicMock( - state=1, - domain="fake", - entity_id="entity.id", - object_id="entity", - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + await _setup(hass, mock_client, config, get_write_api) write_api = get_write_api(mock_client) write_api.side_effect = OSError("foo") # Write fails with patch.object(influxdb.time, "sleep") as mock_sleep: - handler_method(event) + hass.states.async_set("entity.entity_id", 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() assert mock_sleep.called assert write_api.call_count == 2 @@ -1475,7 +1369,8 @@ async def test_event_listener_scheduled_write( # Write works again write_api.side_effect = None with patch.object(influxdb.time, "sleep") as mock_sleep: - handler_method(event) + hass.states.async_set("entity.entity_id", "2") + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() assert not mock_sleep.called assert write_api.call_count == 3 @@ -1503,16 +1398,7 @@ async def test_event_listener_backlog_full( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener drops old events when backlog gets full.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) - - state = MagicMock( - state=1, - domain="fake", - entity_id="entity.id", - object_id="entity", - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + await _setup(hass, mock_client, config_ext, get_write_api) monotonic_time = 0 @@ -1523,7 +1409,8 @@ async def test_event_listener_backlog_full( return monotonic_time with patch("homeassistant.components.influxdb.time.monotonic", new=fast_monotonic): - handler_method(event) + hass.states.async_set("entity.id", 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() assert get_write_api(mock_client).call_count == 0 @@ -1551,26 +1438,17 @@ async def test_event_listener_attribute_name_conflict( hass: HomeAssistant, mock_client, config_ext, get_write_api, get_mock_call ) -> None: """Test the event listener when an attribute conflicts with another field.""" - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) - - attrs = {"value": "value_str"} - state = MagicMock( - state=1, - domain="fake", - entity_id="fake.something", - object_id="something", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) + await _setup(hass, mock_client, config_ext, get_write_api) body = [ { "measurement": "fake.something", "tags": {"domain": "fake", "entity_id": "something"}, - "time": 12345, + "time": ANY, "fields": {"value": 1, "value__str": "value_str"}, } ] - handler_method(event) + hass.states.async_set("fake.something", 1, {"value": "value_str"}) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) @@ -1642,7 +1520,6 @@ async def test_connection_failure_on_startup( == 1 ) event_helper.call_later.assert_called_once() - hass.bus.listen.assert_not_called() @pytest.mark.parametrize( @@ -1686,21 +1563,14 @@ async def test_invalid_inputs_error( But Influx is an external service so there may be edge cases that haven't been encountered yet. """ - handler_method = await _setup(hass, mock_client, config_ext, get_write_api) + await _setup(hass, mock_client, config_ext, get_write_api) write_api = get_write_api(mock_client) write_api.side_effect = test_exception - state = MagicMock( - state=1, - domain="fake", - entity_id="fake.something", - object_id="something", - attributes={}, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) with patch(f"{INFLUX_PATH}.time.sleep") as sleep: - handler_method(event) + hass.states.async_set("fake.something", 1) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api.assert_called_once() @@ -1786,29 +1656,25 @@ async def test_precision( "precision": precision, } config.update(config_ext) - handler_method = await _setup(hass, mock_client, config, get_write_api) + await _setup(hass, mock_client, config, get_write_api) value = "1.9" - attrs = { - "unit_of_measurement": "foobars", - } - state = MagicMock( - state=value, - domain="fake", - entity_id="fake.entity-id", - object_id="entity", - attributes=attrs, - ) - event = MagicMock(data={"new_state": state}, time_fired=12345) body = [ { "measurement": "foobars", - "tags": {"domain": "fake", "entity_id": "entity"}, - "time": 12345, + "tags": {"domain": "fake", "entity_id": "entity_id"}, + "time": ANY, "fields": {"value": float(value)}, } ] - handler_method(event) + hass.states.async_set( + "fake.entity_id", + value, + { + "unit_of_measurement": "foobars", + }, + ) + await hass.async_block_till_done() hass.data[influxdb.DOMAIN].block_till_done() write_api = get_write_api(mock_client) diff --git a/tests/components/logentries/test_init.py b/tests/components/logentries/test_init.py index 0101356e3ed..98b171c813f 100644 --- a/tests/components/logentries/test_init.py +++ b/tests/components/logentries/test_init.py @@ -1,10 +1,10 @@ """The tests for the Logentries component.""" -from unittest.mock import MagicMock, call, patch +from unittest.mock import ANY, call, patch import pytest import homeassistant.components.logentries as logentries -from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON +from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -12,19 +12,23 @@ from homeassistant.setup import async_setup_component async def test_setup_config_full(hass: HomeAssistant) -> None: """Test setup with all data.""" config = {"logentries": {"token": "secret"}} - hass.bus.listen = MagicMock() assert await async_setup_component(hass, logentries.DOMAIN, config) - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED + + with patch("homeassistant.components.logentries.requests.post") as mock_post: + hass.states.async_set("fake.entity", STATE_ON) + await hass.async_block_till_done() + assert len(mock_post.mock_calls) == 1 async def test_setup_config_defaults(hass: HomeAssistant) -> None: """Test setup with defaults.""" config = {"logentries": {"token": "token"}} - hass.bus.listen = MagicMock() assert await async_setup_component(hass, logentries.DOMAIN, config) - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED + + with patch("homeassistant.components.logentries.requests.post") as mock_post: + hass.states.async_set("fake.entity", STATE_ON) + await hass.async_block_till_done() + assert len(mock_post.mock_calls) == 1 @pytest.fixture @@ -47,28 +51,24 @@ async def test_event_listener(hass: HomeAssistant, mock_dump, mock_requests) -> mock_post = mock_requests.post mock_requests.exceptions.RequestException = Exception config = {"logentries": {"token": "token"}} - hass.bus.listen = MagicMock() assert await async_setup_component(hass, logentries.DOMAIN, config) - handler_method = hass.bus.listen.call_args_list[0][0][1] valid = {"1": 1, "1.0": 1.0, STATE_ON: 1, STATE_OFF: 0, "foo": "foo"} for in_, out in valid.items(): - state = MagicMock(state=in_, domain="fake", object_id="entity", attributes={}) - event = MagicMock(data={"new_state": state}, time_fired=12345) - body = [ - { - "domain": "fake", - "entity_id": "entity", - "attributes": {}, - "time": "12345", - "value": out, - } - ] payload = { "host": "https://webhook.logentries.com/noformat/logs/token", - "event": body, + "event": [ + { + "domain": "fake", + "entity_id": "entity", + "attributes": {}, + "time": ANY, + "value": out, + } + ], } - handler_method(event) + hass.states.async_set("fake.entity", in_) + await hass.async_block_till_done() assert mock_post.call_count == 1 assert mock_post.call_args == call(payload["host"], data=payload, timeout=10) mock_post.reset_mock() diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index d9231732941..8b0acb9c5b0 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -44,7 +44,6 @@ from homeassistant.const import ( CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, CONTENT_TYPE_TEXT_PLAIN, DEGREE, - EVENT_STATE_CHANGED, PERCENTAGE, STATE_CLOSED, STATE_CLOSING, @@ -59,7 +58,7 @@ from homeassistant.const import ( UnitOfEnergy, UnitOfTemperature, ) -from homeassistant.core import HomeAssistant, split_entity_id +from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util @@ -1568,23 +1567,13 @@ def mock_client_fixture(): yield counter_client -@pytest.fixture -def mock_bus(hass): - """Mock the event bus listener.""" - hass.bus.listen = mock.MagicMock() - - -@pytest.mark.usefixtures("mock_bus") async def test_minimal_config(hass: HomeAssistant, mock_client) -> None: """Test the minimal config and defaults of component.""" config = {prometheus.DOMAIN: {}} assert await async_setup_component(hass, prometheus.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED -@pytest.mark.usefixtures("mock_bus") async def test_full_config(hass: HomeAssistant, mock_client) -> None: """Test the full config of component.""" config = { @@ -1607,21 +1596,6 @@ async def test_full_config(hass: HomeAssistant, mock_client) -> None: } assert await async_setup_component(hass, prometheus.DOMAIN, config) await hass.async_block_till_done() - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED - - -def make_event(entity_id): - """Make a mock event for test.""" - domain = split_entity_id(entity_id)[0] - state = mock.MagicMock( - state="not blank", - domain=domain, - entity_id=entity_id, - object_id="entity", - attributes={}, - ) - return mock.MagicMock(data={"new_state": state}, time_fired=12345) async def _setup(hass, filter_config): @@ -1629,13 +1603,11 @@ async def _setup(hass, filter_config): config = {prometheus.DOMAIN: {"filter": filter_config}} assert await async_setup_component(hass, prometheus.DOMAIN, config) await hass.async_block_till_done() - return hass.bus.listen.call_args_list[0][0][1] -@pytest.mark.usefixtures("mock_bus") async def test_allowlist(hass: HomeAssistant, mock_client) -> None: """Test an allowlist only config.""" - handler_method = await _setup( + await _setup( hass, { "include_domains": ["fake"], @@ -1654,18 +1626,17 @@ async def test_allowlist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = mock_client.labels.call_count == 1 assert test.should_pass == was_called mock_client.labels.reset_mock() -@pytest.mark.usefixtures("mock_bus") async def test_denylist(hass: HomeAssistant, mock_client) -> None: """Test a denylist only config.""" - handler_method = await _setup( + await _setup( hass, { "exclude_domains": ["fake"], @@ -1684,18 +1655,17 @@ async def test_denylist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = mock_client.labels.call_count == 1 assert test.should_pass == was_called mock_client.labels.reset_mock() -@pytest.mark.usefixtures("mock_bus") async def test_filtered_denylist(hass: HomeAssistant, mock_client) -> None: """Test a denylist config with a filtering allowlist.""" - handler_method = await _setup( + await _setup( hass, { "include_entities": ["fake.included", "test.excluded_test"], @@ -1715,8 +1685,8 @@ async def test_filtered_denylist(hass: HomeAssistant, mock_client) -> None: ] for test in tests: - event = make_event(test.id) - handler_method(event) + hass.states.async_set(test.id, "not blank") + await hass.async_block_till_done() was_called = mock_client.labels.call_count == 1 assert test.should_pass == was_called diff --git a/tests/components/statsd/test_init.py b/tests/components/statsd/test_init.py index 2b94d8c0790..1b48b6195e5 100644 --- a/tests/components/statsd/test_init.py +++ b/tests/components/statsd/test_init.py @@ -1,13 +1,12 @@ """The tests for the StatsD feeder.""" from unittest import mock -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest import voluptuous as vol import homeassistant.components.statsd as statsd -from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON -import homeassistant.core as ha +from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -32,15 +31,15 @@ def test_invalid_config() -> None: async def test_statsd_setup_full(hass: HomeAssistant) -> None: """Test setup with all data.""" config = {"statsd": {"host": "host", "port": 123, "rate": 1, "prefix": "foo"}} - hass.bus.listen = MagicMock() with patch("statsd.StatsClient") as mock_init: assert await async_setup_component(hass, statsd.DOMAIN, config) assert mock_init.call_count == 1 assert mock_init.call_args == mock.call(host="host", port=123, prefix="foo") - assert hass.bus.listen.called - assert hass.bus.listen.call_args_list[0][0][0] == EVENT_STATE_CHANGED + hass.states.async_set("domain.test", "on") + await hass.async_block_till_done() + assert len(mock_init.mock_calls) == 3 async def test_statsd_setup_defaults(hass: HomeAssistant) -> None: @@ -50,13 +49,14 @@ async def test_statsd_setup_defaults(hass: HomeAssistant) -> None: config["statsd"][statsd.CONF_PORT] = statsd.DEFAULT_PORT config["statsd"][statsd.CONF_PREFIX] = statsd.DEFAULT_PREFIX - hass.bus.listen = MagicMock() with patch("statsd.StatsClient") as mock_init: assert await async_setup_component(hass, statsd.DOMAIN, config) assert mock_init.call_count == 1 assert mock_init.call_args == mock.call(host="host", port=8125, prefix="hass") - assert hass.bus.listen.called + hass.states.async_set("domain.test", "on") + await hass.async_block_till_done() + assert len(mock_init.mock_calls) == 3 async def test_event_listener_defaults(hass: HomeAssistant, mock_client) -> None: @@ -65,31 +65,27 @@ async def test_event_listener_defaults(hass: HomeAssistant, mock_client) -> None config["statsd"][statsd.CONF_RATE] = statsd.DEFAULT_RATE - hass.bus.listen = MagicMock() await async_setup_component(hass, statsd.DOMAIN, config) - assert hass.bus.listen.called - handler_method = hass.bus.listen.call_args_list[0][0][1] valid = {"1": 1, "1.0": 1.0, "custom": 3, STATE_ON: 1, STATE_OFF: 0} for in_, out in valid.items(): - state = MagicMock(state=in_, attributes={"attribute key": 3.2}) - handler_method(MagicMock(data={"new_state": state})) + hass.states.async_set("domain.test", in_, {"attribute key": 3.2}) + await hass.async_block_till_done() mock_client.gauge.assert_has_calls( - [mock.call(state.entity_id, out, statsd.DEFAULT_RATE)] + [mock.call("domain.test", out, statsd.DEFAULT_RATE)] ) mock_client.gauge.reset_mock() assert mock_client.incr.call_count == 1 assert mock_client.incr.call_args == mock.call( - state.entity_id, rate=statsd.DEFAULT_RATE + "domain.test", rate=statsd.DEFAULT_RATE ) mock_client.incr.reset_mock() for invalid in ("foo", "", object): - handler_method( - MagicMock(data={"new_state": ha.State("domain.test", invalid, {})}) - ) + hass.states.async_set("domain.test", invalid, {}) + await hass.async_block_till_done() assert not mock_client.gauge.called assert mock_client.incr.called @@ -100,19 +96,16 @@ async def test_event_listener_attr_details(hass: HomeAssistant, mock_client) -> config["statsd"][statsd.CONF_RATE] = statsd.DEFAULT_RATE - hass.bus.listen = MagicMock() await async_setup_component(hass, statsd.DOMAIN, config) - assert hass.bus.listen.called - handler_method = hass.bus.listen.call_args_list[0][0][1] valid = {"1": 1, "1.0": 1.0, STATE_ON: 1, STATE_OFF: 0} for in_, out in valid.items(): - state = MagicMock(state=in_, attributes={"attribute key": 3.2}) - handler_method(MagicMock(data={"new_state": state})) + hass.states.async_set("domain.test", in_, {"attribute key": 3.2}) + await hass.async_block_till_done() mock_client.gauge.assert_has_calls( [ - mock.call(f"{state.entity_id}.state", out, statsd.DEFAULT_RATE), - mock.call(f"{state.entity_id}.attribute_key", 3.2, statsd.DEFAULT_RATE), + mock.call("domain.test.state", out, statsd.DEFAULT_RATE), + mock.call("domain.test.attribute_key", 3.2, statsd.DEFAULT_RATE), ] ) @@ -120,13 +113,12 @@ async def test_event_listener_attr_details(hass: HomeAssistant, mock_client) -> assert mock_client.incr.call_count == 1 assert mock_client.incr.call_args == mock.call( - state.entity_id, rate=statsd.DEFAULT_RATE + "domain.test", rate=statsd.DEFAULT_RATE ) mock_client.incr.reset_mock() for invalid in ("foo", "", object): - handler_method( - MagicMock(data={"new_state": ha.State("domain.test", invalid, {})}) - ) + hass.states.async_set("domain.test", invalid, {}) + await hass.async_block_till_done() assert not mock_client.gauge.called assert mock_client.incr.called