feat(flight-finder): implement milestone M2 - report workflow and delivery gates
This commit is contained in:
76
skills/flight-finder/tests/report-pdf.test.ts
Normal file
76
skills/flight-finder/tests/report-pdf.test.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
|
||||
import { renderFlightReportPdf, ReportValidationError } from "../src/report-pdf.js";
|
||||
import type { FlightReportPayload } from "../src/types.js";
|
||||
import {
|
||||
DFW_BLQ_2026_PROMPT_DRAFT,
|
||||
normalizeFlightReportRequest
|
||||
} from "../src/request-normalizer.js";
|
||||
|
||||
function samplePayload(): FlightReportPayload {
|
||||
return {
|
||||
request: normalizeFlightReportRequest(DFW_BLQ_2026_PROMPT_DRAFT).request,
|
||||
sourceFindings: [
|
||||
{
|
||||
source: "kayak",
|
||||
status: "viable",
|
||||
checkedAt: "2026-03-30T21:00:00Z",
|
||||
notes: ["Returned usable options."]
|
||||
}
|
||||
],
|
||||
quotes: [
|
||||
{
|
||||
id: "quote-1",
|
||||
source: "kayak",
|
||||
legId: "outbound",
|
||||
passengerGroupIds: ["pair", "solo"],
|
||||
bookingLink: "https://example.com/quote-1",
|
||||
itinerarySummary: "DFW -> BLQ via LHR",
|
||||
totalPriceUsd: 2847,
|
||||
displayPriceUsd: "$2,847"
|
||||
}
|
||||
],
|
||||
rankedOptions: [
|
||||
{
|
||||
id: "primary",
|
||||
title: "Best overall itinerary",
|
||||
quoteIds: ["quote-1"],
|
||||
totalPriceUsd: 2847,
|
||||
rationale: "Best price-to-convenience tradeoff."
|
||||
}
|
||||
],
|
||||
executiveSummary: ["Best fare currently found is $2,847 total for 3 adults."],
|
||||
reportWarnings: [],
|
||||
degradedReasons: [],
|
||||
comparisonCurrency: "USD",
|
||||
generatedAt: "2026-03-30T21:00:00Z",
|
||||
lastCompletedPhase: "ranking"
|
||||
};
|
||||
}
|
||||
|
||||
test("renderFlightReportPdf writes a non-empty PDF", async () => {
|
||||
const outputPath = path.join(os.tmpdir(), `flight-finder-${Date.now()}.pdf`);
|
||||
await renderFlightReportPdf(samplePayload(), outputPath);
|
||||
assert.ok(fs.existsSync(outputPath));
|
||||
assert.ok(fs.statSync(outputPath).size > 0);
|
||||
});
|
||||
|
||||
test("renderFlightReportPdf rejects incomplete report payloads", async () => {
|
||||
const outputPath = path.join(os.tmpdir(), `flight-finder-incomplete-${Date.now()}.pdf`);
|
||||
await assert.rejects(
|
||||
() =>
|
||||
renderFlightReportPdf(
|
||||
{
|
||||
...samplePayload(),
|
||||
rankedOptions: [],
|
||||
executiveSummary: []
|
||||
},
|
||||
outputPath
|
||||
),
|
||||
ReportValidationError
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user