107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
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,
|
|
searchExecution: {
|
|
freshSearch: true,
|
|
startedAt: "2026-03-30T20:45:00Z",
|
|
completedAt: "2026-03-30T21:00:00Z",
|
|
artifactsRoot: "/tmp/flight-finder-report-status",
|
|
notes: ["Fresh bounded search executed for this report."]
|
|
},
|
|
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);
|
|
});
|