Files
flights_web/src/shared/utils/datetime/datetime.test.ts
T
gnezim b3ab73253d Add data model types, datetime utils, and dictionary hook
Port Angular flight types (ISimpleFlight, IFlightLeg, ITimesSet, etc.)
to minimal React-friendly interfaces. Add formatDuration/formatTime/
formatDate/isDayChange as pure functions. Stub useCityName hook as
passthrough pending customer dictionary API endpoint.
2026-04-15 07:55:00 +03:00

139 lines
3.6 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { formatDuration, formatTime, formatDate, isDayChange } from "./index.js";
describe("formatDuration", () => {
it("formats zero minutes", () => {
expect(formatDuration(0)).toBe("0h 0m");
});
it("formats minutes only", () => {
expect(formatDuration(45)).toBe("0h 45m");
});
it("formats hours and minutes", () => {
expect(formatDuration(150)).toBe("2h 30m");
});
it("formats days, hours, and minutes", () => {
// 1 day + 5 hours + 12 minutes = 1572 minutes
expect(formatDuration(1572)).toBe("1d 2h 12m");
});
it("formats in Russian locale", () => {
expect(formatDuration(150, "ru")).toBe("2ч 30м");
});
it("formats days in Russian locale", () => {
expect(formatDuration(1572, "ru")).toBe("1д 2ч 12м");
});
it("returns 'Unknown' for negative values", () => {
expect(formatDuration(-1)).toBe("Unknown");
});
it("returns 'Неизвестно' for negative values in Russian", () => {
expect(formatDuration(-1, "ru")).toBe("Неизвестно");
});
it("handles exact hour boundaries", () => {
expect(formatDuration(60)).toBe("1h 0m");
expect(formatDuration(120)).toBe("2h 0m");
});
it("handles exact day boundaries", () => {
expect(formatDuration(1440)).toBe("1d 0h 0m");
});
});
describe("formatTime", () => {
it("formats ISO string to HH:mm", () => {
// Use a fixed date with explicit time to avoid timezone issues
const d = new Date(2025, 0, 15, 10, 30);
expect(formatTime(d)).toBe("10:30");
});
it("pads single-digit hours and minutes", () => {
const d = new Date(2025, 0, 15, 3, 5);
expect(formatTime(d)).toBe("03:05");
});
it("handles midnight", () => {
const d = new Date(2025, 0, 15, 0, 0);
expect(formatTime(d)).toBe("00:00");
});
it("returns empty string for invalid date", () => {
expect(formatTime("not-a-date")).toBe("");
});
it("formats Date objects", () => {
const d = new Date(2025, 0, 15, 14, 45);
expect(formatTime(d)).toBe("14:45");
});
});
describe("formatDate", () => {
it("formats a date in English", () => {
const result = formatDate(new Date(2025, 0, 15), "en");
expect(result).toContain("January");
expect(result).toContain("15");
expect(result).toContain("2025");
});
it("formats a date in Russian", () => {
const result = formatDate(new Date(2025, 0, 15), "ru");
expect(result).toContain("15");
expect(result).toContain("2025");
// Russian month name for January contains "январ"
expect(result.toLowerCase()).toContain("январ");
});
it("returns empty string for invalid date", () => {
expect(formatDate("invalid")).toBe("");
});
it("defaults to English locale", () => {
const result = formatDate(new Date(2025, 0, 15));
expect(result).toContain("January");
});
});
describe("isDayChange", () => {
it("returns 0 for same day", () => {
expect(
isDayChange("2025-01-15T10:00:00", "2025-01-15T23:00:00"),
).toBe(0);
});
it("returns 1 for next day", () => {
expect(
isDayChange(
new Date(2025, 0, 15, 23, 0),
new Date(2025, 0, 16, 1, 0),
),
).toBe(1);
});
it("returns -1 for previous day", () => {
expect(
isDayChange(
new Date(2025, 0, 16, 1, 0),
new Date(2025, 0, 15, 23, 0),
),
).toBe(-1);
});
it("returns 0 for invalid dates", () => {
expect(isDayChange("invalid", "also-invalid")).toBe(0);
});
it("returns 2 for two days later", () => {
expect(
isDayChange(
new Date(2025, 0, 15),
new Date(2025, 0, 17),
),
).toBe(2);
});
});