89 lines
2.6 KiB
TypeScript
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);
|
|
});
|
|
});
|