import { test, expect } from "@playwright/test"; import { resultsUrl } from "../../fixtures/data"; /** * UA-1b ✅ — for a non-Ethiopian (USD) search the results card shows the USD-converted * `displayAmountMinor`, and the internal `baseFareMinor` is the ETB source it was converted from * (exactly the USD→ETB rate apart — a correct conversion, not a mislabel). The passenger sees and * carries forward the USD value; the ETB basis is stored honestly on the booking as `currency: ETB` * (proven end-to-end by UA-2). This pins the display layer so a regression that shows the raw ETB * number, or drops the conversion, is caught. */ test("UA-1b: USD card shows the USD fare, correctly converted from the internal ETB base", async ({ page }) => { const searchDone = page.waitForResponse( (r) => r.url().includes("/search") && r.request().method() === "POST", ); await page.goto(resultsUrl({ nationality: "Other" })); const out = (await (await searchDone).json())?.data?.outbound?.[0]; const cls = out?.faresByClass?.[0]; expect(out.displayCurrency).toBe("USD"); // The USD display fare is the ETB base converted at the USD→ETB rate (100×), not a parity mislabel. expect(cls.displayAmountMinor).toBeGreaterThan(0); expect(cls.displayAmountMinor).toBeLessThan(cls.baseFareMinor); expect(cls.baseFareMinor).toBe(cls.displayAmountMinor * 100); // The DOM shows the USD value the passenger pays (formatFare divides by 100, 2dp) — e.g. "USD 12.50". const usdMajor = (cls.displayAmountMinor / 100).toFixed(2); await expect(page.getByText(new RegExp(`USD\\s*${usdMajor.replace(".", "\\.")}`)).first()).toBeVisible({ timeout: 20_000, }); });