Deprecate the panel_iframe integration (#113410)

* Deprecate the panel_iframe integration

* Address review comments

* Customize issue text

* Update test
This commit is contained in:
Erik Montnemery 2024-03-22 02:48:52 +01:00 committed by GitHub
parent 5b9f40b0f0
commit 79f2eaaf41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 183 additions and 71 deletions

View file

@ -2,10 +2,13 @@
import voluptuous as vol import voluptuous as vol
from homeassistant.components import frontend from homeassistant.components import lovelace
from homeassistant.components.lovelace import dashboard
from homeassistant.const import CONF_ICON, CONF_URL from homeassistant.const import CONF_ICON, CONF_URL
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
DOMAIN = "panel_iframe" DOMAIN = "panel_iframe"
@ -37,18 +40,59 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
STORAGE_KEY = DOMAIN
STORAGE_VERSION_MAJOR = 1
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the iFrame frontend panels.""" """Set up the iFrame frontend panels."""
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml",
breaks_in_ha_version="2024.10.0",
is_fixable=False,
is_persistent=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "iframe Panel",
},
)
store: Store[dict[str, bool]] = Store(
hass,
STORAGE_VERSION_MAJOR,
STORAGE_KEY,
)
data = await store.async_load()
if data:
return True
dashboards_collection: dashboard.DashboardsCollection = hass.data[lovelace.DOMAIN][
"dashboards_collection"
]
for url_path, info in config[DOMAIN].items(): for url_path, info in config[DOMAIN].items():
frontend.async_register_built_in_panel( dashboard_create_data = {
hass, lovelace.CONF_ALLOW_SINGLE_WORD: True,
"iframe", lovelace.CONF_URL_PATH: url_path,
info.get(CONF_TITLE), }
info.get(CONF_ICON), for key in (CONF_ICON, CONF_REQUIRE_ADMIN, CONF_TITLE):
url_path, if key in info:
{"url": info[CONF_URL]}, dashboard_create_data[key] = info[key]
require_admin=info[CONF_REQUIRE_ADMIN],
await dashboards_collection.async_create_item(dashboard_create_data)
dashboard_store: dashboard.LovelaceStorage = hass.data[lovelace.DOMAIN][
"dashboards"
][url_path]
await dashboard_store.async_save(
{"strategy": {"type": "iframe", "url": info[CONF_URL]}}
) )
await store.async_save({"migrated": True})
return True return True

View file

@ -2,7 +2,7 @@
"domain": "panel_iframe", "domain": "panel_iframe",
"name": "iframe Panel", "name": "iframe Panel",
"codeowners": ["@home-assistant/frontend"], "codeowners": ["@home-assistant/frontend"],
"dependencies": ["frontend"], "dependencies": ["frontend", "lovelace"],
"documentation": "https://www.home-assistant.io/integrations/panel_iframe", "documentation": "https://www.home-assistant.io/integrations/panel_iframe",
"quality_scale": "internal" "quality_scale": "internal"
} }

View file

@ -0,0 +1,8 @@
{
"issues": {
"deprecated_yaml": {
"title": "The {integration_title} YAML configuration is being removed",
"description": "Configuring {integration_title} using YAML is being removed.\n\nYour existing YAML configuration has been imported into the UI automatically as a regular dashboard.\n\nRemove the `{domain}` configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
}
}
}

View file

@ -1,11 +1,37 @@
"""The tests for the panel_iframe component.""" """The tests for the panel_iframe component."""
from typing import Any
import pytest import pytest
from homeassistant.components import frontend from homeassistant.components.panel_iframe import DOMAIN
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from tests.typing import WebSocketGenerator
TEST_CONFIG = {
"router": {
"icon": "mdi:network-wireless",
"title": "Router",
"url": "http://192.168.1.1",
"require_admin": True,
},
"weather": {
"icon": "mdi:weather",
"title": "Weather",
"url": "https://www.wunderground.com/us/ca/san-diego",
"require_admin": True,
},
"api": {"icon": "mdi:weather", "title": "Api", "url": "/api"},
"ftp": {
"icon": "mdi:weather",
"title": "FTP",
"url": "ftp://some/ftp",
},
}
@pytest.mark.parametrize( @pytest.mark.parametrize(
"config_to_try", "config_to_try",
@ -21,73 +47,107 @@ async def test_wrong_config(hass: HomeAssistant, config_to_try) -> None:
) )
async def test_correct_config(hass: HomeAssistant) -> None: async def test_import_config(
"""Test correct config.""" hass: HomeAssistant,
hass_storage: dict[str, Any],
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test import config."""
client = await hass_ws_client(hass)
assert await async_setup_component( assert await async_setup_component(
hass, hass,
"panel_iframe", "panel_iframe",
{ {"panel_iframe": TEST_CONFIG},
"panel_iframe": {
"router": {
"icon": "mdi:network-wireless",
"title": "Router",
"url": "http://192.168.1.1",
"require_admin": True,
},
"weather": {
"icon": "mdi:weather",
"title": "Weather",
"url": "https://www.wunderground.com/us/ca/san-diego",
"require_admin": True,
},
"api": {"icon": "mdi:weather", "title": "Api", "url": "/api"},
"ftp": {
"icon": "mdi:weather",
"title": "FTP",
"url": "ftp://some/ftp",
},
}
},
) )
panels = hass.data[frontend.DATA_PANELS] # 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:network-wireless",
"id": "router",
"mode": "storage",
"require_admin": True,
"show_in_sidebar": True,
"title": "Router",
"url_path": "router",
},
{
"icon": "mdi:weather",
"id": "weather",
"mode": "storage",
"require_admin": True,
"show_in_sidebar": True,
"title": "Weather",
"url_path": "weather",
},
{
"icon": "mdi:weather",
"id": "api",
"mode": "storage",
"require_admin": False,
"show_in_sidebar": True,
"title": "Api",
"url_path": "api",
},
{
"icon": "mdi:weather",
"id": "ftp",
"mode": "storage",
"require_admin": False,
"show_in_sidebar": True,
"title": "FTP",
"url_path": "ftp",
},
]
assert panels.get("router").to_response() == { for url_path in ["api", "ftp", "router", "weather"]:
"component_name": "iframe", await client.send_json_auto_id(
"config": {"url": "http://192.168.1.1"}, {"type": "lovelace/config", "url_path": url_path}
"config_panel_domain": None, )
"icon": "mdi:network-wireless", response = await client.receive_json()
"title": "Router", assert response["success"]
"url_path": "router", assert response["result"] == {
"require_admin": True, "strategy": {"type": "iframe", "url": TEST_CONFIG[url_path]["url"]}
}
assert hass_storage[DOMAIN]["data"] == {"migrated": True}
async def test_import_config_once(
hass: HomeAssistant,
hass_storage: dict[str, Any],
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test import config only happens once."""
client = await hass_ws_client(hass)
hass_storage[DOMAIN] = {
"version": 1,
"minor_version": 1,
"key": "map",
"data": {"migrated": True},
} }
assert panels.get("weather").to_response() == { assert await async_setup_component(
"component_name": "iframe", hass,
"config": {"url": "https://www.wunderground.com/us/ca/san-diego"}, "panel_iframe",
"config_panel_domain": None, {"panel_iframe": TEST_CONFIG},
"icon": "mdi:weather", )
"title": "Weather",
"url_path": "weather",
"require_admin": True,
}
assert panels.get("api").to_response() == { # List dashboards
"component_name": "iframe", await client.send_json_auto_id({"type": "lovelace/dashboards/list"})
"config": {"url": "/api"}, response = await client.receive_json()
"config_panel_domain": None, assert response["success"]
"icon": "mdi:weather", assert response["result"] == []
"title": "Api",
"url_path": "api",
"require_admin": False,
}
assert panels.get("ftp").to_response() == {
"component_name": "iframe", async def test_create_issue_when_manually_configured(hass: HomeAssistant) -> None:
"config": {"url": "ftp://some/ftp"}, """Test creating issue registry issues."""
"config_panel_domain": None, assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
"icon": "mdi:weather",
"title": "FTP", issue_registry = ir.async_get(hass)
"url_path": "ftp", assert issue_registry.async_get_issue(DOMAIN, "deprecated_yaml")
"require_admin": False,
}