Files
erika/lib/realtime-refresh.test.ts
T

89 lines
2.6 KiB
TypeScript

import { afterEach, describe, expect, mock, test } from "bun:test";
import {
startRealtimeRefresh,
type RealtimeRefreshHandlers,
} from "@/lib/realtime-refresh";
const cleanups: Array<() => void> = [];
afterEach(() => {
for (const clean of cleanups.splice(0)) clean();
});
function setup(
filter: Parameters<typeof startRealtimeRefresh>[0]["filter"],
debounceMs = 10,
) {
let handlers: RealtimeRefreshHandlers | undefined;
const refresh = mock(() => {});
const cleanSubscription = mock(() => {});
const clean = startRealtimeRefresh({
filter,
debounceMs,
refresh,
subscribe(nextHandlers) {
handlers = nextHandlers;
return { clean: cleanSubscription };
},
});
cleanups.push(clean);
return {
get handlers() {
if (!handlers) throw new Error("Handlers were not registered.");
return handlers;
},
refresh,
clean,
cleanSubscription,
};
}
describe("leaderboard realtime refresh", () => {
test("filters XP and VC events by leaderboard scope", async () => {
const xp = setup({ kind: "xp" });
xp.handlers.onVc({ channelId: "1" });
xp.handlers.onXp();
await Bun.sleep(20);
expect(xp.refresh).toHaveBeenCalledTimes(1);
const selectedVc = setup({ kind: "vc", channelId: "2" });
selectedVc.handlers.onVc({ channelId: "1" });
await Bun.sleep(20);
expect(selectedVc.refresh).not.toHaveBeenCalled();
selectedVc.handlers.onVc({ channelId: "2" });
await Bun.sleep(20);
expect(selectedVc.refresh).toHaveBeenCalledTimes(1);
const allVc = setup({ kind: "vc" });
allVc.handlers.onVc({ channelId: "any" });
await Bun.sleep(20);
expect(allVc.refresh).toHaveBeenCalledTimes(1);
});
test("refreshes after reconnect but not the initial connection", async () => {
const subscription = setup({ kind: "xp" });
subscription.handlers.onOpen();
await Bun.sleep(20);
expect(subscription.refresh).not.toHaveBeenCalled();
subscription.handlers.onOpen();
await Bun.sleep(20);
expect(subscription.refresh).toHaveBeenCalledTimes(1);
});
test("debounces event bursts and cleans timers and subscriptions", async () => {
const subscription = setup({ kind: "xp" }, 20);
subscription.handlers.onXp();
subscription.handlers.onXp();
subscription.handlers.onXp();
await Bun.sleep(30);
expect(subscription.refresh).toHaveBeenCalledTimes(1);
subscription.handlers.onXp();
subscription.clean();
await Bun.sleep(30);
expect(subscription.refresh).toHaveBeenCalledTimes(1);
expect(subscription.cleanSubscription).toHaveBeenCalledTimes(1);
});
});