diff --git a/homeassistant/components/overkiz/config_flow.py b/homeassistant/components/overkiz/config_flow.py index d3ab9722fca..eac749f1bc0 100644 --- a/homeassistant/components/overkiz/config_flow.py +++ b/homeassistant/components/overkiz/config_flow.py @@ -9,6 +9,7 @@ from pyoverkiz.client import OverkizClient from pyoverkiz.const import SUPPORTED_SERVERS from pyoverkiz.exceptions import ( BadCredentialsException, + CozyTouchBadCredentialsException, MaintenanceException, TooManyAttemptsBannedException, TooManyRequestsException, @@ -67,6 +68,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) -> FlowResult: """Handle the initial step via config flow.""" errors = {} + description_placeholders = {} if user_input: 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) except TooManyRequestsException: errors["base"] = "too_many_requests" - except BadCredentialsException: - errors["base"] = "invalid_auth" + except BadCredentialsException as exception: + # 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): errors["base"] = "cannot_connect" except MaintenanceException: @@ -85,7 +95,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): except TooManyAttemptsBannedException: errors["base"] = "too_many_attempts" 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 errors["base"] = "unknown" LOGGER.exception(exception) @@ -129,6 +142,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ), } ), + description_placeholders=description_placeholders, errors=errors, ) diff --git a/homeassistant/components/overkiz/strings.json b/homeassistant/components/overkiz/strings.json index ecc0329eb2a..440ed154cfe 100644 --- a/homeassistant/components/overkiz/strings.json +++ b/homeassistant/components/overkiz/strings.json @@ -19,7 +19,7 @@ "too_many_attempts": "Too many attempts with an invalid token, temporarily banned", "too_many_requests": "Too many requests, try again later", "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": { "already_configured": "[%key:common::config_flow::abort::already_configured_account%]", diff --git a/homeassistant/components/overkiz/translations/en.json b/homeassistant/components/overkiz/translations/en.json index 9c8ad538695..2c534a64cb6 100644 --- a/homeassistant/components/overkiz/translations/en.json +++ b/homeassistant/components/overkiz/translations/en.json @@ -12,7 +12,7 @@ "too_many_attempts": "Too many attempts with an invalid token, temporarily banned", "too_many_requests": "Too many requests, try again later", "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}", "step": { diff --git a/tests/components/overkiz/test_config_flow.py b/tests/components/overkiz/test_config_flow.py index 940da7b39c2..dc50896626d 100644 --- a/tests/components/overkiz/test_config_flow.py +++ b/tests/components/overkiz/test_config_flow.py @@ -27,6 +27,7 @@ TEST_PASSWORD = "test-password" TEST_PASSWORD2 = "test-password2" TEST_HUB = "somfy_europe" TEST_HUB2 = "hi_kumo_europe" +TEST_HUB_COZYTOUCH = "atlantic_cozytouch" TEST_GATEWAY_ID = "1234-5678-9123" TEST_GATEWAY_ID2 = "4321-5678-9123" @@ -89,7 +90,7 @@ async def test_form(hass: HomeAssistant) -> None: (ClientError, "cannot_connect"), (MaintenanceException, "server_in_maintenance"), (TooManyAttemptsBannedException, "too_many_attempts"), - (UnknownUserException, "unknown_user"), + (UnknownUserException, "unsupported_hardware"), (Exception, "unknown"), ], ) @@ -112,6 +113,35 @@ async def test_form_invalid_auth( 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: """Test config flow aborts Config Flow on duplicate entries.""" MockConfigEntry(