Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/utils/stream/event-stream.test.ts
T

48 lines
1.8 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it, vi } from "vitest";
import { eventStream } from "./event-stream";
describe("eventStream", () => {
it("disposes once and ignores late sends after reader cancellation", async () => {
const abortController = new AbortController();
const cleanup = vi.fn();
let sendAfterCancel: ((args: { event?: string; data: string }) => void) | undefined;
const response = eventStream(abortController.signal, (send) => {
sendAfterCancel = send;
send({ event: "ready", data: "initial" });
return cleanup;
});
const reader = response.body!.getReader();
await expect(reader.read()).resolves.toMatchObject({ done: false });
await reader.cancel(new Error("client disconnected"));
expect(cleanup).toHaveBeenCalledTimes(1);
expect(() => sendAfterCancel?.({ event: "heartbeat", data: "late" })).not.toThrow();
abortController.abort();
expect(cleanup).toHaveBeenCalledTimes(1);
});
it("closes and disposes once when the request aborts", async () => {
const abortController = new AbortController();
const cleanup = vi.fn();
let sendAfterAbort: ((args: { event?: string; data: string }) => void) | undefined;
const response = eventStream(abortController.signal, (send) => {
sendAfterAbort = send;
send({ data: "initial" });
return cleanup;
});
const reader = response.body!.getReader();
await expect(reader.read()).resolves.toMatchObject({ done: false });
await expect(reader.read()).resolves.toMatchObject({ done: false });
abortController.abort();
await expect(reader.read()).resolves.toEqual({ done: true, value: undefined });
expect(cleanup).toHaveBeenCalledTimes(1);
expect(() => sendAfterAbort?.({ data: "late" })).not.toThrow();
await reader.cancel();
expect(cleanup).toHaveBeenCalledTimes(1);
});
});