/* Rauchtest gegen die laufende HA-Testinstanz (Docker, Port 18123). Prüft bewusst nur das, was ohne Zugangsdaten prüfbar ist: die Adressbildung, die Existenz der Endpunkte und den Beginn des WebSocket-Handshakes. Damit ist belegt, dass rest.ts und live.ts die richtigen Pfade und das richtige Protokoll ansprechen - ohne dass dafür irgendwo ein Token eingesammelt werden müsste. Aufruf: node scripts/smoke.ts (Node >= 23, Typen werden entfernt) node scripts/smoke.ts http://localhost:18123 */ import { basisUrlNormalisieren, websocketUrl } from "../src/api/umgebung.ts"; const BASIS = basisUrlNormalisieren(process.argv[2] ?? "http://localhost:18123"); let fehler = 0; function pruefe(bezeichnung: string, bedingung: boolean, zusatz = ""): void { console.log(`${bedingung ? "PASS" : "FAIL"} ${bezeichnung}${zusatz ? ` (${zusatz})` : ""}`); if (!bedingung) fehler += 1; } /* ------------------------------------------------- reine Funktionen */ pruefe("basisUrlNormalisieren schneidet Schrägstriche ab", basisUrlNormalisieren("https://host/") === "https://host"); pruefe("basisUrlNormalisieren ergänzt fehlendes Schema", basisUrlNormalisieren("host.example") === "https://host.example"); pruefe("basisUrlNormalisieren lässt http stehen", basisUrlNormalisieren("http://localhost:18123") === "http://localhost:18123"); pruefe("websocketUrl macht aus https wss", websocketUrl("https://h") === "wss://h/api/websocket"); pruefe("websocketUrl macht aus http ws", websocketUrl("http://h") === "ws://h/api/websocket"); /* --------------------------------------------------- REST-Endpunkt */ try { const antwort = await fetch(`${BASIS}/api/`, { headers: { "Content-Type": "application/json" } }); /* Ohne Token muss HA mit 401 antworten. Genau das beweist zweierlei: der Pfad /api/ existiert, und er ist nicht offen zugänglich. */ pruefe("GET /api/ ohne Token antwortet 401", antwort.status === 401, `Status ${antwort.status}`); } catch (e) { pruefe("GET /api/ erreichbar", false, e instanceof Error ? e.message : String(e)); } /* ---------------------------------------------- WebSocket-Handshake */ const wsErgebnis = await new Promise((fertig) => { const frist = setTimeout(() => fertig("Zeitüberschreitung"), 8000); try { const socket = new WebSocket(websocketUrl(BASIS)); socket.addEventListener("message", (e: MessageEvent) => { clearTimeout(frist); try { fertig(String(JSON.parse(String(e.data)).type)); } catch { fertig("kein JSON"); } socket.close(); }); socket.addEventListener("error", () => { clearTimeout(frist); fertig("Verbindungsfehler"); }); } catch (e) { clearTimeout(frist); fertig(e instanceof Error ? e.message : String(e)); } }); /* live.ts wartet als Erstes auf genau diese Nachricht - stimmt sie nicht, liefe der ganze Anmeldeablauf ins Leere. */ pruefe("WebSocket meldet sich mit auth_required", wsErgebnis === "auth_required", `erhalten: ${wsErgebnis}`); console.log(fehler === 0 ? "\nAlle Prüfungen bestanden." : `\n${fehler} Prüfung(en) fehlgeschlagen.`); /* Nur den Rückgabewert setzen, nicht process.exit() aufrufen: unter Windows stürzt libuv sonst mit einer Assertion ab, weil der eben geschlossene WebSocket noch nicht vollständig abgebaut ist. So läuft Node normal aus. */ process.exitCode = fehler === 0 ? 0 : 1;