Verified example · TypeScript
File tests
examples/file-tests.ts
@cavi-ai/api-clientv0.21.007f0ee45
import assert from "node:assert/strict";
import { test } from "node:test";
import { isApiClientError, isAuthError } from "@cavi-ai/api-client";
import { CodexFilesClient } from "@cavi-ai/api-client/providers/codex/files";
import { uploadBatchInput, removeBatchInput } from "./batch-files.js";
function fixture(reply: (url: string, init?: RequestInit) => Response) {
const calls: { url: string; init?: RequestInit }[] = [];
const files = new CodexFilesClient({ apiKey: "fixture-key", defaultTimeoutMs: 1_000,
fetchImpl: async (url, init) => {
calls.push({ url: String(url), init });
return reply(String(url), init);
},
});
return { files, calls };
}
test("uploads provider JSONL as multipart and retains file metadata without deleting", async () => {
const app = fixture(() => Response.json({ id: "file-1", object: "file", bytes: 12 }));
const jsonl = '{"custom_id":"one","method":"POST","url":"/v1/responses","body":{"model":"server-model","input":"Question"}}';
const file = await uploadBatchInput(app.files, jsonl);
assert.deepEqual(file, { id: "file-1", object: "file", bytes: 12 });
assert.equal(app.calls.length, 1);
const { url, init } = app.calls[0];
assert.equal(url, "https://api.openai.com/v1/files");
assert.equal(init?.method, "POST");
assert.equal(new Headers(init?.headers).get("Authorization"), "Bearer fixture-key");
assert.ok(init?.body instanceof FormData);
assert.equal(init.body.get("purpose"), "batch");
const content = init.body.get("file");
assert.ok(content instanceof File);
assert.equal(content.name, "input.jsonl");
assert.equal(await content.text(), jsonl);
});
test("cleans up a persisted ID through a newly configured worker client", async () => {
const app = fixture(() => Response.json({ id: "file-1", deleted: true }));
const receipt = await removeBatchInput(app.files, "file-1");
assert.deepEqual(receipt, { id: "file-1", deleted: true });
assert.equal(app.calls.length, 1);
assert.equal(app.calls[0].url, "https://api.openai.com/v1/files/file-1");
assert.equal(app.calls[0].init?.method, "DELETE");
});
test("rejects blank input or IDs before provider work", async () => {
const app = fixture(() => { throw new Error("Invalid input reached the provider"); });
for (const value of ["", " ", "\n"]) {
await assert.rejects(uploadBatchInput(app.files, value), { code: "invalid_request" });
await assert.rejects(removeBatchInput(app.files, value), { code: "invalid_request" });
}
assert.equal(app.calls.length, 0);
});
test("rejects upload responses without a usable file ID", async () => {
for (const reply of [null, {}, { id: "" }, { id: " " }]) {
const app = fixture(() => Response.json(reply));
await assert.rejects(uploadBatchInput(app.files, "{}"), { code: "protocol_mismatch" });
assert.equal(app.calls.length, 1, "an ambiguous upload must not be replayed or deleted automatically");
}
});
test("requires deletion confirmation for the same saved ID", async () => {
for (const reply of [null, { id: "file-1", deleted: false }, { id: "foreign", deleted: true }, { deleted: true }]) {
const app = fixture(() => Response.json(reply));
await assert.rejects(removeBatchInput(app.files, "file-1"), (error) => {
assert.ok(isApiClientError(error));
assert.equal(error.code, "protocol_mismatch");
assert.equal((error.cause as { fileId: string }).fileId, "file-1");
return true;
});
assert.equal(app.calls.length, 1);
}
});
test("retains failed cleanup as an exception rather than reporting deletion", async () => {
const app = fixture(() => Response.json({}, { status: 503 }));
await assert.rejects(removeBatchInput(app.files, "file-1"), isApiClientError);
assert.equal(app.calls.length, 1);
});
test("keeps authentication failures as exceptions", async () => {
const app = fixture(() => Response.json({}, { status: 401 }));
await assert.rejects(uploadBatchInput(app.files, "{}"), isAuthError);
assert.equal(app.calls.length, 1);
});
Package imports
Referenced by
Artifact provenance
- Package
- @cavi-ai/api-client@0.21.0
- Release
- v0.21.0
- Commit
07f0ee45424c267278f7b0c89a7dcea4e2492cc1- Source
examples/file-tests.ts- Tarball SHA-256
0924b5d3a7a40869bd44fedc47a9b8eb9844c2af1fd5c7ca77469d8b7c0b8558- Content SHA-256
24eff463c41582eaf5e70c58f42e5ae13bd12d02fa14ae2a886afa3abf5cdf48