Improve Google Cast options flow (#50028)

pull/50268/head
Erik Montnemery 2021-05-07 21:59:51 +02:00 committed by GitHub
parent 3a36a976ee
commit 934d241b70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 56 deletions

View File

@ -107,53 +107,77 @@ class CastOptionsFlowHandler(config_entries.OptionsFlow):
"""Handle Google Cast options."""
def __init__(self, config_entry):
"""Initialize MQTT options flow."""
"""Initialize Google Cast options flow."""
self.config_entry = config_entry
self.broker_config = {}
self.options = dict(config_entry.options)
self.updated_config = {}
async def async_step_init(self, user_input=None):
"""Manage the Cast options."""
return await self.async_step_options()
"""Manage the Google Cast options."""
return await self.async_step_basic_options()
async def async_step_options(self, user_input=None):
"""Manage the MQTT options."""
async def async_step_basic_options(self, user_input=None):
"""Manage the Google Cast options."""
errors = {}
current_config = self.config_entry.data
if user_input is not None:
bad_cec, ignore_cec = _string_to_list(
user_input.get(CONF_IGNORE_CEC, ""), IGNORE_CEC_SCHEMA
)
bad_hosts, known_hosts = _string_to_list(
user_input.get(CONF_KNOWN_HOSTS, ""), KNOWN_HOSTS_SCHEMA
)
bad_uuid, wanted_uuid = _string_to_list(
user_input.get(CONF_UUID, ""), WANTED_UUID_SCHEMA
)
if not bad_cec and not bad_hosts and not bad_uuid:
updated_config = dict(current_config)
updated_config[CONF_IGNORE_CEC] = ignore_cec
updated_config[CONF_KNOWN_HOSTS] = known_hosts
updated_config[CONF_UUID] = wanted_uuid
if not bad_hosts:
self.updated_config = dict(current_config)
self.updated_config[CONF_KNOWN_HOSTS] = known_hosts
if self.show_advanced_options:
return await self.async_step_advanced_options()
self.hass.config_entries.async_update_entry(
self.config_entry, data=updated_config
self.config_entry, data=self.updated_config
)
return self.async_create_entry(title="", data=None)
fields = {}
suggested_value = _list_to_string(current_config.get(CONF_KNOWN_HOSTS))
_add_with_suggestion(fields, CONF_KNOWN_HOSTS, suggested_value)
if self.show_advanced_options:
suggested_value = _list_to_string(current_config.get(CONF_UUID))
_add_with_suggestion(fields, CONF_UUID, suggested_value)
suggested_value = _list_to_string(current_config.get(CONF_IGNORE_CEC))
_add_with_suggestion(fields, CONF_IGNORE_CEC, suggested_value)
return self.async_show_form(
step_id="options",
step_id="basic_options",
data_schema=vol.Schema(fields),
errors=errors,
last_step=not self.show_advanced_options,
)
async def async_step_advanced_options(self, user_input=None):
"""Manage the Google Cast options."""
errors = {}
if user_input is not None:
bad_cec, ignore_cec = _string_to_list(
user_input.get(CONF_IGNORE_CEC, ""), IGNORE_CEC_SCHEMA
)
bad_uuid, wanted_uuid = _string_to_list(
user_input.get(CONF_UUID, ""), WANTED_UUID_SCHEMA
)
if not bad_cec and not bad_uuid:
self.updated_config[CONF_IGNORE_CEC] = ignore_cec
self.updated_config[CONF_UUID] = wanted_uuid
self.hass.config_entries.async_update_entry(
self.config_entry, data=self.updated_config
)
return self.async_create_entry(title="", data=None)
fields = {}
current_config = self.config_entry.data
suggested_value = _list_to_string(current_config.get(CONF_UUID))
_add_with_suggestion(fields, CONF_UUID, suggested_value)
suggested_value = _list_to_string(current_config.get(CONF_IGNORE_CEC))
_add_with_suggestion(fields, CONF_IGNORE_CEC, suggested_value)
return self.async_show_form(
step_id="advanced_options",
data_schema=vol.Schema(fields),
errors=errors,
last_step=True,
)

View File

@ -5,10 +5,10 @@
"description": "[%key:common::config_flow::description::confirm_setup%]"
},
"config": {
"title": "Google Cast",
"description": "Please enter the Google Cast configuration.",
"title": "Google Cast configuration",
"description": "Known Hosts - A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
"data": {
"known_hosts": "Optional list of known hosts if mDNS discovery is not working."
"known_hosts": "Known hosts"
}
}
},
@ -21,12 +21,19 @@
},
"options": {
"step": {
"options": {
"description": "Please enter the Google Cast configuration.",
"basic_options": {
"title": "Google Cast configuration",
"description": "Known Hosts - A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
"data": {
"ignore_cec": "Optional list which will be passed to pychromecast.IGNORE_CEC.",
"known_hosts": "Optional list of known hosts if mDNS discovery is not working.",
"uuid": "Optional list of UUIDs. Casts not listed will not be added."
"known_hosts": "Known hosts"
}
},
"advanced_options": {
"title": "Advanced Google Cast configuration",
"description": "Allowed UUIDs - A comma-separated list of UUIDs of Cast devices to add to Home Assistant. Use only if you dont want to add all available cast devices.\nIgnore CEC - A comma-separated list of Chromecasts that should ignore CEC data for determining the active input. This will be will be passed to pychromecast.IGNORE_CEC.",
"data": {
"ignore_cec": "Ignore CEC",
"uuid": "Allowed UUIDs"
}
}
},

View File

@ -1,7 +1,6 @@
{
"config": {
"abort": {
"no_devices_found": "No devices found on the network",
"single_instance_allowed": "Already configured. Only a single configuration possible."
},
"error": {
@ -10,10 +9,10 @@
"step": {
"config": {
"data": {
"known_hosts": "Optional list of known hosts if mDNS discovery is not working."
"known_hosts": "Known hosts"
},
"description": "Please enter the Google Cast configuration.",
"title": "Google Cast"
"description": "### Known Hosts \n A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
"title": "Google Cast configuration"
},
"confirm": {
"description": "Do you want to start set up?"
@ -25,13 +24,20 @@
"invalid_known_hosts": "Known hosts must be a comma separated list of hosts."
},
"step": {
"options": {
"advanced_options": {
"data": {
"ignore_cec": "Optional list which will be passed to pychromecast.IGNORE_CEC.",
"known_hosts": "Optional list of known hosts if mDNS discovery is not working.",
"uuid": "Optional list of UUIDs. Casts not listed will not be added."
"ignore_cec": "Ignore CEC",
"uuid": "Allowed UUIDs"
},
"description": "Please enter the Google Cast configuration."
"description": "### Allowed UUIDs\n A comma-separated list of UUIDs of Cast devices to add to Home Assistant. **Use only if you don\u2019t want to add all available cast devices.** \n ### Ignore CEC \n A comma-separated list of Chromecasts that should ignore CEC data for determining the active input. This will be will be passed to pychromecast.IGNORE_CEC. [See the upstream documentation for more information](https://github.com/balloob/pychromecast#ignoring-cec-data).",
"title": "Advanced Google Cast configuration"
},
"basic_options": {
"data": {
"known_hosts": "Known hosts"
},
"description": "### Known Hosts \n A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
"title": "Google Cast configuration"
}
}
}

View File

@ -153,7 +153,8 @@ def get_suggested(schema, key):
)
async def test_option_flow(hass, parameter_data):
"""Test config flow options."""
all_parameters = ["ignore_cec", "known_hosts", "uuid"]
basic_parameters = ["known_hosts"]
advanced_parameters = ["ignore_cec", "uuid"]
parameter, initial, suggested, user_input, updated = parameter_data
data = {
@ -170,32 +171,61 @@ async def test_option_flow(hass, parameter_data):
# Test ignore_cec and uuid options are hidden if advanced options are disabled
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "options"
assert result["step_id"] == "basic_options"
data_schema = result["data_schema"].schema
assert set(data_schema) == {"known_hosts"}
orig_data = dict(config_entry.data)
# Reconfigure ignore_cec, known_hosts, uuid
# Reconfigure known_hosts
context = {"source": config_entries.SOURCE_USER, "show_advanced_options": True}
result = await hass.config_entries.options.async_init(
config_entry.entry_id, context=context
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "options"
assert result["step_id"] == "basic_options"
data_schema = result["data_schema"].schema
for other_param in all_parameters:
for other_param in basic_parameters:
if other_param == parameter:
continue
assert get_suggested(data_schema, other_param) == ""
assert get_suggested(data_schema, parameter) == suggested
if parameter in basic_parameters:
assert get_suggested(data_schema, parameter) == suggested
user_input_dict = {}
if parameter in basic_parameters:
user_input_dict[parameter] = user_input
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={parameter: user_input},
user_input=user_input_dict,
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "advanced_options"
for other_param in basic_parameters:
if other_param == parameter:
continue
assert config_entry.data[other_param] == []
# No update yet
assert config_entry.data[parameter] == initial
# Reconfigure ignore_cec, uuid
data_schema = result["data_schema"].schema
for other_param in advanced_parameters:
if other_param == parameter:
continue
assert get_suggested(data_schema, other_param) == ""
if parameter in advanced_parameters:
assert get_suggested(data_schema, parameter) == suggested
user_input_dict = {}
if parameter in advanced_parameters:
user_input_dict[parameter] = user_input
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input=user_input_dict,
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] is None
for other_param in all_parameters:
for other_param in advanced_parameters:
if other_param == parameter:
continue
assert config_entry.data[other_param] == []
@ -209,12 +239,10 @@ async def test_option_flow(hass, parameter_data):
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] is None
assert config_entry.data == {
**orig_data,
"ignore_cec": [],
"known_hosts": [],
"uuid": [],
}
expected_data = {**orig_data, "known_hosts": []}
if parameter in advanced_parameters:
expected_data[parameter] = updated
assert dict(config_entry.data) == expected_data
async def test_known_hosts(hass, castbrowser_mock, castbrowser_constructor_mock):