mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Log a warning when replacing existing config entry with same unique id (#130567)
* Log a warning when replacing existing config entry with same unique id * Exclude mobile_app * Ignore custom integrations * Apply suggestions from code review * Apply suggestions from code review * Update config_entries.py * Fix handler * Adjust and add tests * Apply suggestions from code review * Apply suggestions from code review * Update comment * Update config_entries.py * Apply suggestions from code review
This commit is contained in:
parent
d157919da2
commit
030a1460de
@ -1628,6 +1628,23 @@ class ConfigEntriesFlowManager(
|
||||
result["handler"], flow.unique_id
|
||||
)
|
||||
|
||||
if existing_entry is not None and flow.handler != "mobile_app":
|
||||
# This causes the old entry to be removed and replaced, when the flow
|
||||
# should instead be aborted.
|
||||
# In case of manual flows, integrations should implement options, reauth,
|
||||
# reconfigure to allow the user to change settings.
|
||||
# In case of non user visible flows, the integration should optionally
|
||||
# update the existing entry before aborting.
|
||||
# see https://developers.home-assistant.io/blog/2025/01/16/config-flow-unique-id/
|
||||
report_usage(
|
||||
"creates a config entry when another entry with the same unique ID "
|
||||
"exists",
|
||||
core_behavior=ReportBehavior.LOG,
|
||||
core_integration_behavior=ReportBehavior.LOG,
|
||||
custom_integration_behavior=ReportBehavior.LOG,
|
||||
integration_domain=flow.handler,
|
||||
)
|
||||
|
||||
# Unload the entry before setting up the new one.
|
||||
if existing_entry is not None and existing_entry.state.recoverable:
|
||||
await self.config_entries.async_unload(existing_entry.entry_id)
|
||||
|
@ -8899,3 +8899,63 @@ async def test_add_description_placeholder_automatically_not_overwrites(
|
||||
result = await hass.config_entries.flow.async_configure(flows[0]["flow_id"], None)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["description_placeholders"] == {"name": "Custom title"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("domain", "expected_log"),
|
||||
[
|
||||
("some_integration", True),
|
||||
("mobile_app", False),
|
||||
],
|
||||
)
|
||||
async def test_create_entry_existing_unique_id(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
expected_log: bool,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test to highlight unexpected behavior on create_entry."""
|
||||
entry = MockConfigEntry(
|
||||
title="From config flow",
|
||||
domain=domain,
|
||||
entry_id="01J915Q6T9F6G5V0QJX6HBC94T",
|
||||
data={"host": "any", "port": 123},
|
||||
unique_id="mock-unique-id",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert len(hass.config_entries.async_entries(domain)) == 1
|
||||
|
||||
mock_setup_entry = AsyncMock(return_value=True)
|
||||
|
||||
mock_integration(hass, MockModule(domain, async_setup_entry=mock_setup_entry))
|
||||
mock_platform(hass, f"{domain}.config_flow", None)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Test user step."""
|
||||
await self.async_set_unique_id("mock-unique-id")
|
||||
return self.async_create_entry(title="mock-title", data={})
|
||||
|
||||
with (
|
||||
mock_config_flow(domain, TestFlow),
|
||||
patch.object(frame, "_REPORTED_INTEGRATIONS", set()),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
domain, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
|
||||
assert len(hass.config_entries.async_entries(domain)) == 1
|
||||
|
||||
log_text = (
|
||||
f"Detected that integration '{domain}' creates a config entry "
|
||||
"when another entry with the same unique ID exists. Please "
|
||||
"create a bug report at https:"
|
||||
)
|
||||
assert (log_text in caplog.text) == expected_log
|
||||
|
Loading…
x
Reference in New Issue
Block a user