Files
flights_web/tests/e2e/helpers/api-fixtures.ts
T

182 lines
6.2 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import type { Page, Route } from "@playwright/test";
import { replaceVvoMjzFixtureDates } from "./dates";
const FIXTURE_DIR = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"../../fixtures/api",
);
function fixtureText(name: string): string {
return fs.readFileSync(path.join(FIXTURE_DIR, name), "utf8");
}
function vvoMjzFixtureText(name: string): string {
return replaceVvoMjzFixtureDates(fixtureText(name));
}
async function fulfillJson(route: Route, body: string): Promise<void> {
await route.fulfill({
status: 200,
contentType: "application/json",
body,
});
}
export async function routeDictionaryFixtures(page: Page): Promise<void> {
await page.route("**/api/dictionary/1/world_regions", (route) =>
fulfillJson(route, fixtureText("dictionary-regions.json")),
);
await page.route("**/api/dictionary/1/countries", (route) =>
fulfillJson(route, fixtureText("dictionary-countries.json")),
);
await page.route("**/api/dictionary/1/cities", (route) =>
fulfillJson(route, fixtureText("dictionary-cities.json")),
);
await page.route("**/api/dictionary/1/airports", (route) =>
fulfillJson(route, fixtureText("dictionary-airports.json")),
);
}
export async function routeAppSettingsFixture(page: Page): Promise<void> {
await page.route("**/api/appSettings", (route) =>
fulfillJson(route, fixtureText("app-settings.json")),
);
}
export async function routePopularRequestsFixture(page: Page): Promise<void> {
await page.route("**/api/Requests/1/getpopular", (route) =>
fulfillJson(route, fixtureText("popular-requests.json")),
);
}
export async function routeOnlineboardRouteFixtures(page: Page): Promise<void> {
await routePopularRequestsFixture(page);
await routeAppSettingsFixture(page);
await page.route("**/api/flights/v1/*/days/**/board/", (route) =>
fulfillJson(route, fixtureText("board-days-route.json")),
);
await page.route("**/api/flights/v1.1/*/board?**", async (route) => {
const fixture = JSON.parse(fixtureText("board-by-route.json")) as {
data: {
routes: BoardRouteFixture[];
};
};
shiftBoardFixtureToTomorrow(fixture);
const url = new URL(route.request().url());
const from = url.searchParams.get("timeFrom");
const to = url.searchParams.get("timeTo");
if (from && to) {
const fromHHmm = from.slice(0, 5);
const toHHmm = to.slice(0, 5);
fixture.data.routes = fixture.data.routes.filter((flight) => {
const localTime = flight.leg.departure.times.scheduledDeparture?.localTime ?? "";
return localTime >= fromHHmm && localTime <= toHHmm;
});
}
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(fixture),
});
});
}
export async function routeScheduleSearchFixtures(page: Page): Promise<void> {
await routeAppSettingsFixture(page);
await page.route("**/api/flights/v1/*/days/**/schedule/", (route) =>
fulfillJson(route, fixtureText("schedule-days-route.json")),
);
await page.route("**/api/flights/1/*/schedule?**", (route) =>
fulfillJson(route, fixtureText("schedule-search.json")),
);
}
export async function routeScheduleVvoMjzFixtures(page: Page): Promise<void> {
await routeDictionaryFixtures(page);
await routeAppSettingsFixture(page);
await page.route("**/api/flights/v1/*/days/**/schedule/", (route) =>
fulfillJson(route, fixtureText("schedule-days-route.json")),
);
await page.route("**/api/flights/1/*/schedule?**", (route) =>
fulfillJson(route, vvoMjzFixtureText("schedule-search-vvo-mjz.json")),
);
await page.route("**/api/flights/v1.1/*/schedule/details?**", (route) =>
fulfillJson(route, vvoMjzFixtureText("schedule-details-vvo-mjz.json")),
);
}
export async function routeScheduleVvoMjzServicesFixtures(
page: Page,
): Promise<void> {
await routeDictionaryFixtures(page);
await routeAppSettingsFixture(page);
await page.route("**/api/flights/v1/*/days/**/schedule/", (route) =>
fulfillJson(route, fixtureText("schedule-days-route.json")),
);
await page.route("**/api/flights/1/*/schedule?**", (route) =>
fulfillJson(route, vvoMjzFixtureText("schedule-search-vvo-mjz.json")),
);
await page.route("**/api/flights/v1.1/*/schedule/details?**", (route) => {
const fixture = JSON.parse(vvoMjzFixtureText("schedule-details-vvo-mjz.json"));
const actual = fixture.data.routes[0].leg.equipment.aircraft.actual;
actual.onBoardServices = [
{
id: "2",
title: "Space+",
url: "http://www.aeroflot.ru/cms/ru/flight/space_plus",
},
{
id: "5",
title: "Интернет на борту",
url: "http://www.aeroflot.ru/cms/ru/flight/on_board/at_height",
},
{
id: "8",
title: "Выбор места",
url: "https://www.aeroflot.ru/ru-ru/additional_service/#seat_reservation",
},
];
return route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(fixture),
});
});
}
interface BoardRouteFixture {
flightId: { date?: string; dateLT?: string };
leg: {
departure: { times: Record<string, { local?: string; utc?: string; localTime?: string }> };
arrival: { times: Record<string, { local?: string; utc?: string; localTime?: string }> };
};
}
function shiftBoardFixtureToTomorrow(fixture: {
data: {
routes: BoardRouteFixture[];
};
}): void {
const tomorrow = new Date();
tomorrow.setHours(0, 0, 0, 0);
tomorrow.setDate(tomorrow.getDate() + 1);
const y = tomorrow.getFullYear();
const m = String(tomorrow.getMonth() + 1).padStart(2, "0");
const d = String(tomorrow.getDate()).padStart(2, "0");
const iso = `${y}-${m}-${d}`;
for (const flight of fixture.data.routes) {
flight.flightId.date = iso;
flight.flightId.dateLT = iso;
for (const point of [flight.leg.departure, flight.leg.arrival]) {
for (const value of Object.values(point.times)) {
if (value.local) value.local = value.local.replace(/^\d{4}-\d{2}-\d{2}/, iso);
if (value.utc) value.utc = value.utc.replace(/^\d{4}-\d{2}-\d{2}/, iso);
}
}
}
}