Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions homeassistant/components/keenetic_ndms2/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
from ndms2_client import Client, ConnectionException, InterfaceInfo, TelnetConnection
import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
from homeassistant.config_entries import (
SOURCE_RECONFIGURE,
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
)
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
Expand Down Expand Up @@ -45,7 +50,7 @@ class KeeneticFlowHandler(ConfigFlow, domain=DOMAIN):

VERSION = 1

host: str | bytes | None = None
_host: str | bytes | None = None

@staticmethod
@callback
Expand All @@ -61,8 +66,9 @@ async def async_step_user(
"""Handle a flow initialized by the user."""
errors = {}
if user_input is not None:
host = self.host or user_input[CONF_HOST]
self._async_abort_entries_match({CONF_HOST: host})
host = self._host or user_input[CONF_HOST]
if self.source != SOURCE_RECONFIGURE:
self._async_abort_entries_match({CONF_HOST: host})

_client = Client(
TelnetConnection(
Expand All @@ -81,12 +87,17 @@ async def async_step_user(
except ConnectionException:
errors["base"] = "cannot_connect"
else:
if self.source == SOURCE_RECONFIGURE:
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data={CONF_HOST: host, **user_input},
)
return self.async_create_entry(
title=router_info.name, data={CONF_HOST: host, **user_input}
)

host_schema: VolDictType = (
{vol.Required(CONF_HOST): str} if not self.host else {}
{vol.Required(CONF_HOST): str} if not self._host else {}
)

return self.async_show_form(
Expand All @@ -102,6 +113,15 @@ async def async_step_user(
errors=errors,
)

async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration."""
existing_entry_data = dict(self._get_reconfigure_entry().data)
self._host = existing_entry_data[CONF_HOST]

return await self.async_step_user(user_input)

async def async_step_ssdp(
self, discovery_info: SsdpServiceInfo
) -> ConfigFlowResult:
Expand All @@ -124,7 +144,7 @@ async def async_step_ssdp(

self._async_abort_entries_match({CONF_HOST: host})

self.host = host
self._host = host
self.context["title_placeholders"] = {
"name": friendly_name,
"host": host,
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/keenetic_ndms2/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"no_udn": "SSDP discovery info has no UDN",
"not_keenetic_ndms2": "Discovered device is not a Keenetic router"
"not_keenetic_ndms2": "Discovered device is not a Keenetic router",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
}
},
"options": {
Expand Down
6 changes: 6 additions & 0 deletions tests/components/keenetic_ndms2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
CONF_PORT: 23,
}

MOCK_RECONFIGURE = {
CONF_USERNAME: "user1",
CONF_PASSWORD: "pass1",
CONF_PORT: 123,
}

MOCK_OPTIONS = {
CONF_SCAN_INTERVAL: 15,
const.CONF_CONSIDER_HOME: 150,
Expand Down
37 changes: 36 additions & 1 deletion tests/components/keenetic_ndms2/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
ATTR_UPNP_UDN,
)

from . import MOCK_DATA, MOCK_NAME, MOCK_OPTIONS, MOCK_SSDP_DISCOVERY_INFO
from . import (
MOCK_DATA,
MOCK_IP,
MOCK_NAME,
MOCK_OPTIONS,
MOCK_RECONFIGURE,
MOCK_SSDP_DISCOVERY_INFO,
)

from tests.common import MockConfigEntry

Expand Down Expand Up @@ -74,6 +81,34 @@ async def test_flow_works(hass: HomeAssistant, connect) -> None:
assert len(mock_setup_entry.mock_calls) == 1


async def test_reconfigure(hass: HomeAssistant, connect) -> None:
"""Test reconfigure flow."""
entry = MockConfigEntry(domain=keenetic.DOMAIN, data=MOCK_DATA)
entry.add_to_hass(hass)

result = await entry.start_reconfigure_flow(hass)

assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"

with patch(
"homeassistant.components.keenetic_ndms2.async_setup_entry", return_value=True
) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_RECONFIGURE,
)
await hass.async_block_till_done()

assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reconfigure_successful"
assert entry.data == {
CONF_HOST: MOCK_IP,
**MOCK_RECONFIGURE,
}
assert len(mock_setup_entry.mock_calls) == 1


async def test_options(hass: HomeAssistant) -> None:
"""Test updating options."""
entry = MockConfigEntry(domain=keenetic.DOMAIN, data=MOCK_DATA)
Expand Down