Use ConfigFlow.has_matching_flow to deduplicate lifx flows (#127163)

This commit is contained in:
Erik Montnemery 2024-10-01 11:20:50 +02:00 committed by GitHub
parent b12f3e5aff
commit 4ceff8cabf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 7 deletions

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
import socket import socket
from typing import Any from typing import Any, Self
from aiolifx.aiolifx import Light from aiolifx.aiolifx import Light
from aiolifx.connection import LIFXConnection from aiolifx.connection import LIFXConnection
@ -41,6 +41,8 @@ class LifXConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1 VERSION = 1
host: str | None = None
def __init__(self) -> None: def __init__(self) -> None:
"""Initialize the config flow.""" """Initialize the config flow."""
self._discovered_devices: dict[str, Light] = {} self._discovered_devices: dict[str, Light] = {}
@ -90,11 +92,8 @@ class LifXConfigFlow(ConfigFlow, domain=DOMAIN):
) -> ConfigFlowResult: ) -> ConfigFlowResult:
"""Handle any discovery.""" """Handle any discovery."""
self._async_abort_entries_match({CONF_HOST: host}) self._async_abort_entries_match({CONF_HOST: host})
self.context[CONF_HOST] = host self.host = host
if any( if self.hass.config_entries.flow.async_has_matching_flow(self):
progress.get("context", {}).get(CONF_HOST) == host
for progress in self._async_in_progress()
):
return self.async_abort(reason="already_in_progress") return self.async_abort(reason="already_in_progress")
if not ( if not (
device := await self._async_try_connect( device := await self._async_try_connect(
@ -105,6 +104,10 @@ class LifXConfigFlow(ConfigFlow, domain=DOMAIN):
self._discovered_device = device self._discovered_device = device
return await self.async_step_discovery_confirm() return await self.async_step_discovery_confirm()
def is_matching(self, other_flow: Self) -> bool:
"""Return True if other_flow is matching this flow."""
return other_flow.host == self.host
@callback @callback
def _async_discovered_pending_migration(self) -> bool: def _async_discovered_pending_migration(self) -> bool:
"""Check if a discovered device is pending migration.""" """Check if a discovered device is pending migration."""

View File

@ -10,6 +10,7 @@ import pytest
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components import dhcp, zeroconf from homeassistant.components import dhcp, zeroconf
from homeassistant.components.lifx import DOMAIN from homeassistant.components.lifx import DOMAIN
from homeassistant.components.lifx.config_flow import LifXConfigFlow
from homeassistant.components.lifx.const import CONF_SERIAL from homeassistant.components.lifx.const import CONF_SERIAL
from homeassistant.const import CONF_DEVICE, CONF_HOST from homeassistant.const import CONF_DEVICE, CONF_HOST
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -369,7 +370,18 @@ async def test_discovered_by_discovery_and_dhcp(hass: HomeAssistant) -> None:
assert result2["type"] is FlowResultType.ABORT assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "already_in_progress" assert result2["reason"] == "already_in_progress"
with _patch_discovery(), _patch_config_flow_try_connect(): real_is_matching = LifXConfigFlow.is_matching
return_values = []
def is_matching(self, other_flow) -> bool:
return_values.append(real_is_matching(self, other_flow))
return return_values[-1]
with (
_patch_discovery(),
_patch_config_flow_try_connect(),
patch.object(LifXConfigFlow, "is_matching", wraps=is_matching, autospec=True),
):
result3 = await hass.config_entries.flow.async_init( result3 = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={"source": config_entries.SOURCE_DHCP}, context={"source": config_entries.SOURCE_DHCP},
@ -380,6 +392,8 @@ async def test_discovered_by_discovery_and_dhcp(hass: HomeAssistant) -> None:
await hass.async_block_till_done() await hass.async_block_till_done()
assert result3["type"] is FlowResultType.ABORT assert result3["type"] is FlowResultType.ABORT
assert result3["reason"] == "already_in_progress" assert result3["reason"] == "already_in_progress"
# Ensure the is_matching method returned True
assert return_values == [True]
with ( with (
_patch_discovery(no_device=True), _patch_discovery(no_device=True),