Files
paseo/packages/app/src/stores/session-store.test.ts
T

167 lines
4.7 KiB
TypeScript

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<WorkspaceDescriptor> & Pick<WorkspaceDescriptor, "id">,
): 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",
activityAt: input.activityAt ?? null,
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",
hostname: "main.web.localhost",
port: 3000,
url: "http://main.web.localhost:6767",
lifecycle: "running" as const,
health: "healthy" as const,
},
];
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.activityAt).toBeNull();
expect(workspace.scripts).toEqual([
{
scriptName: "web",
hostname: "main.web.localhost",
port: 3000,
url: "http://main.web.localhost:6767",
lifecycle: "running",
health: "healthy",
},
]);
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",
hostname: "main.web.localhost",
port: 3000,
url: "http://main.web.localhost:6767",
lifecycle: "running",
health: "healthy",
},
],
}),
]);
expect(store.getSession("test-server")?.workspaces.get("/repo/main")?.scripts).toEqual([
{
scriptName: "web",
hostname: "main.web.localhost",
port: 3000,
url: "http://main.web.localhost:6767",
lifecycle: "running",
health: "healthy",
},
]);
});
});
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);
});
});