mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Cleanups for somfy_mylink (#45026)
* Cleanups for somfy_mylink * Use the target/unique_id to configure reverse * Simplify options flow * Various code review cleanups * Deprecate YAML * revert get change * revert get change * add note about empty response * move CONF_DEFAULT_REVERSE out of loop * Update homeassistant/components/somfy_mylink/config_flow.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Ensure we deepcopy options Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
f19b72ea02
commit
13cdf0ba63
@ -5,21 +5,23 @@ import logging
|
||||
from somfy_mylink_synergy import SomfyMyLinkSynergy
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.cover import ENTITY_ID_FORMAT
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
CONF_SYSTEM_ID,
|
||||
DATA_SOMFY_MYLINK,
|
||||
DEFAULT_PORT,
|
||||
DOMAIN,
|
||||
MYLINK_ENTITY_IDS,
|
||||
MYLINK_STATUS,
|
||||
SOMFY_MYLINK_COMPONENTS,
|
||||
)
|
||||
@ -44,17 +46,22 @@ def validate_entity_config(values):
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_SYSTEM_ID): cv.string,
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_DEFAULT_REVERSE, default=False): cv.boolean,
|
||||
vol.Optional(CONF_ENTITY_CONFIG, default={}): validate_entity_config,
|
||||
}
|
||||
)
|
||||
},
|
||||
vol.All(
|
||||
cv.deprecated(DOMAIN),
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_SYSTEM_ID): cv.string,
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_DEFAULT_REVERSE, default=False): cv.boolean,
|
||||
vol.Optional(
|
||||
CONF_ENTITY_CONFIG, default={}
|
||||
): validate_entity_config,
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
@ -92,19 +99,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"Unable to connect to the Somfy MyLink device, please check your settings"
|
||||
) from ex
|
||||
|
||||
if "error" in mylink_status:
|
||||
if not mylink_status or "error" in mylink_status:
|
||||
_LOGGER.error(
|
||||
"mylink failed to setup because of an error: %s",
|
||||
mylink_status.get("error", {}).get("message"),
|
||||
mylink_status.get("error", {}).get(
|
||||
"message", "Empty response from mylink device"
|
||||
),
|
||||
)
|
||||
return False
|
||||
|
||||
_async_migrate_entity_config(hass, entry, mylink_status)
|
||||
|
||||
undo_listener = entry.add_update_listener(_async_update_listener)
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = {
|
||||
DATA_SOMFY_MYLINK: somfy_mylink,
|
||||
MYLINK_STATUS: mylink_status,
|
||||
MYLINK_ENTITY_IDS: [],
|
||||
UNDO_UPDATE_LISTENER: undo_listener,
|
||||
}
|
||||
|
||||
@ -136,6 +146,34 @@ def _async_import_options_from_data_if_missing(hass: HomeAssistant, entry: Confi
|
||||
hass.config_entries.async_update_entry(entry, data=data, options=options)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_migrate_entity_config(
|
||||
hass: HomeAssistant, entry: ConfigEntry, mylink_status: dict
|
||||
):
|
||||
if CONF_ENTITY_CONFIG not in entry.options:
|
||||
return
|
||||
|
||||
options = dict(entry.options)
|
||||
|
||||
reversed_target_ids = options[CONF_REVERSED_TARGET_IDS] = {}
|
||||
legacy_entry_config = options[CONF_ENTITY_CONFIG]
|
||||
default_reverse = options.get(CONF_DEFAULT_REVERSE)
|
||||
|
||||
for cover in mylink_status["result"]:
|
||||
legacy_entity_id = ENTITY_ID_FORMAT.format(slugify(cover["name"]))
|
||||
target_id = cover["targetID"]
|
||||
|
||||
entity_config = legacy_entry_config.get(legacy_entity_id, {})
|
||||
if entity_config.get(CONF_REVERSE, default_reverse):
|
||||
reversed_target_ids[target_id] = True
|
||||
|
||||
for legacy_key in (CONF_DEFAULT_REVERSE, CONF_ENTITY_CONFIG):
|
||||
if legacy_key in options:
|
||||
del options[legacy_key]
|
||||
|
||||
hass.config_entries.async_update_entry(entry, data=entry.data, options=options)
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
unload_ok = all(
|
||||
|
@ -1,29 +1,28 @@
|
||||
"""Config flow for Somfy MyLink integration."""
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
import logging
|
||||
|
||||
from somfy_mylink_synergy import SomfyMyLinkSynergy
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, core, exceptions
|
||||
from homeassistant.const import ATTR_FRIENDLY_NAME, CONF_ENTITY_ID, CONF_HOST, CONF_PORT
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import callback
|
||||
|
||||
from .const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
CONF_SYSTEM_ID,
|
||||
DEFAULT_CONF_DEFAULT_REVERSE,
|
||||
CONF_TARGET_ID,
|
||||
CONF_TARGET_NAME,
|
||||
DEFAULT_PORT,
|
||||
MYLINK_ENTITY_IDS,
|
||||
MYLINK_STATUS,
|
||||
)
|
||||
from .const import DOMAIN # pylint:disable=unused-import
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ENTITY_CONFIG_VERSION = "entity_config_version"
|
||||
|
||||
STEP_USER_DATA_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_HOST): str,
|
||||
@ -114,8 +113,24 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
||||
def __init__(self, config_entry: config_entries.ConfigEntry):
|
||||
"""Initialize options flow."""
|
||||
self.config_entry = config_entry
|
||||
self.options = config_entry.options.copy()
|
||||
self._entity_id = None
|
||||
self.options = deepcopy(dict(config_entry.options))
|
||||
self._target_id = None
|
||||
|
||||
@callback
|
||||
def _async_callback_targets(self):
|
||||
"""Return the list of targets."""
|
||||
return self.hass.data[DOMAIN][self.config_entry.entry_id][MYLINK_STATUS][
|
||||
"result"
|
||||
]
|
||||
|
||||
@callback
|
||||
def _async_get_target_name(self, target_id) -> str:
|
||||
"""Find the name of a target in the api data."""
|
||||
mylink_targets = self._async_callback_targets()
|
||||
for cover in mylink_targets:
|
||||
if cover["targetID"] == target_id:
|
||||
return cover["name"]
|
||||
raise KeyError
|
||||
|
||||
async def async_step_init(self, user_input=None):
|
||||
"""Handle options flow."""
|
||||
@ -125,71 +140,45 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
|
||||
if user_input is not None:
|
||||
self.options[CONF_DEFAULT_REVERSE] = user_input[CONF_DEFAULT_REVERSE]
|
||||
|
||||
entity_id = user_input.get(CONF_ENTITY_ID)
|
||||
if entity_id:
|
||||
return await self.async_step_entity_config(None, entity_id)
|
||||
target_id = user_input.get(CONF_TARGET_ID)
|
||||
if target_id:
|
||||
return await self.async_step_target_config(None, target_id)
|
||||
|
||||
return self.async_create_entry(title="", data=self.options)
|
||||
|
||||
data_schema = vol.Schema(
|
||||
{
|
||||
vol.Required(
|
||||
CONF_DEFAULT_REVERSE,
|
||||
default=self.options.get(
|
||||
CONF_DEFAULT_REVERSE, DEFAULT_CONF_DEFAULT_REVERSE
|
||||
),
|
||||
): bool
|
||||
}
|
||||
)
|
||||
data = self.hass.data[DOMAIN][self.config_entry.entry_id]
|
||||
mylink_entity_ids = data[MYLINK_ENTITY_IDS]
|
||||
cover_dict = {None: None}
|
||||
mylink_targets = self._async_callback_targets()
|
||||
if mylink_targets:
|
||||
for cover in mylink_targets:
|
||||
cover_dict[cover["targetID"]] = cover["name"]
|
||||
|
||||
if mylink_entity_ids:
|
||||
entity_dict = {None: None}
|
||||
for entity_id in mylink_entity_ids:
|
||||
name = entity_id
|
||||
state = self.hass.states.get(entity_id)
|
||||
if state:
|
||||
name = state.attributes.get(ATTR_FRIENDLY_NAME, entity_id)
|
||||
entity_dict[entity_id] = f"{name} ({entity_id})"
|
||||
data_schema = data_schema.extend(
|
||||
{vol.Optional(CONF_ENTITY_ID): vol.In(entity_dict)}
|
||||
)
|
||||
data_schema = vol.Schema({vol.Optional(CONF_TARGET_ID): vol.In(cover_dict)})
|
||||
|
||||
return self.async_show_form(step_id="init", data_schema=data_schema, errors={})
|
||||
|
||||
async def async_step_entity_config(self, user_input=None, entity_id=None):
|
||||
"""Handle options flow for entity."""
|
||||
entities_config = self.options.setdefault(CONF_ENTITY_CONFIG, {})
|
||||
async def async_step_target_config(self, user_input=None, target_id=None):
|
||||
"""Handle options flow for target."""
|
||||
reversed_target_ids = self.options.setdefault(CONF_REVERSED_TARGET_IDS, {})
|
||||
|
||||
if user_input is not None:
|
||||
entity_config = entities_config.setdefault(self._entity_id, {})
|
||||
if entity_config.get(CONF_REVERSE) != user_input[CONF_REVERSE]:
|
||||
entity_config[CONF_REVERSE] = user_input[CONF_REVERSE]
|
||||
# If we do not modify a top level key
|
||||
# the entity config will never be written
|
||||
self.options.setdefault(ENTITY_CONFIG_VERSION, 0)
|
||||
self.options[ENTITY_CONFIG_VERSION] += 1
|
||||
if user_input[CONF_REVERSE] != reversed_target_ids.get(self._target_id):
|
||||
reversed_target_ids[self._target_id] = user_input[CONF_REVERSE]
|
||||
return await self.async_step_init()
|
||||
|
||||
self._entity_id = entity_id
|
||||
default_reverse = self.options.get(CONF_DEFAULT_REVERSE, False)
|
||||
entity_config = entities_config.get(entity_id, {})
|
||||
self._target_id = target_id
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="entity_config",
|
||||
step_id="target_config",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_REVERSE,
|
||||
default=entity_config.get(CONF_REVERSE, default_reverse),
|
||||
default=reversed_target_ids.get(target_id, False),
|
||||
): bool
|
||||
}
|
||||
),
|
||||
description_placeholders={
|
||||
CONF_ENTITY_ID: entity_id,
|
||||
CONF_TARGET_NAME: self._async_get_target_name(target_id),
|
||||
},
|
||||
errors={},
|
||||
)
|
||||
|
@ -4,11 +4,16 @@ CONF_ENTITY_CONFIG = "entity_config"
|
||||
CONF_SYSTEM_ID = "system_id"
|
||||
CONF_REVERSE = "reverse"
|
||||
CONF_DEFAULT_REVERSE = "default_reverse"
|
||||
DEFAULT_CONF_DEFAULT_REVERSE = False
|
||||
CONF_TARGET_NAME = "target_name"
|
||||
CONF_REVERSED_TARGET_IDS = "reversed_target_ids"
|
||||
CONF_TARGET_ID = "target_id"
|
||||
|
||||
DEFAULT_PORT = 44100
|
||||
|
||||
DATA_SOMFY_MYLINK = "somfy_mylink_data"
|
||||
MYLINK_STATUS = "mylink_status"
|
||||
MYLINK_ENTITY_IDS = "mylink_entity_ids"
|
||||
DOMAIN = "somfy_mylink"
|
||||
|
||||
SOMFY_MYLINK_COMPONENTS = ["cover"]
|
||||
|
||||
MANUFACTURER = "Somfy"
|
||||
DEFAULT_PORT = 44100
|
||||
|
@ -5,20 +5,16 @@ from homeassistant.components.cover import (
|
||||
DEVICE_CLASS_BLIND,
|
||||
DEVICE_CLASS_SHUTTER,
|
||||
DEVICE_CLASS_WINDOW,
|
||||
ENTITY_ID_FORMAT,
|
||||
CoverEntity,
|
||||
)
|
||||
from homeassistant.const import STATE_CLOSED, STATE_OPEN
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
DATA_SOMFY_MYLINK,
|
||||
DOMAIN,
|
||||
MANUFACTURER,
|
||||
MYLINK_ENTITY_IDS,
|
||||
MYLINK_STATUS,
|
||||
)
|
||||
|
||||
@ -29,26 +25,22 @@ MYLINK_COVER_TYPE_TO_DEVICE_CLASS = {0: DEVICE_CLASS_BLIND, 1: DEVICE_CLASS_SHUT
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Discover and configure Somfy covers."""
|
||||
reversed_target_ids = config_entry.options.get(CONF_REVERSED_TARGET_IDS, {})
|
||||
|
||||
data = hass.data[DOMAIN][config_entry.entry_id]
|
||||
mylink_status = data[MYLINK_STATUS]
|
||||
somfy_mylink = data[DATA_SOMFY_MYLINK]
|
||||
mylink_entity_ids = data[MYLINK_ENTITY_IDS]
|
||||
cover_list = []
|
||||
|
||||
for cover in mylink_status["result"]:
|
||||
entity_id = ENTITY_ID_FORMAT.format(slugify(cover["name"]))
|
||||
mylink_entity_ids.append(entity_id)
|
||||
|
||||
entity_config = config_entry.options.get(entity_id, {})
|
||||
default_reverse = config_entry.options.get(CONF_DEFAULT_REVERSE)
|
||||
|
||||
cover_config = {}
|
||||
cover_config["target_id"] = cover["targetID"]
|
||||
cover_config["name"] = cover["name"]
|
||||
cover_config["device_class"] = MYLINK_COVER_TYPE_TO_DEVICE_CLASS.get(
|
||||
cover.get("type"), DEVICE_CLASS_WINDOW
|
||||
)
|
||||
cover_config["reverse"] = entity_config.get(CONF_REVERSE, default_reverse)
|
||||
cover_config = {
|
||||
"target_id": cover["targetID"],
|
||||
"name": cover["name"],
|
||||
"device_class": MYLINK_COVER_TYPE_TO_DEVICE_CLASS.get(
|
||||
cover.get("type"), DEVICE_CLASS_WINDOW
|
||||
),
|
||||
"reverse": reversed_target_ids.get(cover["targetID"], False),
|
||||
}
|
||||
|
||||
cover_list.append(SomfyShade(somfy_mylink, **cover_config))
|
||||
|
||||
|
@ -26,15 +26,14 @@
|
||||
},
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Configure MyLink Entities",
|
||||
"title": "Configure MyLink Options",
|
||||
"data": {
|
||||
"default_reverse": "Default reversal status for unconfigured covers",
|
||||
"entity_id": "Configure a specific entity."
|
||||
"target_id": "Configure options for a cover."
|
||||
}
|
||||
},
|
||||
"entity_config": {
|
||||
"title": "Configure Entity",
|
||||
"description": "Configure options for `{entity_id}`",
|
||||
"target_config": {
|
||||
"title": "Configure MyLink Cover",
|
||||
"description": "Configure options for `{target_name}`",
|
||||
"data": {
|
||||
"reverse": "Cover is reversed"
|
||||
}
|
||||
|
@ -26,15 +26,14 @@
|
||||
},
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Configure MyLink Entities",
|
||||
"title": "Configure MyLink Options",
|
||||
"data": {
|
||||
"default_reverse": "Default reversal status for unconfigured covers",
|
||||
"entity_id": "Configure a specific entity."
|
||||
"target_id": "Configure options for a cover."
|
||||
}
|
||||
},
|
||||
"entity_config": {
|
||||
"title": "Configure Entity",
|
||||
"description": "Configure options for `{entity_id}`",
|
||||
"target_config": {
|
||||
"title": "Configure MyLink Cover",
|
||||
"description": "Configure options for `{target_name}`",
|
||||
"data": {
|
||||
"reverse": "Cover is reversed"
|
||||
}
|
||||
|
@ -2,11 +2,14 @@
|
||||
import asyncio
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow, setup
|
||||
from homeassistant.components.somfy_mylink.const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
CONF_SYSTEM_ID,
|
||||
DOMAIN,
|
||||
)
|
||||
@ -294,42 +297,9 @@ async def test_options_not_loaded(hass):
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||
|
||||
|
||||
async def test_options_no_entities(hass):
|
||||
"""Test we can configure default reverse."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "1.1.1.1", CONF_PORT: 12, CONF_SYSTEM_ID: 46},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"result": []},
|
||||
):
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"default_reverse": True},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert config_entry.options == {
|
||||
"default_reverse": True,
|
||||
}
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_options_with_entities(hass):
|
||||
"""Test we can configure reverse for an entity."""
|
||||
@pytest.mark.parametrize("reversed", [True, False])
|
||||
async def test_options_with_targets(hass, reversed):
|
||||
"""Test we can configure reverse for a target."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
@ -359,27 +329,96 @@ async def test_options_with_entities(hass):
|
||||
|
||||
result2 = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"default_reverse": True, "entity_id": "cover.master_window"},
|
||||
user_input={"target_id": "a"},
|
||||
)
|
||||
|
||||
assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
result3 = await hass.config_entries.options.async_configure(
|
||||
result2["flow_id"],
|
||||
user_input={"reverse": False},
|
||||
user_input={"reverse": reversed},
|
||||
)
|
||||
|
||||
assert result3["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
||||
result4 = await hass.config_entries.options.async_configure(
|
||||
result3["flow_id"],
|
||||
user_input={"default_reverse": True, "entity_id": None},
|
||||
user_input={"target_id": None},
|
||||
)
|
||||
assert result4["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
||||
assert config_entry.options == {
|
||||
"default_reverse": True,
|
||||
"entity_config": {"cover.master_window": {"reverse": False}},
|
||||
"entity_config_version": 1,
|
||||
CONF_REVERSED_TARGET_IDS: {"a": reversed},
|
||||
}
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("reversed", [True, False])
|
||||
async def test_form_import_with_entity_config_modify_options(hass, reversed):
|
||||
"""Test we can import entity config and modify options."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
mock_imported_config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: 456,
|
||||
CONF_DEFAULT_REVERSE: True,
|
||||
CONF_ENTITY_CONFIG: {"cover.xyz": {CONF_REVERSE: False}},
|
||||
},
|
||||
)
|
||||
mock_imported_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_status_info = {
|
||||
"result": [
|
||||
{"targetID": "1.1", "name": "xyz"},
|
||||
{"targetID": "1.2", "name": "zulu"},
|
||||
]
|
||||
}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.SomfyMyLinkSynergy.status_info",
|
||||
return_value=mock_status_info,
|
||||
):
|
||||
assert await hass.config_entries.async_setup(
|
||||
mock_imported_config_entry.entry_id
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_imported_config_entry.options == {
|
||||
"reversed_target_ids": {"1.2": True}
|
||||
}
|
||||
|
||||
result = await hass.config_entries.options.async_init(
|
||||
mock_imported_config_entry.entry_id
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result2 = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"target_id": "1.2"},
|
||||
)
|
||||
|
||||
assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
result3 = await hass.config_entries.options.async_configure(
|
||||
result2["flow_id"],
|
||||
user_input={"reverse": reversed},
|
||||
)
|
||||
|
||||
assert result3["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
||||
result4 = await hass.config_entries.options.async_configure(
|
||||
result3["flow_id"],
|
||||
user_input={"target_id": None},
|
||||
)
|
||||
assert result4["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
||||
# Will not be altered if nothing changes
|
||||
assert mock_imported_config_entry.options == {
|
||||
CONF_REVERSED_TARGET_IDS: {"1.2": reversed},
|
||||
}
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
Loading…
x
Reference in New Issue
Block a user