From 375d47ee3abb13c0ca81db16050a66d404330573 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 2 Oct 2024 08:25:46 +0200 Subject: [PATCH] Use ConfigFlow.has_matching_flow to deduplicate yeelight flows (#127165) --- .../components/yeelight/config_flow.py | 14 ++++++++------ tests/components/yeelight/test_config_flow.py | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/yeelight/config_flow.py b/homeassistant/components/yeelight/config_flow.py index cafed622300565..5438414ea61634 100644 --- a/homeassistant/components/yeelight/config_flow.py +++ b/homeassistant/components/yeelight/config_flow.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from typing import Any +from typing import Any, Self from urllib.parse import urlparse import voluptuous as vol @@ -53,7 +53,7 @@ class YeelightConfigFlow(ConfigFlow, domain=DOMAIN): VERSION = 1 - _discovered_ip: str + _discovered_ip: str = "" _discovered_model: str @staticmethod @@ -119,10 +119,8 @@ async def _async_handle_discovery_with_unique_id(self) -> ConfigFlowResult: async def _async_handle_discovery(self) -> ConfigFlowResult: """Handle any discovery.""" - self.context[CONF_HOST] = self._discovered_ip - for progress in self._async_in_progress(): - if progress.get("context", {}).get(CONF_HOST) == self._discovered_ip: - return self.async_abort(reason="already_in_progress") + if self.hass.config_entries.flow.async_has_matching_flow(self): + return self.async_abort(reason="already_in_progress") self._async_abort_entries_match({CONF_HOST: self._discovered_ip}) try: @@ -140,6 +138,10 @@ async def _async_handle_discovery(self) -> ConfigFlowResult: ) 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._discovered_ip == self._discovered_ip # noqa: SLF001 + async def async_step_discovery_confirm( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: diff --git a/tests/components/yeelight/test_config_flow.py b/tests/components/yeelight/test_config_flow.py index 4d788ba8258344..1acb553af3d6f4 100644 --- a/tests/components/yeelight/test_config_flow.py +++ b/tests/components/yeelight/test_config_flow.py @@ -7,7 +7,11 @@ from homeassistant import config_entries from homeassistant.components import dhcp, ssdp, zeroconf -from homeassistant.components.yeelight.config_flow import MODEL_UNKNOWN, CannotConnect +from homeassistant.components.yeelight.config_flow import ( + MODEL_UNKNOWN, + CannotConnect, + YeelightConfigFlow, +) from homeassistant.components.yeelight.const import ( CONF_DETECTED_MODEL, CONF_MODE_MUSIC, @@ -503,10 +507,20 @@ async def test_discovered_by_homekit_and_dhcp(hass: HomeAssistant) -> None: assert result["type"] is FlowResultType.FORM assert result["errors"] is None + real_is_matching = YeelightConfigFlow.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_discovery_interval(), patch(f"{MODULE_CONFIG_FLOW}.AsyncBulb", return_value=mocked_bulb), + patch.object( + YeelightConfigFlow, "is_matching", wraps=is_matching, autospec=True + ), ): result2 = await hass.config_entries.flow.async_init( DOMAIN, @@ -518,6 +532,8 @@ async def test_discovered_by_homekit_and_dhcp(hass: HomeAssistant) -> None: await hass.async_block_till_done() assert result2["type"] is FlowResultType.ABORT assert result2["reason"] == "already_in_progress" + # Ensure the is_matching method returned True + assert return_values == [True] with ( _patch_discovery(),