import { afterEach, describe, expect, it } from "vitest"; import type { DaemonClient } from "@server/client/daemon-client"; import type { WorkspaceDescriptorPayload } from "@server/shared/messages"; import { mergeWorkspaceSnapshotWithExisting, normalizeWorkspaceDescriptor, useSessionStore, type WorkspaceDescriptor, } from "./session-store"; function createWorkspace( input: Partial & Pick, ): WorkspaceDescriptor { return { id: input.id, projectId: input.projectId ?? "project-1", projectDisplayName: input.projectDisplayName ?? "Project 1", projectRootPath: input.projectRootPath ?? "/repo", workspaceDirectory: input.workspaceDirectory ?? "/repo", projectKind: input.projectKind ?? "git", workspaceKind: input.workspaceKind ?? "local_checkout", name: input.name ?? "main", status: input.status ?? "done", diffStat: input.diffStat ?? null, scripts: input.scripts ?? [], }; } afterEach(() => { useSessionStore.getState().clearSession("test-server"); }); describe("normalizeWorkspaceDescriptor", () => { it("normalizes workspace scripts and invalid activity timestamps", () => { const scripts = [ { scriptName: "web", type: "service" as const, hostname: "web.paseo.localhost", port: 3000, proxyUrl: "http://web.paseo.localhost:6767", lifecycle: "running" as const, health: "healthy" as const, exitCode: null, }, ]; const workspace = normalizeWorkspaceDescriptor({ id: "1", projectId: "1", projectDisplayName: "Project 1", projectRootPath: "/repo", workspaceDirectory: "/repo", projectKind: "git", workspaceKind: "checkout", name: "main", status: "running", activityAt: "not-a-date", diffStat: null, scripts, }); expect(workspace.scripts).toEqual([ { scriptName: "web", type: "service", hostname: "web.paseo.localhost", port: 3000, proxyUrl: "http://web.paseo.localhost:6767", lifecycle: "running", health: "healthy", exitCode: null, }, ]); expect(workspace.scripts).not.toBe(scripts); }); it("defaults missing scripts to an empty array", () => { const payload = { id: "1", projectId: "1", projectDisplayName: "Project 1", projectRootPath: "/repo", workspaceDirectory: "/repo", projectKind: "git", workspaceKind: "checkout", name: "main", status: "done", activityAt: null, diffStat: null, scripts: [], } as WorkspaceDescriptorPayload; const workspace = normalizeWorkspaceDescriptor(payload); expect(workspace.scripts).toEqual([]); }); }); describe("mergeWorkspaces", () => { it("preserves scripts on merged workspace entries", () => { const store = useSessionStore.getState(); store.initializeSession("test-server", null as unknown as DaemonClient); store.setWorkspaces( "test-server", new Map([["/repo/main", createWorkspace({ id: "/repo/main", scripts: [] })]]), ); store.mergeWorkspaces("test-server", [ createWorkspace({ id: "/repo/main", scripts: [ { scriptName: "web", type: "service", hostname: "web.paseo.localhost", port: 3000, proxyUrl: "http://web.paseo.localhost:6767", lifecycle: "running", health: "healthy", exitCode: null, }, ], }), ]); expect(store.getSession("test-server")?.workspaces.get("/repo/main")?.scripts).toEqual([ { scriptName: "web", type: "service", hostname: "web.paseo.localhost", port: 3000, proxyUrl: "http://web.paseo.localhost:6767", lifecycle: "running", health: "healthy", exitCode: null, }, ]); }); }); describe("mergeWorkspaceSnapshotWithExisting", () => { it("preserves the last known diff stat when a snapshot only has baseline null data", () => { const existing = createWorkspace({ id: "/tmp/repo", diffStat: { additions: 4, deletions: 2 }, }); const incoming = createWorkspace({ id: "/tmp/repo", diffStat: null, }); expect(mergeWorkspaceSnapshotWithExisting({ incoming, existing })).toEqual({ ...incoming, diffStat: { additions: 4, deletions: 2 }, }); }); it("uses the incoming diff stat when the server provides a known value", () => { const existing = createWorkspace({ id: "/tmp/repo", diffStat: { additions: 4, deletions: 2 }, }); const incoming = createWorkspace({ id: "/tmp/repo", diffStat: { additions: 0, deletions: 0 }, }); expect(mergeWorkspaceSnapshotWithExisting({ incoming, existing })).toEqual(incoming); }); });