Fix merge_response template not mutate original object (#127865)

* Fix merge_response template not mutate original object

* Add comment
This commit is contained in:
G Johansson 2024-10-08 18:35:06 +02:00 committed by Franck Nijhof
parent 14a3e5b771
commit a1e42cac7a
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
2 changed files with 21 additions and 1 deletions

View file

@ -9,6 +9,7 @@ import collections.abc
from collections.abc import Callable, Generator, Iterable
from contextlib import AbstractContextManager
from contextvars import ContextVar
from copy import deepcopy
from datetime import date, datetime, time, timedelta
from functools import cache, cached_property, lru_cache, partial, wraps
import json
@ -2166,7 +2167,8 @@ def merge_response(value: ServiceResponse) -> list[Any]:
is_single_list = False
response_items: list = []
for entity_id, entity_response in value.items(): # pylint: disable=too-many-nested-blocks
input_service_response = deepcopy(value)
for entity_id, entity_response in input_service_response.items(): # pylint: disable=too-many-nested-blocks
if not isinstance(entity_response, dict):
raise TypeError("Response is not a dictionary")
for value_key, type_response in entity_response.items():

View file

@ -6564,3 +6564,21 @@ def test_warn_no_hass(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) ->
template.Template("blah", hass)
assert message not in caplog.text
caplog.clear()
async def test_merge_response_not_mutate_original_object(
hass: HomeAssistant, snapshot: SnapshotAssertion
) -> None:
"""Test the merge_response does not mutate original service response value."""
value = '{"calendar.family": {"events": [{"summary": "An event"}]}'
_template = (
"{% set calendar_response = " + value + "} %}"
"{{ merge_response(calendar_response) }}"
# We should be able to merge the same response again
# as the merge is working on a copy of the original object (response)
"{{ merge_response(calendar_response) }}"
)
tpl = template.Template(_template, hass)
assert tpl.async_render()