fix(test): Snapshot-Tests brauchten eine Datenbank — die Ampel hat keine
Ampel / ampel (push) Successful in 40s

WAS: test_snapshot_* ersetzen den Store per monkeypatch, statt
db.list_jobs() wirklich aufzurufen.

WARUM ROT (Lauf 170): Die Ampel startet KEINE Postgres. Mein neuer Test
war der erste im ganzen Repo, der eine Datenbank angefasst hat — alle
anderen in test_api_smoke.py pruefen nur Importe und Routen. Auf der VM
und lokal waere es nie aufgefallen: dort ist eine DB da bzw. der ganze
Test wird uebersprungen (kein fcntl unter Windows).

Geprueft wird die Snapshot-LOGIK ("konnte nicht nachsehen" ergibt None,
nicht []), nicht die Datenbank. Also gehoert die Datenbank da nicht rein.

Dazu ein zweiter Test: der Snapshot muss alle vier Bereiche liefern
(jobs/workers/logs/devices) — ein Client, dem einer fehlt, muesste den
Rest raten und fiele auf Polling zurueck.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-28 09:20:58 +02:00
co-authored by Claude Opus 5
parent 55db9eb13f
commit 1fbe2cfc55
2 changed files with 244 additions and 9 deletions
+33 -9
View File
@@ -286,27 +286,51 @@ def test_sse_rahmen_uebersteht_umlaute():
assert "Größe" in rahmen
def test_snapshot_meldet_unlesbare_laufwerke_als_none():
def test_snapshot_meldet_unlesbare_laufwerke_als_none(monkeypatch):
"""„konnte nicht nachsehen" ist etwas anderes als „es gibt keine".
Genau diese Vermischung hat in v1 die Job-Liste im Sekundentakt geleert
(fuenfmal `catch(() => [])` im UI). Ein Snapshot mit devices=[] wuerde dem
UI sagen „du hast kein Laufwerk"; None sagt „ich weiss es gerade nicht",
und das UI behaelt seinen Stand.
OHNE DATENBANK: Die Ampel hat keine Postgres — der erste Anlauf dieses
Tests lief deshalb rot (Lauf 170). Der Store wird hier ersetzt, denn
geprueft wird die Snapshot-LOGIK, nicht die Datenbank.
"""
import asyncio
import main
monkeypatch.setattr(main.db, "list_jobs", lambda limit=50: [])
monkeypatch.setattr(main.db, "list_workers", lambda: [])
monkeypatch.setattr(main.db, "list_logs", lambda limit=50: [])
def kaputt():
raise OSError("Laufwerk haengt")
original = main.device_discovery.list_optical_devices
main.device_discovery.list_optical_devices = kaputt
try:
zustand = asyncio.run(main._snapshot())
finally:
main.device_discovery.list_optical_devices = original
monkeypatch.setattr(main.device_discovery, "list_optical_devices", kaputt)
assert zustand["devices"] is None
assert isinstance(zustand["jobs"], list)
zustand = asyncio.run(main._snapshot())
assert zustand["devices"] is None, "Ein unlesbares Laufwerk darf nicht als [] durchgehen"
assert zustand["jobs"] == []
def test_snapshot_liefert_alle_vier_bereiche(monkeypatch):
"""Ein Client, der sich verbindet, bekommt das GANZE Bild — sonst muesste
er den Rest raten und faellt auf Polling zurueck."""
import asyncio
import main
monkeypatch.setattr(main.db, "list_jobs", lambda limit=50: [])
monkeypatch.setattr(main.db, "list_workers", lambda: [{"name": "pc"}])
monkeypatch.setattr(main.db, "list_logs", lambda limit=50: [])
monkeypatch.setattr(main.device_discovery, "list_optical_devices", lambda: [])
zustand = asyncio.run(main._snapshot())
assert set(zustand) == {"jobs", "workers", "logs", "devices"}
assert zustand["devices"] == [] # wirklich leer, nicht „unbekannt"
assert zustand["workers"] == [{"name": "pc"}]