From 147183ef90bd552038ffacc5c143043a2bfdb689 Mon Sep 17 00:00:00 2001 From: gnezim Date: Thu, 14 May 2026 18:11:52 +0300 Subject: [PATCH] Match Angular transition visibility --- .../components/details-panels/shared.test.ts | 17 +++--- .../components/details-panels/shared.ts | 13 ++-- ...oard-details-transition-visibility.spec.ts | 60 +++++++++++++++++++ 3 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 tests/e2e/onlineboard-details-transition-visibility.spec.ts diff --git a/src/features/online-board/components/details-panels/shared.test.ts b/src/features/online-board/components/details-panels/shared.test.ts index 3d9dd49e..5143885b 100644 --- a/src/features/online-board/components/details-panels/shared.test.ts +++ b/src/features/online-board/components/details-panels/shared.test.ts @@ -27,18 +27,19 @@ describe("shouldShowTransition", () => { expect(shouldShowTransition(undefined, "Scheduled", "Onlineboard")).toBe(false); }); - // TIRREDESIGN-7: the rule now reads the API's isActual flag rather - // than inferring from status, so a transition marked inactive hides - // even if its status has left Scheduled (e.g. a cancelled boarding - // phase that hasn't been cleared to Scheduled). - it("returns false when item.isActual is false", () => { - const inactive = { ...validItem, isActual: false }; - expect(shouldShowTransition(inactive, "Scheduled", "Onlineboard")).toBe(false); + it("returns false when transition status is Scheduled", () => { + const scheduled = { ...validItem, status: "Scheduled" as const }; + expect(shouldShowTransition(scheduled, "Scheduled", "Onlineboard")).toBe(false); }); - it("returns true when item.isActual is true on Onlineboard", () => { + it("returns true when transition status has left Scheduled on Onlineboard", () => { expect(shouldShowTransition(validItem, "Scheduled", "Onlineboard")).toBe(true); }); + + it("ignores isActual on the full details page like Angular", () => { + const inactiveButInProgress = { ...validItem, isActual: false }; + expect(shouldShowTransition(inactiveButInProgress, "Scheduled", "Onlineboard")).toBe(true); + }); }); describe("shouldShowAircraft", () => { diff --git a/src/features/online-board/components/details-panels/shared.ts b/src/features/online-board/components/details-panels/shared.ts index 2701b931..c67601d8 100644 --- a/src/features/online-board/components/details-panels/shared.ts +++ b/src/features/online-board/components/details-panels/shared.ts @@ -8,14 +8,11 @@ import type { export type DetailsViewType = "Onlineboard" | "Schedule"; /** - * Matches Angular's `showBoardProperty` in flight-details-wrapper.component.ts, - * tightened for TIRREDESIGN-7 to use the payload's `isActual` flag. The - * API sets `isActual=true` precisely when a transition block is in its - * current operational phase — the backend computes that from status + - * clocked times, so consumers shouldn't rediscover it locally. + * Matches Angular's `showBoardProperty` in flight-details-wrapper.component.ts. * - * Transition panels remain hidden for Schedule mode or Cancelled legs - * regardless of the flag (those contexts never show transition detail). + * Full online-board details hide only scheduled transition blocks. This differs + * from the inline board row body, where Angular gates registration/boarding/ + * deboarding on `isActual`. */ export function shouldShowTransition( item: IFlightTransitionItem | undefined, @@ -25,7 +22,7 @@ export function shouldShowTransition( if (viewType === "Schedule") return false; if (legStatus === "Cancelled") return false; if (!item) return false; - return item.isActual === true; + return item.status !== "Scheduled"; } /** diff --git a/tests/e2e/onlineboard-details-transition-visibility.spec.ts b/tests/e2e/onlineboard-details-transition-visibility.spec.ts new file mode 100644 index 00000000..63e24826 --- /dev/null +++ b/tests/e2e/onlineboard-details-transition-visibility.spec.ts @@ -0,0 +1,60 @@ +import { test, expect } from "./fixtures/console-gate"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const FIXTURE_DIR = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + "../fixtures/api", +); + +const baseDetails = JSON.parse( + fs.readFileSync(path.join(FIXTURE_DIR, "onlineboard-details.json"), "utf8"), +); + +test("TIRREDESIGN-7: onlineboard details shows non-scheduled transition even when isActual=false", async ({ + page, + consoleMessages, +}) => { + const details = structuredClone(baseDetails); + const flight = details.data.routes[0]; + const leg = flight.leg; + + flight.status = "InFlight"; + leg.status = "InFlight"; + leg.transition = { + registration: { + start: { + utc: "2026-05-14T07:00:00Z", + local: "2026-05-14T10:00:00+03:00", + dayChange: { value: 0, title: "" }, + localTime: "10:00", + tzOffset: 180, + }, + end: { + utc: "2026-05-14T07:30:00Z", + local: "2026-05-14T10:30:00+03:00", + dayChange: { value: 0, title: "" }, + localTime: "10:30", + tzOffset: 180, + }, + status: "InProgress", + isActual: false, + }, + }; + + await page.route("**/api/flights/v1.1/ru/onlineboard/details?**", async (route) => { + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(details), + }); + }); + + await page.goto("/ru-ru/onlineboard/SU6951-20260514"); + + const registrationRow = page.locator('[data-testid="details-row-registration"]'); + await expect(registrationRow).toBeVisible({ timeout: 15000 }); + await expect(registrationRow.getByText("Регистрация")).toBeVisible(); + await expect(registrationRow.getByText("Идет")).toBeVisible(); +});