Add minor version to config entries (#105479)

This commit is contained in:
Erik Montnemery 2023-12-12 08:44:35 +01:00 committed by GitHub
parent ac656847cb
commit 6908497c3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 198 additions and 31 deletions

View file

@ -205,6 +205,7 @@ class ConfigEntry:
__slots__ = (
"entry_id",
"version",
"minor_version",
"domain",
"title",
"data",
@ -233,7 +234,9 @@ class ConfigEntry:
def __init__(
self,
*,
version: int,
minor_version: int,
domain: str,
title: str,
data: Mapping[str, Any],
@ -252,6 +255,7 @@ class ConfigEntry:
# Version of the configuration.
self.version = version
self.minor_version = minor_version
# Domain the configuration belongs to
self.domain = domain
@ -631,7 +635,8 @@ class ConfigEntry:
while isinstance(handler, functools.partial):
handler = handler.func # type: ignore[unreachable]
if self.version == handler.VERSION:
same_major_version = self.version == handler.VERSION
if same_major_version and self.minor_version == handler.MINOR_VERSION:
return True
if not (integration := self._integration_for_domain):
@ -639,6 +644,8 @@ class ConfigEntry:
component = integration.get_component()
supports_migrate = hasattr(component, "async_migrate_entry")
if not supports_migrate:
if same_major_version:
return True
_LOGGER.error(
"Migration handler not found for entry %s for %s",
self.title,
@ -676,6 +683,7 @@ class ConfigEntry:
return {
"entry_id": self.entry_id,
"version": self.version,
"minor_version": self.minor_version,
"domain": self.domain,
"title": self.title,
"data": dict(self.data),
@ -974,6 +982,7 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager):
entry = ConfigEntry(
version=result["version"],
minor_version=result["minor_version"],
domain=result["handler"],
title=result["title"],
data=result["data"],
@ -1196,6 +1205,7 @@ class ConfigEntries:
config_entry = ConfigEntry(
version=entry["version"],
minor_version=entry.get("minor_version", 1),
domain=domain,
entry_id=entry_id,
data=entry["data"],

View file

@ -94,6 +94,7 @@ class FlowResult(TypedDict, total=False):
handler: Required[str]
last_step: bool | None
menu_options: list[str] | dict[str, str]
minor_version: int
options: Mapping[str, Any]
preview: str | None
progress_action: str
@ -470,6 +471,7 @@ class FlowHandler:
# Set by developer
VERSION = 1
MINOR_VERSION = 1
@property
def source(self) -> str | None:
@ -549,6 +551,7 @@ class FlowHandler:
"""Finish flow."""
flow_result = FlowResult(
version=self.VERSION,
minor_version=self.MINOR_VERSION,
type=FlowResultType.CREATE_ENTRY,
flow_id=self.flow_id,
handler=self.handler,

View file

@ -890,6 +890,7 @@ class MockConfigEntry(config_entries.ConfigEntry):
domain="test",
data=None,
version=1,
minor_version=1,
entry_id=None,
source=config_entries.SOURCE_USER,
title="Mock Title",
@ -910,6 +911,7 @@ class MockConfigEntry(config_entries.ConfigEntry):
"pref_disable_polling": pref_disable_polling,
"options": options,
"version": version,
"minor_version": minor_version,
"title": title,
"unique_id": unique_id,
"disabled_by": disabled_by,

View file

@ -11,6 +11,7 @@
'disabled_by': None,
'domain': 'airly',
'entry_id': '3bd2acb0e4f0476d40865546d0d91921',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -26,6 +26,7 @@
'disabled_by': None,
'domain': 'airnow',
'entry_id': '3bd2acb0e4f0476d40865546d0d91921',
'minor_version': 1,
'options': dict({
'radius': 150,
}),

View file

@ -38,6 +38,7 @@
'disabled_by': None,
'domain': 'airvisual',
'entry_id': '3bd2acb0e4f0476d40865546d0d91921',
'minor_version': 1,
'options': dict({
'show_on_map': True,
}),

View file

@ -93,6 +93,7 @@
'disabled_by': None,
'domain': 'airvisual_pro',
'entry_id': '6a2b3770e53c28dc1eeb2515e906b0ce',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -240,6 +240,7 @@
'disabled_by': None,
'domain': 'airzone',
'entry_id': '6e7a0798c1734ba81d26ced0e690eaec',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -93,6 +93,7 @@
'disabled_by': None,
'domain': 'airzone_cloud',
'entry_id': 'd186e31edb46d64d14b9b2f11f1ebd9f',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -9,6 +9,7 @@
'disabled_by': None,
'domain': 'ambient_station',
'entry_id': '382cf7643f016fd48b3fe52163fe8877',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -41,6 +41,7 @@
'disabled_by': None,
'domain': 'axis',
'entry_id': '676abe5b73621446e6550a2e86ffe3dd',
'minor_version': 1,
'options': dict({
'events': True,
}),

View file

@ -38,6 +38,7 @@
}),
'disabled_by': None,
'domain': 'blink',
'minor_version': 1,
'options': dict({
'scan_interval': 300,
}),

View file

@ -154,6 +154,7 @@ async def test_legacy_subscription_repair_flow(
"handler": DOMAIN,
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(

View file

@ -9,6 +9,7 @@
'disabled_by': None,
'domain': 'co2signal',
'entry_id': '904a74160aa6f335526706bee85dfb83',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -47,6 +47,7 @@
'disabled_by': None,
'domain': 'coinbase',
'entry_id': '080272b77a4f80c41b94d7cdc86fd826',
'minor_version': 1,
'options': dict({
'account_balance_currencies': list([
]),

View file

@ -532,6 +532,7 @@ async def test_create_account(
"description": None,
"description_placeholders": None,
"options": {},
"minor_version": 1,
}
@ -609,6 +610,7 @@ async def test_two_step_flow(
"description": None,
"description_placeholders": None,
"options": {},
"minor_version": 1,
}
@ -942,6 +944,7 @@ async def test_two_step_options_flow(hass: HomeAssistant, client) -> None:
"version": 1,
"description": None,
"description_placeholders": None,
"minor_version": 1,
}

View file

@ -12,6 +12,7 @@
'disabled_by': None,
'domain': 'deconz',
'entry_id': '1',
'minor_version': 1,
'options': dict({
'master': True,
}),

View file

@ -40,6 +40,7 @@
'disabled_by': None,
'domain': 'devolo_home_control',
'entry_id': '123456',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -24,6 +24,7 @@
'disabled_by': None,
'domain': 'devolo_home_network',
'entry_id': '123456',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -14,6 +14,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'elgato',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -25,6 +26,7 @@
'disabled_by': None,
'domain': 'elgato',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -55,6 +57,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'elgato',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -66,6 +69,7 @@
'disabled_by': None,
'domain': 'elgato',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -95,6 +99,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'elgato',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -106,6 +111,7 @@
'disabled_by': None,
'domain': 'elgato',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -11,6 +11,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'energyzero',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -19,6 +20,7 @@
'disabled_by': None,
'domain': 'energyzero',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -15,6 +15,7 @@
'disabled_by': None,
'domain': 'enphase_envoy',
'entry_id': '45a36e55aaddb2007c5f6602e0c38e72',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -12,6 +12,7 @@
'disabled_by': None,
'domain': 'esphome',
'entry_id': '08d821dc059cf4f645cb024d32c8e708',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -8,6 +8,7 @@
'disabled_by': None,
'domain': 'forecast_solar',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
'api_key': 'abcdef12345',
'azimuth': 190,

View file

@ -31,6 +31,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'gardena_bluetooth',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -40,6 +41,7 @@
'disabled_by': None,
'domain': 'gardena_bluetooth',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -238,6 +240,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'gardena_bluetooth',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -247,6 +250,7 @@
'disabled_by': None,
'domain': 'gardena_bluetooth',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -9,6 +9,7 @@
'disabled_by': None,
'domain': 'gios',
'entry_id': '86129426118ae32020417a53712d6eef',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -7,6 +7,7 @@
}),
'disabled_by': None,
'domain': 'google_assistant',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -23,6 +23,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": "guardian",
"title": REDACTED,
"data": {

View file

@ -100,6 +100,7 @@ async def test_supervisor_issue_repair_flow(
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")
@ -195,6 +196,7 @@ async def test_supervisor_issue_repair_flow_with_multiple_suggestions(
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")
@ -309,6 +311,7 @@ async def test_supervisor_issue_repair_flow_with_multiple_suggestions_and_confir
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")
@ -389,6 +392,7 @@ async def test_supervisor_issue_repair_flow_skip_confirmation(
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")
@ -488,6 +492,7 @@ async def test_mount_failed_repair_flow(
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")
@ -599,6 +604,7 @@ async def test_supervisor_issue_docker_config_repair_flow(
"handler": "hassio",
"description": None,
"description_placeholders": None,
"minor_version": 1,
}
assert not issue_registry.async_get_issue(domain="hassio", issue_id="1234")

View file

@ -12,6 +12,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'homewizard',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -21,6 +22,7 @@
'disabled_by': None,
'domain': 'homewizard',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -52,6 +54,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'homewizard',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -61,6 +64,7 @@
'disabled_by': None,
'domain': 'homewizard',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -92,6 +96,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'homewizard',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -101,6 +106,7 @@
'disabled_by': None,
'domain': 'homewizard',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -128,6 +134,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'homewizard',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -137,6 +144,7 @@
'disabled_by': None,
'domain': 'homewizard',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -49,11 +49,12 @@ SCENE_RESPONSE = {
async def test_hue_activate_scene(hass: HomeAssistant, mock_api_v1) -> None:
"""Test successful hue_activate_scene."""
config_entry = config_entries.ConfigEntry(
1,
hue.DOMAIN,
"Mock Title",
{"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
"test",
version=1,
minor_version=1,
domain=hue.DOMAIN,
title="Mock Title",
data={"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
source="test",
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
)
@ -85,11 +86,12 @@ async def test_hue_activate_scene(hass: HomeAssistant, mock_api_v1) -> None:
async def test_hue_activate_scene_transition(hass: HomeAssistant, mock_api_v1) -> None:
"""Test successful hue_activate_scene with transition."""
config_entry = config_entries.ConfigEntry(
1,
hue.DOMAIN,
"Mock Title",
{"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
"test",
version=1,
minor_version=1,
domain=hue.DOMAIN,
title="Mock Title",
data={"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
source="test",
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
)
@ -123,11 +125,12 @@ async def test_hue_activate_scene_group_not_found(
) -> None:
"""Test failed hue_activate_scene due to missing group."""
config_entry = config_entries.ConfigEntry(
1,
hue.DOMAIN,
"Mock Title",
{"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
"test",
version=1,
minor_version=1,
domain=hue.DOMAIN,
title="Mock Title",
data={"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
source="test",
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
)
@ -156,11 +159,12 @@ async def test_hue_activate_scene_scene_not_found(
) -> None:
"""Test failed hue_activate_scene due to missing scene."""
config_entry = config_entries.ConfigEntry(
1,
hue.DOMAIN,
"Mock Title",
{"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
"test",
version=1,
minor_version=1,
domain=hue.DOMAIN,
title="Mock Title",
data={"host": "1.2.3.4", "api_key": "mock-api-key", "api_version": 1},
source="test",
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
)

View file

@ -350,6 +350,7 @@
'disabled_by': None,
'domain': 'iqvia',
'entry_id': '690ac4b7e99855fc5ee7b987a758d5cb',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -229,6 +229,7 @@ async def test_issues_created(
"description_placeholders": None,
"flow_id": flow_id,
"handler": DOMAIN,
"minor_version": 1,
"type": "create_entry",
"version": 1,
}

View file

@ -43,6 +43,7 @@ async def test_entry_diagnostics(
"config_entry": {
"entry_id": "2ab8dd92a62787ddfe213a67e09406bd",
"version": 1,
"minor_version": 1,
"domain": "kostal_plenticore",
"title": "scb",
"data": {"host": "192.168.1.2", "password": REDACTED},

View file

@ -17,6 +17,7 @@
'disabled_by': None,
'domain': 'lacrosse_view',
'entry_id': 'lacrosse_view_test_entry_id',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -588,6 +588,7 @@
}),
'disabled_by': None,
'domain': 'netatmo',
'minor_version': 1,
'options': dict({
'weather_areas': dict({
'Home avg': dict({

View file

@ -9,6 +9,7 @@
'disabled_by': None,
'domain': 'nextdns',
'entry_id': 'd9aa37407ddac7b964a99e86312288d6',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -18,6 +18,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": DOMAIN,
"title": REDACTED,
"data": {"username": REDACTED, "password": REDACTED},

View file

@ -13,6 +13,7 @@
'disabled_by': None,
'domain': 'onvif',
'entry_id': '1',
'minor_version': 1,
'options': dict({
'enable_webhooks': True,
'extra_arguments': '-pred 1',

View file

@ -19,6 +19,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 2,
"minor_version": 1,
"domain": "openuv",
"title": REDACTED,
"data": {

View file

@ -160,6 +160,7 @@ async def test_pairing(hass: HomeAssistant, mock_tv_pairable, mock_setup_entry)
"data": MOCK_CONFIG_PAIRED,
"version": 1,
"options": {},
"minor_version": 1,
}
await hass.async_block_till_done()

View file

@ -25,6 +25,7 @@
'disabled_by': None,
'domain': 'pi_hole',
'entry_id': 'pi_hole_mock_entry',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -44,6 +44,7 @@ MOCK_DATA = {CONF_TOKEN: MOCK_CREDS, "devices": [MOCK_DEVICE]}
MOCK_FLOW_RESULT = {
"version": VERSION,
"minor_version": 1,
"handler": DOMAIN,
"type": data_entry_flow.FlowResultType.CREATE_ENTRY,
"title": "test_ps4",

View file

@ -17,6 +17,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": "purpleair",
"title": REDACTED,
"data": {

View file

@ -19,6 +19,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 2,
"minor_version": 1,
"domain": "rainmachine",
"title": "Mock Title",
"data": {
@ -645,6 +646,7 @@ async def test_entry_diagnostics_failed_controller_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 2,
"minor_version": 1,
"domain": "rainmachine",
"title": "Mock Title",
"data": {

View file

@ -19,6 +19,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 2,
"minor_version": 1,
"domain": "recollect_waste",
"title": REDACTED,
"data": {"place_id": REDACTED, "service_id": TEST_SERVICE_ID},

View file

@ -338,6 +338,7 @@ async def test_fix_issue(
"description_placeholders": None,
"flow_id": flow_id,
"handler": domain,
"minor_version": 1,
"type": "create_entry",
"version": 1,
}

View file

@ -36,6 +36,7 @@
'disabled_by': None,
'domain': 'ridwell',
'entry_id': '11554ec901379b9cc8f5a6c1d11ce978',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -41,6 +41,7 @@ async def test_entry_diagnostics(
"disabled_by": None,
"domain": "samsungtv",
"entry_id": "123456",
"minor_version": 1,
"options": {},
"pref_disable_new_entities": False,
"pref_disable_polling": False,
@ -77,6 +78,7 @@ async def test_entry_diagnostics_encrypted(
"disabled_by": None,
"domain": "samsungtv",
"entry_id": "123456",
"minor_version": 1,
"options": {},
"pref_disable_new_entities": False,
"pref_disable_polling": False,
@ -112,6 +114,7 @@ async def test_entry_diagnostics_encrypte_offline(
"disabled_by": None,
"domain": "samsungtv",
"entry_id": "123456",
"minor_version": 1,
"options": {},
"pref_disable_new_entities": False,
"pref_disable_polling": False,

View file

@ -9,6 +9,7 @@
'disabled_by': None,
'domain': 'screenlogic',
'entry_id': 'screenlogictest',
'minor_version': 1,
'options': dict({
'scan_interval': 30,
}),

View file

@ -17,6 +17,7 @@ async def test_entry_diagnostics(
"entry": {
"entry_id": config_entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": "simplisafe",
"title": REDACTED,
"data": {"token": REDACTED, "username": REDACTED},

View file

@ -130,6 +130,7 @@ async def test_user_form_pin_not_required(
"version": 1,
"data": deepcopy(TEST_CONFIG),
"options": {},
"minor_version": 1,
}
expected["data"][CONF_PIN] = None
@ -316,6 +317,7 @@ async def test_pin_form_success(hass: HomeAssistant, pin_form) -> None:
"version": 1,
"data": TEST_CONFIG,
"options": {},
"minor_version": 1,
}
result["data"][CONF_DEVICE_ID] = TEST_DEVICE_ID
assert result == expected

View file

@ -48,6 +48,7 @@ async def test_diagnostics(
"entry": {
"entry_id": entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": "switcher_kis",
"title": "Mock Title",
"data": {},

View file

@ -15,6 +15,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'twentemilieu',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -27,6 +28,7 @@
'disabled_by': None,
'domain': 'twentemilieu',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -57,6 +59,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'twentemilieu',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -69,6 +72,7 @@
'disabled_by': None,
'domain': 'twentemilieu',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -30,6 +30,7 @@
'disabled_by': None,
'domain': 'twinkly',
'entry_id': '4c8fccf5-e08a-4173-92d5-49bf479252a2',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -930,6 +930,7 @@ async def test_restoring_client(
config_entry = config_entries.ConfigEntry(
version=1,
minor_version=1,
domain=UNIFI_DOMAIN,
title="Mock Title",
data=ENTRY_CONFIG,

View file

@ -129,6 +129,7 @@ async def test_entry_diagnostics(
"disabled_by": None,
"domain": "unifi",
"entry_id": "1",
"minor_version": 1,
"options": {
"allow_bandwidth_sensors": True,
"allow_uptime_sensors": True,

View file

@ -1628,6 +1628,7 @@ async def test_updating_unique_id(
config_entry = config_entries.ConfigEntry(
version=1,
minor_version=1,
domain=UNIFI_DOMAIN,
title="Mock Title",
data=ENTRY_CONFIG,

View file

@ -10,6 +10,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'uptime',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -18,6 +19,7 @@
'disabled_by': None,
'domain': 'uptime',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -4705,6 +4705,7 @@
'disabled_by': None,
'domain': 'vicare',
'entry_id': '1234',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -19,6 +19,7 @@
}),
'disabled_by': None,
'domain': 'watttime',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -44,6 +44,7 @@ async def test_diagnostics(
"entry": {
"entry_id": entry.entry_id,
"version": 1,
"minor_version": 1,
"domain": "webostv",
"title": "fake_webos",
"data": {

View file

@ -12,6 +12,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'whois',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -21,6 +22,7 @@
'disabled_by': None,
'domain': 'whois',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -48,6 +50,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'whois',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -57,6 +60,7 @@
'disabled_by': None,
'domain': 'whois',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -84,6 +88,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'whois',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -93,6 +98,7 @@
'disabled_by': None,
'domain': 'whois',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -120,6 +126,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'whois',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -129,6 +136,7 @@
'disabled_by': None,
'domain': 'whois',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -156,6 +164,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'whois',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -165,6 +174,7 @@
'disabled_by': None,
'domain': 'whois',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -55,6 +55,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'wyoming',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -65,6 +66,7 @@
'disabled_by': None,
'domain': 'wyoming',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -97,6 +99,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'wyoming',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -107,6 +110,7 @@
'disabled_by': None,
'domain': 'wyoming',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
@ -139,6 +143,7 @@
'description_placeholders': None,
'flow_id': <ANY>,
'handler': 'wyoming',
'minor_version': 1,
'options': dict({
}),
'result': ConfigEntrySnapshot({
@ -149,6 +154,7 @@
'disabled_by': None,
'domain': 'wyoming',
'entry_id': <ANY>,
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -6,6 +6,7 @@
'disabled_by': None,
'domain': 'test',
'entry_id': 'mock-entry',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,

View file

@ -913,6 +913,7 @@ async def test_bootstrap_dependencies(
"""Mock the MQTT config flow."""
VERSION = 1
MINOR_VERSION = 1
entry = MockConfigEntry(domain="mqtt", data={"broker": "test-broker"})
entry.add_to_hass(hass)

View file

@ -134,11 +134,15 @@ async def test_call_setup_entry_without_reload_support(hass: HomeAssistant) -> N
assert not entry.supports_unload
async def test_call_async_migrate_entry(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(("major_version", "minor_version"), [(2, 1), (1, 2), (2, 2)])
async def test_call_async_migrate_entry(
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test we call <component>.async_migrate_entry when version mismatch."""
entry = MockConfigEntry(domain="comp")
assert not entry.supports_unload
entry.version = 2
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
mock_migrate_entry = AsyncMock(return_value=True)
@ -164,10 +168,14 @@ async def test_call_async_migrate_entry(hass: HomeAssistant) -> None:
assert entry.supports_unload
async def test_call_async_migrate_entry_failure_false(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(("major_version", "minor_version"), [(2, 1), (1, 2), (2, 2)])
async def test_call_async_migrate_entry_failure_false(
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test migration fails if returns false."""
entry = MockConfigEntry(domain="comp")
entry.version = 2
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
assert not entry.supports_unload
@ -192,10 +200,14 @@ async def test_call_async_migrate_entry_failure_false(hass: HomeAssistant) -> No
assert not entry.supports_unload
async def test_call_async_migrate_entry_failure_exception(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(("major_version", "minor_version"), [(2, 1), (1, 2), (2, 2)])
async def test_call_async_migrate_entry_failure_exception(
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test migration fails if exception raised."""
entry = MockConfigEntry(domain="comp")
entry.version = 2
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
assert not entry.supports_unload
@ -220,10 +232,14 @@ async def test_call_async_migrate_entry_failure_exception(hass: HomeAssistant) -
assert not entry.supports_unload
async def test_call_async_migrate_entry_failure_not_bool(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(("major_version", "minor_version"), [(2, 1), (1, 2), (2, 2)])
async def test_call_async_migrate_entry_failure_not_bool(
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test migration fails if boolean not returned."""
entry = MockConfigEntry(domain="comp")
entry.version = 2
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
assert not entry.supports_unload
@ -248,12 +264,14 @@ async def test_call_async_migrate_entry_failure_not_bool(hass: HomeAssistant) ->
assert not entry.supports_unload
@pytest.mark.parametrize(("major_version", "minor_version"), [(2, 1), (2, 2)])
async def test_call_async_migrate_entry_failure_not_supported(
hass: HomeAssistant,
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test migration fails if async_migrate_entry not implemented."""
entry = MockConfigEntry(domain="comp")
entry.version = 2
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
assert not entry.supports_unload
@ -269,6 +287,29 @@ async def test_call_async_migrate_entry_failure_not_supported(
assert not entry.supports_unload
@pytest.mark.parametrize(("major_version", "minor_version"), [(1, 2)])
async def test_call_async_migrate_entry_not_supported_minor_version(
hass: HomeAssistant, major_version: int, minor_version: int
) -> None:
"""Test migration without async_migrate_entry and minor version changed."""
entry = MockConfigEntry(domain="comp")
entry.version = major_version
entry.minor_version = minor_version
entry.add_to_hass(hass)
assert not entry.supports_unload
mock_setup_entry = AsyncMock(return_value=True)
mock_integration(hass, MockModule("comp", async_setup_entry=mock_setup_entry))
mock_platform(hass, "comp.config_flow", None)
result = await async_setup_component(hass, "comp", {})
assert result
assert len(mock_setup_entry.mock_calls) == 1
assert entry.state is config_entries.ConfigEntryState.LOADED
assert not entry.supports_unload
async def test_remove_entry(
hass: HomeAssistant,
manager: config_entries.ConfigEntries,