Compare commits

...

5 Commits

Author SHA1 Message Date
G Johansson 789d389da6 Fix test from rebase 2025-02-22 08:45:12 +00:00
G Johansson 3a693ce12a Mods 2025-02-22 08:44:24 +00:00
G Johansson 6d83b48448 Adjusted proposal 2025-02-22 08:44:22 +00:00
G Johansson 495bd1d5c8 Update docstring 2025-02-22 08:44:06 +00:00
G Johansson 3b5b71e458 Fix async_update_reload_and_abort only reload if no update listener 2025-02-22 08:44:03 +00:00
2 changed files with 109 additions and 1 deletions
+22 -1
View File
@@ -1120,7 +1120,13 @@ class ConfigEntry[_DataT = Any]:
Returns function to unlisten.
"""
self.update_listeners.append(listener)
return lambda: self.update_listeners.remove(listener)
def remove_listener() -> None:
"""Remove listener."""
if listener in self.update_listeners:
self.update_listeners.remove(listener)
return remove_listener
def as_dict(self) -> dict[str, Any]:
"""Return dictionary version of this entry."""
@@ -3223,6 +3229,9 @@ class ConfigFlow(ConfigEntryBaseFlow):
) -> ConfigFlowResult:
"""Update config entry, reload config entry and finish config flow.
Any update listener will be removed before updating the entry as the config entry
will be reloaded in the case the entry has been updated.
:param data: replace the entry data with new data
:param data_updates: add items from data_updates to entry data - existing keys
are overridden
@@ -3240,6 +3249,13 @@ class ConfigFlow(ConfigEntryBaseFlow):
if data is not UNDEFINED:
raise ValueError("Cannot set both data and data_updates")
data = entry.data | data_updates
restore_update_listeners = []
if entry.update_listeners:
# Save a copy of the update listeners to be restored in case no reload.
restore_update_listeners = list(entry.update_listeners)
entry.update_listeners = []
result = self.hass.config_entries.async_update_entry(
entry=entry,
unique_id=unique_id,
@@ -3247,8 +3263,13 @@ class ConfigFlow(ConfigEntryBaseFlow):
data=data,
options=options,
)
if reload_even_if_entry_is_unchanged or result:
self.hass.config_entries.async_schedule_reload(entry.entry_id)
else:
# Restore the update listeners in the case an update did not occur.
entry.update_listeners = restore_update_listeners
if reason is UNDEFINED:
reason = "reauth_successful"
if self.source == SOURCE_RECONFIGURE:
+87
View File
@@ -6542,6 +6542,93 @@ async def test_update_subentry_and_abort(
assert result["reason"] == "reconfigure_successful"
@pytest.mark.parametrize(
("source", "reason"),
[
(config_entries.SOURCE_REAUTH, "reauth_successful"),
(config_entries.SOURCE_RECONFIGURE, "reconfigure_successful"),
],
)
async def test_update_entry_and_reload_not_reload_if_update_listener(
hass: HomeAssistant,
source: str,
reason: str,
) -> None:
"""Test updating an entry and not reloading if update listener."""
entry = MockConfigEntry(
domain="comp",
unique_id="1234",
title="Test",
data={"vendor": "data"},
options={"vendor": "options"},
)
entry.add_to_hass(hass)
called_setup = []
called_update_listener = []
async def update_listener(hass: HomeAssistant, entry: ConfigEntry):
"""Mock update listener."""
called_update_listener.append(1)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Mock setting up entry."""
called_setup.append(1)
entry.async_on_unload(entry.add_update_listener(update_listener))
return True
comp = MockModule(
"comp",
async_setup_entry=async_setup_entry,
async_unload_entry=AsyncMock(return_value=True),
)
mock_integration(hass, comp)
mock_platform(hass, "comp.config_flow", None)
await hass.config_entries.async_setup(entry.entry_id)
kwargs = {
"unique_id": "5678",
"title": "Updated title",
"data": {"vendor": "data2"},
"options": {"vendor": "options2"},
}
class MockFlowHandler(config_entries.ConfigFlow):
"""Define a mock flow handler."""
VERSION = 1
async def async_step_reauth(self, data):
"""Mock Reauth."""
return self.async_update_reload_and_abort(entry, **kwargs)
async def async_step_reconfigure(self, data):
"""Mock Reconfigure."""
return self.async_update_reload_and_abort(entry, **kwargs)
with mock_config_flow("comp", MockFlowHandler):
if source == config_entries.SOURCE_REAUTH:
result = await entry.start_reauth_flow(hass)
elif source == config_entries.SOURCE_RECONFIGURE:
result = await entry.start_reconfigure_flow(hass)
await hass.async_block_till_done()
assert entry.title == "Updated title"
assert entry.unique_id == "5678"
assert entry.data == {"vendor": "data2"}
assert entry.options == {"vendor": "options2"}
assert entry.state == config_entries.ConfigEntryState.LOADED
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == reason
# Assert entry was reloaded
assert len(called_setup) == 2
assert len(called_update_listener) == 0
assert len(comp.async_unload_entry.mock_calls) == 1
async def test_reconfigure_subentry_create_subentry(hass: HomeAssistant) -> None:
"""Test it's not allowed to create a subentry from a subentry reconfigure flow."""
subentry_id = "blabla"