Only show light group all option in advanced mode (#68610)

This commit is contained in:
Erik Montnemery 2022-03-24 16:51:31 +01:00 committed by GitHub
parent 8aff8d89d2
commit 76103752b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 345 additions and 1 deletions

View File

@ -49,7 +49,9 @@ BINARY_SENSOR_OPTIONS_SCHEMA = basic_group_options_schema("binary_sensor").exten
LIGHT_OPTIONS_SCHEMA = basic_group_options_schema("light").extend(
{
vol.Required(CONF_ALL, default=False): selector.selector({"boolean": {}}),
vol.Required(
CONF_ALL, default=False, description={"advanced": True}
): selector.selector({"boolean": {}}),
}
)

View File

@ -79,6 +79,23 @@ class HelperCommonFlowHandler:
"""Handle a form step."""
form_step: HelperFlowFormStep = cast(HelperFlowFormStep, self._flow[step_id])
if (
user_input is not None
and (data_schema := form_step.schema)
and data_schema.schema
and not self._handler.show_advanced_options
):
# Add advanced field default if not set
for key in data_schema.schema.keys():
if isinstance(key, (vol.Optional, vol.Required)):
if (
key.description
and key.description.get("advanced")
and key.default is not vol.UNDEFINED
and key not in self._options
):
user_input[str(key.schema)] = key.default()
if user_input is not None and form_step.schema is not None:
# Do extra validation of user input
try:
@ -120,6 +137,16 @@ class HelperCommonFlowHandler:
# Make a copy of the schema with suggested values set to saved options
schema = {}
for key, val in data_schema.schema.items():
if isinstance(key, vol.Marker):
# Exclude advanced field
if (
key.description
and key.description.get("advanced")
and not self._handler.show_advanced_options
):
continue
new_key = key
if key in options and isinstance(key, vol.Marker):
# Copy the marker to not modify the flow schema

View File

@ -266,6 +266,73 @@ async def test_options(
assert get_suggested(result["data_schema"].schema, "name") is None
@pytest.mark.parametrize(
"group_type,extra_options,extra_options_after,advanced",
(
("light", {"all": False}, {"all": False}, False),
("light", {"all": True}, {"all": True}, False),
("light", {"all": False}, {"all": False}, True),
("light", {"all": True}, {"all": False}, True),
),
)
async def test_light_all_options(
hass: HomeAssistant, group_type, extra_options, extra_options_after, advanced
) -> None:
"""Test reconfiguring."""
members1 = [f"{group_type}.one", f"{group_type}.two"]
members2 = [f"{group_type}.four", f"{group_type}.five"]
group_config_entry = MockConfigEntry(
data={},
domain=DOMAIN,
options={
"entities": members1,
"group_type": group_type,
"name": "Bed Room",
**extra_options,
},
title="Bed Room",
)
group_config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(group_config_entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(f"{group_type}.bed_room")
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": advanced}
)
assert result["type"] == RESULT_TYPE_FORM
assert result["step_id"] == group_type
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
"entities": members2,
},
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {
"entities": members2,
"group_type": group_type,
"hide_members": False,
"name": "Bed Room",
**extra_options_after,
}
assert config_entry.data == {}
assert config_entry.options == {
"entities": members2,
"group_type": group_type,
"hide_members": False,
"name": "Bed Room",
**extra_options_after,
}
assert config_entry.title == "Bed Room"
@pytest.mark.parametrize(
"hide_members,hidden_by_initial,hidden_by",
((False, "integration", None), (True, None, "integration")),

View File

@ -1,9 +1,52 @@
"""Test helper_config_entry_flow."""
import pytest
import voluptuous as vol
from homeassistant import data_entry_flow
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.helper_config_entry_flow import (
HelperConfigFlowHandler,
HelperFlowFormStep,
HelperFlowMenuStep,
wrapped_entity_config_entry_title,
)
from homeassistant.util.decorator import Registry
from tests.common import MockConfigEntry
@pytest.fixture
def manager():
"""Return a flow manager."""
handlers = Registry()
entries = []
class FlowManager(data_entry_flow.FlowManager):
"""Test flow manager."""
async def async_create_flow(self, handler_key, *, context, data):
"""Test create flow."""
handler = handlers.get(handler_key)
if handler is None:
raise data_entry_flow.UnknownHandler
flow = handler()
flow.init_step = context.get("init_step", "init")
return flow
async def async_finish_flow(self, flow, result):
"""Test finish flow."""
if result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
result["source"] = flow.context.get("source")
entries.append(result)
return result
mgr = FlowManager(None)
mgr.mock_created_entries = entries
mgr.mock_reg_handler = handlers.register
return mgr
async def test_name(hass: HomeAssistant) -> None:
@ -36,3 +79,208 @@ async def test_name(hass: HomeAssistant) -> None:
registry.async_update_entity("switch.ceiling", name="Custom Name")
assert wrapped_entity_config_entry_title(hass, entity_id) == "Custom Name"
assert wrapped_entity_config_entry_title(hass, entry.id) == "Custom Name"
@pytest.mark.parametrize("marker", (vol.Required, vol.Optional))
async def test_config_flow_advanced_option(
hass: HomeAssistant, manager: data_entry_flow.FlowManager, marker
):
"""Test handling of advanced options in config flow."""
manager.hass = hass
CONFIG_SCHEMA = vol.Schema(
{
marker("option1"): str,
marker("advanced_no_default", description={"advanced": True}): str,
marker(
"advanced_default",
default="a very reasonable default",
description={"advanced": True},
): str,
}
)
CONFIG_FLOW: dict[str, HelperFlowFormStep | HelperFlowMenuStep] = {
"init": HelperFlowFormStep(CONFIG_SCHEMA)
}
@manager.mock_reg_handler("test")
class TestFlow(HelperConfigFlowHandler):
config_flow = CONFIG_FLOW
# Start flow in basic mode
result = await manager.async_init("test")
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == ["option1"]
result = await manager.async_configure(result["flow_id"], {"option1": "blabla"})
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {}
assert result["options"] == {
"advanced_default": "a very reasonable default",
"option1": "blabla",
}
for option in result["options"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)
# Start flow in advanced mode
result = await manager.async_init("test", context={"show_advanced_options": True})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == [
"option1",
"advanced_no_default",
"advanced_default",
]
result = await manager.async_configure(
result["flow_id"], {"advanced_no_default": "abc123", "option1": "blabla"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {}
assert result["options"] == {
"advanced_default": "a very reasonable default",
"advanced_no_default": "abc123",
"option1": "blabla",
}
for option in result["options"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)
# Start flow in advanced mode
result = await manager.async_init("test", context={"show_advanced_options": True})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == [
"option1",
"advanced_no_default",
"advanced_default",
]
result = await manager.async_configure(
result["flow_id"],
{
"advanced_default": "not default",
"advanced_no_default": "abc123",
"option1": "blabla",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {}
assert result["options"] == {
"advanced_default": "not default",
"advanced_no_default": "abc123",
"option1": "blabla",
}
for option in result["options"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)
@pytest.mark.parametrize("marker", (vol.Required, vol.Optional))
async def test_options_flow_advanced_option(
hass: HomeAssistant, manager: data_entry_flow.FlowManager, marker
):
"""Test handling of advanced options in options flow."""
manager.hass = hass
OPTIONS_SCHEMA = vol.Schema(
{
marker("option1"): str,
marker("advanced_no_default", description={"advanced": True}): str,
marker(
"advanced_default",
default="a very reasonable default",
description={"advanced": True},
): str,
}
)
OPTIONS_FLOW: dict[str, HelperFlowFormStep | HelperFlowMenuStep] = {
"init": HelperFlowFormStep(OPTIONS_SCHEMA)
}
class TestFlow(HelperConfigFlowHandler, domain="test"):
config_flow = {}
options_flow = OPTIONS_FLOW
config_entry = MockConfigEntry(
data={},
domain="test",
options={
"option1": "blabla",
"advanced_no_default": "abc123",
"advanced_default": "not default",
},
)
config_entry.add_to_hass(hass)
# Start flow in basic mode
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == ["option1"]
result = await hass.config_entries.options.async_configure(
result["flow_id"], {"option1": "blublu"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {
"advanced_default": "not default",
"advanced_no_default": "abc123",
"option1": "blublu",
}
for option in result["data"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)
# Start flow in advanced mode
result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": True}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == [
"option1",
"advanced_no_default",
"advanced_default",
]
result = await hass.config_entries.options.async_configure(
result["flow_id"], {"advanced_no_default": "def456", "option1": "blabla"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {
"advanced_default": "a very reasonable default",
"advanced_no_default": "def456",
"option1": "blabla",
}
for option in result["data"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)
# Start flow in advanced mode
result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": True}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert list(result["data_schema"].schema.keys()) == [
"option1",
"advanced_no_default",
"advanced_default",
]
result = await hass.config_entries.options.async_configure(
result["flow_id"],
{
"advanced_default": "also not default",
"advanced_no_default": "abc123",
"option1": "blabla",
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == {
"advanced_default": "also not default",
"advanced_no_default": "abc123",
"option1": "blabla",
}
for option in result["data"]:
# Make sure we didn't get the Optional or Required instance as key
assert isinstance(option, str)