From 0ec89ae5da532257db2dc64b5751046d25c27e56 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 16 Feb 2022 11:15:31 -0600 Subject: [PATCH] Teach _async_abort_entries_match about entry options (#66662) --- homeassistant/config_entries.py | 6 +++++- tests/test_config_entries.py | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index a0017c36684..400cea3f78c 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -2,6 +2,7 @@ from __future__ import annotations import asyncio +from collections import ChainMap from collections.abc import Awaitable, Callable, Iterable, Mapping from contextvars import ContextVar import dataclasses @@ -1211,7 +1212,10 @@ class ConfigFlow(data_entry_flow.FlowHandler): if match_dict is None: match_dict = {} # Match any entry for entry in self._async_current_entries(include_ignore=False): - if all(item in entry.data.items() for item in match_dict.items()): + if all( + item in ChainMap(entry.options, entry.data).items() # type: ignore + for item in match_dict.items() + ): raise data_entry_flow.AbortFlow("already_configured") @callback diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index cad92a5d92d..b62e9bffbce 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -2893,12 +2893,23 @@ async def test_setup_retrying_during_shutdown(hass): [ ({}, "already_configured"), ({"host": "3.3.3.3"}, "no_match"), + ({"vendor": "no_match"}, "no_match"), ({"host": "3.4.5.6"}, "already_configured"), ({"host": "3.4.5.6", "ip": "3.4.5.6"}, "no_match"), ({"host": "3.4.5.6", "ip": "1.2.3.4"}, "already_configured"), ({"host": "3.4.5.6", "ip": "1.2.3.4", "port": 23}, "already_configured"), + ( + {"host": "9.9.9.9", "ip": "6.6.6.6", "port": 12, "vendor": "zoo"}, + "already_configured", + ), + ({"vendor": "zoo"}, "already_configured"), ({"ip": "9.9.9.9"}, "already_configured"), ({"ip": "7.7.7.7"}, "no_match"), # ignored + ({"vendor": "data"}, "no_match"), + ( + {"vendor": "options"}, + "already_configured", + ), # ensure options takes precedence over data ], ) async def test__async_abort_entries_match(hass, manager, matchers, reason): @@ -2917,6 +2928,16 @@ async def test__async_abort_entries_match(hass, manager, matchers, reason): source=config_entries.SOURCE_IGNORE, data={"ip": "7.7.7.7", "host": "4.5.6.7", "port": 23}, ).add_to_hass(hass) + MockConfigEntry( + domain="comp", + data={"ip": "6.6.6.6", "host": "9.9.9.9", "port": 12}, + options={"vendor": "zoo"}, + ).add_to_hass(hass) + MockConfigEntry( + domain="comp", + data={"vendor": "data"}, + options={"vendor": "options"}, + ).add_to_hass(hass) mock_setup_entry = AsyncMock(return_value=True)