1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-01 11:46:40 +01:00
Files
core/tests/components/shelly/bluetooth/test_scanner.py
T
2026-05-24 14:53:54 -05:00

209 lines
6.6 KiB
Python

"""Test the shelly bluetooth scanner."""
from unittest.mock import Mock, patch
from aioshelly.ble.backend.scanner import ShellyBLEScanner
from aioshelly.ble.const import BLE_SCAN_RESULT_EVENT
import pytest
from homeassistant.components import bluetooth
from homeassistant.components.bluetooth import BluetoothScanningMode
from homeassistant.components.shelly.const import CONF_BLE_SCANNER_MODE, BLEScannerMode
from homeassistant.core import HomeAssistant
from .. import init_integration, inject_rpc_device_event
async def test_scanner_v1(
hass: HomeAssistant, mock_rpc_device, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test injecting data into the scanner v1."""
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
inject_rpc_device_event(
monkeypatch,
mock_rpc_device,
{
"events": [
{
"component": "script:1",
"data": [
1,
"aa:bb:cc:dd:ee:ff",
-62,
"AgEGCf9ZANH7O3TIkA==",
"EQcbxdWlAgC4n+YRTSIADaLLBhYADUgQYQ==",
],
"event": BLE_SCAN_RESULT_EVENT,
"id": 1,
"ts": 1668522399.2,
}
],
"ts": 1668522399.2,
},
)
ble_device = bluetooth.async_ble_device_from_address(
hass, "AA:BB:CC:DD:EE:FF", connectable=False
)
assert ble_device is not None
ble_device = bluetooth.async_ble_device_from_address(
hass, "AA:BB:CC:DD:EE:FF", connectable=True
)
assert ble_device is None
async def test_scanner_v2(
hass: HomeAssistant, mock_rpc_device, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test injecting data into the scanner v2."""
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
inject_rpc_device_event(
monkeypatch,
mock_rpc_device,
{
"events": [
{
"component": "script:1",
"data": [
2,
[
[
"aa:bb:cc:dd:ee:ff",
-62,
"AgEGCf9ZANH7O3TIkA==",
"EQcbxdWlAgC4n+YRTSIADaLLBhYADUgQYQ==",
]
],
],
"event": BLE_SCAN_RESULT_EVENT,
"id": 1,
"ts": 1668522399.2,
}
],
"ts": 1668522399.2,
},
)
ble_device = bluetooth.async_ble_device_from_address(
hass, "AA:BB:CC:DD:EE:FF", connectable=False
)
assert ble_device is not None
ble_device = bluetooth.async_ble_device_from_address(
hass, "AA:BB:CC:DD:EE:FF", connectable=True
)
assert ble_device is None
async def test_scanner_ignores_non_ble_events(
hass: HomeAssistant, mock_rpc_device, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test injecting non ble data into the scanner."""
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
inject_rpc_device_event(
monkeypatch,
mock_rpc_device,
{
"events": [
{
"component": "script:1",
"data": [],
"event": "not_ble_scan_result",
"id": 1,
"ts": 1668522399.2,
}
],
"ts": 1668522399.2,
},
)
async def test_scanner_ignores_wrong_version_and_logs(
hass: HomeAssistant,
mock_rpc_device,
monkeypatch: pytest.MonkeyPatch,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test injecting wrong version of ble data into the scanner."""
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
inject_rpc_device_event(
monkeypatch,
mock_rpc_device,
{
"events": [
{
"component": "script:1",
"data": [
0,
"aa:bb:cc:dd:ee:ff",
-62,
"AgEGCf9ZANH7O3TIkA==",
"EQcbxdWlAgC4n+YRTSIADaLLBhYADUgQYQ==",
],
"event": BLE_SCAN_RESULT_EVENT,
"id": 1,
"ts": 1668522399.2,
}
],
"ts": 1668522399.2,
},
)
assert "Unsupported BLE scan result version: 0" in caplog.text
async def test_scanner_warns_on_corrupt_event(
hass: HomeAssistant,
mock_rpc_device,
monkeypatch: pytest.MonkeyPatch,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test injecting garbage ble data into the scanner."""
await init_integration(
hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE}
)
assert mock_rpc_device.initialized is True
inject_rpc_device_event(
monkeypatch,
mock_rpc_device,
{
"events": [
{
"component": "script:1",
"data": [
1,
],
"event": BLE_SCAN_RESULT_EVENT,
"id": 1,
"ts": 1668522399.2,
}
],
"ts": 1668522399.2,
},
)
assert "Failed to parse BLE event" in caplog.text
async def test_scanner_auto_mode_starts_passive_and_binds_provider(
hass: HomeAssistant, mock_rpc_device: Mock
) -> None:
"""AUTO runs the radio passive; the scanner is pinned AUTO so the worker spawns."""
with patch.object(
ShellyBLEScanner, "set_active_window_provider", autospec=True
) as mock_set_provider:
await init_integration(hass, 2, options={CONF_BLE_SCANNER_MODE: "auto"})
assert mock_rpc_device.initialized is True
scanner = bluetooth.async_scanner_by_source(hass, "12:34:56:78:9A:BE")
assert scanner is not None
assert scanner.requested_mode is BluetoothScanningMode.AUTO
assert scanner.current_mode is BluetoothScanningMode.PASSIVE
mock_set_provider.assert_called_once_with(scanner, mock_rpc_device)