import { describe, it, expect } from 'vitest'; import { buildServiceTimeline } from './serviceTimeline'; import type { Appointment } from '../../types'; const DAY = 1_800_000_000; // نیمه‌شبِ فرضی const at = (h: number) => DAY + h * 3600; function appointment(from: number, to: number, over: Partial = {}): Appointment { return { uuid: `a-${from}`, patient_name: 'بیمار', patient_mobile: '09120000000', doctor_uuid: 'd1', doctor_name: 'دکتر', slot_start: from, slot_end: to, appointment_date: '', appointment_time: '', end_time: '', status: 'confirmed', version: 1, created_at: '', ...over, } as Appointment; } describe('buildServiceTimeline', () => { const window = [{ start: at(8), end: at(14) }]; it('یک نوبت، بازهٔ کاری را به «خالی — نوبت — خالی» می‌شکند', () => { const rows = buildServiceTimeline(window, [appointment(at(10), at(11))], at(0)); expect(rows.map(r => [r.start, r.end, r.appointment !== null])).toEqual([ [at(8), at(10), false], [at(10), at(11), true], [at(11), at(14), false], ]); }); it('بدون نوبت، کل بازهٔ کاری یک ردیفِ خالی است', () => { const rows = buildServiceTimeline(window, [], at(0)); expect(rows).toHaveLength(1); expect(rows[0].is_available).toBe(true); }); it('نوبت لغوشده جای خالی را نمی‌گیرد', () => { const rows = buildServiceTimeline( window, [appointment(at(10), at(11), { status: 'cancelled_by_doctor' })], at(0), ); expect(rows).toHaveLength(1); expect(rows[0].appointment).toBeNull(); }); it('نوبتِ رزرو (روزانه) بازه‌ای اشغال نمی‌کند', () => { const rows = buildServiceTimeline(window, [appointment(at(10), at(11), { is_reserve: true })], at(0)); expect(rows).toHaveLength(1); expect(rows[0].appointment).toBeNull(); }); it('بازهٔ خالیِ گذشته به «اکنون» بریده می‌شود و ردیفِ تمام‌گذشته حذف', () => { const rows = buildServiceTimeline([{ start: at(8), end: at(9) }, { start: at(10), end: at(14) }], [], at(11)); expect(rows).toHaveLength(1); expect(rows[0].start).toBe(at(11)); expect(rows[0].end).toBe(at(14)); }); it('نوبتِ خارج از بازهٔ کاری، ردیف نمی‌سازد', () => { const rows = buildServiceTimeline(window, [appointment(at(20), at(21))], at(0)); expect(rows.every(r => r.appointment === null)).toBe(true); }); });