Files
claw3d/tests/unit/studioSettingsCoordinator.test.ts
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

96 lines
2.8 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { defaultStudioSettings, sanitizeStudioSettings } from "@/lib/studio/settings";
import { StudioSettingsCoordinator } from "@/lib/studio/coordinator";
describe("StudioSettingsCoordinator", () => {
const createResponse = () => ({
settings: sanitizeStudioSettings(defaultStudioSettings()),
});
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it("coalesces multiple scheduled patches into one update", async () => {
const fetchSettings = vi.fn(async () => createResponse());
const updateSettings = vi.fn(async () => createResponse());
const coordinator = new StudioSettingsCoordinator({ fetchSettings, updateSettings }, 300);
coordinator.schedulePatch({
gateway: { url: "ws://localhost:18789", token: "abc" },
});
coordinator.schedulePatch({
focused: {
"ws://localhost:18789": {
mode: "focused",
filter: "running",
selectedAgentId: null,
},
},
});
await vi.advanceTimersByTimeAsync(300);
expect(updateSettings).toHaveBeenCalledTimes(1);
expect(updateSettings).toHaveBeenCalledWith({
gateway: { url: "ws://localhost:18789", token: "abc" },
focused: {
"ws://localhost:18789": {
mode: "focused",
filter: "running",
selectedAgentId: null,
},
},
});
coordinator.dispose();
});
it("flushPending persists queued patch immediately", async () => {
const fetchSettings = vi.fn(async () => createResponse());
const updateSettings = vi.fn(async () => createResponse());
const coordinator = new StudioSettingsCoordinator({ fetchSettings, updateSettings }, 1000);
coordinator.schedulePatch({
gateway: { url: "ws://localhost:18789", token: "session-a" },
});
await coordinator.flushPending();
expect(updateSettings).toHaveBeenCalledTimes(1);
expect(updateSettings).toHaveBeenCalledWith({
gateway: { url: "ws://localhost:18789", token: "session-a" },
});
await vi.advanceTimersByTimeAsync(2000);
expect(updateSettings).toHaveBeenCalledTimes(1);
coordinator.dispose();
});
it("dispose clears pending timer without writing", async () => {
const fetchSettings = vi.fn(async () => createResponse());
const updateSettings = vi.fn(async () => createResponse());
const coordinator = new StudioSettingsCoordinator({ fetchSettings, updateSettings }, 200);
coordinator.schedulePatch({
focused: {
"ws://localhost:18789": {
mode: "focused",
filter: "approvals",
selectedAgentId: null,
},
},
});
coordinator.dispose();
await vi.advanceTimersByTimeAsync(500);
expect(updateSettings).not.toHaveBeenCalled();
});
});