Clean up devolo Home Control config flow (#49585)
This commit is contained in:
parent
50d2c3bfe3
commit
c6edc7ae4f
3 changed files with 47 additions and 14 deletions
|
@ -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,
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
"""Custom exceptions for the devolo_home_control integration."""
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialsInvalid(HomeAssistantError):
|
||||||
|
"""Given credentials are invalid."""
|
|
@ -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(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue