From 7268bcd9be413360a077966e982a1c39c36291af Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 13 Mar 2020 19:55:53 +0100 Subject: [PATCH] Check if panel url used and delay dashboard reg till start (#32771) * Check if panel url used and delay dashboard reg till start * move storage_dashboard_changed * fix tests --- homeassistant/components/frontend/__init__.py | 3 +- homeassistant/components/lovelace/__init__.py | 53 ++++++++++--------- .../components/lovelace/dashboard.py | 5 +- tests/components/frontend/test_init.py | 11 +--- tests/components/lovelace/test_dashboard.py | 8 +++ 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 1e3dea98619..d9a39ce5726 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -276,8 +276,7 @@ async def async_setup(hass, config): hass.http.app.router.register_resource(IndexView(repo_path, hass)) - for panel in ("kiosk", "states", "profile"): - async_register_built_in_panel(hass, panel) + async_register_built_in_panel(hass, "profile") # To smooth transition to new urls, add redirects to new urls of dev tools # Added June 27, 2019. Can be removed in 2021. diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 23e8a14e511..8ed5e1abfbb 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -4,7 +4,7 @@ import logging import voluptuous as vol from homeassistant.components import frontend -from homeassistant.const import CONF_FILENAME +from homeassistant.const import CONF_FILENAME, EVENT_HOMEASSISTANT_START from homeassistant.core import callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import collection, config_validation as cv @@ -127,25 +127,12 @@ async def async_setup(hass, config): # We store a dictionary mapping url_path: config. None is the default. "dashboards": {None: default_config}, "resources": resource_collection, + "yaml_dashboards": config[DOMAIN].get(CONF_DASHBOARDS, {}), } if hass.config.safe_mode: return True - # Process YAML dashboards - for url_path, dashboard_conf in config[DOMAIN].get(CONF_DASHBOARDS, {}).items(): - # For now always mode=yaml - config = dashboard.LovelaceYAML(hass, url_path, dashboard_conf) - hass.data[DOMAIN]["dashboards"][url_path] = config - - try: - _register_panel(hass, url_path, MODE_YAML, dashboard_conf, False) - except ValueError: - _LOGGER.warning("Panel url path %s is not unique", url_path) - - # Process storage dashboards - dashboards_collection = dashboard.DashboardsCollection(hass) - async def storage_dashboard_changed(change_type, item_id, item): """Handle a storage dashboard change.""" url_path = item[CONF_URL_PATH] @@ -180,16 +167,34 @@ async def async_setup(hass, config): except ValueError: _LOGGER.warning("Failed to %s panel %s from storage", change_type, url_path) - dashboards_collection.async_add_listener(storage_dashboard_changed) - await dashboards_collection.async_load() + async def async_setup_dashboards(event): + """Register dashboards on startup.""" + # Process YAML dashboards + for url_path, dashboard_conf in hass.data[DOMAIN]["yaml_dashboards"].items(): + # For now always mode=yaml + config = dashboard.LovelaceYAML(hass, url_path, dashboard_conf) + hass.data[DOMAIN]["dashboards"][url_path] = config - collection.StorageCollectionWebsocket( - dashboards_collection, - "lovelace/dashboards", - "dashboard", - STORAGE_DASHBOARD_CREATE_FIELDS, - STORAGE_DASHBOARD_UPDATE_FIELDS, - ).async_setup(hass, create_list=False) + try: + _register_panel(hass, url_path, MODE_YAML, dashboard_conf, False) + except ValueError: + _LOGGER.warning("Panel url path %s is not unique", url_path) + + # Process storage dashboards + dashboards_collection = dashboard.DashboardsCollection(hass) + + dashboards_collection.async_add_listener(storage_dashboard_changed) + await dashboards_collection.async_load() + + collection.StorageCollectionWebsocket( + dashboards_collection, + "lovelace/dashboards", + "dashboard", + STORAGE_DASHBOARD_CREATE_FIELDS, + STORAGE_DASHBOARD_UPDATE_FIELDS, + ).async_setup(hass, create_list=False) + + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, async_setup_dashboards) return True diff --git a/homeassistant/components/lovelace/dashboard.py b/homeassistant/components/lovelace/dashboard.py index 514f1eb87b6..f32ac2ed1ff 100644 --- a/homeassistant/components/lovelace/dashboard.py +++ b/homeassistant/components/lovelace/dashboard.py @@ -6,6 +6,7 @@ import time import voluptuous as vol +from homeassistant.components.frontend import DATA_PANELS from homeassistant.const import CONF_FILENAME from homeassistant.core import callback from homeassistant.exceptions import HomeAssistantError @@ -231,8 +232,8 @@ class DashboardsCollection(collection.StorageCollection): async def _process_create_data(self, data: dict) -> dict: """Validate the config is valid.""" - if data[CONF_URL_PATH] in self.hass.data[DOMAIN]["dashboards"]: - raise vol.Invalid("Dashboard url path needs to be unique") + if data[CONF_URL_PATH] in self.hass.data[DATA_PANELS]: + raise vol.Invalid("Panel url path needs to be unique") return self.CREATE_SCHEMA(data) diff --git a/tests/components/frontend/test_init.py b/tests/components/frontend/test_init.py index 627bf23341d..36243972fb6 100644 --- a/tests/components/frontend/test_init.py +++ b/tests/components/frontend/test_init.py @@ -106,15 +106,6 @@ async def test_we_cannot_POST_to_root(mock_http_client): assert resp.status == 405 -async def test_states_routes(mock_http_client): - """All served by index.""" - resp = await mock_http_client.get("/states") - assert resp.status == 200 - - resp = await mock_http_client.get("/states/group.existing") - assert resp.status == 200 - - async def test_themes_api(hass, hass_ws_client): """Test that /api/themes returns correct data.""" assert await async_setup_component(hass, "frontend", CONFIG_THEMES) @@ -217,7 +208,7 @@ async def test_missing_themes(hass, hass_ws_client): async def test_extra_urls(mock_http_client_with_urls, mock_onboarded): """Test that extra urls are loaded.""" - resp = await mock_http_client_with_urls.get("/states?latest") + resp = await mock_http_client_with_urls.get("/lovelace?latest") assert resp.status == 200 text = await resp.text() assert text.find('href="https://domain.com/my_extra_url.html"') >= 0 diff --git a/tests/components/lovelace/test_dashboard.py b/tests/components/lovelace/test_dashboard.py index 21a44bc771d..9bfe3da38c9 100644 --- a/tests/components/lovelace/test_dashboard.py +++ b/tests/components/lovelace/test_dashboard.py @@ -5,6 +5,7 @@ import pytest from homeassistant.components import frontend from homeassistant.components.lovelace import const, dashboard +from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.setup import async_setup_component from tests.common import async_capture_events, get_system_health_info @@ -223,6 +224,8 @@ async def test_dashboard_from_yaml(hass, hass_ws_client, url_path): } }, ) + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() assert hass.data[frontend.DATA_PANELS]["test-panel"].config == {"mode": "yaml"} assert hass.data[frontend.DATA_PANELS]["test-panel-no-sidebar"].config == { "mode": "yaml" @@ -306,6 +309,8 @@ async def test_dashboard_from_yaml(hass, hass_ws_client, url_path): async def test_storage_dashboards(hass, hass_ws_client, hass_storage): """Test we load lovelace config from storage.""" assert await async_setup_component(hass, "lovelace", {}) + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() assert hass.data[frontend.DATA_PANELS]["lovelace"].config == {"mode": "storage"} client = await hass_ws_client(hass) @@ -450,6 +455,9 @@ async def test_websocket_list_dashboards(hass, hass_ws_client): }, ) + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() + client = await hass_ws_client(hass) # Create a storage dashboard