From aa8d8402b47b413f8506d468dbe0dfa6a91a9bfc Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 17 Feb 2024 19:07:46 +0100 Subject: [PATCH] Cleanups in entity registry tests (#110788) Co-authored-by: Joost Lekkerkerker Co-authored-by: J. Nick Koston --- .../components/config/test_entity_registry.py | 114 +++++++++--------- tests/helpers/test_entity_registry.py | 102 ++++++++-------- 2 files changed, 109 insertions(+), 107 deletions(-) diff --git a/tests/components/config/test_entity_registry.py b/tests/components/config/test_entity_registry.py index ab125651729..c2cd547d425 100644 --- a/tests/components/config/test_entity_registry.py +++ b/tests/components/config/test_entity_registry.py @@ -19,7 +19,6 @@ from tests.common import ( MockConfigEntry, MockEntity, MockEntityPlatform, - mock_device_registry, mock_registry, ) from tests.typing import MockHAClientWebSocket, WebSocketGenerator @@ -34,13 +33,9 @@ async def client( return await hass_ws_client(hass) -@pytest.fixture -def device_registry(hass): - """Return an empty, loaded, registry.""" - return mock_device_registry(hass) - - -async def test_list_entities(hass: HomeAssistant, client) -> None: +async def test_list_entities( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test list entries.""" mock_registry( hass, @@ -59,7 +54,7 @@ async def test_list_entities(hass: HomeAssistant, client) -> None: }, ) - await client.send_json({"id": 5, "type": "config/entity_registry/list"}) + await client.send_json_auto_id({"type": "config/entity_registry/list"}) msg = await client.receive_json() assert msg["result"] == [ @@ -122,7 +117,7 @@ async def test_list_entities(hass: HomeAssistant, client) -> None: }, ) - await client.send_json({"id": 6, "type": "config/entity_registry/list"}) + await client.send_json_auto_id({"type": "config/entity_registry/list"}) msg = await client.receive_json() assert msg["result"] == [ @@ -314,7 +309,7 @@ async def test_list_entities_for_display( } -async def test_get_entity(hass: HomeAssistant, client) -> None: +async def test_get_entity(hass: HomeAssistant, client: MockHAClientWebSocket) -> None: """Test get entry.""" mock_registry( hass, @@ -333,8 +328,8 @@ async def test_get_entity(hass: HomeAssistant, client) -> None: }, ) - await client.send_json( - {"id": 5, "type": "config/entity_registry/get", "entity_id": "test_domain.name"} + await client.send_json_auto_id( + {"type": "config/entity_registry/get", "entity_id": "test_domain.name"} ) msg = await client.receive_json() @@ -362,9 +357,8 @@ async def test_get_entity(hass: HomeAssistant, client) -> None: "unique_id": "1234", } - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/get", "entity_id": "test_domain.no_name", } @@ -396,7 +390,7 @@ async def test_get_entity(hass: HomeAssistant, client) -> None: } -async def test_get_entities(hass: HomeAssistant, client) -> None: +async def test_get_entities(hass: HomeAssistant, client: MockHAClientWebSocket) -> None: """Test get entry.""" mock_registry( hass, @@ -415,9 +409,8 @@ async def test_get_entities(hass: HomeAssistant, client) -> None: }, ) - await client.send_json( + await client.send_json_auto_id( { - "id": 5, "type": "config/entity_registry/get_entries", "entity_ids": [ "test_domain.name", @@ -479,7 +472,9 @@ async def test_get_entities(hass: HomeAssistant, client) -> None: } -async def test_update_entity(hass: HomeAssistant, client) -> None: +async def test_update_entity( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test updating entity.""" registry = mock_registry( hass, @@ -504,9 +499,8 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: assert state.attributes[ATTR_ICON] == "icon:before update" # UPDATE AREA, DEVICE_CLASS, HIDDEN_BY, ICON AND NAME - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "aliases": ["alias_1", "alias_2"], @@ -551,9 +545,8 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: assert state.attributes[ATTR_ICON] == "icon:after update" # UPDATE HIDDEN_BY TO ILLEGAL VALUE - await client.send_json( + await client.send_json_auto_id( { - "id": 7, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "hidden_by": "ivy", @@ -566,9 +559,8 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: assert registry.entities["test_domain.world"].hidden_by is RegistryEntryHider.USER # UPDATE DISABLED_BY TO USER - await client.send_json( + await client.send_json_auto_id( { - "id": 8, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": "user", # We exchange strings over the WS API, not enums @@ -584,9 +576,8 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: ) # UPDATE DISABLED_BY TO NONE - await client.send_json( + await client.send_json_auto_id( { - "id": 9, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "disabled_by": None, @@ -623,9 +614,8 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: } # UPDATE ENTITY OPTION - await client.send_json( + await client.send_json_auto_id( { - "id": 10, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "options_domain": "sensor", @@ -662,7 +652,9 @@ async def test_update_entity(hass: HomeAssistant, client) -> None: } -async def test_update_entity_require_restart(hass: HomeAssistant, client) -> None: +async def test_update_entity_require_restart( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test updating entity.""" entity_id = "test_domain.test_platform_1234" config_entry = MockConfigEntry(domain="test_platform") @@ -676,9 +668,8 @@ async def test_update_entity_require_restart(hass: HomeAssistant, client) -> Non assert state is not None # UPDATE DISABLED_BY TO NONE - await client.send_json( + await client.send_json_auto_id( { - "id": 8, "type": "config/entity_registry/update", "entity_id": entity_id, "disabled_by": None, @@ -716,7 +707,9 @@ async def test_update_entity_require_restart(hass: HomeAssistant, client) -> Non async def test_enable_entity_disabled_device( - hass: HomeAssistant, client, device_registry: dr.DeviceRegistry + hass: HomeAssistant, + client: MockHAClientWebSocket, + device_registry: dr.DeviceRegistry, ) -> None: """Test enabling entity of disabled device.""" entity_id = "test_domain.test_platform_1234" @@ -750,9 +743,8 @@ async def test_enable_entity_disabled_device( assert entity_entry.disabled_by == RegistryEntryDisabler.DEVICE # UPDATE DISABLED_BY TO NONE - await client.send_json( + await client.send_json_auto_id( { - "id": 8, "type": "config/entity_registry/update", "entity_id": entity_id, "disabled_by": None, @@ -764,7 +756,9 @@ async def test_enable_entity_disabled_device( assert not msg["success"] -async def test_update_entity_no_changes(hass: HomeAssistant, client) -> None: +async def test_update_entity_no_changes( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test update entity with no changes.""" mock_registry( hass, @@ -786,9 +780,8 @@ async def test_update_entity_no_changes(hass: HomeAssistant, client) -> None: assert state is not None assert state.name == "name of entity" - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "name": "name of entity", @@ -827,11 +820,10 @@ async def test_update_entity_no_changes(hass: HomeAssistant, client) -> None: assert state.name == "name of entity" -async def test_get_nonexisting_entity(client) -> None: +async def test_get_nonexisting_entity(client: MockHAClientWebSocket) -> None: """Test get entry with nonexisting entity.""" - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/get", "entity_id": "test_domain.no_name", } @@ -841,11 +833,10 @@ async def test_get_nonexisting_entity(client) -> None: assert not msg["success"] -async def test_update_nonexisting_entity(client) -> None: +async def test_update_nonexisting_entity(client: MockHAClientWebSocket) -> None: """Test update a nonexisting entity.""" - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.no_name", "name": "new-name", @@ -856,7 +847,9 @@ async def test_update_nonexisting_entity(client) -> None: assert not msg["success"] -async def test_update_entity_id(hass: HomeAssistant, client) -> None: +async def test_update_entity_id( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test update entity id.""" mock_registry( hass, @@ -875,9 +868,8 @@ async def test_update_entity_id(hass: HomeAssistant, client) -> None: assert hass.states.get("test_domain.world") is not None - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "new_entity_id": "test_domain.planet", @@ -916,7 +908,9 @@ async def test_update_entity_id(hass: HomeAssistant, client) -> None: assert hass.states.get("test_domain.planet") is not None -async def test_update_existing_entity_id(hass: HomeAssistant, client) -> None: +async def test_update_existing_entity_id( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test update entity id to an already registered entity id.""" mock_registry( hass, @@ -939,9 +933,8 @@ async def test_update_existing_entity_id(hass: HomeAssistant, client) -> None: entities = [MockEntity(unique_id="1234"), MockEntity(unique_id="2345")] await platform.async_add_entities(entities) - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "new_entity_id": "test_domain.planet", @@ -953,7 +946,9 @@ async def test_update_existing_entity_id(hass: HomeAssistant, client) -> None: assert not msg["success"] -async def test_update_invalid_entity_id(hass: HomeAssistant, client) -> None: +async def test_update_invalid_entity_id( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test update entity id to an invalid entity id.""" mock_registry( hass, @@ -970,9 +965,8 @@ async def test_update_invalid_entity_id(hass: HomeAssistant, client) -> None: entities = [MockEntity(unique_id="1234"), MockEntity(unique_id="2345")] await platform.async_add_entities(entities) - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/update", "entity_id": "test_domain.world", "new_entity_id": "another_domain.planet", @@ -984,7 +978,9 @@ async def test_update_invalid_entity_id(hass: HomeAssistant, client) -> None: assert not msg["success"] -async def test_remove_entity(hass: HomeAssistant, client) -> None: +async def test_remove_entity( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test removing entity.""" registry = mock_registry( hass, @@ -999,9 +995,8 @@ async def test_remove_entity(hass: HomeAssistant, client) -> None: }, ) - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/remove", "entity_id": "test_domain.world", } @@ -1013,13 +1008,14 @@ async def test_remove_entity(hass: HomeAssistant, client) -> None: assert len(registry.entities) == 0 -async def test_remove_non_existing_entity(hass: HomeAssistant, client) -> None: +async def test_remove_non_existing_entity( + hass: HomeAssistant, client: MockHAClientWebSocket +) -> None: """Test removing non existing entity.""" mock_registry(hass, {}) - await client.send_json( + await client.send_json_auto_id( { - "id": 6, "type": "config/entity_registry/remove", "entity_id": "test_domain.world", } diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 9e86b0279de..542fe46968d 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -4,6 +4,7 @@ from typing import Any from unittest.mock import patch import attr +from freezegun.api import FrozenDateTimeFactory import pytest import voluptuous as vol @@ -17,26 +18,17 @@ from homeassistant.core import CoreState, HomeAssistant, callback from homeassistant.exceptions import MaxLengthExceeded from homeassistant.helpers import device_registry as dr, entity_registry as er -from tests.common import MockConfigEntry, async_fire_time_changed, flush_store +from tests.common import ( + MockConfigEntry, + async_capture_events, + async_fire_time_changed, + flush_store, +) YAML__OPEN_PATH = "homeassistant.util.yaml.loader.open" -@pytest.fixture -def update_events(hass): - """Capture update events.""" - events = [] - - @callback - def async_capture(event): - events.append(event.data) - - hass.bus.async_listen(er.EVENT_ENTITY_REGISTRY_UPDATED, async_capture) - - return events - - -async def test_get(hass: HomeAssistant, entity_registry: er.EntityRegistry): +async def test_get(entity_registry: er.EntityRegistry): """Test we can get an item.""" entry = entity_registry.async_get_or_create("light", "hue", "1234") @@ -47,9 +39,10 @@ async def test_get(hass: HomeAssistant, entity_registry: er.EntityRegistry): async def test_get_or_create_returns_same_entry( - hass: HomeAssistant, entity_registry: er.EntityRegistry, update_events + hass: HomeAssistant, entity_registry: er.EntityRegistry ) -> None: """Make sure we do not duplicate entries.""" + update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) entry = entity_registry.async_get_or_create("light", "hue", "1234") entry2 = entity_registry.async_get_or_create("light", "hue", "1234") @@ -59,8 +52,10 @@ async def test_get_or_create_returns_same_entry( assert entry is entry2 assert entry.entity_id == "light.hue_1234" assert len(update_events) == 1 - assert update_events[0]["action"] == "create" - assert update_events[0]["entity_id"] == entry.entity_id + assert update_events[0].data == { + "action": "create", + "entity_id": entry.entity_id, + } def test_get_or_create_suggested_object_id(entity_registry: er.EntityRegistry) -> None: @@ -449,9 +444,10 @@ def test_async_get_entity_id(entity_registry: er.EntityRegistry) -> None: async def test_updating_config_entry_id( - hass: HomeAssistant, entity_registry: er.EntityRegistry, update_events + hass: HomeAssistant, entity_registry: er.EntityRegistry ) -> None: """Test that we update config entry id in registry.""" + update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) mock_config_1 = MockConfigEntry(domain="light", entry_id="mock-id-1") entry = entity_registry.async_get_or_create( "light", "hue", "5678", config_entry=mock_config_1 @@ -467,17 +463,22 @@ async def test_updating_config_entry_id( await hass.async_block_till_done() assert len(update_events) == 2 - assert update_events[0]["action"] == "create" - assert update_events[0]["entity_id"] == entry.entity_id - assert update_events[1]["action"] == "update" - assert update_events[1]["entity_id"] == entry.entity_id - assert update_events[1]["changes"] == {"config_entry_id": "mock-id-1"} + assert update_events[0].data == { + "action": "create", + "entity_id": entry.entity_id, + } + assert update_events[1].data == { + "action": "update", + "entity_id": entry.entity_id, + "changes": {"config_entry_id": "mock-id-1"}, + } async def test_removing_config_entry_id( - hass: HomeAssistant, entity_registry: er.EntityRegistry, update_events + hass: HomeAssistant, entity_registry: er.EntityRegistry ) -> None: """Test that we update config entry id in registry.""" + update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) mock_config = MockConfigEntry(domain="light", entry_id="mock-id-1") entry = entity_registry.async_get_or_create( @@ -491,14 +492,18 @@ async def test_removing_config_entry_id( await hass.async_block_till_done() assert len(update_events) == 2 - assert update_events[0]["action"] == "create" - assert update_events[0]["entity_id"] == entry.entity_id - assert update_events[1]["action"] == "remove" - assert update_events[1]["entity_id"] == entry.entity_id + assert update_events[0].data == { + "action": "create", + "entity_id": entry.entity_id, + } + assert update_events[1].data == { + "action": "remove", + "entity_id": entry.entity_id, + } async def test_deleted_entity_removing_config_entry_id( - hass, entity_registry: er.EntityRegistry + entity_registry: er.EntityRegistry, ): """Test that we update config entry id in registry on deleted entity.""" mock_config = MockConfigEntry(domain="light", entry_id="mock-id-1") @@ -1515,9 +1520,7 @@ async def test_entity_category_str_not_allowed( ) -async def test_hidden_by_str_not_allowed( - hass: HomeAssistant, entity_registry: er.EntityRegistry -) -> None: +async def test_hidden_by_str_not_allowed(entity_registry: er.EntityRegistry) -> None: """Test we need to pass hidden by type.""" with pytest.raises(ValueError): entity_registry.async_get_or_create( @@ -1605,9 +1608,12 @@ def test_migrate_entity_to_new_platform( async def test_restore_entity( - hass: HomeAssistant, entity_registry: er.EntityRegistry, update_events, freezer + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + freezer: FrozenDateTimeFactory, ): """Make sure entity registry id is stable and entity_id is reused if possible.""" + update_events = async_capture_events(hass, er.EVENT_ENTITY_REGISTRY_UPDATED) config_entry = MockConfigEntry(domain="light") entry1 = entity_registry.async_get_or_create( "light", "hue", "1234", config_entry=config_entry @@ -1679,22 +1685,22 @@ async def test_restore_entity( # Check the events await hass.async_block_till_done() assert len(update_events) == 13 - assert update_events[0] == {"action": "create", "entity_id": "light.hue_1234"} - assert update_events[1] == {"action": "create", "entity_id": "light.hue_5678"} - assert update_events[2]["action"] == "update" - assert update_events[3] == {"action": "remove", "entity_id": "light.custom_1"} - assert update_events[4] == {"action": "remove", "entity_id": "light.hue_5678"} + assert update_events[0].data == {"action": "create", "entity_id": "light.hue_1234"} + assert update_events[1].data == {"action": "create", "entity_id": "light.hue_5678"} + assert update_events[2].data["action"] == "update" + assert update_events[3].data == {"action": "remove", "entity_id": "light.custom_1"} + assert update_events[4].data == {"action": "remove", "entity_id": "light.hue_5678"} # Restore entities the 1st time - assert update_events[5] == {"action": "create", "entity_id": "light.hue_1234"} - assert update_events[6] == {"action": "create", "entity_id": "light.hue_5678"} - assert update_events[7] == {"action": "remove", "entity_id": "light.hue_1234"} - assert update_events[8] == {"action": "remove", "entity_id": "light.hue_5678"} + assert update_events[5].data == {"action": "create", "entity_id": "light.hue_1234"} + assert update_events[6].data == {"action": "create", "entity_id": "light.hue_5678"} + assert update_events[7].data == {"action": "remove", "entity_id": "light.hue_1234"} + assert update_events[8].data == {"action": "remove", "entity_id": "light.hue_5678"} # Restore entities the 2nd time - assert update_events[9] == {"action": "create", "entity_id": "light.hue_1234"} - assert update_events[10] == {"action": "create", "entity_id": "light.hue_5678"} - assert update_events[11] == {"action": "remove", "entity_id": "light.hue_1234"} + assert update_events[9].data == {"action": "create", "entity_id": "light.hue_1234"} + assert update_events[10].data == {"action": "create", "entity_id": "light.hue_5678"} + assert update_events[11].data == {"action": "remove", "entity_id": "light.hue_1234"} # Restore entities the 3rd time - assert update_events[12] == {"action": "create", "entity_id": "light.hue_1234"} + assert update_events[12].data == {"action": "create", "entity_id": "light.hue_1234"} async def test_async_migrate_entry_delete_self(