Migrate wolflink config_entry unique_id to string (#125653)

* Migrate wolflink config_entry unique_id to string

* Move CONFIG to const

* isinstance

* Migrate identifiers

* Use async_migrate_entry
This commit is contained in:
epenet 2024-09-10 15:16:26 +02:00 committed by GitHub
parent 745a05d984
commit 2f38731f62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 109 additions and 11 deletions

View file

@ -11,6 +11,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -30,6 +31,7 @@ PLATFORMS = [Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Wolf SmartSet Service from a config entry."""
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
device_name = entry.data[DEVICE_NAME]
@ -125,6 +127,32 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old entry."""
# convert unique_id to string
if entry.version == 1 and entry.minor_version == 1:
if isinstance(entry.unique_id, int):
hass.config_entries.async_update_entry(
entry, unique_id=str(entry.unique_id)
)
device_registry = dr.async_get(hass)
for device in dr.async_entries_for_config_entry(
device_registry, entry.entry_id
):
new_identifiers = set()
for identifier in device.identifiers:
if identifier[0] == DOMAIN:
new_identifiers.add((DOMAIN, str(identifier[1])))
else:
new_identifiers.add(identifier)
device_registry.async_update_device(
device.id, new_identifiers=new_identifiers
)
hass.config_entries.async_update_entry(entry, minor_version=2)
return True
async def fetch_parameters(client: WolfClient, gateway_id: int, device_id: int):
"""Fetch all available parameters with usage of WolfClient.

View file

@ -24,6 +24,7 @@ class WolfLinkConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Wolf SmartSet Service."""
VERSION = 1
MINOR_VERSION = 2
def __init__(self) -> None:
"""Initialize with empty username and password."""
@ -66,7 +67,7 @@ class WolfLinkConfigFlow(ConfigFlow, domain=DOMAIN):
device for device in self.fetched_systems if device.name == device_name
]
device_id = system[0].id
await self.async_set_unique_id(device_id)
await self.async_set_unique_id(str(device_id))
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[DEVICE_NAME],

View file

@ -63,7 +63,7 @@ class WolfLinkSensor(CoordinatorEntity, SensorEntity):
self._attr_unique_id = f"{device_id}:{wolf_object.parameter_id}"
self._state = None
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device_id)},
identifiers={(DOMAIN, str(device_id))},
configuration_url="https://www.wolf-smartset.com/",
manufacturer=MANUFACTURER,
)

View file

@ -0,0 +1,16 @@
"""Constants for the Wolf SmartSet Service tests."""
from homeassistant.components.wolflink.const import (
DEVICE_GATEWAY,
DEVICE_ID,
DEVICE_NAME,
)
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
CONFIG = {
DEVICE_NAME: "test-device",
DEVICE_ID: 1234,
DEVICE_GATEWAY: 5678,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
}

View file

@ -17,15 +17,9 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
from .const import CONFIG
CONFIG = {
DEVICE_NAME: "test-device",
DEVICE_ID: 1234,
DEVICE_GATEWAY: 5678,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
}
from tests.common import MockConfigEntry
INPUT_CONFIG = {
CONF_USERNAME: CONFIG[CONF_USERNAME],
@ -134,7 +128,7 @@ async def test_already_configured_error(hass: HomeAssistant) -> None:
patch("homeassistant.components.wolflink.async_setup_entry", return_value=True),
):
MockConfigEntry(
domain=DOMAIN, unique_id=CONFIG[DEVICE_ID], data=CONFIG
domain=DOMAIN, unique_id=str(CONFIG[DEVICE_ID]), data=CONFIG
).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(

View file

@ -0,0 +1,59 @@
"""Test the Wolf SmartSet Service."""
from unittest.mock import patch
from httpx import RequestError
from homeassistant.components.wolflink.const import DEVICE_ID, DOMAIN, MANUFACTURER
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from .const import CONFIG
from tests.common import MockConfigEntry
async def test_unique_id_migration(
hass: HomeAssistant, device_registry: dr.DeviceRegistry
) -> None:
"""Test already configured while creating entry."""
config_entry = MockConfigEntry(
domain=DOMAIN, unique_id=CONFIG[DEVICE_ID], data=CONFIG
)
config_entry.add_to_hass(hass)
device_id = device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
identifiers={(DOMAIN, CONFIG[DEVICE_ID])},
configuration_url="https://www.wolf-smartset.com/",
manufacturer=MANUFACTURER,
).id
assert config_entry.version == 1
assert config_entry.minor_version == 1
assert config_entry.unique_id == 1234
assert (
hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, 1234)
is config_entry
)
assert hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, "1234") is None
assert device_registry.async_get(device_id).identifiers == {(DOMAIN, 1234)}
with (
patch(
"homeassistant.components.wolflink.fetch_parameters",
side_effect=RequestError("Unable to fetch parameters"),
),
):
await hass.config_entries.async_setup(config_entry.entry_id)
assert config_entry.version == 1
assert config_entry.minor_version == 2
assert config_entry.unique_id == "1234"
assert (
hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, "1234")
is config_entry
)
assert hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, 1234) is None
assert device_registry.async_get(device_id).identifiers == {(DOMAIN, "1234")}