Skip to content

Commit 74b7315

Browse files
authored
Improve config entry migration for edge cases in Alexa Devices (#151788)
1 parent c361c32 commit 74b7315

File tree

6 files changed

+102
-15
lines changed

6 files changed

+102
-15
lines changed

homeassistant/components/alexa_devices/__init__.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from homeassistant.helpers import aiohttp_client, config_validation as cv
66
from homeassistant.helpers.typing import ConfigType
77

8-
from .const import _LOGGER, CONF_LOGIN_DATA, COUNTRY_DOMAINS, DOMAIN
8+
from .const import _LOGGER, CONF_LOGIN_DATA, CONF_SITE, COUNTRY_DOMAINS, DOMAIN
99
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
1010
from .services import async_setup_services
1111

@@ -42,7 +42,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bo
4242

4343
async def async_migrate_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bool:
4444
"""Migrate old entry."""
45-
if entry.version == 1 and entry.minor_version == 1:
45+
46+
if entry.version == 1 and entry.minor_version < 3:
47+
if CONF_SITE in entry.data:
48+
# Site in data (wrong place), just move to login data
49+
new_data = entry.data.copy()
50+
new_data[CONF_LOGIN_DATA][CONF_SITE] = new_data[CONF_SITE]
51+
new_data.pop(CONF_SITE)
52+
hass.config_entries.async_update_entry(
53+
entry, data=new_data, version=1, minor_version=3
54+
)
55+
return True
56+
57+
if CONF_SITE in entry.data[CONF_LOGIN_DATA]:
58+
# Site is there, just update version to avoid future migrations
59+
hass.config_entries.async_update_entry(entry, version=1, minor_version=3)
60+
return True
61+
4662
_LOGGER.debug(
4763
"Migrating from version %s.%s", entry.version, entry.minor_version
4864
)
@@ -53,10 +69,10 @@ async def async_migrate_entry(hass: HomeAssistant, entry: AmazonConfigEntry) ->
5369

5470
# Add site to login data
5571
new_data = entry.data.copy()
56-
new_data[CONF_LOGIN_DATA]["site"] = f"https://www.amazon.{domain}"
72+
new_data[CONF_LOGIN_DATA][CONF_SITE] = f"https://www.amazon.{domain}"
5773

5874
hass.config_entries.async_update_entry(
59-
entry, data=new_data, version=1, minor_version=2
75+
entry, data=new_data, version=1, minor_version=3
6076
)
6177

6278
_LOGGER.info(

homeassistant/components/alexa_devices/config_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):
5252
"""Handle a config flow for Alexa Devices."""
5353

5454
VERSION = 1
55-
MINOR_VERSION = 2
55+
MINOR_VERSION = 3
5656

5757
async def async_step_user(
5858
self, user_input: dict[str, Any] | None = None

homeassistant/components/alexa_devices/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
DOMAIN = "alexa_devices"
88
CONF_LOGIN_DATA = "login_data"
9+
CONF_SITE = "site"
910

1011
DEFAULT_DOMAIN = "com"
1112
COUNTRY_DOMAINS = {

tests/components/alexa_devices/conftest.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from aioamazondevices.const import DEVICE_TYPE_TO_MODEL
88
import pytest
99

10-
from homeassistant.components.alexa_devices.const import CONF_LOGIN_DATA, DOMAIN
10+
from homeassistant.components.alexa_devices.const import (
11+
CONF_LOGIN_DATA,
12+
CONF_SITE,
13+
DOMAIN,
14+
)
1115
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
1216

1317
from .const import TEST_PASSWORD, TEST_SERIAL_NUMBER, TEST_USERNAME
@@ -81,9 +85,12 @@ def mock_config_entry() -> MockConfigEntry:
8185
data={
8286
CONF_USERNAME: TEST_USERNAME,
8387
CONF_PASSWORD: TEST_PASSWORD,
84-
CONF_LOGIN_DATA: {"session": "test-session"},
88+
CONF_LOGIN_DATA: {
89+
"session": "test-session",
90+
CONF_SITE: "https://www.amazon.com",
91+
},
8592
},
8693
unique_id=TEST_USERNAME,
8794
version=1,
88-
minor_version=2,
95+
minor_version=3,
8996
)

tests/components/alexa_devices/snapshots/test_diagnostics.ambr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
'data': dict({
5050
'login_data': dict({
5151
'session': 'test-session',
52+
'site': 'https://www.amazon.com',
5253
}),
5354
'password': '**REDACTED**',
5455
'username': '**REDACTED**',
@@ -57,7 +58,7 @@
5758
'discovery_keys': dict({
5859
}),
5960
'domain': 'alexa_devices',
60-
'minor_version': 2,
61+
'minor_version': 3,
6162
'options': dict({
6263
}),
6364
'pref_disable_new_entities': False,

tests/components/alexa_devices/test_init.py

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22

33
from unittest.mock import AsyncMock
44

5+
import pytest
56
from syrupy.assertion import SnapshotAssertion
67

7-
from homeassistant.components.alexa_devices.const import CONF_LOGIN_DATA, DOMAIN
8+
from homeassistant.components.alexa_devices.const import (
9+
CONF_LOGIN_DATA,
10+
CONF_SITE,
11+
DOMAIN,
12+
)
813
from homeassistant.config_entries import ConfigEntryState
914
from homeassistant.const import CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
1015
from homeassistant.core import HomeAssistant
@@ -32,30 +37,87 @@ async def test_device_info(
3237
assert device_entry == snapshot
3338

3439

40+
@pytest.mark.parametrize(
41+
("minor_version", "extra_data"),
42+
[
43+
# Standard migration case
44+
(
45+
1,
46+
{
47+
CONF_COUNTRY: "US",
48+
CONF_LOGIN_DATA: {
49+
"session": "test-session",
50+
},
51+
},
52+
),
53+
# Edge case #1: no country, site already in login data, minor version 1
54+
(
55+
1,
56+
{
57+
CONF_LOGIN_DATA: {
58+
"session": "test-session",
59+
CONF_SITE: "https://www.amazon.com",
60+
},
61+
},
62+
),
63+
# Edge case #2: no country, site in data (wrong place), minor version 1
64+
(
65+
1,
66+
{
67+
CONF_SITE: "https://www.amazon.com",
68+
CONF_LOGIN_DATA: {
69+
"session": "test-session",
70+
},
71+
},
72+
),
73+
# Edge case #3: no country, site already in login data, minor version 2
74+
(
75+
2,
76+
{
77+
CONF_LOGIN_DATA: {
78+
"session": "test-session",
79+
CONF_SITE: "https://www.amazon.com",
80+
},
81+
},
82+
),
83+
# Edge case #4: no country, site in data (wrong place), minor version 2
84+
(
85+
2,
86+
{
87+
CONF_SITE: "https://www.amazon.com",
88+
CONF_LOGIN_DATA: {
89+
"session": "test-session",
90+
},
91+
},
92+
),
93+
],
94+
)
3595
async def test_migrate_entry(
3696
hass: HomeAssistant,
3797
mock_amazon_devices_client: AsyncMock,
3898
mock_config_entry: MockConfigEntry,
99+
minor_version: int,
100+
extra_data: dict[str, str],
39101
) -> None:
40102
"""Test successful migration of entry data."""
103+
41104
config_entry = MockConfigEntry(
42105
domain=DOMAIN,
43106
title="Amazon Test Account",
44107
data={
45-
CONF_COUNTRY: "US", # country should be in COUNTRY_DOMAINS exceptions
46108
CONF_USERNAME: TEST_USERNAME,
47109
CONF_PASSWORD: TEST_PASSWORD,
48-
CONF_LOGIN_DATA: {"session": "test-session"},
110+
**(extra_data),
49111
},
50112
unique_id=TEST_USERNAME,
51113
version=1,
52-
minor_version=1,
114+
minor_version=minor_version,
53115
)
54116
config_entry.add_to_hass(hass)
55117
await hass.config_entries.async_setup(config_entry.entry_id)
56118
await hass.async_block_till_done()
57119

58120
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
59121
assert config_entry.state is ConfigEntryState.LOADED
60-
assert config_entry.minor_version == 2
61-
assert config_entry.data[CONF_LOGIN_DATA]["site"] == "https://www.amazon.com"
122+
assert config_entry.minor_version == 3
123+
assert config_entry.data[CONF_LOGIN_DATA][CONF_SITE] == "https://www.amazon.com"

0 commit comments

Comments
 (0)