Handle locked account error in Whirlpool (#136861)

This commit is contained in:
Abílio Costa 2025-01-29 18:51:09 +00:00 committed by GitHub
parent 46cef2986c
commit b500fde468
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 33 additions and 2 deletions

View File

@ -5,7 +5,7 @@ import logging
from aiohttp import ClientError from aiohttp import ClientError
from whirlpool.appliancesmanager import AppliancesManager from whirlpool.appliancesmanager import AppliancesManager
from whirlpool.auth import Auth from whirlpool.auth import AccountLockedError as WhirlpoolAccountLocked, Auth
from whirlpool.backendselector import BackendSelector from whirlpool.backendselector import BackendSelector
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -39,6 +39,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: WhirlpoolConfigEntry) ->
await auth.do_auth(store=False) await auth.do_auth(store=False)
except (ClientError, TimeoutError) as ex: except (ClientError, TimeoutError) as ex:
raise ConfigEntryNotReady("Cannot connect") from ex raise ConfigEntryNotReady("Cannot connect") from ex
except WhirlpoolAccountLocked as ex:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN, translation_key="account_locked"
) from ex
if not auth.is_access_token_valid(): if not auth.is_access_token_valid():
_LOGGER.error("Authentication failed") _LOGGER.error("Authentication failed")

View File

@ -9,7 +9,7 @@ from typing import Any
from aiohttp import ClientError from aiohttp import ClientError
import voluptuous as vol import voluptuous as vol
from whirlpool.appliancesmanager import AppliancesManager from whirlpool.appliancesmanager import AppliancesManager
from whirlpool.auth import Auth from whirlpool.auth import AccountLockedError as WhirlpoolAccountLocked, Auth
from whirlpool.backendselector import BackendSelector from whirlpool.backendselector import BackendSelector
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
@ -55,6 +55,8 @@ async def authenticate(
try: try:
await auth.do_auth() await auth.do_auth()
except WhirlpoolAccountLocked:
return "account_locked"
except (TimeoutError, ClientError): except (TimeoutError, ClientError):
return "cannot_connect" return "cannot_connect"
except Exception: except Exception:

View File

@ -1,4 +1,7 @@
{ {
"common": {
"account_locked_error": "The account is locked. Please follow the instructions in the manufacturer's app to unlock it"
},
"config": { "config": {
"step": { "step": {
"user": { "user": {
@ -31,6 +34,7 @@
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}, },
"error": { "error": {
"account_locked": "[%key:component::whirlpool::common::account_locked_error%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]", "unknown": "[%key:common::config_flow::error::unknown%]",
@ -85,5 +89,10 @@
"name": "End time" "name": "End time"
} }
} }
},
"exceptions": {
"account_locked": {
"message": "[%key:component::whirlpool::common::account_locked_error%]"
}
} }
} }

View File

@ -4,6 +4,7 @@ from unittest.mock import MagicMock, patch
import aiohttp import aiohttp
import pytest import pytest
from whirlpool.auth import AccountLockedError
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.whirlpool.const import CONF_BRAND, DOMAIN from homeassistant.components.whirlpool.const import CONF_BRAND, DOMAIN
@ -82,6 +83,7 @@ async def test_form_invalid_auth(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("exception", "expected_error"), ("exception", "expected_error"),
[ [
(AccountLockedError, "account_locked"),
(aiohttp.ClientConnectionError, "cannot_connect"), (aiohttp.ClientConnectionError, "cannot_connect"),
(TimeoutError, "cannot_connect"), (TimeoutError, "cannot_connect"),
(Exception, "unknown"), (Exception, "unknown"),
@ -249,6 +251,7 @@ async def test_reauth_flow_invalid_auth(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("exception", "expected_error"), ("exception", "expected_error"),
[ [
(AccountLockedError, "account_locked"),
(aiohttp.ClientConnectionError, "cannot_connect"), (aiohttp.ClientConnectionError, "cannot_connect"),
(TimeoutError, "cannot_connect"), (TimeoutError, "cannot_connect"),
(Exception, "unknown"), (Exception, "unknown"),

View File

@ -3,6 +3,7 @@
from unittest.mock import AsyncMock, MagicMock from unittest.mock import AsyncMock, MagicMock
import aiohttp import aiohttp
from whirlpool.auth import AccountLockedError
from whirlpool.backendselector import Brand, Region from whirlpool.backendselector import Brand, Region
from homeassistant.components.whirlpool.const import DOMAIN from homeassistant.components.whirlpool.const import DOMAIN
@ -104,6 +105,18 @@ async def test_setup_auth_failed(
assert entry.state is ConfigEntryState.SETUP_ERROR assert entry.state is ConfigEntryState.SETUP_ERROR
async def test_setup_auth_account_locked(
hass: HomeAssistant,
mock_auth_api: MagicMock,
mock_aircon_api_instances: MagicMock,
) -> None:
"""Test setup with failed auth due to account being locked."""
mock_auth_api.return_value.do_auth.side_effect = AccountLockedError
entry = await init_integration(hass)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state is ConfigEntryState.SETUP_ERROR
async def test_setup_fetch_appliances_failed( async def test_setup_fetch_appliances_failed(
hass: HomeAssistant, hass: HomeAssistant,
mock_appliances_manager_api: MagicMock, mock_appliances_manager_api: MagicMock,