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.
This commit is contained in:
@@ -72,6 +72,14 @@ describe('AppointmentsPage — پروفایل کلینیک چندپزشکه', ()
|
||||
}
|
||||
if (url.includes('appointment-slots')) return Promise.resolve({ success: true, data: { sessions: [], empty_reason: 'holiday' } });
|
||||
if (url.includes('/my/appointments')) return Promise.resolve({ success: true, data: [], meta: { totalRecords: 0, totalPages: 0, currentPage: 1 } });
|
||||
// بازهٔ کاری منبع از تقویم خودش میآید، نه از برنامهٔ هفتگی پزشک.
|
||||
if (url.includes('/day-slots')) {
|
||||
const day = Math.floor(Date.now() / 1000) + 7 * 86400;
|
||||
return Promise.resolve({ success: true, data: {
|
||||
windows: [{ start: day, end: day + 4 * 3600, start_time: '08:00', end_time: '12:00' }],
|
||||
empty_reason: null,
|
||||
} });
|
||||
}
|
||||
// منابع زیر نظر پزشکاند؛ تب هر منبع فقط زیر ناظرِ خودش دیده میشود.
|
||||
if (url.includes('/api/v1/resources')) return Promise.resolve({ success: true, data: [
|
||||
{ uuid: 'r-1', name: 'اتاق ۱', type_name: 'اتاق درمان', supervisor: { uuid: 'd1', name: 'دکتر محمدی' } },
|
||||
@@ -147,25 +155,32 @@ describe('AppointmentsPage — پروفایل کلینیک چندپزشکه', ()
|
||||
|
||||
await screen.findByText('دکتر محمدی');
|
||||
await user.click(await screen.findByRole('button', { name: 'لیزر CO2' }));
|
||||
expect(await screen.findByText(/نوبتدهی این منبع سرویسی است/)).toBeInTheDocument();
|
||||
expect(await screen.findByText(/نوبتها بر اساس مدت سرویس چیده میشوند/)).toBeInTheDocument();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'نوبتهای خود پزشک' }));
|
||||
|
||||
expect(screen.queryByText(/نوبتدهی این منبع سرویسی است/)).toBeNull();
|
||||
expect(screen.queryByText(/نوبتها بر اساس مدت سرویس چیده میشوند/)).toBeNull();
|
||||
});
|
||||
|
||||
/** باگ گزارششده: نمای منبع نباید اسلاتی باشد. */
|
||||
it('نمای منبع سرویسی است و تایملاین اسلاتی ندارد', async () => {
|
||||
/**
|
||||
* نمای منبع همان تایملاینِ سرویسی است: بازهٔ کاری از `day-slots` خودِ منبع میآید
|
||||
* و ردیفهای خالی «افزودن نوبت سریع»اند — نه شبکهٔ اسلاتِ پزشک.
|
||||
*/
|
||||
it('نمای منبع، تایملاین سرویسیِ تقویم خودِ منبع است', async () => {
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<AppointmentsPage />);
|
||||
|
||||
await screen.findByText('دکتر محمدی');
|
||||
await user.click(await screen.findByRole('button', { name: 'لیزر CO2' }));
|
||||
|
||||
expect(await screen.findByText(/نوبتدهی این منبع سرویسی است/)).toBeInTheDocument();
|
||||
expect(screen.getByText('افزودن نوبت سرویس')).toBeInTheDocument();
|
||||
// ورودی اسلاتی نباید باشد.
|
||||
expect(screen.queryByText('افزودن نوبت سریع')).toBeNull();
|
||||
expect(await screen.findByText(/نوبتها بر اساس مدت سرویس چیده میشوند/)).toBeInTheDocument();
|
||||
expect(await screen.findByText('افزودن نوبت سریع')).toBeInTheDocument();
|
||||
expect(screen.getByText(/ساعت کاری/)).toBeInTheDocument();
|
||||
// بازهٔ کاری از تقویم منبع خوانده میشود، نه از اسلاتهای پزشک.
|
||||
const askedResourceDay = get.mock.calls.some(
|
||||
(c: any[]) => typeof c[0] === 'string' && c[0].includes('/api/v1/resource/r-2/day-slots'),
|
||||
);
|
||||
expect(askedResourceDay).toBe(true);
|
||||
expect(screen.queryByText('این روز تعطیل است')).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user