Error checking for OTBR (#88620)

* Error checking for OTBR

* Other errors in flow too

* Tests
pull/88637/head
Paulus Schoutsen 2023-02-22 14:58:11 -05:00 committed by GitHub
parent 3ebb2fc3a9
commit c6ff79aa0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 9 deletions

View File

@ -1,11 +1,13 @@
"""The Open Thread Border Router integration.""" """The Open Thread Border Router integration."""
from __future__ import annotations from __future__ import annotations
import asyncio
from collections.abc import Callable, Coroutine from collections.abc import Callable, Coroutine
import dataclasses import dataclasses
from functools import wraps from functools import wraps
from typing import Any, Concatenate, ParamSpec, TypeVar from typing import Any, Concatenate, ParamSpec, TypeVar
import aiohttp
import python_otbr_api import python_otbr_api
from homeassistant.components.thread import async_add_dataset from homeassistant.components.thread import async_add_dataset
@ -63,8 +65,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
otbrdata = OTBRData(entry.data["url"], api) otbrdata = OTBRData(entry.data["url"], api)
try: try:
dataset = await otbrdata.get_active_dataset_tlvs() dataset = await otbrdata.get_active_dataset_tlvs()
except HomeAssistantError as err: except (
raise ConfigEntryNotReady from err HomeAssistantError,
aiohttp.ClientError,
asyncio.TimeoutError,
) as err:
raise ConfigEntryNotReady("Unable to connect") from err
if dataset: if dataset:
await async_add_dataset(hass, entry.title, dataset.hex()) await async_add_dataset(hass, entry.title, dataset.hex())

View File

@ -1,8 +1,10 @@
"""Config flow for the Open Thread Border Router integration.""" """Config flow for the Open Thread Border Router integration."""
from __future__ import annotations from __future__ import annotations
import asyncio
import logging import logging
import aiohttp
import python_otbr_api import python_otbr_api
import voluptuous as vol import voluptuous as vol
@ -48,7 +50,11 @@ class OTBRConfigFlow(ConfigFlow, domain=DOMAIN):
url = user_input[CONF_URL] url = user_input[CONF_URL]
try: try:
await self._connect_and_create_dataset(url) await self._connect_and_create_dataset(url)
except python_otbr_api.OTBRError: except (
python_otbr_api.OTBRError,
aiohttp.ClientError,
asyncio.TimeoutError,
):
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
else: else:
await self.async_set_unique_id(DOMAIN) await self.async_set_unique_id(DOMAIN)

View File

@ -1,8 +1,11 @@
"""Test the Open Thread Border Router config flow.""" """Test the Open Thread Border Router config flow."""
import asyncio
from http import HTTPStatus from http import HTTPStatus
from unittest.mock import patch from unittest.mock import patch
import aiohttp
import pytest import pytest
import python_otbr_api
from homeassistant.components import hassio, otbr from homeassistant.components import hassio, otbr
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -137,6 +140,34 @@ async def test_user_flow_404(
assert result["errors"] == {"base": "cannot_connect"} assert result["errors"] == {"base": "cannot_connect"}
@pytest.mark.parametrize(
"error",
[
asyncio.TimeoutError,
python_otbr_api.OTBRError,
aiohttp.ClientError,
],
)
async def test_user_flow_connect_error(hass: HomeAssistant, error) -> None:
"""Test the user flow."""
result = await hass.config_entries.flow.async_init(
otbr.DOMAIN, context={"source": "user"}
)
assert result["type"] == FlowResultType.FORM
assert result["errors"] == {}
with patch("python_otbr_api.OTBR.get_active_dataset_tlvs", side_effect=error):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
"url": "http://custom_url:1234",
},
)
assert result["type"] == FlowResultType.FORM
assert result["errors"] == {"base": "cannot_connect"}
async def test_hassio_discovery_flow( async def test_hassio_discovery_flow(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: ) -> None:

View File

@ -1,9 +1,11 @@
"""Test the Open Thread Border Router integration.""" """Test the Open Thread Border Router integration."""
import asyncio
from http import HTTPStatus from http import HTTPStatus
from unittest.mock import patch from unittest.mock import patch
import aiohttp
import pytest import pytest
import python_otbr_api
from homeassistant.components import otbr from homeassistant.components import otbr
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -35,9 +37,15 @@ async def test_import_dataset(hass: HomeAssistant) -> None:
mock_add.assert_called_once_with(config_entry.title, DATASET.hex()) mock_add.assert_called_once_with(config_entry.title, DATASET.hex())
async def test_config_entry_not_ready( @pytest.mark.parametrize(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker "error",
) -> None: [
asyncio.TimeoutError,
python_otbr_api.OTBRError,
aiohttp.ClientError,
],
)
async def test_config_entry_not_ready(hass: HomeAssistant, error) -> None:
"""Test raising ConfigEntryNotReady .""" """Test raising ConfigEntryNotReady ."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
@ -47,8 +55,8 @@ async def test_config_entry_not_ready(
title="My OTBR", title="My OTBR",
) )
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
aioclient_mock.get(f"{BASE_URL}/node/dataset/active", status=HTTPStatus.CREATED) with patch("python_otbr_api.OTBR.get_active_dataset_tlvs", side_effect=error):
assert not await hass.config_entries.async_setup(config_entry.entry_id) assert not await hass.config_entries.async_setup(config_entry.entry_id)
async def test_remove_entry( async def test_remove_entry(