2021-11-26 21:44:49 +00:00
|
|
|
"""UniFi Network switch platform tests."""
|
2019-10-05 14:16:08 +00:00
|
|
|
from copy import deepcopy
|
2021-03-05 21:09:05 +00:00
|
|
|
from unittest.mock import patch
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2020-05-04 17:29:49 +00:00
|
|
|
from aiounifi.controller import MESSAGE_CLIENT_REMOVED, MESSAGE_EVENT
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-03-05 21:09:05 +00:00
|
|
|
from homeassistant import config_entries, core
|
2020-04-23 14:48:24 +00:00
|
|
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
2020-03-05 05:55:56 +00:00
|
|
|
from homeassistant.components.unifi.const import (
|
|
|
|
CONF_BLOCK_CLIENT,
|
2020-11-03 07:36:37 +00:00
|
|
|
CONF_DPI_RESTRICTIONS,
|
|
|
|
CONF_POE_CLIENTS,
|
2020-03-05 05:55:56 +00:00
|
|
|
CONF_TRACK_CLIENTS,
|
|
|
|
CONF_TRACK_DEVICES,
|
2020-04-23 14:48:24 +00:00
|
|
|
DOMAIN as UNIFI_DOMAIN,
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
2020-04-23 14:48:24 +00:00
|
|
|
from homeassistant.components.unifi.switch import POE_SWITCH
|
2021-12-17 10:12:43 +00:00
|
|
|
from homeassistant.const import STATE_OFF, STATE_ON
|
2021-03-09 13:25:03 +00:00
|
|
|
from homeassistant.helpers import entity_registry as er
|
2021-03-05 20:28:41 +00:00
|
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
2021-12-17 10:12:43 +00:00
|
|
|
from homeassistant.helpers.entity import EntityCategory
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2019-10-07 19:55:35 +00:00
|
|
|
from .test_controller import (
|
|
|
|
CONTROLLER_HOST,
|
2021-11-18 23:56:22 +00:00
|
|
|
DEFAULT_CONFIG_ENTRY_ID,
|
2020-05-12 22:37:16 +00:00
|
|
|
DESCRIPTION,
|
2019-10-07 19:55:35 +00:00
|
|
|
ENTRY_CONFIG,
|
|
|
|
setup_unifi_integration,
|
|
|
|
)
|
|
|
|
|
2018-10-16 08:35:35 +00:00
|
|
|
CLIENT_1 = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_1",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
"name": "POE Client 1",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 1,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
2018-10-16 08:35:35 +00:00
|
|
|
}
|
|
|
|
CLIENT_2 = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_2",
|
|
|
|
"ip": "10.0.0.2",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "POE Client 2",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 2,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
2018-10-16 08:35:35 +00:00
|
|
|
}
|
|
|
|
CLIENT_3 = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_3",
|
|
|
|
"ip": "10.0.0.3",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:03",
|
|
|
|
"name": "Non-POE Client 3",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 3,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
2018-10-16 08:35:35 +00:00
|
|
|
}
|
|
|
|
CLIENT_4 = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_4",
|
|
|
|
"ip": "10.0.0.4",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:04",
|
|
|
|
"name": "Non-POE Client 4",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 4,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
2018-10-16 08:35:35 +00:00
|
|
|
}
|
|
|
|
POE_SWITCH_CLIENTS = [
|
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_1",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
"name": "POE Client 1",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 1,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
2018-10-16 08:35:35 +00:00
|
|
|
},
|
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"hostname": "client_2",
|
|
|
|
"ip": "10.0.0.2",
|
|
|
|
"is_wired": True,
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "POE Client 2",
|
|
|
|
"oui": "Producer",
|
|
|
|
"sw_mac": "00:00:00:00:01:01",
|
|
|
|
"sw_port": 1,
|
|
|
|
"wired-rx_bytes": 1234000000,
|
|
|
|
"wired-tx_bytes": 5678000000,
|
|
|
|
},
|
2018-10-16 08:35:35 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
DEVICE_1 = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"device_id": "mock-id",
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"mac": "00:00:00:00:01:01",
|
2019-10-05 14:16:08 +00:00
|
|
|
"last_seen": 1562600145,
|
|
|
|
"model": "US16P150",
|
2019-07-31 19:25:30 +00:00
|
|
|
"name": "mock-name",
|
|
|
|
"port_overrides": [],
|
|
|
|
"port_table": [
|
2018-10-16 08:35:35 +00:00
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 1",
|
|
|
|
"port_idx": 1,
|
|
|
|
"poe_class": "Class 4",
|
|
|
|
"poe_enable": True,
|
|
|
|
"poe_mode": "auto",
|
|
|
|
"poe_power": "2.56",
|
|
|
|
"poe_voltage": "53.40",
|
|
|
|
"portconf_id": "1a1",
|
|
|
|
"port_poe": True,
|
|
|
|
"up": True,
|
2018-10-16 08:35:35 +00:00
|
|
|
},
|
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 2",
|
|
|
|
"port_idx": 2,
|
|
|
|
"poe_class": "Class 4",
|
|
|
|
"poe_enable": True,
|
|
|
|
"poe_mode": "auto",
|
|
|
|
"poe_power": "2.56",
|
|
|
|
"poe_voltage": "53.40",
|
|
|
|
"portconf_id": "1a2",
|
|
|
|
"port_poe": True,
|
|
|
|
"up": True,
|
2018-10-16 08:35:35 +00:00
|
|
|
},
|
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 3",
|
|
|
|
"port_idx": 3,
|
|
|
|
"poe_class": "Unknown",
|
|
|
|
"poe_enable": False,
|
|
|
|
"poe_mode": "off",
|
|
|
|
"poe_power": "0.00",
|
|
|
|
"poe_voltage": "0.00",
|
|
|
|
"portconf_id": "1a3",
|
|
|
|
"port_poe": False,
|
|
|
|
"up": True,
|
2018-10-16 08:35:35 +00:00
|
|
|
},
|
|
|
|
{
|
2019-07-31 19:25:30 +00:00
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 4",
|
|
|
|
"port_idx": 4,
|
|
|
|
"poe_class": "Unknown",
|
|
|
|
"poe_enable": False,
|
|
|
|
"poe_mode": "auto",
|
|
|
|
"poe_power": "0.00",
|
|
|
|
"poe_voltage": "0.00",
|
|
|
|
"portconf_id": "1a4",
|
|
|
|
"port_poe": True,
|
|
|
|
"up": True,
|
|
|
|
},
|
|
|
|
],
|
2019-10-05 14:16:08 +00:00
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"version": "4.0.42.10433",
|
2018-10-16 08:35:35 +00:00
|
|
|
}
|
|
|
|
|
2019-07-25 14:56:56 +00:00
|
|
|
BLOCKED = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"blocked": True,
|
|
|
|
"hostname": "block_client_1",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_guest": False,
|
|
|
|
"is_wired": False,
|
2020-04-16 22:08:53 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"name": "Block Client 1",
|
|
|
|
"noted": True,
|
|
|
|
"oui": "Producer",
|
2019-07-25 14:56:56 +00:00
|
|
|
}
|
|
|
|
UNBLOCKED = {
|
2019-07-31 19:25:30 +00:00
|
|
|
"blocked": False,
|
|
|
|
"hostname": "block_client_2",
|
|
|
|
"ip": "10.0.0.2",
|
|
|
|
"is_guest": False,
|
|
|
|
"is_wired": True,
|
2020-04-16 22:08:53 +00:00
|
|
|
"last_seen": 1562600145,
|
2019-07-31 19:25:30 +00:00
|
|
|
"mac": "00:00:00:00:01:02",
|
|
|
|
"name": "Block Client 2",
|
|
|
|
"noted": True,
|
|
|
|
"oui": "Producer",
|
2019-07-25 14:56:56 +00:00
|
|
|
}
|
|
|
|
|
2020-05-04 17:29:49 +00:00
|
|
|
EVENT_BLOCKED_CLIENT_CONNECTED = {
|
|
|
|
"user": BLOCKED["mac"],
|
|
|
|
"radio": "na",
|
|
|
|
"channel": "44",
|
|
|
|
"hostname": BLOCKED["hostname"],
|
|
|
|
"key": "EVT_WU_Connected",
|
|
|
|
"subsystem": "wlan",
|
|
|
|
"site_id": "name",
|
|
|
|
"time": 1587753456179,
|
|
|
|
"datetime": "2020-04-24T18:37:36Z",
|
|
|
|
"msg": f'User{[BLOCKED["mac"]]} has connected."',
|
|
|
|
"_id": "5ea331fa30c49e00f90ddc1a",
|
|
|
|
}
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
EVENT_BLOCKED_CLIENT_BLOCKED = {
|
|
|
|
"user": BLOCKED["mac"],
|
|
|
|
"hostname": BLOCKED["hostname"],
|
|
|
|
"key": "EVT_WC_Blocked",
|
|
|
|
"subsystem": "wlan",
|
|
|
|
"site_id": "name",
|
|
|
|
"time": 1587753456179,
|
|
|
|
"datetime": "2020-04-24T18:37:36Z",
|
|
|
|
"msg": f'User{[BLOCKED["mac"]]} has been blocked."',
|
|
|
|
"_id": "5ea331fa30c49e00f90ddc1a",
|
|
|
|
}
|
|
|
|
|
|
|
|
EVENT_BLOCKED_CLIENT_UNBLOCKED = {
|
|
|
|
"user": BLOCKED["mac"],
|
|
|
|
"hostname": BLOCKED["hostname"],
|
|
|
|
"key": "EVT_WC_Unblocked",
|
|
|
|
"subsystem": "wlan",
|
|
|
|
"site_id": "name",
|
|
|
|
"time": 1587753456179,
|
|
|
|
"datetime": "2020-04-24T18:37:36Z",
|
|
|
|
"msg": f'User{[BLOCKED["mac"]]} has been unblocked."',
|
|
|
|
"_id": "5ea331fa30c49e00f90ddc1a",
|
|
|
|
}
|
|
|
|
|
2020-05-04 17:29:49 +00:00
|
|
|
|
|
|
|
EVENT_CLIENT_2_CONNECTED = {
|
|
|
|
"user": CLIENT_2["mac"],
|
|
|
|
"radio": "na",
|
|
|
|
"channel": "44",
|
|
|
|
"hostname": CLIENT_2["hostname"],
|
|
|
|
"key": "EVT_WU_Connected",
|
|
|
|
"subsystem": "wlan",
|
|
|
|
"site_id": "name",
|
|
|
|
"time": 1587753456179,
|
|
|
|
"datetime": "2020-04-24T18:37:36Z",
|
|
|
|
"msg": f'User{[CLIENT_2["mac"]]} has connected."',
|
|
|
|
"_id": "5ea331fa30c49e00f90ddc1a",
|
|
|
|
}
|
|
|
|
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2020-11-03 07:36:37 +00:00
|
|
|
DPI_GROUPS = [
|
|
|
|
{
|
|
|
|
"_id": "5ba29dd8e3c58f026e9d7c4a",
|
|
|
|
"attr_no_delete": True,
|
|
|
|
"attr_hidden_id": "Default",
|
|
|
|
"name": "Default",
|
|
|
|
"site_id": "name",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
|
|
|
"name": "Block Media Streaming",
|
|
|
|
"site_id": "name",
|
|
|
|
"dpiapp_ids": ["5f976f62e3c58f018ec7e17d"],
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
DPI_APPS = [
|
|
|
|
{
|
|
|
|
"_id": "5f976f62e3c58f018ec7e17d",
|
|
|
|
"apps": [],
|
|
|
|
"blocked": True,
|
|
|
|
"cats": ["4"],
|
|
|
|
"enabled": True,
|
|
|
|
"log": True,
|
|
|
|
"site_id": "name",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
DPI_GROUP_REMOVED_EVENT = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpigroup:delete"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
2022-01-12 16:11:05 +00:00
|
|
|
"name": "Block Media Streaming",
|
|
|
|
"site_id": "name",
|
|
|
|
"dpiapp_ids": [],
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
DPI_GROUP_CREATED_EVENT = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpigroup:add"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"name": "Block Media Streaming",
|
|
|
|
"site_id": "name",
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
DPI_GROUP_ADDED_APP = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpigroup:sync"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
|
|
|
"name": "Block Media Streaming",
|
|
|
|
"site_id": "name",
|
|
|
|
"dpiapp_ids": ["5f976f62e3c58f018ec7e17d"],
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
DPI_GROUP_REMOVE_APP = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpigroup:sync"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
|
|
|
"name": "Block Media Streaming",
|
2021-10-27 08:35:44 +00:00
|
|
|
"site_id": "name",
|
|
|
|
"dpiapp_ids": [],
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
DPI_APP_DISABLED_EVENT = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpiapp:sync"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"_id": "5f976f62e3c58f018ec7e17d",
|
|
|
|
"apps": [],
|
|
|
|
"blocked": False,
|
|
|
|
"cats": [],
|
|
|
|
"enabled": False,
|
|
|
|
"log": False,
|
|
|
|
"site_id": "name",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2020-11-03 07:36:37 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_no_clients(hass, aioclient_mock):
|
2018-10-16 08:35:35 +00:00
|
|
|
"""Test the update_clients function when no clients are found."""
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-11-03 07:36:37 +00:00
|
|
|
options={
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
|
|
|
CONF_DPI_RESTRICTIONS: False,
|
|
|
|
},
|
2019-10-05 14:16:08 +00:00
|
|
|
)
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 10
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2018-10-16 08:35:35 +00:00
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_controller_not_client(hass, aioclient_mock):
|
2018-11-02 20:09:16 +00:00
|
|
|
"""Test that the controller doesn't become a switch."""
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(
|
2019-10-05 14:16:08 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-03-05 05:55:56 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: False, CONF_TRACK_DEVICES: False},
|
2019-10-07 19:55:35 +00:00
|
|
|
clients_response=[CONTROLLER_HOST],
|
2019-10-05 14:16:08 +00:00
|
|
|
devices_response=[DEVICE_1],
|
|
|
|
)
|
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2019-07-31 19:25:30 +00:00
|
|
|
cloudkey = hass.states.get("switch.cloud_key")
|
2018-11-02 20:09:16 +00:00
|
|
|
assert cloudkey is None
|
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_not_admin(hass, aioclient_mock):
|
2019-07-14 19:57:09 +00:00
|
|
|
"""Test that switch platform only work on an admin account."""
|
2020-05-12 22:37:16 +00:00
|
|
|
description = deepcopy(DESCRIPTION)
|
|
|
|
description[0]["site_role"] = "not admin"
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(
|
2019-10-05 14:16:08 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-03-05 05:55:56 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: False, CONF_TRACK_DEVICES: False},
|
2020-05-12 22:37:16 +00:00
|
|
|
site_description=description,
|
2019-10-05 14:16:08 +00:00
|
|
|
clients_response=[CLIENT_1],
|
|
|
|
devices_response=[DEVICE_1],
|
|
|
|
)
|
2019-07-14 19:57:09 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2019-07-14 19:57:09 +00:00
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_switches(hass, aioclient_mock):
|
2019-07-14 19:57:09 +00:00
|
|
|
"""Test the update_items function with some clients."""
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2019-10-05 14:16:08 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2019-10-05 14:16:08 +00:00
|
|
|
options={
|
2020-03-05 05:55:56 +00:00
|
|
|
CONF_BLOCK_CLIENT: [BLOCKED["mac"], UNBLOCKED["mac"]],
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
2019-10-05 14:16:08 +00:00
|
|
|
},
|
|
|
|
clients_response=[CLIENT_1, CLIENT_4],
|
|
|
|
devices_response=[DEVICE_1],
|
|
|
|
clients_all_response=[BLOCKED, UNBLOCKED, CLIENT_1],
|
2020-11-03 07:36:37 +00:00
|
|
|
dpigroup_response=DPI_GROUPS,
|
|
|
|
dpiapp_response=DPI_APPS,
|
2019-10-05 14:16:08 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2019-07-14 19:57:09 +00:00
|
|
|
|
2020-11-03 07:36:37 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 4
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
switch_1 = hass.states.get("switch.poe_client_1")
|
2018-10-16 08:35:35 +00:00
|
|
|
assert switch_1 is not None
|
2019-07-31 19:25:30 +00:00
|
|
|
assert switch_1.state == "on"
|
|
|
|
assert switch_1.attributes["power"] == "2.56"
|
2020-04-23 14:48:24 +00:00
|
|
|
assert switch_1.attributes[SWITCH_DOMAIN] == "00:00:00:00:01:01"
|
2019-07-31 19:25:30 +00:00
|
|
|
assert switch_1.attributes["port"] == 1
|
|
|
|
assert switch_1.attributes["poe_mode"] == "auto"
|
|
|
|
|
|
|
|
switch_4 = hass.states.get("switch.poe_client_4")
|
2019-07-14 19:57:09 +00:00
|
|
|
assert switch_4 is None
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
2019-07-25 14:56:56 +00:00
|
|
|
assert blocked is not None
|
2019-08-04 14:57:36 +00:00
|
|
|
assert blocked.state == "off"
|
2019-07-25 14:56:56 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
unblocked = hass.states.get("switch.block_client_2")
|
2019-07-25 14:56:56 +00:00
|
|
|
assert unblocked is not None
|
2019-08-04 14:57:36 +00:00
|
|
|
assert unblocked.state == "on"
|
2019-07-25 14:56:56 +00:00
|
|
|
|
2020-11-03 07:36:37 +00:00
|
|
|
dpi_switch = hass.states.get("switch.block_media_streaming")
|
|
|
|
assert dpi_switch is not None
|
|
|
|
assert dpi_switch.state == "on"
|
2021-03-05 20:28:41 +00:00
|
|
|
assert dpi_switch.attributes["icon"] == "mdi:network"
|
2020-11-03 07:36:37 +00:00
|
|
|
|
2021-10-26 18:23:20 +00:00
|
|
|
ent_reg = er.async_get(hass)
|
|
|
|
for entry_id in (
|
|
|
|
"switch.poe_client_1",
|
|
|
|
"switch.block_client_1",
|
|
|
|
"switch.block_media_streaming",
|
|
|
|
):
|
2021-12-17 10:12:43 +00:00
|
|
|
assert ent_reg.async_get(entry_id).entity_category is EntityCategory.CONFIG
|
2021-10-26 18:23:20 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
# Block and unblock client
|
|
|
|
|
|
|
|
aioclient_mock.post(
|
|
|
|
f"https://{controller.host}:1234/api/s/{controller.site}/cmd/stamgr",
|
|
|
|
)
|
|
|
|
|
2020-03-05 05:55:56 +00:00
|
|
|
await hass.services.async_call(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN, "turn_off", {"entity_id": "switch.block_client_1"}, blocking=True
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 11
|
|
|
|
assert aioclient_mock.mock_calls[10][2] == {
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"cmd": "block-sta",
|
2020-03-05 05:55:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
await hass.services.async_call(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN, "turn_on", {"entity_id": "switch.block_client_1"}, blocking=True
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 12
|
|
|
|
assert aioclient_mock.mock_calls[11][2] == {
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"cmd": "unblock-sta",
|
2020-03-05 05:55:56 +00:00
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
# Enable and disable DPI
|
|
|
|
|
|
|
|
aioclient_mock.put(
|
|
|
|
f"https://{controller.host}:1234/api/s/{controller.site}/rest/dpiapp/5f976f62e3c58f018ec7e17d",
|
|
|
|
)
|
|
|
|
|
2020-11-03 07:36:37 +00:00
|
|
|
await hass.services.async_call(
|
|
|
|
SWITCH_DOMAIN,
|
|
|
|
"turn_off",
|
|
|
|
{"entity_id": "switch.block_media_streaming"},
|
|
|
|
blocking=True,
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 13
|
|
|
|
assert aioclient_mock.mock_calls[12][2] == {"enabled": False}
|
2020-11-03 07:36:37 +00:00
|
|
|
|
|
|
|
await hass.services.async_call(
|
|
|
|
SWITCH_DOMAIN,
|
|
|
|
"turn_on",
|
|
|
|
{"entity_id": "switch.block_media_streaming"},
|
|
|
|
blocking=True,
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 14
|
|
|
|
assert aioclient_mock.mock_calls[13][2] == {"enabled": True}
|
2020-11-03 07:36:37 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
# Make sure no duplicates arise on generic signal update
|
|
|
|
async_dispatcher_send(hass, controller.signal_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 4
|
|
|
|
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
async def test_remove_switches(hass, aioclient_mock, mock_unifi_websocket):
|
2020-04-16 22:08:53 +00:00
|
|
|
"""Test the update_items function with some clients."""
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2020-04-16 22:08:53 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-04-16 22:08:53 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: [UNBLOCKED["mac"]]},
|
|
|
|
clients_response=[CLIENT_1, UNBLOCKED],
|
|
|
|
devices_response=[DEVICE_1],
|
2021-10-27 08:35:44 +00:00
|
|
|
dpigroup_response=DPI_GROUPS,
|
|
|
|
dpiapp_response=DPI_APPS,
|
2020-04-16 22:08:53 +00:00
|
|
|
)
|
2021-03-05 20:28:41 +00:00
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 3
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
assert hass.states.get("switch.poe_client_1") is not None
|
|
|
|
assert hass.states.get("switch.block_client_2") is not None
|
|
|
|
assert hass.states.get("switch.block_media_streaming") is not None
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT_REMOVED},
|
|
|
|
"data": [CLIENT_1, UNBLOCKED],
|
|
|
|
}
|
|
|
|
)
|
2020-04-16 22:08:53 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
|
|
|
|
|
|
|
assert hass.states.get("switch.poe_client_1") is None
|
|
|
|
assert hass.states.get("switch.block_client_2") is None
|
|
|
|
assert hass.states.get("switch.block_media_streaming") is not None
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
mock_unifi_websocket(data=DPI_GROUP_REMOVED_EVENT)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.async_block_till_done()
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
assert hass.states.get("switch.block_media_streaming") is None
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2020-04-16 22:08:53 +00:00
|
|
|
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
async def test_block_switches(hass, aioclient_mock, mock_unifi_websocket):
|
2020-05-08 20:19:27 +00:00
|
|
|
"""Test the update_items function with some clients."""
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-05-08 20:19:27 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-05-08 20:19:27 +00:00
|
|
|
options={
|
|
|
|
CONF_BLOCK_CLIENT: [BLOCKED["mac"], UNBLOCKED["mac"]],
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
|
|
|
},
|
|
|
|
clients_response=[UNBLOCKED],
|
|
|
|
clients_all_response=[BLOCKED],
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
|
|
|
|
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
|
|
|
assert blocked is not None
|
|
|
|
assert blocked.state == "off"
|
|
|
|
|
|
|
|
unblocked = hass.states.get("switch.block_client_2")
|
|
|
|
assert unblocked is not None
|
|
|
|
assert unblocked.state == "on"
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_EVENT},
|
|
|
|
"data": [EVENT_BLOCKED_CLIENT_UNBLOCKED],
|
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
|
|
|
assert blocked is not None
|
|
|
|
assert blocked.state == "on"
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_EVENT},
|
|
|
|
"data": [EVENT_BLOCKED_CLIENT_BLOCKED],
|
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
|
|
|
assert blocked is not None
|
|
|
|
assert blocked.state == "off"
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock.post(
|
|
|
|
f"https://{controller.host}:1234/api/s/{controller.site}/cmd/stamgr",
|
|
|
|
)
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.services.async_call(
|
|
|
|
SWITCH_DOMAIN, "turn_off", {"entity_id": "switch.block_client_1"}, blocking=True
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 11
|
|
|
|
assert aioclient_mock.mock_calls[10][2] == {
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"cmd": "block-sta",
|
2020-05-08 20:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
await hass.services.async_call(
|
|
|
|
SWITCH_DOMAIN, "turn_on", {"entity_id": "switch.block_client_1"}, blocking=True
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 12
|
|
|
|
assert aioclient_mock.mock_calls[11][2] == {
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"cmd": "unblock-sta",
|
2020-05-08 20:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
async def test_dpi_switches(hass, aioclient_mock, mock_unifi_websocket):
|
|
|
|
"""Test the update_items function with some clients."""
|
|
|
|
await setup_unifi_integration(
|
|
|
|
hass,
|
|
|
|
aioclient_mock,
|
|
|
|
dpigroup_response=DPI_GROUPS,
|
|
|
|
dpiapp_response=DPI_APPS,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
|
|
|
|
|
|
|
dpi_switch = hass.states.get("switch.block_media_streaming")
|
|
|
|
assert dpi_switch is not None
|
|
|
|
assert dpi_switch.state == STATE_ON
|
|
|
|
assert dpi_switch.attributes["icon"] == "mdi:network"
|
|
|
|
|
|
|
|
mock_unifi_websocket(data=DPI_APP_DISABLED_EVENT)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("switch.block_media_streaming").state == STATE_OFF
|
|
|
|
|
2022-01-12 16:11:05 +00:00
|
|
|
mock_unifi_websocket(data=DPI_GROUP_REMOVE_APP)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("switch.block_media_streaming") is None
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
|
|
|
|
|
|
|
|
|
|
|
async def test_dpi_switches_add_second_app(hass, aioclient_mock, mock_unifi_websocket):
|
|
|
|
"""Test the update_items function with some clients."""
|
|
|
|
await setup_unifi_integration(
|
|
|
|
hass,
|
|
|
|
aioclient_mock,
|
|
|
|
dpigroup_response=DPI_GROUPS,
|
|
|
|
dpiapp_response=DPI_APPS,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
|
|
|
assert hass.states.get("switch.block_media_streaming").state == STATE_ON
|
|
|
|
|
|
|
|
second_app_event = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpiapp:add"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"apps": [524292],
|
|
|
|
"blocked": False,
|
|
|
|
"cats": [],
|
|
|
|
"enabled": False,
|
|
|
|
"log": False,
|
|
|
|
"site_id": "name",
|
|
|
|
"_id": "61783e89c1773a18c0c61f00",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
mock_unifi_websocket(data=second_app_event)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("switch.block_media_streaming").state == STATE_ON
|
|
|
|
|
|
|
|
add_second_app_to_group = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpigroup:sync"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"_id": "5f976f4ae3c58f018ec7dff6",
|
|
|
|
"name": "Block Media Streaming",
|
|
|
|
"site_id": "name",
|
|
|
|
"dpiapp_ids": ["5f976f62e3c58f018ec7e17d", "61783e89c1773a18c0c61f00"],
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
mock_unifi_websocket(data=add_second_app_to_group)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("switch.block_media_streaming").state == STATE_OFF
|
|
|
|
|
|
|
|
second_app_event_enabled = {
|
|
|
|
"meta": {"rc": "ok", "message": "dpiapp:sync"},
|
|
|
|
"data": [
|
|
|
|
{
|
|
|
|
"apps": [524292],
|
|
|
|
"blocked": False,
|
|
|
|
"cats": [],
|
|
|
|
"enabled": True,
|
|
|
|
"log": False,
|
|
|
|
"site_id": "name",
|
|
|
|
"_id": "61783e89c1773a18c0c61f00",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
mock_unifi_websocket(data=second_app_event_enabled)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("switch.block_media_streaming").state == STATE_ON
|
|
|
|
|
2021-10-27 08:35:44 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
async def test_new_client_discovered_on_block_control(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket
|
|
|
|
):
|
2019-10-07 19:55:35 +00:00
|
|
|
"""Test if 2nd update has a new client."""
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2019-10-07 19:55:35 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2019-10-07 19:55:35 +00:00
|
|
|
options={
|
2020-03-05 05:55:56 +00:00
|
|
|
CONF_BLOCK_CLIENT: [BLOCKED["mac"]],
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
2020-11-03 07:36:37 +00:00
|
|
|
CONF_DPI_RESTRICTIONS: False,
|
2019-10-07 19:55:35 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2020-03-05 05:55:56 +00:00
|
|
|
|
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
|
|
|
assert blocked is None
|
2019-10-07 19:55:35 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": "sta:sync"},
|
|
|
|
"data": [BLOCKED],
|
|
|
|
}
|
|
|
|
)
|
2020-05-04 17:29:49 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_EVENT},
|
|
|
|
"data": [EVENT_BLOCKED_CLIENT_CONNECTED],
|
|
|
|
}
|
|
|
|
)
|
2020-03-05 05:55:56 +00:00
|
|
|
await hass.async_block_till_done()
|
2019-10-07 19:55:35 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2020-03-05 05:55:56 +00:00
|
|
|
blocked = hass.states.get("switch.block_client_1")
|
|
|
|
assert blocked is not None
|
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_option_block_clients(hass, aioclient_mock):
|
2020-03-05 05:55:56 +00:00
|
|
|
"""Test the changes to option reflects accordingly."""
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-03-05 05:55:56 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-03-05 05:55:56 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]},
|
|
|
|
clients_all_response=[BLOCKED, UNBLOCKED],
|
2019-10-07 19:55:35 +00:00
|
|
|
)
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2019-10-07 19:55:35 +00:00
|
|
|
|
2020-03-05 05:55:56 +00:00
|
|
|
# Add a second switch
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-03-05 05:55:56 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: [BLOCKED["mac"], UNBLOCKED["mac"]]},
|
2019-10-07 19:55:35 +00:00
|
|
|
)
|
2020-03-05 05:55:56 +00:00
|
|
|
await hass.async_block_till_done()
|
2020-04-23 19:29:38 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2020-03-05 05:55:56 +00:00
|
|
|
|
|
|
|
# Remove the second switch again
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]},
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2020-03-05 05:55:56 +00:00
|
|
|
|
|
|
|
# Enable one and remove another one
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: [UNBLOCKED["mac"]]},
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
2020-04-23 19:29:38 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2020-03-05 05:55:56 +00:00
|
|
|
|
|
|
|
# Remove one
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: []},
|
2020-03-05 05:55:56 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
2019-10-07 19:55:35 +00:00
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_option_remove_switches(hass, aioclient_mock):
|
2020-11-03 07:36:37 +00:00
|
|
|
"""Test removal of DPI switch when options updated."""
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-11-03 07:36:37 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-11-03 07:36:37 +00:00
|
|
|
options={
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
|
|
|
},
|
|
|
|
clients_response=[CLIENT_1],
|
|
|
|
devices_response=[DEVICE_1],
|
|
|
|
dpigroup_response=DPI_GROUPS,
|
|
|
|
dpiapp_response=DPI_APPS,
|
|
|
|
)
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
|
|
|
|
|
|
|
# Disable DPI Switches
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-11-03 07:36:37 +00:00
|
|
|
options={CONF_DPI_RESTRICTIONS: False, CONF_POE_CLIENTS: False},
|
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 0
|
|
|
|
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
async def test_new_client_discovered_on_poe_control(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket
|
|
|
|
):
|
2018-10-16 08:35:35 +00:00
|
|
|
"""Test if 2nd update has a new client."""
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2019-10-05 14:16:08 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-03-05 05:55:56 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: False, CONF_TRACK_DEVICES: False},
|
2019-10-05 14:16:08 +00:00
|
|
|
clients_response=[CLIENT_1],
|
|
|
|
devices_response=[DEVICE_1],
|
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": "sta:sync"},
|
|
|
|
"data": [CLIENT_2],
|
|
|
|
}
|
|
|
|
)
|
2020-05-04 17:29:49 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_EVENT},
|
|
|
|
"data": [EVENT_CLIENT_2_CONNECTED],
|
|
|
|
}
|
|
|
|
)
|
2020-05-04 17:29:49 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
|
|
|
switch_2 = hass.states.get("switch.poe_client_2")
|
|
|
|
assert switch_2 is not None
|
2018-10-16 08:35:35 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock.put(
|
|
|
|
f"https://{controller.host}:1234/api/s/{controller.site}/rest/device/mock-id",
|
|
|
|
)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
await hass.services.async_call(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN, "turn_off", {"entity_id": "switch.poe_client_1"}, blocking=True
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 2
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 11
|
|
|
|
assert aioclient_mock.mock_calls[10][2] == {
|
|
|
|
"port_overrides": [{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "off"}]
|
2019-07-14 19:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
await hass.services.async_call(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN, "turn_on", {"entity_id": "switch.poe_client_1"}, blocking=True
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
assert aioclient_mock.call_count == 12
|
|
|
|
assert aioclient_mock.mock_calls[11][2] == {
|
|
|
|
"port_overrides": [{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "auto"}]
|
2019-07-14 19:57:09 +00:00
|
|
|
}
|
2018-10-16 08:35:35 +00:00
|
|
|
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
async def test_ignore_multiple_poe_clients_on_same_port(hass, aioclient_mock):
|
2018-10-16 08:35:35 +00:00
|
|
|
"""Ignore when there are multiple POE driven clients on same port.
|
|
|
|
|
|
|
|
If there is a non-UniFi switch powered by POE,
|
|
|
|
clients will be transparently marked as having POE as well.
|
|
|
|
"""
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-08-27 11:56:20 +00:00
|
|
|
clients_response=POE_SWITCH_CLIENTS,
|
|
|
|
devices_response=[DEVICE_1],
|
2019-10-05 14:16:08 +00:00
|
|
|
)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
switch_1 = hass.states.get("switch.poe_client_1")
|
|
|
|
switch_2 = hass.states.get("switch.poe_client_2")
|
2018-10-16 08:35:35 +00:00
|
|
|
assert switch_1 is None
|
|
|
|
assert switch_2 is None
|
2019-07-29 17:48:38 +00:00
|
|
|
|
|
|
|
|
2021-03-05 21:09:05 +00:00
|
|
|
async def test_restore_client_succeed(hass, aioclient_mock):
|
|
|
|
"""Test that RestoreEntity works as expected."""
|
|
|
|
POE_DEVICE = {
|
|
|
|
"device_id": "12345",
|
|
|
|
"ip": "1.0.1.1",
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "POE Switch",
|
|
|
|
"port_overrides": [
|
|
|
|
{
|
|
|
|
"poe_mode": "off",
|
|
|
|
"port_idx": 1,
|
|
|
|
"portconf_id": "5f3edd2aba4cc806a19f2db2",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"port_table": [
|
|
|
|
{
|
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 1",
|
|
|
|
"op_mode": "switch",
|
|
|
|
"poe_caps": 7,
|
|
|
|
"poe_class": "Unknown",
|
|
|
|
"poe_current": "0.00",
|
|
|
|
"poe_enable": False,
|
|
|
|
"poe_good": False,
|
|
|
|
"poe_mode": "off",
|
|
|
|
"poe_power": "0.00",
|
|
|
|
"poe_voltage": "0.00",
|
|
|
|
"port_idx": 1,
|
|
|
|
"port_poe": True,
|
|
|
|
"portconf_id": "5f3edd2aba4cc806a19f2db2",
|
|
|
|
"up": False,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
POE_CLIENT = {
|
|
|
|
"hostname": "poe_client",
|
|
|
|
"ip": "1.0.0.1",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
"name": "POE Client",
|
|
|
|
"oui": "Producer",
|
|
|
|
}
|
|
|
|
|
|
|
|
fake_state = core.State(
|
|
|
|
"switch.poe_client",
|
|
|
|
"off",
|
|
|
|
{
|
|
|
|
"power": "0.00",
|
|
|
|
"switch": POE_DEVICE["mac"],
|
|
|
|
"port": 1,
|
|
|
|
"poe_mode": "auto",
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2019-08-18 04:34:11 +00:00
|
|
|
config_entry = config_entries.ConfigEntry(
|
2019-10-05 14:16:08 +00:00
|
|
|
version=1,
|
2020-04-23 14:48:24 +00:00
|
|
|
domain=UNIFI_DOMAIN,
|
2019-10-05 14:16:08 +00:00
|
|
|
title="Mock Title",
|
|
|
|
data=ENTRY_CONFIG,
|
|
|
|
source="test",
|
|
|
|
options={},
|
2021-11-18 23:56:22 +00:00
|
|
|
entry_id=DEFAULT_CONFIG_ENTRY_ID,
|
2019-08-18 04:34:11 +00:00
|
|
|
)
|
|
|
|
|
2021-03-09 13:25:03 +00:00
|
|
|
registry = er.async_get(hass)
|
2019-07-29 17:48:38 +00:00
|
|
|
registry.async_get_or_create(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN,
|
|
|
|
UNIFI_DOMAIN,
|
2021-03-05 21:09:05 +00:00
|
|
|
f'{POE_SWITCH}-{POE_CLIENT["mac"]}',
|
|
|
|
suggested_object_id=POE_CLIENT["hostname"],
|
2019-08-18 04:34:11 +00:00
|
|
|
config_entry=config_entry,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2021-03-05 21:09:05 +00:00
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.helpers.restore_state.RestoreEntity.async_get_last_state",
|
|
|
|
return_value=fake_state,
|
|
|
|
):
|
|
|
|
await setup_unifi_integration(
|
|
|
|
hass,
|
|
|
|
aioclient_mock,
|
|
|
|
options={
|
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
|
|
|
},
|
|
|
|
clients_response=[],
|
|
|
|
devices_response=[POE_DEVICE],
|
|
|
|
clients_all_response=[POE_CLIENT],
|
|
|
|
)
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
|
|
|
|
|
|
|
poe_client = hass.states.get("switch.poe_client")
|
|
|
|
assert poe_client.state == "off"
|
|
|
|
|
|
|
|
|
|
|
|
async def test_restore_client_no_old_state(hass, aioclient_mock):
|
|
|
|
"""Test that RestoreEntity without old state makes entity unavailable."""
|
|
|
|
POE_DEVICE = {
|
|
|
|
"device_id": "12345",
|
|
|
|
"ip": "1.0.1.1",
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "POE Switch",
|
|
|
|
"port_overrides": [
|
|
|
|
{
|
|
|
|
"poe_mode": "off",
|
|
|
|
"port_idx": 1,
|
|
|
|
"portconf_id": "5f3edd2aba4cc806a19f2db2",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"port_table": [
|
|
|
|
{
|
|
|
|
"media": "GE",
|
|
|
|
"name": "Port 1",
|
|
|
|
"op_mode": "switch",
|
|
|
|
"poe_caps": 7,
|
|
|
|
"poe_class": "Unknown",
|
|
|
|
"poe_current": "0.00",
|
|
|
|
"poe_enable": False,
|
|
|
|
"poe_good": False,
|
|
|
|
"poe_mode": "off",
|
|
|
|
"poe_power": "0.00",
|
|
|
|
"poe_voltage": "0.00",
|
|
|
|
"port_idx": 1,
|
|
|
|
"port_poe": True,
|
|
|
|
"portconf_id": "5f3edd2aba4cc806a19f2db2",
|
|
|
|
"up": False,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
POE_CLIENT = {
|
|
|
|
"hostname": "poe_client",
|
|
|
|
"ip": "1.0.0.1",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
"name": "POE Client",
|
|
|
|
"oui": "Producer",
|
|
|
|
}
|
|
|
|
|
|
|
|
config_entry = config_entries.ConfigEntry(
|
|
|
|
version=1,
|
|
|
|
domain=UNIFI_DOMAIN,
|
|
|
|
title="Mock Title",
|
|
|
|
data=ENTRY_CONFIG,
|
|
|
|
source="test",
|
|
|
|
options={},
|
2021-11-18 23:56:22 +00:00
|
|
|
entry_id=DEFAULT_CONFIG_ENTRY_ID,
|
2021-03-05 21:09:05 +00:00
|
|
|
)
|
|
|
|
|
2021-03-09 13:25:03 +00:00
|
|
|
registry = er.async_get(hass)
|
2019-07-29 17:48:38 +00:00
|
|
|
registry.async_get_or_create(
|
2020-04-23 14:48:24 +00:00
|
|
|
SWITCH_DOMAIN,
|
|
|
|
UNIFI_DOMAIN,
|
2021-03-05 21:09:05 +00:00
|
|
|
f'{POE_SWITCH}-{POE_CLIENT["mac"]}',
|
|
|
|
suggested_object_id=POE_CLIENT["hostname"],
|
2019-08-18 04:34:11 +00:00
|
|
|
config_entry=config_entry,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2019-07-29 17:48:38 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(
|
2019-10-05 14:16:08 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2019-10-05 14:16:08 +00:00
|
|
|
options={
|
2020-03-05 05:55:56 +00:00
|
|
|
CONF_TRACK_CLIENTS: False,
|
|
|
|
CONF_TRACK_DEVICES: False,
|
2019-10-05 14:16:08 +00:00
|
|
|
},
|
2021-03-05 21:09:05 +00:00
|
|
|
clients_response=[],
|
|
|
|
devices_response=[POE_DEVICE],
|
|
|
|
clients_all_response=[POE_CLIENT],
|
2019-10-05 14:16:08 +00:00
|
|
|
)
|
|
|
|
|
2021-03-05 21:09:05 +00:00
|
|
|
assert len(hass.states.async_entity_ids(SWITCH_DOMAIN)) == 1
|
2019-07-29 17:48:38 +00:00
|
|
|
|
2021-03-05 21:09:05 +00:00
|
|
|
poe_client = hass.states.get("switch.poe_client")
|
|
|
|
assert poe_client.state == "unavailable" # self.poe_mode is None
|