Clean up Alexa when logging out from cloud (#109738)

* Clean up Alexa when logging out from cloud

* Add test
pull/109767/head
Erik Montnemery 2024-02-05 23:58:34 +01:00 committed by GitHub
parent 6fce8a5403
commit b7284b92ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 37 additions and 10 deletions

View File

@ -29,12 +29,20 @@ class AbstractConfig(ABC):
"""Initialize abstract config."""
self.hass = hass
self._enable_proactive_mode_lock = asyncio.Lock()
self._on_deinitialize: list[CALLBACK_TYPE] = []
async def async_initialize(self) -> None:
"""Perform async initialization of config."""
self._store = AlexaConfigStore(self.hass)
await self._store.async_load()
@callback
def async_deinitialize(self) -> None:
"""Remove listeners."""
_LOGGER.debug("async_deinitialize")
while self._on_deinitialize:
self._on_deinitialize.pop()()
@property
def supports_auth(self) -> bool:
"""Return if config supports auth."""

View File

@ -246,21 +246,27 @@ class CloudAlexaConfig(alexa_config.AbstractConfig):
await self._prefs.async_update(
alexa_settings_version=ALEXA_SETTINGS_VERSION
)
async_listen_entity_updates(
self.hass, CLOUD_ALEXA, self._async_exposed_entities_updated
self._on_deinitialize.append(
async_listen_entity_updates(
self.hass, CLOUD_ALEXA, self._async_exposed_entities_updated
)
)
async def on_hass_start(hass: HomeAssistant) -> None:
if self.enabled and ALEXA_DOMAIN not in self.hass.config.components:
await async_setup_component(self.hass, ALEXA_DOMAIN, {})
start.async_at_start(self.hass, on_hass_start)
start.async_at_started(self.hass, on_hass_started)
self._on_deinitialize.append(start.async_at_start(self.hass, on_hass_start))
self._on_deinitialize.append(start.async_at_started(self.hass, on_hass_started))
self._prefs.async_listen_updates(self._async_prefs_updated)
self.hass.bus.async_listen(
er.EVENT_ENTITY_REGISTRY_UPDATED,
self._handle_entity_registry_updated,
self._on_deinitialize.append(
self._prefs.async_listen_updates(self._async_prefs_updated)
)
self._on_deinitialize.append(
self.hass.bus.async_listen(
er.EVENT_ENTITY_REGISTRY_UPDATED,
self._handle_entity_registry_updated,
)
)
def _should_expose_legacy(self, entity_id: str) -> bool:

View File

@ -213,6 +213,10 @@ class CloudClient(Interface):
"""Cleanup some stuff after logout."""
await self.prefs.async_set_username(None)
if self._alexa_config:
self._alexa_config.async_deinitialize()
self._alexa_config = None
if self._google_config:
self._google_config.async_deinitialize()
self._google_config = None

View File

@ -526,6 +526,9 @@ async def test_alexa_handle_logout(
return_value=Mock(),
) as mock_enable:
await aconf.async_enable_proactive_mode()
await hass.async_block_till_done()
assert len(aconf._on_deinitialize) == 5
# This will trigger a prefs update when we logout.
await cloud_prefs.get_cloud_user()
@ -536,8 +539,13 @@ async def test_alexa_handle_logout(
"async_check_token",
side_effect=AssertionError("Should not be called"),
):
# Fake logging out; CloudClient.logout_cleanups sets username to None
# and deinitializes the Google config.
await cloud_prefs.async_set_username(None)
aconf.async_deinitialize()
await hass.async_block_till_done()
# Check listeners are removed:
assert not aconf._on_deinitialize
assert len(mock_enable.return_value.mock_calls) == 1

View File

@ -468,10 +468,11 @@ async def test_logged_out(
await cloud.logout()
await hass.async_block_till_done()
# Alexa is not cleaned up, Google is
assert cloud.client._alexa_config is alexa_config_mock
# Check we clean up Alexa and Google
assert cloud.client._alexa_config is None
assert cloud.client._google_config is None
google_config_mock.async_deinitialize.assert_called_once_with()
alexa_config_mock.async_deinitialize.assert_called_once_with()
async def test_remote_enable(hass: HomeAssistant) -> None: