Re-run expose entities migration if first time failed (#92564)
* Re-run expose entities migration if first time failed * Count number of exposed entities * Add tests --------- Co-authored-by: Erik <erik@montnemery.com>
This commit is contained in:
parent
6f3c9324ac
commit
19dcc8c88f
5 changed files with 219 additions and 6 deletions
|
@ -216,8 +216,18 @@ class CloudAlexaConfig(alexa_config.AbstractConfig):
|
|||
|
||||
async def on_hass_started(hass):
|
||||
if self._prefs.alexa_settings_version != ALEXA_SETTINGS_VERSION:
|
||||
if self._prefs.alexa_settings_version < 2:
|
||||
if self._prefs.alexa_settings_version < 2 or (
|
||||
# Recover from a bug we had in 2023.5.0 where entities didn't get exposed
|
||||
self._prefs.alexa_settings_version < 3
|
||||
and not any(
|
||||
settings.get("should_expose", False)
|
||||
for settings in async_get_assistant_settings(
|
||||
hass, CLOUD_ALEXA
|
||||
).values()
|
||||
)
|
||||
):
|
||||
self._migrate_alexa_entity_settings_v1()
|
||||
|
||||
await self._prefs.async_update(
|
||||
alexa_settings_version=ALEXA_SETTINGS_VERSION
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ from homeassistant.components.google_assistant import DOMAIN as GOOGLE_DOMAIN
|
|||
from homeassistant.components.google_assistant.helpers import AbstractConfig
|
||||
from homeassistant.components.homeassistant.exposed_entities import (
|
||||
async_expose_entity,
|
||||
async_get_assistant_settings,
|
||||
async_get_entity_settings,
|
||||
async_listen_entity_updates,
|
||||
async_set_assistant_option,
|
||||
|
@ -200,8 +201,18 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
|
||||
async def on_hass_started(hass: HomeAssistant) -> None:
|
||||
if self._prefs.google_settings_version != GOOGLE_SETTINGS_VERSION:
|
||||
if self._prefs.google_settings_version < 2:
|
||||
if self._prefs.google_settings_version < 2 or (
|
||||
# Recover from a bug we had in 2023.5.0 where entities didn't get exposed
|
||||
self._prefs.google_settings_version < 3
|
||||
and not any(
|
||||
settings.get("should_expose", False)
|
||||
for settings in async_get_assistant_settings(
|
||||
hass, CLOUD_GOOGLE
|
||||
).values()
|
||||
)
|
||||
):
|
||||
self._migrate_google_entity_settings_v1()
|
||||
|
||||
await self._prefs.async_update(
|
||||
google_settings_version=GOOGLE_SETTINGS_VERSION
|
||||
)
|
||||
|
|
|
@ -41,8 +41,8 @@ STORAGE_KEY = DOMAIN
|
|||
STORAGE_VERSION = 1
|
||||
STORAGE_VERSION_MINOR = 2
|
||||
|
||||
ALEXA_SETTINGS_VERSION = 2
|
||||
GOOGLE_SETTINGS_VERSION = 2
|
||||
ALEXA_SETTINGS_VERSION = 3
|
||||
GOOGLE_SETTINGS_VERSION = 3
|
||||
|
||||
|
||||
class CloudPreferencesStore(Store):
|
||||
|
|
|
@ -542,11 +542,13 @@ async def test_alexa_handle_logout(
|
|||
assert len(mock_enable.return_value.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("alexa_settings_version", [1, 2])
|
||||
async def test_alexa_config_migrate_expose_entity_prefs(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
cloud_stub,
|
||||
entity_registry: er.EntityRegistry,
|
||||
alexa_settings_version: int,
|
||||
) -> None:
|
||||
"""Test migrating Alexa entity config."""
|
||||
hass.state = CoreState.starting
|
||||
|
@ -593,7 +595,7 @@ async def test_alexa_config_migrate_expose_entity_prefs(
|
|||
await cloud_prefs.async_update(
|
||||
alexa_enabled=True,
|
||||
alexa_report_state=False,
|
||||
alexa_settings_version=1,
|
||||
alexa_settings_version=alexa_settings_version,
|
||||
)
|
||||
expose_entity(hass, entity_migrated.entity_id, False)
|
||||
|
||||
|
@ -641,6 +643,100 @@ async def test_alexa_config_migrate_expose_entity_prefs(
|
|||
}
|
||||
|
||||
|
||||
async def test_alexa_config_migrate_expose_entity_prefs_v2_no_exposed(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating Alexa entity config from v2 to v3 when no entity is exposed."""
|
||||
hass.state = CoreState.starting
|
||||
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
hass.states.async_set("light.state_only", "on")
|
||||
entity_migrated = entity_registry.async_get_or_create(
|
||||
"light",
|
||||
"test",
|
||||
"light_migrated",
|
||||
suggested_object_id="migrated",
|
||||
)
|
||||
await cloud_prefs.async_update(
|
||||
alexa_enabled=True,
|
||||
alexa_report_state=False,
|
||||
alexa_settings_version=2,
|
||||
)
|
||||
expose_entity(hass, "light.state_only", False)
|
||||
expose_entity(hass, entity_migrated.entity_id, False)
|
||||
|
||||
cloud_prefs._prefs[PREF_ALEXA_ENTITY_CONFIGS]["light.state_only"] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
cloud_prefs._prefs[PREF_ALEXA_ENTITY_CONFIGS][entity_migrated.entity_id] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
conf = alexa_config.CloudAlexaConfig(
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, Mock(is_logged_in=False)
|
||||
)
|
||||
await conf.async_initialize()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert async_get_entity_settings(hass, "light.state_only") == {
|
||||
"cloud.alexa": {"should_expose": True}
|
||||
}
|
||||
assert async_get_entity_settings(hass, entity_migrated.entity_id) == {
|
||||
"cloud.alexa": {"should_expose": True}
|
||||
}
|
||||
|
||||
|
||||
async def test_alexa_config_migrate_expose_entity_prefs_v2_exposed(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating Alexa entity config from v2 to v3 when an entity is exposed."""
|
||||
hass.state = CoreState.starting
|
||||
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
hass.states.async_set("light.state_only", "on")
|
||||
entity_migrated = entity_registry.async_get_or_create(
|
||||
"light",
|
||||
"test",
|
||||
"light_migrated",
|
||||
suggested_object_id="migrated",
|
||||
)
|
||||
await cloud_prefs.async_update(
|
||||
alexa_enabled=True,
|
||||
alexa_report_state=False,
|
||||
alexa_settings_version=2,
|
||||
)
|
||||
expose_entity(hass, "light.state_only", False)
|
||||
expose_entity(hass, entity_migrated.entity_id, True)
|
||||
|
||||
cloud_prefs._prefs[PREF_ALEXA_ENTITY_CONFIGS]["light.state_only"] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
cloud_prefs._prefs[PREF_ALEXA_ENTITY_CONFIGS][entity_migrated.entity_id] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
conf = alexa_config.CloudAlexaConfig(
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, Mock(is_logged_in=False)
|
||||
)
|
||||
await conf.async_initialize()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert async_get_entity_settings(hass, "light.state_only") == {
|
||||
"cloud.alexa": {"should_expose": False}
|
||||
}
|
||||
assert async_get_entity_settings(hass, entity_migrated.entity_id) == {
|
||||
"cloud.alexa": {"should_expose": True}
|
||||
}
|
||||
|
||||
|
||||
async def test_alexa_config_migrate_expose_entity_prefs_default_none(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
|
|
|
@ -483,10 +483,12 @@ async def test_google_handle_logout(
|
|||
assert len(mock_enable.return_value.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("google_settings_version", [1, 2])
|
||||
async def test_google_config_migrate_expose_entity_prefs(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
entity_registry: er.EntityRegistry,
|
||||
google_settings_version: int,
|
||||
) -> None:
|
||||
"""Test migrating Google entity config."""
|
||||
hass.state = CoreState.starting
|
||||
|
@ -540,7 +542,7 @@ async def test_google_config_migrate_expose_entity_prefs(
|
|||
await cloud_prefs.async_update(
|
||||
google_enabled=True,
|
||||
google_report_state=False,
|
||||
google_settings_version=1,
|
||||
google_settings_version=google_settings_version,
|
||||
)
|
||||
expose_entity(hass, entity_migrated.entity_id, False)
|
||||
|
||||
|
@ -596,6 +598,100 @@ async def test_google_config_migrate_expose_entity_prefs(
|
|||
}
|
||||
|
||||
|
||||
async def test_google_config_migrate_expose_entity_prefs_v2_no_exposed(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating Google entity config from v2 to v3 when no entity is exposed."""
|
||||
hass.state = CoreState.starting
|
||||
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
hass.states.async_set("light.state_only", "on")
|
||||
entity_migrated = entity_registry.async_get_or_create(
|
||||
"light",
|
||||
"test",
|
||||
"light_migrated",
|
||||
suggested_object_id="migrated",
|
||||
)
|
||||
await cloud_prefs.async_update(
|
||||
google_enabled=True,
|
||||
google_report_state=False,
|
||||
google_settings_version=2,
|
||||
)
|
||||
expose_entity(hass, "light.state_only", False)
|
||||
expose_entity(hass, entity_migrated.entity_id, False)
|
||||
|
||||
cloud_prefs._prefs[PREF_GOOGLE_ENTITY_CONFIGS]["light.state_only"] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
cloud_prefs._prefs[PREF_GOOGLE_ENTITY_CONFIGS][entity_migrated.entity_id] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
conf = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, Mock(is_logged_in=False)
|
||||
)
|
||||
await conf.async_initialize()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert async_get_entity_settings(hass, "light.state_only") == {
|
||||
"cloud.google_assistant": {"should_expose": True}
|
||||
}
|
||||
assert async_get_entity_settings(hass, entity_migrated.entity_id) == {
|
||||
"cloud.google_assistant": {"should_expose": True}
|
||||
}
|
||||
|
||||
|
||||
async def test_google_config_migrate_expose_entity_prefs_v2_exposed(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating Google entity config from v2 to v3 when an entity is exposed."""
|
||||
hass.state = CoreState.starting
|
||||
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
hass.states.async_set("light.state_only", "on")
|
||||
entity_migrated = entity_registry.async_get_or_create(
|
||||
"light",
|
||||
"test",
|
||||
"light_migrated",
|
||||
suggested_object_id="migrated",
|
||||
)
|
||||
await cloud_prefs.async_update(
|
||||
google_enabled=True,
|
||||
google_report_state=False,
|
||||
google_settings_version=2,
|
||||
)
|
||||
expose_entity(hass, "light.state_only", False)
|
||||
expose_entity(hass, entity_migrated.entity_id, True)
|
||||
|
||||
cloud_prefs._prefs[PREF_GOOGLE_ENTITY_CONFIGS]["light.state_only"] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
cloud_prefs._prefs[PREF_GOOGLE_ENTITY_CONFIGS][entity_migrated.entity_id] = {
|
||||
PREF_SHOULD_EXPOSE: True
|
||||
}
|
||||
conf = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, Mock(is_logged_in=False)
|
||||
)
|
||||
await conf.async_initialize()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert async_get_entity_settings(hass, "light.state_only") == {
|
||||
"cloud.google_assistant": {"should_expose": False}
|
||||
}
|
||||
assert async_get_entity_settings(hass, entity_migrated.entity_id) == {
|
||||
"cloud.google_assistant": {"should_expose": True}
|
||||
}
|
||||
|
||||
|
||||
async def test_google_config_migrate_expose_entity_prefs_default_none(
|
||||
hass: HomeAssistant,
|
||||
cloud_prefs: CloudPreferences,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue