58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { validateUsageEvent, type UsageEventV1 } from "./usageTypes";
|
|
|
|
const fixtures = path.join(process.cwd(), "docs", "schemas", "fixtures");
|
|
|
|
function fixture(relative: string): Record<string, unknown> {
|
|
return JSON.parse(fs.readFileSync(path.join(fixtures, relative), "utf8"));
|
|
}
|
|
|
|
describe("UsageEvent v1 shared contract", () => {
|
|
for (const name of ["confirmed", "unknown"]) {
|
|
it(`accepts the shared ${name} fixture`, () => {
|
|
const result = validateUsageEvent(fixture(`accepted/${name}.json`));
|
|
expect(result.issues).toEqual([]);
|
|
expect(result.value?.schema_version).toBe(1);
|
|
});
|
|
}
|
|
|
|
it("applies every shared rejected fixture", () => {
|
|
const rejected = fixture("rejected/unsafe-token-sum.json") as {
|
|
base_fixture: string;
|
|
patch: Partial<UsageEventV1>;
|
|
expected_reason: string;
|
|
};
|
|
const basePath = path.resolve(fixtures, "rejected", rejected.base_fixture);
|
|
const event = {
|
|
...JSON.parse(fs.readFileSync(basePath, "utf8")),
|
|
...rejected.patch,
|
|
};
|
|
expect(validateUsageEvent(event).issues).toContain(
|
|
rejected.expected_reason
|
|
);
|
|
});
|
|
|
|
it.each([
|
|
["source", "gateway_final"],
|
|
["authority_class", "provider_reconciled"],
|
|
["revision", 2],
|
|
])("rejects unsupported %s", (field, value) => {
|
|
const event = { ...fixture("accepted/confirmed.json"), [field]: value };
|
|
expect(validateUsageEvent(event).value).toBeUndefined();
|
|
});
|
|
|
|
it("rejects non-string wire timestamps", () => {
|
|
const event = {
|
|
...fixture("accepted/confirmed.json"),
|
|
started_at: null,
|
|
observed_at: 0,
|
|
completed_at: 0,
|
|
};
|
|
expect(validateUsageEvent(event).issues).toEqual(
|
|
expect.arrayContaining(["invalid_observed_at", "invalid_completed_at"])
|
|
);
|
|
});
|
|
});
|