import { describe, expect, test } from "bun:test"; import { matchesRealtimeRefresh, startRealtimeRefresh, type RealtimeRefreshEvent, } from "@/lib/realtime/realtime-refresh"; function waitForRefresh() { return new Promise((resolve) => setTimeout(resolve, 5)); } describe("realtime refresh policy", () => { test("matches page intent against one event stream", () => { expect(matchesRealtimeRefresh({ kind: "profile" }, { kind: "xp" })).toBeTrue(); expect(matchesRealtimeRefresh({ kind: "profile" }, { kind: "vc", channelId: "1" })).toBeTrue(); expect(matchesRealtimeRefresh({ kind: "vc", channelId: "1" }, { kind: "vc", channelId: "2" })).toBeFalse(); expect(matchesRealtimeRefresh({ kind: "form", formId: "form-1" }, { kind: "form", formId: "form-2" })).toBeFalse(); expect(matchesRealtimeRefresh({ kind: "uploads" }, { kind: "upload" })).toBeTrue(); }); test("refreshes for matching events and reconnects", async () => { let emit: ((event: RealtimeRefreshEvent) => void) | undefined; let refreshes = 0; const clean = startRealtimeRefresh({ filter: { kind: "profile" }, debounceMs: 0, refresh: () => { refreshes += 1; }, subscribe: (nextEmit) => { emit = nextEmit; return { clean() {} }; }, }); emit?.({ kind: "open" }); emit?.({ kind: "xp" }); await waitForRefresh(); emit?.({ kind: "vc", channelId: "1234567890" }); await waitForRefresh(); emit?.({ kind: "open" }); await waitForRefresh(); expect(refreshes).toBe(3); clean(); }); test("debounces event bursts and cancels on cleanup", async () => { let emit: ((event: RealtimeRefreshEvent) => void) | undefined; let refreshes = 0; const clean = startRealtimeRefresh({ filter: { kind: "xp" }, debounceMs: 1, refresh: () => { refreshes += 1; }, subscribe: (nextEmit) => { emit = nextEmit; return { clean() {} }; }, }); emit?.({ kind: "xp" }); emit?.({ kind: "xp" }); await waitForRefresh(); expect(refreshes).toBe(1); emit?.({ kind: "xp" }); clean(); await waitForRefresh(); expect(refreshes).toBe(1); }); });