import test from "node:test"; import assert from "node:assert/strict"; import { DFW_BLQ_2026_PROMPT_DRAFT, normalizeFlightReportRequest } from "../src/request-normalizer.js"; import { getFlightReportStatus } from "../src/report-status.js"; import type { FlightReportPayload } from "../src/types.js"; function buildPayload(): 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", crossCheckStatus: "not-available" } ], 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("getFlightReportStatus treats missing recipient email as delivery-only blocker", () => { const normalized = normalizeFlightReportRequest({ ...DFW_BLQ_2026_PROMPT_DRAFT, recipientEmail: null }); const payload = { ...buildPayload(), request: normalized.request }; const status = getFlightReportStatus(normalized, payload); assert.equal(status.readyToSearch, true); assert.equal(status.pdfReady, true); assert.equal(status.emailReady, false); assert.deepEqual(status.needsMissingInputs, ["recipient email"]); }); test("getFlightReportStatus marks all-sources-failed as a blocked but chat-summarizable outcome", () => { const normalized = normalizeFlightReportRequest(DFW_BLQ_2026_PROMPT_DRAFT); const status = getFlightReportStatus(normalized, { ...buildPayload(), sourceFindings: [ { source: "kayak", status: "blocked", checkedAt: "2026-03-30T21:00:00Z", notes: ["Timed out."] }, { source: "skyscanner", status: "blocked", checkedAt: "2026-03-30T21:00:00Z", notes: ["Timed out."] } ], quotes: [], rankedOptions: [], executiveSummary: [], degradedReasons: ["All configured travel sources failed."] }); assert.equal(status.terminalOutcome, "all-sources-failed"); assert.equal(status.chatSummaryReady, true); assert.equal(status.pdfReady, false); assert.equal(status.degraded, true); });