tests: add type annotations to CLI, protocol, and smartcam tests (#1687)

Add type annotations (`-> None` return types and parameter types) to
test files in the `tests/cli/`, `tests/protocols/`, and
`tests/smartcam/` directories. This enables mypy to check test function
bodies, catching type errors that were previously hidden.
This commit is contained in:
ZeliardM
2026-07-05 12:46:01 -04:00
committed by GitHub
parent da2588291d
commit 1a84242a05
11 changed files with 255 additions and 138 deletions

View File

@@ -16,7 +16,7 @@ from ...conftest import hub_smartcam
@hub_smartcam
async def test_alarm(dev: Device):
async def test_alarm(dev: Device) -> None:
"""Test device alarm."""
alarm = dev.modules.get(Module.Alarm)
assert alarm
@@ -83,7 +83,7 @@ async def test_alarm(dev: Device):
@hub_smartcam
async def test_alarm_invalid_setters(dev: Device):
async def test_alarm_invalid_setters(dev: Device) -> None:
"""Test device alarm invalid setter values."""
alarm = dev.modules.get(Module.Alarm)
assert alarm
@@ -105,7 +105,7 @@ async def test_alarm_invalid_setters(dev: Device):
@hub_smartcam
async def test_alarm_features(dev: Device):
async def test_alarm_features(dev: Device) -> None:
"""Test device alarm features."""
alarm = dev.modules.get(Module.Alarm)
assert alarm

View File

@@ -17,7 +17,7 @@ battery_smartcam = parametrize(
@battery_smartcam
async def test_battery(dev: Device):
async def test_battery(dev: Device) -> None:
"""Test device battery."""
battery = dev.modules.get(SmartCamModule.SmartCamBattery)
assert battery
@@ -46,7 +46,9 @@ async def test_battery(dev: Device):
("12.3", 12.3), # sanity: happy path
],
)
async def test_battery_temperature_edge_cases(dev: Device, raw, expected):
async def test_battery_temperature_edge_cases(
dev: Device, raw: str | None, expected: float | None
) -> None:
battery = dev.modules.get(SmartCamModule.SmartCamBattery)
assert battery
@@ -63,7 +65,9 @@ async def test_battery_temperature_edge_cases(dev: Device, raw, expected):
("12000", 12.0), # sanity: parses string -> float(...) / 1000
],
)
async def test_battery_voltage_edge_cases(dev: Device, voltage_raw, expected_v):
async def test_battery_voltage_edge_cases(
dev: Device, voltage_raw: str | None, expected_v: float | None
) -> None:
battery = dev.modules.get(SmartCamModule.SmartCamBattery)
assert battery
@@ -82,7 +86,9 @@ async def test_battery_voltage_edge_cases(dev: Device, voltage_raw, expected_v):
("NO", False), # sanity: string normalization path
],
)
async def test_battery_charging_edge_cases(dev: Device, charging_raw, expected):
async def test_battery_charging_edge_cases(
dev: Device, charging_raw: bool | str | None, expected: bool
) -> None:
battery = dev.modules.get(SmartCamModule.SmartCamBattery)
assert battery

View File

