Clean up devolo Home Control config flow (#49585)

This commit is contained in:
Guido Schmitz 2021-04-23 13:48:24 +02:00 committed by GitHub
parent 50d2c3bfe3
commit c6edc7ae4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 14 deletions

View file

@ -1,6 +1,4 @@
"""Config flow to configure the devolo home control integration.""" """Config flow to configure the devolo home control integration."""
import logging
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
@ -15,8 +13,7 @@ from .const import ( # pylint:disable=unused-import
DOMAIN, DOMAIN,
SUPPORTED_MODEL_TYPES, SUPPORTED_MODEL_TYPES,
) )
from .exceptions import CredentialsInvalid
_LOGGER = logging.getLogger(__name__)
class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
@ -39,8 +36,11 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
vol.Required(CONF_MYDEVOLO, default=DEFAULT_MYDEVOLO) vol.Required(CONF_MYDEVOLO, default=DEFAULT_MYDEVOLO)
] = str ] = str
if user_input is None: if user_input is None:
return self._show_form(user_input) return self._show_form(step_id="user")
try:
return await self._connect_mydevolo(user_input) return await self._connect_mydevolo(user_input)
except CredentialsInvalid:
return self._show_form(step_id="user", errors={"base": "invalid_auth"})
async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType): async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
"""Handle zeroconf discovery.""" """Handle zeroconf discovery."""
@ -54,7 +54,12 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a flow initiated by zeroconf.""" """Handle a flow initiated by zeroconf."""
if user_input is None: if user_input is None:
return self._show_form(step_id="zeroconf_confirm") return self._show_form(step_id="zeroconf_confirm")
try:
return await self._connect_mydevolo(user_input) return await self._connect_mydevolo(user_input)
except CredentialsInvalid:
return self._show_form(
step_id="zeroconf_confirm", errors={"base": "invalid_auth"}
)
async def _connect_mydevolo(self, user_input): async def _connect_mydevolo(self, user_input):
"""Connect to mydevolo.""" """Connect to mydevolo."""
@ -63,8 +68,7 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
mydevolo.credentials_valid mydevolo.credentials_valid
) )
if not credentials_valid: if not credentials_valid:
return self._show_form({"base": "invalid_auth"}) raise CredentialsInvalid
_LOGGER.debug("Credentials valid")
uuid = await self.hass.async_add_executor_job(mydevolo.uuid) uuid = await self.hass.async_add_executor_job(mydevolo.uuid)
await self.async_set_unique_id(uuid) await self.async_set_unique_id(uuid)
self._abort_if_unique_id_configured() self._abort_if_unique_id_configured()
@ -79,7 +83,7 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
) )
@callback @callback
def _show_form(self, errors=None, step_id="user"): def _show_form(self, step_id, errors=None):
"""Show the form to the user.""" """Show the form to the user."""
return self.async_show_form( return self.async_show_form(
step_id=step_id, step_id=step_id,

View file

@ -0,0 +1,6 @@
"""Custom exceptions for the devolo_home_control integration."""
from homeassistant.exceptions import HomeAssistantError
class CredentialsInvalid(HomeAssistantError):
"""Given credentials are invalid."""

View file

@ -22,20 +22,22 @@ async def test_form(hass):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["step_id"] == "user"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {} assert result["errors"] == {}
await _setup(hass, result) await _setup(hass, result)
@pytest.mark.credentials_invalid @pytest.mark.credentials_invalid
async def test_form_invalid_credentials(hass): async def test_form_invalid_credentials_user(hass):
"""Test if we get the error message on invalid credentials.""" """Test if we get the error message on invalid credentials."""
await setup.async_setup_component(hass, "persistent_notification", {}) await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["step_id"] == "user"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {} assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
@ -98,7 +100,7 @@ async def test_form_advanced_options(hass):
assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
async def test_show_zeroconf_form(hass): async def test_form_zeroconf(hass):
"""Test that the zeroconf confirmation form is served.""" """Test that the zeroconf confirmation form is served."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
@ -112,6 +114,27 @@ async def test_show_zeroconf_form(hass):
await _setup(hass, result) await _setup(hass, result)
@pytest.mark.credentials_invalid
async def test_form_invalid_credentials_zeroconf(hass):
"""Test if we get the error message on invalid credentials."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_ZEROCONF},
data=DISCOVERY_INFO,
)
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"username": "test-username", "password": "test-password"},
)
assert result["errors"] == {"base": "invalid_auth"}
async def test_zeroconf_wrong_device(hass): async def test_zeroconf_wrong_device(hass):
"""Test that the zeroconf ignores wrong devices.""" """Test that the zeroconf ignores wrong devices."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(