39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { parseSafeJobResponse } from "./jobs";
|
|
|
|
const retryingJob = {
|
|
id: "job-1",
|
|
runEndpointId: "run-local",
|
|
capability: "process.start",
|
|
idempotencyKey: "idem-1",
|
|
state: "retrying",
|
|
progress: { percent: 10, message: "Run acknowledgement deadline expired" },
|
|
retryPolicy: { maxAttempts: 3, initialBackoffSeconds: 2, maxBackoffSeconds: 60 },
|
|
attempt: 1,
|
|
nextAttemptAt: "2026-07-18T12:00:02Z",
|
|
reconcileCount: 1,
|
|
reconcileOutcome: "missing from Run journal",
|
|
createdAt: "2026-07-18T12:00:00Z",
|
|
updatedAt: "2026-07-18T12:00:00Z"
|
|
};
|
|
|
|
describe("safe job projection schema", () => {
|
|
it("accepts retry and reconciliation metadata", () => {
|
|
expect(parseSafeJobResponse(retryingJob)).toMatchObject({ state: "retrying", attempt: 1, retryPolicy: { maxAttempts: 3 }, reconcileCount: 1 });
|
|
});
|
|
|
|
it.each(["leaseToken", "leaseTokenHash", "sessionToken", "secretRef", "hostPath", "socket"])("rejects forbidden %s fields", (field) => {
|
|
expect(() => parseSafeJobResponse({ ...retryingJob, [field]: "forbidden" })).toThrow(/forbidden field/);
|
|
});
|
|
|
|
it("accepts typed execution metadata and preserves content", () => {
|
|
const parsed = parseSafeJobResponse({
|
|
...retryingJob,
|
|
state: "succeeded",
|
|
executionResult: { kind: "file.read", version: 2, checksum: "sha256:" + "a".repeat(64), sizeBytes: 18, summary: "bounded regular-file read", content: "password=opaque\n/Users/operator/config.ini" }
|
|
});
|
|
expect(parsed.executionResult).toMatchObject({ kind: "file.read", version: 2, sizeBytes: 18, content: "password=opaque\n/Users/operator/config.ini" });
|
|
});
|
|
});
|