mirror of
https://github.com/home-assistant/core.git
synced 2025-11-20 08:20:12 +00:00
Compare commits
3 Commits
setpoint_c
...
show_sideb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53edbacef3 | ||
|
|
7e15923dfc | ||
|
|
80e57a8394 |
@@ -36,6 +36,10 @@ from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.loader import async_get_integration, bind_hass
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
from .panel_preferences import (
|
||||
async_get_panel_preferences,
|
||||
async_setup_panel_preferences,
|
||||
)
|
||||
from .storage import async_setup_frontend_storage
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -51,6 +55,7 @@ CONF_EXTRA_MODULE_URL = "extra_module_url"
|
||||
CONF_EXTRA_JS_URL_ES5 = "extra_js_url_es5"
|
||||
CONF_FRONTEND_REPO = "development_repo"
|
||||
CONF_JS_VERSION = "javascript_version"
|
||||
CONF_SHOW_IN_SIDEBAR = "show_in_sidebar"
|
||||
|
||||
DEFAULT_THEME_COLOR = "#2980b9"
|
||||
|
||||
@@ -272,6 +277,9 @@ class Panel:
|
||||
# If the panel should only be visible to admins
|
||||
require_admin = False
|
||||
|
||||
# If the panel should be shown in the sidebar by default
|
||||
show_in_sidebar: bool = True
|
||||
|
||||
# If the panel is a configuration panel for a integration
|
||||
config_panel_domain: str | None = None
|
||||
|
||||
@@ -284,6 +292,7 @@ class Panel:
|
||||
config: dict[str, Any] | None,
|
||||
require_admin: bool,
|
||||
config_panel_domain: str | None,
|
||||
show_in_sidebar: bool | None = None,
|
||||
) -> None:
|
||||
"""Initialize a built-in panel."""
|
||||
self.component_name = component_name
|
||||
@@ -293,6 +302,11 @@ class Panel:
|
||||
self.config = config
|
||||
self.require_admin = require_admin
|
||||
self.config_panel_domain = config_panel_domain
|
||||
# Default to True if title is provided, False otherwise
|
||||
if show_in_sidebar is None:
|
||||
self.show_in_sidebar = sidebar_title is not None
|
||||
else:
|
||||
self.show_in_sidebar = show_in_sidebar
|
||||
|
||||
@callback
|
||||
def to_response(self) -> PanelResponse:
|
||||
@@ -305,6 +319,7 @@ class Panel:
|
||||
"url_path": self.frontend_url_path,
|
||||
"require_admin": self.require_admin,
|
||||
"config_panel_domain": self.config_panel_domain,
|
||||
"show_in_sidebar": self.show_in_sidebar,
|
||||
}
|
||||
|
||||
|
||||
@@ -321,6 +336,7 @@ def async_register_built_in_panel(
|
||||
*,
|
||||
update: bool = False,
|
||||
config_panel_domain: str | None = None,
|
||||
show_in_sidebar: bool | None = None,
|
||||
) -> None:
|
||||
"""Register a built-in panel."""
|
||||
panel = Panel(
|
||||
@@ -331,6 +347,7 @@ def async_register_built_in_panel(
|
||||
config,
|
||||
require_admin,
|
||||
config_panel_domain,
|
||||
show_in_sidebar,
|
||||
)
|
||||
|
||||
panels = hass.data.setdefault(DATA_PANELS, {})
|
||||
@@ -395,6 +412,7 @@ def _frontend_root(dev_repo_path: str | None) -> pathlib.Path:
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the serving of the frontend."""
|
||||
await async_setup_frontend_storage(hass)
|
||||
await async_setup_panel_preferences(hass)
|
||||
websocket_api.async_register_command(hass, websocket_get_icons)
|
||||
websocket_api.async_register_command(hass, websocket_get_panels)
|
||||
websocket_api.async_register_command(hass, websocket_get_themes)
|
||||
@@ -769,12 +787,26 @@ def websocket_get_panels(
|
||||
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Handle get panels command."""
|
||||
|
||||
user_is_admin = connection.user.is_admin
|
||||
panels = {
|
||||
panel_key: panel.to_response()
|
||||
for panel_key, panel in connection.hass.data[DATA_PANELS].items()
|
||||
if user_is_admin or not panel.require_admin
|
||||
}
|
||||
panel_prefs = async_get_panel_preferences(hass)
|
||||
|
||||
panels = {}
|
||||
for panel_key, panel in connection.hass.data[DATA_PANELS].items():
|
||||
if not user_is_admin and panel.require_admin:
|
||||
continue
|
||||
|
||||
panel_response = panel.to_response()
|
||||
|
||||
# Check if user has set a preference for this panel
|
||||
if panel_key in panel_prefs and CONF_SHOW_IN_SIDEBAR in panel_prefs[panel_key]:
|
||||
show_in_sidebar = panel_prefs[panel_key][CONF_SHOW_IN_SIDEBAR]
|
||||
else:
|
||||
# Use integration-defined default
|
||||
show_in_sidebar = panel.show_in_sidebar
|
||||
|
||||
panel_response["show_in_sidebar"] = show_in_sidebar
|
||||
panels[panel_key] = panel_response
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], panels))
|
||||
|
||||
@@ -883,3 +915,4 @@ class PanelResponse(TypedDict):
|
||||
url_path: str
|
||||
require_admin: bool
|
||||
config_panel_domain: str | None
|
||||
show_in_sidebar: bool
|
||||
|
||||
105
homeassistant/components/frontend/panel_preferences.py
Normal file
105
homeassistant/components/frontend/panel_preferences.py
Normal file
@@ -0,0 +1,105 @@
|
||||
"""Panel preferences for the frontend."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import EVENT_PANELS_UPDATED
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import collection, storage
|
||||
from homeassistant.helpers.typing import VolDictType
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
DOMAIN = "frontend"
|
||||
|
||||
CONF_SHOW_IN_SIDEBAR = "show_in_sidebar"
|
||||
|
||||
STORAGE_KEY = f"{DOMAIN}_panel_preferences"
|
||||
STORAGE_VERSION = 1
|
||||
|
||||
DATA_PANEL_PREFERENCES: HassKey[PanelPreferencesCollection] = HassKey(
|
||||
"frontend_panel_preferences"
|
||||
)
|
||||
|
||||
PANEL_PREFERENCE_CREATE_FIELDS: VolDictType = {
|
||||
vol.Required("panel_id"): str,
|
||||
vol.Optional(CONF_SHOW_IN_SIDEBAR): bool,
|
||||
}
|
||||
|
||||
PANEL_PREFERENCE_UPDATE_FIELDS: VolDictType = {
|
||||
vol.Optional(CONF_SHOW_IN_SIDEBAR): bool,
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_panel_preferences(hass: HomeAssistant) -> None:
|
||||
"""Set up panel preferences."""
|
||||
panel_prefs_collection = PanelPreferencesCollection(hass)
|
||||
await panel_prefs_collection.async_load()
|
||||
|
||||
hass.data[DATA_PANEL_PREFERENCES] = panel_prefs_collection
|
||||
|
||||
collection.DictStorageCollectionWebsocket(
|
||||
panel_prefs_collection,
|
||||
"frontend/panel_preferences",
|
||||
"panel",
|
||||
PANEL_PREFERENCE_CREATE_FIELDS,
|
||||
PANEL_PREFERENCE_UPDATE_FIELDS,
|
||||
).async_setup(hass)
|
||||
|
||||
|
||||
class PanelPreferencesCollection(collection.DictStorageCollection):
|
||||
"""Panel preferences collection."""
|
||||
|
||||
CREATE_SCHEMA = vol.Schema(PANEL_PREFERENCE_CREATE_FIELDS)
|
||||
UPDATE_SCHEMA = vol.Schema(PANEL_PREFERENCE_UPDATE_FIELDS)
|
||||
|
||||
def __init__(self, hass: HomeAssistant) -> None:
|
||||
"""Initialize panel preferences collection."""
|
||||
super().__init__(
|
||||
storage.Store(hass, STORAGE_VERSION, STORAGE_KEY),
|
||||
)
|
||||
|
||||
async def _process_create_data(self, data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Validate the config is valid."""
|
||||
return self.CREATE_SCHEMA(data) # type: ignore[no-any-return]
|
||||
|
||||
@callback
|
||||
def _get_suggested_id(self, info: dict[str, Any]) -> str:
|
||||
"""Suggest an ID based on the panel_id."""
|
||||
return str(info["panel_id"])
|
||||
|
||||
async def _update_data(
|
||||
self, item: dict[str, Any], update_data: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""Return a new updated item."""
|
||||
update_data = self.UPDATE_SCHEMA(update_data)
|
||||
updated = {**item, **update_data}
|
||||
# Fire panels updated event so frontend knows to refresh
|
||||
self.hass.bus.async_fire(EVENT_PANELS_UPDATED)
|
||||
return updated
|
||||
|
||||
def _create_item(self, item_id: str, data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Create an item from its validated, serialized representation."""
|
||||
# Fire panels updated event so frontend knows to refresh
|
||||
self.hass.bus.async_fire(EVENT_PANELS_UPDATED)
|
||||
return super()._create_item(item_id, data)
|
||||
|
||||
async def async_delete_item(self, item_id: str) -> None:
|
||||
"""Delete a panel preference."""
|
||||
await super().async_delete_item(item_id)
|
||||
# Fire panels updated event so frontend knows to refresh
|
||||
self.hass.bus.async_fire(EVENT_PANELS_UPDATED)
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_panel_preferences(
|
||||
hass: HomeAssistant,
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""Get panel preferences."""
|
||||
if DATA_PANEL_PREFERENCES not in hass.data:
|
||||
return {}
|
||||
|
||||
collection_obj: PanelPreferencesCollection = hass.data[DATA_PANEL_PREFERENCES]
|
||||
return collection_obj.data
|
||||
@@ -645,6 +645,7 @@ async def test_get_panels(
|
||||
assert msg["result"]["map"]["icon"] == "mdi:tooltip-account"
|
||||
assert msg["result"]["map"]["title"] == "Map"
|
||||
assert msg["result"]["map"]["require_admin"] is True
|
||||
assert msg["result"]["map"]["show_in_sidebar"] is True
|
||||
|
||||
async_remove_panel(hass, "map")
|
||||
|
||||
|
||||
379
tests/components/frontend/test_panel_preferences.py
Normal file
379
tests/components/frontend/test_panel_preferences.py
Normal file
@@ -0,0 +1,379 @@
|
||||
"""Tests for frontend panel preferences."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.frontend import (
|
||||
EVENT_PANELS_UPDATED,
|
||||
async_register_built_in_panel,
|
||||
)
|
||||
from homeassistant.components.frontend.panel_preferences import (
|
||||
DATA_PANEL_PREFERENCES,
|
||||
STORAGE_KEY,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import async_capture_events
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def setup_frontend(hass: HomeAssistant) -> None:
|
||||
"""Set up the frontend integration."""
|
||||
assert await async_setup_component(hass, "frontend", {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_panel_preferences_collection_loaded(hass: HomeAssistant) -> None:
|
||||
"""Test that panel preferences collection is loaded on setup."""
|
||||
assert DATA_PANEL_PREFERENCES in hass.data
|
||||
collection = hass.data[DATA_PANEL_PREFERENCES]
|
||||
assert collection is not None
|
||||
|
||||
|
||||
async def test_create_panel_preference(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test creating a panel preference."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Register a test panel
|
||||
async_register_built_in_panel(
|
||||
hass,
|
||||
"test_panel",
|
||||
sidebar_title="Test Panel",
|
||||
sidebar_icon="mdi:test",
|
||||
)
|
||||
|
||||
# Create a panel preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["success"]
|
||||
assert msg["result"]["panel_id"] == "test_panel"
|
||||
assert msg["result"]["show_in_sidebar"] is False
|
||||
|
||||
|
||||
async def test_create_panel_preference_without_field_uses_panel_auto_default(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test creating preference without field uses panel's auto-determined default."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Register a panel with title (auto show_in_sidebar=True)
|
||||
async_register_built_in_panel(
|
||||
hass,
|
||||
"test_panel_auto_true",
|
||||
sidebar_title="Test Panel",
|
||||
sidebar_icon="mdi:test",
|
||||
)
|
||||
|
||||
# Create a panel preference without specifying show_in_sidebar
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel_auto_true",
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["success"]
|
||||
assert msg["result"]["panel_id"] == "test_panel_auto_true"
|
||||
# When not specified, show_in_sidebar should not be in the preference
|
||||
assert "show_in_sidebar" not in msg["result"]
|
||||
|
||||
# Get panels - should use panel's auto-determined default (True)
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["test_panel_auto_true"]["show_in_sidebar"] is True
|
||||
|
||||
|
||||
async def test_update_panel_preference(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test updating a panel preference."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Create a panel preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel",
|
||||
"show_in_sidebar": True,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
item_id = msg["result"]["id"]
|
||||
|
||||
# Update the preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/update",
|
||||
"panel_id": item_id,
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["success"]
|
||||
assert msg["result"]["show_in_sidebar"] is False
|
||||
|
||||
|
||||
async def test_list_panel_preferences(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test listing panel preferences."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Create two panel preferences
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "panel_1",
|
||||
"show_in_sidebar": True,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "panel_2",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
|
||||
# List all preferences
|
||||
await client.send_json_auto_id({"type": "frontend/panel_preferences/list"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["success"]
|
||||
assert len(msg["result"]) == 2
|
||||
panel_ids = {item["panel_id"] for item in msg["result"]}
|
||||
assert panel_ids == {"panel_1", "panel_2"}
|
||||
|
||||
|
||||
async def test_delete_panel_preference(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test deleting a panel preference."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Create a panel preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
item_id = msg["result"]["id"]
|
||||
|
||||
# Delete the preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/delete",
|
||||
"panel_id": item_id,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
|
||||
# Verify it's deleted
|
||||
await client.send_json_auto_id({"type": "frontend/panel_preferences/list"})
|
||||
msg = await client.receive_json()
|
||||
assert len(msg["result"]) == 0
|
||||
|
||||
|
||||
async def test_get_panels_respects_preferences(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test that get_panels respects panel preferences."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Register a panel with sidebar info
|
||||
async_register_built_in_panel(
|
||||
hass,
|
||||
"test_panel",
|
||||
sidebar_title="Test Panel",
|
||||
sidebar_icon="mdi:test",
|
||||
)
|
||||
|
||||
# Get panels - should show in sidebar by default
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["test_panel"]["title"] == "Test Panel"
|
||||
assert msg["result"]["test_panel"]["icon"] == "mdi:test"
|
||||
assert msg["result"]["test_panel"]["show_in_sidebar"] is True
|
||||
|
||||
# Create preference to hide from sidebar
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
|
||||
# Get panels again - show_in_sidebar should be False
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["test_panel"]["title"] == "Test Panel"
|
||||
assert msg["result"]["test_panel"]["icon"] == "mdi:test"
|
||||
assert msg["result"]["test_panel"]["show_in_sidebar"] is False
|
||||
|
||||
|
||||
async def test_get_panels_no_sidebar_by_default(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test that panels without title are not shown in sidebar."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Register a panel WITHOUT sidebar info
|
||||
async_register_built_in_panel(hass, "test_panel_no_sidebar")
|
||||
|
||||
# Get panels - should not show in sidebar by default
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["test_panel_no_sidebar"]["title"] is None
|
||||
assert msg["result"]["test_panel_no_sidebar"]["icon"] is None
|
||||
assert msg["result"]["test_panel_no_sidebar"]["show_in_sidebar"] is False
|
||||
|
||||
|
||||
async def test_get_panels_preference_overrides_default(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test that user preference can override default sidebar visibility."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Register a panel WITHOUT sidebar info (default show_in_sidebar=False)
|
||||
async_register_built_in_panel(hass, "hidden_panel")
|
||||
|
||||
# Get panels - should not show in sidebar by default
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["hidden_panel"]["show_in_sidebar"] is False
|
||||
|
||||
# Create preference to show it (even though it has no sidebar info by default)
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "hidden_panel",
|
||||
"show_in_sidebar": True,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
|
||||
# Get panels - preference is true, so show_in_sidebar should be True
|
||||
# (even though panel has no sidebar info)
|
||||
await client.send_json_auto_id({"type": "get_panels"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"]["hidden_panel"]["title"] is None
|
||||
assert msg["result"]["hidden_panel"]["icon"] is None
|
||||
assert msg["result"]["hidden_panel"]["show_in_sidebar"] is True
|
||||
|
||||
|
||||
async def test_panel_preferences_fire_update_event(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test that panel preference changes fire update events."""
|
||||
client = await hass_ws_client(hass)
|
||||
events = async_capture_events(hass, EVENT_PANELS_UPDATED)
|
||||
|
||||
# Create a preference - should fire event
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "test_panel",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
item_id = msg["result"]["id"]
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 1
|
||||
|
||||
# Update a preference - should fire event
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/update",
|
||||
"panel_id": item_id,
|
||||
"show_in_sidebar": True,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 2
|
||||
|
||||
# Delete a preference - should fire event
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/delete",
|
||||
"panel_id": item_id,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 3
|
||||
|
||||
|
||||
async def test_panel_preferences_storage_persistence(
|
||||
hass: HomeAssistant,
|
||||
hass_storage: dict[str, Any],
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test that panel preferences are persisted to storage."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Create a panel preference
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "frontend/panel_preferences/create",
|
||||
"panel_id": "persisted_panel",
|
||||
"show_in_sidebar": False,
|
||||
}
|
||||
)
|
||||
await client.receive_json()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Manually flush the storage
|
||||
collection_obj = hass.data[DATA_PANEL_PREFERENCES]
|
||||
await collection_obj.store.async_save(collection_obj._data_to_save())
|
||||
|
||||
# Check storage
|
||||
assert STORAGE_KEY in hass_storage
|
||||
stored_data = hass_storage[STORAGE_KEY]
|
||||
assert stored_data["version"] == 1
|
||||
items = stored_data["data"]["items"]
|
||||
# Items is stored as a list
|
||||
assert len(items) == 1
|
||||
item = items[0] if isinstance(items, list) else list(items.values())[0]
|
||||
assert item["panel_id"] == "persisted_panel"
|
||||
assert item["show_in_sidebar"] is False
|
||||
@@ -252,6 +252,7 @@ async def test_setup_api_panel(
|
||||
"component_name": "custom",
|
||||
"icon": None,
|
||||
"title": None,
|
||||
"show_in_sidebar": False,
|
||||
"url_path": "hassio",
|
||||
"require_admin": True,
|
||||
"config_panel_domain": None,
|
||||
|
||||
Reference in New Issue
Block a user