mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 21:06:19 +00:00
Revert "Add support for subentries to config entries" (#133470)
Revert "Add support for subentries to config entries (#117355)"
This reverts commit ad15786115.
This commit is contained in:
@@ -4,7 +4,6 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Generator
|
||||
from contextlib import AbstractContextManager, nullcontext as does_not_raise
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import re
|
||||
@@ -906,7 +905,7 @@ async def test_entries_excludes_ignore_and_disabled(
|
||||
|
||||
|
||||
async def test_saving_and_loading(
|
||||
hass: HomeAssistant, freezer: FrozenDateTimeFactory, hass_storage: dict[str, Any]
|
||||
hass: HomeAssistant, freezer: FrozenDateTimeFactory
|
||||
) -> None:
|
||||
"""Test that we're saving and loading correctly."""
|
||||
mock_integration(
|
||||
@@ -923,17 +922,7 @@ async def test_saving_and_loading(
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Test user step."""
|
||||
await self.async_set_unique_id("unique")
|
||||
subentries = [
|
||||
config_entries.ConfigSubentryData(
|
||||
data={"foo": "bar"}, title="subentry 1"
|
||||
),
|
||||
config_entries.ConfigSubentryData(
|
||||
data={"sun": "moon"}, title="subentry 2", unique_id="very_unique"
|
||||
),
|
||||
]
|
||||
return self.async_create_entry(
|
||||
title="Test Title", data={"token": "abcd"}, subentries=subentries
|
||||
)
|
||||
return self.async_create_entry(title="Test Title", data={"token": "abcd"})
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
await hass.config_entries.flow.async_init(
|
||||
@@ -982,98 +971,6 @@ async def test_saving_and_loading(
|
||||
# To execute the save
|
||||
await hass.async_block_till_done()
|
||||
|
||||
stored_data = hass_storage["core.config_entries"]
|
||||
assert stored_data == {
|
||||
"data": {
|
||||
"entries": [
|
||||
{
|
||||
"created_at": ANY,
|
||||
"data": {
|
||||
"token": "abcd",
|
||||
},
|
||||
"disabled_by": None,
|
||||
"discovery_keys": {},
|
||||
"domain": "test",
|
||||
"entry_id": ANY,
|
||||
"minor_version": 1,
|
||||
"modified_at": ANY,
|
||||
"options": {},
|
||||
"pref_disable_new_entities": True,
|
||||
"pref_disable_polling": True,
|
||||
"source": "user",
|
||||
"subentries": [
|
||||
{
|
||||
"data": {"foo": "bar"},
|
||||
"subentry_id": ANY,
|
||||
"title": "subentry 1",
|
||||
"unique_id": None,
|
||||
},
|
||||
{
|
||||
"data": {"sun": "moon"},
|
||||
"subentry_id": ANY,
|
||||
"title": "subentry 2",
|
||||
"unique_id": "very_unique",
|
||||
},
|
||||
],
|
||||
"title": "Test Title",
|
||||
"unique_id": "unique",
|
||||
"version": 5,
|
||||
},
|
||||
{
|
||||
"created_at": ANY,
|
||||
"data": {
|
||||
"username": "bla",
|
||||
},
|
||||
"disabled_by": None,
|
||||
"discovery_keys": {
|
||||
"test": [
|
||||
{"domain": "test", "key": "blah", "version": 1},
|
||||
],
|
||||
},
|
||||
"domain": "test",
|
||||
"entry_id": ANY,
|
||||
"minor_version": 1,
|
||||
"modified_at": ANY,
|
||||
"options": {},
|
||||
"pref_disable_new_entities": False,
|
||||
"pref_disable_polling": False,
|
||||
"source": "user",
|
||||
"subentries": [],
|
||||
"title": "Test 2 Title",
|
||||
"unique_id": None,
|
||||
"version": 3,
|
||||
},
|
||||
{
|
||||
"created_at": ANY,
|
||||
"data": {
|
||||
"username": "bla",
|
||||
},
|
||||
"disabled_by": None,
|
||||
"discovery_keys": {
|
||||
"test": [
|
||||
{"domain": "test", "key": ["a", "b"], "version": 1},
|
||||
],
|
||||
},
|
||||
"domain": "test",
|
||||
"entry_id": ANY,
|
||||
"minor_version": 1,
|
||||
"modified_at": ANY,
|
||||
"options": {},
|
||||
"pref_disable_new_entities": False,
|
||||
"pref_disable_polling": False,
|
||||
"source": "user",
|
||||
"subentries": [],
|
||||
"title": "Test 2 Title",
|
||||
"unique_id": None,
|
||||
"version": 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
"key": "core.config_entries",
|
||||
"minor_version": 5,
|
||||
"version": 1,
|
||||
}
|
||||
|
||||
# Now load written data in new config manager
|
||||
manager = config_entries.ConfigEntries(hass, {})
|
||||
await manager.async_initialize()
|
||||
@@ -1086,25 +983,6 @@ async def test_saving_and_loading(
|
||||
):
|
||||
assert orig.as_dict() == loaded.as_dict()
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
entry_1,
|
||||
pref_disable_polling=False,
|
||||
pref_disable_new_entities=False,
|
||||
)
|
||||
|
||||
# To trigger the call_later
|
||||
freezer.tick(1.0)
|
||||
async_fire_time_changed(hass)
|
||||
# To execute the save
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Assert no data is lost when storing again
|
||||
expected_stored_data = stored_data
|
||||
expected_stored_data["data"]["entries"][0]["modified_at"] = ANY
|
||||
expected_stored_data["data"]["entries"][0]["pref_disable_new_entities"] = False
|
||||
expected_stored_data["data"]["entries"][0]["pref_disable_polling"] = False
|
||||
assert hass_storage["core.config_entries"] == expected_stored_data | {}
|
||||
|
||||
|
||||
@freeze_time("2024-02-14 12:00:00")
|
||||
async def test_as_dict(snapshot: SnapshotAssertion) -> None:
|
||||
@@ -1538,42 +1416,6 @@ async def test_update_entry_options_and_trigger_listener(
|
||||
assert len(update_listener_calls) == 1
|
||||
|
||||
|
||||
async def test_update_subentry_and_trigger_listener(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test that we can update subentry and trigger listener."""
|
||||
entry = MockConfigEntry(domain="test", options={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
update_listener_calls = []
|
||||
|
||||
subentry = config_entries.ConfigSubentry(
|
||||
data={"test": "test"}, unique_id="test", title="Mock title"
|
||||
)
|
||||
|
||||
async def update_listener(
|
||||
hass: HomeAssistant, entry: config_entries.ConfigEntry
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
assert entry.subentries == expected_subentries
|
||||
update_listener_calls.append(None)
|
||||
|
||||
entry.add_update_listener(update_listener)
|
||||
|
||||
expected_subentries = {subentry.subentry_id: subentry}
|
||||
assert manager.async_add_subentry(entry, subentry) is True
|
||||
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert entry.subentries == expected_subentries
|
||||
assert len(update_listener_calls) == 1
|
||||
|
||||
expected_subentries = {}
|
||||
assert manager.async_remove_subentry(entry, subentry.subentry_id) is True
|
||||
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert entry.subentries == expected_subentries
|
||||
assert len(update_listener_calls) == 2
|
||||
|
||||
|
||||
async def test_setup_raise_not_ready(
|
||||
hass: HomeAssistant,
|
||||
manager: config_entries.ConfigEntries,
|
||||
@@ -1900,456 +1742,20 @@ async def test_entry_options_unknown_config_entry(
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
|
||||
class TestFlow:
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry):
|
||||
"""Test options flow."""
|
||||
|
||||
with pytest.raises(config_entries.UnknownEntry):
|
||||
await manager.options.async_create_flow(
|
||||
"blah", context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
|
||||
async def test_create_entry_subentries(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test a config entry being created with subentries."""
|
||||
|
||||
subentrydata = config_entries.ConfigSubentryData(
|
||||
data={"test": "test"},
|
||||
title="Mock title",
|
||||
unique_id="test",
|
||||
)
|
||||
|
||||
async def mock_async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Mock setup."""
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
"comp",
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={"data": "data", "subentry": subentrydata},
|
||||
)
|
||||
)
|
||||
return True
|
||||
|
||||
async_setup_entry = AsyncMock(return_value=True)
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
"comp", async_setup=mock_async_setup, async_setup_entry=async_setup_entry
|
||||
),
|
||||
)
|
||||
mock_platform(hass, "comp.config_flow", None)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def async_step_import(self, user_input):
|
||||
"""Test import step creating entry, with subentry."""
|
||||
return self.async_create_entry(
|
||||
title="title",
|
||||
data={"example": user_input["data"]},
|
||||
subentries=[user_input["subentry"]],
|
||||
)
|
||||
|
||||
with patch.dict(config_entries.HANDLERS, {"comp": TestFlow}):
|
||||
assert await async_setup_component(hass, "comp", {})
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(async_setup_entry.mock_calls) == 1
|
||||
|
||||
entries = hass.config_entries.async_entries("comp")
|
||||
assert len(entries) == 1
|
||||
assert entries[0].supported_subentries == ()
|
||||
assert entries[0].data == {"example": "data"}
|
||||
assert len(entries[0].subentries) == 1
|
||||
subentry_id = list(entries[0].subentries)[0]
|
||||
subentry = config_entries.ConfigSubentry(
|
||||
data=subentrydata["data"],
|
||||
subentry_id=subentry_id,
|
||||
title=subentrydata["title"],
|
||||
unique_id="test",
|
||||
)
|
||||
assert entries[0].subentries == {subentry_id: subentry}
|
||||
|
||||
|
||||
async def test_entry_subentry(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test that we can add a subentry to an entry."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
flow = await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry
|
||||
|
||||
await manager.subentries.async_finish_flow(
|
||||
flow,
|
||||
{
|
||||
"data": {"second": True},
|
||||
"title": "Mock title",
|
||||
"type": data_entry_flow.FlowResultType.CREATE_ENTRY,
|
||||
"unique_id": "test",
|
||||
},
|
||||
)
|
||||
|
||||
assert entry.data == {"first": True}
|
||||
assert entry.options == {}
|
||||
subentry_id = list(entry.subentries)[0]
|
||||
assert entry.subentries == {
|
||||
subentry_id: config_entries.ConfigSubentry(
|
||||
data={"second": True},
|
||||
subentry_id=subentry_id,
|
||||
title="Mock title",
|
||||
unique_id="test",
|
||||
)
|
||||
}
|
||||
assert entry.supported_subentries == ("test",)
|
||||
|
||||
|
||||
async def test_entry_subentry_non_string(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test adding an invalid subentry to an entry."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
flow = await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await manager.subentries.async_finish_flow(
|
||||
flow,
|
||||
{
|
||||
"data": {"second": True},
|
||||
"title": "Mock title",
|
||||
"type": data_entry_flow.FlowResultType.CREATE_ENTRY,
|
||||
"unique_id": 123,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("context", [None, {}, {"bla": "bleh"}])
|
||||
async def test_entry_subentry_no_context(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries, context: dict | None
|
||||
) -> None:
|
||||
"""Test starting a subentry flow without "source" in context."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow), pytest.raises(KeyError):
|
||||
await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context=context, data=None
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("unique_id", "expected_result"),
|
||||
[(None, does_not_raise()), ("test", pytest.raises(HomeAssistantError))],
|
||||
)
|
||||
async def test_entry_subentry_duplicate(
|
||||
hass: HomeAssistant,
|
||||
manager: config_entries.ConfigEntries,
|
||||
unique_id: str | None,
|
||||
expected_result: AbstractContextManager,
|
||||
) -> None:
|
||||
"""Test adding a duplicated subentry to an entry."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(
|
||||
domain="test",
|
||||
data={"first": True},
|
||||
subentries_data=[
|
||||
config_entries.ConfigSubentryData(
|
||||
data={},
|
||||
subentry_id="blabla",
|
||||
title="Mock title",
|
||||
unique_id=unique_id,
|
||||
)
|
||||
],
|
||||
)
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
flow = await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry
|
||||
|
||||
with expected_result:
|
||||
await manager.subentries.async_finish_flow(
|
||||
flow,
|
||||
{
|
||||
"data": {"second": True},
|
||||
"title": "Mock title",
|
||||
"type": data_entry_flow.FlowResultType.CREATE_ENTRY,
|
||||
"unique_id": unique_id,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_subentry_abort(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test that we can abort subentry flow."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
flow = await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry
|
||||
|
||||
assert await manager.subentries.async_finish_flow(
|
||||
flow, {"type": data_entry_flow.FlowResultType.ABORT, "reason": "test"}
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_subentry_unknown_config_entry(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test attempting to start a subentry flow for an unknown config entry."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
|
||||
with pytest.raises(config_entries.UnknownEntry):
|
||||
await manager.subentries.async_create_flow(
|
||||
("blah", "blah"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_subentry_deleted_config_entry(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test attempting to finish a subentry flow for a deleted config entry."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with mock_config_flow("test", TestFlow):
|
||||
flow = await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
flow.handler = (entry.entry_id, "test") # Set to keep reference to config entry
|
||||
|
||||
await hass.config_entries.async_remove(entry.entry_id)
|
||||
|
||||
with pytest.raises(config_entries.UnknownEntry):
|
||||
await manager.subentries.async_finish_flow(
|
||||
flow,
|
||||
{
|
||||
"data": {"second": True},
|
||||
"title": "Mock title",
|
||||
"type": data_entry_flow.FlowResultType.CREATE_ENTRY,
|
||||
"unique_id": "test",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_subentry_unsupported(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test attempting to start a subentry flow for a config entry without support."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_subentry_flow(config_entry, subentry_type: str):
|
||||
"""Test subentry flow."""
|
||||
|
||||
class SubentryFlowHandler(data_entry_flow.FlowHandler):
|
||||
"""Test subentry flow handler."""
|
||||
|
||||
return SubentryFlowHandler()
|
||||
|
||||
@classmethod
|
||||
@callback
|
||||
def async_supported_subentries(
|
||||
cls, config_entry: ConfigEntry
|
||||
) -> tuple[str, ...]:
|
||||
return ("test",)
|
||||
|
||||
with (
|
||||
mock_config_flow("test", TestFlow),
|
||||
pytest.raises(data_entry_flow.UnknownHandler),
|
||||
):
|
||||
await manager.subentries.async_create_flow(
|
||||
(
|
||||
entry.entry_id,
|
||||
"unknown",
|
||||
),
|
||||
context={"source": "test"},
|
||||
data=None,
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_subentry_unsupported_subentry_type(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
"""Test attempting to start a subentry flow for a config entry without support."""
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_platform(hass, "test.config_flow", None)
|
||||
entry = MockConfigEntry(domain="test", data={"first": True})
|
||||
entry.add_to_manager(manager)
|
||||
|
||||
class TestFlow(config_entries.ConfigFlow):
|
||||
"""Test flow."""
|
||||
|
||||
with (
|
||||
mock_config_flow("test", TestFlow),
|
||||
pytest.raises(data_entry_flow.UnknownHandler),
|
||||
):
|
||||
await manager.subentries.async_create_flow(
|
||||
(entry.entry_id, "test"), context={"source": "test"}, data=None
|
||||
)
|
||||
|
||||
|
||||
async def test_entry_setup_succeed(
|
||||
hass: HomeAssistant, manager: config_entries.ConfigEntries
|
||||
) -> None:
|
||||
@@ -4505,20 +3911,21 @@ async def test_updating_entry_with_and_without_changes(
|
||||
|
||||
assert manager.async_update_entry(entry) is False
|
||||
|
||||
for change, expected_value in (
|
||||
({"data": {"second": True, "third": 456}}, {"second": True, "third": 456}),
|
||||
({"data": {"second": True}}, {"second": True}),
|
||||
({"minor_version": 2}, 2),
|
||||
({"options": {"hello": True}}, {"hello": True}),
|
||||
({"pref_disable_new_entities": True}, True),
|
||||
({"pref_disable_polling": True}, True),
|
||||
({"title": "sometitle"}, "sometitle"),
|
||||
({"unique_id": "abcd1234"}, "abcd1234"),
|
||||
({"version": 2}, 2),
|
||||
for change in (
|
||||
{"data": {"second": True, "third": 456}},
|
||||
{"data": {"second": True}},
|
||||
{"minor_version": 2},
|
||||
{"options": {"hello": True}},
|
||||
{"pref_disable_new_entities": True},
|
||||
{"pref_disable_polling": True},
|
||||
{"title": "sometitle"},
|
||||
{"unique_id": "abcd1234"},
|
||||
{"version": 2},
|
||||
):
|
||||
assert manager.async_update_entry(entry, **change) is True
|
||||
key = next(iter(change))
|
||||
assert getattr(entry, key) == expected_value
|
||||
value = next(iter(change.values()))
|
||||
assert getattr(entry, key) == value
|
||||
assert manager.async_update_entry(entry, **change) is False
|
||||
|
||||
assert manager.async_entry_for_domain_unique_id("test", "abc123") is None
|
||||
@@ -6052,7 +5459,6 @@ async def test_unhashable_unique_id_fails(
|
||||
minor_version=1,
|
||||
options={},
|
||||
source="test",
|
||||
subentries_data=(),
|
||||
title="title",
|
||||
unique_id=unique_id,
|
||||
version=1,
|
||||
@@ -6088,7 +5494,6 @@ async def test_unhashable_unique_id_fails_on_update(
|
||||
minor_version=1,
|
||||
options={},
|
||||
source="test",
|
||||
subentries_data=(),
|
||||
title="title",
|
||||
unique_id="123",
|
||||
version=1,
|
||||
@@ -6119,7 +5524,6 @@ async def test_string_unique_id_no_warning(
|
||||
minor_version=1,
|
||||
options={},
|
||||
source="test",
|
||||
subentries_data=(),
|
||||
title="title",
|
||||
unique_id="123",
|
||||
version=1,
|
||||
@@ -6162,7 +5566,6 @@ async def test_hashable_unique_id(
|
||||
minor_version=1,
|
||||
options={},
|
||||
source="test",
|
||||
subentries_data=(),
|
||||
title="title",
|
||||
unique_id=unique_id,
|
||||
version=1,
|
||||
@@ -6197,7 +5600,6 @@ async def test_no_unique_id_no_warning(
|
||||
minor_version=1,
|
||||
options={},
|
||||
source="test",
|
||||
subentries_data=(),
|
||||
title="title",
|
||||
unique_id=None,
|
||||
version=1,
|
||||
@@ -7122,7 +6524,6 @@ async def test_migration_from_1_2(
|
||||
"pref_disable_new_entities": False,
|
||||
"pref_disable_polling": False,
|
||||
"source": "import",
|
||||
"subentries": {},
|
||||
"title": "Sun",
|
||||
"unique_id": None,
|
||||
"version": 1,
|
||||
|
||||
Reference in New Issue
Block a user