mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Make type checking pass for deCONZ init, gateway and services (#66054)
* Type and enable type checking for init, config_flow, diagnostics, gateway and services * Fix import * Fix review comment
This commit is contained in:
parent
3afadf8adb
commit
dd88a05cb4
@ -58,6 +58,11 @@ homeassistant.components.canary.*
|
||||
homeassistant.components.cover.*
|
||||
homeassistant.components.crownstone.*
|
||||
homeassistant.components.cpuspeed.*
|
||||
homeassistant.components.deconz
|
||||
homeassistant.components.deconz.config_flow
|
||||
homeassistant.components.deconz.diagnostics
|
||||
homeassistant.components.deconz.gateway
|
||||
homeassistant.components.deconz.services
|
||||
homeassistant.components.device_automation.*
|
||||
homeassistant.components.device_tracker.*
|
||||
homeassistant.components.devolo_home_control.*
|
||||
|
@ -12,11 +12,14 @@ from homeassistant.const import (
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
|
||||
from .config_flow import get_master_gateway
|
||||
from .const import CONF_GROUP_ID_BASE, CONF_MASTER_GATEWAY, DOMAIN
|
||||
from .gateway import DeconzGateway
|
||||
from .const import CONF_GROUP_ID_BASE, CONF_MASTER_GATEWAY, DOMAIN, PLATFORMS
|
||||
from .deconz_event import async_setup_events, async_unload_events
|
||||
from .errors import AuthenticationRequired, CannotConnect
|
||||
from .gateway import DeconzGateway, get_deconz_session
|
||||
from .services import async_setup_services, async_unload_services
|
||||
|
||||
|
||||
@ -33,16 +36,27 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||
if not config_entry.options:
|
||||
await async_update_master_gateway(hass, config_entry)
|
||||
|
||||
gateway = DeconzGateway(hass, config_entry)
|
||||
if not await gateway.async_setup():
|
||||
return False
|
||||
try:
|
||||
api = await get_deconz_session(hass, config_entry.data)
|
||||
except CannotConnect as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
except AuthenticationRequired as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
|
||||
if not hass.data[DOMAIN]:
|
||||
gateway = hass.data[DOMAIN][config_entry.entry_id] = DeconzGateway(
|
||||
hass, config_entry, api
|
||||
)
|
||||
|
||||
config_entry.add_update_listener(gateway.async_config_entry_updated)
|
||||
hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)
|
||||
|
||||
await async_setup_events(gateway)
|
||||
await gateway.async_update_device_registry()
|
||||
|
||||
if len(hass.data[DOMAIN]) == 1:
|
||||
async_setup_services(hass)
|
||||
|
||||
hass.data[DOMAIN][config_entry.entry_id] = gateway
|
||||
|
||||
await gateway.async_update_device_registry()
|
||||
api.start()
|
||||
|
||||
config_entry.async_on_unload(
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, gateway.shutdown)
|
||||
@ -53,7 +67,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Unload deCONZ config entry."""
|
||||
gateway = hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
gateway: DeconzGateway = hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
async_unload_events(gateway)
|
||||
|
||||
if not hass.data[DOMAIN]:
|
||||
async_unload_services(hass)
|
||||
@ -89,9 +104,10 @@ async def async_update_group_unique_id(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Update unique ID entities based on deCONZ groups."""
|
||||
if not isinstance(old_unique_id := config_entry.data.get(CONF_GROUP_ID_BASE), str):
|
||||
if not (group_id_base := config_entry.data.get(CONF_GROUP_ID_BASE)):
|
||||
return
|
||||
|
||||
old_unique_id = cast(str, group_id_base)
|
||||
new_unique_id = cast(str, config_entry.unique_id)
|
||||
|
||||
@callback
|
||||
|
@ -1,13 +1,21 @@
|
||||
"""Representation of a deCONZ gateway."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from types import MappingProxyType
|
||||
from typing import Any, cast
|
||||
|
||||
import async_timeout
|
||||
from pydeconz import DeconzSession, errors, group, light, sensor
|
||||
from pydeconz.alarm_system import AlarmSystem as DeconzAlarmSystem
|
||||
from pydeconz.group import Group as DeconzGroup
|
||||
from pydeconz.light import DeconzLight
|
||||
from pydeconz.sensor import DeconzSensor
|
||||
|
||||
from homeassistant.config_entries import SOURCE_HASSIO, ConfigEntry
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.helpers import (
|
||||
aiohttp_client,
|
||||
device_registry as dr,
|
||||
@ -29,25 +37,23 @@ from .const import (
|
||||
LOGGER,
|
||||
PLATFORMS,
|
||||
)
|
||||
from .deconz_event import async_setup_events, async_unload_events
|
||||
from .deconz_event import DeconzAlarmEvent, DeconzEvent
|
||||
from .errors import AuthenticationRequired, CannotConnect
|
||||
|
||||
|
||||
@callback
|
||||
def get_gateway_from_config_entry(hass, config_entry):
|
||||
"""Return gateway with a matching config entry ID."""
|
||||
return hass.data[DECONZ_DOMAIN][config_entry.entry_id]
|
||||
|
||||
|
||||
class DeconzGateway:
|
||||
"""Manages a single deCONZ gateway."""
|
||||
|
||||
def __init__(self, hass, config_entry) -> None:
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, config_entry: ConfigEntry, api: DeconzSession
|
||||
) -> None:
|
||||
"""Initialize the system."""
|
||||
self.hass = hass
|
||||
self.config_entry = config_entry
|
||||
self.api = api
|
||||
|
||||
self.api = None
|
||||
api.add_device_callback = self.async_add_device_callback
|
||||
api.connection_status_callback = self.async_connection_status_callback
|
||||
|
||||
self.available = True
|
||||
self.ignore_state_updates = False
|
||||
@ -66,24 +72,24 @@ class DeconzGateway:
|
||||
sensor.RESOURCE_TYPE: self.signal_new_sensor,
|
||||
}
|
||||
|
||||
self.deconz_ids = {}
|
||||
self.entities = {}
|
||||
self.events = []
|
||||
self.deconz_ids: dict[str, str] = {}
|
||||
self.entities: dict[str, set[str]] = {}
|
||||
self.events: list[DeconzAlarmEvent | DeconzEvent] = []
|
||||
|
||||
@property
|
||||
def bridgeid(self) -> str:
|
||||
"""Return the unique identifier of the gateway."""
|
||||
return self.config_entry.unique_id
|
||||
return cast(str, self.config_entry.unique_id)
|
||||
|
||||
@property
|
||||
def host(self) -> str:
|
||||
"""Return the host of the gateway."""
|
||||
return self.config_entry.data[CONF_HOST]
|
||||
return cast(str, self.config_entry.data[CONF_HOST])
|
||||
|
||||
@property
|
||||
def master(self) -> bool:
|
||||
"""Gateway which is used with deCONZ services without defining id."""
|
||||
return self.config_entry.options[CONF_MASTER_GATEWAY]
|
||||
return cast(bool, self.config_entry.options[CONF_MASTER_GATEWAY])
|
||||
|
||||
# Options
|
||||
|
||||
@ -111,7 +117,7 @@ class DeconzGateway:
|
||||
# Callbacks
|
||||
|
||||
@callback
|
||||
def async_connection_status_callback(self, available) -> None:
|
||||
def async_connection_status_callback(self, available: bool) -> None:
|
||||
"""Handle signals of gateway connection status."""
|
||||
self.available = available
|
||||
self.ignore_state_updates = False
|
||||
@ -119,7 +125,15 @@ class DeconzGateway:
|
||||
|
||||
@callback
|
||||
def async_add_device_callback(
|
||||
self, resource_type, device=None, force: bool = False
|
||||
self,
|
||||
resource_type: str,
|
||||
device: DeconzAlarmSystem
|
||||
| DeconzGroup
|
||||
| DeconzLight
|
||||
| DeconzSensor
|
||||
| list[DeconzAlarmSystem | DeconzGroup | DeconzLight | DeconzSensor]
|
||||
| None = None,
|
||||
force: bool = False,
|
||||
) -> None:
|
||||
"""Handle event of new device creation in deCONZ."""
|
||||
if (
|
||||
@ -166,32 +180,6 @@ class DeconzGateway:
|
||||
via_device=(CONNECTION_NETWORK_MAC, self.api.config.mac),
|
||||
)
|
||||
|
||||
async def async_setup(self) -> bool:
|
||||
"""Set up a deCONZ gateway."""
|
||||
try:
|
||||
self.api = await get_gateway(
|
||||
self.hass,
|
||||
self.config_entry.data,
|
||||
self.async_add_device_callback,
|
||||
self.async_connection_status_callback,
|
||||
)
|
||||
|
||||
except CannotConnect as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
except AuthenticationRequired as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
|
||||
self.hass.config_entries.async_setup_platforms(self.config_entry, PLATFORMS)
|
||||
|
||||
await async_setup_events(self)
|
||||
|
||||
self.api.start()
|
||||
|
||||
self.config_entry.add_update_listener(self.async_config_entry_updated)
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
async def async_config_entry_updated(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
@ -211,7 +199,7 @@ class DeconzGateway:
|
||||
|
||||
await gateway.options_updated()
|
||||
|
||||
async def options_updated(self):
|
||||
async def options_updated(self) -> None:
|
||||
"""Manage entities affected by config entry options."""
|
||||
deconz_ids = []
|
||||
|
||||
@ -242,14 +230,14 @@ class DeconzGateway:
|
||||
entity_registry.async_remove(entity_id)
|
||||
|
||||
@callback
|
||||
def shutdown(self, event) -> None:
|
||||
def shutdown(self, event: Event) -> None:
|
||||
"""Wrap the call to deconz.close.
|
||||
|
||||
Used as an argument to EventBus.async_listen_once.
|
||||
"""
|
||||
self.api.close()
|
||||
|
||||
async def async_reset(self):
|
||||
async def async_reset(self) -> bool:
|
||||
"""Reset this gateway to default state."""
|
||||
self.api.async_connection_status_callback = None
|
||||
self.api.close()
|
||||
@ -258,30 +246,35 @@ class DeconzGateway:
|
||||
self.config_entry, PLATFORMS
|
||||
)
|
||||
|
||||
async_unload_events(self)
|
||||
|
||||
self.deconz_ids = {}
|
||||
return True
|
||||
|
||||
|
||||
async def get_gateway(
|
||||
hass, config, async_add_device_callback, async_connection_status_callback
|
||||
@callback
|
||||
def get_gateway_from_config_entry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> DeconzGateway:
|
||||
"""Return gateway with a matching config entry ID."""
|
||||
return cast(DeconzGateway, hass.data[DECONZ_DOMAIN][config_entry.entry_id])
|
||||
|
||||
|
||||
async def get_deconz_session(
|
||||
hass: HomeAssistant,
|
||||
config: MappingProxyType[str, Any],
|
||||
) -> DeconzSession:
|
||||
"""Create a gateway object and verify configuration."""
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
|
||||
deconz = DeconzSession(
|
||||
deconz_session = DeconzSession(
|
||||
session,
|
||||
config[CONF_HOST],
|
||||
config[CONF_PORT],
|
||||
config[CONF_API_KEY],
|
||||
add_device=async_add_device_callback,
|
||||
connection_status=async_connection_status_callback,
|
||||
)
|
||||
try:
|
||||
async with async_timeout.timeout(10):
|
||||
await deconz.refresh_state()
|
||||
return deconz
|
||||
await deconz_session.refresh_state()
|
||||
return deconz_session
|
||||
|
||||
except errors.Unauthorized as err:
|
||||
LOGGER.warning("Invalid key for deCONZ at %s", config[CONF_HOST])
|
||||
|
@ -1,7 +1,5 @@
|
||||
"""deCONZ services."""
|
||||
|
||||
from types import MappingProxyType
|
||||
|
||||
from pydeconz.utils import normalize_bridge_id
|
||||
import voluptuous as vol
|
||||
|
||||
@ -16,6 +14,7 @@ from homeassistant.helpers.entity_registry import (
|
||||
async_entries_for_config_entry,
|
||||
async_entries_for_device,
|
||||
)
|
||||
from homeassistant.util.read_only_dict import ReadOnlyDict
|
||||
|
||||
from .config_flow import get_master_gateway
|
||||
from .const import CONF_BRIDGE_ID, DOMAIN, LOGGER
|
||||
@ -111,9 +110,7 @@ def async_unload_services(hass: HomeAssistant) -> None:
|
||||
hass.services.async_remove(DOMAIN, service)
|
||||
|
||||
|
||||
async def async_configure_service(
|
||||
gateway: DeconzGateway, data: MappingProxyType
|
||||
) -> None:
|
||||
async def async_configure_service(gateway: DeconzGateway, data: ReadOnlyDict) -> None:
|
||||
"""Set attribute of device in deCONZ.
|
||||
|
||||
Entity is used to resolve to a device path (e.g. '/lights/1').
|
||||
|
64
mypy.ini
64
mypy.ini
@ -447,6 +447,61 @@ no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.deconz]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.config_flow]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.diagnostics]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.gateway]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.services]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.device_automation.*]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
@ -2209,9 +2264,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.conversation.default_agent]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.alarm_control_panel]
|
||||
ignore_errors = true
|
||||
|
||||
@ -2227,9 +2279,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.deconz.fan]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.gateway]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.light]
|
||||
ignore_errors = true
|
||||
|
||||
@ -2245,9 +2294,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.deconz.sensor]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.services]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.deconz.siren]
|
||||
ignore_errors = true
|
||||
|
||||
|
@ -23,19 +23,16 @@ IGNORED_MODULES: Final[list[str]] = [
|
||||
"homeassistant.components.cloud.http_api",
|
||||
"homeassistant.components.conversation",
|
||||
"homeassistant.components.conversation.default_agent",
|
||||
"homeassistant.components.deconz",
|
||||
"homeassistant.components.deconz.alarm_control_panel",
|
||||
"homeassistant.components.deconz.binary_sensor",
|
||||
"homeassistant.components.deconz.climate",
|
||||
"homeassistant.components.deconz.cover",
|
||||
"homeassistant.components.deconz.fan",
|
||||
"homeassistant.components.deconz.gateway",
|
||||
"homeassistant.components.deconz.light",
|
||||
"homeassistant.components.deconz.lock",
|
||||
"homeassistant.components.deconz.logbook",
|
||||
"homeassistant.components.deconz.number",
|
||||
"homeassistant.components.deconz.sensor",
|
||||
"homeassistant.components.deconz.services",
|
||||
"homeassistant.components.deconz.siren",
|
||||
"homeassistant.components.deconz.switch",
|
||||
"homeassistant.components.denonavr.config_flow",
|
||||
|
@ -1,7 +1,8 @@
|
||||
"""Test deCONZ gateway."""
|
||||
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
import pydeconz
|
||||
from pydeconz.websocket import STATE_RETRYING, STATE_RUNNING
|
||||
@ -19,7 +20,7 @@ from homeassistant.components.deconz.config_flow import DECONZ_MANUFACTURERURL
|
||||
from homeassistant.components.deconz.const import DOMAIN as DECONZ_DOMAIN
|
||||
from homeassistant.components.deconz.errors import AuthenticationRequired, CannotConnect
|
||||
from homeassistant.components.deconz.gateway import (
|
||||
get_gateway,
|
||||
get_deconz_session,
|
||||
get_gateway_from_config_entry,
|
||||
)
|
||||
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
|
||||
@ -202,25 +203,6 @@ async def test_gateway_device_configuration_url_when_addon(hass, aioclient_mock)
|
||||
)
|
||||
|
||||
|
||||
async def test_gateway_retry(hass):
|
||||
"""Retry setup."""
|
||||
with patch(
|
||||
"homeassistant.components.deconz.gateway.get_gateway",
|
||||
side_effect=CannotConnect,
|
||||
):
|
||||
await setup_deconz_integration(hass)
|
||||
assert not hass.data[DECONZ_DOMAIN]
|
||||
|
||||
|
||||
async def test_gateway_setup_fails(hass):
|
||||
"""Retry setup."""
|
||||
with patch(
|
||||
"homeassistant.components.deconz.gateway.get_gateway", side_effect=Exception
|
||||
):
|
||||
await setup_deconz_integration(hass)
|
||||
assert not hass.data[DECONZ_DOMAIN]
|
||||
|
||||
|
||||
async def test_connection_status_signalling(
|
||||
hass, aioclient_mock, mock_deconz_websocket
|
||||
):
|
||||
@ -282,18 +264,6 @@ async def test_update_address(hass, aioclient_mock):
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_gateway_trigger_reauth_flow(hass):
|
||||
"""Failed authentication trigger a reauthentication flow."""
|
||||
with patch(
|
||||
"homeassistant.components.deconz.gateway.get_gateway",
|
||||
side_effect=AuthenticationRequired,
|
||||
), patch.object(hass.config_entries.flow, "async_init") as mock_flow_init:
|
||||
await setup_deconz_integration(hass)
|
||||
mock_flow_init.assert_called_once()
|
||||
|
||||
assert hass.data[DECONZ_DOMAIN] == {}
|
||||
|
||||
|
||||
async def test_reset_after_successful_setup(hass, aioclient_mock):
|
||||
"""Make sure that connection status triggers a dispatcher send."""
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
@ -305,25 +275,24 @@ async def test_reset_after_successful_setup(hass, aioclient_mock):
|
||||
assert result is True
|
||||
|
||||
|
||||
async def test_get_gateway(hass):
|
||||
async def test_get_deconz_session(hass):
|
||||
"""Successful call."""
|
||||
with patch("pydeconz.DeconzSession.refresh_state", return_value=True):
|
||||
assert await get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
|
||||
assert await get_deconz_session(hass, ENTRY_CONFIG)
|
||||
|
||||
|
||||
async def test_get_gateway_fails_unauthorized(hass):
|
||||
@pytest.mark.parametrize(
|
||||
"side_effect, raised_exception",
|
||||
[
|
||||
(asyncio.TimeoutError, CannotConnect),
|
||||
(pydeconz.RequestError, CannotConnect),
|
||||
(pydeconz.Unauthorized, AuthenticationRequired),
|
||||
],
|
||||
)
|
||||
async def test_get_deconz_session_fails(hass, side_effect, raised_exception):
|
||||
"""Failed call."""
|
||||
with patch(
|
||||
"pydeconz.DeconzSession.refresh_state",
|
||||
side_effect=pydeconz.errors.Unauthorized,
|
||||
), pytest.raises(AuthenticationRequired):
|
||||
assert await get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False
|
||||
|
||||
|
||||
async def test_get_gateway_fails_cannot_connect(hass):
|
||||
"""Failed call."""
|
||||
with patch(
|
||||
"pydeconz.DeconzSession.refresh_state",
|
||||
side_effect=pydeconz.errors.RequestError,
|
||||
), pytest.raises(CannotConnect):
|
||||
assert await get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False
|
||||
side_effect=side_effect,
|
||||
), pytest.raises(raised_exception):
|
||||
assert await get_deconz_session(hass, ENTRY_CONFIG)
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""Test deCONZ component setup process."""
|
||||
|
||||
import asyncio
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.deconz import (
|
||||
@ -13,6 +12,7 @@ from homeassistant.components.deconz.const import (
|
||||
CONF_GROUP_ID_BASE,
|
||||
DOMAIN as DECONZ_DOMAIN,
|
||||
)
|
||||
from homeassistant.components.deconz.errors import AuthenticationRequired, CannotConnect
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
@ -42,22 +42,6 @@ async def setup_entry(hass, entry):
|
||||
assert await async_setup_entry(hass, entry) is True
|
||||
|
||||
|
||||
async def test_setup_entry_fails(hass):
|
||||
"""Test setup entry fails if deCONZ is not available."""
|
||||
with patch("pydeconz.DeconzSession.refresh_state", side_effect=Exception):
|
||||
await setup_deconz_integration(hass)
|
||||
assert not hass.data[DECONZ_DOMAIN]
|
||||
|
||||
|
||||
async def test_setup_entry_no_available_bridge(hass):
|
||||
"""Test setup entry fails if deCONZ is not available."""
|
||||
with patch(
|
||||
"pydeconz.DeconzSession.refresh_state", side_effect=asyncio.TimeoutError
|
||||
):
|
||||
await setup_deconz_integration(hass)
|
||||
assert not hass.data[DECONZ_DOMAIN]
|
||||
|
||||
|
||||
async def test_setup_entry_successful(hass, aioclient_mock):
|
||||
"""Test setup entry is successful."""
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
@ -67,6 +51,29 @@ async def test_setup_entry_successful(hass, aioclient_mock):
|
||||
assert hass.data[DECONZ_DOMAIN][config_entry.entry_id].master
|
||||
|
||||
|
||||
async def test_setup_entry_fails_config_entry_not_ready(hass):
|
||||
"""Failed authentication trigger a reauthentication flow."""
|
||||
with patch(
|
||||
"homeassistant.components.deconz.get_deconz_session",
|
||||
side_effect=CannotConnect,
|
||||
):
|
||||
await setup_deconz_integration(hass)
|
||||
|
||||
assert hass.data[DECONZ_DOMAIN] == {}
|
||||
|
||||
|
||||
async def test_setup_entry_fails_trigger_reauth_flow(hass):
|
||||
"""Failed authentication trigger a reauthentication flow."""
|
||||
with patch(
|
||||
"homeassistant.components.deconz.get_deconz_session",
|
||||
side_effect=AuthenticationRequired,
|
||||
), patch.object(hass.config_entries.flow, "async_init") as mock_flow_init:
|
||||
await setup_deconz_integration(hass)
|
||||
mock_flow_init.assert_called_once()
|
||||
|
||||
assert hass.data[DECONZ_DOMAIN] == {}
|
||||
|
||||
|
||||
async def test_setup_entry_multiple_gateways(hass, aioclient_mock):
|
||||
"""Test setup entry is successful with multiple gateways."""
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
|
Loading…
x
Reference in New Issue
Block a user