Fix Doorbird yaml import aborted if discovery finds it first (#33843)
parent
885cf20afa
commit
9b8d1b88c5
|
@ -68,17 +68,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
"""Handle the initial step."""
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
try:
|
||||
info = await validate_input(self.hass, user_input)
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except InvalidAuth:
|
||||
errors["base"] = "invalid_auth"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
|
||||
if "base" not in errors:
|
||||
info, errors = await self._async_validate_or_error(user_input)
|
||||
if not errors:
|
||||
await self.async_set_unique_id(info["mac_addr"])
|
||||
self._abort_if_unique_id_configured()
|
||||
return self.async_create_entry(title=info["title"], data=user_input)
|
||||
|
@ -119,8 +110,31 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def async_step_import(self, user_input):
|
||||
"""Handle import."""
|
||||
if user_input:
|
||||
info, errors = await self._async_validate_or_error(user_input)
|
||||
if not errors:
|
||||
await self.async_set_unique_id(
|
||||
info["mac_addr"], raise_on_progress=False
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
return self.async_create_entry(title=info["title"], data=user_input)
|
||||
return await self.async_step_user(user_input)
|
||||
|
||||
async def _async_validate_or_error(self, user_input):
|
||||
"""Validate doorbird or error."""
|
||||
errors = {}
|
||||
info = {}
|
||||
try:
|
||||
info = await validate_input(self.hass, user_input)
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except InvalidAuth:
|
||||
errors["base"] = "invalid_auth"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
return info, errors
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry):
|
||||
|
|
|
@ -127,6 +127,73 @@ async def test_form_import(hass):
|
|||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_import_with_zeroconf_already_discovered(hass):
|
||||
"""Test we get the form with import source."""
|
||||
await hass.async_add_executor_job(
|
||||
init_recorder_component, hass
|
||||
) # force in memory db
|
||||
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
# Running the zeroconf init will make the unique id
|
||||
# in progress
|
||||
zero_conf = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||
data={
|
||||
"properties": {"macaddress": "1CCAE3DOORBIRD"},
|
||||
"name": "Doorstation - abc123._axis-video._tcp.local.",
|
||||
"host": "192.168.1.5",
|
||||
},
|
||||
)
|
||||
assert zero_conf["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert zero_conf["step_id"] == "user"
|
||||
assert zero_conf["errors"] == {}
|
||||
|
||||
import_config = VALID_CONFIG.copy()
|
||||
import_config[CONF_EVENTS] = ["event1", "event2", "event3"]
|
||||
import_config[CONF_TOKEN] = "imported_token"
|
||||
import_config[
|
||||
CONF_CUSTOM_URL
|
||||
] = "http://legacy.custom.url/should/only/come/in/from/yaml"
|
||||
|
||||
doorbirdapi = _get_mock_doorbirdapi_return_values(
|
||||
ready=[True], info={"WIFI_MAC_ADDR": "1CCAE3DOORBIRD"}
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.doorbird.config_flow.DoorBird",
|
||||
return_value=doorbirdapi,
|
||||
), patch("homeassistant.components.logbook.async_setup", return_value=True), patch(
|
||||
"homeassistant.components.doorbird.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.doorbird.async_setup_entry", return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data=import_config,
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == "1.2.3.4"
|
||||
assert result["data"] == {
|
||||
"host": "1.2.3.4",
|
||||
"name": "mydoorbird",
|
||||
"password": "password",
|
||||
"username": "friend",
|
||||
"events": ["event1", "event2", "event3"],
|
||||
"token": "imported_token",
|
||||
# This will go away once we convert to cloud hooks
|
||||
"hass_url_override": "http://legacy.custom.url/should/only/come/in/from/yaml",
|
||||
}
|
||||
# It is not possible to import options at this time
|
||||
# so they end up in the config entry data and are
|
||||
# used a fallback when they are not in options
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_zeroconf_wrong_oui(hass):
|
||||
"""Test we abort when we get the wrong OUI via zeroconf."""
|
||||
await hass.async_add_executor_job(
|
||||
|
|
Loading…
Reference in New Issue