Files
flights_web/src/features/schedule/json-ld.test.ts
T
gnezim 93f49cddae Add schedule SEO and JSON-LD tests (Phase 3D)
Tests cover start page, search, and details SEO builders plus
Flight/ItemList JSON-LD schema generation for schedule pages.
2026-04-15 09:28:04 +03:00

165 lines
4.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { Flight, ItemList } from "schema-dts";
import { buildScheduleFlightJsonLd, buildScheduleFlightListJsonLd } from "./json-ld.js";
import type { ISimpleFlight } from "./types.js";
function makeDirectFlight(overrides: Partial<{
carrier: string;
flightNumber: string;
depCode: string;
depAirport: string;
arrCode: string;
arrAirport: string;
depTime: string;
arrTime: string;
}> = {}): ISimpleFlight {
return {
id: "test-schedule-1",
routeType: "Direct",
flightId: {
carrier: overrides.carrier ?? "SU",
flightNumber: overrides.flightNumber ?? "0012",
suffix: "",
date: "20220527",
},
flyingTime: "1h 30m",
operatingBy: {},
status: "Scheduled",
leg: {
index: 0,
status: "Scheduled",
flyingTime: "1h 30m",
updated: "2022-05-27T10:00:00Z",
dayChange: 0,
equipment: { name: "Airbus A320", code: "320" },
flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false },
operatingBy: {},
departure: {
scheduled: {
airport: overrides.depAirport ?? "Sheremetyevo",
airportCode: overrides.depCode ?? "SVO",
city: "Moscow",
cityCode: "MOW",
countryCode: "RU",
},
checkingStatus: "closed",
times: {
scheduledDeparture: {
dayChange: { value: 0, title: "" },
local: overrides.depTime ?? "2022-05-27T10:00:00",
localTime: "10:00",
tzOffset: 3,
utc: "2022-05-27T07:00:00Z",
},
},
},
arrival: {
scheduled: {
airport: overrides.arrAirport ?? "Pulkovo",
airportCode: overrides.arrCode ?? "LED",
city: "Saint Petersburg",
cityCode: "LED",
countryCode: "RU",
},
times: {
scheduledArrival: {
dayChange: { value: 0, title: "" },
local: overrides.arrTime ?? "2022-05-27T11:30:00",
localTime: "11:30",
tzOffset: 3,
utc: "2022-05-27T08:30:00Z",
},
},
},
},
};
}
describe("buildScheduleFlightJsonLd", () => {
it("returns a Flight schema with correct @type", () => {
const flight = makeDirectFlight();
const result = buildScheduleFlightJsonLd(flight);
expect(result["@type"]).toBe("Flight");
});
it("sets flightNumber in IATA format", () => {
const flight = makeDirectFlight({ carrier: "SU", flightNumber: "0012" });
const result = buildScheduleFlightJsonLd(flight);
expect(result.flightNumber).toBe("SU0012");
});
it("maps departure airport", () => {
const flight = makeDirectFlight({ depCode: "SVO", depAirport: "Sheremetyevo" });
const result = buildScheduleFlightJsonLd(flight);
expect(result.departureAirport).toEqual({
"@type": "Airport",
iataCode: "SVO",
name: "Sheremetyevo",
});
});
it("maps arrival airport", () => {
const flight = makeDirectFlight({ arrCode: "LED", arrAirport: "Pulkovo" });
const result = buildScheduleFlightJsonLd(flight);
expect(result.arrivalAirport).toEqual({
"@type": "Airport",
iataCode: "LED",
name: "Pulkovo",
});
});
it("is type-compatible with schema-dts Flight", () => {
const flight = makeDirectFlight();
const result = buildScheduleFlightJsonLd(flight);
const _typed: Flight = result;
expect(_typed["@type"]).toBe("Flight");
});
});
describe("buildScheduleFlightListJsonLd", () => {
it("returns an ItemList schema", () => {
const flights = [makeDirectFlight()];
const result = buildScheduleFlightListJsonLd(flights, "Schedule SVO to LED");
expect(result["@type"]).toBe("ItemList");
});
it("sets the description", () => {
const flights = [makeDirectFlight()];
const result = buildScheduleFlightListJsonLd(flights, "Schedule SVO to LED");
expect(result.description).toBe("Schedule SVO to LED");
});
it("wraps each flight as a ListItem with position", () => {
const flights = [
makeDirectFlight({ carrier: "SU", flightNumber: "0012" }),
makeDirectFlight({ carrier: "SU", flightNumber: "0013" }),
];
const result = buildScheduleFlightListJsonLd(flights, "Flights");
const items = result.itemListElement as unknown as Array<{ position: number }>;
expect(Array.isArray(items)).toBe(true);
expect(items).toHaveLength(2);
expect(items[0]).toHaveProperty("position", 1);
expect(items[1]).toHaveProperty("position", 2);
});
it("handles empty flight list", () => {
const result = buildScheduleFlightListJsonLd([], "No flights");
expect(result["@type"]).toBe("ItemList");
expect(result.itemListElement).toEqual([]);
});
it("is type-compatible with schema-dts ItemList", () => {
const result = buildScheduleFlightListJsonLd([], "test");
const _typed: ItemList = result;
expect(_typed["@type"]).toBe("ItemList");
});
});