@@ -20,7 +20,7 @@ not_child_camera_smartcam = parametrize(
@device_smartcam
async def test_state(dev: Device):
async def test_state(dev: Device) -> None:
if dev.device_type is DeviceType.Hub:
pytest.skip("Hubs cannot be switched on and off")
@@ -31,7 +31,7 @@ async def test_state(dev: Device):
@not_child_camera_smartcam
async def test_stream_rtsp_url(dev: Device):
async def test_stream_rtsp_url(dev: Device) -> None:
camera_module = dev.modules.get(Module.Camera)
assert camera_module
@@ -91,7 +91,7 @@ async def test_stream_rtsp_url(dev: Device):
@not_child_camera_smartcam
async def test_onvif_url(dev: Device):
async def test_onvif_url(dev: Device) -> None:
"""Test the onvif url."""
camera_module = dev.modules.get(Module.Camera)
assert camera_module

View File

@@ -15,7 +15,7 @@ childsetup = parametrize(
@childsetup
async def test_childsetup_features(dev: Device):
async def test_childsetup_features(dev: Device) -> None:
"""Test the exposed features."""
cs = dev.modules[Module.ChildSetup]
@@ -27,7 +27,7 @@ async def test_childsetup_features(dev: Device):
@childsetup
async def test_childsetup_pair(
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
):
) -> None:
"""Test device pairing."""
caplog.set_level(logging.INFO)
mock_query_helper = mocker.spy(dev, "_query_helper")
@@ -70,7 +70,7 @@ async def test_childsetup_pair(
@childsetup
async def test_childsetup_unpair(
dev: Device, mocker: MockerFixture, caplog: pytest.LogCaptureFixture
):
) -> None:
"""Test unpair."""
mock_query_helper = mocker.spy(dev, "_query_helper")
DUMMY_ID = "dummy_id"

View File

@@ -25,8 +25,8 @@ class Detection(NamedTuple):
def parametrize_detection(
*,
model_filter=None,
protocol_filter=None,
fixture_name="dev",
protocol_filter: set[str] | None = None,
fixture_name: str = "dev",
extra_params_names: list[str],
extra_params_values: list[Detection],
):
@@ -139,7 +139,7 @@ params_detections = parametrize_detection(
@params_detections
async def test_detections(
dev: Device, module: ModuleName[DetectionModule], feature_name: str
):
) -> None:
detection = dev.modules.get(module)
assert detection

View File

@@ -15,7 +15,7 @@ pantilt = parametrize(
@pantilt
async def test_pantilt_presets(dev: Device, mocker: MockerFixture):
async def test_pantilt_presets(dev: Device, mocker: MockerFixture) -> None:
"""Test PanTilt module preset functionality."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -42,7 +42,7 @@ async def test_pantilt_presets(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_save_preset(dev: Device, mocker: MockerFixture):
async def test_pantilt_save_preset(dev: Device, mocker: MockerFixture) -> None:
"""Test PanTilt save_preset functionality."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -62,7 +62,7 @@ async def test_pantilt_save_preset(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_invalid_preset(dev: Device, mocker: MockerFixture):
async def test_pantilt_invalid_preset(dev: Device, mocker: MockerFixture) -> None:
"""Test set_preset with invalid preset name raises ValueError."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -81,7 +81,7 @@ async def test_pantilt_invalid_preset(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_move(dev: Device, mocker: MockerFixture):
async def test_pantilt_move(dev: Device, mocker: MockerFixture) -> None:
"""Test PanTilt move commands."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -103,7 +103,7 @@ async def test_pantilt_move(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_goto_preset(dev: Device, mocker: MockerFixture):
async def test_pantilt_goto_preset(dev: Device, mocker: MockerFixture) -> None:
"""Test PanTilt goto_preset command."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -119,7 +119,7 @@ async def test_pantilt_goto_preset(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_get_presets(dev: Device, mocker: MockerFixture):
async def test_pantilt_get_presets(dev: Device, mocker: MockerFixture) -> None:
"""Test PanTilt get_presets command."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -135,7 +135,7 @@ async def test_pantilt_get_presets(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_set_preset_by_id(dev: Device, mocker: MockerFixture):
async def test_pantilt_set_preset_by_id(dev: Device, mocker: MockerFixture) -> None:
"""Test set_preset with preset ID instead of name."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -160,7 +160,7 @@ async def test_pantilt_set_preset_by_id(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_set_preset_not_found(dev: Device, mocker: MockerFixture):
async def test_pantilt_set_preset_not_found(dev: Device, mocker: MockerFixture) -> None:
"""Test set_preset with non-existent preset returns empty dict."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -177,7 +177,7 @@ async def test_pantilt_set_preset_not_found(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_step_features(dev: Device, mocker: MockerFixture):
async def test_pantilt_step_features(dev: Device, mocker: MockerFixture) -> None:
"""Test pan/tilt step features."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None
@@ -200,7 +200,7 @@ async def test_pantilt_step_features(dev: Device, mocker: MockerFixture):
@pantilt
async def test_pantilt_no_presets_in_data(dev: Device, mocker: MockerFixture):
async def test_pantilt_no_presets_in_data(dev: Device, mocker: MockerFixture) -> None:
"""Test _presets returns empty dict when no preset data."""
pantilt_mod = dev.modules.get(Module.PanTilt)
assert pantilt_mod is not None

View File

@@ -17,7 +17,7 @@ from ..conftest import device_smartcam, hub_smartcam
@device_smartcam
async def test_state(dev: Device):
async def test_state(dev: Device) -> None:
if dev.device_type is DeviceType.Hub:
pytest.skip("Hubs cannot be switched on and off")
@@ -38,7 +38,7 @@ async def test_state(dev: Device):
@device_smartcam
async def test_alias(dev: Device):
async def test_alias(dev: Device) -> None:
test_alias = "TEST1234"
original = dev.alias
@@ -53,7 +53,7 @@ async def test_alias(dev: Device):
@hub_smartcam
async def test_hub(dev: Device):
async def test_hub(dev: Device) -> None:
assert dev.children
for child in dev.children:
assert child.modules
@@ -65,7 +65,7 @@ async def test_hub(dev: Device):
@device_smartcam
async def test_wifi_scan(dev: SmartCamDevice):
async def test_wifi_scan(dev: SmartCamDevice) -> None:
fake_scan_data = {
"scanApList": {
"onboarding": {
@@ -97,7 +97,7 @@ async def test_wifi_scan(dev: SmartCamDevice):
@device_smartcam
async def test_wifi_join_success_and_errors(dev: SmartCamDevice):
async def test_wifi_join_success_and_errors(dev: SmartCamDevice) -> None:
dev._networks = [
type(
"WifiNetwork",
@@ -154,7 +154,7 @@ async def test_wifi_join_success_and_errors(dev: SmartCamDevice):
@device_smartcam
async def test_device_time(dev: Device, freezer: FrozenDateTimeFactory):
async def test_device_time(dev: Device, freezer: FrozenDateTimeFactory) -> None:
"""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
@@ -165,7 +165,7 @@ async def test_device_time(dev: Device, freezer: FrozenDateTimeFactory):
@device_smartcam
async def test_wifi_join_typeerror_on_non_rsa_key(dev: SmartCamDevice):
async def test_wifi_join_typeerror_on_non_rsa_key(dev: SmartCamDevice) -> None:
dev._networks = [
type(
"WifiNetwork",