fabro/apps/fabro-web/app/lib/board-events.test.tsx
Bryan Helmkamp d4104be841
refactor(web): simplify SWR event plumbing
Share SSE subscription management, reuse query key builders, and remove duplicate route mapping/error helpers from the SWR refactor.
2026-04-25 07:37:17 -04:00

61 lines
1.7 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
shouldRefreshBoardForEvent,
subscribeToBoardEvents,
} from "./board-events";
import { queryKeys } from "./query-keys";
type MessageHandler = ((event: { data: string }) => void) | null;
class FakeEventSource {
onmessage: MessageHandler = null;
closed = false;
emit(payload: unknown) {
this.onmessage?.({ data: JSON.stringify(payload) });
}
close() {
this.closed = true;
}
}
describe("shouldRefreshBoardForEvent", () => {
test("refreshes board for run and interview status changes only", () => {
expect(shouldRefreshBoardForEvent("run.running")).toBe(true);
expect(shouldRefreshBoardForEvent("run.blocked")).toBe(true);
expect(shouldRefreshBoardForEvent("interview.completed")).toBe(true);
expect(shouldRefreshBoardForEvent("checkpoint.completed")).toBe(false);
});
});
describe("subscribeToBoardEvents", () => {
test("shares one source and invalidates the board runs key", () => {
const source = new FakeEventSource();
const created: string[] = [];
const keys: string[] = [];
const mutate = (key: string) => {
keys.push(key);
return Promise.resolve();
};
const firstCleanup = subscribeToBoardEvents(mutate, (url) => {
created.push(url);
return source;
}, { debounceMs: 0 });
const secondCleanup = subscribeToBoardEvents(mutate, () => {
throw new Error("source should be reused");
}, { debounceMs: 0 });
source.emit({ event: "run.running" });
expect(created).toEqual(["/api/v1/attach"]);
expect(keys).toEqual([queryKeys.boards.runs()]);
firstCleanup();
expect(source.closed).toBe(false);
secondCleanup();
expect(source.closed).toBe(true);
});
});