Add buildBuyTicketUrl + escapeHtml helpers for popup content

This commit is contained in:
2026-04-17 10:52:32 +03:00
parent 40f170f87a
commit 77272423c1
2 changed files with 72 additions and 0 deletions
@@ -0,0 +1,34 @@
import { describe, it, expect } from "vitest";
import { buildBuyTicketUrl, escapeHtml } from "./buyTicketUrl.js";
describe("buildBuyTicketUrl", () => {
it("builds a URL with the correct base", () => {
const url = buildBuyTicketUrl("MOW", "LED", "20260501");
expect(url.startsWith("https://www.aeroflot.ru/sb/app/ru-ru#/search?")).toBe(true);
});
it("includes the routes triple dep.date.arr", () => {
const url = buildBuyTicketUrl("MOW", "LED", "20260501");
expect(url).toContain("routes=MOW.20260501.LED");
});
it("includes the stable UTM and adults/cabin params", () => {
const url = buildBuyTicketUrl("MOW", "LED", "20260501");
expect(url).toContain("adults=1");
expect(url).toContain("cabin=economy");
expect(url).toContain("autosearch=Y");
expect(url).toContain("utm_source=aflwebbot");
});
});
describe("escapeHtml", () => {
it("escapes &, <, >, and double-quote", () => {
expect(escapeHtml("A & B < C > D \"E\"")).toBe(
"A &amp; B &lt; C &gt; D &quot;E&quot;",
);
});
it("returns the input unchanged when no special chars", () => {
expect(escapeHtml("Москва")).toBe("Москва");
});
});
+38
View File
@@ -0,0 +1,38 @@
/**
* Buy-ticket URL for the arrival popup (Angular parity: `getLink`).
*
* Base path + fixed params are hardcoded to the Russian-locale Aeroflot
* search page. The routes triple `{dep}.{date}.{arr}` is the only variable
* part of the URL.
*/
const BASE = "https://www.aeroflot.ru/sb/app/ru-ru#/search";
const FIXED_PARAMS =
"adults=1&cabin=economy&children=0&infants=0&autosearch=Y" +
"&utm_source=aflwebbot&utm_medium=referral" +
"&utm_campaign=ref_3015_general_rf_button.index__all_flight.map";
/**
* @param departure 3-letter city code (e.g. "MOW").
* @param arrival 3-letter city code (e.g. "LED").
* @param date YYYYMMDD — typically filter.date or today.
*/
export function buildBuyTicketUrl(
departure: string,
arrival: string,
date: string,
): string {
return `${BASE}?${FIXED_PARAMS}&routes=${departure}.${date}.${arrival}`;
}
/**
* Minimal HTML escape for popup content — prevents injection via
* city names containing `& < > "`.
*/
export function escapeHtml(s: string): string {
return s
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}