mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 14:57:09 +00:00
Set and check unique id of config in NUT (#141783)
* Set and check unique id in config * Update homeassistant/components/nut/config_flow.py Set unique ID and abort only if value is defined Co-authored-by: J. Nick Koston <nick+github@koston.org> * Add duplicate ID test case for multiple devices * Add unique ID check to config flow step for UPS * Update homeassistant/components/nut/__init__.py Fix to only set config_entries unique ID if not None Co-authored-by: J. Nick Koston <nick+github@koston.org> * Remove duplicate config flow call --------- Co-authored-by: J. Nick Koston <nick+github@koston.org> Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
3ab2cd3fb7
commit
1c16fb8e42
@ -121,6 +121,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
|
|||||||
if unique_id is None:
|
if unique_id is None:
|
||||||
unique_id = entry.entry_id
|
unique_id = entry.entry_id
|
||||||
|
|
||||||
|
elif entry.unique_id is None:
|
||||||
|
hass.config_entries.async_update_entry(entry, unique_id=unique_id)
|
||||||
|
|
||||||
if username is not None and password is not None:
|
if username is not None and password is not None:
|
||||||
# Dynamically add outlet integration commands
|
# Dynamically add outlet integration commands
|
||||||
additional_integration_commands = set()
|
additional_integration_commands = set()
|
||||||
|
@ -22,7 +22,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.data_entry_flow import AbortFlow
|
from homeassistant.data_entry_flow import AbortFlow
|
||||||
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||||
|
|
||||||
from . import PyNUTData
|
from . import PyNUTData, _unique_id_from_status
|
||||||
from .const import DEFAULT_HOST, DEFAULT_PORT, DOMAIN
|
from .const import DEFAULT_HOST, DEFAULT_PORT, DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -119,6 +119,11 @@ class NutConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
if self._host_port_alias_already_configured(nut_config):
|
if self._host_port_alias_already_configured(nut_config):
|
||||||
return self.async_abort(reason="already_configured")
|
return self.async_abort(reason="already_configured")
|
||||||
|
|
||||||
|
if unique_id := _unique_id_from_status(info["available_resources"]):
|
||||||
|
await self.async_set_unique_id(unique_id)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
|
||||||
title = _format_host_port_alias(nut_config)
|
title = _format_host_port_alias(nut_config)
|
||||||
return self.async_create_entry(title=title, data=nut_config)
|
return self.async_create_entry(title=title, data=nut_config)
|
||||||
|
|
||||||
@ -141,8 +146,13 @@ class NutConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
self.nut_config.update(user_input)
|
self.nut_config.update(user_input)
|
||||||
if self._host_port_alias_already_configured(nut_config):
|
if self._host_port_alias_already_configured(nut_config):
|
||||||
return self.async_abort(reason="already_configured")
|
return self.async_abort(reason="already_configured")
|
||||||
_, errors, placeholders = await self._async_validate_or_error(nut_config)
|
|
||||||
|
info, errors, placeholders = await self._async_validate_or_error(nut_config)
|
||||||
if not errors:
|
if not errors:
|
||||||
|
if unique_id := _unique_id_from_status(info["available_resources"]):
|
||||||
|
await self.async_set_unique_id(unique_id)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
|
||||||
title = _format_host_port_alias(nut_config)
|
title = _format_host_port_alias(nut_config)
|
||||||
return self.async_create_entry(title=title, data=nut_config)
|
return self.async_create_entry(title=title, data=nut_config)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||||
|
|
||||||
from .util import _get_mock_nutclient
|
from .util import _get_mock_nutclient, async_init_integration
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
@ -524,6 +524,104 @@ async def test_abort_if_already_setup(hass: HomeAssistant) -> None:
|
|||||||
assert result2["reason"] == "already_configured"
|
assert result2["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_abort_duplicate_unique_ids(hass: HomeAssistant) -> None:
|
||||||
|
"""Test we abort if unique_id is already setup."""
|
||||||
|
|
||||||
|
list_vars = {
|
||||||
|
"device.mfr": "Some manufacturer",
|
||||||
|
"device.model": "Some model",
|
||||||
|
"device.serial": "0000-1",
|
||||||
|
}
|
||||||
|
await async_init_integration(
|
||||||
|
hass,
|
||||||
|
list_ups={"ups1": "UPS 1"},
|
||||||
|
list_vars=list_vars,
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_pynut = _get_mock_nutclient(list_ups={"ups2": "UPS 2"}, list_vars=list_vars)
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.nut.AIONUTClient",
|
||||||
|
return_value=mock_pynut,
|
||||||
|
):
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_HOST: "1.1.1.1",
|
||||||
|
CONF_PORT: 2222,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] is FlowResultType.ABORT
|
||||||
|
assert result2["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_abort_multiple_ups_duplicate_unique_ids(hass: HomeAssistant) -> None:
|
||||||
|
"""Test we abort on multiple devices if unique_id is already setup."""
|
||||||
|
|
||||||
|
list_vars = {
|
||||||
|
"device.mfr": "Some manufacturer",
|
||||||
|
"device.model": "Some model",
|
||||||
|
"device.serial": "0000-1",
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_pynut = _get_mock_nutclient(
|
||||||
|
list_ups={"ups2": "UPS 2", "ups3": "UPS 3"}, list_vars=list_vars
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.nut.AIONUTClient",
|
||||||
|
return_value=mock_pynut,
|
||||||
|
):
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_HOST: "1.1.1.1",
|
||||||
|
CONF_PORT: 2222,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["step_id"] == "ups"
|
||||||
|
assert result2["type"] is FlowResultType.FORM
|
||||||
|
|
||||||
|
await async_init_integration(
|
||||||
|
hass,
|
||||||
|
list_ups={"ups1": "UPS 1"},
|
||||||
|
list_vars=list_vars,
|
||||||
|
)
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.nut.AIONUTClient",
|
||||||
|
return_value=mock_pynut,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.nut.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
result3 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{CONF_ALIAS: "ups2"},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result3["type"] is FlowResultType.ABORT
|
||||||
|
assert result3["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_abort_if_already_setup_alias(hass: HomeAssistant) -> None:
|
async def test_abort_if_already_setup_alias(hass: HomeAssistant) -> None:
|
||||||
"""Test we abort if component is already setup with same alias."""
|
"""Test we abort if component is already setup with same alias."""
|
||||||
config_entry = MockConfigEntry(
|
config_entry = MockConfigEntry(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user