Skip to content

Commit

Permalink
Clean up old config migration of Axis config (#85671)
Browse files Browse the repository at this point in the history
* Revert Axis config flow version to 1

* Set up using hass.config_entries.async_setup

* Fix review comment

* Update homeassistant/components/axis/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
  • Loading branch information
Kane610 and MartinHjelmare authored Jan 13, 2023
1 parent 4c2b20d commit 7953c4a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 98 deletions.
38 changes: 6 additions & 32 deletions homeassistant/components/axis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DEVICE, CONF_MAC, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant, callback
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.entity_registry import async_migrate_entries

from .const import DOMAIN as AXIS_DOMAIN, PLATFORMS
from .device import AxisNetworkDevice, get_axis_device
Expand Down Expand Up @@ -50,34 +48,10 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
"""Migrate old entry."""
_LOGGER.debug("Migrating from version %s", config_entry.version)

# Flatten configuration but keep old data if user rollbacks HASS prior to 0.106
if config_entry.version == 1:
unique_id = config_entry.data[CONF_MAC]
data = {**config_entry.data, **config_entry.data[CONF_DEVICE]}
hass.config_entries.async_update_entry(
config_entry, unique_id=unique_id, data=data
)
config_entry.version = 2

# Normalise MAC address of device which also affects entity unique IDs
if config_entry.version == 2 and (old_unique_id := config_entry.unique_id):
new_unique_id = format_mac(old_unique_id)

@callback
def update_unique_id(entity_entry):
"""Update unique ID of entity entry."""
return {
"new_unique_id": entity_entry.unique_id.replace(
old_unique_id, new_unique_id
)
}

if old_unique_id != new_unique_id:
await async_migrate_entries(hass, config_entry.entry_id, update_unique_id)

hass.config_entries.async_update_entry(
config_entry, unique_id=new_unique_id
)
if config_entry.version != 3:
# Home Assistant 2023.2
config_entry.version = 3
hass.config_entries.async_update_entry(config_entry)

_LOGGER.info("Migration to version %s successful", config_entry.version)

Expand Down
6 changes: 4 additions & 2 deletions tests/components/axis/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,15 @@ def mock_default_vapix_requests(respx: respx, host: str = DEFAULT_HOST) -> None:
respx.post(f"http://{host}:80/local/vmd/control.cgi").respond(json=VMD4_RESPONSE)


async def setup_axis_integration(hass, config=ENTRY_CONFIG, options=ENTRY_OPTIONS):
async def setup_axis_integration(
hass, config=ENTRY_CONFIG, options=ENTRY_OPTIONS, entry_version=3
):
"""Create the Axis device."""
config_entry = MockConfigEntry(
domain=AXIS_DOMAIN,
data=deepcopy(config),
options=deepcopy(options),
version=3,
version=entry_version,
unique_id=FORMATTED_MAC,
)
config_entry.add_to_hass(hass)
Expand Down
86 changes: 22 additions & 64 deletions tests/components/axis/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,7 @@

from homeassistant.components import axis
from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.const import (
CONF_DEVICE,
CONF_HOST,
CONF_MAC,
CONF_MODEL,
CONF_NAME,
CONF_PASSWORD,
CONF_PORT,
CONF_USERNAME,
)
from homeassistant.helpers import entity_registry as er
from homeassistant.const import CONF_MAC
from homeassistant.helpers.device_registry import format_mac
from homeassistant.setup import async_setup_component

Expand All @@ -38,9 +27,7 @@ async def test_setup_entry(hass):

async def test_setup_entry_fails(hass):
"""Test successful setup of entry."""
config_entry = MockConfigEntry(
domain=AXIS_DOMAIN, data={CONF_MAC: "0123"}, version=3
)
config_entry = MockConfigEntry(domain=AXIS_DOMAIN, data={CONF_MAC: "0123"})
config_entry.add_to_hass(hass)

mock_device = Mock()
Expand All @@ -66,52 +53,23 @@ async def test_unload_entry(hass):

async def test_migrate_entry(hass):
"""Test successful migration of entry data."""
legacy_config = {
CONF_DEVICE: {
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_PORT: 80,
},
CONF_MAC: "00408C123456",
CONF_MODEL: "model",
CONF_NAME: "name",
}
entry = MockConfigEntry(domain=AXIS_DOMAIN, data=legacy_config)

assert entry.data == legacy_config
assert entry.version == 1
assert not entry.unique_id

# Create entity entry to migrate to new unique ID
registry = er.async_get(hass)
registry.async_get_or_create(
BINARY_SENSOR_DOMAIN,
AXIS_DOMAIN,
"00408C123456-vmd4-0",
suggested_object_id="vmd4",
config_entry=entry,
)

await entry.async_migrate(hass)

assert entry.data == {
CONF_DEVICE: {
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_PORT: 80,
},
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_PORT: 80,
CONF_MAC: "00408C123456",
CONF_MODEL: "model",
CONF_NAME: "name",
}
assert entry.version == 2 # Keep version to support rollbacking
assert entry.unique_id == "00:40:8c:12:34:56"

vmd4_entity = registry.async_get("binary_sensor.vmd4")
assert vmd4_entity.unique_id == "00:40:8c:12:34:56-vmd4-0"
config_entry = MockConfigEntry(domain=AXIS_DOMAIN, version=1)
config_entry.add_to_hass(hass)

assert config_entry.version == 1

mock_device = Mock()
mock_device.async_setup = AsyncMock()
mock_device.async_update_device_registry = AsyncMock()
mock_device.api.vapix.light_control = None
mock_device.api.vapix.params.image_format = None

with patch.object(axis, "get_axis_device"), patch.object(
axis, "AxisNetworkDevice"
) as mock_device_class:
mock_device_class.return_value = mock_device

assert await hass.config_entries.async_setup(config_entry.entry_id)

assert hass.data[AXIS_DOMAIN]
assert config_entry.version == 3

0 comments on commit 7953c4a

Please sign in to comment.