mirror of
https://github.com/python-kasa/python-kasa.git
synced 2026-07-08 06:41:59 +00:00
tests: add type annotations to Smart tests (#1686)
Some checks are pending
CI / Perform Lint Checks (3.14) (push) Waiting to run
CI / Python 3.11 on macos-latest (push) Blocked by required conditions
CI / Python 3.12 on macos-latest (push) Blocked by required conditions
CI / Python 3.13 on macos-latest (push) Blocked by required conditions
CI / Python 3.14 on macos-latest (push) Blocked by required conditions
CI / Python 3.11 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.12 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.13 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.14 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.11 on windows-latest (push) Blocked by required conditions
CI / Python 3.12 on windows-latest (push) Blocked by required conditions
CI / Python 3.13 on windows-latest (push) Blocked by required conditions
CI / Python 3.14 on windows-latest (push) Blocked by required conditions
CodeQL Checks / Analyze (python) (push) Waiting to run
Some checks are pending
CI / Perform Lint Checks (3.14) (push) Waiting to run
CI / Python 3.11 on macos-latest (push) Blocked by required conditions
CI / Python 3.12 on macos-latest (push) Blocked by required conditions
CI / Python 3.13 on macos-latest (push) Blocked by required conditions
CI / Python 3.14 on macos-latest (push) Blocked by required conditions
CI / Python 3.11 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.12 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.13 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.14 on ubuntu-latest (push) Blocked by required conditions
CI / Python 3.11 on windows-latest (push) Blocked by required conditions
CI / Python 3.12 on windows-latest (push) Blocked by required conditions
CI / Python 3.13 on windows-latest (push) Blocked by required conditions
CI / Python 3.14 on windows-latest (push) Blocked by required conditions
CodeQL Checks / Analyze (python) (push) Waiting to run
Add type annotations across all 'smart' tests, enabling mypy to check test function bodies, catching type errors that were previously hidden.
This commit is contained in:
@@ -9,7 +9,7 @@ brightness = parametrize("brightness smart", component_filter="brightness")
|
|||||||
|
|
||||||
|
|
||||||
@brightness
|
@brightness
|
||||||
async def test_brightness_component(dev: SmartDevice):
|
async def test_brightness_component(dev: SmartDevice) -> None:
|
||||||
"""Test brightness feature."""
|
"""Test brightness feature."""
|
||||||
brightness = next(get_parent_and_child_modules(dev, "Brightness"))
|
brightness = next(get_parent_and_child_modules(dev, "Brightness"))
|
||||||
assert brightness
|
assert brightness
|
||||||
@@ -35,7 +35,7 @@ async def test_brightness_component(dev: SmartDevice):
|
|||||||
|
|
||||||
|
|
||||||
@dimmable_iot
|
@dimmable_iot
|
||||||
async def test_brightness_dimmable(dev: IotDevice):
|
async def test_brightness_dimmable(dev: IotDevice) -> None:
|
||||||
"""Test brightness feature."""
|
"""Test brightness feature."""
|
||||||
assert isinstance(dev, IotDevice)
|
assert isinstance(dev, IotDevice)
|
||||||
assert "brightness" in dev.sys_info or bool(dev.sys_info["is_dimmable"])
|
assert "brightness" in dev.sys_info or bool(dev.sys_info["is_dimmable"])
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from ...conftest import variable_temp_smart
|
|||||||
|
|
||||||
|
|
||||||
@variable_temp_smart
|
@variable_temp_smart
|
||||||
async def test_colortemp_component(dev: SmartDevice):
|
async def test_colortemp_component(dev: SmartDevice) -> None:
|
||||||
"""Test brightness feature."""
|
"""Test brightness feature."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
assert "color_temperature" in dev._components
|
assert "color_temperature" in dev._components
|
||||||
|
|||||||
@@ -1,17 +1,32 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TypedDict
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from kasa import Module
|
from kasa import Module
|
||||||
from kasa.smart import SmartDevice
|
from kasa.smart import SmartDevice
|
||||||
from kasa.smart.modules import Alarm
|
from kasa.smart.modules import Alarm
|
||||||
|
from kasa.smart.modules.alarm import AlarmVolume
|
||||||
|
|
||||||
from ...device_fixtures import get_parent_and_child_modules, parametrize
|
from ...device_fixtures import get_parent_and_child_modules, parametrize
|
||||||
|
|
||||||
alarm = parametrize("has alarm", component_filter="alarm", protocol_filter={"SMART"})
|
alarm = parametrize("has alarm", component_filter="alarm", protocol_filter={"SMART"})
|
||||||
|
|
||||||
|
|
||||||
|
class PlayAlarmKwargs(TypedDict, total=False):
|
||||||
|
duration: int
|
||||||
|
volume: AlarmVolume | int
|
||||||
|
sound: str
|
||||||
|
|
||||||
|
|
||||||
|
class PlayAlarmRequestParams(TypedDict, total=False):
|
||||||
|
alarm_duration: int
|
||||||
|
alarm_volume: AlarmVolume
|
||||||
|
alarm_type: str
|
||||||
|
|
||||||
|
|
||||||
@alarm
|
@alarm
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("feature", "prop_name", "type"),
|
("feature", "prop_name", "type"),
|
||||||
@@ -23,7 +38,9 @@ alarm = parametrize("has alarm", component_filter="alarm", protocol_filter={"SMA
|
|||||||
("alarm_volume_level", "alarm_volume", int),
|
("alarm_volume_level", "alarm_volume", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
||||||
assert alarm is not None
|
assert alarm is not None
|
||||||
@@ -37,7 +54,7 @@ async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: ty
|
|||||||
|
|
||||||
|
|
||||||
@alarm
|
@alarm
|
||||||
async def test_volume_feature(dev: SmartDevice):
|
async def test_volume_feature(dev: SmartDevice) -> None:
|
||||||
"""Test that volume features have correct choices and range."""
|
"""Test that volume features have correct choices and range."""
|
||||||
alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
||||||
assert alarm is not None
|
assert alarm is not None
|
||||||
@@ -64,7 +81,12 @@ async def test_volume_feature(dev: SmartDevice):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_play(dev: SmartDevice, kwargs, request_params, mocker: MockerFixture):
|
async def test_play(
|
||||||
|
dev: SmartDevice,
|
||||||
|
kwargs: PlayAlarmKwargs,
|
||||||
|
request_params: PlayAlarmRequestParams,
|
||||||
|
mocker: MockerFixture,
|
||||||
|
) -> None:
|
||||||
"""Test that play parameters are handled correctly."""
|
"""Test that play parameters are handled correctly."""
|
||||||
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
||||||
call_spy = mocker.spy(alarm, "call")
|
call_spy = mocker.spy(alarm, "call")
|
||||||
@@ -86,7 +108,7 @@ async def test_play(dev: SmartDevice, kwargs, request_params, mocker: MockerFixt
|
|||||||
|
|
||||||
|
|
||||||
@alarm
|
@alarm
|
||||||
async def test_stop(dev: SmartDevice, mocker: MockerFixture):
|
async def test_stop(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test that stop creates the correct call."""
|
"""Test that stop creates the correct call."""
|
||||||
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
||||||
call_spy = mocker.spy(alarm, "call")
|
call_spy = mocker.spy(alarm, "call")
|
||||||
@@ -112,7 +134,7 @@ async def test_set_alarm_configure(
|
|||||||
method: str,
|
method: str,
|
||||||
value: str | int,
|
value: str | int,
|
||||||
target_key: str,
|
target_key: str,
|
||||||
):
|
) -> None:
|
||||||
"""Test that set_alarm_sound creates the correct call."""
|
"""Test that set_alarm_sound creates the correct call."""
|
||||||
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
alarm: Alarm = next(get_parent_and_child_modules(dev, Module.Alarm))
|
||||||
call_spy = mocker.spy(alarm, "call")
|
call_spy = mocker.spy(alarm, "call")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ autooff = parametrize(
|
|||||||
)
|
)
|
||||||
async def test_autooff_features(
|
async def test_autooff_features(
|
||||||
dev: SmartDevice, feature: str, prop_name: str, type: type
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
):
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
||||||
assert autooff is not None
|
assert autooff is not None
|
||||||
@@ -40,7 +40,7 @@ async def test_autooff_features(
|
|||||||
|
|
||||||
|
|
||||||
@autooff
|
@autooff
|
||||||
async def test_settings(dev: SmartDevice, mocker: MockerFixture):
|
async def test_settings(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test autooff settings."""
|
"""Test autooff settings."""
|
||||||
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
||||||
assert autooff
|
assert autooff
|
||||||
@@ -79,7 +79,7 @@ async def test_settings(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
@pytest.mark.parametrize("is_timer_active", [True, False])
|
@pytest.mark.parametrize("is_timer_active", [True, False])
|
||||||
async def test_auto_off_at(
|
async def test_auto_off_at(
|
||||||
dev: SmartDevice, mocker: MockerFixture, is_timer_active: bool
|
dev: SmartDevice, mocker: MockerFixture, is_timer_active: bool
|
||||||
):
|
) -> None:
|
||||||
"""Test auto-off at sensor."""
|
"""Test auto-off at sensor."""
|
||||||
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
autooff = next(get_parent_and_child_modules(dev, Module.AutoOff))
|
||||||
assert autooff
|
assert autooff
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa import Module
|
from kasa import Module
|
||||||
from kasa.smart.modules import ChildLock
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...device_fixtures import parametrize
|
from ...device_fixtures import parametrize
|
||||||
|
|
||||||
@@ -19,9 +19,11 @@ childlock = parametrize(
|
|||||||
("child_lock", "enabled", bool),
|
("child_lock", "enabled", bool),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev, feature, prop_name, type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
protect: ChildLock = dev.modules[Module.ChildLock]
|
protect = dev.modules[Module.ChildLock]
|
||||||
assert protect is not None
|
assert protect is not None
|
||||||
|
|
||||||
prop = getattr(protect, prop_name)
|
prop = getattr(protect, prop_name)
|
||||||
@@ -33,9 +35,9 @@ async def test_features(dev, feature, prop_name, type):
|
|||||||
|
|
||||||
|
|
||||||
@childlock
|
@childlock
|
||||||
async def test_enabled(dev):
|
async def test_enabled(dev: SmartDevice) -> None:
|
||||||
"""Test the API."""
|
"""Test the API."""
|
||||||
protect: ChildLock = dev.modules[Module.ChildLock]
|
protect = dev.modules[Module.ChildLock]
|
||||||
assert protect is not None
|
assert protect is not None
|
||||||
|
|
||||||
assert isinstance(protect.enabled, bool)
|
assert isinstance(protect.enabled, bool)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa import Module
|
from kasa import Module
|
||||||
from kasa.smart.modules import ChildProtection
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...device_fixtures import parametrize
|
from ...device_fixtures import parametrize
|
||||||
|
|
||||||
@@ -19,9 +19,11 @@ child_protection = parametrize(
|
|||||||
("child_lock", "enabled", bool),
|
("child_lock", "enabled", bool),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev, feature, prop_name, type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
protect: ChildProtection = dev.modules[Module.ChildProtection]
|
protect = dev.modules[Module.ChildProtection]
|
||||||
assert protect is not None
|
assert protect is not None
|
||||||
|
|
||||||
prop = getattr(protect, prop_name)
|
prop = getattr(protect, prop_name)
|
||||||
@@ -33,9 +35,9 @@ async def test_features(dev, feature, prop_name, type):
|
|||||||
|
|
||||||
|
|
||||||
@child_protection
|
@child_protection
|
||||||
async def test_enabled(dev):
|
async def test_enabled(dev: SmartDevice) -> None:
|
||||||
"""Test the API."""
|
"""Test the API."""
|
||||||
protect: ChildProtection = dev.modules[Module.ChildProtection]
|
protect = dev.modules[Module.ChildProtection]
|
||||||
assert protect is not None
|
assert protect is not None
|
||||||
|
|
||||||
assert isinstance(protect.enabled, bool)
|
assert isinstance(protect.enabled, bool)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ childsetup = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@childsetup
|
@childsetup
|
||||||
async def test_childsetup_features(dev: Device):
|
async def test_childsetup_features(dev: Device) -> None:
|
||||||
"""Test the exposed features."""
|
"""Test the exposed features."""
|
||||||
cs = dev.modules.get(Module.ChildSetup)
|
cs = dev.modules.get(Module.ChildSetup)
|
||||||
assert cs
|
assert cs
|
||||||
@@ -28,7 +28,7 @@ async def test_childsetup_features(dev: Device):
|
|||||||
@childsetup
|
@childsetup
|
||||||
async def test_childsetup_pair(
|
async def test_childsetup_pair(
|
||||||
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test device pairing."""
|
"""Test device pairing."""
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
mock_query_helper = mocker.spy(dev, "_query_helper")
|
mock_query_helper = mocker.spy(dev, "_query_helper")
|
||||||
@@ -52,7 +52,7 @@ async def test_childsetup_pair(
|
|||||||
@childsetup
|
@childsetup
|
||||||
async def test_childsetup_unpair(
|
async def test_childsetup_unpair(
|
||||||
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test unpair."""
|
"""Test unpair."""
|
||||||
mock_query_helper = mocker.spy(dev, "_query_helper")
|
mock_query_helper = mocker.spy(dev, "_query_helper")
|
||||||
DUMMY_ID = "dummy_id"
|
DUMMY_ID = "dummy_id"
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ clean = parametrize("clean module", component_filter="clean", protocol_filter={"
|
|||||||
("battery_level", "battery", int),
|
("battery_level", "battery", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
assert clean is not None
|
assert clean is not None
|
||||||
@@ -94,7 +96,7 @@ async def test_actions(
|
|||||||
value: str | int,
|
value: str | int,
|
||||||
method: str,
|
method: str,
|
||||||
params: dict,
|
params: dict,
|
||||||
):
|
) -> None:
|
||||||
"""Test the clean actions."""
|
"""Test the clean actions."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
call = mocker.spy(clean, "call")
|
call = mocker.spy(clean, "call")
|
||||||
@@ -130,7 +132,7 @@ async def test_post_update_hook(
|
|||||||
error: ErrorCode,
|
error: ErrorCode,
|
||||||
warning_msg: str | None,
|
warning_msg: str | None,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
):
|
) -> None:
|
||||||
"""Test that post update hook sets error states correctly."""
|
"""Test that post update hook sets error states correctly."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
assert clean
|
assert clean
|
||||||
@@ -160,7 +162,7 @@ async def test_post_update_hook(
|
|||||||
|
|
||||||
|
|
||||||
@clean
|
@clean
|
||||||
async def test_resume(dev: SmartDevice, mocker: MockerFixture):
|
async def test_resume(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test that start calls resume if the state is paused."""
|
"""Test that start calls resume if the state is paused."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
|
|
||||||
@@ -182,7 +184,7 @@ async def test_resume(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
@clean
|
@clean
|
||||||
async def test_unknown_status(
|
async def test_unknown_status(
|
||||||
dev: SmartDevice, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
dev: SmartDevice, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test that unknown status is logged."""
|
"""Test that unknown status is logged."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
|
|
||||||
@@ -227,7 +229,7 @@ async def test_invalid_settings(
|
|||||||
value: str,
|
value: str,
|
||||||
exc: type[Exception],
|
exc: type[Exception],
|
||||||
exc_message: str,
|
exc_message: str,
|
||||||
):
|
) -> None:
|
||||||
"""Test invalid settings."""
|
"""Test invalid settings."""
|
||||||
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
clean = next(get_parent_and_child_modules(dev, Module.Clean))
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ cleanrecords = parametrize(
|
|||||||
("last_clean_timestamp", "last_clean_timestamp", datetime),
|
("last_clean_timestamp", "last_clean_timestamp", datetime),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
records = next(get_parent_and_child_modules(dev, Module.CleanRecords))
|
records = next(get_parent_and_child_modules(dev, Module.CleanRecords))
|
||||||
assert records is not None
|
assert records is not None
|
||||||
@@ -41,7 +43,7 @@ async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: ty
|
|||||||
|
|
||||||
|
|
||||||
@cleanrecords
|
@cleanrecords
|
||||||
async def test_timezone(dev: SmartDevice):
|
async def test_timezone(dev: SmartDevice) -> None:
|
||||||
"""Test that timezone is added to timestamps."""
|
"""Test that timezone is added to timestamps."""
|
||||||
clean_records = next(get_parent_and_child_modules(dev, Module.CleanRecords))
|
clean_records = next(get_parent_and_child_modules(dev, Module.CleanRecords))
|
||||||
assert clean_records is not None
|
assert clean_records is not None
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ consumables = parametrize(
|
|||||||
"consumable_name", [consumable.id for consumable in CONSUMABLE_METAS]
|
"consumable_name", [consumable.id for consumable in CONSUMABLE_METAS]
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("postfix", ["used", "remaining"])
|
@pytest.mark.parametrize("postfix", ["used", "remaining"])
|
||||||
async def test_features(dev: SmartDevice, consumable_name: str, postfix: str):
|
async def test_features(dev: SmartDevice, consumable_name: str, postfix: str) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
consumables = next(get_parent_and_child_modules(dev, Module.Consumables))
|
consumables = next(get_parent_and_child_modules(dev, Module.Consumables))
|
||||||
assert consumables is not None
|
assert consumables is not None
|
||||||
@@ -39,7 +39,7 @@ async def test_features(dev: SmartDevice, consumable_name: str, postfix: str):
|
|||||||
)
|
)
|
||||||
async def test_erase(
|
async def test_erase(
|
||||||
dev: SmartDevice, mocker: MockerFixture, consumable_name: str, data_key: str
|
dev: SmartDevice, mocker: MockerFixture, consumable_name: str, data_key: str
|
||||||
):
|
) -> None:
|
||||||
"""Test autocollection switch."""
|
"""Test autocollection switch."""
|
||||||
consumables = next(get_parent_and_child_modules(dev, Module.Consumables))
|
consumables = next(get_parent_and_child_modules(dev, Module.Consumables))
|
||||||
call = mocker.spy(consumables, "call")
|
call = mocker.spy(consumables, "call")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ contact = parametrize(
|
|||||||
("is_open", bool),
|
("is_open", bool),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_contact_features(dev: Device, feature, type):
|
async def test_contact_features(dev: Device, feature: str, type: type) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
contact = dev.modules.get(Module.ContactSensor)
|
contact = dev.modules.get(Module.ContactSensor)
|
||||||
assert contact is not None
|
assert contact is not None
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ dustbin = parametrize(
|
|||||||
("dustbin_mode", "mode", str),
|
("dustbin_mode", "mode", str),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
||||||
assert dustbin is not None
|
assert dustbin is not None
|
||||||
@@ -36,7 +38,7 @@ async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: ty
|
|||||||
|
|
||||||
|
|
||||||
@dustbin
|
@dustbin
|
||||||
async def test_dustbin_mode(dev: SmartDevice, mocker: MockerFixture):
|
async def test_dustbin_mode(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test dust mode."""
|
"""Test dust mode."""
|
||||||
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
||||||
call = mocker.spy(dustbin, "call")
|
call = mocker.spy(dustbin, "call")
|
||||||
@@ -61,7 +63,7 @@ async def test_dustbin_mode(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@dustbin
|
@dustbin
|
||||||
async def test_dustbin_mode_off(dev: SmartDevice, mocker: MockerFixture):
|
async def test_dustbin_mode_off(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test dustbin_mode == Off."""
|
"""Test dustbin_mode == Off."""
|
||||||
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
||||||
call = mocker.spy(dustbin, "call")
|
call = mocker.spy(dustbin, "call")
|
||||||
@@ -80,7 +82,7 @@ async def test_dustbin_mode_off(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@dustbin
|
@dustbin
|
||||||
async def test_autocollection(dev: SmartDevice, mocker: MockerFixture):
|
async def test_autocollection(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test autocollection switch."""
|
"""Test autocollection switch."""
|
||||||
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
||||||
call = mocker.spy(dustbin, "call")
|
call = mocker.spy(dustbin, "call")
|
||||||
@@ -101,7 +103,7 @@ async def test_autocollection(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@dustbin
|
@dustbin
|
||||||
async def test_empty_dustbin(dev: SmartDevice, mocker: MockerFixture):
|
async def test_empty_dustbin(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test the empty dustbin feature."""
|
"""Test the empty dustbin feature."""
|
||||||
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
dustbin = next(get_parent_and_child_modules(dev, Module.Dustbin))
|
||||||
call = mocker.spy(dustbin, "call")
|
call = mocker.spy(dustbin, "call")
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from tests.conftest import has_emeter_smart
|
|||||||
|
|
||||||
|
|
||||||
@has_emeter_smart
|
@has_emeter_smart
|
||||||
async def test_supported(dev: SmartDevice):
|
async def test_supported(dev: SmartDevice) -> None:
|
||||||
energy_module = dev.modules.get(Module.Energy)
|
energy_module = dev.modules.get(Module.Energy)
|
||||||
if not energy_module:
|
if not energy_module:
|
||||||
pytest.skip(f"Energy module not supported for {dev}.")
|
pytest.skip(f"Energy module not supported for {dev}.")
|
||||||
@@ -31,7 +31,7 @@ async def test_supported(dev: SmartDevice):
|
|||||||
@has_emeter_smart
|
@has_emeter_smart
|
||||||
async def test_get_energy_usage_error(
|
async def test_get_energy_usage_error(
|
||||||
dev: SmartDevice, caplog: pytest.LogCaptureFixture
|
dev: SmartDevice, caplog: pytest.LogCaptureFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test errors on get_energy_usage."""
|
"""Test errors on get_energy_usage."""
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ fan = parametrize("has fan", component_filter="fan_control", protocol_filter={"S
|
|||||||
|
|
||||||
|
|
||||||
@fan
|
@fan
|
||||||
async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture):
|
async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test fan speed feature."""
|
"""Test fan speed feature."""
|
||||||
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
||||||
assert fan
|
assert fan
|
||||||
@@ -35,7 +35,7 @@ async def test_fan_speed(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@fan
|
@fan
|
||||||
async def test_sleep_mode(dev: SmartDevice, mocker: MockerFixture):
|
async def test_sleep_mode(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test sleep mode feature."""
|
"""Test sleep mode feature."""
|
||||||
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
||||||
assert fan
|
assert fan
|
||||||
@@ -53,7 +53,7 @@ async def test_sleep_mode(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@fan
|
@fan
|
||||||
async def test_fan_module(dev: SmartDevice, mocker: MockerFixture):
|
async def test_fan_module(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test fan speed on device interface."""
|
"""Test fan speed on device interface."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
||||||
@@ -89,7 +89,7 @@ async def test_fan_module(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@fan
|
@fan
|
||||||
async def test_fan_features(dev: SmartDevice, mocker: MockerFixture):
|
async def test_fan_features(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test fan speed on device interface."""
|
"""Test fan speed on device interface."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
fan = next(get_parent_and_child_modules(dev, Module.Fan))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from contextlib import nullcontext
|
from contextlib import AbstractContextManager, nullcontext
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
@@ -31,9 +31,14 @@ firmware = parametrize(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_firmware_features(
|
async def test_firmware_features(
|
||||||
dev: SmartDevice, feature, prop_name, type, required_version, mocker: MockerFixture
|
dev: SmartDevice,
|
||||||
):
|
feature: str,
|
||||||
"""Test light effect."""
|
prop_name: str,
|
||||||
|
type: type,
|
||||||
|
required_version: int,
|
||||||
|
mocker: MockerFixture,
|
||||||
|
) -> None:
|
||||||
|
"""Test firmware features."""
|
||||||
fw = dev.modules.get(Module.Firmware)
|
fw = dev.modules.get(Module.Firmware)
|
||||||
assert fw
|
assert fw
|
||||||
assert fw.firmware_update_info is None
|
assert fw.firmware_update_info is None
|
||||||
@@ -54,7 +59,7 @@ async def test_firmware_features(
|
|||||||
|
|
||||||
|
|
||||||
@firmware
|
@firmware
|
||||||
async def test_firmware_update_info(dev: SmartDevice):
|
async def test_firmware_update_info(dev: SmartDevice) -> None:
|
||||||
"""Test that the firmware UpdateInfo object deserializes correctly."""
|
"""Test that the firmware UpdateInfo object deserializes correctly."""
|
||||||
fw = dev.modules.get(Module.Firmware)
|
fw = dev.modules.get(Module.Firmware)
|
||||||
assert fw
|
assert fw
|
||||||
@@ -68,7 +73,7 @@ async def test_firmware_update_info(dev: SmartDevice):
|
|||||||
|
|
||||||
|
|
||||||
@firmware
|
@firmware
|
||||||
async def test_update_available_without_cloud(dev: SmartDevice):
|
async def test_update_available_without_cloud(dev: SmartDevice) -> None:
|
||||||
"""Test that update_available returns None when disconnected."""
|
"""Test that update_available returns None when disconnected."""
|
||||||
fw = dev.modules.get(Module.Firmware)
|
fw = dev.modules.get(Module.Firmware)
|
||||||
assert fw
|
assert fw
|
||||||
@@ -95,9 +100,9 @@ async def test_firmware_update(
|
|||||||
dev: SmartDevice,
|
dev: SmartDevice,
|
||||||
mocker: MockerFixture,
|
mocker: MockerFixture,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
update_available,
|
update_available: bool,
|
||||||
expected_result,
|
expected_result: AbstractContextManager,
|
||||||
):
|
) -> None:
|
||||||
"""Test updating firmware."""
|
"""Test updating firmware."""
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ homekit = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@homekit
|
@homekit
|
||||||
async def test_info(dev: SmartDevice):
|
async def test_info(dev: SmartDevice) -> None:
|
||||||
"""Test homekit info."""
|
"""Test homekit info."""
|
||||||
homekit = dev.modules.get(Module.HomeKit)
|
homekit = dev.modules.get(Module.HomeKit)
|
||||||
assert homekit
|
assert homekit
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa.smart.modules import HumiditySensor
|
from kasa import Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...device_fixtures import parametrize
|
from ...device_fixtures import parametrize
|
||||||
|
|
||||||
@@ -17,9 +18,9 @@ humidity = parametrize(
|
|||||||
("humidity_warning", bool),
|
("humidity_warning", bool),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_humidity_features(dev, feature, type):
|
async def test_humidity_features(dev: SmartDevice, feature: str, type: type) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
humidity: HumiditySensor = dev.modules["HumiditySensor"]
|
humidity = dev.modules[Module.HumiditySensor]
|
||||||
|
|
||||||
prop = getattr(humidity, feature)
|
prop = getattr(humidity, feature)
|
||||||
assert isinstance(prop, type)
|
assert isinstance(prop, type)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ light_effect = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@light_effect
|
@light_effect
|
||||||
async def test_light_effect(dev: Device, mocker: MockerFixture):
|
async def test_light_effect(dev: Device, mocker: MockerFixture) -> None:
|
||||||
"""Test light effect."""
|
"""Test light effect."""
|
||||||
light_effect = dev.modules.get(Module.LightEffect)
|
light_effect = dev.modules.get(Module.LightEffect)
|
||||||
assert isinstance(light_effect, LightEffect)
|
assert isinstance(light_effect, LightEffect)
|
||||||
@@ -46,7 +46,7 @@ async def test_light_effect(dev: Device, mocker: MockerFixture):
|
|||||||
@pytest.mark.parametrize("effect_active", [True, False])
|
@pytest.mark.parametrize("effect_active", [True, False])
|
||||||
async def test_light_effect_brightness(
|
async def test_light_effect_brightness(
|
||||||
dev: Device, effect_active: bool, mocker: MockerFixture
|
dev: Device, effect_active: bool, mocker: MockerFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test that light module uses light_effect for brightness when active."""
|
"""Test that light module uses light_effect for brightness when active."""
|
||||||
light_module = dev.modules[Module.Light]
|
light_module = dev.modules[Module.Light]
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ light_strip_effect = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@light_strip_effect
|
@light_strip_effect
|
||||||
async def test_light_strip_effect(dev: Device, mocker: MockerFixture):
|
async def test_light_strip_effect(dev: Device, mocker: MockerFixture) -> None:
|
||||||
"""Test light strip effect."""
|
"""Test light strip effect."""
|
||||||
light_effect = dev.modules.get(Module.LightEffect)
|
light_effect = dev.modules.get(Module.LightEffect)
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ async def test_light_strip_effect(dev: Device, mocker: MockerFixture):
|
|||||||
@pytest.mark.parametrize("effect_active", [True, False])
|
@pytest.mark.parametrize("effect_active", [True, False])
|
||||||
async def test_light_effect_brightness(
|
async def test_light_effect_brightness(
|
||||||
dev: Device, effect_active: bool, mocker: MockerFixture
|
dev: Device, effect_active: bool, mocker: MockerFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test that light module uses light_effect for brightness when active."""
|
"""Test that light module uses light_effect for brightness when active."""
|
||||||
light_module = dev.modules[Module.Light]
|
light_module = dev.modules[Module.Light]
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ light_transition_gt_v1 = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@light_transition_v1
|
@light_transition_v1
|
||||||
async def test_module_v1(dev: SmartDevice, mocker: MockerFixture):
|
async def test_module_v1(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test light transition module."""
|
"""Test light transition module."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
light_transition = next(get_parent_and_child_modules(dev, Module.LightTransition))
|
light_transition = next(get_parent_and_child_modules(dev, Module.LightTransition))
|
||||||
@@ -42,7 +42,7 @@ async def test_module_v1(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@light_transition_gt_v1
|
@light_transition_gt_v1
|
||||||
async def test_module_gt_v1(dev: SmartDevice, mocker: MockerFixture):
|
async def test_module_gt_v1(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test light transition module."""
|
"""Test light transition module."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
light_transition = next(get_parent_and_child_modules(dev, Module.LightTransition))
|
light_transition = next(get_parent_and_child_modules(dev, Module.LightTransition))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ matter = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@matter
|
@matter
|
||||||
async def test_info(dev: SmartDevice):
|
async def test_info(dev: SmartDevice) -> None:
|
||||||
"""Test matter info."""
|
"""Test matter info."""
|
||||||
matter = dev.modules.get(Module.Matter)
|
matter = dev.modules.get(Module.Matter)
|
||||||
assert matter
|
assert matter
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ mop = parametrize("has mop", component_filter="mop", protocol_filter={"SMART"})
|
|||||||
("mop_waterlevel", "waterlevel", str),
|
("mop_waterlevel", "waterlevel", str),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
mod = next(get_parent_and_child_modules(dev, Module.Mop))
|
mod = next(get_parent_and_child_modules(dev, Module.Mop))
|
||||||
assert mod is not None
|
assert mod is not None
|
||||||
@@ -34,7 +36,7 @@ async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: ty
|
|||||||
|
|
||||||
|
|
||||||
@mop
|
@mop
|
||||||
async def test_mop_waterlevel(dev: SmartDevice, mocker: MockerFixture):
|
async def test_mop_waterlevel(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test dust mode."""
|
"""Test dust mode."""
|
||||||
mop_module = next(get_parent_and_child_modules(dev, Module.Mop))
|
mop_module = next(get_parent_and_child_modules(dev, Module.Mop))
|
||||||
call = mocker.spy(mop_module, "call")
|
call = mocker.spy(mop_module, "call")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ motion = parametrize(
|
|||||||
("motion_detected", bool),
|
("motion_detected", bool),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_motion_features(dev: Device, feature, type):
|
async def test_motion_features(dev: Device, feature: str, type: type) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
motion = dev.modules.get(Module.MotionSensor)
|
motion = dev.modules.get(Module.MotionSensor)
|
||||||
assert motion is not None
|
assert motion is not None
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from kasa import Device, Module
|
from kasa import Device, Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...device_fixtures import get_parent_and_child_modules, parametrize
|
from ...device_fixtures import get_parent_and_child_modules, parametrize
|
||||||
|
|
||||||
@@ -20,7 +21,9 @@ powerprotection = parametrize(
|
|||||||
("power_protection_threshold", "protection_threshold", int),
|
("power_protection_threshold", "protection_threshold", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev, feature, prop_name, type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
||||||
assert powerprot
|
assert powerprot
|
||||||
@@ -35,7 +38,7 @@ async def test_features(dev, feature, prop_name, type):
|
|||||||
|
|
||||||
|
|
||||||
@powerprotection
|
@powerprotection
|
||||||
async def test_set_enable(dev: Device, mocker: MockerFixture):
|
async def test_set_enable(dev: Device, mocker: MockerFixture) -> None:
|
||||||
"""Test enable."""
|
"""Test enable."""
|
||||||
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
||||||
assert powerprot
|
assert powerprot
|
||||||
@@ -88,7 +91,7 @@ async def test_set_enable(dev: Device, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@powerprotection
|
@powerprotection
|
||||||
async def test_set_threshold(dev: Device, mocker: MockerFixture):
|
async def test_set_threshold(dev: Device, mocker: MockerFixture) -> None:
|
||||||
"""Test enable."""
|
"""Test enable."""
|
||||||
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
powerprot = next(get_parent_and_child_modules(dev, Module.PowerProtection))
|
||||||
assert powerprot
|
assert powerprot
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ speaker = parametrize(
|
|||||||
("volume", "volume", int),
|
("volume", "volume", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: type):
|
async def test_features(
|
||||||
|
dev: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
||||||
assert speaker is not None
|
assert speaker is not None
|
||||||
@@ -34,7 +36,7 @@ async def test_features(dev: SmartDevice, feature: str, prop_name: str, type: ty
|
|||||||
|
|
||||||
|
|
||||||
@speaker
|
@speaker
|
||||||
async def test_set_volume(dev: SmartDevice, mocker: MockerFixture):
|
async def test_set_volume(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test speaker settings."""
|
"""Test speaker settings."""
|
||||||
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
||||||
assert speaker is not None
|
assert speaker is not None
|
||||||
@@ -61,7 +63,7 @@ async def test_set_volume(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@speaker
|
@speaker
|
||||||
async def test_locate(dev: SmartDevice, mocker: MockerFixture):
|
async def test_locate(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test the locate method."""
|
"""Test the locate method."""
|
||||||
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
speaker = next(get_parent_and_child_modules(dev, Module.Speaker))
|
||||||
call = mocker.spy(speaker, "call")
|
call = mocker.spy(speaker, "call")
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa.smart.modules import TemperatureSensor
|
from kasa import Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...device_fixtures import parametrize
|
from ...device_fixtures import parametrize
|
||||||
|
|
||||||
@@ -23,9 +24,9 @@ temperature_warning = parametrize(
|
|||||||
("temperature_unit", str),
|
("temperature_unit", str),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_temperature_features(dev, feature, type):
|
async def test_temperature_features(dev: SmartDevice, feature: str, type: type) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
temp_module: TemperatureSensor = dev.modules["TemperatureSensor"]
|
temp_module = dev.modules[Module.TemperatureSensor]
|
||||||
|
|
||||||
prop = getattr(temp_module, feature)
|
prop = getattr(temp_module, feature)
|
||||||
assert isinstance(prop, type)
|
assert isinstance(prop, type)
|
||||||
@@ -36,9 +37,9 @@ async def test_temperature_features(dev, feature, type):
|
|||||||
|
|
||||||
|
|
||||||
@temperature_warning
|
@temperature_warning
|
||||||
async def test_temperature_warning(dev):
|
async def test_temperature_warning(dev: SmartDevice) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
temp_module: TemperatureSensor = dev.modules["TemperatureSensor"]
|
temp_module = dev.modules[Module.TemperatureSensor]
|
||||||
|
|
||||||
assert hasattr(temp_module, "temperature_warning")
|
assert hasattr(temp_module, "temperature_warning")
|
||||||
assert isinstance(temp_module.temperature_warning, bool)
|
assert isinstance(temp_module.temperature_warning, bool)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import re
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa.smart.modules import TemperatureControl
|
from kasa import Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
from kasa.smart.modules.temperaturecontrol import ThermostatState
|
from kasa.smart.modules.temperaturecontrol import ThermostatState
|
||||||
|
|
||||||
from ...device_fixtures import parametrize, thermostats_smart
|
from ...device_fixtures import parametrize, thermostats_smart
|
||||||
@@ -23,9 +24,11 @@ temperature = parametrize(
|
|||||||
("temperature_offset", int),
|
("temperature_offset", int),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_temperature_control_features(dev, feature, type):
|
async def test_temperature_control_features(
|
||||||
|
dev: SmartDevice, feature: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
|
|
||||||
prop = getattr(temp_module, feature)
|
prop = getattr(temp_module, feature)
|
||||||
assert isinstance(prop, type)
|
assert isinstance(prop, type)
|
||||||
@@ -40,9 +43,9 @@ async def test_temperature_control_features(dev, feature, type):
|
|||||||
|
|
||||||
|
|
||||||
@thermostats_smart
|
@thermostats_smart
|
||||||
async def test_set_temperature_turns_heating_on(dev):
|
async def test_set_temperature_turns_heating_on(dev: SmartDevice) -> None:
|
||||||
"""Test that set_temperature turns heating on."""
|
"""Test that set_temperature turns heating on."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
|
|
||||||
await temp_module.set_state(False)
|
await temp_module.set_state(False)
|
||||||
await dev.update()
|
await dev.update()
|
||||||
@@ -57,9 +60,9 @@ async def test_set_temperature_turns_heating_on(dev):
|
|||||||
|
|
||||||
|
|
||||||
@thermostats_smart
|
@thermostats_smart
|
||||||
async def test_set_temperature_invalid_values(dev):
|
async def test_set_temperature_invalid_values(dev: SmartDevice) -> None:
|
||||||
"""Test that out-of-bounds temperature values raise errors."""
|
"""Test that out-of-bounds temperature values raise errors."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
ValueError, match="Invalid target temperature -1, must be in range"
|
ValueError, match="Invalid target temperature -1, must be in range"
|
||||||
@@ -73,9 +76,9 @@ async def test_set_temperature_invalid_values(dev):
|
|||||||
|
|
||||||
|
|
||||||
@thermostats_smart
|
@thermostats_smart
|
||||||
async def test_temperature_offset(dev):
|
async def test_temperature_offset(dev: SmartDevice) -> None:
|
||||||
"""Test the temperature offset API."""
|
"""Test the temperature offset API."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
ValueError, match=re.escape("Temperature offset must be [-10, 10]")
|
ValueError, match=re.escape("Temperature offset must be [-10, 10]")
|
||||||
):
|
):
|
||||||
@@ -111,9 +114,11 @@ async def test_temperature_offset(dev):
|
|||||||
pytest.param(ThermostatState.Unknown, ["invalid"], False, id="unknown state"),
|
pytest.param(ThermostatState.Unknown, ["invalid"], False, id="unknown state"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_thermostat_mode(dev, mode, states, frost_protection):
|
async def test_thermostat_mode(
|
||||||
|
dev: SmartDevice, mode: ThermostatState, states: list[str], frost_protection: bool
|
||||||
|
) -> None:
|
||||||
"""Test different thermostat modes."""
|
"""Test different thermostat modes."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
|
|
||||||
temp_module.data["frost_protection_on"] = frost_protection
|
temp_module.data["frost_protection_on"] = frost_protection
|
||||||
temp_module.data["trv_states"] = states
|
temp_module.data["trv_states"] = states
|
||||||
@@ -138,9 +143,15 @@ async def test_thermostat_mode(dev, mode, states, frost_protection):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.xdist_group(name="caplog")
|
@pytest.mark.xdist_group(name="caplog")
|
||||||
async def test_thermostat_mode_warnings(dev, mode, states, msg, caplog):
|
async def test_thermostat_mode_warnings(
|
||||||
|
dev: SmartDevice,
|
||||||
|
mode: ThermostatState,
|
||||||
|
states: list[str],
|
||||||
|
msg: str,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
"""Test thermostat modes that should log a warning."""
|
"""Test thermostat modes that should log a warning."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
caplog.set_level(logging.WARNING)
|
caplog.set_level(logging.WARNING)
|
||||||
|
|
||||||
temp_module.data["trv_states"] = states
|
temp_module.data["trv_states"] = states
|
||||||
@@ -149,17 +160,19 @@ async def test_thermostat_mode_warnings(dev, mode, states, msg, caplog):
|
|||||||
|
|
||||||
|
|
||||||
@thermostats_smart
|
@thermostats_smart
|
||||||
async def test_thermostat_heating_with_low_battery(dev):
|
async def test_thermostat_heating_with_low_battery(dev: SmartDevice) -> None:
|
||||||
"""Test that mode is reported correctly with extra states."""
|
"""Test that mode is reported correctly with extra states."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
temp_module.data["trv_states"] = ["low_battery", "heating"]
|
temp_module.data["trv_states"] = ["low_battery", "heating"]
|
||||||
assert temp_module.mode is ThermostatState.Heating
|
assert temp_module.mode is ThermostatState.Heating
|
||||||
|
|
||||||
|
|
||||||
@thermostats_smart
|
@thermostats_smart
|
||||||
async def test_thermostat_idle_with_low_battery(dev, caplog):
|
async def test_thermostat_idle_with_low_battery(
|
||||||
|
dev: SmartDevice, caplog: pytest.LogCaptureFixture
|
||||||
|
) -> None:
|
||||||
"""Test that mode is reported correctly with extra states."""
|
"""Test that mode is reported correctly with extra states."""
|
||||||
temp_module: TemperatureControl = dev.modules["TemperatureControl"]
|
temp_module = dev.modules[Module.TemperatureControl]
|
||||||
temp_module.data["trv_states"] = ["low_battery"]
|
temp_module.data["trv_states"] = ["low_battery"]
|
||||||
with caplog.at_level(logging.WARNING):
|
with caplog.at_level(logging.WARNING):
|
||||||
assert temp_module.mode is ThermostatState.Idle
|
assert temp_module.mode is ThermostatState.Idle
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ triggerlogs = parametrize(
|
|||||||
|
|
||||||
|
|
||||||
@triggerlogs
|
@triggerlogs
|
||||||
async def test_trigger_logs(dev: Device):
|
async def test_trigger_logs(dev: Device) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
triggerlogs = dev.modules.get(Module.TriggerLogs)
|
triggerlogs = dev.modules.get(Module.TriggerLogs)
|
||||||
assert triggerlogs is not None
|
assert triggerlogs is not None
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ from enum import Enum
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from kasa.smart.modules import WaterleakSensor
|
from kasa import Module
|
||||||
|
from kasa.smart import SmartDevice
|
||||||
|
|
||||||
from ...conftest import get_device_for_fixture_protocol
|
from ...conftest import get_device_for_fixture_protocol
|
||||||
from ...device_fixtures import parametrize
|
from ...device_fixtures import parametrize
|
||||||
@@ -28,10 +29,12 @@ async def parent(request):
|
|||||||
("water_leak", "status", Enum),
|
("water_leak", "status", Enum),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_waterleak_properties(dev, parent, feature, prop_name, type):
|
async def test_waterleak_properties(
|
||||||
|
dev: SmartDevice, parent: SmartDevice, feature: str, prop_name: str, type: type
|
||||||
|
) -> None:
|
||||||
"""Test that features are registered and work as expected."""
|
"""Test that features are registered and work as expected."""
|
||||||
dev._parent = parent
|
dev._parent = parent
|
||||||
waterleak: WaterleakSensor = dev.modules["WaterleakSensor"]
|
waterleak = dev.modules[Module.WaterleakSensor]
|
||||||
|
|
||||||
prop = getattr(waterleak, prop_name)
|
prop = getattr(waterleak, prop_name)
|
||||||
assert isinstance(prop, type)
|
assert isinstance(prop, type)
|
||||||
@@ -42,10 +45,10 @@ async def test_waterleak_properties(dev, parent, feature, prop_name, type):
|
|||||||
|
|
||||||
|
|
||||||
@waterleak
|
@waterleak
|
||||||
async def test_waterleak_features(dev, parent):
|
async def test_waterleak_features(dev: SmartDevice, parent: SmartDevice) -> None:
|
||||||
"""Test waterleak features."""
|
"""Test waterleak features."""
|
||||||
dev._parent = parent
|
dev._parent = parent
|
||||||
waterleak: WaterleakSensor = dev.modules["WaterleakSensor"]
|
waterleak = dev.modules[Module.WaterleakSensor]
|
||||||
|
|
||||||
assert "water_leak" in dev.features
|
assert "water_leak" in dev.features
|
||||||
assert dev.features["water_leak"].value == waterleak.status
|
assert dev.features["water_leak"].value == waterleak.status
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ hub_all = parametrize_combine([hubs_smart, hub_smartcam])
|
|||||||
@device_smart
|
@device_smart
|
||||||
@pytest.mark.requires_dummy
|
@pytest.mark.requires_dummy
|
||||||
@pytest.mark.xdist_group(name="caplog")
|
@pytest.mark.xdist_group(name="caplog")
|
||||||
async def test_try_get_response(dev: SmartDevice, caplog):
|
async def test_try_get_response(
|
||||||
|
dev: SmartDevice, caplog: pytest.LogCaptureFixture
|
||||||
|
) -> None:
|
||||||
mock_response: dict = {
|
mock_response: dict = {
|
||||||
"get_device_info": SmartErrorCode.PARAMS_ERROR,
|
"get_device_info": SmartErrorCode.PARAMS_ERROR,
|
||||||
}
|
}
|
||||||
@@ -56,7 +58,7 @@ async def test_try_get_response(dev: SmartDevice, caplog):
|
|||||||
|
|
||||||
@device_smart
|
@device_smart
|
||||||
@pytest.mark.requires_dummy
|
@pytest.mark.requires_dummy
|
||||||
async def test_update_no_device_info(dev: SmartDevice, mocker: MockerFixture):
|
async def test_update_no_device_info(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
mock_response: dict = {
|
mock_response: dict = {
|
||||||
"get_device_usage": {},
|
"get_device_usage": {},
|
||||||
"get_device_time": {},
|
"get_device_time": {},
|
||||||
@@ -68,7 +70,9 @@ async def test_update_no_device_info(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@smart_discovery
|
@smart_discovery
|
||||||
async def test_device_type_no_update(discovery_mock, caplog: pytest.LogCaptureFixture):
|
async def test_device_type_no_update(
|
||||||
|
discovery_mock, caplog: pytest.LogCaptureFixture
|
||||||
|
) -> None:
|
||||||
"""Test device type and repr when device not updated."""
|
"""Test device type and repr when device not updated."""
|
||||||
dev = SmartDevice(DISCOVERY_MOCK_IP)
|
dev = SmartDevice(DISCOVERY_MOCK_IP)
|
||||||
assert dev.device_type is DeviceType.Unknown
|
assert dev.device_type is DeviceType.Unknown
|
||||||
@@ -96,7 +100,7 @@ async def test_device_type_no_update(discovery_mock, caplog: pytest.LogCaptureFi
|
|||||||
|
|
||||||
|
|
||||||
@device_smart
|
@device_smart
|
||||||
async def test_initial_update(dev: SmartDevice, mocker: MockerFixture):
|
async def test_initial_update(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test the initial update cycle."""
|
"""Test the initial update cycle."""
|
||||||
# As the fixture data is already initialized, we reset the state for testing
|
# As the fixture data is already initialized, we reset the state for testing
|
||||||
dev._components_raw = None
|
dev._components_raw = None
|
||||||
@@ -124,7 +128,7 @@ async def test_initial_update(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@device_smart
|
@device_smart
|
||||||
async def test_negotiate(dev: SmartDevice, mocker: MockerFixture):
|
async def test_negotiate(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test that the initial negotiation performs expected steps."""
|
"""Test that the initial negotiation performs expected steps."""
|
||||||
# As the fixture data is already initialized, we reset the state for testing
|
# As the fixture data is already initialized, we reset the state for testing
|
||||||
dev._components_raw = None
|
dev._components_raw = None
|
||||||
@@ -158,7 +162,7 @@ async def test_negotiate(dev: SmartDevice, mocker: MockerFixture):
|
|||||||
|
|
||||||
|
|
||||||
@device_smart
|
@device_smart
|
||||||
async def test_update_module_queries(dev: SmartDevice, mocker: MockerFixture):
|
async def test_update_module_queries(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Test that the regular update uses queries from all supported modules."""
|
"""Test that the regular update uses queries from all supported modules."""
|
||||||
# We need to have some modules initialized by now
|
# We need to have some modules initialized by now
|
||||||
assert dev._modules
|
assert dev._modules
|
||||||
@@ -195,7 +199,7 @@ async def test_update_module_update_delays(
|
|||||||
mocker: MockerFixture,
|
mocker: MockerFixture,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
):
|
) -> None:
|
||||||
"""Test that modules with minimum delays delay."""
|
"""Test that modules with minimum delays delay."""
|
||||||
# We need to have some modules initialized by now
|
# We need to have some modules initialized by now
|
||||||
assert dev._modules
|
assert dev._modules
|
||||||
@@ -253,7 +257,7 @@ async def test_hub_children_update_delays(
|
|||||||
mocker: MockerFixture,
|
mocker: MockerFixture,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
):
|
) -> None:
|
||||||
"""Test that hub children use the correct delay."""
|
"""Test that hub children use the correct delay."""
|
||||||
if not dev.children:
|
if not dev.children:
|
||||||
pytest.skip(f"Device {dev.model} does not have children.")
|
pytest.skip(f"Device {dev.model} does not have children.")
|
||||||
@@ -416,14 +420,15 @@ async def test_update_module_query_errors(
|
|||||||
mocker: MockerFixture,
|
mocker: MockerFixture,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
first_update,
|
first_update: bool,
|
||||||
error_type,
|
error_type: SmartErrorCode | TimeoutError,
|
||||||
recover,
|
recover: bool,
|
||||||
):
|
) -> None:
|
||||||
"""Test that modules that disabled / removed on query failures.
|
"""Test that modules that disabled / removed on query failures.
|
||||||
|
|
||||||
i.e. the whole query times out rather than device returns an error.
|
i.e. the whole query times out rather than device returns an error.
|
||||||
"""
|
"""
|
||||||
|
caplog.set_level(logging.DEBUG)
|
||||||
# We need to have some modules initialized by now
|
# We need to have some modules initialized by now
|
||||||
assert dev._modules
|
assert dev._modules
|
||||||
|
|
||||||
@@ -480,8 +485,6 @@ async def test_update_module_query_errors(
|
|||||||
raise TimeoutError()
|
raise TimeoutError()
|
||||||
if len(child_requests) > 1:
|
if len(child_requests) > 1:
|
||||||
raise TimeoutError()
|
raise TimeoutError()
|
||||||
|
|
||||||
if raise_error:
|
|
||||||
resp = {
|
resp = {
|
||||||
"method": child_requests[0]["method"],
|
"method": child_requests[0]["method"],
|
||||||
"error_code": error_type.value,
|
"error_code": error_type.value,
|
||||||
@@ -594,7 +597,7 @@ async def test_update_module_query_errors(
|
|||||||
assert emod.status is not None
|
assert emod.status is not None
|
||||||
|
|
||||||
|
|
||||||
async def test_get_modules():
|
async def test_get_modules() -> None:
|
||||||
"""Test getting modules for child and parent modules."""
|
"""Test getting modules for child and parent modules."""
|
||||||
dummy_device = await get_device_for_fixture_protocol(
|
dummy_device = await get_device_for_fixture_protocol(
|
||||||
"KS240(US)_1.0_1.0.5.json", "SMART"
|
"KS240(US)_1.0_1.0.5.json", "SMART"
|
||||||
@@ -629,7 +632,9 @@ async def test_get_modules():
|
|||||||
|
|
||||||
|
|
||||||
@device_smart
|
@device_smart
|
||||||
async def test_smartdevice_cloud_connection(dev: SmartDevice, mocker: MockerFixture):
|
async def test_smartdevice_cloud_connection(
|
||||||
|
dev: SmartDevice, mocker: MockerFixture
|
||||||
|
) -> None:
|
||||||
"""Test is_cloud_connected property."""
|
"""Test is_cloud_connected property."""
|
||||||
assert isinstance(dev, SmartDevice)
|
assert isinstance(dev, SmartDevice)
|
||||||
assert "cloud_connect" in dev._components
|
assert "cloud_connect" in dev._components
|
||||||
@@ -697,7 +702,7 @@ async def test_smartdevice_cloud_connection(dev: SmartDevice, mocker: MockerFixt
|
|||||||
|
|
||||||
|
|
||||||
@variable_temp_smart
|
@variable_temp_smart
|
||||||
async def test_smart_temp_range(dev: Device):
|
async def test_smart_temp_range(dev: Device) -> None:
|
||||||
light = dev.modules.get(Module.Light)
|
light = dev.modules.get(Module.Light)
|
||||||
assert light
|
assert light
|
||||||
color_temp_feat = light.get_feature("color_temp")
|
color_temp_feat = light.get_feature("color_temp")
|
||||||
@@ -708,7 +713,7 @@ async def test_smart_temp_range(dev: Device):
|
|||||||
@device_smart
|
@device_smart
|
||||||
async def test_initialize_modules_sysinfo_lookup_keys(
|
async def test_initialize_modules_sysinfo_lookup_keys(
|
||||||
dev: SmartDevice, mocker: MockerFixture
|
dev: SmartDevice, mocker: MockerFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test that matching modules using SYSINFO_LOOKUP_KEYS are initialized correctly."""
|
"""Test that matching modules using SYSINFO_LOOKUP_KEYS are initialized correctly."""
|
||||||
|
|
||||||
class AvailableKey(SmartModule):
|
class AvailableKey(SmartModule):
|
||||||
@@ -737,7 +742,7 @@ async def test_initialize_modules_sysinfo_lookup_keys(
|
|||||||
@device_smart
|
@device_smart
|
||||||
async def test_initialize_modules_required_component(
|
async def test_initialize_modules_required_component(
|
||||||
dev: SmartDevice, mocker: MockerFixture
|
dev: SmartDevice, mocker: MockerFixture
|
||||||
):
|
) -> None:
|
||||||
"""Test that matching modules using REQUIRED_COMPONENT are initialized correctly."""
|
"""Test that matching modules using REQUIRED_COMPONENT are initialized correctly."""
|
||||||
|
|
||||||
class AvailableComponent(SmartModule):
|
class AvailableComponent(SmartModule):
|
||||||
@@ -763,7 +768,7 @@ async def test_initialize_modules_required_component(
|
|||||||
assert "NonExistingComponent" not in dev.modules
|
assert "NonExistingComponent" not in dev.modules
|
||||||
|
|
||||||
|
|
||||||
async def test_smartmodule_query():
|
async def test_smartmodule_query() -> None:
|
||||||
"""Test that a module that doesn't set QUERY_GETTER_NAME has empty query."""
|
"""Test that a module that doesn't set QUERY_GETTER_NAME has empty query."""
|
||||||
|
|
||||||
class DummyModule(SmartModule):
|
class DummyModule(SmartModule):
|
||||||
@@ -779,7 +784,7 @@ async def test_smartmodule_query():
|
|||||||
@hub_all
|
@hub_all
|
||||||
@pytest.mark.xdist_group(name="caplog")
|
@pytest.mark.xdist_group(name="caplog")
|
||||||
@pytest.mark.requires_dummy
|
@pytest.mark.requires_dummy
|
||||||
async def test_dynamic_devices(dev: Device, caplog: pytest.LogCaptureFixture):
|
async def test_dynamic_devices(dev: Device, caplog: pytest.LogCaptureFixture) -> None:
|
||||||
"""Test dynamic child devices."""
|
"""Test dynamic child devices."""
|
||||||
if not dev.children:
|
if not dev.children:
|
||||||
pytest.skip(f"Device {dev.model} does not have children.")
|
pytest.skip(f"Device {dev.model} does not have children.")
|
||||||
@@ -992,7 +997,7 @@ async def test_dynamic_devices(dev: Device, caplog: pytest.LogCaptureFixture):
|
|||||||
|
|
||||||
|
|
||||||
@hubs_smart
|
@hubs_smart
|
||||||
async def test_unpair(dev: SmartDevice, mocker: MockerFixture):
|
async def test_unpair(dev: SmartDevice, mocker: MockerFixture) -> None:
|
||||||
"""Verify that unpair calls childsetup module."""
|
"""Verify that unpair calls childsetup module."""
|
||||||
if not dev.children:
|
if not dev.children:
|
||||||
pytest.skip("device has no children")
|
pytest.skip("device has no children")
|
||||||
|
|||||||
Reference in New Issue
Block a user