0b4f739d12
- FastAPI server with audio mixer (Windows + Voicemeeter), media tracking, notifications (progress + alerts), telemetry, and system tray .exe build - Test suite covering notifications, audio mixer, media, telemetry, and API - E-Ink web client (vanilla JS, DOM API, block meters, swipe gestures) - Android WebView APK for BOOX Go 7 Color Gen II (Android 13, Kotlin) - Design decision records in .pi/docs/design/ - PyInstaller build script for server .exe
121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
"""Tests for the notification system."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from ..notifications import Notification, NotificationManager, ProgressState
|
|
|
|
|
|
@pytest.fixture
|
|
def manager() -> NotificationManager:
|
|
return NotificationManager()
|
|
|
|
|
|
class TestNotificationCreation:
|
|
@pytest.mark.asyncio
|
|
async def test_create_alert(self, manager: NotificationManager) -> None:
|
|
notif = Notification(
|
|
type="alert",
|
|
title="Build Complete",
|
|
message="Deployment succeeded.",
|
|
priority="info",
|
|
)
|
|
result = await manager.create(notif)
|
|
assert result.id
|
|
assert result.type == "alert"
|
|
assert result.title == "Build Complete"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_progress(self, manager: NotificationManager) -> None:
|
|
notif = Notification(
|
|
type="progress",
|
|
title="Backup",
|
|
message="Uploading...",
|
|
progress=ProgressState(current=50, min=0, max=100, unit="MB"),
|
|
)
|
|
result = await manager.create(notif)
|
|
assert result.type == "progress"
|
|
assert result.progress is not None
|
|
progress = result.progress
|
|
assert progress.percentage == 50.0
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_existing_notification(
|
|
self, manager: NotificationManager
|
|
) -> None:
|
|
notif = Notification(
|
|
id="test_01",
|
|
type="progress",
|
|
title="Backup",
|
|
progress=ProgressState(current=10, max=100),
|
|
)
|
|
await manager.create(notif)
|
|
|
|
notif.progress = ProgressState(current=50, max=100)
|
|
result = await manager.create(notif)
|
|
assert result.progress is not None
|
|
assert result.progress.percentage == 50.0
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_active_returns_list(self, manager: NotificationManager) -> None:
|
|
await manager.create(Notification(title="Test"))
|
|
active = manager.get_active()
|
|
assert len(active) == 1
|
|
assert active[0]["title"] == "Test"
|
|
|
|
|
|
class TestNotificationPruning:
|
|
@pytest.mark.asyncio
|
|
async def test_prunes_old_notifications(self) -> None:
|
|
manager = NotificationManager()
|
|
manager._max_active = 3
|
|
|
|
for i in range(5):
|
|
await manager.create(Notification(id=f"n{i}", title=f"Msg {i}"))
|
|
|
|
active = manager.get_active()
|
|
assert len(active) == 3
|
|
ids = [n["id"] for n in active]
|
|
assert "n0" not in ids
|
|
assert "n4" in ids
|
|
|
|
|
|
class TestNotificationDismiss:
|
|
@pytest.mark.asyncio
|
|
async def test_dismiss_removes_notification(
|
|
self, manager: NotificationManager
|
|
) -> None:
|
|
notif = Notification(id="dismiss_me", title="Temp")
|
|
await manager.create(notif)
|
|
assert len(manager.get_active()) == 1
|
|
|
|
result = await manager.dismiss("dismiss_me")
|
|
assert result
|
|
assert len(manager.get_active()) == 0
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_dismiss_nonexistent_returns_false(
|
|
self, manager: NotificationManager
|
|
) -> None:
|
|
result = await manager.dismiss("does_not_exist")
|
|
assert not result
|
|
|
|
|
|
class TestProgressState:
|
|
def test_percentage_calculation(self) -> None:
|
|
p = ProgressState(current=75, min=0, max=100)
|
|
assert p.percentage == 75.0
|
|
|
|
def test_percentage_clamped_at_zero(self) -> None:
|
|
p = ProgressState(current=-10, min=0, max=100)
|
|
assert p.percentage == 0.0
|
|
|
|
def test_percentage_clamped_at_hundred(self) -> None:
|
|
p = ProgressState(current=150, min=0, max=100)
|
|
assert p.percentage == 100.0
|
|
|
|
def test_zero_range_returns_zero(self) -> None:
|
|
p = ProgressState(current=50, min=0, max=0)
|
|
assert p.percentage == 0.0
|