import { describe, expect, test } from "bun:test"; import { MAX_WORKSPACE_CONFIG_BYTES, MemoryWorkspaceStore, WorkspaceConflictError, WorkspaceValidationError, workspaceEtag, } from "../../server/workspace-store"; const source = { uri: "oci://registry.example/app", digest: "sha256:abc" }; describe("workspace store", () => { test("validates IDs and reserved namespaces", async () => { const store = new MemoryWorkspaceStore(); for (const id of [ "Upper", "has_dot", "kube-public", "database", "garage-system", "routing", ]) { expect(store.create({ id, source })).rejects.toBeInstanceOf( WorkspaceValidationError, ); } await expect( store.create({ id: "kuber-system", source }), ).resolves.toMatchObject({ metadata: { name: "kuber-system" }, }); }); test("creates immutable revisions and uses ETags for replacement", async () => { let uid = 0; const store = new MemoryWorkspaceStore({ now: () => new Date("2026-09-02T00:00:00.000Z"), uid: () => `uid-${++uid}`, }); const created = await store.create({ id: "demo", source, config: { a: 1 }, }); expect(created.metadata.uid).toBe("uid-1"); expect(workspaceEtag(created)).toBe('"1"'); const updated = await store.update( "demo", { source: { ...source, digest: "sha256:def" }, config: { a: 2 } }, workspaceEtag(created), ); expect(updated.metadata.resourceVersion).toBe("2"); expect(updated.status.latestRevision).toBe(2); expect((await store.getRevision("demo", 1))?.spec.config).toEqual({ a: 1 }); expect((await store.getRevision("demo", 2))?.spec.config).toEqual({ a: 2 }); expect(store.update("demo", { source }, '"1"')).rejects.toBeInstanceOf( WorkspaceConflictError, ); }); test("rejects inline source and oversized config payloads", async () => { const store = new MemoryWorkspaceStore(); expect( store.create({ id: "inline", source: { ...source, content: "source" } as typeof source, }), ).rejects.toBeInstanceOf(WorkspaceValidationError); expect( store.create({ id: "large", source, config: "x".repeat(MAX_WORKSPACE_CONFIG_BYTES), }), ).rejects.toBeInstanceOf(WorkspaceValidationError); }); });