Improve mysensors config flow (#75122)
* Improve mysensors config flow * Improve form input order * Update flow testspull/76372/head
parent
1aa0e64354
commit
e864b82c03
|
@ -20,13 +20,13 @@ from homeassistant.components.mqtt import (
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
|
from homeassistant.helpers import selector
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_BAUD_RATE,
|
CONF_BAUD_RATE,
|
||||||
CONF_DEVICE,
|
CONF_DEVICE,
|
||||||
CONF_GATEWAY_TYPE,
|
CONF_GATEWAY_TYPE,
|
||||||
CONF_GATEWAY_TYPE_ALL,
|
|
||||||
CONF_GATEWAY_TYPE_MQTT,
|
CONF_GATEWAY_TYPE_MQTT,
|
||||||
CONF_GATEWAY_TYPE_SERIAL,
|
CONF_GATEWAY_TYPE_SERIAL,
|
||||||
CONF_GATEWAY_TYPE_TCP,
|
CONF_GATEWAY_TYPE_TCP,
|
||||||
|
@ -45,6 +45,15 @@ DEFAULT_BAUD_RATE = 115200
|
||||||
DEFAULT_TCP_PORT = 5003
|
DEFAULT_TCP_PORT = 5003
|
||||||
DEFAULT_VERSION = "1.4"
|
DEFAULT_VERSION = "1.4"
|
||||||
|
|
||||||
|
_PORT_SELECTOR = vol.All(
|
||||||
|
selector.NumberSelector(
|
||||||
|
selector.NumberSelectorConfig(
|
||||||
|
min=1, max=65535, mode=selector.NumberSelectorMode.BOX
|
||||||
|
),
|
||||||
|
),
|
||||||
|
vol.Coerce(int),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def is_persistence_file(value: str) -> str:
|
def is_persistence_file(value: str) -> str:
|
||||||
"""Validate that persistence file path ends in either .pickle or .json."""
|
"""Validate that persistence file path ends in either .pickle or .json."""
|
||||||
|
@ -119,51 +128,34 @@ class MySensorsConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
self, user_input: dict[str, str] | None = None
|
self, user_input: dict[str, str] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Create a config entry from frontend user input."""
|
"""Create a config entry from frontend user input."""
|
||||||
schema = {vol.Required(CONF_GATEWAY_TYPE): vol.In(CONF_GATEWAY_TYPE_ALL)}
|
return self.async_show_menu(
|
||||||
schema = vol.Schema(schema)
|
step_id="select_gateway_type",
|
||||||
errors = {}
|
menu_options=["gw_serial", "gw_tcp", "gw_mqtt"],
|
||||||
|
)
|
||||||
if user_input is not None:
|
|
||||||
gw_type = self._gw_type = user_input[CONF_GATEWAY_TYPE]
|
|
||||||
input_pass = user_input if CONF_DEVICE in user_input else None
|
|
||||||
if gw_type == CONF_GATEWAY_TYPE_MQTT:
|
|
||||||
# Naive check that doesn't consider config entry state.
|
|
||||||
if MQTT_DOMAIN in self.hass.config.components:
|
|
||||||
return await self.async_step_gw_mqtt(input_pass)
|
|
||||||
|
|
||||||
errors["base"] = "mqtt_required"
|
|
||||||
if gw_type == CONF_GATEWAY_TYPE_TCP:
|
|
||||||
return await self.async_step_gw_tcp(input_pass)
|
|
||||||
if gw_type == CONF_GATEWAY_TYPE_SERIAL:
|
|
||||||
return await self.async_step_gw_serial(input_pass)
|
|
||||||
|
|
||||||
return self.async_show_form(step_id="user", data_schema=schema, errors=errors)
|
|
||||||
|
|
||||||
async def async_step_gw_serial(
|
async def async_step_gw_serial(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Create config entry for a serial gateway."""
|
"""Create config entry for a serial gateway."""
|
||||||
|
gw_type = self._gw_type = CONF_GATEWAY_TYPE_SERIAL
|
||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
errors.update(
|
errors.update(await self.validate_common(gw_type, errors, user_input))
|
||||||
await self.validate_common(CONF_GATEWAY_TYPE_SERIAL, errors, user_input)
|
|
||||||
)
|
|
||||||
if not errors:
|
if not errors:
|
||||||
return self._async_create_entry(user_input)
|
return self._async_create_entry(user_input)
|
||||||
|
|
||||||
user_input = user_input or {}
|
user_input = user_input or {}
|
||||||
schema = _get_schema_common(user_input)
|
schema = {
|
||||||
schema[
|
vol.Required(
|
||||||
|
CONF_DEVICE, default=user_input.get(CONF_DEVICE, "/dev/ttyACM0")
|
||||||
|
): str,
|
||||||
vol.Required(
|
vol.Required(
|
||||||
CONF_BAUD_RATE,
|
CONF_BAUD_RATE,
|
||||||
default=user_input.get(CONF_BAUD_RATE, DEFAULT_BAUD_RATE),
|
default=user_input.get(CONF_BAUD_RATE, DEFAULT_BAUD_RATE),
|
||||||
)
|
): cv.positive_int,
|
||||||
] = cv.positive_int
|
}
|
||||||
schema[
|
schema.update(_get_schema_common(user_input))
|
||||||
vol.Required(
|
|
||||||
CONF_DEVICE, default=user_input.get(CONF_DEVICE, "/dev/ttyACM0")
|
|
||||||
)
|
|
||||||
] = str
|
|
||||||
|
|
||||||
schema = vol.Schema(schema)
|
schema = vol.Schema(schema)
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
|
@ -174,30 +166,24 @@ class MySensorsConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Create a config entry for a tcp gateway."""
|
"""Create a config entry for a tcp gateway."""
|
||||||
errors = {}
|
gw_type = self._gw_type = CONF_GATEWAY_TYPE_TCP
|
||||||
if user_input is not None:
|
errors: dict[str, str] = {}
|
||||||
if CONF_TCP_PORT in user_input:
|
|
||||||
port: int = user_input[CONF_TCP_PORT]
|
|
||||||
if not (0 < port <= 65535):
|
|
||||||
errors[CONF_TCP_PORT] = "port_out_of_range"
|
|
||||||
|
|
||||||
errors.update(
|
if user_input is not None:
|
||||||
await self.validate_common(CONF_GATEWAY_TYPE_TCP, errors, user_input)
|
errors.update(await self.validate_common(gw_type, errors, user_input))
|
||||||
)
|
|
||||||
if not errors:
|
if not errors:
|
||||||
return self._async_create_entry(user_input)
|
return self._async_create_entry(user_input)
|
||||||
|
|
||||||
user_input = user_input or {}
|
user_input = user_input or {}
|
||||||
schema = _get_schema_common(user_input)
|
schema = {
|
||||||
schema[
|
vol.Required(
|
||||||
vol.Required(CONF_DEVICE, default=user_input.get(CONF_DEVICE, "127.0.0.1"))
|
CONF_DEVICE, default=user_input.get(CONF_DEVICE, "127.0.0.1")
|
||||||
] = str
|
): str,
|
||||||
# Don't use cv.port as that would show a slider *facepalm*
|
|
||||||
schema[
|
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_TCP_PORT, default=user_input.get(CONF_TCP_PORT, DEFAULT_TCP_PORT)
|
CONF_TCP_PORT, default=user_input.get(CONF_TCP_PORT, DEFAULT_TCP_PORT)
|
||||||
)
|
): _PORT_SELECTOR,
|
||||||
] = vol.Coerce(int)
|
}
|
||||||
|
schema.update(_get_schema_common(user_input))
|
||||||
|
|
||||||
schema = vol.Schema(schema)
|
schema = vol.Schema(schema)
|
||||||
return self.async_show_form(step_id="gw_tcp", data_schema=schema, errors=errors)
|
return self.async_show_form(step_id="gw_tcp", data_schema=schema, errors=errors)
|
||||||
|
@ -214,7 +200,13 @@ class MySensorsConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Create a config entry for a mqtt gateway."""
|
"""Create a config entry for a mqtt gateway."""
|
||||||
errors = {}
|
# Naive check that doesn't consider config entry state.
|
||||||
|
if MQTT_DOMAIN not in self.hass.config.components:
|
||||||
|
return self.async_abort(reason="mqtt_required")
|
||||||
|
|
||||||
|
gw_type = self._gw_type = CONF_GATEWAY_TYPE_MQTT
|
||||||
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
user_input[CONF_DEVICE] = MQTT_COMPONENT
|
user_input[CONF_DEVICE] = MQTT_COMPONENT
|
||||||
|
|
||||||
|
@ -239,27 +231,21 @@ class MySensorsConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
elif self._check_topic_exists(user_input[CONF_TOPIC_OUT_PREFIX]):
|
elif self._check_topic_exists(user_input[CONF_TOPIC_OUT_PREFIX]):
|
||||||
errors[CONF_TOPIC_OUT_PREFIX] = "duplicate_topic"
|
errors[CONF_TOPIC_OUT_PREFIX] = "duplicate_topic"
|
||||||
|
|
||||||
errors.update(
|
errors.update(await self.validate_common(gw_type, errors, user_input))
|
||||||
await self.validate_common(CONF_GATEWAY_TYPE_MQTT, errors, user_input)
|
|
||||||
)
|
|
||||||
if not errors:
|
if not errors:
|
||||||
return self._async_create_entry(user_input)
|
return self._async_create_entry(user_input)
|
||||||
|
|
||||||
user_input = user_input or {}
|
user_input = user_input or {}
|
||||||
schema = _get_schema_common(user_input)
|
schema = {
|
||||||
schema[
|
|
||||||
vol.Required(CONF_RETAIN, default=user_input.get(CONF_RETAIN, True))
|
|
||||||
] = bool
|
|
||||||
schema[
|
|
||||||
vol.Required(
|
vol.Required(
|
||||||
CONF_TOPIC_IN_PREFIX, default=user_input.get(CONF_TOPIC_IN_PREFIX, "")
|
CONF_TOPIC_IN_PREFIX, default=user_input.get(CONF_TOPIC_IN_PREFIX, "")
|
||||||
)
|
): str,
|
||||||
] = str
|
|
||||||
schema[
|
|
||||||
vol.Required(
|
vol.Required(
|
||||||
CONF_TOPIC_OUT_PREFIX, default=user_input.get(CONF_TOPIC_OUT_PREFIX, "")
|
CONF_TOPIC_OUT_PREFIX, default=user_input.get(CONF_TOPIC_OUT_PREFIX, "")
|
||||||
)
|
): str,
|
||||||
] = str
|
vol.Required(CONF_RETAIN, default=user_input.get(CONF_RETAIN, True)): bool,
|
||||||
|
}
|
||||||
|
schema.update(_get_schema_common(user_input))
|
||||||
|
|
||||||
schema = vol.Schema(schema)
|
schema = vol.Schema(schema)
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
|
|
|
@ -22,11 +22,6 @@ ConfGatewayType = Literal["Serial", "TCP", "MQTT"]
|
||||||
CONF_GATEWAY_TYPE_SERIAL: ConfGatewayType = "Serial"
|
CONF_GATEWAY_TYPE_SERIAL: ConfGatewayType = "Serial"
|
||||||
CONF_GATEWAY_TYPE_TCP: ConfGatewayType = "TCP"
|
CONF_GATEWAY_TYPE_TCP: ConfGatewayType = "TCP"
|
||||||
CONF_GATEWAY_TYPE_MQTT: ConfGatewayType = "MQTT"
|
CONF_GATEWAY_TYPE_MQTT: ConfGatewayType = "MQTT"
|
||||||
CONF_GATEWAY_TYPE_ALL: list[str] = [
|
|
||||||
CONF_GATEWAY_TYPE_MQTT,
|
|
||||||
CONF_GATEWAY_TYPE_SERIAL,
|
|
||||||
CONF_GATEWAY_TYPE_TCP,
|
|
||||||
]
|
|
||||||
|
|
||||||
DOMAIN: Final = "mysensors"
|
DOMAIN: Final = "mysensors"
|
||||||
MYSENSORS_GATEWAY_START_TASK: str = "mysensors_gateway_start_task_{}"
|
MYSENSORS_GATEWAY_START_TASK: str = "mysensors_gateway_start_task_{}"
|
||||||
|
|
|
@ -7,6 +7,14 @@
|
||||||
},
|
},
|
||||||
"description": "Choose connection method to the gateway"
|
"description": "Choose connection method to the gateway"
|
||||||
},
|
},
|
||||||
|
"select_gateway_type": {
|
||||||
|
"description": "Select which gateway to configure.",
|
||||||
|
"menu_options": {
|
||||||
|
"gw_mqtt": "Configure an MQTT gateway",
|
||||||
|
"gw_serial": "Configure a serial gateway",
|
||||||
|
"gw_tcp": "Configure a TCP gateway"
|
||||||
|
}
|
||||||
|
},
|
||||||
"gw_tcp": {
|
"gw_tcp": {
|
||||||
"description": "Ethernet gateway setup",
|
"description": "Ethernet gateway setup",
|
||||||
"data": {
|
"data": {
|
||||||
|
@ -51,7 +59,6 @@
|
||||||
"invalid_serial": "Invalid serial port",
|
"invalid_serial": "Invalid serial port",
|
||||||
"invalid_device": "Invalid device",
|
"invalid_device": "Invalid device",
|
||||||
"invalid_version": "Invalid MySensors version",
|
"invalid_version": "Invalid MySensors version",
|
||||||
"mqtt_required": "The MQTT integration is not set up",
|
|
||||||
"not_a_number": "Please enter a number",
|
"not_a_number": "Please enter a number",
|
||||||
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
||||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||||
|
@ -71,6 +78,7 @@
|
||||||
"invalid_serial": "Invalid serial port",
|
"invalid_serial": "Invalid serial port",
|
||||||
"invalid_device": "Invalid device",
|
"invalid_device": "Invalid device",
|
||||||
"invalid_version": "Invalid MySensors version",
|
"invalid_version": "Invalid MySensors version",
|
||||||
|
"mqtt_required": "The MQTT integration is not set up",
|
||||||
"not_a_number": "Please enter a number",
|
"not_a_number": "Please enter a number",
|
||||||
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
||||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"invalid_serial": "Invalid serial port",
|
"invalid_serial": "Invalid serial port",
|
||||||
"invalid_subscribe_topic": "Invalid subscribe topic",
|
"invalid_subscribe_topic": "Invalid subscribe topic",
|
||||||
"invalid_version": "Invalid MySensors version",
|
"invalid_version": "Invalid MySensors version",
|
||||||
|
"mqtt_required": "The MQTT integration is not set up",
|
||||||
"not_a_number": "Please enter a number",
|
"not_a_number": "Please enter a number",
|
||||||
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
||||||
"same_topic": "Subscribe and publish topics are the same",
|
"same_topic": "Subscribe and publish topics are the same",
|
||||||
|
@ -33,7 +34,6 @@
|
||||||
"invalid_serial": "Invalid serial port",
|
"invalid_serial": "Invalid serial port",
|
||||||
"invalid_subscribe_topic": "Invalid subscribe topic",
|
"invalid_subscribe_topic": "Invalid subscribe topic",
|
||||||
"invalid_version": "Invalid MySensors version",
|
"invalid_version": "Invalid MySensors version",
|
||||||
"mqtt_required": "The MQTT integration is not set up",
|
|
||||||
"not_a_number": "Please enter a number",
|
"not_a_number": "Please enter a number",
|
||||||
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
"port_out_of_range": "Port number must be at least 1 and at most 65535",
|
||||||
"same_topic": "Subscribe and publish topics are the same",
|
"same_topic": "Subscribe and publish topics are the same",
|
||||||
|
@ -68,6 +68,14 @@
|
||||||
},
|
},
|
||||||
"description": "Ethernet gateway setup"
|
"description": "Ethernet gateway setup"
|
||||||
},
|
},
|
||||||
|
"select_gateway_type": {
|
||||||
|
"description": "Select which gateway to configure.",
|
||||||
|
"menu_options": {
|
||||||
|
"gw_mqtt": "Configure an MQTT gateway",
|
||||||
|
"gw_serial": "Configure a serial gateway",
|
||||||
|
"gw_tcp": "Configure a TCP gateway"
|
||||||
|
}
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"gateway_type": "Gateway type"
|
"gateway_type": "Gateway type"
|
||||||
|
|
|
@ -24,28 +24,32 @@ from homeassistant.components.mysensors.const import (
|
||||||
ConfGatewayType,
|
ConfGatewayType,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult, FlowResultType
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
GATEWAY_TYPE_TO_STEP = {
|
||||||
|
CONF_GATEWAY_TYPE_TCP: "gw_tcp",
|
||||||
|
CONF_GATEWAY_TYPE_SERIAL: "gw_serial",
|
||||||
|
CONF_GATEWAY_TYPE_MQTT: "gw_mqtt",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def get_form(
|
async def get_form(
|
||||||
hass: HomeAssistant, gatway_type: ConfGatewayType, expected_step_id: str
|
hass: HomeAssistant, gateway_type: ConfGatewayType, expected_step_id: str
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Get a form for the given gateway type."""
|
"""Get a form for the given gateway type."""
|
||||||
|
|
||||||
stepuser = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
)
|
)
|
||||||
assert stepuser["type"] == "form"
|
assert result["type"] == FlowResultType.MENU
|
||||||
assert not stepuser["errors"]
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
stepuser["flow_id"],
|
result["flow_id"], {"next_step_id": GATEWAY_TYPE_TO_STEP[gateway_type]}
|
||||||
{CONF_GATEWAY_TYPE: gatway_type},
|
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert result["type"] == "form"
|
assert result["type"] == FlowResultType.FORM
|
||||||
assert result["step_id"] == expected_step_id
|
assert result["step_id"] == expected_step_id
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -62,7 +66,7 @@ async def test_config_mqtt(hass: HomeAssistant, mqtt: None) -> None:
|
||||||
"homeassistant.components.mysensors.async_setup_entry",
|
"homeassistant.components.mysensors.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id,
|
flow_id,
|
||||||
{
|
{
|
||||||
CONF_RETAIN: True,
|
CONF_RETAIN: True,
|
||||||
|
@ -73,11 +77,11 @@ async def test_config_mqtt(hass: HomeAssistant, mqtt: None) -> None:
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
if "errors" in result2:
|
if "errors" in result:
|
||||||
assert not result2["errors"]
|
assert not result["errors"]
|
||||||
assert result2["type"] == "create_entry"
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
assert result2["title"] == "mqtt"
|
assert result["title"] == "mqtt"
|
||||||
assert result2["data"] == {
|
assert result["data"] == {
|
||||||
CONF_DEVICE: "mqtt",
|
CONF_DEVICE: "mqtt",
|
||||||
CONF_RETAIN: True,
|
CONF_RETAIN: True,
|
||||||
CONF_TOPIC_IN_PREFIX: "bla",
|
CONF_TOPIC_IN_PREFIX: "bla",
|
||||||
|
@ -91,20 +95,19 @@ async def test_config_mqtt(hass: HomeAssistant, mqtt: None) -> None:
|
||||||
|
|
||||||
async def test_missing_mqtt(hass: HomeAssistant) -> None:
|
async def test_missing_mqtt(hass: HomeAssistant) -> None:
|
||||||
"""Test configuring a mqtt gateway without mqtt integration setup."""
|
"""Test configuring a mqtt gateway without mqtt integration setup."""
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
)
|
)
|
||||||
assert result["type"] == "form"
|
assert result["type"] == FlowResultType.MENU
|
||||||
assert not result["errors"]
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_GATEWAY_TYPE: CONF_GATEWAY_TYPE_MQTT},
|
{"next_step_id": GATEWAY_TYPE_TO_STEP[CONF_GATEWAY_TYPE_MQTT]},
|
||||||
)
|
)
|
||||||
assert result["step_id"] == "user"
|
await hass.async_block_till_done()
|
||||||
assert result["type"] == "form"
|
|
||||||
assert result["errors"] == {"base": "mqtt_required"}
|
assert result["type"] == FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "mqtt_required"
|
||||||
|
|
||||||
|
|
||||||
async def test_config_serial(hass: HomeAssistant) -> None:
|
async def test_config_serial(hass: HomeAssistant) -> None:
|
||||||
|
@ -123,7 +126,7 @@ async def test_config_serial(hass: HomeAssistant) -> None:
|
||||||
"homeassistant.components.mysensors.async_setup_entry",
|
"homeassistant.components.mysensors.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id,
|
flow_id,
|
||||||
{
|
{
|
||||||
CONF_BAUD_RATE: 115200,
|
CONF_BAUD_RATE: 115200,
|
||||||
|
@ -133,11 +136,11 @@ async def test_config_serial(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
if "errors" in result2:
|
if "errors" in result:
|
||||||
assert not result2["errors"]
|
assert not result["errors"]
|
||||||
assert result2["type"] == "create_entry"
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
assert result2["title"] == "/dev/ttyACM0"
|
assert result["title"] == "/dev/ttyACM0"
|
||||||
assert result2["data"] == {
|
assert result["data"] == {
|
||||||
CONF_DEVICE: "/dev/ttyACM0",
|
CONF_DEVICE: "/dev/ttyACM0",
|
||||||
CONF_BAUD_RATE: 115200,
|
CONF_BAUD_RATE: 115200,
|
||||||
CONF_VERSION: "2.4",
|
CONF_VERSION: "2.4",
|
||||||
|
@ -160,7 +163,7 @@ async def test_config_tcp(hass: HomeAssistant) -> None:
|
||||||
"homeassistant.components.mysensors.async_setup_entry",
|
"homeassistant.components.mysensors.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id,
|
flow_id,
|
||||||
{
|
{
|
||||||
CONF_TCP_PORT: 5003,
|
CONF_TCP_PORT: 5003,
|
||||||
|
@ -170,11 +173,11 @@ async def test_config_tcp(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
if "errors" in result2:
|
if "errors" in result:
|
||||||
assert not result2["errors"]
|
assert not result["errors"]
|
||||||
assert result2["type"] == "create_entry"
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
assert result2["title"] == "127.0.0.1"
|
assert result["title"] == "127.0.0.1"
|
||||||
assert result2["data"] == {
|
assert result["data"] == {
|
||||||
CONF_DEVICE: "127.0.0.1",
|
CONF_DEVICE: "127.0.0.1",
|
||||||
CONF_TCP_PORT: 5003,
|
CONF_TCP_PORT: 5003,
|
||||||
CONF_VERSION: "2.4",
|
CONF_VERSION: "2.4",
|
||||||
|
@ -197,7 +200,7 @@ async def test_fail_to_connect(hass: HomeAssistant) -> None:
|
||||||
"homeassistant.components.mysensors.async_setup_entry",
|
"homeassistant.components.mysensors.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id,
|
flow_id,
|
||||||
{
|
{
|
||||||
CONF_TCP_PORT: 5003,
|
CONF_TCP_PORT: 5003,
|
||||||
|
@ -207,9 +210,9 @@ async def test_fail_to_connect(hass: HomeAssistant) -> None:
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result["type"] == FlowResultType.FORM
|
||||||
assert "errors" in result2
|
assert "errors" in result
|
||||||
errors = result2["errors"]
|
errors = result["errors"]
|
||||||
assert errors
|
assert errors
|
||||||
assert errors.get("base") == "cannot_connect"
|
assert errors.get("base") == "cannot_connect"
|
||||||
assert len(mock_setup.mock_calls) == 0
|
assert len(mock_setup.mock_calls) == 0
|
||||||
|
@ -219,28 +222,6 @@ async def test_fail_to_connect(hass: HomeAssistant) -> None:
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"gateway_type, expected_step_id, user_input, err_field, err_string",
|
"gateway_type, expected_step_id, user_input, err_field, err_string",
|
||||||
[
|
[
|
||||||
(
|
|
||||||
CONF_GATEWAY_TYPE_TCP,
|
|
||||||
"gw_tcp",
|
|
||||||
{
|
|
||||||
CONF_TCP_PORT: 600_000,
|
|
||||||
CONF_DEVICE: "127.0.0.1",
|
|
||||||
CONF_VERSION: "2.4",
|
|
||||||
},
|
|
||||||
CONF_TCP_PORT,
|
|
||||||
"port_out_of_range",
|
|
||||||
),
|
|
||||||
(
|
|
||||||
CONF_GATEWAY_TYPE_TCP,
|
|
||||||
"gw_tcp",
|
|
||||||
{
|
|
||||||
CONF_TCP_PORT: 0,
|
|
||||||
CONF_DEVICE: "127.0.0.1",
|
|
||||||
CONF_VERSION: "2.4",
|
|
||||||
},
|
|
||||||
CONF_TCP_PORT,
|
|
||||||
"port_out_of_range",
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
CONF_GATEWAY_TYPE_TCP,
|
CONF_GATEWAY_TYPE_TCP,
|
||||||
"gw_tcp",
|
"gw_tcp",
|
||||||
|
@ -382,15 +363,15 @@ async def test_config_invalid(
|
||||||
"homeassistant.components.mysensors.async_setup_entry",
|
"homeassistant.components.mysensors.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id,
|
flow_id,
|
||||||
user_input,
|
user_input,
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result["type"] == FlowResultType.FORM
|
||||||
assert "errors" in result2
|
assert "errors" in result
|
||||||
errors = result2["errors"]
|
errors = result["errors"]
|
||||||
assert errors
|
assert errors
|
||||||
assert err_field in errors
|
assert err_field in errors
|
||||||
assert errors[err_field] == err_string
|
assert errors[err_field] == err_string
|
||||||
|
@ -681,10 +662,8 @@ async def test_duplicate(
|
||||||
MockConfigEntry(domain=DOMAIN, data=first_input).add_to_hass(hass)
|
MockConfigEntry(domain=DOMAIN, data=first_input).add_to_hass(hass)
|
||||||
|
|
||||||
second_gateway_type = second_input.pop(CONF_GATEWAY_TYPE)
|
second_gateway_type = second_input.pop(CONF_GATEWAY_TYPE)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await get_form(
|
||||||
DOMAIN,
|
hass, second_gateway_type, GATEWAY_TYPE_TO_STEP[second_gateway_type]
|
||||||
data={CONF_GATEWAY_TYPE: second_gateway_type},
|
|
||||||
context={"source": config_entries.SOURCE_USER},
|
|
||||||
)
|
)
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
|
|
Loading…
Reference in New Issue