import { describe, expect, it } from "vitest"; import type { DashboardSnapshot } from "../src/contracts"; import { actionInbox, aggregateTrend, alertDestination } from "../src/operator-data"; const snapshot: DashboardSnapshot = { generatedAt: "2026-10-01T10:00:00Z", staleAfterSeconds: 90, health: { hub: "healthy", gateway: "healthy", detail: "Available" }, projects: [], connectors: [{ id: "gitea-alpha", name: "gitea", project: "alpha", state: "degraded", registrationState: "registered", readiness: { state: "unknown", detail: "Not probed", observedAt: null, source: "not-probed" }, detail: "Readiness failed" }], denials: { count: 2, window: "24h", latestTool: "gitea.repository.get" }, drift: { count: 1, projects: ["alpha"], known: true, detail: "Catalog differs" }, activeClients: 1, backup: { state: "degraded", lastSuccessfulAt: null, detail: "No backup observed" }, version: { application: "1.0.0", schema: "1" }, }; describe("operator signals", () => { it("routes a connector signal to its exact project binding context", () => { const item = actionInbox(snapshot, false, false).find((signal) => signal.project === "alpha" && signal.subsystem === "gitea"); expect(item?.href).toBe("/connectors/gitea-alpha"); expect(item?.detail).toBe("Readiness failed"); expect(item?.observedAt).toBe("2026-10-01T10:00:00Z"); }); it("exposes audit navigation only to an authorized auditor", () => { expect(actionInbox(snapshot, false, false).find((signal) => signal.subsystem === "Authorization")?.href).toBe("/operations?section=alerts"); expect(actionInbox(snapshot, false, true).find((signal) => signal.subsystem === "Authorization")?.href).toBe("/audit?q=gitea.repository.get"); }); it("links drift and backup to their bounded resolution workspace", () => { const signals = actionInbox(snapshot, false, true); expect(signals.find((signal) => signal.subsystem === "Catalog")?.href).toBe("/operations?section=checks"); expect(signals.find((signal) => signal.subsystem === "Recovery")?.href).toBe("/operations?section=recovery"); expect(alertDestination("BACKUP_STALE", false)).toBe("/operations?section=recovery"); }); it("keeps unknown and stale state explicit without claiming a diagnosis", () => { const signals = actionInbox({ ...snapshot, drift: { ...snapshot.drift, known: false } }, true, false); expect(signals[0]?.subsystem).toBe("Freshness"); expect(signals.find((signal) => signal.subsystem === "Catalog")?.status).toBe("unknown"); }); }); describe("mobile call buckets", () => { it("aggregates each four-hour interval without dropping outcomes", () => { const trend = Array.from({ length: 24 }, (_, hour) => ({ hour: `2026-10-01T${String(hour).padStart(2, "0")}:00:00Z`, success: 1, denied: 2, error: 3, rate_limited: 4 })); const buckets = aggregateTrend(trend, 4); expect(buckets).toHaveLength(6); expect(buckets[0]).toEqual({ hour: "2026-10-01T00:00:00Z", endHour: "2026-10-01T03:00:00Z", success: 4, denied: 8, error: 12, rate_limited: 16 }); expect(buckets[5]?.success).toBe(4); }); it("retains partial buckets and handles empty observations", () => { expect(aggregateTrend([], 4)).toEqual([]); expect(aggregateTrend([{ hour: "2026-10-01T00:00:00Z", success: 2, denied: 0, error: 1, rate_limited: 0 }], 4)[0]?.error).toBe(1); }); });