diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 4d8472da9a2..c0262f42f6c 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -6,7 +6,7 @@ from typing import Any import voluptuous as vol -from homeassistant.components import frontend, websocket_api +from homeassistant.components import frontend, onboarding, websocket_api from homeassistant.config import ( async_hass_config_yaml, async_process_component_and_handle_errors, @@ -17,6 +17,7 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import collection, config_validation as cv from homeassistant.helpers.frame import report_usage from homeassistant.helpers.service import async_register_admin_service +from homeassistant.helpers.translation import async_get_translations from homeassistant.helpers.typing import ConfigType from homeassistant.loader import async_get_integration from homeassistant.util import slugify @@ -282,6 +283,13 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: STORAGE_DASHBOARD_UPDATE_FIELDS, ).async_setup(hass) + def create_map_dashboard() -> None: + """Create a map dashboard.""" + hass.async_create_task(_create_map_dashboard(hass, dashboards_collection)) + + if not onboarding.async_is_onboarded(hass): + onboarding.async_add_listener(hass, create_map_dashboard) + return True @@ -323,3 +331,25 @@ def _register_panel( kwargs["sidebar_icon"] = config.get(CONF_ICON, DEFAULT_ICON) frontend.async_register_built_in_panel(hass, DOMAIN, **kwargs) + + +async def _create_map_dashboard( + hass: HomeAssistant, dashboards_collection: dashboard.DashboardsCollection +) -> None: + """Create a map dashboard.""" + translations = await async_get_translations( + hass, hass.config.language, "dashboard", {onboarding.DOMAIN} + ) + title = translations["component.onboarding.dashboard.map.title"] + + await dashboards_collection.async_create_item( + { + CONF_ALLOW_SINGLE_WORD: True, + CONF_ICON: "mdi:map", + CONF_TITLE: title, + CONF_URL_PATH: "map", + } + ) + + map_store = hass.data[LOVELACE_DATA].dashboards["map"] + await map_store.async_save({"strategy": {"type": "map"}}) diff --git a/tests/components/lovelace/test_init.py b/tests/components/lovelace/test_init.py index f35f7369f93..4c7cc96504b 100644 --- a/tests/components/lovelace/test_init.py +++ b/tests/components/lovelace/test_init.py @@ -13,6 +13,16 @@ from homeassistant.setup import async_setup_component from tests.typing import WebSocketGenerator +@pytest.fixture +def mock_onboarding_not_done() -> Generator[MagicMock]: + """Mock that Home Assistant is currently onboarding.""" + with patch( + "homeassistant.components.onboarding.async_is_onboarded", + return_value=False, + ) as mock_onboarding: + yield mock_onboarding + + @pytest.fixture def mock_onboarding_done() -> Generator[MagicMock]: """Mock that Home Assistant is currently onboarding.""" @@ -23,6 +33,15 @@ def mock_onboarding_done() -> Generator[MagicMock]: yield mock_onboarding +@pytest.fixture +def mock_add_onboarding_listener() -> Generator[MagicMock]: + """Mock that Home Assistant is currently onboarding.""" + with patch( + "homeassistant.components.onboarding.async_add_listener", + ) as mock_add_onboarding_listener: + yield mock_add_onboarding_listener + + async def test_create_dashboards_when_onboarded( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, @@ -41,6 +60,45 @@ async def test_create_dashboards_when_onboarded( assert response["result"] == [] +async def test_create_dashboards_when_not_onboarded( + hass: HomeAssistant, + hass_ws_client: WebSocketGenerator, + hass_storage: dict[str, Any], + mock_add_onboarding_listener, + mock_onboarding_not_done, +) -> None: + """Test we automatically create dashboards when not onboarded.""" + client = await hass_ws_client(hass) + + assert await async_setup_component(hass, "lovelace", {}) + + # Call onboarding listener + mock_add_onboarding_listener.mock_calls[0][1][1]() + await hass.async_block_till_done() + + # List dashboards + await client.send_json_auto_id({"type": "lovelace/dashboards/list"}) + response = await client.receive_json() + assert response["success"] + assert response["result"] == [ + { + "icon": "mdi:map", + "id": "map", + "mode": "storage", + "require_admin": False, + "show_in_sidebar": True, + "title": "Map", + "url_path": "map", + } + ] + + # List map dashboard config + await client.send_json_auto_id({"type": "lovelace/config", "url_path": "map"}) + response = await client.receive_json() + assert response["success"] + assert response["result"] == {"strategy": {"type": "map"}} + + @pytest.mark.parametrize("integration_frame_path", ["custom_components/my_integration"]) @pytest.mark.usefixtures("mock_integration_frame") async def test_hass_data_compatibility(