import { ref } from 'vue' import { describe, expect, it } from 'vitest' import type { ScheduleEvent, ScheduleView } from '../../types/components' import { SCHEDULE_SLOT_HEIGHT, getWeekStart, parseScheduleModelDate, useScheduleCalendarLayout, } from '../../composables/useScheduleCalendarLayout' function dateKey(date: Date): string { const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${date.getFullYear()}-${month}-${day}` } function makeLayout(overrides: Partial[0]> = {}) { const events: ScheduleEvent[] = [ { id: 'run-1', title: 'LCMS run', start: '2024-05-15T07:00:00', end: '2024-05-15T08:30:00', status: 'in-progress', }, ] return useScheduleCalendarLayout({ currentView: ref('week'), currentDate: ref(new Date('2024-05-15T12:00:00')), now: ref(new Date('2024-05-15T07:30:00')), events: ref(events), blockedSlots: ref([ { start: '2024-05-15T09:00:00', end: '2024-05-15T09:30:00', label: 'maintenance', }, ]), dayStartHour: ref(6), dayEndHour: ref(10), slotDuration: ref(30), weekStartsOn: ref<0 | 1>(1), locale: ref('en-US'), showNowIndicator: ref(true), slotHeight: ref(SCHEDULE_SLOT_HEIGHT), ...overrides, }) } describe('useScheduleCalendarLayout', () => { it('builds week ranges and time labels from calendar settings', () => { const layout = makeLayout() expect(layout.totalSlots.value).toBe(8) expect(layout.timeLabels.value.slice(0, 3)).toEqual(['06:00', '06:30', '07:00']) expect(dateKey(layout.visibleDays.value[0])).toBe('2024-05-13') expect(dateKey(layout.visibleDays.value[6])).toBe('2024-05-19') }) it('computes timed event, blocked slot, and now indicator styles', () => { const layout = makeLayout() const event = layout.getEventsForDate(new Date('2024-05-15T00:00:00'))[0] expect(layout.getEventStyle(event, new Date('2024-05-15T00:00:00'))).toEqual({ top: '80px', height: '120px', }) expect(layout.getBlockedStyle(layout.getBlockedForDay(new Date('2024-05-15T00:00:00'))[0])).toEqual({ top: '240px', height: '40px', }) expect(layout.getNowIndicatorStyle()).toEqual({ top: '120px' }) }) it('builds month cells and weekday labels according to the week start', () => { const layout = makeLayout({ currentView: ref('month') }) expect(layout.monthDays.value).toHaveLength(42) expect(dateKey(layout.monthDays.value[0].date)).toBe('2024-04-29') expect(layout.monthWeekdayLabels.value[0]).toBe('Mon') expect(layout.headerTitle.value).toBe('May 2024') }) it('parses model dates and honors alternate week starts', () => { expect(parseScheduleModelDate('2024-05-15T00:00:00').getFullYear()).toBe(2024) expect(dateKey(getWeekStart(new Date('2024-05-15T00:00:00'), 0))).toBe('2024-05-12') }) })