mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 04:37:06 +00:00
Make Withings recoverable after internet outage (#115124)
This commit is contained in:
parent
c108c7df38
commit
cc2e0fd921
@ -12,6 +12,7 @@ from dataclasses import dataclass, field
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from typing import TYPE_CHECKING, Any, cast
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
|
from aiohttp import ClientError
|
||||||
from aiohttp.hdrs import METH_POST
|
from aiohttp.hdrs import METH_POST
|
||||||
from aiohttp.web import Request, Response
|
from aiohttp.web import Request, Response
|
||||||
from aiowithings import NotificationCategory, WithingsClient
|
from aiowithings import NotificationCategory, WithingsClient
|
||||||
@ -274,7 +275,11 @@ class WithingsWebhookManager:
|
|||||||
|
|
||||||
async def async_unsubscribe_webhooks(client: WithingsClient) -> None:
|
async def async_unsubscribe_webhooks(client: WithingsClient) -> None:
|
||||||
"""Unsubscribe to all Withings webhooks."""
|
"""Unsubscribe to all Withings webhooks."""
|
||||||
current_webhooks = await client.list_notification_configurations()
|
try:
|
||||||
|
current_webhooks = await client.list_notification_configurations()
|
||||||
|
except ClientError:
|
||||||
|
LOGGER.exception("Error when unsubscribing webhooks")
|
||||||
|
return
|
||||||
|
|
||||||
for webhook_configuration in current_webhooks:
|
for webhook_configuration in current_webhooks:
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
|
@ -5,6 +5,7 @@ from typing import Any
|
|||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
from aiohttp import ClientConnectionError
|
||||||
from aiohttp.hdrs import METH_HEAD
|
from aiohttp.hdrs import METH_HEAD
|
||||||
from aiowithings import (
|
from aiowithings import (
|
||||||
NotificationCategory,
|
NotificationCategory,
|
||||||
@ -425,6 +426,110 @@ async def test_cloud_disconnect(
|
|||||||
assert withings.subscribe_notification.call_count == 12
|
assert withings.subscribe_notification.call_count == 12
|
||||||
|
|
||||||
|
|
||||||
|
async def test_internet_disconnect(
|
||||||
|
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 = ClientConnectionError
|
||||||
|
|
||||||
|
async_mock_cloud_connection_status(hass, False)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert withings.revoke_notification_configurations.call_count == 3
|
||||||
|
|
||||||
|
async_mock_cloud_connection_status(hass, True)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert withings.subscribe_notification.call_count == 12
|
||||||
|
|
||||||
|
|
||||||
|
async def test_cloud_disconnect_retry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
withings: AsyncMock,
|
||||||
|
webhook_config_entry: MockConfigEntry,
|
||||||
|
hass_client_no_auth: ClientSessionGenerator,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test we retry to create webhook connection again after cloud 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
|
||||||
|
) as mock_async_active_subscription,
|
||||||
|
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 mock_async_active_subscription.call_count == 3
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
async_mock_cloud_connection_status(hass, False)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_async_active_subscription.call_count == 3
|
||||||
|
|
||||||
|
freezer.tick(timedelta(seconds=30))
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_async_active_subscription.call_count == 4
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("body", "expected_code"),
|
("body", "expected_code"),
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user