Gracefully handle webhook unsubscription if error occurs while contacting Withings (#134271)

pull/136092/head
dcmeglio 2025-01-17 04:14:41 -05:00 committed by Franck Nijhof
parent 9680abf51e
commit 8865fc0c33
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 59 additions and 1 deletions

View File

@ -16,6 +16,7 @@ from aiohttp import ClientError
from aiohttp.hdrs import METH_POST
from aiohttp.web import Request, Response
from aiowithings import NotificationCategory, WithingsClient
from aiowithings.exceptions import WithingsError
from aiowithings.util import to_enum
from yarl import URL
@ -223,10 +224,13 @@ class WithingsWebhookManager:
"Unregister Withings webhook (%s)", self.entry.data[CONF_WEBHOOK_ID]
)
webhook_unregister(self.hass, self.entry.data[CONF_WEBHOOK_ID])
await async_unsubscribe_webhooks(self.withings_data.client)
for coordinator in self.withings_data.coordinators:
coordinator.webhook_subscription_listener(False)
self._webhooks_registered = False
try:
await async_unsubscribe_webhooks(self.withings_data.client)
except WithingsError as ex:
LOGGER.warning("Failed to unsubscribe from Withings webhook: %s", ex)
async def register_webhook(
self,

View File

@ -10,6 +10,7 @@ from aiohttp.hdrs import METH_HEAD
from aiowithings import (
NotificationCategory,
WithingsAuthenticationFailedError,
WithingsConnectionError,
WithingsUnauthorizedError,
)
from freezegun.api import FrozenDateTimeFactory
@ -532,6 +533,59 @@ async def test_cloud_disconnect_retry(
assert mock_async_active_subscription.call_count == 4
async def test_internet_timeout_then_restore(
hass: HomeAssistant,
withings: AsyncMock,
webhook_config_entry: MockConfigEntry,
hass_client_no_auth: ClientSessionGenerator,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test we can recover from internet disconnects."""
await mock_cloud(hass)
await hass.async_block_till_done()
with (
patch("homeassistant.components.cloud.async_is_logged_in", return_value=True),
patch.object(cloud, "async_is_connected", return_value=True),
patch.object(cloud, "async_active_subscription", return_value=True),
patch(
"homeassistant.components.cloud.async_create_cloudhook",
return_value="https://hooks.nabu.casa/ABCD",
),
patch(
"homeassistant.components.withings.async_get_config_entry_implementation",
),
patch(
"homeassistant.components.cloud.async_delete_cloudhook",
),
patch(
"homeassistant.components.withings.webhook_generate_url",
),
):
await setup_integration(hass, webhook_config_entry)
await prepare_webhook_setup(hass, freezer)
assert cloud.async_active_subscription(hass) is True
assert cloud.async_is_connected(hass) is True
assert withings.revoke_notification_configurations.call_count == 3
assert withings.subscribe_notification.call_count == 6
await hass.async_block_till_done()
withings.list_notification_configurations.side_effect = WithingsConnectionError
async_mock_cloud_connection_status(hass, False)
await hass.async_block_till_done()
assert withings.revoke_notification_configurations.call_count == 3
withings.list_notification_configurations.side_effect = None
async_mock_cloud_connection_status(hass, True)
await hass.async_block_till_done()
assert withings.subscribe_notification.call_count == 12
@pytest.mark.parametrize(
("body", "expected_code"),
[