Use fixtures to setup UniFi config entries (#118126)

This commit is contained in:
Robert Svensson 2024-05-26 16:30:22 +02:00 committed by GitHub
parent caa65708fb
commit a7938091bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 427 additions and 261 deletions

View file

@ -1,9 +1,11 @@
"""Test UniFi Network integration setup process."""
from collections.abc import Callable
from typing import Any
from unittest.mock import patch
from aiounifi.models.message import MessageKey
import pytest
from homeassistant.components import unifi
from homeassistant.components.unifi.const import (
@ -14,11 +16,12 @@ from homeassistant.components.unifi.const import (
DOMAIN as UNIFI_DOMAIN,
)
from homeassistant.components.unifi.errors import AuthenticationRequired, CannotConnect
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.setup import async_setup_component
from .test_hub import DEFAULT_CONFIG_ENTRY_ID, setup_unifi_integration
from .test_hub import DEFAULT_CONFIG_ENTRY_ID
from tests.common import flush_store
from tests.test_util.aiohttp import AiohttpClientMocker
@ -31,18 +34,22 @@ async def test_setup_with_no_config(hass: HomeAssistant) -> None:
assert UNIFI_DOMAIN not in hass.data
async def test_setup_entry_fails_config_entry_not_ready(hass: HomeAssistant) -> None:
async def test_setup_entry_fails_config_entry_not_ready(
hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry]
) -> None:
"""Failed authentication trigger a reauthentication flow."""
with patch(
"homeassistant.components.unifi.get_unifi_api",
side_effect=CannotConnect,
):
await setup_unifi_integration(hass)
config_entry = await prepare_config_entry()
assert hass.data[UNIFI_DOMAIN] == {}
assert config_entry.state == ConfigEntryState.SETUP_RETRY
async def test_setup_entry_fails_trigger_reauth_flow(hass: HomeAssistant) -> None:
async def test_setup_entry_fails_trigger_reauth_flow(
hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry]
) -> None:
"""Failed authentication trigger a reauthentication flow."""
with (
patch(
@ -51,16 +58,35 @@ async def test_setup_entry_fails_trigger_reauth_flow(hass: HomeAssistant) -> Non
),
patch.object(hass.config_entries.flow, "async_init") as mock_flow_init,
):
await setup_unifi_integration(hass)
config_entry = await prepare_config_entry()
mock_flow_init.assert_called_once()
assert hass.data[UNIFI_DOMAIN] == {}
assert config_entry.state == ConfigEntryState.SETUP_ERROR
@pytest.mark.parametrize(
"client_payload",
[
[
{
"hostname": "client_1",
"ip": "10.0.0.1",
"is_wired": False,
"mac": "00:00:00:00:00:01",
},
{
"hostname": "client_2",
"ip": "10.0.0.2",
"is_wired": False,
"mac": "00:00:00:00:00:02",
},
]
],
)
async def test_wireless_clients(
hass: HomeAssistant,
hass_storage: dict[str, Any],
aioclient_mock: AiohttpClientMocker,
prepare_config_entry: Callable[[], ConfigEntry],
) -> None:
"""Verify wireless clients class."""
hass_storage[unifi.STORAGE_KEY] = {
@ -72,21 +98,7 @@ async def test_wireless_clients(
},
}
client_1 = {
"hostname": "client_1",
"ip": "10.0.0.1",
"is_wired": False,
"mac": "00:00:00:00:00:01",
}
client_2 = {
"hostname": "client_2",
"ip": "10.0.0.2",
"is_wired": False,
"mac": "00:00:00:00:00:02",
}
await setup_unifi_integration(
hass, aioclient_mock, clients_response=[client_1, client_2]
)
await prepare_config_entry()
await flush_store(hass.data[unifi.UNIFI_WIRELESS_CLIENTS]._store)
assert sorted(hass_storage[unifi.STORAGE_KEY]["data"]["wireless_clients"]) == [
@ -96,98 +108,113 @@ async def test_wireless_clients(
]
@pytest.mark.parametrize(
"client_payload",
[
[
{
"hostname": "Wired client",
"is_wired": True,
"mac": "00:00:00:00:00:01",
"oui": "Producer",
"wired-rx_bytes": 1234000000,
"wired-tx_bytes": 5678000000,
"uptime": 1600094505,
},
{
"is_wired": False,
"mac": "00:00:00:00:00:02",
"name": "Wireless client",
"oui": "Producer",
"rx_bytes": 2345000000,
"tx_bytes": 6789000000,
"uptime": 60,
},
]
],
)
@pytest.mark.parametrize(
"device_payload",
[
[
{
"board_rev": 3,
"device_id": "mock-id",
"has_fan": True,
"fan_level": 0,
"ip": "10.0.1.1",
"last_seen": 1562600145,
"mac": "00:00:00:00:01:01",
"model": "US16P150",
"name": "Device 1",
"next_interval": 20,
"overheating": True,
"state": 1,
"type": "usw",
"upgradable": True,
"version": "4.0.42.10433",
}
]
],
)
@pytest.mark.parametrize(
"config_entry_options",
[
{
CONF_ALLOW_BANDWIDTH_SENSORS: True,
CONF_ALLOW_UPTIME_SENSORS: True,
CONF_TRACK_CLIENTS: True,
CONF_TRACK_DEVICES: True,
}
],
)
async def test_remove_config_entry_device(
hass: HomeAssistant,
hass_storage: dict[str, Any],
aioclient_mock: AiohttpClientMocker,
device_registry: dr.DeviceRegistry,
prepare_config_entry: Callable[[], ConfigEntry],
client_payload: list[dict[str, Any]],
device_payload: list[dict[str, Any]],
mock_unifi_websocket,
hass_ws_client: WebSocketGenerator,
) -> None:
"""Verify removing a device manually."""
client_1 = {
"hostname": "Wired client",
"is_wired": True,
"mac": "00:00:00:00:00:01",
"oui": "Producer",
"wired-rx_bytes": 1234000000,
"wired-tx_bytes": 5678000000,
"uptime": 1600094505,
}
client_2 = {
"is_wired": False,
"mac": "00:00:00:00:00:02",
"name": "Wireless client",
"oui": "Producer",
"rx_bytes": 2345000000,
"tx_bytes": 6789000000,
"uptime": 60,
}
device_1 = {
"board_rev": 3,
"device_id": "mock-id",
"has_fan": True,
"fan_level": 0,
"ip": "10.0.1.1",
"last_seen": 1562600145,
"mac": "00:00:00:00:01:01",
"model": "US16P150",
"name": "Device 1",
"next_interval": 20,
"overheating": True,
"state": 1,
"type": "usw",
"upgradable": True,
"version": "4.0.42.10433",
}
options = {
CONF_ALLOW_BANDWIDTH_SENSORS: True,
CONF_ALLOW_UPTIME_SENSORS: True,
CONF_TRACK_CLIENTS: True,
CONF_TRACK_DEVICES: True,
}
config_entry = await setup_unifi_integration(
hass,
aioclient_mock,
options=options,
clients_response=[client_1, client_2],
devices_response=[device_1],
)
config_entry = await prepare_config_entry()
assert await async_setup_component(hass, "config", {})
ws_client = await hass_ws_client(hass)
# Try to remove an active client from UI: not allowed
device_entry = device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, client_1["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, client_payload[0]["mac"])}
)
response = await ws_client.remove_device(device_entry.id, config_entry.entry_id)
assert not response["success"]
assert device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, client_1["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, client_payload[0]["mac"])}
)
# Try to remove an active device from UI: not allowed
device_entry = device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, device_1["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, device_payload[0]["mac"])}
)
response = await ws_client.remove_device(device_entry.id, config_entry.entry_id)
assert not response["success"]
assert device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, device_1["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, device_payload[0]["mac"])}
)
# Remove a client from Unifi API
mock_unifi_websocket(message=MessageKey.CLIENT_REMOVED, data=[client_2])
mock_unifi_websocket(message=MessageKey.CLIENT_REMOVED, data=[client_payload[1]])
await hass.async_block_till_done()
# Try to remove an inactive client from UI: allowed
device_entry = device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, client_2["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, client_payload[1]["mac"])}
)
response = await ws_client.remove_device(device_entry.id, config_entry.entry_id)
assert response["success"]
assert not device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, client_2["mac"])}
connections={(dr.CONNECTION_NETWORK_MAC, client_payload[1]["mac"])}
)