import { beforeEach, expect, test, vi } from "vitest"; import type { AppConfig } from "../src/config.js"; const fakes = vi.hoisted(() => ({ catalogRepository: { close: vi.fn(async () => {}) }, createCatalogRepository: vi.fn(), runnerConfig: undefined as Record | undefined, acquireWorkspaceRuntime: vi.fn(), releaseWorkspaceRuntime: vi.fn(), run: vi.fn(async () => ({ code: 0, stdout: JSON.stringify({ ok: true }), stderr: "", })), })); vi.mock("../src/catalog/repository.js", () => ({ createCatalogRepository: fakes.createCatalogRepository, })); vi.mock("../src/tht/tht-runner.js", () => ({ ThtRunner: class { constructor(config: Record) { fakes.runnerConfig = config; } run = fakes.run; acquireWorkspaceRuntime = fakes.acquireWorkspaceRuntime; withPrincipal() { return this; } }, })); vi.mock("../src/workspaces/registry.js", () => ({ WorkspaceRegistry: class { async pull() { return { branch: "main", head: "a".repeat(40), ahead: 0, behind: 0, degraded: false }; } async listRetainedSnapshots() { return [{ snapshotPath: "/data/workspace-registry/snapshots/revision/workspace.yaml" }]; } }, })); vi.mock("../src/workspaces/secret-store.js", () => ({ WorkspaceSecretStore: class {}, })); import { runOperatorAction } from "../src/operator-command.js"; const config = { catalogDatabase: { host: "catalog-db" }, workspaceSecretStoreRoot: "/data/workspace-secrets", workspaceSecretRuntimeRoot: "/tmp/workspace-secrets", workspaceRegistry: { installationId: "test", root: "/data/workspace-registry", secretRoots: ["/run/secrets"], }, thtBin: "/opt/venv/bin/tht", harnessDir: "/app/harness", dataRoot: "/data", internalQdrantUrl: "http://qdrant:6333", internalEmbeddingUrl: "http://embedding:11434", internalEmbeddingModel: "qwen3-embedding:0.6b", internalEmbeddingDimensions: 1024, } as AppConfig; beforeEach(() => { fakes.catalogRepository.close.mockClear(); fakes.createCatalogRepository.mockReset(); fakes.createCatalogRepository.mockReturnValue(fakes.catalogRepository); fakes.run.mockClear(); fakes.acquireWorkspaceRuntime.mockReset(); fakes.acquireWorkspaceRuntime.mockResolvedValue({ path: "/data/workspace-registry/snapshots/runtime/workspace.yaml", release: fakes.releaseWorkspaceRuntime, }); fakes.releaseWorkspaceRuntime.mockClear(); fakes.runnerConfig = undefined; }); test("workflow doctor gives schema-v4 runtime rendering a live Catalog repository", async () => { await expect(runOperatorAction("workflow-doctor", config)).resolves.toEqual({ ready: true, workspaces: 1, }); expect(fakes.createCatalogRepository).toHaveBeenCalledWith(config.catalogDatabase); expect(fakes.runnerConfig?.catalogRepository).toBe(fakes.catalogRepository); expect(fakes.acquireWorkspaceRuntime).toHaveBeenCalledWith( "/data/workspace-registry/snapshots/revision/workspace.yaml", ); expect(fakes.run).toHaveBeenCalledWith( ["doctor", "--json"], "/data/workspace-registry/snapshots/runtime/workspace.yaml", ); expect(fakes.releaseWorkspaceRuntime).toHaveBeenCalledOnce(); expect(fakes.catalogRepository.close).toHaveBeenCalledOnce(); }); test("workspace pull exposes only safe Git status", async () => { await expect(runOperatorAction("workspace-pull", config)).resolves.toEqual({ ready: true, status: "succeeded", branch: "main", head: "a".repeat(40), degraded: false, }); });