182 lines
6.2 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|
|
}
|