Update Config Flow to show message about unsupported Overkiz hardware (#79503)

* Update Config Flow to show cozytouch unsupported hardware error

* Apply feedback

* Remove vague unknown user exception

* Fix test

* Code coverage back to 100%
This commit is contained in:
Mick Vleeshouwer 2022-10-09 00:37:03 +02:00 committed by GitHub
parent 8471a71b60
commit 132ff2c410
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 6 deletions

View File

@ -9,6 +9,7 @@ from pyoverkiz.client import OverkizClient
from pyoverkiz.const import SUPPORTED_SERVERS from pyoverkiz.const import SUPPORTED_SERVERS
from pyoverkiz.exceptions import ( from pyoverkiz.exceptions import (
BadCredentialsException, BadCredentialsException,
CozyTouchBadCredentialsException,
MaintenanceException, MaintenanceException,
TooManyAttemptsBannedException, TooManyAttemptsBannedException,
TooManyRequestsException, TooManyRequestsException,
@ -67,6 +68,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
) -> FlowResult: ) -> FlowResult:
"""Handle the initial step via config flow.""" """Handle the initial step via config flow."""
errors = {} errors = {}
description_placeholders = {}
if user_input: if user_input:
self._default_user = user_input[CONF_USERNAME] self._default_user = user_input[CONF_USERNAME]
@ -76,8 +78,16 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
await self.async_validate_input(user_input) await self.async_validate_input(user_input)
except TooManyRequestsException: except TooManyRequestsException:
errors["base"] = "too_many_requests" errors["base"] = "too_many_requests"
except BadCredentialsException: except BadCredentialsException as exception:
errors["base"] = "invalid_auth" # If authentication with CozyTouch auth server is valid, but token is invalid
# for Overkiz API server, the hardware is not supported.
if user_input[CONF_HUB] == "atlantic_cozytouch" and not isinstance(
exception, CozyTouchBadCredentialsException
):
description_placeholders["unsupported_device"] = "CozyTouch"
errors["base"] = "unsupported_hardware"
else:
errors["base"] = "invalid_auth"
except (TimeoutError, ClientError): except (TimeoutError, ClientError):
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
except MaintenanceException: except MaintenanceException:
@ -85,7 +95,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
except TooManyAttemptsBannedException: except TooManyAttemptsBannedException:
errors["base"] = "too_many_attempts" errors["base"] = "too_many_attempts"
except UnknownUserException: except UnknownUserException:
errors["base"] = "unknown_user" # Somfy Protect accounts are not supported since they don't use
# the Overkiz API server. Login will return unknown user.
description_placeholders["unsupported_device"] = "Somfy Protect"
errors["base"] = "unsupported_hardware"
except Exception as exception: # pylint: disable=broad-except except Exception as exception: # pylint: disable=broad-except
errors["base"] = "unknown" errors["base"] = "unknown"
LOGGER.exception(exception) LOGGER.exception(exception)
@ -129,6 +142,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
), ),
} }
), ),
description_placeholders=description_placeholders,
errors=errors, errors=errors,
) )

View File

@ -19,7 +19,7 @@
"too_many_attempts": "Too many attempts with an invalid token, temporarily banned", "too_many_attempts": "Too many attempts with an invalid token, temporarily banned",
"too_many_requests": "Too many requests, try again later", "too_many_requests": "Too many requests, try again later",
"unknown": "[%key:common::config_flow::error::unknown%]", "unknown": "[%key:common::config_flow::error::unknown%]",
"unknown_user": "Unknown user. Somfy Protect accounts are not supported by this integration." "unsupported_hardware": "Your {unsupported_device} hardware is not supported by this integration."
}, },
"abort": { "abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]", "already_configured": "[%key:common::config_flow::abort::already_configured_account%]",

View File

@ -12,7 +12,7 @@
"too_many_attempts": "Too many attempts with an invalid token, temporarily banned", "too_many_attempts": "Too many attempts with an invalid token, temporarily banned",
"too_many_requests": "Too many requests, try again later", "too_many_requests": "Too many requests, try again later",
"unknown": "Unexpected error", "unknown": "Unexpected error",
"unknown_user": "Unknown user. Somfy Protect accounts are not supported by this integration." "unsupported_hardware": "Your {unsupported_device} hardware is not supported by this integration."
}, },
"flow_title": "Gateway: {gateway_id}", "flow_title": "Gateway: {gateway_id}",
"step": { "step": {

View File

@ -27,6 +27,7 @@ TEST_PASSWORD = "test-password"
TEST_PASSWORD2 = "test-password2" TEST_PASSWORD2 = "test-password2"
TEST_HUB = "somfy_europe" TEST_HUB = "somfy_europe"
TEST_HUB2 = "hi_kumo_europe" TEST_HUB2 = "hi_kumo_europe"
TEST_HUB_COZYTOUCH = "atlantic_cozytouch"
TEST_GATEWAY_ID = "1234-5678-9123" TEST_GATEWAY_ID = "1234-5678-9123"
TEST_GATEWAY_ID2 = "4321-5678-9123" TEST_GATEWAY_ID2 = "4321-5678-9123"
@ -89,7 +90,7 @@ async def test_form(hass: HomeAssistant) -> None:
(ClientError, "cannot_connect"), (ClientError, "cannot_connect"),
(MaintenanceException, "server_in_maintenance"), (MaintenanceException, "server_in_maintenance"),
(TooManyAttemptsBannedException, "too_many_attempts"), (TooManyAttemptsBannedException, "too_many_attempts"),
(UnknownUserException, "unknown_user"), (UnknownUserException, "unsupported_hardware"),
(Exception, "unknown"), (Exception, "unknown"),
], ],
) )
@ -112,6 +113,35 @@ async def test_form_invalid_auth(
assert result2["errors"] == {"base": error} assert result2["errors"] == {"base": error}
@pytest.mark.parametrize(
"side_effect, error",
[
(BadCredentialsException, "unsupported_hardware"),
],
)
async def test_form_invalid_cozytouch_auth(
hass: HomeAssistant, side_effect: Exception, error: str
) -> None:
"""Test we handle invalid auth from CozyTouch."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("pyoverkiz.client.OverkizClient.login", side_effect=side_effect):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"username": TEST_EMAIL,
"password": TEST_PASSWORD,
"hub": TEST_HUB_COZYTOUCH,
},
)
assert result["step_id"] == config_entries.SOURCE_USER
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result2["errors"] == {"base": error}
async def test_abort_on_duplicate_entry(hass: HomeAssistant) -> None: async def test_abort_on_duplicate_entry(hass: HomeAssistant) -> None:
"""Test config flow aborts Config Flow on duplicate entries.""" """Test config flow aborts Config Flow on duplicate entries."""
MockConfigEntry( MockConfigEntry(