docs: add project description and server setup instructions to README

This commit is contained in:
2026-03-21 18:25:35 +00:00
parent c81815a83d
commit 6115a065c7
36 changed files with 4003 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
"""
Tests for the in-memory DeviceStore.
"""
from __future__ import annotations
import asyncio
import pytest
from app.device_store import DeviceStore, SensorReading
@pytest.mark.asyncio
async def test_get_all_devices(store: DeviceStore):
"""All registered devices are returned."""
devices = await store.get_all_devices()
assert len(devices) == 3
@pytest.mark.asyncio
async def test_get_enabled_devices(store: DeviceStore):
"""Only enabled devices are returned."""
devices = await store.get_enabled_devices()
assert len(devices) == 2
ids = {d.config.id for d in devices}
assert "test-disabled" not in ids
@pytest.mark.asyncio
async def test_get_device_by_id(store: DeviceStore):
"""Lookup by device ID."""
device = await store.get_device("test-plant-01")
assert device is not None
assert device.config.name == "Test Plant"
missing = await store.get_device("nonexistent")
assert missing is None
@pytest.mark.asyncio
async def test_get_device_by_ip(store: DeviceStore):
"""Lookup by IP address."""
device = await store.get_device_by_ip("192.168.1.100")
assert device is not None
assert device.config.id == "test-plant-01"
@pytest.mark.asyncio
async def test_update_reading(store: DeviceStore):
"""Recording a reading updates value and marks device online."""
await store.update_reading("test-plant-01", "sensors/soil_moisture", 42.5, "percent")
device = await store.get_device("test-plant-01")
assert device.online is True
assert "sensors/soil_moisture" in device.readings
assert device.readings["sensors/soil_moisture"].value == 42.5
assert device.readings["sensors/soil_moisture"].unit == "percent"
@pytest.mark.asyncio
async def test_update_reading_unknown_device(store: DeviceStore):
"""Readings for unknown devices are silently ignored."""
await store.update_reading("unknown-device", "sensors/x", 99, "unit")
device = await store.get_device("unknown-device")
assert device is None
@pytest.mark.asyncio
async def test_mark_offline(store: DeviceStore):
"""Marking offline sets flag and marks readings stale."""
await store.update_reading("test-plant-01", "sensors/temperature", 24.0, "celsius")
await store.mark_offline("test-plant-01")
device = await store.get_device("test-plant-01")
assert device.online is False
assert device.readings["sensors/temperature"].stale is True
@pytest.mark.asyncio
async def test_mark_online(store: DeviceStore):
"""Marking online resets the flag."""
await store.mark_offline("test-plant-01")
await store.mark_online("test-plant-01")
device = await store.get_device("test-plant-01")
assert device.online is True
@pytest.mark.asyncio
async def test_snapshot(store: DeviceStore):
"""Snapshot returns a serializable dict of all devices."""
await store.update_reading("test-plant-01", "sensors/temperature", 23.5, "celsius")
snap = await store.snapshot()
assert "test-plant-01" in snap
assert snap["test-plant-01"]["readings"]["sensors/temperature"]["value"] == 23.5
def test_sensor_reading_age():
"""SensorReading.age_seconds returns meaningful values."""
import time
reading = SensorReading(value=42, unit="percent", timestamp=time.time() - 10)
assert 9.5 < reading.age_seconds() < 11.0
stale = SensorReading(value=0, timestamp=0)
assert stale.age_seconds() == float("inf")