From 9a5eec561a18cd0bffbbd65afe68f70c0893d28c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 21 Feb 2022 08:27:23 -1000 Subject: [PATCH] Only set require_restart on config entry reload if its not recoverable (#66994) --- .../components/config/config_entries.py | 10 +++--- .../components/config/test_config_entries.py | 33 ++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/config/config_entries.py b/homeassistant/components/config/config_entries.py index c3d20fb0f16..07bdc794128 100644 --- a/homeassistant/components/config/config_entries.py +++ b/homeassistant/components/config/config_entries.py @@ -88,15 +88,17 @@ class ConfigManagerEntryResourceReloadView(HomeAssistantView): raise Unauthorized(config_entry_id=entry_id, permission="remove") hass = request.app["hass"] + entry = hass.config_entries.async_get_entry(entry_id) + if not entry: + return self.json_message("Invalid entry specified", HTTPStatus.NOT_FOUND) + assert isinstance(entry, config_entries.ConfigEntry) try: - result = await hass.config_entries.async_reload(entry_id) + await hass.config_entries.async_reload(entry_id) except config_entries.OperationNotAllowed: return self.json_message("Entry cannot be reloaded", HTTPStatus.FORBIDDEN) - except config_entries.UnknownEntry: - return self.json_message("Invalid entry specified", HTTPStatus.NOT_FOUND) - return self.json({"require_restart": not result}) + return self.json({"require_restart": not entry.state.recoverable}) def _prepare_config_flow_result_json(result, prepare_result_json): diff --git a/tests/components/config/test_config_entries.py b/tests/components/config/test_config_entries.py index cfc6d8d4907..06b9f1ae7f6 100644 --- a/tests/components/config/test_config_entries.py +++ b/tests/components/config/test_config_entries.py @@ -9,7 +9,7 @@ import voluptuous as vol from homeassistant import config_entries as core_ce, data_entry_flow from homeassistant.components.config import config_entries -from homeassistant.config_entries import HANDLERS +from homeassistant.config_entries import HANDLERS, ConfigFlow from homeassistant.core import callback from homeassistant.generated import config_flows from homeassistant.helpers import config_validation as cv @@ -193,6 +193,37 @@ async def test_reload_entry_in_failed_state(hass, client, hass_admin_user): assert len(hass.config_entries.async_entries()) == 1 +async def test_reload_entry_in_setup_retry(hass, client, hass_admin_user): + """Test reloading an entry via the API that is in setup retry.""" + mock_setup_entry = AsyncMock(return_value=True) + mock_unload_entry = AsyncMock(return_value=True) + mock_migrate_entry = AsyncMock(return_value=True) + + mock_integration( + hass, + MockModule( + "comp", + async_setup_entry=mock_setup_entry, + async_unload_entry=mock_unload_entry, + async_migrate_entry=mock_migrate_entry, + ), + ) + mock_entity_platform(hass, "config_flow.comp", None) + entry = MockConfigEntry(domain="comp", state=core_ce.ConfigEntryState.SETUP_RETRY) + entry.supports_unload = True + entry.add_to_hass(hass) + + with patch.dict(HANDLERS, {"comp": ConfigFlow, "test": ConfigFlow}): + resp = await client.post( + f"/api/config/config_entries/entry/{entry.entry_id}/reload" + ) + await hass.async_block_till_done() + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert data == {"require_restart": False} + assert len(hass.config_entries.async_entries()) == 1 + + async def test_available_flows(hass, client): """Test querying the available flows.""" with patch.object(config_flows, "FLOWS", ["hello", "world"]):