import { describe, expect, it } from "vitest"; import { countAxelQuoteTiers, extractAxelQuoteContract, } from "@/scripts/phase0/lib/axel-quote-contract"; import { pickBestQuoteEntry, scoreQuoteBody } from "@/scripts/phase0/lib/har-parse"; import { buildQuoteContractSchema } from "@/scripts/phase0/lib/schema-infer"; const AXEL_SAMPLE = { data: { rates: { standard: { lowest: { price: 100, days: 5, serviceType: "lowest" }, fastest: { price: 200, days: 2, serviceType: "fastest" }, bestValue: { price: 150, days: 3, serviceType: "bestValue" }, }, guaranteed: { bestValue: { price: 250, days: 2, serviceType: "bestValue" }, }, }, availableRates: { rate_a: { price: 100, serviceLevel: "standard", serviceType: "lowest" }, rate_b: { price: 200, serviceLevel: "standard", serviceType: "fastest" }, rate_c: { price: 110, serviceLevel: "guaranteed", serviceType: "lowest" }, rate_d: { price: 220, serviceLevel: "guaranteed", serviceType: "fastest" }, }, }, }; describe("phase0 axel-quote-contract", () => { it("识别 data.rates 四档与 availableRates", () => { const c = extractAxelQuoteContract(AXEL_SAMPLE); expect(c.fourTierCoverage.standardLowest).toBe(true); expect(c.fourTierCoverage.standardFastest).toBe(true); expect(c.availableRateCount).toBe(4); expect(countAxelQuoteTiers(AXEL_SAMPLE).pricedLeafCount).toBeGreaterThanOrEqual(4); }); }); describe("phase0 har-parse", () => { it("pickBestQuoteEntry 识别 axel/quote 响应", () => { const har = { log: { entries: [ { request: { url: "https://services.mothership.com/axel/quote", method: "POST", }, response: { status: 200, content: { mimeType: "application/json", text: JSON.stringify(AXEL_SAMPLE), }, }, }, ], }, }; const picked = pickBestQuoteEntry(har.log!.entries!); expect(picked).not.toBeNull(); expect(scoreQuoteBody(picked!.body)).toBeGreaterThanOrEqual(5); }); }); describe("phase0 schema-infer", () => { it("buildQuoteContractSchema 产出含 body 与 sourceHar", () => { const doc = buildQuoteContractSchema({ body: AXEL_SAMPLE, harEntry: { url: "https://services.mothership.com/axel/quote", method: "POST", status: 200, }, }); expect(doc.$schema).toContain("json-schema.org"); expect(doc.sourceHar.url).toContain("axel/quote"); expect(doc.body.type).toBe("object"); }); });