import { afterEach, describe, expect, it, vi } from "vitest"; import { createWebWorkspaceSyncBus } from "./webWorkspaceSync"; class FakeBroadcastChannel { static channels = new Map>(); onmessage: ((event: MessageEvent) => void) | null = null; constructor(private readonly name: string) { const peers = FakeBroadcastChannel.channels.get(name) ?? new Set(); peers.add(this); FakeBroadcastChannel.channels.set(name, peers); } postMessage(data: unknown): void { for (const peer of FakeBroadcastChannel.channels.get(this.name) ?? []) { if (peer !== this) { peer.onmessage?.({ data } as MessageEvent); } } } close(): void { FakeBroadcastChannel.channels.get(this.name)?.delete(this); } } afterEach(() => { vi.unstubAllGlobals(); FakeBroadcastChannel.channels.clear(); }); describe("web workspace sync bus (#205)", () => { it("broadcasts focus changes to other browser hosts, not itself", () => { vi.stubGlobal("BroadcastChannel", FakeBroadcastChannel); const first = createWebWorkspaceSyncBus(); const second = createWebWorkspaceSyncBus(); const firstHandler = vi.fn(); const secondHandler = vi.fn(); first.subscribe(firstHandler); second.subscribe(secondHandler); first.publish({ type: "focus", project: { id: "p-1", name: "Demo", root: "/srv/demo" }, activePanel: "tickets", }); expect(firstHandler).not.toHaveBeenCalled(); expect(secondHandler).toHaveBeenCalledWith( expect.objectContaining({ type: "focus", sourceId: first.sourceId, project: { id: "p-1", name: "Demo", root: "/srv/demo" }, activePanel: "tickets", }), ); first.close(); second.close(); }); });