Files
core/tests/components/airthings_ble/test_init.py
2025-11-07 12:17:09 +01:00

193 lines
5.7 KiB
Python

"""Test the Airthings BLE integration init."""
from copy import deepcopy
from airthings_ble import AirthingsDeviceType
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.airthings_ble.const import (
DEFAULT_SCAN_INTERVAL,
DEVICE_MODEL,
DEVICE_SPECIFIC_SCAN_INTERVAL,
DOMAIN,
)
from homeassistant.core import HomeAssistant
from . import (
CORENTIUM_HOME_2_DEVICE_INFO,
CORENTIUM_HOME_2_SERVICE_INFO,
WAVE_DEVICE_INFO,
WAVE_ENHANCE_DEVICE_INFO,
WAVE_ENHANCE_SERVICE_INFO,
WAVE_SERVICE_INFO,
patch_airthings_ble,
patch_async_ble_device_from_address,
)
from tests.common import MockConfigEntry, async_fire_time_changed
from tests.components.bluetooth import inject_bluetooth_service_info
@pytest.mark.parametrize(
("service_info", "device_info"),
[
(WAVE_SERVICE_INFO, WAVE_DEVICE_INFO),
(WAVE_ENHANCE_SERVICE_INFO, WAVE_ENHANCE_DEVICE_INFO),
(CORENTIUM_HOME_2_SERVICE_INFO, CORENTIUM_HOME_2_DEVICE_INFO),
],
)
async def test_migration_existing_entries(
hass: HomeAssistant,
service_info,
device_info,
) -> None:
"""Test migration of existing config entry without device model."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=service_info.address,
data={},
)
entry.add_to_hass(hass)
inject_bluetooth_service_info(hass, service_info)
assert DEVICE_MODEL not in entry.data
with (
patch_async_ble_device_from_address(service_info.device),
patch_airthings_ble(device_info),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
# Migration should have added device_model to entry data
assert DEVICE_MODEL in entry.data
assert entry.data[DEVICE_MODEL] == device_info.model.value
async def test_no_migration_when_device_model_exists(
hass: HomeAssistant,
) -> None:
"""Test that migration does not run when device_model already exists."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=WAVE_SERVICE_INFO.address,
data={DEVICE_MODEL: WAVE_DEVICE_INFO.model.value},
)
entry.add_to_hass(hass)
inject_bluetooth_service_info(hass, WAVE_SERVICE_INFO)
with (
patch_async_ble_device_from_address(WAVE_SERVICE_INFO.device),
patch_airthings_ble(WAVE_DEVICE_INFO) as mock_update,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
# Should have only 1 call for initial refresh (no migration call)
assert mock_update.call_count == 1
assert entry.data[DEVICE_MODEL] == WAVE_DEVICE_INFO.model.value
async def test_scan_interval_corentium_home_2(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test that coordinator uses radon scan interval for Corentium Home 2."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=WAVE_SERVICE_INFO.address,
data={DEVICE_MODEL: CORENTIUM_HOME_2_DEVICE_INFO.model.value},
)
entry.add_to_hass(hass)
inject_bluetooth_service_info(hass, WAVE_SERVICE_INFO)
with (
patch_async_ble_device_from_address(WAVE_SERVICE_INFO.device),
patch_airthings_ble(CORENTIUM_HOME_2_DEVICE_INFO),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert (
hass.states.get("sensor.airthings_corentium_home_2_123456_battery").state
== "90"
)
changed_info = deepcopy(CORENTIUM_HOME_2_DEVICE_INFO)
changed_info.sensors["battery"] = 89
with patch_airthings_ble(changed_info):
freezer.tick(DEFAULT_SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert (
hass.states.get("sensor.airthings_corentium_home_2_123456_battery").state
== "90"
)
freezer.tick(
DEVICE_SPECIFIC_SCAN_INTERVAL.get(
AirthingsDeviceType.CORENTIUM_HOME_2.value
)
- DEFAULT_SCAN_INTERVAL
)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert (
hass.states.get("sensor.airthings_corentium_home_2_123456_battery").state
== "89"
)
@pytest.mark.parametrize(
("service_info", "device_info", "battery_entity_id"),
[
(WAVE_SERVICE_INFO, WAVE_DEVICE_INFO, "sensor.airthings_wave_123456_battery"),
(
WAVE_ENHANCE_SERVICE_INFO,
WAVE_ENHANCE_DEVICE_INFO,
"sensor.airthings_wave_enhance_123456_battery",
),
],
)
async def test_coordinator_default_scan_interval(
hass: HomeAssistant,
service_info,
device_info,
freezer: FrozenDateTimeFactory,
battery_entity_id: str,
) -> None:
"""Test that coordinator uses default scan interval."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=service_info.address,
data={DEVICE_MODEL: device_info.model.value},
)
entry.add_to_hass(hass)
inject_bluetooth_service_info(hass, service_info)
with (
patch_async_ble_device_from_address(service_info.device),
patch_airthings_ble(device_info),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(battery_entity_id).state == "85"
changed_info = deepcopy(device_info)
changed_info.sensors["battery"] = 84
with patch_airthings_ble(changed_info):
freezer.tick(DEFAULT_SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert hass.states.get(battery_entity_id).state == "84"