mirror of
https://github.com/Electric-Special/ha-core.git
synced 2026-03-21 03:03:17 +01:00
Skip ignored discovery entries when showing migrate/setup config flow steps for ZHA and Hardware (#152895)
This commit is contained in:
@@ -123,8 +123,12 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
||||
) -> ConfigFlowResult:
|
||||
"""Pick Thread or Zigbee firmware."""
|
||||
# Determine if ZHA or Thread are already configured to present migrate options
|
||||
zha_entries = self.hass.config_entries.async_entries(ZHA_DOMAIN)
|
||||
otbr_entries = self.hass.config_entries.async_entries(OTBR_DOMAIN)
|
||||
zha_entries = self.hass.config_entries.async_entries(
|
||||
ZHA_DOMAIN, include_ignore=False
|
||||
)
|
||||
otbr_entries = self.hass.config_entries.async_entries(
|
||||
OTBR_DOMAIN, include_ignore=False
|
||||
)
|
||||
|
||||
return self.async_show_menu(
|
||||
step_id="pick_firmware",
|
||||
|
||||
@@ -364,7 +364,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
|
||||
if user_input is not None or self._radio_mgr.radio_type in RECOMMENDED_RADIOS:
|
||||
# ZHA disables the single instance check and will decide at runtime if we
|
||||
# are migrating or setting up from scratch
|
||||
if self.hass.config_entries.async_entries(DOMAIN):
|
||||
if self.hass.config_entries.async_entries(DOMAIN, include_ignore=False):
|
||||
return await self.async_step_choose_migration_strategy()
|
||||
return await self.async_step_choose_setup_strategy()
|
||||
|
||||
@@ -386,7 +386,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
|
||||
# Allow onboarding for new users to just create a new network automatically
|
||||
if (
|
||||
not onboarding.async_is_onboarded(self.hass)
|
||||
and not self.hass.config_entries.async_entries(DOMAIN)
|
||||
and not self.hass.config_entries.async_entries(DOMAIN, include_ignore=False)
|
||||
and not self._radio_mgr.backups
|
||||
):
|
||||
return await self.async_step_setup_strategy_recommended()
|
||||
@@ -438,7 +438,9 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
|
||||
"""Erase the old radio's network settings before migration."""
|
||||
|
||||
# Like in the options flow, pull the correct settings from the config entry
|
||||
config_entries = self.hass.config_entries.async_entries(DOMAIN)
|
||||
config_entries = self.hass.config_entries.async_entries(
|
||||
DOMAIN, include_ignore=False
|
||||
)
|
||||
|
||||
if config_entries:
|
||||
assert len(config_entries) == 1
|
||||
@@ -697,7 +699,9 @@ class ZhaConfigFlowHandler(BaseZhaFlow, ConfigFlow, domain=DOMAIN):
|
||||
|
||||
self._set_confirm_only()
|
||||
|
||||
zha_config_entries = self.hass.config_entries.async_entries(DOMAIN)
|
||||
zha_config_entries = self.hass.config_entries.async_entries(
|
||||
DOMAIN, include_ignore=False
|
||||
)
|
||||
|
||||
# Without confirmation, discovery can automatically progress into parts of the
|
||||
# config flow logic that interacts with hardware.
|
||||
@@ -866,7 +870,9 @@ class ZhaConfigFlowHandler(BaseZhaFlow, ConfigFlow, domain=DOMAIN):
|
||||
|
||||
# ZHA is still single instance only, even though we use discovery to allow for
|
||||
# migrating to a new radio
|
||||
zha_config_entries = self.hass.config_entries.async_entries(DOMAIN)
|
||||
zha_config_entries = self.hass.config_entries.async_entries(
|
||||
DOMAIN, include_ignore=False
|
||||
)
|
||||
data = await self._get_config_entry_data()
|
||||
|
||||
if len(zha_config_entries) == 1:
|
||||
|
||||
@@ -26,7 +26,13 @@ from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult, OptionsFlow
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_IGNORE,
|
||||
SOURCE_USER,
|
||||
ConfigEntry,
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
@@ -1100,3 +1106,59 @@ async def test_config_flow_thread_migrate_handler(hass: HomeAssistant) -> None:
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["progress_action"] == "install_firmware"
|
||||
assert result["step_id"] == "install_thread_firmware"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("zha_source", "otbr_source", "expected_menu"),
|
||||
[
|
||||
(
|
||||
SOURCE_USER,
|
||||
SOURCE_USER,
|
||||
["pick_firmware_zigbee_migrate", "pick_firmware_thread_migrate"],
|
||||
),
|
||||
(
|
||||
SOURCE_IGNORE,
|
||||
SOURCE_USER,
|
||||
["pick_firmware_zigbee", "pick_firmware_thread_migrate"],
|
||||
),
|
||||
(
|
||||
SOURCE_USER,
|
||||
SOURCE_IGNORE,
|
||||
["pick_firmware_zigbee_migrate", "pick_firmware_thread"],
|
||||
),
|
||||
(
|
||||
SOURCE_IGNORE,
|
||||
SOURCE_IGNORE,
|
||||
["pick_firmware_zigbee", "pick_firmware_thread"],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_config_flow_pick_firmware_with_ignored_entries(
|
||||
hass: HomeAssistant, zha_source: str, otbr_source: str, expected_menu: str
|
||||
) -> None:
|
||||
"""Test that ignored entries are properly excluded from migration menu options."""
|
||||
zha_entry = MockConfigEntry(
|
||||
domain="zha",
|
||||
data={"device": {"path": "/dev/ttyUSB1"}},
|
||||
title="ZHA",
|
||||
source=zha_source,
|
||||
)
|
||||
zha_entry.add_to_hass(hass)
|
||||
|
||||
otbr_entry = MockConfigEntry(
|
||||
domain="otbr",
|
||||
data={"url": "http://192.168.1.100:8081"},
|
||||
title="OTBR",
|
||||
source=otbr_source,
|
||||
)
|
||||
otbr_entry.add_to_hass(hass)
|
||||
|
||||
# Set up the flow
|
||||
init_result = await hass.config_entries.flow.async_init(
|
||||
TEST_DOMAIN, context={"source": "hardware"}
|
||||
)
|
||||
|
||||
assert init_result["type"] is FlowResultType.MENU
|
||||
assert init_result["step_id"] == "pick_firmware"
|
||||
|
||||
assert init_result["menu_options"] == expected_menu
|
||||
|
||||
@@ -2378,3 +2378,52 @@ async def test_formation_strategy_restore_manual_backup_overwrite_ieee_ezsp_writ
|
||||
|
||||
assert mock_restore_backup.call_count == 1
|
||||
assert mock_restore_backup.mock_calls[0].kwargs["overwrite_ieee"] is True
|
||||
|
||||
|
||||
@patch(f"bellows.{PROBE_FUNCTION_PATH}", AsyncMock(return_value=True))
|
||||
async def test_migrate_setup_options_with_ignored_discovery(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Test that ignored discovery info is migrated to options."""
|
||||
|
||||
# Ignored ZHA
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="AAAA:AAAA_1234_test_zigbee radio",
|
||||
data={
|
||||
CONF_DEVICE: {
|
||||
CONF_DEVICE_PATH: "/dev/ttyUSB1",
|
||||
CONF_BAUDRATE: 115200,
|
||||
CONF_FLOW_CONTROL: None,
|
||||
}
|
||||
},
|
||||
source=config_entries.SOURCE_IGNORE,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
# Set up one discovery entry
|
||||
discovery_info = UsbServiceInfo(
|
||||
device="/dev/ttyZIGBEE",
|
||||
pid="BBBB",
|
||||
vid="BBBB",
|
||||
serial_number="5678",
|
||||
description="zigbee radio",
|
||||
manufacturer="test manufacturer",
|
||||
)
|
||||
discovery_result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USB}, data=discovery_info
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Progress the discovery
|
||||
confirm_result = await hass.config_entries.flow.async_configure(
|
||||
discovery_result["flow_id"], user_input={}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# We only show "setup" options, not "migrate"
|
||||
assert confirm_result["step_id"] == "choose_setup_strategy"
|
||||
assert confirm_result["menu_options"] == [
|
||||
"setup_strategy_recommended",
|
||||
"setup_strategy_advanced",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user