diff --git a/homeassistant/components/bond/config_flow.py b/homeassistant/components/bond/config_flow.py index 6eba9897468..9670782d2a6 100644 --- a/homeassistant/components/bond/config_flow.py +++ b/homeassistant/components/bond/config_flow.py @@ -1,6 +1,7 @@ """Config flow for Bond integration.""" from __future__ import annotations +import contextlib from http import HTTPStatus import logging from typing import Any @@ -33,10 +34,9 @@ TOKEN_SCHEMA = vol.Schema({}) async def async_get_token(hass: HomeAssistant, host: str) -> str | None: """Try to fetch the token from the bond device.""" bond = Bond(host, "", session=async_get_clientsession(hass)) - try: - response: dict[str, str] = await bond.token() - except ClientConnectionError: - return None + response: dict[str, str] = {} + with contextlib.suppress(ClientConnectionError): + response = await bond.token() return response.get("token") @@ -101,6 +101,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): host: str = discovery_info.host bond_id = name.partition(".")[0] await self.async_set_unique_id(bond_id) + hass = self.hass for entry in self._async_current_entries(): if entry.unique_id != bond_id: continue @@ -110,13 +111,12 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ): updates[CONF_ACCESS_TOKEN] = token new_data = {**entry.data, **updates} - if new_data != dict(entry.data): - self.hass.config_entries.async_update_entry( - entry, data={**entry.data, **updates} - ) - self.hass.async_create_task( - self.hass.config_entries.async_reload(entry.entry_id) - ) + changed = new_data != dict(entry.data) + if changed: + hass.config_entries.async_update_entry(entry, data=new_data) + if changed or entry.state is ConfigEntryState.SETUP_RETRY: + entry_id = entry.entry_id + hass.async_create_task(hass.config_entries.async_reload(entry_id)) raise AbortFlow("already_configured") self._discovered = {CONF_HOST: host, CONF_NAME: bond_id} diff --git a/tests/components/bond/test_config_flow.py b/tests/components/bond/test_config_flow.py index 5d3b357b9f7..67910af7b6c 100644 --- a/tests/components/bond/test_config_flow.py +++ b/tests/components/bond/test_config_flow.py @@ -381,6 +381,45 @@ async def test_zeroconf_already_configured(hass: core.HomeAssistant): assert len(mock_setup_entry.mock_calls) == 1 +async def test_zeroconf_in_setup_retry_state(hass: core.HomeAssistant): + """Test we retry right away on zeroconf discovery.""" + + entry = MockConfigEntry( + domain=DOMAIN, + unique_id="already-registered-bond-id", + data={CONF_HOST: "stored-host", CONF_ACCESS_TOKEN: "test-token"}, + ) + entry.add_to_hass(hass) + + with patch_bond_version(side_effect=OSError): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state is ConfigEntryState.SETUP_RETRY + + with _patch_async_setup_entry() as mock_setup_entry: + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_ZEROCONF}, + data=zeroconf.ZeroconfServiceInfo( + host="updated-host", + addresses=["updated-host"], + hostname="mock_hostname", + name="already-registered-bond-id.some-other-tail-info", + port=None, + properties={}, + type="mock_type", + ), + ) + await hass.async_block_till_done() + + assert result["type"] == "abort" + assert result["reason"] == "already_configured" + assert entry.data["host"] == "updated-host" + assert len(mock_setup_entry.mock_calls) == 1 + assert entry.state is ConfigEntryState.LOADED + + async def test_zeroconf_already_configured_refresh_token(hass: core.HomeAssistant): """Test starting a flow from zeroconf when already configured and the token is out of date.""" entry2 = MockConfigEntry(