1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00

Add single_config_entry manifest option (#109505)

* Allow setting if we support multiple config entries in config flow

* Move property to config flow instead of flow handler

* Move marking an integration as single instance only to manifest

* Revert line remove

* Avoid init a config flow or adding a new entry on a single instance with an entry

* Revert changes in test

* Process code review comments

* Apply code review suggestion
This commit is contained in:
Jan-Philipp Benecke
2024-02-26 19:00:33 +01:00
committed by GitHub
parent 673a95227b
commit baf84b6fba
5 changed files with 233 additions and 2 deletions

View File

@@ -4434,6 +4434,177 @@ async def test_hashable_non_string_unique_id(
assert entries.get_entry_by_domain_and_unique_id("test", unique_id) is None
async def test_avoid_starting_config_flow_on_single_config_entry(
hass: HomeAssistant, manager: config_entries.ConfigEntries
) -> None:
"""Test that we cannot start a config flow for a single config entry integration."""
integration = loader.Integration(
hass,
"components.comp",
None,
{
"name": "Comp",
"dependencies": [],
"requirements": [],
"domain": "comp",
"single_config_entry": True,
},
)
entry = MockConfigEntry(
domain="comp",
unique_id="1234",
title="Test",
data={"vendor": "data"},
options={"vendor": "options"},
)
entry.add_to_hass(hass)
mock_platform(hass, "comp.config_flow", None)
with patch(
"homeassistant.loader.async_get_integration",
return_value=integration,
), pytest.raises(
HomeAssistantError,
match=r"Cannot start a config flow, the integration supports only a single config entry but already has one",
):
await hass.config_entries.flow.async_init("comp", context={"source": "user"})
async def test_avoid_adding_second_config_entry_on_single_config_entry(
hass: HomeAssistant, manager: config_entries.ConfigEntries
) -> None:
"""Test that we cannot add a second entry for a single config entry integration."""
integration = loader.Integration(
hass,
"components.comp",
None,
{
"name": "Comp",
"dependencies": [],
"requirements": [],
"domain": "comp",
"single_config_entry": True,
},
)
entry = MockConfigEntry(
domain="comp",
unique_id="1234",
title="Test",
data={"vendor": "data"},
options={"vendor": "options"},
)
entry.add_to_hass(hass)
with patch(
"homeassistant.loader.async_get_integration",
return_value=integration,
), pytest.raises(
HomeAssistantError,
match=r"An entry for comp already exists, but integration supports only one config entry",
):
await hass.config_entries.async_add(
MockConfigEntry(
title="Second comp entry", domain="comp", data={"vendor": "data2"}
)
)
async def test_in_progress_get_canceled_when_entry_is_created(
hass: HomeAssistant, manager: config_entries.ConfigEntries
) -> None:
"""Test that we abort all in progress flows when a new entry is created on a single instance only integration."""
integration = loader.Integration(
hass,
"components.comp",
None,
{
"name": "Comp",
"dependencies": [],
"requirements": [],
"domain": "comp",
"single_config_entry": True,
},
)
mock_integration(hass, MockModule("comp"))
mock_platform(hass, "comp.config_flow", None)
class TestFlow(config_entries.ConfigFlow):
"""Test flow."""
VERSION = 1
async def async_step_user(self, user_input=None):
"""Test user step."""
if user_input is not None:
return self.async_create_entry(title="Test Title", data=user_input)
return self.async_show_form(step_id="user")
with patch.dict(config_entries.HANDLERS, {"comp": TestFlow}), patch(
"homeassistant.loader.async_get_integration",
return_value=integration,
):
# Create one to be in progress
result = await manager.flow.async_init(
"comp", context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.FlowResultType.FORM
# Will be canceled
result2 = await manager.flow.async_init(
"comp", context={"source": config_entries.SOURCE_USER}
)
assert result2["type"] == data_entry_flow.FlowResultType.FORM
result = await manager.flow.async_configure(
result["flow_id"], user_input={"host": "127.0.0.1"}
)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 1
async def test_start_reauth_still_possible_for_single_config_entry(
hass: HomeAssistant, manager: config_entries.ConfigEntries
):
"""Test that we can still start a reauth flow on a single config entry integration."""
integration = loader.Integration(
hass,
"components.comp",
None,
{
"name": "Comp",
"dependencies": [],
"requirements": [],
"domain": "comp",
"single_config_entry": True,
},
)
entry = MockConfigEntry(
domain="comp",
unique_id="1234",
title="Test",
data={"vendor": "data"},
options={"vendor": "options"},
)
entry.add_to_hass(hass)
mock_platform(hass, "comp.config_flow", None)
with patch(
"homeassistant.loader.async_get_integration",
return_value=integration,
):
result = await hass.config_entries.flow.async_init(
"comp", context={"source": config_entries.SOURCE_REAUTH}
)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
async def test_directly_mutating_blocked(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None: