Files
NianAIGC/tests/jobs-go-contract.test.ts

56 lines
2.3 KiB
TypeScript

import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { createPublicGenerationJob, PublicApiConflictError } from "@/lib/server/public-api-jobs";
const fixtureUrl = new URL("../contracts/jobs/jobs-v1.json", import.meta.url);
let runtimeDir: string | undefined;
afterEach(async () => {
if (runtimeDir) await rm(runtimeDir, { recursive: true, force: true });
runtimeDir = undefined;
});
describe("jobs v1 cross-language contract", () => {
it("freezes statuses, bounds and retry behavior", async () => {
const fixture = JSON.parse(await readFile(fixtureUrl, "utf8"));
expect(fixture.version).toBe(1);
expect(fixture.statuses).toEqual(["queued", "running", "succeeded", "failed", "expired", "cancelled"]);
expect(fixture.terminalStatuses).toEqual(["succeeded", "failed", "expired", "cancelled"]);
expect(fixture.priority).toEqual({ minimum: -100, maximum: 100, default: 0 });
expect(fixture.claim).toEqual({ minimumBatch: 1, maximumBatch: 20, defaultLockTimeoutSeconds: 300 });
});
it("uses stable request fingerprints and rejects payload drift", async () => {
const fixture = JSON.parse(await readFile(fixtureUrl, "utf8"));
runtimeDir = await mkdtemp(join(tmpdir(), "zhinian-jobs-contract-"));
process.env.ZHINIAN_RUNTIME_DIR = runtimeDir;
process.env.ZHINIAN_DATA_BACKEND = "local";
process.env.JIMENG_VISUAL_MOCK = "true";
const request = new Request("http://local.test/api/v1/jobs", {
headers: { "Idempotency-Key": "header-key" },
});
const input = {
client: { id: "fixture-client", key: "secret" },
request,
origin: "http://local.test",
body: fixture.idempotency.body,
};
const created = await createPublicGenerationJob(input);
expect(created.reused).toBe(false);
expect(created.job.idempotencyKey).toBe("header-key");
expect(created.job.idempotencyFingerprint).toBe(fixture.idempotency.fingerprint);
const replay = await createPublicGenerationJob(input);
expect(replay.reused).toBe(true);
expect(replay.job.id).toBe(created.job.id);
await expect(createPublicGenerationJob({
...input,
body: { ...fixture.idempotency.body, prompt: "hello!" },
})).rejects.toBeInstanceOf(PublicApiConflictError);
});
});