marmar-context / web / context / test / hours.test.ts
hours.test.ts
Raw
// Settings' weekly hours (YCI-5): one span a day, Monday first, or closed, in the backend's days.
import { describe, expect, it } from "vitest";
import { wireHours } from "../src/api/adapt";
import { changeDay, dayRows, DAY_NAMES, hoursErrors, hoursFrom, sameHours, timeZones } from "../src/logic/hours";

const weekdays = [1, 2, 3, 4, 5].map((day) => ({ day, open: "08:00", close: "17:00" }));

describe("weekly hours in Settings", () => {
  it("shows the week Monday first, each day open with its times or closed", () => {
    const rows = dayRows([...weekdays, { day: 6, open: "09:00", close: "14:00" }]);
    expect(rows.map((r) => DAY_NAMES[r.day])).toEqual(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]);
    expect(rows[5]).toEqual({ day: 6, open: true, from: "09:00", to: "14:00", more: [] });
    expect(rows[6]).toMatchObject({ day: 0, open: false });
  });

  it("gives back what the backend takes: a span per open day, days 1 to 7 on the wire", () => {
    let rows = dayRows([]);
    expect(hoursFrom(rows)).toEqual([]);
    rows = changeDay(rows, 0, { open: true, from: "10:00", to: "12:00" });
    rows = changeDay(rows, 1, { open: true });
    expect(hoursFrom(rows)).toEqual([{ day: 1, open: "08:00", close: "17:00" }, { day: 0, open: "10:00", close: "12:00" }]);
    expect(wireHours(hoursFrom(rows))).toEqual([{ day: 1, open: "08:00", close: "17:00" }, { day: 7, open: "10:00", close: "12:00" }]);
  });

  it("keeps a day's other spans unless the day is closed", () => {
    const split = [{ day: 2, open: "14:00", close: "18:00" }, { day: 2, open: "08:00", close: "12:00" }];
    let rows = dayRows(split);
    expect(rows[1]).toMatchObject({ from: "08:00", to: "12:00", more: [{ open: "14:00", close: "18:00" }] });
    rows = changeDay(rows, 2, { to: "12:30" });
    expect(hoursFrom(rows)).toEqual([{ day: 2, open: "08:00", close: "12:30" }, { day: 2, open: "14:00", close: "18:00" }]);
    expect(hoursFrom(changeDay(rows, 2, { open: false }))).toEqual([]);
  });

  it("says plainly what is wrong with a day, and nothing for a closed one", () => {
    let rows = changeDay(dayRows(weekdays), 1, { from: "18:00", to: "08:00" });
    rows = changeDay(rows, 2, { to: "" });
    rows = changeDay(rows, 3, { open: false, from: "nonsense" });
    expect(hoursErrors(rows)).toEqual({
      1: "Monday: the closing time must be after the opening time.",
      2: "Tuesday: enter an opening and a closing time, for example 08:00 and 17:00.",
    });
    expect(hoursErrors(dayRows(weekdays))).toEqual({});
  });

  it("knows unchanged hours, so Settings sends them only when they changed", () => {
    expect(sameHours(weekdays, [...weekdays].reverse())).toBe(true);
    expect(sameHours(weekdays, weekdays.slice(1))).toBe(false);
  });

  it("offers every time zone the browser knows, with the clinic's own in the list", () => {
    expect(timeZones("Africa/Lagos")).toContain("Africa/Lagos");
    expect(timeZones("Africa/Kigali")).toContain("Africa/Kigali");
    expect(timeZones("Etc/Made_Up")[0]).toBe("Etc/Made_Up");
  });
});