Ensure entry_id is set on reauth/reconfigure flows (#129319)
* Ensure entry_id is set on reauth/reconfigure flows * Improve * Improve * Use report helper * Adjust deprecation date * Update config_entries.py * Improve message and adjust tests * Apply suggestions from code review Co-authored-by: G Johansson <goran.johansson@shiftit.se> --------- Co-authored-by: G Johansson <goran.johansson@shiftit.se>pull/129479/head^2
parent
5430eca93e
commit
b626c9b450
|
@ -1260,13 +1260,24 @@ class ConfigEntriesFlowManager(
|
|||
if not context or "source" not in context:
|
||||
raise KeyError("Context not set or doesn't have a source set")
|
||||
|
||||
# reauth/reconfigure flows should be linked to a config entry
|
||||
if (source := context["source"]) in {
|
||||
SOURCE_REAUTH,
|
||||
SOURCE_RECONFIGURE,
|
||||
} and "entry_id" not in context:
|
||||
# Deprecated in 2024.12, should fail in 2025.12
|
||||
report(
|
||||
f"initialises a {source} flow without a link to the config entry",
|
||||
error_if_integration=False,
|
||||
error_if_core=True,
|
||||
)
|
||||
|
||||
flow_id = ulid_util.ulid_now()
|
||||
|
||||
# Avoid starting a config flow on an integration that only supports
|
||||
# a single config entry, but which already has an entry
|
||||
if (
|
||||
context.get("source")
|
||||
not in {SOURCE_IGNORE, SOURCE_REAUTH, SOURCE_RECONFIGURE}
|
||||
source 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)
|
||||
):
|
||||
|
@ -1280,7 +1291,7 @@ class ConfigEntriesFlowManager(
|
|||
|
||||
loop = self.hass.loop
|
||||
|
||||
if context["source"] == SOURCE_IMPORT:
|
||||
if source == SOURCE_IMPORT:
|
||||
self._pending_import_flows[handler][flow_id] = loop.create_future()
|
||||
|
||||
cancel_init_future = loop.create_future()
|
||||
|
|
|
@ -37,7 +37,7 @@ from homeassistant.exceptions import (
|
|||
ConfigEntryNotReady,
|
||||
HomeAssistantError,
|
||||
)
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers import entity_registry as er, frame, issue_registry as ir
|
||||
from homeassistant.helpers.discovery_flow import DiscoveryKey
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.json import json_dumps
|
||||
|
@ -4779,6 +4779,74 @@ async def test_reauth(
|
|||
assert len(hass.config_entries.flow.async_progress()) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source", [config_entries.SOURCE_REAUTH, config_entries.SOURCE_RECONFIGURE]
|
||||
)
|
||||
async def test_reauth_reconfigure_missing_entry(
|
||||
hass: HomeAssistant,
|
||||
manager: config_entries.ConfigEntries,
|
||||
source: str,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the async_reauth_helper."""
|
||||
entry = MockConfigEntry(title="test_title", domain="test")
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
mock_setup_entry = AsyncMock(return_value=True)
|
||||
mock_integration(hass, MockModule("test", async_setup_entry=mock_setup_entry))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
|
||||
await manager.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match=f"Detected code that initialises a {source} flow without a link "
|
||||
"to the config entry. Please report this issue.",
|
||||
):
|
||||
await manager.flow.async_init("test", context={"source": source})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 0
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_integration_frame")
|
||||
@pytest.mark.parametrize(
|
||||
"source", [config_entries.SOURCE_REAUTH, config_entries.SOURCE_RECONFIGURE]
|
||||
)
|
||||
async def test_reauth_reconfigure_missing_entry_component(
|
||||
hass: HomeAssistant,
|
||||
manager: config_entries.ConfigEntries,
|
||||
source: str,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the async_reauth_helper."""
|
||||
entry = MockConfigEntry(title="test_title", domain="test")
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
mock_setup_entry = AsyncMock(return_value=True)
|
||||
mock_integration(hass, MockModule("test", async_setup_entry=mock_setup_entry))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
|
||||
await manager.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch.object(frame, "_REPORTED_INTEGRATIONS", set()):
|
||||
await manager.flow.async_init("test", context={"source": source})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Flow still created, but deprecation logged
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["context"]["source"] == source
|
||||
|
||||
assert (
|
||||
f"Detected that integration 'hue' initialises a {source} flow"
|
||||
" without a link to the config entry at homeassistant/components" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
async def test_reconfigure(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
|
@ -5012,7 +5080,9 @@ async def test_initializing_flows_canceled_on_shutdown(
|
|||
config_entries.HANDLERS, {"comp": MockFlowHandler, "test": MockFlowHandler}
|
||||
):
|
||||
task = asyncio.create_task(
|
||||
manager.flow.async_init("test", context={"source": "reauth"})
|
||||
manager.flow.async_init(
|
||||
"test", context={"source": "reauth", "entry_id": "abc"}
|
||||
)
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
manager.flow.async_shutdown()
|
||||
|
|
Loading…
Reference in New Issue