"""Tests for the bluetooth component.""" from collections.abc import Generator from unittest.mock import patch from bleak_retry_connector import bleak_manager from dbus_fast.aio import message_bus import habluetooth.util as habluetooth_utils import pytest @pytest.fixture(name="disable_bluez_manager_socket", autouse=True, scope="package") def disable_bluez_manager_socket(): """Mock the bluez manager socket.""" with patch.object(bleak_manager, "get_global_bluez_manager_with_timeout"): yield @pytest.fixture(name="disable_dbus_socket", autouse=True, scope="package") def disable_dbus_socket(): """Mock the dbus message bus to avoid creating a socket.""" with patch.object(message_bus, "MessageBus"): yield @pytest.fixture(name="disable_bluetooth_auto_recovery", autouse=True, scope="package") def disable_bluetooth_auto_recovery(): """Mock out auto recovery.""" with patch.object(habluetooth_utils, "recover_adapter"): yield @pytest.fixture(name="operating_system_85") def mock_operating_system_85(): """Mock running Home Assistant Operating system 8.5.""" with ( patch("homeassistant.components.hassio.is_hassio", return_value=True), patch( "homeassistant.components.hassio.get_os_info", return_value={ "version": "8.5", "version_latest": "10.0.dev20220912", "update_available": False, "board": "odroid-n2", "boot": "B", "data_disk": "/dev/mmcblk1p4", }, ), patch("homeassistant.components.hassio.get_info", return_value={}), patch("homeassistant.components.hassio.get_host_info", return_value={}), ): yield @pytest.fixture(name="operating_system_90") def mock_operating_system_90(): """Mock running Home Assistant Operating system 9.0.""" with ( patch("homeassistant.components.hassio.is_hassio", return_value=True), patch( "homeassistant.components.hassio.get_os_info", return_value={ "version": "9.0.dev20220912", "version_latest": "10.0.dev20220912", "update_available": False, "board": "odroid-n2", "boot": "B", "data_disk": "/dev/mmcblk1p4", }, ), patch("homeassistant.components.hassio.get_info", return_value={}), patch("homeassistant.components.hassio.get_host_info", return_value={}), ): yield @pytest.fixture(name="macos_adapter") def macos_adapter() -> Generator[None]: """Fixture that mocks the macos adapter.""" with ( patch("bleak.get_platform_scanner_backend_type"), patch( "homeassistant.components.bluetooth.platform.system", return_value="Darwin", ), patch( "habluetooth.scanner.platform.system", return_value="Darwin", ), patch( "bluetooth_adapters.systems.platform.system", return_value="Darwin", ), patch("habluetooth.scanner.SYSTEM", "Darwin"), ): yield @pytest.fixture(name="windows_adapter") def windows_adapter(): """Fixture that mocks the windows adapter.""" with ( patch( "bluetooth_adapters.systems.platform.system", return_value="Windows", ), patch("habluetooth.scanner.SYSTEM", "Windows"), ): yield @pytest.fixture(name="no_adapters") def no_adapter_fixture() -> Generator[None]: """Fixture that mocks no adapters on Linux.""" with ( patch( "homeassistant.components.bluetooth.platform.system", return_value="Linux", ), patch( "habluetooth.scanner.platform.system", return_value="Linux", ), patch( "bluetooth_adapters.systems.platform.system", return_value="Linux", ), patch("habluetooth.scanner.SYSTEM", "Linux"), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.refresh", ), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", {}, ), ): yield @pytest.fixture(name="one_adapter") def one_adapter_fixture() -> Generator[None]: """Fixture that mocks one adapter on Linux.""" with ( patch( "homeassistant.components.bluetooth.platform.system", return_value="Linux", ), patch( "habluetooth.scanner.platform.system", return_value="Linux", ), patch( "bluetooth_adapters.systems.platform.system", return_value="Linux", ), patch("habluetooth.scanner.SYSTEM", "Linux"), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.refresh", ), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", { "hci0": { "address": "00:00:00:00:00:01", "hw_version": "usb:v1D6Bp0246d053F", "passive_scan": True, "sw_version": "homeassistant", "manufacturer": "ACME", "product": "Bluetooth Adapter 5.0", "product_id": "aa01", "vendor_id": "cc01", }, }, ), ): yield @pytest.fixture(name="two_adapters") def two_adapters_fixture() -> Generator[None]: """Fixture that mocks two adapters on Linux.""" with ( patch( "homeassistant.components.bluetooth.platform.system", return_value="Linux" ), patch( "habluetooth.scanner.platform.system", return_value="Linux", ), patch("bluetooth_adapters.systems.platform.system", return_value="Linux"), patch("bluetooth_adapters.systems.linux.LinuxAdapters.refresh"), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", { "hci0": { "address": "00:00:00:00:00:01", "hw_version": "usb:v1D6Bp0246d053F", "passive_scan": False, "sw_version": "homeassistant", "manufacturer": "ACME", "product": "Bluetooth Adapter 5.0", "product_id": "aa01", "vendor_id": "cc01", "connection_slots": 1, }, "hci1": { "address": "00:00:00:00:00:02", "hw_version": "usb:v1D6Bp0246d053F", "passive_scan": True, "sw_version": "homeassistant", "manufacturer": "ACME", "product": "Bluetooth Adapter 5.0", "product_id": "aa01", "vendor_id": "cc01", "connection_slots": 2, }, }, ), ): yield @pytest.fixture(name="crashed_adapter") def crashed_adapter_fixture(): """Fixture that mocks one crashed adapter on Linux.""" with ( patch( "homeassistant.components.bluetooth.platform.system", return_value="Linux", ), patch( "habluetooth.scanner.platform.system", return_value="Linux", ), patch( "bluetooth_adapters.systems.platform.system", return_value="Linux", ), patch("habluetooth.scanner.SYSTEM", "Linux"), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.refresh", ), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", { "hci0": { "address": "00:00:00:00:00:00", "hw_version": "usb:v1D6Bp0246d053F", "passive_scan": True, "sw_version": "homeassistant", "manufacturer": None, "product": None, "product_id": None, "vendor_id": None, }, }, ), ): yield @pytest.fixture(name="one_adapter_old_bluez") def one_adapter_old_bluez(): """Fixture that mocks two adapters on Linux.""" with ( patch( "homeassistant.components.bluetooth.platform.system", return_value="Linux" ), patch( "habluetooth.scanner.platform.system", return_value="Linux", ), patch("bluetooth_adapters.systems.platform.system", return_value="Linux"), patch("bluetooth_adapters.systems.linux.LinuxAdapters.refresh"), patch( "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", { "hci0": { "address": "00:00:00:00:00:01", "hw_version": "usb:v1D6Bp0246d053F", "passive_scan": False, "sw_version": "homeassistant", "manufacturer": "ACME", "product": "Bluetooth Adapter 5.0", "product_id": "aa01", "vendor_id": "cc01", }, }, ), ): yield @pytest.fixture(name="disable_new_discovery_flows") def disable_new_discovery_flows_fixture(): """Fixture that disables new discovery flows. We want to disable new discovery flows as we are testing the BluetoothManager and not the discovery flows. This fixture will patch the discovery_flow.async_create_flow method to ensure we do not load other integrations. """ with patch( "homeassistant.components.bluetooth.manager.discovery_flow.async_create_flow" ) as mock_create_flow: yield mock_create_flow