evOo-local/apps/web/src/lib/workspace-pane-pref.test.ts
cynarAI e28c3acf02
feat: let the pane beside a conversation follow the bot's work (#123)
The live screen opens wide beside the chat while the bot works on it or asks
for a takeover, a file the bot presents as its result opens next to the
conversation, and a question that scrolled away gets a "Needs you" pill back
to it. Shared core rules derive the focus from signals clients already have
(pointer events, takeover requests, a new `present` flag on attach_file,
pending asks), move the pane only on focus edges, never replace a pane the
user opened, and learn per bot whether the screen opens on its own. Pane
widths persist per device; mobile shows a pill that opens the computer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7VSRHHzyt2KwoCkUkZ2Gc
2026-10-03 22:23:46 +02:00

62 lines
1.8 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import {
readPaneWidth,
readScreenPaneHabit,
writePaneWidth,
writeScreenPaneHabit,
} from "./workspace-pane-pref";
function stubStorage() {
const store = new Map<string, string>();
vi.stubGlobal("window", {
localStorage: {
getItem: (key: string) => store.get(key) ?? null,
setItem: (key: string, value: string) => {
store.set(key, value);
},
removeItem: (key: string) => {
store.delete(key);
},
},
});
return store;
}
afterEach(() => {
vi.unstubAllGlobals();
});
describe("workspace pane preferences", () => {
it("keeps the learned screen habit per user and bot", () => {
const store = stubStorage();
expect(readScreenPaneHabit("user-1", "bot-1")).toBe(0);
writeScreenPaneHabit("user-1", "bot-1", 2);
expect(readScreenPaneHabit("user-1", "bot-1")).toBe(2);
expect(readScreenPaneHabit("user-1", "bot-2")).toBe(0);
writeScreenPaneHabit("user-1", "bot-1", 0);
expect(store.size).toBe(0);
writeScreenPaneHabit(null, "bot-1", 3);
expect(store.size).toBe(0);
});
it("restores a stored pane width within its bounds", () => {
stubStorage();
expect(readPaneWidth("width", 500, 320, 900)).toBe(500);
writePaneWidth("width", 640.4);
expect(readPaneWidth("width", 500, 320, 900)).toBe(640);
writePaneWidth("width", 2_000);
expect(readPaneWidth("width", 500, 320, 900)).toBe(900);
});
it("falls back when storage is unavailable", () => {
vi.stubGlobal("window", {
get localStorage(): Storage {
throw new Error("blocked");
},
});
expect(readScreenPaneHabit("user-1", "bot-1")).toBe(0);
expect(readPaneWidth("width", 500, 320, 900)).toBe(500);
expect(() => writePaneWidth("width", 600)).not.toThrow();
});
});