Skip to content

Commit

Permalink
Migrate wolflink config_entry unique_id to string (#125653)
Browse files Browse the repository at this point in the history
* Migrate wolflink config_entry unique_id to string

* Move CONFIG to const

* isinstance

* Migrate identifiers

* Use async_migrate_entry
  • Loading branch information
epenet authored Sep 10, 2024
1 parent 745a05d commit 2f38731
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
28 changes: 28 additions & 0 deletions homeassistant/components/wolflink/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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

Expand All @@ -30,6 +31,7 @@

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]
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/wolflink/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -66,7 +67,7 @@ async def async_step_device(self, user_input=None):
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],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/wolflink/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __init__(self, coordinator, wolf_object: Parameter, device_id) -> None:
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,
)
Expand Down
16 changes: 16 additions & 0 deletions tests/components/wolflink/const.py
Original file line number Diff line number Diff line change
@@ -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",
}
12 changes: 3 additions & 9 deletions tests/components/wolflink/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,9 @@
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],
Expand Down Expand Up @@ -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(
Expand Down
59 changes: 59 additions & 0 deletions tests/components/wolflink/test_init.py
Original file line number Diff line number Diff line change
@@ -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")}

0 comments on commit 2f38731

Please sign in to comment.