From 7d61cb1ef5797f2169d729207c9f951c01831ae8 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 25 Sep 2024 20:29:14 +0200 Subject: [PATCH] Remove unignore flow (#126765) --- homeassistant/config_entries.py | 26 +-- tests/components/bluetooth/test_manager.py | 215 +-------------------- tests/components/dhcp/test_init.py | 112 +---------- tests/components/ssdp/test_init.py | 123 +----------- tests/components/zeroconf/test_init.py | 158 +-------------- tests/test_config_entries.py | 133 ------------- 6 files changed, 37 insertions(+), 730 deletions(-) diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index be7f74582eb..404ae1c91dd 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -106,11 +106,6 @@ SOURCE_ZEROCONF = "zeroconf" # source and while it exists normal discoveries with the same unique id are ignored. SOURCE_IGNORE = "ignore" -# This is used when a user uses the "Stop Ignoring" button in the UI (the -# config_entries/ignore_flow websocket command). It's triggered after the -# "ignore" config entry has been removed and unloaded. -SOURCE_UNIGNORE = "unignore" - # This is used to signal that re-authentication is required by the user. SOURCE_REAUTH = "reauth" @@ -179,7 +174,6 @@ DISCOVERY_SOURCES = { SOURCE_INTEGRATION_DISCOVERY, SOURCE_MQTT, SOURCE_SSDP, - SOURCE_UNIGNORE, SOURCE_USB, SOURCE_ZEROCONF, } @@ -1264,7 +1258,7 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager[ConfigFlowResult]): # a single config entry, but which already has an entry if ( context.get("source") - not in {SOURCE_IGNORE, SOURCE_REAUTH, SOURCE_UNIGNORE, SOURCE_RECONFIGURE} + not in {SOURCE_IGNORE, SOURCE_REAUTH, SOURCE_RECONFIGURE} and self.config_entries.async_has_entries(handler, include_ignore=False) and await _support_single_config_entry_only(self.hass, handler) ): @@ -1855,20 +1849,6 @@ class ConfigEntries: issue_id = f"config_entry_reauth_{entry.domain}_{entry.entry_id}" ir.async_delete_issue(self.hass, HOMEASSISTANT_DOMAIN, issue_id) - # After we have fully removed an "ignore" config entry we can try and rediscover - # it so that a user is able to immediately start configuring it. We do this by - # starting a new flow with the 'unignore' step. If the integration doesn't - # implement async_step_unignore then this will be a no-op. - if entry.source == SOURCE_IGNORE: - self.hass.async_create_task_internal( - self.hass.config_entries.flow.async_init( - entry.domain, - context={"source": SOURCE_UNIGNORE}, - data={"unique_id": entry.unique_id}, - ), - f"config entry unignore {entry.title} {entry.domain} {entry.unique_id}", - ) - self._async_dispatch(ConfigEntryChange.REMOVED, entry) for discovery_domain in entry.discovery_keys: async_dispatcher_send_internal( @@ -2544,10 +2524,6 @@ class ConfigFlow(ConfigEntryBaseFlow): await self.async_set_unique_id(user_input["unique_id"], raise_on_progress=False) return self.async_create_entry(title=user_input["title"], data={}) - async def async_step_unignore(self, user_input: dict[str, Any]) -> ConfigFlowResult: - """Rediscover a config entry by it's unique_id.""" - return self.async_abort(reason="not_implemented") - async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: diff --git a/tests/components/bluetooth/test_manager.py b/tests/components/bluetooth/test_manager.py index caff31d74d2..2542b88cef3 100644 --- a/tests/components/bluetooth/test_manager.py +++ b/tests/components/bluetooth/test_manager.py @@ -1335,7 +1335,14 @@ async def test_set_fallback_interval_big(hass: HomeAssistant) -> None: ), ], ) -@pytest.mark.parametrize("entry_source", [config_entries.SOURCE_IGNORE]) +@pytest.mark.parametrize( + "entry_source", + [ + config_entries.SOURCE_BLUETOOTH, + config_entries.SOURCE_IGNORE, + config_entries.SOURCE_USER, + ], +) async def test_bluetooth_rediscover( hass: HomeAssistant, entry_domain: str, @@ -1386,205 +1393,6 @@ async def test_bluetooth_rediscover( BluetoothScanningMode.ACTIVE, ) - class FakeScanner(BaseHaRemoteScanner): - def inject_advertisement( - self, device: BLEDevice, advertisement_data: AdvertisementData - ) -> None: - """Inject an advertisement.""" - self._async_on_advertisement( - device.address, - advertisement_data.rssi, - device.name, - advertisement_data.service_uuids, - advertisement_data.service_data, - advertisement_data.manufacturer_data, - advertisement_data.tx_power, - {"scanner_specific_data": "test"}, - MONOTONIC_TIME(), - ) - - def clear_all_devices(self) -> None: - """Clear all devices.""" - self._discovered_device_advertisement_datas.clear() - self._discovered_device_timestamps.clear() - self._previous_service_info.clear() - - connector = ( - HaBluetoothConnector(MockBleakClient, "mock_bleak_client", lambda: False), - ) - non_connectable_scanner = FakeScanner( - "connectable", - "connectable", - connector, - False, - ) - unsetup_connectable_scanner = non_connectable_scanner.async_setup() - cancel_connectable_scanner = _get_manager().async_register_scanner( - non_connectable_scanner - ) - with patch.object(hass.config_entries.flow, "async_init") as mock_config_flow: - non_connectable_scanner.inject_advertisement( - switchbot_device_non_connectable, switchbot_device_adv - ) - await hass.async_block_till_done() - - expected_context = { - "discovery_key": DiscoveryKey( - domain="bluetooth", key="44:44:33:11:23:45", version=1 - ), - "source": "bluetooth", - } - assert len(mock_config_flow.mock_calls) == 1 - assert mock_config_flow.mock_calls[0][1][0] == "switchbot" - assert mock_config_flow.mock_calls[0][2]["context"] == expected_context - - hass.config.components.add(entry_domain) - mock_integration(hass, MockModule(entry_domain)) - - entry = MockConfigEntry( - domain=entry_domain, - discovery_keys=entry_discovery_keys, - unique_id="mock-unique-id", - state=config_entries.ConfigEntryState.LOADED, - source=entry_source, - ) - entry.add_to_hass(hass) - - assert ( - async_ble_device_from_address(hass, "44:44:33:11:23:45", False) is not None - ) - assert async_scanner_count(hass, connectable=False) == 1 - assert len(callbacks) == 1 - - assert ( - "44:44:33:11:23:45" - in non_connectable_scanner.discovered_devices_and_advertisement_data - ) - - await hass.config_entries.async_remove(entry.entry_id) - await hass.async_block_till_done() - - assert ( - async_ble_device_from_address(hass, "44:44:33:11:23:45", False) is not None - ) - assert async_scanner_count(hass, connectable=False) == 1 - assert len(callbacks) == 1 - - assert len(mock_config_flow.mock_calls) == 3 - assert mock_config_flow.mock_calls[1][1][0] == entry_domain - assert mock_config_flow.mock_calls[1][2]["context"] == { - "source": "unignore", - } - assert mock_config_flow.mock_calls[2][1][0] == "switchbot" - assert mock_config_flow.mock_calls[2][2]["context"] == expected_context - - cancel() - unsetup_connectable_scanner() - cancel_connectable_scanner() - - -@pytest.mark.usefixtures("mock_bluetooth_adapters") -@pytest.mark.parametrize( - ( - "entry_domain", - "entry_discovery_keys", - ), - [ - # Matching discovery key - ( - "switchbot", - { - "bluetooth": ( - DiscoveryKey( - domain="bluetooth", key="44:44:33:11:23:45", version=1 - ), - ) - }, - ), - # Matching discovery key - ( - "switchbot", - { - "bluetooth": ( - DiscoveryKey( - domain="bluetooth", key="44:44:33:11:23:45", version=1 - ), - ), - "other": (DiscoveryKey(domain="other", key="blah", version=1),), - }, - ), - # Matching discovery key, other domain - # Note: Rediscovery is not currently restricted to the domain of the removed - # entry. Such a check can be added if needed. - ( - "comp", - { - "bluetooth": ( - DiscoveryKey( - domain="bluetooth", key="44:44:33:11:23:45", version=1 - ), - ) - }, - ), - ], -) -@pytest.mark.parametrize( - "entry_source", [config_entries.SOURCE_BLUETOOTH, config_entries.SOURCE_USER] -) -async def test_bluetooth_rediscover_2( - hass: HomeAssistant, - entry_domain: str, - entry_discovery_keys: tuple, - entry_source: str, -) -> None: - """Test we reinitiate flows when an ignored config entry is removed. - - This test can be merged with test_zeroconf_rediscover when - async_step_unignore has been removed from the ConfigFlow base class. - """ - mock_bt = [ - { - "domain": "switchbot", - "service_data_uuid": "050a021a-0000-1000-8000-00805f9b34fb", - "connectable": False, - }, - ] - with patch( - "homeassistant.components.bluetooth.async_get_bluetooth", return_value=mock_bt - ): - assert await async_setup_component(hass, bluetooth.DOMAIN, {}) - await hass.async_block_till_done() - - assert async_scanner_count(hass, connectable=False) == 0 - switchbot_device_non_connectable = generate_ble_device( - "44:44:33:11:23:45", - "wohand", - {}, - rssi=-100, - ) - switchbot_device_adv = generate_advertisement_data( - local_name="wohand", - service_uuids=["050a021a-0000-1000-8000-00805f9b34fb"], - service_data={"050a021a-0000-1000-8000-00805f9b34fb": b"\n\xff"}, - manufacturer_data={1: b"\x01"}, - rssi=-100, - ) - callbacks = [] - - def _fake_subscriber( - service_info: BluetoothServiceInfo, - change: BluetoothChange, - ) -> None: - """Fake subscriber for the BleakScanner.""" - callbacks.append((service_info, change)) - - cancel = bluetooth.async_register_callback( - hass, - _fake_subscriber, - {"address": "44:44:33:11:23:45", "connectable": False}, - BluetoothScanningMode.ACTIVE, - ) - class FakeScanner(BaseHaRemoteScanner): def inject_advertisement( self, device: BLEDevice, advertisement_data: AdvertisementData @@ -1847,12 +1655,7 @@ async def test_bluetooth_rediscover_no_match( ) assert async_scanner_count(hass, connectable=False) == 1 assert len(callbacks) == 1 - - assert len(mock_config_flow.mock_calls) == 2 - assert mock_config_flow.mock_calls[1][1][0] == entry_domain - assert mock_config_flow.mock_calls[1][2]["context"] == { - "source": "unignore", - } + assert len(mock_config_flow.mock_calls) == 1 cancel() unsetup_connectable_scanner() diff --git a/tests/components/dhcp/test_init.py b/tests/components/dhcp/test_init.py index 3916a854247..c5dbba43c91 100644 --- a/tests/components/dhcp/test_init.py +++ b/tests/components/dhcp/test_init.py @@ -1201,7 +1201,14 @@ async def test_aiodiscover_finds_new_hosts_after_interval(hass: HomeAssistant) - ), ], ) -@pytest.mark.parametrize("entry_source", [config_entries.SOURCE_IGNORE]) +@pytest.mark.parametrize( + "entry_source", + [ + config_entries.SOURCE_DHCP, + config_entries.SOURCE_IGNORE, + config_entries.SOURCE_USER, + ], +) async def test_dhcp_rediscover( hass: HomeAssistant, entry_domain: str, @@ -1255,105 +1262,6 @@ async def test_dhcp_rediscover( macaddress="b8b7f16db533", ) - with patch.object(hass.config_entries.flow, "async_init") as mock_init: - await hass.config_entries.async_remove(entry.entry_id) - await hass.async_block_till_done() - - assert len(mock_init.mock_calls) == 2 - assert mock_init.mock_calls[0][1][0] == entry_domain - assert mock_init.mock_calls[0][2]["context"] == {"source": "unignore"} - assert mock_init.mock_calls[1][1][0] == "mock-domain" - assert mock_init.mock_calls[1][2]["context"] == expected_context - - -@pytest.mark.parametrize( - ( - "entry_domain", - "entry_discovery_keys", - ), - [ - # Matching discovery key - ( - "mock-domain", - {"dhcp": (DiscoveryKey(domain="dhcp", key="b8b7f16db533", version=1),)}, - ), - # Matching discovery key - ( - "mock-domain", - { - "dhcp": (DiscoveryKey(domain="dhcp", key="b8b7f16db533", version=1),), - "other": (DiscoveryKey(domain="other", key="blah", version=1),), - }, - ), - # Matching discovery key, other domain - # Note: Rediscovery is not currently restricted to the domain of the removed - # entry. Such a check can be added if needed. - ( - "comp", - {"dhcp": (DiscoveryKey(domain="dhcp", key="b8b7f16db533", version=1),)}, - ), - ], -) -@pytest.mark.parametrize( - "entry_source", [config_entries.SOURCE_USER, config_entries.SOURCE_ZEROCONF] -) -async def test_dhcp_rediscover_2( - hass: HomeAssistant, - entry_domain: str, - entry_discovery_keys: tuple, - entry_source: str, -) -> None: - """Test we reinitiate flows when an ignored config entry is removed. - - This test can be merged with test_zeroconf_rediscover when - async_step_unignore has been removed from the ConfigFlow base class. - """ - - entry = MockConfigEntry( - domain=entry_domain, - discovery_keys=entry_discovery_keys, - unique_id="mock-unique-id", - state=config_entries.ConfigEntryState.LOADED, - source=entry_source, - ) - entry.add_to_hass(hass) - - address_data = {} - integration_matchers = dhcp.async_index_integration_matchers( - [{"domain": "mock-domain", "hostname": "connect", "macaddress": "B8B7F1*"}] - ) - packet = Ether(RAW_DHCP_REQUEST) - - async_handle_dhcp_packet = await _async_get_handle_dhcp_packet( - hass, integration_matchers, address_data - ) - rediscovery_watcher = dhcp.RediscoveryWatcher( - hass, address_data, integration_matchers - ) - rediscovery_watcher.async_start() - with patch.object(hass.config_entries.flow, "async_init") as mock_init: - await async_handle_dhcp_packet(packet) - # Ensure no change is ignored - await async_handle_dhcp_packet(packet) - - # Assert the cached MAC address is hexstring without : - assert address_data == { - "b8b7f16db533": {"hostname": "connect", "ip": "192.168.210.56"} - } - - expected_context = { - "discovery_key": DiscoveryKey(domain="dhcp", key="b8b7f16db533", version=1), - "source": config_entries.SOURCE_DHCP, - } - assert len(mock_init.mock_calls) == 1 - assert mock_init.mock_calls[0][1][0] == "mock-domain" - assert mock_init.mock_calls[0][2]["context"] == expected_context - assert mock_init.mock_calls[0][2]["data"] == dhcp.DhcpServiceInfo( - ip="192.168.210.56", - hostname="connect", - macaddress="b8b7f16db533", - ) - with patch.object(hass.config_entries.flow, "async_init") as mock_init: await hass.config_entries.async_remove(entry.entry_id) await hass.async_block_till_done() @@ -1447,6 +1355,4 @@ async def test_dhcp_rediscover_no_match( await hass.config_entries.async_remove(entry.entry_id) await hass.async_block_till_done() - assert len(mock_init.mock_calls) == 1 - assert mock_init.mock_calls[0][1][0] == entry_domain - assert mock_init.mock_calls[0][2]["context"] == {"source": "unignore"} + assert len(mock_init.mock_calls) == 0 diff --git a/tests/components/ssdp/test_init.py b/tests/components/ssdp/test_init.py index 5592f7a6809..aa8d0234246 100644 --- a/tests/components/ssdp/test_init.py +++ b/tests/components/ssdp/test_init.py @@ -938,7 +938,14 @@ async def test_flow_dismiss_on_byebye( ), ], ) -@pytest.mark.parametrize("entry_source", [config_entries.SOURCE_IGNORE]) +@pytest.mark.parametrize( + "entry_source", + [ + config_entries.SOURCE_IGNORE, + config_entries.SOURCE_SSDP, + config_entries.SOURCE_USER, + ], +) async def test_ssdp_rediscover( mock_get_ssdp, hass: HomeAssistant, @@ -999,116 +1006,6 @@ async def test_ssdp_rediscover( await hass.config_entries.async_remove(entry.entry_id) await hass.async_block_till_done() - assert len(mock_flow_init.mock_calls) == 3 - assert mock_flow_init.mock_calls[1][1][0] == entry_domain - assert mock_flow_init.mock_calls[1][2]["context"] == {"source": "unignore"} - assert mock_flow_init.mock_calls[2][1][0] == "mock-domain" - assert mock_flow_init.mock_calls[2][2]["context"] == expected_context - assert ( - mock_flow_init.mock_calls[2][2]["data"] - == mock_flow_init.mock_calls[0][2]["data"] - ) - - -@patch( - "homeassistant.components.ssdp.async_get_ssdp", - return_value={"mock-domain": [{"st": "mock-st"}]}, -) -@pytest.mark.parametrize( - ( - "entry_domain", - "entry_discovery_keys", - ), - [ - # Matching discovery key - ( - "mock-domain", - {"ssdp": (DiscoveryKey(domain="ssdp", key="uuid:mock-udn", version=1),)}, - ), - # Matching discovery key - ( - "mock-domain", - { - "ssdp": (DiscoveryKey(domain="ssdp", key="uuid:mock-udn", version=1),), - "other": (DiscoveryKey(domain="other", key="blah", version=1),), - }, - ), - # Matching discovery key, other domain - # Note: Rediscovery is not currently restricted to the domain of the removed - # entry. Such a check can be added if needed. - ( - "comp", - {"ssdp": (DiscoveryKey(domain="ssdp", key="uuid:mock-udn", version=1),)}, - ), - ], -) -@pytest.mark.parametrize( - "entry_source", [config_entries.SOURCE_USER, config_entries.SOURCE_ZEROCONF] -) -async def test_ssdp_rediscover_2( - mock_get_ssdp, - hass: HomeAssistant, - aioclient_mock: AiohttpClientMocker, - mock_flow_init, - entry_domain: str, - entry_discovery_keys: tuple, - entry_source: str, -) -> None: - """Test we reinitiate flows when an ignored config entry is removed. - - This test can be merged with test_zeroconf_rediscover when - async_step_unignore has been removed from the ConfigFlow base class. - """ - entry = MockConfigEntry( - domain=entry_domain, - discovery_keys=entry_discovery_keys, - unique_id="mock-unique-id", - state=config_entries.ConfigEntryState.LOADED, - source=entry_source, - ) - entry.add_to_hass(hass) - - mock_ssdp_search_response = _ssdp_headers( - { - "st": "mock-st", - "location": "http://1.1.1.1", - "usn": "uuid:mock-udn::mock-st", - "server": "mock-server", - "ext": "", - "_source": "search", - } - ) - aioclient_mock.get( - "http://1.1.1.1", - text=""" - - - Paulus - Paulus - - - """, - ) - ssdp_listener = await init_ssdp_component(hass) - ssdp_listener._on_search(mock_ssdp_search_response) - await hass.async_block_till_done() - hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) - await hass.async_block_till_done() - - expected_context = { - "discovery_key": DiscoveryKey(domain="ssdp", key="uuid:mock-udn", version=1), - "source": config_entries.SOURCE_SSDP, - } - assert len(mock_flow_init.mock_calls) == 1 - assert mock_flow_init.mock_calls[0][1][0] == "mock-domain" - assert mock_flow_init.mock_calls[0][2]["context"] == expected_context - mock_call_data: ssdp.SsdpServiceInfo = mock_flow_init.mock_calls[0][2]["data"] - assert mock_call_data.ssdp_st == "mock-st" - assert mock_call_data.ssdp_location == "http://1.1.1.1" - - await hass.config_entries.async_remove(entry.entry_id) - await hass.async_block_till_done() - assert len(mock_flow_init.mock_calls) == 2 assert mock_flow_init.mock_calls[1][1][0] == "mock-domain" assert mock_flow_init.mock_calls[1][2]["context"] == expected_context @@ -1196,6 +1093,4 @@ async def test_ssdp_rediscover_no_match( await hass.config_entries.async_remove(entry.entry_id) await hass.async_block_till_done() - assert len(mock_flow_init.mock_calls) == 2 - assert mock_flow_init.mock_calls[1][1][0] == entry_domain - assert mock_flow_init.mock_calls[1][2]["context"] == {"source": "unignore"} + assert len(mock_flow_init.mock_calls) == 1 diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index 8dd8d118d72..103b2f609e0 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -1456,7 +1456,14 @@ async def test_zeroconf_removed(hass: HomeAssistant) -> None: ), ], ) -@pytest.mark.parametrize("entry_source", [config_entries.SOURCE_IGNORE]) +@pytest.mark.parametrize( + "entry_source", + [ + config_entries.SOURCE_IGNORE, + config_entries.SOURCE_USER, + config_entries.SOURCE_ZEROCONF, + ], +) async def test_zeroconf_rediscover( hass: HomeAssistant, entry_domain: str, @@ -1483,149 +1490,6 @@ async def test_zeroconf_rediscover( ) entry.add_to_hass(hass) - with ( - patch.dict( - zc_gen.ZEROCONF, - { - "_http._tcp.local.": [ - { - "domain": "shelly", - "name": "shelly*", - "properties": {"macaddress": "ffaadd*"}, - } - ] - }, - clear=True, - ), - patch.object(hass.config_entries.flow, "async_init") as mock_config_flow, - patch.object( - zeroconf, "AsyncServiceBrowser", side_effect=http_only_service_update_mock - ) as mock_service_browser, - patch( - "homeassistant.components.zeroconf.AsyncServiceInfo", - side_effect=get_zeroconf_info_mock("FFAADDCC11DD"), - ), - ): - assert await async_setup_component(hass, zeroconf.DOMAIN, {zeroconf.DOMAIN: {}}) - hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) - await hass.async_block_till_done() - - expected_context = { - "discovery_key": DiscoveryKey( - domain="zeroconf", - key=("_http._tcp.local.", "Shelly108._http._tcp.local."), - version=1, - ), - "source": "zeroconf", - } - assert len(mock_service_browser.mock_calls) == 1 - assert len(mock_config_flow.mock_calls) == 1 - assert mock_config_flow.mock_calls[0][1][0] == "shelly" - assert mock_config_flow.mock_calls[0][2]["context"] == expected_context - - await hass.config_entries.async_remove(entry.entry_id) - await hass.async_block_till_done() - - assert len(mock_service_browser.mock_calls) == 1 - assert len(mock_config_flow.mock_calls) == 3 - assert mock_config_flow.mock_calls[1][1][0] == entry_domain - assert mock_config_flow.mock_calls[1][2]["context"] == { - "source": "unignore", - } - assert mock_config_flow.mock_calls[2][1][0] == "shelly" - assert mock_config_flow.mock_calls[2][2]["context"] == expected_context - - -@pytest.mark.usefixtures("mock_async_zeroconf") -@pytest.mark.parametrize( - ( - "entry_domain", - "entry_discovery_keys", - ), - [ - # Matching discovery key - ( - "shelly", - { - "zeroconf": ( - DiscoveryKey( - domain="zeroconf", - key=("_http._tcp.local.", "Shelly108._http._tcp.local."), - version=1, - ), - ) - }, - ), - # Matching discovery key - ( - "shelly", - { - "zeroconf": ( - DiscoveryKey( - domain="zeroconf", - key=("_http._tcp.local.", "Shelly108._http._tcp.local."), - version=1, - ), - ), - "other": ( - DiscoveryKey( - domain="other", - key="blah", - version=1, - ), - ), - }, - ), - # Matching discovery key, other domain - # Note: Rediscovery is not currently restricted to the domain of the removed - # entry. Such a check can be added if needed. - ( - "comp", - { - "zeroconf": ( - DiscoveryKey( - domain="zeroconf", - key=("_http._tcp.local.", "Shelly108._http._tcp.local."), - version=1, - ), - ) - }, - ), - ], -) -@pytest.mark.parametrize( - "entry_source", [config_entries.SOURCE_USER, config_entries.SOURCE_ZEROCONF] -) -async def test_zeroconf_rediscover_2( - hass: HomeAssistant, - entry_domain: str, - entry_discovery_keys: tuple, - entry_source: str, -) -> None: - """Test we reinitiate flows when an ignored config entry is removed. - - This test can be merged with test_zeroconf_rediscover when - async_step_unignore has been removed from the ConfigFlow base class. - """ - - def http_only_service_update_mock(zeroconf, services, handlers): - """Call service update handler.""" - handlers[0]( - zeroconf, - "_http._tcp.local.", - "Shelly108._http._tcp.local.", - ServiceStateChange.Added, - ) - - entry = MockConfigEntry( - domain=entry_domain, - discovery_keys=entry_discovery_keys, - unique_id="mock-unique-id", - state=config_entries.ConfigEntryState.LOADED, - source=entry_source, - ) - entry.add_to_hass(hass) - with ( patch.dict( zc_gen.ZEROCONF, @@ -1790,8 +1654,4 @@ async def test_zeroconf_rediscover_no_match( await hass.async_block_till_done() assert len(mock_service_browser.mock_calls) == 1 - assert len(mock_config_flow.mock_calls) == 2 - assert mock_config_flow.mock_calls[1][1][0] == entry_domain - assert mock_config_flow.mock_calls[1][2]["context"] == { - "source": "unignore", - } + assert len(mock_config_flow.mock_calls) == 1 diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 53bcb459c60..9cba19ef3b1 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -3271,129 +3271,6 @@ async def test_async_current_entries_explicit_include_ignore( assert len(mock_setup_entry.mock_calls) == 0 -async def test_unignore_step_form( - hass: HomeAssistant, manager: config_entries.ConfigEntries -) -> None: - """Test that we can ignore flows that are in progress and have a unique ID, then rediscover them.""" - async_setup_entry = AsyncMock(return_value=True) - mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) - mock_platform(hass, "comp.config_flow", None) - - class TestFlow(config_entries.ConfigFlow): - """Test flow.""" - - VERSION = 1 - - async def async_step_unignore(self, user_input): - """Test unignore step.""" - unique_id = user_input["unique_id"] - await self.async_set_unique_id(unique_id) - return self.async_show_form(step_id="discovery") - - with mock_config_flow("comp", TestFlow): - result = await manager.flow.async_init( - "comp", - context={"source": config_entries.SOURCE_IGNORE}, - data={"unique_id": "mock-unique-id", "title": "Ignored Title"}, - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - - entry = hass.config_entries.async_entries("comp")[0] - assert entry.source == "ignore" - assert entry.unique_id == "mock-unique-id" - assert entry.domain == "comp" - assert entry.title == "Ignored Title" - - await manager.async_remove(entry.entry_id) - - # But after a 'tick' the unignore step has run and we can see an active flow again. - await hass.async_block_till_done() - assert len(hass.config_entries.flow.async_progress_by_handler("comp")) == 1 - - # and still not config entries - assert len(hass.config_entries.async_entries("comp")) == 0 - - -async def test_unignore_create_entry( - hass: HomeAssistant, manager: config_entries.ConfigEntries -) -> None: - """Test that we can ignore flows that are in progress and have a unique ID, then rediscover them.""" - async_setup_entry = AsyncMock(return_value=True) - mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) - mock_platform(hass, "comp.config_flow", None) - - class TestFlow(config_entries.ConfigFlow): - """Test flow.""" - - VERSION = 1 - - async def async_step_unignore(self, user_input): - """Test unignore step.""" - unique_id = user_input["unique_id"] - await self.async_set_unique_id(unique_id) - return self.async_create_entry(title="yo", data={}) - - with mock_config_flow("comp", TestFlow): - result = await manager.flow.async_init( - "comp", - context={"source": config_entries.SOURCE_IGNORE}, - data={"unique_id": "mock-unique-id", "title": "Ignored Title"}, - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - - entry = hass.config_entries.async_entries("comp")[0] - assert entry.source == "ignore" - assert entry.unique_id == "mock-unique-id" - assert entry.domain == "comp" - assert entry.title == "Ignored Title" - - await manager.async_remove(entry.entry_id) - - # But after a 'tick' the unignore step has run and we can see a config entry. - await hass.async_block_till_done() - entry = hass.config_entries.async_entries("comp")[0] - assert entry.source == config_entries.SOURCE_UNIGNORE - assert entry.unique_id == "mock-unique-id" - assert entry.title == "yo" - - # And still no active flow - assert len(hass.config_entries.flow.async_progress_by_handler("comp")) == 0 - - -async def test_unignore_default_impl( - hass: HomeAssistant, manager: config_entries.ConfigEntries -) -> None: - """Test that resdicovery is a no-op by default.""" - async_setup_entry = AsyncMock(return_value=True) - mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) - mock_platform(hass, "comp.config_flow", None) - - class TestFlow(config_entries.ConfigFlow): - """Test flow.""" - - VERSION = 1 - - with mock_config_flow("comp", TestFlow): - result = await manager.flow.async_init( - "comp", - context={"source": config_entries.SOURCE_IGNORE}, - data={"unique_id": "mock-unique-id", "title": "Ignored Title"}, - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - - entry = hass.config_entries.async_entries("comp")[0] - assert entry.source == "ignore" - assert entry.unique_id == "mock-unique-id" - assert entry.domain == "comp" - assert entry.title == "Ignored Title" - - await manager.async_remove(entry.entry_id) - await hass.async_block_till_done() - - assert len(hass.config_entries.async_entries("comp")) == 0 - assert len(hass.config_entries.flow.async_progress()) == 0 - - async def test_partial_flows_hidden( hass: HomeAssistant, manager: config_entries.ConfigEntries ) -> None: @@ -5396,11 +5273,6 @@ async def test_hashable_non_string_unique_id( None, {"type": data_entry_flow.FlowResultType.FORM, "step_id": "reauth_confirm"}, ), - ( - config_entries.SOURCE_UNIGNORE, - None, - {"type": data_entry_flow.FlowResultType.ABORT, "reason": "not_implemented"}, - ), ( config_entries.SOURCE_USER, None, @@ -5485,11 +5357,6 @@ async def test_starting_config_flow_on_single_config_entry( None, {"type": data_entry_flow.FlowResultType.FORM, "step_id": "reauth_confirm"}, ), - ( - config_entries.SOURCE_UNIGNORE, - None, - {"type": data_entry_flow.FlowResultType.ABORT, "reason": "not_implemented"}, - ), ( config_entries.SOURCE_USER, None,