import { describe, expect, test } from "bun:test"; import { normalizeAiDateString } from "@/lib/date-normalizer"; import { AiEventResponseSchema } from "@/lib/types"; describe("normalizeAiDateString", () => { test("converts bare ISO datetime (no offset) to valid offset datetime accepted by Zod", () => { const input = "2025-04-10T10:00:00"; const result = normalizeAiDateString(input); expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$/); expect(new Date(result).getHours()).toBe(10); }); test("converts date-only string to midnight datetime with offset", () => { const input = "2025-04-10"; const result = normalizeAiDateString(input); expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T00:00:00(Z|[+-]\d{2}:\d{2})$/); }); test("passes through already-valid datetime with offset unchanged", () => { const input = "2025-04-10T10:00:00-04:00"; const result = normalizeAiDateString(input); expect(result).toBe("2025-04-10T10:00:00-04:00"); }); test("passes through datetime with Z suffix unchanged", () => { const input = "2025-04-10T10:00:00Z"; const result = normalizeAiDateString(input); expect(result).toBe("2025-04-10T10:00:00Z"); }); test("handles datetime with fractional seconds", () => { const input = "2025-04-10T10:00:00.000Z"; const result = normalizeAiDateString(input); expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/); expect(new Date(result).getHours()).toBe(10); }); }); describe("AiEventResponseSchema date normalization", () => { test("accepts event with bare ISO datetime (no offset) by normalizing it", () => { const raw = [ { title: "Team Meeting", start: "2025-04-10T10:00:00", end: "2025-04-10T11:00:00", }, ]; const result = AiEventResponseSchema.safeParse(raw); expect(result.success).toBe(true); if (result.success) { expect(result.data[0].start).toMatch( /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$/, ); } }); test("accepts event with date-only start and no end", () => { const raw = [ { title: "All-day workshop", start: "2025-07-20", allDay: true, }, ]; const result = AiEventResponseSchema.safeParse(raw); expect(result.success).toBe(true); }); test("accepts event with already-valid offset datetime", () => { const raw = [ { title: "Standup", start: "2025-04-10T09:00:00-05:00", end: "2025-04-10T09:30:00-05:00", }, ]; const result = AiEventResponseSchema.safeParse(raw); expect(result.success).toBe(true); if (result.success) { expect(result.data[0].start).toBe("2025-04-10T09:00:00-05:00"); } }); });