Files
agents-marketplace/tests/unit/surplus-history-export.test.ts
david a5cb4b03e1
Some checks failed
CI / typecheck + vitest (Node 20) (push) Has been cancelled
feat: backfill Vector proofs from the Surplus support export
2026-08-28 12:29:45 +02:00

99 lines
3.5 KiB
TypeScript

import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { loadHistoricalSalesCsv } from "../../supplier/src/surplus/historyExport.js";
const HEADER =
"request_id,settled_at,model,input_tokens,output_tokens,seller_earned_usd,settlement_status,settlement_type,tx_hash";
const directories: string[] = [];
async function csvFile(content: string): Promise<string> {
const directory = await mkdtemp(join(tmpdir(), "surplus-history-"));
directories.push(directory);
const path = join(directory, "sales.csv");
await writeFile(path, content, "utf8");
return path;
}
afterEach(async () => {
await Promise.all(directories.splice(0).map((path) =>
rm(path, { recursive: true, force: true })
));
});
describe("loadHistoricalSalesCsv", () => {
it("maps settled export rows onto publisher sales and skips unsettled rows", async () => {
const baseTx = "0x" + "A".repeat(64);
const path = await csvFile([
HEADER,
`"01SALE1","2026-08-28T07:39:33.869Z","deepseek-v4-flash","151204","805","0.000607","confirmed","onchain","${baseTx}"`,
`"01SALE2","2026-08-28T07:39:22.308Z","deepseek-v4-flash","10","2","1.5","confirmed","onchain",""`,
`"01SALE3","2026-08-28T07:39:48.036Z","deepseek-v4-flash","47257","1761","0.000202","accrued","credit",""`,
].join("\n"));
const result = await loadHistoricalSalesCsv(path, "offer-1");
expect(result.skippedUnsettled).toBe(1);
expect(result.settledWithoutTx).toBe(1);
expect(result.sales).toHaveLength(2);
expect(result.sales[0]).toMatchObject({
id: "01SALE1",
offerId: "offer-1",
model: "deepseek-v4-flash",
settlementStatus: "confirmed",
createdAt: "2026-08-28T07:39:33.869Z",
createdAtMs: Date.parse("2026-08-28T07:39:33.869Z"),
sellerCostMicroUsd: 607,
inputTokens: 151_204,
outputTokens: 805,
cacheReadTokens: 0,
effectiveInputUsdPer1m: 0,
effectiveOutputUsdPer1m: 0,
transactionHash: baseTx.toLowerCase(),
});
expect(result.sales[1]).toMatchObject({
id: "01SALE2",
sellerCostMicroUsd: 1_500_000,
transactionHash: null,
});
});
it("rejects an unexpected header, duplicate ids, and malformed rows", async () => {
const wrongHeader = await csvFile("request_id,foo\n\"a\",\"b\"");
await expect(loadHistoricalSalesCsv(wrongHeader, "offer-1")).rejects.toThrow(
/header must be exactly/,
);
const duplicate = await csvFile([
HEADER,
`"01SAME","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain",""`,
`"01SAME","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain",""`,
].join("\n"));
await expect(loadHistoricalSalesCsv(duplicate, "offer-1")).rejects.toThrow(
/repeats request_id/,
);
const badTx = await csvFile([
HEADER,
`"01SALE","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain","0x123"`,
].join("\n"));
await expect(loadHistoricalSalesCsv(badTx, "offer-1")).rejects.toThrow(
/invalid tx_hash/,
);
const badTokens = await csvFile([
HEADER,
`"01SALE","2026-08-28T07:39:33.869Z","m","-4","1","0.1","confirmed","onchain",""`,
].join("\n"));
await expect(loadHistoricalSalesCsv(badTokens, "offer-1")).rejects.toThrow(
/input_tokens/,
);
await expect(loadHistoricalSalesCsv(badTokens, " ")).rejects.toThrow(
/non-empty offer id/,
);
});
});