mirror of
https://github.com/home-assistant/core.git
synced 2026-05-14 12:31:04 +01:00
Load lovelace resource collection eagerly during setup (#165773)
This commit is contained in:
@@ -62,14 +62,32 @@ class ResourceStorageCollection(collection.DictStorageCollection):
|
||||
)
|
||||
self.ll_config = ll_config
|
||||
|
||||
async def async_get_info(self) -> dict[str, int]:
|
||||
"""Return the resources info for YAML mode."""
|
||||
async def _async_ensure_loaded(self) -> None:
|
||||
"""Ensure the collection has been loaded from storage."""
|
||||
if not self.loaded:
|
||||
await self.async_load()
|
||||
self.loaded = True
|
||||
|
||||
async def async_get_info(self) -> dict[str, int]:
|
||||
"""Return the resources info for YAML mode."""
|
||||
await self._async_ensure_loaded()
|
||||
return {"resources": len(self.async_items() or [])}
|
||||
|
||||
async def async_create_item(self, data: dict) -> dict:
|
||||
"""Create a new item."""
|
||||
await self._async_ensure_loaded()
|
||||
return await super().async_create_item(data)
|
||||
|
||||
async def async_update_item(self, item_id: str, updates: dict) -> dict:
|
||||
"""Update item."""
|
||||
await self._async_ensure_loaded()
|
||||
return await super().async_update_item(item_id, updates)
|
||||
|
||||
async def async_delete_item(self, item_id: str) -> None:
|
||||
"""Delete item."""
|
||||
await self._async_ensure_loaded()
|
||||
await super().async_delete_item(item_id)
|
||||
|
||||
async def _async_load_data(self) -> collection.SerializedStorageCollection | None:
|
||||
"""Load the data."""
|
||||
if (store_data := await self.store.async_load()) is not None:
|
||||
@@ -118,10 +136,6 @@ class ResourceStorageCollection(collection.DictStorageCollection):
|
||||
|
||||
async def _update_data(self, item: dict, update_data: dict) -> dict:
|
||||
"""Return a new updated data object."""
|
||||
if not self.loaded:
|
||||
await self.async_load()
|
||||
self.loaded = True
|
||||
|
||||
update_data = self.UPDATE_SCHEMA(update_data)
|
||||
if CONF_RESOURCE_TYPE_WS in update_data:
|
||||
update_data[CONF_TYPE] = update_data.pop(CONF_RESOURCE_TYPE_WS)
|
||||
|
||||
@@ -8,6 +8,7 @@ import uuid
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.lovelace import dashboard, resources
|
||||
from homeassistant.components.lovelace.const import LOVELACE_DATA
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
@@ -278,6 +279,41 @@ async def test_storage_resources_import_invalid(
|
||||
)
|
||||
|
||||
|
||||
async def test_storage_resources_create_preserves_existing(
|
||||
hass: HomeAssistant,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test async_create_item lazy-loads before writing.
|
||||
|
||||
Custom integrations may call async_create_item() during startup before the
|
||||
frontend triggers a resource listing. Without a lazy-load guard, the
|
||||
collection is empty and async_create_item() overwrites all existing
|
||||
resources on disk.
|
||||
"""
|
||||
resource_config = [{**item, "id": uuid.uuid4().hex} for item in RESOURCE_EXAMPLES]
|
||||
hass_storage[resources.RESOURCE_STORAGE_KEY] = {
|
||||
"key": resources.RESOURCE_STORAGE_KEY,
|
||||
"version": 1,
|
||||
"data": {"items": resource_config},
|
||||
}
|
||||
assert await async_setup_component(hass, "lovelace", {})
|
||||
|
||||
resource_collection = hass.data[LOVELACE_DATA].resources
|
||||
|
||||
# Directly call async_create_item before any websocket listing
|
||||
await resource_collection.async_create_item(
|
||||
{"res_type": "module", "url": "/local/new.js"}
|
||||
)
|
||||
|
||||
# Existing resources must still be present
|
||||
items = resource_collection.async_items()
|
||||
assert len(items) == len(resource_config) + 1
|
||||
urls = [item["url"] for item in items]
|
||||
for original in resource_config:
|
||||
assert original["url"] in urls
|
||||
assert "/local/new.js" in urls
|
||||
|
||||
|
||||
@pytest.mark.parametrize("list_cmd", ["lovelace/resources", "lovelace/resources/list"])
|
||||
async def test_storage_resources_safe_mode(
|
||||
hass: HomeAssistant,
|
||||
|
||||
Reference in New Issue
Block a user