mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 00:20:30 +01:00
Allow TODO entity listeners to handle None state (#166276)
This commit is contained in:
@@ -240,7 +240,7 @@ class TodoListEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
"""An entity that represents a To-do list."""
|
||||
|
||||
_attr_todo_items: list[TodoItem] | None = None
|
||||
_update_listeners: list[Callable[[list[TodoItem]], None]] | None = None
|
||||
_update_listeners: list[Callable[[list[TodoItem] | None], None]] | None = None
|
||||
|
||||
@property
|
||||
def state(self) -> int | None:
|
||||
@@ -281,7 +281,7 @@ class TodoListEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
@final
|
||||
@callback
|
||||
def async_subscribe_updates(
|
||||
self, listener: Callable[[list[TodoItem]], None]
|
||||
self, listener: Callable[[list[TodoItem] | None], None]
|
||||
) -> CALLBACK_TYPE:
|
||||
"""Subscribe to To-do list item updates."""
|
||||
if self._update_listeners is None:
|
||||
@@ -302,7 +302,12 @@ class TodoListEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
if not self._update_listeners:
|
||||
return
|
||||
|
||||
todo_items = [copy.copy(item) for item in self.todo_items or []]
|
||||
todo_items = (
|
||||
[copy.copy(item) for item in self.todo_items]
|
||||
if self.todo_items is not None
|
||||
else None
|
||||
)
|
||||
|
||||
for listener in self._update_listeners:
|
||||
listener(todo_items)
|
||||
|
||||
@@ -335,14 +340,13 @@ async def websocket_handle_subscribe_todo_items(
|
||||
return
|
||||
|
||||
@callback
|
||||
def todo_item_listener(todo_items: list[TodoItem]) -> None:
|
||||
def todo_item_listener(todo_items: list[TodoItem] | None) -> None:
|
||||
"""Push updated To-do list items to websocket."""
|
||||
items = [dataclasses.asdict(item) for item in todo_items or []]
|
||||
connection.send_message(
|
||||
websocket_api.event_message(
|
||||
msg["id"],
|
||||
{
|
||||
"items": [dataclasses.asdict(item) for item in todo_items],
|
||||
},
|
||||
{"items": items},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1239,9 +1239,9 @@ async def test_async_subscribe_updates(
|
||||
"""Test async_subscribe_updates delivers list updates to listeners."""
|
||||
await create_mock_platform(hass, [test_entity])
|
||||
|
||||
received_updates: list[list[TodoItem]] = []
|
||||
received_updates: list[list[TodoItem] | None] = []
|
||||
|
||||
def listener(items: list[TodoItem]) -> None:
|
||||
def listener(items: list[TodoItem] | None) -> None:
|
||||
received_updates.append(items)
|
||||
|
||||
unsub = test_entity.async_subscribe_updates(listener)
|
||||
@@ -1277,7 +1277,25 @@ async def test_async_subscribe_updates(
|
||||
assert len(items) == 3
|
||||
assert items[2].summary == "Item #3"
|
||||
|
||||
# Set items to None and trigger update
|
||||
test_entity._attr_todo_items = None
|
||||
test_entity.async_write_ha_state()
|
||||
assert len(received_updates) == 3
|
||||
assert received_updates[2] is None
|
||||
|
||||
# Add a new item to make it available again and trigger update
|
||||
test_entity._attr_todo_items = [
|
||||
TodoItem(summary="New item", uid="4", status=TodoItemStatus.NEEDS_ACTION)
|
||||
]
|
||||
test_entity.async_write_ha_state()
|
||||
assert len(received_updates) == 4
|
||||
items = received_updates[3]
|
||||
assert len(items) == 1
|
||||
assert items[0].summary == "New item"
|
||||
assert items[0].uid == "4"
|
||||
assert items[0].status == TodoItemStatus.NEEDS_ACTION
|
||||
|
||||
# Unsubscribe and verify no more updates
|
||||
unsub()
|
||||
test_entity.async_write_ha_state()
|
||||
assert len(received_updates) == 2
|
||||
assert len(received_updates) == 4
|
||||
|
||||
Reference in New Issue
Block a user