Rename tests/smartcamera to tests/smartcam (#1315)

This commit is contained in:
Steven B.
2024-11-26 11:36:30 +00:00
committed by GitHub
parent 0c755f7120
commit 6c42b36865
4 changed files with 0 additions and 0 deletions

View File

View File

View File

@@ -0,0 +1,159 @@
"""Tests for smart camera devices."""
from __future__ import annotations
import pytest
from kasa import Device
from kasa.smartcam.modules.alarm import (
DURATION_MAX,
DURATION_MIN,
VOLUME_MAX,
VOLUME_MIN,
)
from kasa.smartcam.smartcammodule import SmartCamModule
from ...conftest import hub_smartcam
@hub_smartcam
async def test_alarm(dev: Device):
"""Test device alarm."""
alarm = dev.modules.get(SmartCamModule.SmartCamAlarm)
assert alarm
original_duration = alarm.alarm_duration
assert original_duration is not None
original_volume = alarm.alarm_volume
assert original_volume is not None
original_sound = alarm.alarm_sound
try:
# test volume
new_volume = original_volume - 1 if original_volume > 1 else original_volume + 1
await alarm.set_alarm_volume(new_volume) # type: ignore[arg-type]
await dev.update()
assert alarm.alarm_volume == new_volume
# test duration
new_duration = (
original_duration - 1 if original_duration > 1 else original_duration + 1
)
await alarm.set_alarm_duration(new_duration)
await dev.update()
assert alarm.alarm_duration == new_duration
# test start
await alarm.play()
await dev.update()
assert alarm.active
# test stop
await alarm.stop()
await dev.update()
assert not alarm.active
# test set sound
new_sound = (
alarm.alarm_sounds[0]
if alarm.alarm_sound != alarm.alarm_sounds[0]
else alarm.alarm_sounds[1]
)
await alarm.set_alarm_sound(new_sound)
await dev.update()
assert alarm.alarm_sound == new_sound
finally:
await alarm.set_alarm_volume(original_volume)
await alarm.set_alarm_duration(original_duration)
await alarm.set_alarm_sound(original_sound)
await dev.update()
@hub_smartcam
async def test_alarm_invalid_setters(dev: Device):
"""Test device alarm invalid setter values."""
alarm = dev.modules.get(SmartCamModule.SmartCamAlarm)
assert alarm
# test set sound invalid
msg = f"sound must be one of {', '.join(alarm.alarm_sounds)}: foobar"
with pytest.raises(ValueError, match=msg):
await alarm.set_alarm_sound("foobar")
# test volume invalid
msg = f"volume must be between {VOLUME_MIN} and {VOLUME_MAX}"
with pytest.raises(ValueError, match=msg):
await alarm.set_alarm_volume(-3)
# test duration invalid
msg = f"duration must be between {DURATION_MIN} and {DURATION_MAX}"
with pytest.raises(ValueError, match=msg):
await alarm.set_alarm_duration(-3)
@hub_smartcam
async def test_alarm_features(dev: Device):
"""Test device alarm features."""
alarm = dev.modules.get(SmartCamModule.SmartCamAlarm)
assert alarm
original_duration = alarm.alarm_duration
assert original_duration is not None
original_volume = alarm.alarm_volume
assert original_volume is not None
original_sound = alarm.alarm_sound
try:
# test volume
new_volume = original_volume - 1 if original_volume > 1 else original_volume + 1
feature = dev.features.get("alarm_volume")
assert feature
await feature.set_value(new_volume) # type: ignore[arg-type]
await dev.update()
assert feature.value == new_volume
# test duration
feature = dev.features.get("alarm_duration")
assert feature
new_duration = (
original_duration - 1 if original_duration > 1 else original_duration + 1
)
await feature.set_value(new_duration)
await dev.update()
assert feature.value == new_duration
# test start
feature = dev.features.get("test_alarm")
assert feature
await feature.set_value(None)
await dev.update()
feature = dev.features.get("alarm")
assert feature
assert feature.value is True
# test stop
feature = dev.features.get("stop_alarm")
assert feature
await feature.set_value(None)
await dev.update()
assert dev.features["alarm"].value is False
# test set sound
feature = dev.features.get("alarm_sound")
assert feature
new_sound = (
alarm.alarm_sounds[0]
if alarm.alarm_sound != alarm.alarm_sounds[0]
else alarm.alarm_sounds[1]
)
await feature.set_value(new_sound)
await alarm.set_alarm_sound(new_sound)
await dev.update()
assert feature.value == new_sound
finally:
await alarm.set_alarm_volume(original_volume)
await alarm.set_alarm_duration(original_duration)
await alarm.set_alarm_sound(original_sound)
await dev.update()

View File

@@ -0,0 +1,123 @@
"""Tests for smart camera devices."""
from __future__ import annotations
import base64
import json
from datetime import UTC, datetime
from unittest.mock import patch
import pytest
from freezegun.api import FrozenDateTimeFactory
from kasa import Credentials, Device, DeviceType, Module
from ..conftest import camera_smartcam, device_smartcam, hub_smartcam
@device_smartcam
async def test_state(dev: Device):
if dev.device_type is DeviceType.Hub:
pytest.skip("Hubs cannot be switched on and off")
state = dev.is_on
await dev.set_state(not state)
await dev.update()
assert dev.is_on is not state
@camera_smartcam
async def test_stream_rtsp_url(dev: Device):
camera_module = dev.modules.get(Module.Camera)
assert camera_module
await camera_module.set_state(True)
await dev.update()
assert camera_module.is_on
url = camera_module.stream_rtsp_url(Credentials("foo", "bar"))
assert url == "rtsp://foo:bar@127.0.0.123:554/stream1"
with patch.object(dev.config, "credentials", Credentials("bar", "foo")):
url = camera_module.stream_rtsp_url()
assert url == "rtsp://bar:foo@127.0.0.123:554/stream1"
with patch.object(dev.config, "credentials", Credentials("bar", "")):
url = camera_module.stream_rtsp_url()
assert url is None
with patch.object(dev.config, "credentials", Credentials("", "Foo")):
url = camera_module.stream_rtsp_url()
assert url is None
# Test with credentials_hash
cred = json.dumps({"un": "bar", "pwd": "foobar"})
cred_hash = base64.b64encode(cred.encode()).decode()
with (
patch.object(dev.config, "credentials", None),
patch.object(dev.config, "credentials_hash", cred_hash),
):
url = camera_module.stream_rtsp_url()
assert url == "rtsp://bar:foobar@127.0.0.123:554/stream1"
# Test with invalid credentials_hash
with (
patch.object(dev.config, "credentials", None),
patch.object(dev.config, "credentials_hash", b"238472871"),
):
url = camera_module.stream_rtsp_url()
assert url is None
# Test with no credentials
with (
patch.object(dev.config, "credentials", None),
patch.object(dev.config, "credentials_hash", None),
):
url = camera_module.stream_rtsp_url()
assert url is None
# Test with camera off
await camera_module.set_state(False)
await dev.update()
url = camera_module.stream_rtsp_url(Credentials("foo", "bar"))
assert url is None
with patch.object(dev.config, "credentials", Credentials("bar", "foo")):
url = camera_module.stream_rtsp_url()
assert url is None
@device_smartcam
async def test_alias(dev):
test_alias = "TEST1234"
original = dev.alias
assert isinstance(original, str)
await dev.set_alias(test_alias)
await dev.update()
assert dev.alias == test_alias
await dev.set_alias(original)
await dev.update()
assert dev.alias == original
@hub_smartcam
async def test_hub(dev):
assert dev.children
for child in dev.children:
assert "Cloud" in child.modules
assert child.modules["Cloud"].data
assert child.alias
await child.update()
assert "Time" not in child.modules
assert child.time
@device_smartcam
async def test_device_time(dev: Device, freezer: FrozenDateTimeFactory):
"""Test a child device gets the time from it's parent module."""
fallback_time = datetime.now(UTC).astimezone().replace(microsecond=0)
assert dev.time != fallback_time
module = dev.modules[Module.Time]
await module.set_time(fallback_time)
await dev.update()
assert dev.time == fallback_time