mirror of
https://github.com/home-assistant/core.git
synced 2026-07-12 09:07:59 +01:00
Add subentry reconfigure flow to SMTP integration (#176152)
This commit is contained in:
@@ -10,6 +10,7 @@ from typing import Any, override
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_USER,
|
||||
ConfigFlow,
|
||||
@@ -33,7 +34,7 @@ from homeassistant.const import (
|
||||
UnitOfTime,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||
from homeassistant.helpers.selector import (
|
||||
NumberSelector,
|
||||
NumberSelectorConfig,
|
||||
@@ -359,6 +360,55 @@ class RecipientSubentryFlowHandler(ConfigSubentryFlow):
|
||||
),
|
||||
)
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> SubentryFlowResult:
|
||||
"""Reconfigure flow to update a recipient."""
|
||||
|
||||
entry = self._get_entry()
|
||||
subentry = self._get_reconfigure_subentry()
|
||||
|
||||
if user_input is not None:
|
||||
old_unique_id = subentry.unique_id
|
||||
result = self.async_update_and_abort(
|
||||
entry,
|
||||
subentry=subentry,
|
||||
title=(
|
||||
user_input[CONF_RECIPIENT]
|
||||
if subentry.title == old_unique_id
|
||||
else subentry.title
|
||||
),
|
||||
data_updates={},
|
||||
unique_id=user_input[CONF_RECIPIENT],
|
||||
)
|
||||
if result.get("reason") == "reconfigure_successful" and (
|
||||
entity := er.async_get(self.hass).async_get_entity_id(
|
||||
NOTIFY_DOMAIN, DOMAIN, f"{entry.entry_id}_{old_unique_id}"
|
||||
)
|
||||
):
|
||||
er.async_get(self.hass).async_update_entity(
|
||||
entity,
|
||||
new_unique_id=f"{entry.entry_id}_{user_input[CONF_RECIPIENT]}",
|
||||
)
|
||||
return result
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="reconfigure",
|
||||
data_schema=self.add_suggested_values_to_schema(
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_RECIPIENT): TextSelector(
|
||||
TextSelectorConfig(
|
||||
type=TextSelectorType.EMAIL,
|
||||
autocomplete="email",
|
||||
),
|
||||
)
|
||||
}
|
||||
),
|
||||
suggested_values={CONF_RECIPIENT: subentry.unique_id},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class OptionsFlowHandler(OptionsFlow):
|
||||
"""Handle options flow."""
|
||||
|
||||
@@ -74,13 +74,24 @@
|
||||
"config_subentries": {
|
||||
"recipient": {
|
||||
"abort": {
|
||||
"already_configured": "Recipient is already configured"
|
||||
"already_configured": "Recipient is already configured",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
},
|
||||
"entry_type": "Recipient",
|
||||
"initiate_flow": {
|
||||
"user": "Add recipient"
|
||||
},
|
||||
"step": {
|
||||
"reconfigure": {
|
||||
"data": {
|
||||
"recipient": "[%key:common::config_flow::data::email%]"
|
||||
},
|
||||
"data_description": {
|
||||
"recipient": "[%key:component::smtp::config_subentries::recipient::step::user::data_description::recipient%]"
|
||||
},
|
||||
"description": "Update the recipient email address.",
|
||||
"title": "Reconfigure recipient"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
|
||||
@@ -13,7 +13,13 @@ from homeassistant.components.smtp.const import (
|
||||
DOMAIN,
|
||||
SUBENTRY_TYPE_RECIPIENT,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState, FlowType
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_RECONFIGURE,
|
||||
SOURCE_USER,
|
||||
ConfigEntryState,
|
||||
ConfigSubentryData,
|
||||
FlowType,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_PASSWORD,
|
||||
@@ -24,6 +30,7 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import USER_INPUT
|
||||
|
||||
@@ -442,3 +449,136 @@ async def test_form_reauth_errors(
|
||||
CONF_PASSWORD: "new-password",
|
||||
}
|
||||
assert len(hass.config_entries.async_entries()) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("smtp")
|
||||
async def test_form_subentry_reconfigure(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test subentry reconfigure flow."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
len(er.async_entries_for_config_entry(entity_registry, config_entry.entry_id))
|
||||
== 1
|
||||
)
|
||||
assert (entity := entity_registry.async_get("notify.home_assistant_recipient"))
|
||||
assert entity.unique_id == "123456789_recipient@example.com"
|
||||
|
||||
result = await config_entry.start_subentry_reconfigure_flow(hass, "ABCDEF")
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == SOURCE_RECONFIGURE
|
||||
|
||||
result = await hass.config_entries.subentries.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_RECIPIENT: "changed@example.com"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reconfigure_successful"
|
||||
|
||||
assert config_entry.subentries["ABCDEF"].unique_id == "changed@example.com"
|
||||
assert (
|
||||
len(er.async_entries_for_config_entry(entity_registry, config_entry.entry_id))
|
||||
== 1
|
||||
)
|
||||
assert (entity := entity_registry.async_get("notify.home_assistant_recipient"))
|
||||
assert entity.unique_id == "123456789_changed@example.com"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("smtp")
|
||||
async def test_form_subentry_reconfigure_already_configured(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test we abort subentry reconfigure flow when already configured."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home Assistant",
|
||||
data=USER_INPUT,
|
||||
options={
|
||||
CONF_TIMEOUT: 5,
|
||||
},
|
||||
entry_id="123456789",
|
||||
subentries_data=[
|
||||
ConfigSubentryData(
|
||||
data={},
|
||||
subentry_id="ABCDEF",
|
||||
subentry_type=SUBENTRY_TYPE_RECIPIENT,
|
||||
title="Recipient",
|
||||
unique_id="recipient@example.com",
|
||||
),
|
||||
ConfigSubentryData(
|
||||
data={},
|
||||
subentry_id="GHIJKL",
|
||||
subentry_type=SUBENTRY_TYPE_RECIPIENT,
|
||||
title="Recipient2",
|
||||
unique_id="changed@example.com",
|
||||
),
|
||||
],
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
result = await config_entry.start_subentry_reconfigure_flow(hass, "ABCDEF")
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == SOURCE_RECONFIGURE
|
||||
|
||||
result = await hass.config_entries.subentries.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_RECIPIENT: "changed@example.com"},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("smtp")
|
||||
async def test_form_subentry_reconfigure_updates_title(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test subentry reconfigure flow updates subentry title if it matches email."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home Assistant",
|
||||
data=USER_INPUT,
|
||||
options={
|
||||
CONF_TIMEOUT: 5,
|
||||
},
|
||||
entry_id="123456789",
|
||||
subentries_data=[
|
||||
ConfigSubentryData(
|
||||
data={},
|
||||
subentry_id="ABCDEF",
|
||||
subentry_type=SUBENTRY_TYPE_RECIPIENT,
|
||||
title="recipient@example.com",
|
||||
unique_id="recipient@example.com",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
result = await config_entry.start_subentry_reconfigure_flow(hass, "ABCDEF")
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == SOURCE_RECONFIGURE
|
||||
|
||||
result = await hass.config_entries.subentries.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_RECIPIENT: "changed@example.com"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reconfigure_successful"
|
||||
|
||||
assert config_entry.subentries["ABCDEF"].unique_id == "changed@example.com"
|
||||
assert config_entry.subentries["ABCDEF"].title == "changed@example.com"
|
||||
|
||||
Reference in New Issue
Block a user