import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; // sever the server-only @/app/client import chain; the network functions are not under test vi.mock("@/app/client", () => ({ getClient: vi.fn() })); import type { OpeningHoursRangeBlockFragment, OpeningHoursSetFragment, } from "@/gql/graphql"; import { getOpeningHoursForFunction, getPrettyOpeningHoursForFunction, getTodaysOpeningHoursForFunction, groupOpeningHours, } from "./openinghours.ts"; const range = ( timeFrom: string | null, timeTo: string | null, custom: string | null = null ) => ({ timeFrom, timeTo, custom }); const week = { __typename: "OpeningHoursWeekBlock", monday: range("16:00:00", "23:00:00"), tuesday: range("16:00:00", "23:00:00"), wednesday: range("16:00:00", "23:00:00"), thursday: range("16:00:00", "23:00:00"), friday: range("15:00:00", "01:00:00"), saturday: null, sunday: range(null, null, "Kun ved arrangement"), }; const openingHours = { name: "Vanlige åpningstider", effectiveFrom: "2026-01-01", effectiveTo: null, announcement: null, items: [{ id: "1", function: "bar", week: [week] }], } as unknown as OpeningHoursSetFragment; const perDay = (days: Record | null>) => days as unknown as Record; describe("groupOpeningHours", () => { it("collapses adjacent days with identical hours", () => { const grouped = groupOpeningHours( perDay({ monday: range("16:00:00", "23:00:00"), tuesday: range("16:00:00", "23:00:00"), wednesday: range("12:00:00", "20:00:00"), }) ); expect(grouped).toEqual([ { days: ["monday", "tuesday"], timeFrom: "16:00:00", timeTo: "23:00:00", custom: null, }, { days: ["wednesday"], timeFrom: "12:00:00", timeTo: "20:00:00", custom: null, }, ]); }); it("treats a null day as closed instead of crashing", () => { const grouped = groupOpeningHours( perDay({ monday: range("16:00:00", "23:00:00"), tuesday: null, }) ); expect(grouped[1]).toEqual({ days: ["tuesday"], timeFrom: null, timeTo: null, custom: null, }); }); it("skips days missing from the record", () => { const grouped = groupOpeningHours( perDay({ monday: range("16:00:00", "23:00:00"), wednesday: range("12:00:00", "20:00:00"), }) ); expect(grouped.map((g) => g.days)).toEqual([["monday"], ["wednesday"]]); }); }); describe("getOpeningHoursForFunction", () => { it("returns the week for a known function", () => { expect(getOpeningHoursForFunction(openingHours, "bar")).toEqual(week); }); it("returns undefined for unknown or malformed items", () => { expect(getOpeningHoursForFunction(openingHours, "kafé")).toBeUndefined(); const malformed = { ...openingHours, items: [{ id: "1", function: "bar", week: [] }], } as unknown as OpeningHoursSetFragment; expect(getOpeningHoursForFunction(malformed, "bar")).toBeUndefined(); }); }); describe("getPrettyOpeningHoursForFunction", () => { it("formats grouped Norwegian day ranges", () => { expect(getPrettyOpeningHoursForFunction(openingHours, "bar")).toEqual([ { range: "mandag—torsdag", time: "16:00—23:00" }, { range: "fredag", time: "15:00—01:00" }, { range: "lørdag" }, { range: "søndag", custom: "Kun ved arrangement" }, ]); }); it("returns an empty list for unknown functions", () => { expect(getPrettyOpeningHoursForFunction(openingHours, "kafé")).toEqual([]); }); }); describe("getTodaysOpeningHoursForFunction", () => { beforeEach(() => { vi.useFakeTimers(); }); afterEach(() => { vi.useRealTimers(); }); it("returns today's hours", () => { vi.setSystemTime(new Date("2026-07-07T10:00:00Z")); // tirsdag expect(getTodaysOpeningHoursForFunction(openingHours, "bar")).toBe( "16:00—23:00" ); }); it("returns Stengt for a null day", () => { vi.setSystemTime(new Date("2026-07-11T10:00:00Z")); // lørdag expect(getTodaysOpeningHoursForFunction(openingHours, "bar")).toBe( "Stengt" ); }); it("returns the custom text when set", () => { vi.setSystemTime(new Date("2026-07-12T10:00:00Z")); // søndag expect(getTodaysOpeningHoursForFunction(openingHours, "bar")).toBe( "Kun ved arrangement" ); }); it("returns ? for unknown functions", () => { vi.setSystemTime(new Date("2026-07-07T10:00:00Z")); expect(getTodaysOpeningHoursForFunction(openingHours, "kafé")).toBe("?"); }); it("uses the Oslo weekday when the server runs in UTC", () => { const tz = process.env.TZ; process.env.TZ = "UTC"; try { // 22:20 UTC on torsdag is 00:20 fredag in Oslo (CEST) vi.setSystemTime(new Date("2026-07-09T22:20:00Z")); expect(getTodaysOpeningHoursForFunction(openingHours, "bar")).toBe( "15:00—01:00" ); // 23:20 UTC on torsdag is 00:20 fredag in Oslo (CET) vi.setSystemTime(new Date("2026-01-08T23:20:00Z")); expect(getTodaysOpeningHoursForFunction(openingHours, "bar")).toBe( "15:00—01:00" ); } finally { process.env.TZ = tz; } }); });