import { expect, test } from "bun:test"; import { createPresenceEvent, createRealtimeMessage, createTypingEvent, parseRealtimeMessage, roomMemberSummary, roomQuery, } from "../src/index.ts"; test("creates and parses typed realtime messages", () => { const message = createRealtimeMessage({ id: "message-1", type: "message", room: "support/general", data: { text: "Hi" }, sentAt: "2026-01-01T00:00:00.000Z", }); expect(parseRealtimeMessage(JSON.stringify(message), { room: "support/general" })).toEqual( message, ); }); test("builds presence and typing events", () => { expect(createPresenceEvent("join", { userId: "u1" }).type).toBe("presence"); expect(createTypingEvent("u1", true).data.typing).toBe(true); }); test("summarizes room members and query parameters", () => { expect( roomMemberSummary([ { userId: "1", status: "online" }, { userId: "2", status: "away" }, ]), ).toEqual({ total: 2, online: 1, away: 1, busy: 0 }); expect(roomQuery({ user: "u1", page: 2, active: true })).toBe("user=u1&page=2&active=true"); }); test("rejects oversized, unsafe, mismatched, and unknown messages", () => { const message = createRealtimeMessage({ id: "message-2", type: "message", room: "support", data: { text: "Hi" }, }); expect(() => parseRealtimeMessage(JSON.stringify(message), { allowedTypes: ["presence"] }), ).toThrow("not allowed"); expect(() => parseRealtimeMessage(JSON.stringify(message), { room: "other" })).toThrow( "does not match", ); expect(() => parseRealtimeMessage(JSON.stringify(message), { maxBytes: 16 })).toThrow( "maximum size", ); expect(() => roomQuery({ "bad key": "x" })).toThrow("query key"); });