Fix async_get_scanner to return the correct bluetooth scanner (#75637)
This commit is contained in:
parent
cb543a21b3
commit
326e05dcf1
4 changed files with 70 additions and 52 deletions
|
@ -12,7 +12,6 @@ from homeassistant.components.bluetooth import (
|
|||
UNAVAILABLE_TRACK_SECONDS,
|
||||
BluetoothChange,
|
||||
BluetoothServiceInfo,
|
||||
async_get_scanner,
|
||||
async_track_unavailable,
|
||||
models,
|
||||
)
|
||||
|
@ -21,6 +20,8 @@ from homeassistant.core import callback
|
|||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import _get_underlying_scanner
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
|
@ -135,7 +136,7 @@ async def test_discovery_match_by_service_uuid(
|
|||
wrong_device = BLEDevice("44:44:33:11:23:45", "wrong_name")
|
||||
wrong_adv = AdvertisementData(local_name="wrong_name", service_uuids=[])
|
||||
|
||||
async_get_scanner(hass)._callback(wrong_device, wrong_adv)
|
||||
_get_underlying_scanner()._callback(wrong_device, wrong_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 0
|
||||
|
@ -145,7 +146,7 @@ async def test_discovery_match_by_service_uuid(
|
|||
local_name="wohand", service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 1
|
||||
|
@ -172,7 +173,7 @@ async def test_discovery_match_by_local_name(hass, mock_bleak_scanner_start):
|
|||
wrong_device = BLEDevice("44:44:33:11:23:45", "wrong_name")
|
||||
wrong_adv = AdvertisementData(local_name="wrong_name", service_uuids=[])
|
||||
|
||||
async_get_scanner(hass)._callback(wrong_device, wrong_adv)
|
||||
_get_underlying_scanner()._callback(wrong_device, wrong_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 0
|
||||
|
@ -180,7 +181,7 @@ async def test_discovery_match_by_local_name(hass, mock_bleak_scanner_start):
|
|||
switchbot_device = BLEDevice("44:44:33:11:23:45", "wohand")
|
||||
switchbot_adv = AdvertisementData(local_name="wohand", service_uuids=[])
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 1
|
||||
|
@ -219,7 +220,7 @@ async def test_discovery_match_by_manufacturer_id_and_first_byte(
|
|||
manufacturer_data={76: b"\x06\x02\x03\x99"},
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(hkc_device, hkc_adv)
|
||||
_get_underlying_scanner()._callback(hkc_device, hkc_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 1
|
||||
|
@ -227,7 +228,7 @@ async def test_discovery_match_by_manufacturer_id_and_first_byte(
|
|||
mock_config_flow.reset_mock()
|
||||
|
||||
# 2nd discovery should not generate another flow
|
||||
async_get_scanner(hass)._callback(hkc_device, hkc_adv)
|
||||
_get_underlying_scanner()._callback(hkc_device, hkc_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 0
|
||||
|
@ -238,7 +239,7 @@ async def test_discovery_match_by_manufacturer_id_and_first_byte(
|
|||
local_name="lock", service_uuids=[], manufacturer_data={76: b"\x02"}
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(not_hkc_device, not_hkc_adv)
|
||||
_get_underlying_scanner()._callback(not_hkc_device, not_hkc_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 0
|
||||
|
@ -247,7 +248,7 @@ async def test_discovery_match_by_manufacturer_id_and_first_byte(
|
|||
local_name="lock", service_uuids=[], manufacturer_data={21: b"\x02"}
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(not_apple_device, not_apple_adv)
|
||||
_get_underlying_scanner()._callback(not_apple_device, not_apple_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 0
|
||||
|
@ -279,10 +280,10 @@ async def test_async_discovered_device_api(hass, mock_bleak_scanner_start):
|
|||
|
||||
wrong_device = BLEDevice("44:44:33:11:23:42", "wrong_name")
|
||||
wrong_adv = AdvertisementData(local_name="wrong_name", service_uuids=[])
|
||||
async_get_scanner(hass)._callback(wrong_device, wrong_adv)
|
||||
_get_underlying_scanner()._callback(wrong_device, wrong_adv)
|
||||
switchbot_device = BLEDevice("44:44:33:11:23:45", "wohand")
|
||||
switchbot_adv = AdvertisementData(local_name="wohand", service_uuids=[])
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
wrong_device_went_unavailable = False
|
||||
switchbot_device_went_unavailable = False
|
||||
|
||||
|
@ -316,8 +317,8 @@ async def test_async_discovered_device_api(hass, mock_bleak_scanner_start):
|
|||
assert wrong_device_went_unavailable is True
|
||||
|
||||
# See the devices again
|
||||
async_get_scanner(hass)._callback(wrong_device, wrong_adv)
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(wrong_device, wrong_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
# Cancel the callbacks
|
||||
wrong_device_unavailable_cancel()
|
||||
switchbot_device_unavailable_cancel()
|
||||
|
@ -382,25 +383,25 @@ async def test_register_callbacks(hass, mock_bleak_scanner_start, enable_bluetoo
|
|||
service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10c"},
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
|
||||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
# 3rd callback raises ValueError but is still tracked
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
cancel()
|
||||
|
||||
# 4th callback should not be tracked since we canceled
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(callbacks) == 3
|
||||
|
@ -467,25 +468,25 @@ async def test_register_callback_by_address(
|
|||
service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10c"},
|
||||
)
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
|
||||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
# 3rd callback raises ValueError but is still tracked
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
cancel()
|
||||
|
||||
# 4th callback should not be tracked since we canceled
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Now register again with a callback that fails to
|
||||
|
@ -549,15 +550,15 @@ async def test_wrapped_instance_with_filter(
|
|||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper(
|
||||
filters={"UUIDs": ["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]}
|
||||
)
|
||||
scanner.register_detection_callback(_device_detected)
|
||||
|
||||
mock_discovered = [MagicMock()]
|
||||
type(async_get_scanner(hass)).discovered_devices = mock_discovered
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
type(_get_underlying_scanner()).discovered_devices = mock_discovered
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
discovered = await scanner.discover(timeout=0)
|
||||
|
@ -572,17 +573,17 @@ async def test_wrapped_instance_with_filter(
|
|||
# We should get a reply from the history when we register again
|
||||
assert len(detected) == 3
|
||||
|
||||
type(async_get_scanner(hass)).discovered_devices = []
|
||||
type(_get_underlying_scanner()).discovered_devices = []
|
||||
discovered = await scanner.discover(timeout=0)
|
||||
assert len(discovered) == 0
|
||||
assert discovered == []
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
assert len(detected) == 4
|
||||
|
||||
# The filter we created in the wrapped scanner with should be respected
|
||||
# and we should not get another callback
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
assert len(detected) == 4
|
||||
|
||||
|
||||
|
@ -620,22 +621,22 @@ async def test_wrapped_instance_with_service_uuids(
|
|||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper(
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]
|
||||
)
|
||||
scanner.register_detection_callback(_device_detected)
|
||||
|
||||
type(async_get_scanner(hass)).discovered_devices = [MagicMock()]
|
||||
type(_get_underlying_scanner()).discovered_devices = [MagicMock()]
|
||||
for _ in range(2):
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(detected) == 2
|
||||
|
||||
# The UUIDs list we created in the wrapped scanner with should be respected
|
||||
# and we should not get another callback
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
assert len(detected) == 2
|
||||
|
||||
|
||||
|
@ -673,15 +674,15 @@ async def test_wrapped_instance_with_broken_callbacks(
|
|||
service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10c"},
|
||||
)
|
||||
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper(
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]
|
||||
)
|
||||
scanner.register_detection_callback(_device_detected)
|
||||
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
assert len(detected) == 1
|
||||
|
||||
|
@ -719,23 +720,23 @@ async def test_wrapped_instance_changes_uuids(
|
|||
empty_device = BLEDevice("11:22:33:44:55:66", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper()
|
||||
scanner.set_scanning_filter(
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]
|
||||
)
|
||||
scanner.register_detection_callback(_device_detected)
|
||||
|
||||
type(async_get_scanner(hass)).discovered_devices = [MagicMock()]
|
||||
type(_get_underlying_scanner()).discovered_devices = [MagicMock()]
|
||||
for _ in range(2):
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(detected) == 2
|
||||
|
||||
# The UUIDs list we created in the wrapped scanner with should be respected
|
||||
# and we should not get another callback
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
assert len(detected) == 2
|
||||
|
||||
|
||||
|
@ -772,23 +773,23 @@ async def test_wrapped_instance_changes_filters(
|
|||
empty_device = BLEDevice("11:22:33:44:55:62", "empty")
|
||||
empty_adv = AdvertisementData(local_name="empty")
|
||||
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper()
|
||||
scanner.set_scanning_filter(
|
||||
filters={"UUIDs": ["cba20d00-224d-11e6-9fb8-0002a5d5c51b"]}
|
||||
)
|
||||
scanner.register_detection_callback(_device_detected)
|
||||
|
||||
type(async_get_scanner(hass)).discovered_devices = [MagicMock()]
|
||||
type(_get_underlying_scanner()).discovered_devices = [MagicMock()]
|
||||
for _ in range(2):
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(detected) == 2
|
||||
|
||||
# The UUIDs list we created in the wrapped scanner with should be respected
|
||||
# and we should not get another callback
|
||||
async_get_scanner(hass)._callback(empty_device, empty_adv)
|
||||
_get_underlying_scanner()._callback(empty_device, empty_adv)
|
||||
assert len(detected) == 2
|
||||
|
||||
|
||||
|
@ -807,7 +808,7 @@ async def test_wrapped_instance_unsupported_filter(
|
|||
with patch.object(hass.config_entries.flow, "async_init"):
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
assert async_get_scanner(hass) is not None
|
||||
assert _get_underlying_scanner() is not None
|
||||
scanner = models.HaBleakScannerWrapper()
|
||||
scanner.set_scanning_filter(
|
||||
filters={
|
||||
|
@ -845,7 +846,7 @@ async def test_async_ble_device_from_address(hass, mock_bleak_scanner_start):
|
|||
|
||||
switchbot_device = BLEDevice("44:44:33:11:23:45", "wohand")
|
||||
switchbot_adv = AdvertisementData(local_name="wohand", service_uuids=[])
|
||||
async_get_scanner(hass)._callback(switchbot_device, switchbot_adv)
|
||||
_get_underlying_scanner()._callback(switchbot_device, switchbot_adv)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
|
@ -935,3 +936,9 @@ async def test_raising_runtime_error_when_no_bluetooth(hass):
|
|||
"""Test we raise an exception if we try to get the scanner when its not there."""
|
||||
with pytest.raises(RuntimeError):
|
||||
bluetooth.async_get_scanner(hass)
|
||||
|
||||
|
||||
async def test_getting_the_scanner_returns_the_wrapped_instance(hass, enable_bluetooth):
|
||||
"""Test getting the scanner returns the wrapped instance."""
|
||||
scanner = bluetooth.async_get_scanner(hass)
|
||||
assert isinstance(scanner, models.HaBleakScannerWrapper)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue