mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-25 12:33:34 +00:00
fe0bbf1b98
Removes the logic to expose child modules on parent devices, which could cause complications with downstream consumers unknowingly duplicating things.
244 lines
7.3 KiB
Python
244 lines
7.3 KiB
Python
import pytest
|
|
from pytest_mock import MockerFixture
|
|
|
|
from kasa import Device, LightState, Module
|
|
from kasa.tests.device_fixtures import (
|
|
bulb_iot,
|
|
bulb_smart,
|
|
dimmable_iot,
|
|
dimmer_iot,
|
|
get_parent_and_child_modules,
|
|
lightstrip_iot,
|
|
parametrize,
|
|
parametrize_combine,
|
|
plug_iot,
|
|
)
|
|
|
|
led_smart = parametrize(
|
|
"has led smart", component_filter="led", protocol_filter={"SMART"}
|
|
)
|
|
led = parametrize_combine([led_smart, plug_iot])
|
|
|
|
light_effect_smart = parametrize(
|
|
"has light effect smart", component_filter="light_effect", protocol_filter={"SMART"}
|
|
)
|
|
light_strip_effect_smart = parametrize(
|
|
"has light strip effect smart",
|
|
component_filter="light_strip_lighting_effect",
|
|
protocol_filter={"SMART"},
|
|
)
|
|
light_effect = parametrize_combine(
|
|
[light_effect_smart, light_strip_effect_smart, lightstrip_iot]
|
|
)
|
|
|
|
dimmable_smart = parametrize(
|
|
"dimmable smart", component_filter="brightness", protocol_filter={"SMART"}
|
|
)
|
|
dimmable = parametrize_combine([dimmable_smart, dimmer_iot, dimmable_iot])
|
|
|
|
light_preset_smart = parametrize(
|
|
"has light preset smart", component_filter="preset", protocol_filter={"SMART"}
|
|
)
|
|
|
|
light_preset = parametrize_combine([light_preset_smart, bulb_iot])
|
|
|
|
light = parametrize_combine([bulb_smart, bulb_iot, dimmable])
|
|
|
|
|
|
@led
|
|
async def test_led_module(dev: Device, mocker: MockerFixture):
|
|
"""Test fan speed feature."""
|
|
led_module = dev.modules.get(Module.Led)
|
|
assert led_module
|
|
feat = dev.features["led"]
|
|
|
|
call = mocker.spy(led_module, "call")
|
|
await led_module.set_led(True)
|
|
assert call.call_count == 1
|
|
await dev.update()
|
|
assert led_module.led is True
|
|
assert feat.value is True
|
|
|
|
await led_module.set_led(False)
|
|
assert call.call_count == 2
|
|
await dev.update()
|
|
assert led_module.led is False
|
|
assert feat.value is False
|
|
|
|
await feat.set_value(True)
|
|
assert call.call_count == 3
|
|
await dev.update()
|
|
assert feat.value is True
|
|
assert led_module.led is True
|
|
|
|
|
|
@light_effect
|
|
async def test_light_effect_module(dev: Device, mocker: MockerFixture):
|
|
"""Test fan speed feature."""
|
|
light_effect_module = dev.modules[Module.LightEffect]
|
|
assert light_effect_module
|
|
feat = dev.features["light_effect"]
|
|
|
|
call = mocker.spy(dev, "_query_helper")
|
|
effect_list = light_effect_module.effect_list
|
|
assert "Off" in effect_list
|
|
assert effect_list.index("Off") == 0
|
|
assert len(effect_list) > 1
|
|
assert effect_list == feat.choices
|
|
|
|
assert light_effect_module.has_custom_effects is not None
|
|
|
|
await light_effect_module.set_effect("Off")
|
|
assert call.call_count == 1
|
|
await dev.update()
|
|
assert light_effect_module.effect == "Off"
|
|
assert feat.value == "Off"
|
|
|
|
second_effect = effect_list[1]
|
|
await light_effect_module.set_effect(second_effect)
|
|
assert call.call_count == 2
|
|
await dev.update()
|
|
assert light_effect_module.effect == second_effect
|
|
assert feat.value == second_effect
|
|
|
|
last_effect = effect_list[len(effect_list) - 1]
|
|
await light_effect_module.set_effect(last_effect)
|
|
assert call.call_count == 3
|
|
await dev.update()
|
|
assert light_effect_module.effect == last_effect
|
|
assert feat.value == last_effect
|
|
|
|
# Test feature set
|
|
await feat.set_value(second_effect)
|
|
assert call.call_count == 4
|
|
await dev.update()
|
|
assert light_effect_module.effect == second_effect
|
|
assert feat.value == second_effect
|
|
|
|
with pytest.raises(ValueError):
|
|
await light_effect_module.set_effect("foobar")
|
|
assert call.call_count == 4
|
|
|
|
|
|
@dimmable
|
|
async def test_light_brightness(dev: Device):
|
|
"""Test brightness setter and getter."""
|
|
assert isinstance(dev, Device)
|
|
light = next(get_parent_and_child_modules(dev, Module.Light))
|
|
assert light
|
|
|
|
# Test getting the value
|
|
feature = light._device.features["brightness"]
|
|
assert feature.minimum_value == 0
|
|
assert feature.maximum_value == 100
|
|
|
|
await light.set_brightness(10)
|
|
await dev.update()
|
|
assert light.brightness == 10
|
|
|
|
with pytest.raises(ValueError):
|
|
await light.set_brightness(feature.minimum_value - 10)
|
|
|
|
with pytest.raises(ValueError):
|
|
await light.set_brightness(feature.maximum_value + 10)
|
|
|
|
|
|
@light
|
|
async def test_light_set_state(dev: Device):
|
|
"""Test brightness setter and getter."""
|
|
assert isinstance(dev, Device)
|
|
light = next(get_parent_and_child_modules(dev, Module.Light))
|
|
assert light
|
|
|
|
await light.set_state(LightState(light_on=False))
|
|
await dev.update()
|
|
assert light.state.light_on is False
|
|
|
|
await light.set_state(LightState(light_on=True))
|
|
await dev.update()
|
|
assert light.state.light_on is True
|
|
|
|
await light.set_state(LightState(brightness=0))
|
|
await dev.update()
|
|
assert light.state.light_on is False
|
|
|
|
await light.set_state(LightState(brightness=50))
|
|
await dev.update()
|
|
assert light.state.light_on is True
|
|
|
|
|
|
@light_preset
|
|
async def test_light_preset_module(dev: Device, mocker: MockerFixture):
|
|
"""Test light preset module."""
|
|
preset_mod = next(get_parent_and_child_modules(dev, Module.LightPreset))
|
|
assert preset_mod
|
|
light_mod = next(get_parent_and_child_modules(dev, Module.Light))
|
|
assert light_mod
|
|
feat = preset_mod._device.features["light_preset"]
|
|
|
|
preset_list = preset_mod.preset_list
|
|
assert "Not set" in preset_list
|
|
assert preset_list.index("Not set") == 0
|
|
assert preset_list == feat.choices
|
|
|
|
assert preset_mod.has_save_preset is True
|
|
|
|
await light_mod.set_brightness(33) # Value that should not be a preset
|
|
await dev.update()
|
|
assert preset_mod.preset == "Not set"
|
|
assert feat.value == "Not set"
|
|
|
|
if len(preset_list) == 1:
|
|
return
|
|
|
|
call = mocker.spy(light_mod, "set_state")
|
|
second_preset = preset_list[1]
|
|
await preset_mod.set_preset(second_preset)
|
|
assert call.call_count == 1
|
|
await dev.update()
|
|
assert preset_mod.preset == second_preset
|
|
assert feat.value == second_preset
|
|
|
|
last_preset = preset_list[len(preset_list) - 1]
|
|
await preset_mod.set_preset(last_preset)
|
|
assert call.call_count == 2
|
|
await dev.update()
|
|
assert preset_mod.preset == last_preset
|
|
assert feat.value == last_preset
|
|
|
|
# Test feature set
|
|
await feat.set_value(second_preset)
|
|
assert call.call_count == 3
|
|
await dev.update()
|
|
assert preset_mod.preset == second_preset
|
|
assert feat.value == second_preset
|
|
|
|
with pytest.raises(ValueError):
|
|
await preset_mod.set_preset("foobar")
|
|
assert call.call_count == 3
|
|
|
|
|
|
@light_preset
|
|
async def test_light_preset_save(dev: Device, mocker: MockerFixture):
|
|
"""Test saving a new preset value."""
|
|
preset_mod = next(get_parent_and_child_modules(dev, Module.LightPreset))
|
|
assert preset_mod
|
|
preset_list = preset_mod.preset_list
|
|
if len(preset_list) == 1:
|
|
return
|
|
|
|
second_preset = preset_list[1]
|
|
if preset_mod.preset_states_list[0].hue is None:
|
|
new_preset = LightState(brightness=52)
|
|
else:
|
|
new_preset = LightState(brightness=52, color_temp=3000, hue=20, saturation=30)
|
|
await preset_mod.save_preset(second_preset, new_preset)
|
|
await dev.update()
|
|
new_preset_state = preset_mod.preset_states_list[0]
|
|
assert (
|
|
new_preset_state.brightness == new_preset.brightness
|
|
and new_preset_state.hue == new_preset.hue
|
|
and new_preset_state.saturation == new_preset.saturation
|
|
and new_preset_state.color_temp == new_preset.color_temp
|
|
)
|