1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-15 07:36:16 +00:00
Files
core/tests/components/switchbot/test_init.py
2026-02-09 13:30:14 +01:00

214 lines
6.0 KiB
Python

"""Test the switchbot init."""
from collections.abc import Callable
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.switchbot.const import (
CONF_CURTAIN_SPEED,
CONF_RETRY_COUNT,
DEFAULT_CURTAIN_SPEED,
DEFAULT_RETRY_COUNT,
DOMAIN,
)
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_SENSOR_TYPE
from homeassistant.core import HomeAssistant
from . import (
HUBMINI_MATTER_SERVICE_INFO,
LOCK_SERVICE_INFO,
WOCURTAIN_SERVICE_INFO,
WOSENSORTH_SERVICE_INFO,
patch_async_ble_device_from_address,
)
from tests.common import MockConfigEntry
from tests.components.bluetooth import inject_bluetooth_service_info
@pytest.mark.parametrize(
("exception", "error_message"),
[
(
ValueError("wrong model"),
"Switchbot device initialization failed because of incorrect configuration parameters: wrong model",
),
],
)
async def test_exception_handling_for_device_initialization(
hass: HomeAssistant,
mock_entry_encrypted_factory: Callable[[str], MockConfigEntry],
exception: Exception,
error_message: str,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test exception handling for lock initialization."""
inject_bluetooth_service_info(hass, LOCK_SERVICE_INFO)
entry = mock_entry_encrypted_factory(sensor_type="lock")
entry.add_to_hass(hass)
with patch(
"homeassistant.components.switchbot.lock.switchbot.SwitchbotLock.__init__",
side_effect=exception,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert error_message in caplog.text
async def test_setup_entry_without_ble_device(
hass: HomeAssistant,
mock_entry_factory: Callable[[str], MockConfigEntry],
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test setup entry without ble device."""
entry = mock_entry_factory("hygrometer_co2")
entry.add_to_hass(hass)
with patch_async_ble_device_from_address(None):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert (
"Could not find Switchbot hygrometer_co2 with address aa:bb:cc:dd:ee:ff"
in caplog.text
)
async def test_coordinator_wait_ready_timeout(
hass: HomeAssistant,
mock_entry_factory: Callable[[str], MockConfigEntry],
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the coordinator async_wait_ready timeout by calling it directly."""
inject_bluetooth_service_info(hass, HUBMINI_MATTER_SERVICE_INFO)
entry = mock_entry_factory("hubmini_matter")
entry.add_to_hass(hass)
timeout_mock = AsyncMock()
timeout_mock.__aenter__.side_effect = TimeoutError
timeout_mock.__aexit__.return_value = None
with patch(
"homeassistant.components.switchbot.coordinator.asyncio.timeout",
return_value=timeout_mock,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert "aa:bb:cc:dd:ee:ff is not advertising state" in caplog.text
@pytest.mark.parametrize(
("sensor_type", "service_info", "expected_options"),
[
(
"curtain",
WOCURTAIN_SERVICE_INFO,
{
CONF_RETRY_COUNT: DEFAULT_RETRY_COUNT,
CONF_CURTAIN_SPEED: DEFAULT_CURTAIN_SPEED,
},
),
(
"hygrometer",
WOSENSORTH_SERVICE_INFO,
{
CONF_RETRY_COUNT: DEFAULT_RETRY_COUNT,
},
),
],
)
async def test_migrate_entry_from_v1_1_to_v1_2(
hass: HomeAssistant,
sensor_type: str,
service_info,
expected_options: dict,
) -> None:
"""Test migration from version 1.1 to 1.2 adds default options."""
inject_bluetooth_service_info(hass, service_info)
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
CONF_NAME: "test-name",
CONF_SENSOR_TYPE: sensor_type,
},
unique_id="aabbccddeeff",
version=1,
minor_version=1,
options={},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.version == 1
assert entry.minor_version == 2
assert entry.options == expected_options
async def test_migrate_entry_preserves_existing_options(
hass: HomeAssistant,
) -> None:
"""Test migration preserves existing options."""
inject_bluetooth_service_info(hass, WOCURTAIN_SERVICE_INFO)
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
CONF_NAME: "test-name",
CONF_SENSOR_TYPE: "curtain",
},
unique_id="aabbccddeeff",
version=1,
minor_version=1,
options={CONF_RETRY_COUNT: 5},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.version == 1
assert entry.minor_version == 2
# Existing retry_count should be preserved, curtain_speed added
assert entry.options[CONF_RETRY_COUNT] == 5
assert entry.options[CONF_CURTAIN_SPEED] == DEFAULT_CURTAIN_SPEED
async def test_migrate_entry_fails_for_future_version(
hass: HomeAssistant,
) -> None:
"""Test migration fails for future versions."""
inject_bluetooth_service_info(hass, WOCURTAIN_SERVICE_INFO)
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
CONF_NAME: "test-name",
CONF_SENSOR_TYPE: "curtain",
},
unique_id="aabbccddeeff",
version=2,
minor_version=1,
options={},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
# Entry should not be loaded due to failed migration
assert entry.version == 2
assert entry.minor_version == 1