diff --git a/homeassistant/components/config/floor_registry.py b/homeassistant/components/config/floor_registry.py index 05d563325e8..f3c9793d25e 100644 --- a/homeassistant/components/config/floor_registry.py +++ b/homeassistant/components/config/floor_registry.py @@ -132,8 +132,10 @@ def _entry_dict(entry: FloorEntry) -> dict[str, Any]: """Convert entry to API format.""" return { "aliases": list(entry.aliases), + "created_at": entry.created_at.timestamp(), "floor_id": entry.floor_id, "icon": entry.icon, "level": entry.level, "name": entry.name, + "modified_at": entry.modified_at.timestamp(), } diff --git a/homeassistant/components/config/label_registry.py b/homeassistant/components/config/label_registry.py index 07b2f1bbd2e..d02b9849d46 100644 --- a/homeassistant/components/config/label_registry.py +++ b/homeassistant/components/config/label_registry.py @@ -157,8 +157,10 @@ def _entry_dict(entry: LabelEntry) -> dict[str, Any]: """Convert entry to API format.""" return { "color": entry.color, + "created_at": entry.created_at.timestamp(), "description": entry.description, "icon": entry.icon, "label_id": entry.label_id, "name": entry.name, + "modified_at": entry.modified_at.timestamp(), } diff --git a/homeassistant/helpers/area_registry.py b/homeassistant/helpers/area_registry.py index 67af70ea22c..bf6dd0d6fcb 100644 --- a/homeassistant/helpers/area_registry.py +++ b/homeassistant/helpers/area_registry.py @@ -87,8 +87,8 @@ class AreaEntry(NormalizedNameBaseRegistryEntry): "labels": list(self.labels), "name": self.name, "picture": self.picture, - "created_at": self.created_at.isoformat(), - "modified_at": self.modified_at.isoformat(), + "created_at": self.created_at.timestamp(), + "modified_at": self.modified_at.timestamp(), } ) ) diff --git a/tests/components/config/test_area_registry.py b/tests/components/config/test_area_registry.py index ed2c1866ad9..03a8272e586 100644 --- a/tests/components/config/test_area_registry.py +++ b/tests/components/config/test_area_registry.py @@ -1,5 +1,7 @@ """Test area_registry API.""" +from datetime import datetime + from freezegun.api import FrozenDateTimeFactory import pytest from pytest_unordered import unordered @@ -28,11 +30,11 @@ async def test_list_areas( freezer: FrozenDateTimeFactory, ) -> None: """Test list entries.""" - created_area1 = "2024-07-16T13:30:00.900075+00:00" + created_area1 = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") freezer.move_to(created_area1) area1 = area_registry.async_create("mock 1") - created_area2 = "2024-07-16T13:45:00.900075+00:00" + created_area2 = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") freezer.move_to(created_area2) area2 = area_registry.async_create( "mock 2", @@ -55,8 +57,8 @@ async def test_list_areas( "labels": [], "name": "mock 1", "picture": None, - "created_at": created_area1, - "modified_at": created_area1, + "created_at": created_area1.timestamp(), + "modified_at": created_area1.timestamp(), }, { "aliases": unordered(["alias_1", "alias_2"]), @@ -66,8 +68,8 @@ async def test_list_areas( "labels": unordered(["label_1", "label_2"]), "name": "mock 2", "picture": "/image/example.png", - "created_at": created_area2, - "modified_at": created_area2, + "created_at": created_area2.timestamp(), + "modified_at": created_area2.timestamp(), }, ] @@ -93,8 +95,8 @@ async def test_create_area( "labels": [], "name": "mock", "picture": None, - "created_at": utcnow().isoformat(), - "modified_at": utcnow().isoformat(), + "created_at": utcnow().timestamp(), + "modified_at": utcnow().timestamp(), } assert len(area_registry.areas) == 1 @@ -121,8 +123,8 @@ async def test_create_area( "labels": unordered(["label_1", "label_2"]), "name": "mock 2", "picture": "/image/example.png", - "created_at": utcnow().isoformat(), - "modified_at": utcnow().isoformat(), + "created_at": utcnow().timestamp(), + "modified_at": utcnow().timestamp(), } assert len(area_registry.areas) == 2 @@ -185,10 +187,10 @@ async def test_update_area( freezer: FrozenDateTimeFactory, ) -> None: """Test update entry.""" - created_at = "2024-07-16T13:30:00.900075+00:00" + created_at = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") freezer.move_to(created_at) area = area_registry.async_create("mock 1") - modified_at = "2024-07-16T13:45:00.900075+00:00" + modified_at = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") freezer.move_to(modified_at) await client.send_json_auto_id( @@ -214,12 +216,12 @@ async def test_update_area( "labels": unordered(["label_1", "label_2"]), "name": "mock 2", "picture": "/image/example.png", - "created_at": created_at, - "modified_at": modified_at, + "created_at": created_at.timestamp(), + "modified_at": modified_at.timestamp(), } assert len(area_registry.areas) == 1 - modified_at = "2024-07-16T13:50:00.900075+00:00" + modified_at = datetime.fromisoformat("2024-07-16T13:50:00.900075+00:00") freezer.move_to(modified_at) await client.send_json_auto_id( @@ -244,8 +246,8 @@ async def test_update_area( "labels": [], "name": "mock 2", "picture": None, - "created_at": created_at, - "modified_at": modified_at, + "created_at": created_at.timestamp(), + "modified_at": modified_at.timestamp(), } assert len(area_registry.areas) == 1 diff --git a/tests/components/config/test_floor_registry.py b/tests/components/config/test_floor_registry.py index b4e3907bc4d..da6e550b1f6 100644 --- a/tests/components/config/test_floor_registry.py +++ b/tests/components/config/test_floor_registry.py @@ -1,11 +1,15 @@ """Test floor registry API.""" +from datetime import datetime + +from freezegun.api import FrozenDateTimeFactory import pytest from pytest_unordered import unordered from homeassistant.components.config import floor_registry from homeassistant.core import HomeAssistant from homeassistant.helpers import floor_registry as fr +from homeassistant.util.dt import utcnow from tests.typing import MockHAClientWebSocket, WebSocketGenerator @@ -22,9 +26,15 @@ async def client_fixture( async def test_list_floors( client: MockHAClientWebSocket, floor_registry: fr.FloorRegistry, + freezer: FrozenDateTimeFactory, ) -> None: """Test list entries.""" + created_1 = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") + freezer.move_to(created_1) floor_registry.async_create("First floor") + + created_2 = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") + freezer.move_to(created_2) floor_registry.async_create( name="Second floor", aliases={"top floor", "attic"}, @@ -34,6 +44,12 @@ async def test_list_floors( assert len(floor_registry.floors) == 2 + # update first floor to change modified_at + floor_registry.async_update( + "first_floor", + name="First floor...", + ) + await client.send_json_auto_id({"type": "config/floor_registry/list"}) msg = await client.receive_json() @@ -41,20 +57,25 @@ async def test_list_floors( assert len(msg["result"]) == len(floor_registry.floors) assert msg["result"][0] == { "aliases": [], + "created_at": created_1.timestamp(), "icon": None, "floor_id": "first_floor", - "name": "First floor", + "modified_at": created_2.timestamp(), + "name": "First floor...", "level": None, } assert msg["result"][1] == { "aliases": unordered(["top floor", "attic"]), + "created_at": created_2.timestamp(), "icon": "mdi:home-floor-2", "floor_id": "second_floor", + "modified_at": created_2.timestamp(), "name": "Second floor", "level": 2, } +@pytest.mark.usefixtures("freezer") async def test_create_floor( client: MockHAClientWebSocket, floor_registry: fr.FloorRegistry, @@ -69,8 +90,10 @@ async def test_create_floor( assert len(floor_registry.floors) == 1 assert msg["result"] == { "aliases": [], + "created_at": utcnow().timestamp(), "icon": None, "floor_id": "first_floor", + "modified_at": utcnow().timestamp(), "name": "First floor", "level": None, } @@ -90,8 +113,10 @@ async def test_create_floor( assert len(floor_registry.floors) == 2 assert msg["result"] == { "aliases": unordered(["top floor", "attic"]), + "created_at": utcnow().timestamp(), "icon": "mdi:home-floor-2", "floor_id": "second_floor", + "modified_at": utcnow().timestamp(), "name": "Second floor", "level": 2, } @@ -163,10 +188,15 @@ async def test_delete_non_existing_floor( async def test_update_floor( client: MockHAClientWebSocket, floor_registry: fr.FloorRegistry, + freezer: FrozenDateTimeFactory, ) -> None: """Test update entry.""" + created_at = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") + freezer.move_to(created_at) floor = floor_registry.async_create("First floor") assert len(floor_registry.floors) == 1 + modified_at = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") + freezer.move_to(modified_at) await client.send_json_auto_id( { @@ -184,12 +214,16 @@ async def test_update_floor( assert len(floor_registry.floors) == 1 assert msg["result"] == { "aliases": unordered(["top floor", "attic"]), + "created_at": created_at.timestamp(), "icon": "mdi:home-floor-2", "floor_id": floor.floor_id, + "modified_at": modified_at.timestamp(), "name": "Second floor", "level": 2, } + modified_at = datetime.fromisoformat("2024-07-16T13:50:00.900075+00:00") + freezer.move_to(modified_at) await client.send_json_auto_id( { "floor_id": floor.floor_id, @@ -206,8 +240,10 @@ async def test_update_floor( assert len(floor_registry.floors) == 1 assert msg["result"] == { "aliases": [], + "created_at": created_at.timestamp(), "icon": None, "floor_id": floor.floor_id, + "modified_at": modified_at.timestamp(), "name": "First floor", "level": None, } diff --git a/tests/components/config/test_label_registry.py b/tests/components/config/test_label_registry.py index 040b3bfe28a..3eff759132f 100644 --- a/tests/components/config/test_label_registry.py +++ b/tests/components/config/test_label_registry.py @@ -1,5 +1,8 @@ """Test label registry API.""" +from datetime import datetime + +from freezegun.api import FrozenDateTimeFactory import pytest from homeassistant.components.config import label_registry @@ -21,9 +24,15 @@ async def client_fixture( async def test_list_labels( client: MockHAClientWebSocket, label_registry: lr.LabelRegistry, + freezer: FrozenDateTimeFactory, ) -> None: """Test list entries.""" + created_1 = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") + freezer.move_to(created_1) label_registry.async_create("mock 1") + + created_2 = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") + freezer.move_to(created_2) label_registry.async_create( name="mock 2", color="#00FF00", @@ -33,6 +42,12 @@ async def test_list_labels( assert len(label_registry.labels) == 2 + # update mock 1 to change modified_at + label_registry.async_update( + "mock_1", + name="Mock 1...", + ) + await client.send_json_auto_id({"type": "config/label_registry/list"}) msg = await client.receive_json() @@ -40,16 +55,20 @@ async def test_list_labels( assert len(msg["result"]) == len(label_registry.labels) assert msg["result"][0] == { "color": None, + "created_at": created_1.timestamp(), "description": None, "icon": None, "label_id": "mock_1", - "name": "mock 1", + "modified_at": created_2.timestamp(), + "name": "Mock 1...", } assert msg["result"][1] == { "color": "#00FF00", + "created_at": created_2.timestamp(), "description": "This is the second label", "icon": "mdi:two", "label_id": "mock_2", + "modified_at": created_2.timestamp(), "name": "mock 2", } @@ -57,8 +76,11 @@ async def test_list_labels( async def test_create_label( client: MockHAClientWebSocket, label_registry: lr.LabelRegistry, + freezer: FrozenDateTimeFactory, ) -> None: """Test create entry.""" + created_1 = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") + freezer.move_to(created_1) await client.send_json_auto_id( { "name": "MOCK", @@ -71,12 +93,16 @@ async def test_create_label( assert len(label_registry.labels) == 1 assert msg["result"] == { "color": None, + "created_at": created_1.timestamp(), "description": None, "icon": None, "label_id": "mock", "name": "MOCK", + "modified_at": created_1.timestamp(), } + created_2 = datetime.fromisoformat("2024-07-17T13:30:00.900075+00:00") + freezer.move_to(created_2) await client.send_json_auto_id( { "id": 2, @@ -93,12 +119,16 @@ async def test_create_label( assert len(label_registry.labels) == 2 assert msg["result"] == { "color": "#00FF00", + "created_at": created_2.timestamp(), "description": "This is the second label", "icon": "mdi:two", "label_id": "mockery", + "modified_at": created_2.timestamp(), "name": "MOCKERY", } + created_3 = datetime.fromisoformat("2024-07-18T13:30:00.900075+00:00") + freezer.move_to(created_3) await client.send_json_auto_id( { "name": "MAGIC", @@ -114,9 +144,11 @@ async def test_create_label( assert len(label_registry.labels) == 3 assert msg["result"] == { "color": "indigo", + "created_at": created_3.timestamp(), "description": "This is the third label", "icon": "mdi:three", "label_id": "magic", + "modified_at": created_3.timestamp(), "name": "MAGIC", } @@ -182,11 +214,17 @@ async def test_delete_non_existing_label( async def test_update_label( client: MockHAClientWebSocket, label_registry: lr.LabelRegistry, + freezer: FrozenDateTimeFactory, ) -> None: """Test update entry.""" + created_at = datetime.fromisoformat("2024-07-16T13:30:00.900075+00:00") + freezer.move_to(created_at) label = label_registry.async_create("mock") assert len(label_registry.labels) == 1 + modified_at = datetime.fromisoformat("2024-07-16T13:45:00.900075+00:00") + freezer.move_to(modified_at) + await client.send_json_auto_id( { "label_id": label.label_id, @@ -203,12 +241,17 @@ async def test_update_label( assert len(label_registry.labels) == 1 assert msg["result"] == { "color": "#00FF00", + "created_at": created_at.timestamp(), "description": "This is a label description", "icon": "mdi:test", "label_id": "mock", + "modified_at": modified_at.timestamp(), "name": "UPDATED", } + modified_at = datetime.fromisoformat("2024-07-16T13:50:00.900075+00:00") + freezer.move_to(modified_at) + await client.send_json_auto_id( { "label_id": label.label_id, @@ -225,12 +268,17 @@ async def test_update_label( assert len(label_registry.labels) == 1 assert msg["result"] == { "color": None, + "created_at": created_at.timestamp(), "description": None, "icon": None, "label_id": "mock", + "modified_at": modified_at.timestamp(), "name": "UPDATED AGAIN", } + modified_at = datetime.fromisoformat("2024-07-16T13:55:00.900075+00:00") + freezer.move_to(modified_at) + await client.send_json_auto_id( { "label_id": label.label_id, @@ -247,9 +295,11 @@ async def test_update_label( assert len(label_registry.labels) == 1 assert msg["result"] == { "color": "primary", + "created_at": created_at.timestamp(), "description": None, "icon": None, "label_id": "mock", + "modified_at": modified_at.timestamp(), "name": "UPDATED YET AGAIN", }