import { afterEach, beforeEach, expect, test } from "bun:test"; const sent: Array<[string, unknown]> = []; beforeEach(() => { sent.length = 0; (globalThis as any).window = {}; }); afterEach(async () => { const { __resetTrackQueue } = await import("./trackEvent"); __resetTrackQueue(); delete (globalThis as any).window; }); const umami = { track: (e: string, d: unknown) => sent.push([e, d]) }; const wait = (ms: number) => new Promise((r) => setTimeout(r, ms)); test("sends immediately when umami is loaded", async () => { const { trackEvent } = await import("./trackEvent"); (globalThis as any).window.umami = umami; trackEvent("a", { x: 1 }); expect(sent).toEqual([["a", { x: 1 }]]); }); test("queues until umami appears, then flushes in order and calls onSent", async () => { const { trackEvent } = await import("./trackEvent"); let confirmed = false; trackEvent("first"); trackEvent("purchase-completed", { revenue: 12.5, currency: "EUR" }, () => (confirmed = true)); expect(sent).toEqual([]); await wait(300); (globalThis as any).window.umami = umami; await wait(400); expect(sent.map((s) => s[0])).toEqual(["first", "purchase-completed"]); expect(confirmed).toBe(true); }); test("never throws and drops events when umami never loads", async () => { const { trackEvent } = await import("./trackEvent"); let confirmed = false; trackEvent("lost", undefined, () => (confirmed = true)); await wait(10_500); (globalThis as any).window.umami = umami; await wait(400); expect(sent).toEqual([]); expect(confirmed).toBe(false); }, 15_000); test("is a no-op on the server", async () => { delete (globalThis as any).window; const { trackEvent } = await import("./trackEvent"); expect(() => trackEvent("ssr")).not.toThrow(); });