Ignore malformed direct map routes
This commit is contained in:
@@ -476,6 +476,28 @@ describe("FlightsMapStartPage — C.4 integration", () => {
|
||||
expect(popups[1]!.content).toContain("https://www.aeroflot.ru/sb/app/ru-ru");
|
||||
});
|
||||
|
||||
it("does not draw malformed multi-hop direct routes when transfers are off", () => {
|
||||
searchState.routes = [
|
||||
{ route: ["SVO", "LED"], isDirect: true },
|
||||
{ route: ["SVO", "AER", "LED"], isDirect: true },
|
||||
];
|
||||
setMapFilter({
|
||||
departure: "MOW",
|
||||
arrival: "LED",
|
||||
date: null,
|
||||
showInternal: false,
|
||||
showInternational: false,
|
||||
showTransfers: false,
|
||||
});
|
||||
|
||||
render(<FlightsMapStartPage />);
|
||||
|
||||
const polylines = lastMapCanvasProps!["polylines"] as Array<{ cityIds: string[] }>;
|
||||
expect(polylines).toEqual([
|
||||
expect.objectContaining({ cityIds: ["MOW", "LED"] }),
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not render popups in spider mode (departure only)", () => {
|
||||
searchState.routes = [{ route: ["MOW", "LED"], isDirect: true }];
|
||||
render(<FlightsMapStartPage />);
|
||||
|
||||
@@ -102,6 +102,49 @@ describe("filterRoutes — connections", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("filterRoutes — route mode without transfer-only toggle", () => {
|
||||
it("drops malformed direct routes that contain intermediate cities", () => {
|
||||
const routes: IFlightRoute[] = [
|
||||
{ route: ["SVO", "LED"], isDirect: true },
|
||||
{ route: ["SVO", "AER", "LED"], isDirect: true },
|
||||
{ route: ["SVO", "AER", "LED"], isDirect: false },
|
||||
];
|
||||
|
||||
const out = filterRoutes(
|
||||
routes,
|
||||
filter({ departure: "MOW", arrival: "LED", connections: false }),
|
||||
d,
|
||||
);
|
||||
|
||||
expect(out).toEqual([{ route: ["SVO", "LED"], isDirect: true }]);
|
||||
});
|
||||
|
||||
it("keeps connecting routes in route mode when transfer-only toggle is active", () => {
|
||||
const routes: IFlightRoute[] = [
|
||||
{ route: ["SVO", "LED"], isDirect: true },
|
||||
{ route: ["SVO", "AER", "LED"], isDirect: false },
|
||||
];
|
||||
|
||||
const out = filterRoutes(
|
||||
routes,
|
||||
filter({ departure: "MOW", arrival: "LED", connections: true }),
|
||||
d,
|
||||
);
|
||||
|
||||
expect(out).toEqual([{ route: ["SVO", "AER", "LED"], isDirect: false }]);
|
||||
});
|
||||
|
||||
it("does not apply endpoint-direct filtering in spider mode", () => {
|
||||
const routes: IFlightRoute[] = [
|
||||
{ route: ["SVO", "AER", "LED"], isDirect: true },
|
||||
];
|
||||
|
||||
const out = filterRoutes(routes, filter({ departure: "MOW" }), d);
|
||||
|
||||
expect(out).toEqual(routes);
|
||||
});
|
||||
});
|
||||
|
||||
describe("filterRoutes — airport-code normalization", () => {
|
||||
it("treats airport codes (SVO, JFK) as their city codes (MOW, NYC)", () => {
|
||||
const routes: IFlightRoute[] = [
|
||||
|
||||
@@ -17,7 +17,10 @@ import type { IFlightRoute, IFlightsMapFilterState } from "./types.js";
|
||||
|
||||
export function filterRoutes(
|
||||
routes: IFlightRoute[],
|
||||
filter: Pick<IFlightsMapFilterState, "domestic" | "international" | "connections">,
|
||||
filter: Pick<
|
||||
IFlightsMapFilterState,
|
||||
"departure" | "arrival" | "domestic" | "international" | "connections"
|
||||
>,
|
||||
dictionaries: IDictionaries,
|
||||
): IFlightRoute[] {
|
||||
const { domestic, international, connections } = filter;
|
||||
@@ -32,6 +35,17 @@ export function filterRoutes(
|
||||
r.route.some((code) => dictionaries.otherCityCodes.has(toCityCode(code)));
|
||||
|
||||
const hasConnections = (r: IFlightRoute): boolean => !r.isDirect;
|
||||
const isEndpointDirectRoute = (r: IFlightRoute): boolean => {
|
||||
if (!filter.departure || !filter.arrival) return true;
|
||||
if (!r.isDirect) return false;
|
||||
|
||||
const normalized = r.route.map(toCityCode);
|
||||
return (
|
||||
normalized.length === 2 &&
|
||||
normalized[0] === toCityCode(filter.departure) &&
|
||||
normalized[1] === toCityCode(filter.arrival)
|
||||
);
|
||||
};
|
||||
|
||||
const predicates: Array<(r: IFlightRoute) => boolean> = [];
|
||||
|
||||
@@ -39,6 +53,7 @@ export function filterRoutes(
|
||||
else if (international && !domestic) predicates.push(isInternational);
|
||||
|
||||
if (connections) predicates.push(hasConnections);
|
||||
else if (filter.arrival) predicates.push(isEndpointDirectRoute);
|
||||
|
||||
if (predicates.length === 0) return routes;
|
||||
return routes.filter((r) => predicates.every((p) => p(r)));
|
||||
|
||||
Reference in New Issue
Block a user