From 7252c33df8b903de65643e2168b4a73f39742c5b Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 29 Jun 2023 10:25:25 -0700 Subject: [PATCH] Limit fields returned for the list events service (#95506) * Limit fields returned for the list events service * Update websocket tests and fix bugs in response fields * Omit 'None' fields in the list events response --- homeassistant/components/calendar/__init__.py | 20 +++++++++++++++---- homeassistant/components/calendar/const.py | 9 +++++++++ tests/components/calendar/test_init.py | 18 +++++++++++------ .../components/websocket_api/test_commands.py | 3 --- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/calendar/__init__.py b/homeassistant/components/calendar/__init__.py index 5d0d2526bf2..86f61f0ed87 100644 --- a/homeassistant/components/calendar/__init__.py +++ b/homeassistant/components/calendar/__init__.py @@ -60,6 +60,7 @@ from .const import ( EVENT_TIME_FIELDS, EVENT_TYPES, EVENT_UID, + LIST_EVENT_FIELDS, CalendarEntityFeature, ) @@ -415,6 +416,17 @@ def _api_event_dict_factory(obj: Iterable[tuple[str, Any]]) -> dict[str, Any]: return result +def _list_events_dict_factory( + obj: Iterable[tuple[str, Any]] +) -> dict[str, JsonValueType]: + """Convert CalendarEvent dataclass items to dictionary of attributes.""" + return { + name: value + for name, value in obj + if name in LIST_EVENT_FIELDS and value is not None + } + + def _get_datetime_local( dt_or_d: datetime.datetime | datetime.date, ) -> datetime.datetime: @@ -782,9 +794,9 @@ async def async_list_events_service( else: end = service_call.data[EVENT_END_DATETIME] calendar_event_list = await calendar.async_get_events(calendar.hass, start, end) - events: list[JsonValueType] = [ - dataclasses.asdict(event) for event in calendar_event_list - ] return { - "events": events, + "events": [ + dataclasses.asdict(event, dict_factory=_list_events_dict_factory) + for event in calendar_event_list + ] } diff --git a/homeassistant/components/calendar/const.py b/homeassistant/components/calendar/const.py index 2d4f0dfe0ba..e667510325b 100644 --- a/homeassistant/components/calendar/const.py +++ b/homeassistant/components/calendar/const.py @@ -41,3 +41,12 @@ EVENT_TIME_FIELDS = { } EVENT_TYPES = "event_types" EVENT_DURATION = "duration" + +# Fields for the list events service +LIST_EVENT_FIELDS = { + "start", + "end", + EVENT_SUMMARY, + EVENT_DESCRIPTION, + EVENT_LOCATION, +} diff --git a/tests/components/calendar/test_init.py b/tests/components/calendar/test_init.py index 97292221819..9fdc76abe03 100644 --- a/tests/components/calendar/test_init.py +++ b/tests/components/calendar/test_init.py @@ -4,7 +4,7 @@ from __future__ import annotations from datetime import timedelta from http import HTTPStatus from typing import Any -from unittest.mock import patch +from unittest.mock import ANY, patch import pytest import voluptuous as vol @@ -405,11 +405,17 @@ async def test_list_events_service(hass: HomeAssistant) -> None: blocking=True, return_response=True, ) - assert response - assert "events" in response - events = response["events"] - assert len(events) == 1 - assert events[0]["summary"] == "Future Event" + assert response == { + "events": [ + { + "start": ANY, + "end": ANY, + "summary": "Future Event", + "description": "Future Description", + "location": "Future Location", + } + ] + } @pytest.mark.parametrize( diff --git a/tests/components/websocket_api/test_commands.py b/tests/components/websocket_api/test_commands.py index c8f494a0071..7e46dc0d0bd 100644 --- a/tests/components/websocket_api/test_commands.py +++ b/tests/components/websocket_api/test_commands.py @@ -1769,9 +1769,6 @@ async def test_execute_script_complex_response( "summary": "Future Event", "description": "Future Description", "location": "Future Location", - "uid": None, - "recurrence_id": None, - "rrule": None, } ] }