python-kasa/kasa/tests/smart/modules/test_autooff.py
Teemu R 767156421b
Initialize autooff features only when data is available (#933)
For power strips, the autooff data needs to be requested from the
children.
Until we do that, we should not create these features to avoid crashing
during switch platform initialization.

This also ports the module to use `_initialize_features` and add tests.
2024-05-24 19:39:10 +02:00

104 lines
2.6 KiB
Python

from __future__ import annotations
import sys
from datetime import datetime
from typing import Optional
import pytest
from pytest_mock import MockerFixture
from kasa import Module
from kasa.smart import SmartDevice
from kasa.tests.device_fixtures import parametrize
autooff = parametrize(
"has autooff", component_filter="auto_off", protocol_filter={"SMART"}
)
@autooff
@pytest.mark.parametrize(
"feature, prop_name, type",
[
("auto_off_enabled", "enabled", bool),
("auto_off_minutes", "delay", int),
("auto_off_at", "auto_off_at", Optional[datetime]),
],
)
@pytest.mark.skipif(
sys.version_info < (3, 10),
reason="Subscripted generics cannot be used with class and instance checks",
)
async def test_autooff_features(
dev: SmartDevice, feature: str, prop_name: str, type: type
):
"""Test that features are registered and work as expected."""
autooff = dev.modules.get(Module.AutoOff)
assert autooff is not None
prop = getattr(autooff, prop_name)
assert isinstance(prop, type)
feat = dev.features[feature]
assert feat.value == prop
assert isinstance(feat.value, type)
@autooff
async def test_settings(dev: SmartDevice, mocker: MockerFixture):
"""Test autooff settings."""
autooff = dev.modules.get(Module.AutoOff)
assert autooff
enabled = dev.features["auto_off_enabled"]
assert autooff.enabled == enabled.value
delay = dev.features["auto_off_minutes"]
assert autooff.delay == delay.value
call = mocker.spy(autooff, "call")
new_state = True
await autooff.set_enabled(new_state)
call.assert_called_with(
"set_auto_off_config", {"enable": new_state, "delay_min": delay.value}
)
call.reset_mock()
await dev.update()
new_delay = 123
await autooff.set_delay(new_delay)
call.assert_called_with(
"set_auto_off_config", {"enable": new_state, "delay_min": new_delay}
)
await dev.update()
assert autooff.enabled == new_state
assert autooff.delay == new_delay
@autooff
@pytest.mark.parametrize("is_timer_active", [True, False])
async def test_auto_off_at(
dev: SmartDevice, mocker: MockerFixture, is_timer_active: bool
):
"""Test auto-off at sensor."""
autooff = dev.modules.get(Module.AutoOff)
assert autooff
autooff_at = dev.features["auto_off_at"]
mocker.patch.object(
type(autooff),
"is_timer_active",
new_callable=mocker.PropertyMock,
return_value=is_timer_active,
)
if is_timer_active:
assert isinstance(autooff_at.value, datetime)
else:
assert autooff_at.value is None