Files
clinicpro/assets/admin/components/appointments/serviceTimeline.test.ts
T
hamed 4f69bc9044 feat: Implement resource booking functionality
- Add service timeline builder for appointments to manage available slots.
- Create a hook to fetch resource booking services with effective durations.
- Develop ResourceBookingSlotController to handle API requests for resource booking slots.
- Implement ResourceBookingSlotService to calculate available time slots based on resource occupancy and service durations.
- Add tests for resource appointment creation and booking slot functionality to ensure correct behavior and edge cases.
2026-08-03 14:34:23 +03:30

70 lines
2.6 KiB
TypeScript

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> = {}): 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);
});
});