Fix next authentication token error handling (#138299)

This commit is contained in:
Allen Porter 2025-02-11 12:47:36 -08:00 committed by Franck Nijhof
parent 979b3d4269
commit 7e52170789
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 61 additions and 6 deletions

View File

@ -8,7 +8,7 @@ from collections.abc import Awaitable, Callable
from http import HTTPStatus from http import HTTPStatus
import logging import logging
from aiohttp import web from aiohttp import ClientError, ClientResponseError, web
from google_nest_sdm.camera_traits import CameraClipPreviewTrait from google_nest_sdm.camera_traits import CameraClipPreviewTrait
from google_nest_sdm.device import Device from google_nest_sdm.device import Device
from google_nest_sdm.event import EventMessage from google_nest_sdm.event import EventMessage
@ -201,11 +201,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: NestConfigEntry) -> bool
auth = await api.new_auth(hass, entry) auth = await api.new_auth(hass, entry)
try: try:
await auth.async_get_access_token() await auth.async_get_access_token()
except AuthException as err: except ClientResponseError as err:
raise ConfigEntryAuthFailed(f"Authentication error: {err!s}") from err if 400 <= err.status < 500:
except ConfigurationException as err: raise ConfigEntryAuthFailed from err
_LOGGER.error("Configuration error: %s", err) raise ConfigEntryNotReady from err
return False except ClientError as err:
raise ConfigEntryNotReady from err
subscriber = await api.new_subscriber(hass, entry, auth) subscriber = await api.new_subscriber(hass, entry, auth)
if not subscriber: if not subscriber:

View File

@ -9,10 +9,12 @@ relevant modes.
""" """
from collections.abc import Generator from collections.abc import Generator
import datetime
from http import HTTPStatus from http import HTTPStatus
import logging import logging
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
import aiohttp
from google_nest_sdm.exceptions import ( from google_nest_sdm.exceptions import (
ApiException, ApiException,
AuthException, AuthException,
@ -22,6 +24,7 @@ from google_nest_sdm.exceptions import (
import pytest import pytest
from homeassistant.components.nest import DOMAIN from homeassistant.components.nest import DOMAIN
from homeassistant.components.nest.const import OAUTH2_TOKEN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -36,6 +39,8 @@ from tests.test_util.aiohttp import AiohttpClientMocker
PLATFORM = "sensor" PLATFORM = "sensor"
EXPIRED_TOKEN_TIMESTAMP = datetime.datetime(2022, 4, 8).timestamp()
@pytest.fixture @pytest.fixture
def platforms() -> list[str]: def platforms() -> list[str]:
@ -139,6 +144,55 @@ async def test_setup_device_manager_failure(
assert entries[0].state is ConfigEntryState.SETUP_RETRY assert entries[0].state is ConfigEntryState.SETUP_RETRY
@pytest.mark.parametrize("token_expiration_time", [EXPIRED_TOKEN_TIMESTAMP])
@pytest.mark.parametrize(
("token_response_args", "expected_state", "expected_steps"),
[
# Cases that retry integration setup
(
{"status": HTTPStatus.INTERNAL_SERVER_ERROR},
ConfigEntryState.SETUP_RETRY,
[],
),
({"exc": aiohttp.ClientError("No internet")}, ConfigEntryState.SETUP_RETRY, []),
# Cases that require the user to reauthenticate in a config flow
(
{"status": HTTPStatus.BAD_REQUEST},
ConfigEntryState.SETUP_ERROR,
["reauth_confirm"],
),
(
{"status": HTTPStatus.FORBIDDEN},
ConfigEntryState.SETUP_ERROR,
["reauth_confirm"],
),
],
)
async def test_expired_token_refresh_error(
hass: HomeAssistant,
setup_base_platform: PlatformSetup,
aioclient_mock: AiohttpClientMocker,
token_response_args: dict,
expected_state: ConfigEntryState,
expected_steps: list[str],
) -> None:
"""Test errors when attempting to refresh the auth token."""
aioclient_mock.post(
OAUTH2_TOKEN,
**token_response_args,
)
await setup_base_platform()
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1
assert entries[0].state is expected_state
flows = hass.config_entries.flow.async_progress()
assert expected_steps == [flow["step_id"] for flow in flows]
@pytest.mark.parametrize("subscriber_side_effect", [AuthException()]) @pytest.mark.parametrize("subscriber_side_effect", [AuthException()])
async def test_subscriber_auth_failure( async def test_subscriber_auth_failure(
hass: HomeAssistant, hass: HomeAssistant,