Add WS command for discovering Thread routers (#88021)
* Add WS command for discovering Thread routers * Fix type annotations * Mock zeroconf in tests * Key discovery by external MAC address * Add tests * Include hostname in data, allow missing fields * Fix typo * Include server instead of hostname
This commit is contained in:
parent
c7fc90f8a0
commit
8613d60c5e
7 changed files with 793 additions and 3 deletions
|
@ -1,11 +1,21 @@
|
|||
"""Test the thread websocket API."""
|
||||
|
||||
from homeassistant.components.thread import dataset_store
|
||||
from unittest.mock import ANY, AsyncMock
|
||||
|
||||
from zeroconf.asyncio import AsyncServiceInfo
|
||||
|
||||
from homeassistant.components.thread import dataset_store, discovery
|
||||
from homeassistant.components.thread.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from . import DATASET_1, DATASET_2, DATASET_3
|
||||
from . import (
|
||||
DATASET_1,
|
||||
DATASET_2,
|
||||
DATASET_3,
|
||||
ROUTER_DISCOVERY_GOOGLE_1,
|
||||
ROUTER_DISCOVERY_HASS,
|
||||
)
|
||||
|
||||
|
||||
async def test_add_dataset(hass: HomeAssistant, hass_ws_client) -> None:
|
||||
|
@ -121,3 +131,98 @@ async def test_list_get_dataset(hass: HomeAssistant, hass_ws_client) -> None:
|
|||
msg = await client.receive_json()
|
||||
assert not msg["success"]
|
||||
assert msg["error"] == {"code": "not_found", "message": "unknown dataset"}
|
||||
|
||||
|
||||
async def test_discover_routers(
|
||||
hass: HomeAssistant, hass_ws_client, mock_async_zeroconf
|
||||
) -> None:
|
||||
"""Test discovering thread routers."""
|
||||
mock_async_zeroconf.async_add_service_listener = AsyncMock()
|
||||
mock_async_zeroconf.async_remove_service_listener = AsyncMock()
|
||||
mock_async_zeroconf.async_get_service_info = AsyncMock()
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Subscribe
|
||||
await client.send_json({"id": 1, "type": "thread/discover_routers"})
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
assert msg["result"] is None
|
||||
|
||||
mock_async_zeroconf.async_add_service_listener.assert_called_once_with(
|
||||
"_meshcop._udp.local.", ANY
|
||||
)
|
||||
listener: discovery.ThreadRouterDiscovery.ThreadServiceListener = (
|
||||
mock_async_zeroconf.async_add_service_listener.mock_calls[0][1][1]
|
||||
)
|
||||
|
||||
# Discover a service
|
||||
mock_async_zeroconf.async_get_service_info.return_value = AsyncServiceInfo(
|
||||
**ROUTER_DISCOVERY_HASS
|
||||
)
|
||||
listener.add_service(
|
||||
None, ROUTER_DISCOVERY_HASS["type_"], ROUTER_DISCOVERY_HASS["name"]
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg == {
|
||||
"event": {
|
||||
"data": {
|
||||
"brand": "homeassistant",
|
||||
"extended_pan_id": "e60fc7c186212ce5",
|
||||
"model_name": "OpenThreadBorderRouter",
|
||||
"network_name": "OpenThread HC",
|
||||
"server": "core-silabs-multiprotocol.local.",
|
||||
"vendor_name": "HomeAssistant",
|
||||
},
|
||||
"key": "aeeb2f594b570bbf",
|
||||
"type": "router_discovered",
|
||||
},
|
||||
"id": 1,
|
||||
"type": "event",
|
||||
}
|
||||
|
||||
# Discover another service - we don't care if zeroconf considers this an update
|
||||
mock_async_zeroconf.async_get_service_info.return_value = AsyncServiceInfo(
|
||||
**ROUTER_DISCOVERY_GOOGLE_1
|
||||
)
|
||||
listener.update_service(
|
||||
None, ROUTER_DISCOVERY_GOOGLE_1["type_"], ROUTER_DISCOVERY_GOOGLE_1["name"]
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg == {
|
||||
"event": {
|
||||
"data": {
|
||||
"brand": "google",
|
||||
"extended_pan_id": "9e75e256f61409a3",
|
||||
"model_name": "Google Nest Hub",
|
||||
"network_name": "NEST-PAN-E1AF",
|
||||
"server": "2d99f293-cd8e-2770-8dd2-6675de9fa000.local.",
|
||||
"vendor_name": "Google Inc.",
|
||||
},
|
||||
"key": "f6a99b425a67abed",
|
||||
"type": "router_discovered",
|
||||
},
|
||||
"id": 1,
|
||||
"type": "event",
|
||||
}
|
||||
|
||||
# Remove a service
|
||||
listener.remove_service(
|
||||
None, ROUTER_DISCOVERY_HASS["type_"], ROUTER_DISCOVERY_HASS["name"]
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg == {
|
||||
"event": {"key": "aeeb2f594b570bbf", "type": "router_removed"},
|
||||
"id": 1,
|
||||
"type": "event",
|
||||
}
|
||||
|
||||
# Unsubscribe
|
||||
await client.send_json({"id": 2, "type": "unsubscribe_events", "subscription": 1})
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
|
||||
mock_async_zeroconf.async_remove_service_listener.assert_called_once_with(listener)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue