Ensure history states can be copied (#37081)
The filter integration makes a copy of a state object obtained from history.
This commit is contained in:
parent
5bc6ed4cef
commit
f4528d0db2
2 changed files with 46 additions and 2 deletions
|
@ -616,7 +616,7 @@ class LazyState(State):
|
||||||
self._last_updated = None
|
self._last_updated = None
|
||||||
self._context = None
|
self._context = None
|
||||||
|
|
||||||
@property
|
@property # type: ignore
|
||||||
def attributes(self):
|
def attributes(self):
|
||||||
"""State attributes."""
|
"""State attributes."""
|
||||||
if not self._attributes:
|
if not self._attributes:
|
||||||
|
@ -628,13 +628,23 @@ class LazyState(State):
|
||||||
self._attributes = {}
|
self._attributes = {}
|
||||||
return self._attributes
|
return self._attributes
|
||||||
|
|
||||||
@property
|
@attributes.setter
|
||||||
|
def attributes(self, value):
|
||||||
|
"""Set attributes."""
|
||||||
|
self._attributes = value
|
||||||
|
|
||||||
|
@property # type: ignore
|
||||||
def context(self):
|
def context(self):
|
||||||
"""State context."""
|
"""State context."""
|
||||||
if not self._context:
|
if not self._context:
|
||||||
self._context = Context(id=None)
|
self._context = Context(id=None)
|
||||||
return self._context
|
return self._context
|
||||||
|
|
||||||
|
@context.setter
|
||||||
|
def context(self, value):
|
||||||
|
"""Set context."""
|
||||||
|
self._context = value
|
||||||
|
|
||||||
@property # type: ignore
|
@property # type: ignore
|
||||||
def last_changed(self):
|
def last_changed(self):
|
||||||
"""Last changed datetime."""
|
"""Last changed datetime."""
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""The tests the History component."""
|
"""The tests the History component."""
|
||||||
# pylint: disable=protected-access,invalid-name
|
# pylint: disable=protected-access,invalid-name
|
||||||
|
from copy import copy
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import json
|
import json
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -188,6 +189,39 @@ class TestComponentHistory(unittest.TestCase):
|
||||||
|
|
||||||
assert states == hist[entity_id]
|
assert states == hist[entity_id]
|
||||||
|
|
||||||
|
def test_ensure_state_can_be_copied(self):
|
||||||
|
"""Ensure a state can pass though copy().
|
||||||
|
|
||||||
|
The filter integration uses copy() on states
|
||||||
|
from history.
|
||||||
|
"""
|
||||||
|
self.init_recorder()
|
||||||
|
entity_id = "sensor.test"
|
||||||
|
|
||||||
|
def set_state(state):
|
||||||
|
"""Set the state."""
|
||||||
|
self.hass.states.set(entity_id, state)
|
||||||
|
wait_recording_done(self.hass)
|
||||||
|
return self.hass.states.get(entity_id)
|
||||||
|
|
||||||
|
start = dt_util.utcnow() - timedelta(minutes=2)
|
||||||
|
point = start + timedelta(minutes=1)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.recorder.dt_util.utcnow", return_value=start
|
||||||
|
):
|
||||||
|
set_state("1")
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.recorder.dt_util.utcnow", return_value=point
|
||||||
|
):
|
||||||
|
set_state("2")
|
||||||
|
|
||||||
|
hist = history.get_last_state_changes(self.hass, 2, entity_id)
|
||||||
|
|
||||||
|
assert copy(hist[entity_id][0]) == hist[entity_id][0]
|
||||||
|
assert copy(hist[entity_id][1]) == hist[entity_id][1]
|
||||||
|
|
||||||
def test_get_significant_states(self):
|
def test_get_significant_states(self):
|
||||||
"""Test that only significant states are returned.
|
"""Test that only significant states are returned.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue