Files
calendar/packages/features/schedules/components/parse-time-string.test.ts
T
Benny JooGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c7ee3984ef refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules (#27222)
* refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* fix: move DatePicker and DateOverrideInputDialog to apps/web/modules and update imports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* rename

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* wip

* wip

* wip

* fix unit tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 16:41:44 +02:00

237 lines
8.0 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { parseTimeString } from "./ScheduleComponent";
describe("parseTimeString", () => {
beforeEach(() => {
vi.useFakeTimers();
// Set a consistent date for testing
vi.setSystemTime(new Date("2024-01-15T12:00:00Z"));
});
afterEach(() => {
vi.useRealTimers();
});
describe("24-hour format (timeFormat = 24 or null)", () => {
it("should parse valid 24h format (HH:mm)", () => {
const result = parseTimeString("16:05", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse valid 24h format with single digit hour (via h:mma fallback)", () => {
const result = parseTimeString("8:05am", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(8);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse valid 12h format when user prefers 24h (format fallback)", () => {
const result = parseTimeString("4:05pm", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse midnight (00:00)", () => {
const result = parseTimeString("00:00", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(0);
expect(result?.getUTCMinutes()).toBe(0);
});
it("should parse end of day (23:59)", () => {
const result = parseTimeString("23:59", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(23);
expect(result?.getUTCMinutes()).toBe(59);
});
it("should return null for invalid hours (> 23)", () => {
const result = parseTimeString("24:00", 24);
expect(result).toBeNull();
});
it("should return null for invalid minutes (> 59)", () => {
const result = parseTimeString("16:60", 24);
expect(result).toBeNull();
});
it("should return null for negative hours", () => {
const result = parseTimeString("-1:00", 24);
expect(result).toBeNull();
});
it("should return null for negative minutes", () => {
const result = parseTimeString("16:-5", 24);
expect(result).toBeNull();
});
it("should return null for invalid format", () => {
const result = parseTimeString("invalid", 24);
expect(result).toBeNull();
});
it("should return null for empty string", () => {
const result = parseTimeString("", 24);
expect(result).toBeNull();
});
it("should return null for whitespace only", () => {
const result = parseTimeString(" ", 24);
expect(result).toBeNull();
});
it("should handle null timeFormat as 24h", () => {
const result = parseTimeString("16:05", null);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
});
describe("12-hour format (timeFormat = 12)", () => {
it("should parse valid 12h format with am (h:mma)", () => {
const result = parseTimeString("4:05am", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(4);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse valid 12h format with pm (h:mma)", () => {
const result = parseTimeString("4:05pm", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse valid 12h format with single digit hour", () => {
const result = parseTimeString("8:30am", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(8);
expect(result?.getUTCMinutes()).toBe(30);
});
it("should parse 12:00am (midnight)", () => {
const result = parseTimeString("12:00am", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(0);
expect(result?.getUTCMinutes()).toBe(0);
});
it("should parse 12:00pm (noon)", () => {
const result = parseTimeString("12:00pm", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(12);
expect(result?.getUTCMinutes()).toBe(0);
});
it("should parse 11:59pm (end of day)", () => {
const result = parseTimeString("11:59pm", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(23);
expect(result?.getUTCMinutes()).toBe(59);
});
it("should parse valid 24h format when user prefers 12h (format fallback)", () => {
const result = parseTimeString("16:05", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should return null for invalid format", () => {
const result = parseTimeString("invalid", 12);
expect(result).toBeNull();
});
it("should return null for empty string", () => {
const result = parseTimeString("", 12);
expect(result).toBeNull();
});
});
describe("custom times (5-minute intervals)", () => {
it("should parse 16:05 in 24h format", () => {
const result = parseTimeString("16:05", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse 08:20 in 24h format", () => {
const result = parseTimeString("08:20", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(8);
expect(result?.getUTCMinutes()).toBe(20);
});
it("should parse 4:05pm in 12h format", () => {
const result = parseTimeString("4:05pm", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should parse 8:20am in 12h format", () => {
const result = parseTimeString("8:20am", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(8);
expect(result?.getUTCMinutes()).toBe(20);
});
});
describe("edge cases", () => {
it("should handle times with leading zeros", () => {
const result = parseTimeString("09:05", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(9);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should handle times without leading zeros (via h:mma fallback)", () => {
const result = parseTimeString("9:05am", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(9);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should set seconds and milliseconds to 0", () => {
const result = parseTimeString("16:05", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCSeconds()).toBe(0);
expect(result?.getUTCMilliseconds()).toBe(0);
});
it("should preserve exact minutes (no rounding)", () => {
const result = parseTimeString("16:07", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCMinutes()).toBe(7);
});
it("should preserve exact minutes in 12h format (no rounding)", () => {
const result = parseTimeString("4:07pm", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCMinutes()).toBe(7);
});
});
describe("format acceptance (both formats)", () => {
it("should accept 24h format when user prefers 12h (format fallback)", () => {
const result = parseTimeString("16:05", 12);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
it("should accept 12h format when user prefers 24h (format fallback)", () => {
const result = parseTimeString("4:05pm", 24);
expect(result).toBeInstanceOf(Date);
expect(result?.getUTCHours()).toBe(16);
expect(result?.getUTCMinutes()).toBe(5);
});
});
});