Files
openwork/apps/app/tests/openwork-context-projector.test.ts

203 lines
6.5 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
buildOpenworkContext,
screenFromRoute,
} from "../src/react-app/shell/openwork-context-projector";
import type { WorkbenchSnapshot } from "../src/react-app/domains/session/chat/workbench-store";
type ContextProjectorInput = Parameters<typeof buildOpenworkContext>[0];
const baseInput: ContextProjectorInput = {
route: "/workspace/workspace-a/session/session-a",
revision: 4,
capturedAt: "2026-07-23T12:00:00.000Z",
workbench: {
revision: 4,
primary: {
workspaceId: "workspace-a",
workspaceTitle: "Customer workspace",
sessionId: "session-a",
title: "Primary",
},
tabs: [
{ workspaceId: "workspace-a", workspaceTitle: "Customer workspace", sessionId: "session-a", title: "Primary" },
{ workspaceId: "workspace-b", workspaceTitle: "Research workspace", sessionId: "session-b", title: "Secondary" },
],
secondary: {
workspaceId: "workspace-b",
workspaceTitle: "Research workspace",
sessionId: "session-b",
title: "Secondary",
},
focusedPane: "secondary",
},
ui: {
sidebarOpen: true,
sidePanelState: { "session-b": "panel" },
applicationMenuVisible: false,
workspaceRightSidebarExpanded: true,
},
panelSessions: {
"session-b": {
tabs: [{ id: "artifact-a", type: "artifact", label: "Report", preview: "markdown" }],
activeTabId: "artifact-a",
},
},
availableAffordances: [],
};
describe("OpenWork context projector", () => {
test("projects the focused split session and its panel state", () => {
const context = buildOpenworkContext(baseInput);
expect(context.conversations.layout).toEqual({
kind: "split",
primarySessionId: "session-a",
primaryWorkspaceId: "workspace-a",
secondarySessionId: "session-b",
secondaryWorkspaceId: "workspace-b",
focused: "secondary",
});
expect(context.resources.find((resource) => resource.kind === "workspace")?.title)
.toBe("Customer workspace");
expect(context.resources.find((resource) => resource.ref === "workspace:workspace-b")?.title)
.toBe("Research workspace");
expect(context.resources.find((resource) => resource.ref === "session:workspace-a:session-a")?.state.workspaceId)
.toBe("workspace-a");
expect(context.resources.find((resource) => resource.ref === "session:workspace-b:session-b")?.state.workspaceId)
.toBe("workspace-b");
expect(context.sidePanel).toEqual({
open: true,
ownerSessionId: "session-b",
kind: "panel",
tabs: [{ id: "artifact-a", kind: "artifact", label: "Report" }],
activeTabId: "artifact-a",
});
});
test("does not leak artifact tabs into a non-panel surface", () => {
const context = buildOpenworkContext({
...baseInput,
ui: {
...baseInput.ui,
sidePanelState: { "session-b": "extensions" },
},
});
expect(context.sidePanel.kind).toBe("extensions");
expect(context.sidePanel.tabs).toEqual([]);
expect(context.sidePanel.activeTabId).toBeNull();
});
});
const splitWorkbench: WorkbenchSnapshot = {
revision: 5,
primary: { workspaceId: "workspace-a", workspaceTitle: "Workspace A", sessionId: "session-a", title: "Current plan" },
tabs: [
{ workspaceId: "workspace-a", workspaceTitle: "Workspace A", sessionId: "session-a", title: "Current plan" },
{ workspaceId: "workspace-a", workspaceTitle: "Workspace A", sessionId: "session-b", title: "Previous research" },
{ workspaceId: "workspace-a", workspaceTitle: "Workspace A", sessionId: "session-c", title: "Draft" },
],
secondary: { workspaceId: "workspace-a", workspaceTitle: "Workspace A", sessionId: "session-b", title: "Previous research" },
focusedPane: "secondary",
};
function contextForRoute(route: string) {
return buildOpenworkContext({
route,
revision: 7,
capturedAt: "2026-07-23T10:59:00.000Z",
workbench: splitWorkbench,
ui: {
sidebarOpen: false,
sidePanelState: { "session-a": "panel" },
applicationMenuVisible: false,
workspaceRightSidebarExpanded: true,
},
panelSessions: {
"session-a": {
tabs: [{
id: "browser-one",
type: "browser",
label: "OpenWork docs",
url: "https://docs.openwork.so",
favicon: null,
status: "ready",
canGoBack: false,
canGoForward: false,
}],
activeTabId: "browser-one",
},
},
availableAffordances: [],
});
}
describe("OpenWork context projector", () => {
test("represents all open tabs and both visible split sessions", () => {
const context = contextForRoute("/workspace/workspace-a/session/session-a");
expect(context.conversations.tabs.map((tab) => tab.sessionId)).toEqual([
"session-a",
"session-b",
"session-c",
]);
expect(context.conversations.layout).toEqual({
kind: "split",
primarySessionId: "session-a",
primaryWorkspaceId: "workspace-a",
secondarySessionId: "session-b",
secondaryWorkspaceId: "workspace-a",
focused: "secondary",
});
expect(context.resources.find((resource) => resource.ref === "session:workspace-a:session-b")).toMatchObject({
kind: "session",
title: "Previous research",
state: {
open: true,
visible: true,
pane: "secondary",
focused: true,
},
});
expect(context.chrome.sidebarOpen).toBe(false);
expect(context.execution).toEqual({
queries: "parallel",
commands: "serialized",
busyCommandId: null,
busyActor: null,
});
expect(context.sidePanel).toMatchObject({
open: true,
ownerSessionId: "session-a",
kind: "panel",
activeTabId: "browser-one",
});
});
test("retains workbench context while settings is the active screen", () => {
const context = contextForRoute("/workspace/workspace-a/settings/ai");
expect(context.screen).toEqual({
kind: "settings",
route: "/workspace/workspace-a/settings/ai",
workspaceId: "workspace-a",
panel: "ai",
});
expect(context.conversations.layout.kind).toBe("split");
expect(context.conversations.tabs).toHaveLength(3);
});
test("parses legacy and workspace-scoped routes without reading the DOM", () => {
expect(screenFromRoute("/session/session-a")).toMatchObject({
kind: "conversation",
sessionId: "session-a",
});
expect(screenFromRoute("/settings/extensions")).toMatchObject({
kind: "settings",
panel: "extensions",
});
});
});