feat(web): persist workspace presentation across browser hosts — #205
This commit is contained in:
62
frontend/src/features/web/webWorkspaceSync.test.ts
Normal file
62
frontend/src/features/web/webWorkspaceSync.test.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { createWebWorkspaceSyncBus } from "./webWorkspaceSync";
|
||||
|
||||
class FakeBroadcastChannel {
|
||||
static channels = new Map<string, Set<FakeBroadcastChannel>>();
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user