mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 10:44:04 +00:00
Update cli to use common modules and remove iot specific cli testing (#913)
This commit is contained in:
@@ -13,6 +13,7 @@ from kasa import (
|
||||
DeviceError,
|
||||
EmeterStatus,
|
||||
KasaException,
|
||||
Module,
|
||||
UnsupportedDeviceError,
|
||||
)
|
||||
from kasa.cli import (
|
||||
@@ -21,11 +22,15 @@ from kasa.cli import (
|
||||
brightness,
|
||||
cli,
|
||||
cmd_command,
|
||||
effect,
|
||||
emeter,
|
||||
hsv,
|
||||
led,
|
||||
raw_command,
|
||||
reboot,
|
||||
state,
|
||||
sysinfo,
|
||||
temperature,
|
||||
toggle,
|
||||
update_credentials,
|
||||
wifi,
|
||||
@@ -34,7 +39,6 @@ from kasa.discover import Discover, DiscoveryResult
|
||||
from kasa.iot import IotDevice
|
||||
|
||||
from .conftest import (
|
||||
device_iot,
|
||||
device_smart,
|
||||
get_device_for_fixture_protocol,
|
||||
handle_turn_on,
|
||||
@@ -78,11 +82,10 @@ async def test_update_called_by_cli(dev, mocker, runner):
|
||||
update.assert_called()
|
||||
|
||||
|
||||
@device_iot
|
||||
async def test_sysinfo(dev, runner):
|
||||
async def test_sysinfo(dev: Device, runner):
|
||||
res = await runner.invoke(sysinfo, obj=dev)
|
||||
assert "System info" in res.output
|
||||
assert dev.alias in res.output
|
||||
assert dev.model in res.output
|
||||
|
||||
|
||||
@turn_on
|
||||
@@ -108,7 +111,6 @@ async def test_toggle(dev, turn_on, runner):
|
||||
assert dev.is_on != turn_on
|
||||
|
||||
|
||||
@device_iot
|
||||
async def test_alias(dev, runner):
|
||||
res = await runner.invoke(alias, obj=dev)
|
||||
assert f"Alias: {dev.alias}" in res.output
|
||||
@@ -308,15 +310,14 @@ async def test_emeter(dev: Device, mocker, runner):
|
||||
daily.assert_called_with(year=1900, month=12)
|
||||
|
||||
|
||||
@device_iot
|
||||
async def test_brightness(dev, runner):
|
||||
async def test_brightness(dev: Device, runner):
|
||||
res = await runner.invoke(brightness, obj=dev)
|
||||
if not dev.is_dimmable:
|
||||
if not (light := dev.modules.get(Module.Light)) or not light.is_dimmable:
|
||||
assert "This device does not support brightness." in res.output
|
||||
return
|
||||
|
||||
res = await runner.invoke(brightness, obj=dev)
|
||||
assert f"Brightness: {dev.brightness}" in res.output
|
||||
assert f"Brightness: {light.brightness}" in res.output
|
||||
|
||||
res = await runner.invoke(brightness, ["12"], obj=dev)
|
||||
assert "Setting brightness" in res.output
|
||||
@@ -326,7 +327,110 @@ async def test_brightness(dev, runner):
|
||||
assert "Brightness: 12" in res.output
|
||||
|
||||
|
||||
@device_iot
|
||||
async def test_color_temperature(dev: Device, runner):
|
||||
res = await runner.invoke(temperature, obj=dev)
|
||||
if not (light := dev.modules.get(Module.Light)) or not light.is_variable_color_temp:
|
||||
assert "Device does not support color temperature" in res.output
|
||||
return
|
||||
|
||||
res = await runner.invoke(temperature, obj=dev)
|
||||
assert f"Color temperature: {light.color_temp}" in res.output
|
||||
valid_range = light.valid_temperature_range
|
||||
assert f"(min: {valid_range.min}, max: {valid_range.max})" in res.output
|
||||
|
||||
val = int((valid_range.min + valid_range.max) / 2)
|
||||
res = await runner.invoke(temperature, [str(val)], obj=dev)
|
||||
assert "Setting color temperature to " in res.output
|
||||
await dev.update()
|
||||
|
||||
res = await runner.invoke(temperature, obj=dev)
|
||||
assert f"Color temperature: {val}" in res.output
|
||||
assert res.exit_code == 0
|
||||
|
||||
invalid_max = valid_range.max + 100
|
||||
# Lights that support the maximum range will not get past the click cli range check
|
||||
# So can't be tested for the internal range check.
|
||||
if invalid_max < 9000:
|
||||
res = await runner.invoke(temperature, [str(invalid_max)], obj=dev)
|
||||
assert res.exit_code == 1
|
||||
assert isinstance(res.exception, ValueError)
|
||||
|
||||
res = await runner.invoke(temperature, [str(9100)], obj=dev)
|
||||
assert res.exit_code == 2
|
||||
|
||||
|
||||
async def test_color_hsv(dev: Device, runner: CliRunner):
|
||||
res = await runner.invoke(hsv, obj=dev)
|
||||
if not (light := dev.modules.get(Module.Light)) or not light.is_color:
|
||||
assert "Device does not support colors" in res.output
|
||||
return
|
||||
|
||||
res = await runner.invoke(hsv, obj=dev)
|
||||
assert f"Current HSV: {light.hsv}" in res.output
|
||||
|
||||
res = await runner.invoke(hsv, ["180", "50", "50"], obj=dev)
|
||||
assert "Setting HSV: 180 50 50" in res.output
|
||||
assert res.exit_code == 0
|
||||
await dev.update()
|
||||
|
||||
res = await runner.invoke(hsv, ["180", "50"], obj=dev)
|
||||
assert "Setting a color requires 3 values." in res.output
|
||||
assert res.exit_code == 2
|
||||
|
||||
|
||||
async def test_light_effect(dev: Device, runner: CliRunner):
|
||||
res = await runner.invoke(effect, obj=dev)
|
||||
if not (light_effect := dev.modules.get(Module.LightEffect)):
|
||||
assert "Device does not support effects" in res.output
|
||||
return
|
||||
|
||||
# Start off with a known state of off
|
||||
await light_effect.set_effect(light_effect.LIGHT_EFFECTS_OFF)
|
||||
await dev.update()
|
||||
assert light_effect.effect == light_effect.LIGHT_EFFECTS_OFF
|
||||
|
||||
res = await runner.invoke(effect, obj=dev)
|
||||
msg = (
|
||||
"Setting an effect requires a named built-in effect: "
|
||||
+ f"{light_effect.effect_list}"
|
||||
)
|
||||
assert msg in res.output
|
||||
assert res.exit_code == 2
|
||||
|
||||
res = await runner.invoke(effect, [light_effect.effect_list[1]], obj=dev)
|
||||
assert f"Setting Effect: {light_effect.effect_list[1]}" in res.output
|
||||
assert res.exit_code == 0
|
||||
await dev.update()
|
||||
assert light_effect.effect == light_effect.effect_list[1]
|
||||
|
||||
res = await runner.invoke(effect, ["foobar"], obj=dev)
|
||||
assert f"Effect must be one of: {light_effect.effect_list}" in res.output
|
||||
assert res.exit_code == 2
|
||||
|
||||
|
||||
async def test_led(dev: Device, runner: CliRunner):
|
||||
res = await runner.invoke(led, obj=dev)
|
||||
if not (led_module := dev.modules.get(Module.Led)):
|
||||
assert "Device does not support led" in res.output
|
||||
return
|
||||
|
||||
res = await runner.invoke(led, obj=dev)
|
||||
assert f"LED state: {led_module.led}" in res.output
|
||||
assert res.exit_code == 0
|
||||
|
||||
res = await runner.invoke(led, ["on"], obj=dev)
|
||||
assert "Turning led to True" in res.output
|
||||
assert res.exit_code == 0
|
||||
await dev.update()
|
||||
assert led_module.led is True
|
||||
|
||||
res = await runner.invoke(led, ["off"], obj=dev)
|
||||
assert "Turning led to False" in res.output
|
||||
assert res.exit_code == 0
|
||||
await dev.update()
|
||||
assert led_module.led is False
|
||||
|
||||
|
||||
async def test_json_output(dev: Device, mocker, runner):
|
||||
"""Test that the json output produces correct output."""
|
||||
mocker.patch("kasa.Discover.discover", return_value={"127.0.0.1": dev})
|
||||
@@ -375,7 +479,6 @@ async def test_credentials(discovery_mock, mocker, runner):
|
||||
assert "Username:foo Password:bar\n" in res.output
|
||||
|
||||
|
||||
@device_iot
|
||||
async def test_without_device_type(dev, mocker, runner):
|
||||
"""Test connecting without the device type."""
|
||||
discovery_mock = mocker.patch(
|
||||
|
Reference in New Issue
Block a user