Files
erika/lib/realtime/sse.test.ts
T

69 lines
2.0 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { isSseTopic, sse } from "@/lib/realtime/sse";
describe("leaderboard SSE contract", () => {
test("registers the public leaderboards topic", () => {
expect(isSseTopic("leaderboards")).toBeTrue();
expect(sse.leaderboards.adminOnly).toBeFalse();
});
test("accepts only the minimal XP envelope", () => {
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "xp", data: {} }),
)).toEqual({ event: "xp", data: {} });
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "xp", data: { userId: "1" } }),
)).toBeNull();
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "xp", data: {}, extra: true }),
)).toBeNull();
});
test("validates VC channel IDs and rejects malformed messages", () => {
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "vc", data: { channelId: "1234567890" } }),
)).toEqual({
event: "vc",
data: { channelId: "1234567890" },
});
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "vc", data: { channelId: "voice-one" } }),
)).toBeNull();
expect(sse.leaderboards.parseRedisMessage("{")).toBeNull();
expect(sse.leaderboards.parseRedisMessage(
JSON.stringify({ event: "unknown", data: {} }),
)).toBeNull();
});
});
describe("upload SSE contract", () => {
test("registers an admin-only upload topic", () => {
expect(isSseTopic("uploads")).toBeTrue();
expect(sse.uploads.adminOnly).toBeTrue();
});
test("validates upload job status events", () => {
const message = JSON.stringify({
event: "update",
data: {
uploadId: "upload-1",
jobId: "job-1",
platform: "youtube",
status: "completed",
},
});
expect(sse.uploads.parseRedisMessage(message)).toEqual({
event: "update",
data: {
uploadId: "upload-1",
jobId: "job-1",
platform: "youtube",
status: "completed",
},
});
});
});