1
mirror of https://github.com/home-assistant/core synced 2024-08-31 05:57:13 +02:00

Allow new UniFi flows to update existing entries if host and site match (#45668)

This commit is contained in:
Robert Svensson 2021-01-29 18:14:39 +01:00 committed by GitHub
parent af68d5fb41
commit 97fd05eb9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 32 deletions

View File

@ -38,9 +38,9 @@ from .const import (
LOGGER,
)
from .controller import get_controller
from .errors import AlreadyConfigured, AuthenticationRequired, CannotConnect
from .errors import AuthenticationRequired, CannotConnect
DEFAULT_PORT = 8443
DEFAULT_PORT = 443
DEFAULT_SITE_ID = "default"
DEFAULT_VERIFY_SSL = False
@ -76,7 +76,7 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN):
"""Initialize the UniFi flow."""
self.config = {}
self.sites = None
self.reauth_config_entry = {}
self.reauth_config_entry = None
self.reauth_config = {}
self.reauth_schema = {}
@ -146,32 +146,40 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN):
errors = {}
if user_input is not None:
try:
self.config[CONF_SITE_ID] = user_input[CONF_SITE_ID]
data = {CONF_CONTROLLER: self.config}
if self.reauth_config_entry:
self.hass.config_entries.async_update_entry(
self.reauth_config_entry, data=data
)
await self.hass.config_entries.async_reload(
self.reauth_config_entry.entry_id
)
return self.async_abort(reason="reauth_successful")
self.config[CONF_SITE_ID] = user_input[CONF_SITE_ID]
data = {CONF_CONTROLLER: self.config}
for entry in self._async_current_entries():
controller = entry.data[CONF_CONTROLLER]
if (
controller[CONF_HOST] == self.config[CONF_HOST]
and controller[CONF_SITE_ID] == self.config[CONF_SITE_ID]
):
raise AlreadyConfigured
if self.reauth_config_entry:
self.hass.config_entries.async_update_entry(
self.reauth_config_entry, data=data
)
await self.hass.config_entries.async_reload(
self.reauth_config_entry.entry_id
)
return self.async_abort(reason="reauth_successful")
site_nice_name = self.sites[self.config[CONF_SITE_ID]]
return self.async_create_entry(title=site_nice_name, data=data)
for config_entry in self._async_current_entries():
controller_data = config_entry.data[CONF_CONTROLLER]
if (
controller_data[CONF_HOST] != self.config[CONF_HOST]
or controller_data[CONF_SITE_ID] != self.config[CONF_SITE_ID]
):
continue
except AlreadyConfigured:
return self.async_abort(reason="already_configured")
controller = self.hass.data.get(UNIFI_DOMAIN, {}).get(
config_entry.entry_id
)
if controller and controller.available:
return self.async_abort(reason="already_configured")
self.hass.config_entries.async_update_entry(config_entry, data=data)
await self.hass.config_entries.async_reload(config_entry.entry_id)
return self.async_abort(reason="configuration_updated")
site_nice_name = self.sites[self.config[CONF_SITE_ID]]
return self.async_create_entry(title=site_nice_name, data=data)
if len(self.sites) == 1:
return await self.async_step_site({CONF_SITE_ID: next(iter(self.sites))})

View File

@ -21,6 +21,7 @@
},
"abort": {
"already_configured": "Controller site is already configured",
"configuration_updated": "Configuration updated.",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},

View File

@ -97,7 +97,7 @@ async def test_flow_works(hass, aioclient_mock, mock_discovery):
CONF_HOST: "unifi",
CONF_USERNAME: "",
CONF_PASSWORD: "",
CONF_PORT: 8443,
CONF_PORT: 443,
CONF_VERIFY_SSL: False,
}
@ -189,12 +189,9 @@ async def test_flow_works_multiple_sites(hass, aioclient_mock):
assert result["data_schema"]({"site": "site2"})
async def test_flow_fails_site_already_configured(hass, aioclient_mock):
"""Test config flow."""
entry = MockConfigEntry(
domain=UNIFI_DOMAIN, data={"controller": {"host": "1.2.3.4", "site": "site_id"}}
)
entry.add_to_hass(hass)
async def test_flow_raise_already_configured(hass, aioclient_mock):
"""Test config flow aborts since a connected config entry already exists."""
await setup_unifi_integration(hass)
result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, context={"source": "user"}
@ -235,6 +232,58 @@ async def test_flow_fails_site_already_configured(hass, aioclient_mock):
assert result["reason"] == "already_configured"
async def test_flow_aborts_configuration_updated(hass, aioclient_mock):
"""Test config flow aborts since a connected config entry already exists."""
entry = MockConfigEntry(
domain=UNIFI_DOMAIN, data={"controller": {"host": "1.2.3.4", "site": "office"}}
)
entry.add_to_hass(hass)
entry = MockConfigEntry(
domain=UNIFI_DOMAIN, data={"controller": {"host": "1.2.3.4", "site": "site_id"}}
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, context={"source": "user"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
aioclient_mock.get("https://1.2.3.4:1234", status=302)
aioclient_mock.post(
"https://1.2.3.4:1234/api/login",
json={"data": "login successful", "meta": {"rc": "ok"}},
headers={"content-type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
"https://1.2.3.4:1234/api/self/sites",
json={
"data": [{"desc": "Site name", "name": "site_id", "role": "admin"}],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
with patch("homeassistant.components.unifi.async_setup_entry"):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username",
CONF_PASSWORD: "password",
CONF_PORT: 1234,
CONF_VERIFY_SSL: True,
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "configuration_updated"
async def test_flow_fails_user_credentials_faulty(hass, aioclient_mock):
"""Test config flow."""
result = await hass.config_entries.flow.async_init(