import { beforeEach, expect, mock, test } from 'bun:test'; import { Errors } from '@/lib/errors'; import { err, ok } from '@/lib/result'; const rescheduleAdminBookingMock = mock(async (_userId: string, _id: string, _input: unknown) => ok({}) ); mock.module( '@/modules/admin-booking/features/reschedule-admin-booking/reschedule-admin-booking.business', () => ({ __esModule: true, rescheduleAdminBooking: rescheduleAdminBookingMock, }) ); const { rescheduleAdminBookingHandler } = await import( '@/modules/admin-booking/features/reschedule-admin-booking/reschedule-admin-booking.handler' ); type HandlerContext = { get: (key: 'user' | 'requestId') => { id: string } | undefined; req: { valid: (type: string) => Record; }; json: ReturnType; }; function createContext(input: { userId: string; body: unknown }) { const json = mock((payload: unknown, init?: unknown) => ({ payload, init, })); const c = { get: (key: 'user' | 'requestId') => { if (key === 'user') return { id: input.userId }; return undefined; }, req: { valid: (type: string) => { if (type === 'param') return { id: 'booking-1' }; if (type === 'json') return input.body as Record; return {}; }, }, json, } as unknown as HandlerContext; return { c, json }; } beforeEach(() => { rescheduleAdminBookingMock.mockReset(); }); test('returns 200 with the updated booking', async () => { const updatedBooking = { id: 'booking-1', bookingCode: 'ABC123', complexId: 'complex-1', complexName: 'Complejo Test', courtId: 'court-2', courtName: 'Cancha 2', sport: { id: 'sport-1', name: 'Tenis', slug: 'tenis' }, date: '2026-07-15', startTime: '14:00', endTime: '15:00', customerName: 'Juan Perez', customerPhone: '1144444444', customerEmail: 'juan@example.com', price: 15000, status: 'CONFIRMED', recurringGroupId: null, createdAt: '2026-07-14T00:00:00.000Z', updatedAt: '2026-07-14T00:00:00.000Z', } as const; rescheduleAdminBookingMock.mockResolvedValue(ok(updatedBooking)); const { c, json } = createContext({ userId: 'user-1', body: { courtId: 'court-2', startTime: '14:00' }, }); const response = await rescheduleAdminBookingHandler(c as never); expect(rescheduleAdminBookingMock).toHaveBeenCalledWith('user-1', 'booking-1', { courtId: 'court-2', startTime: '14:00', }); expect(json.mock.calls[0]?.[0]).toEqual(updatedBooking); expect(json.mock.calls[0]?.[1]).toBe(200); expect(response).toBeDefined(); }); test('maps AdminBookingServiceError to an error response', async () => { rescheduleAdminBookingMock.mockResolvedValue( err(Errors.conflict('Solo se pueden reprogramar reservas en estado confirmada.')) ); const { c, json } = createContext({ userId: 'user-1', body: { startTime: '14:00' }, }); const response = await rescheduleAdminBookingHandler(c as never); expect(rescheduleAdminBookingMock).toHaveBeenCalledWith('user-1', 'booking-1', { startTime: '14:00', }); expect(json.mock.calls[0]?.[0]).toEqual({ type: 'https://api.myapp.dev/problems/conflict', title: 'Conflict', status: 409, detail: 'Solo se pueden reprogramar reservas en estado confirmada.', }); expect(json.mock.calls[0]?.[1]).toBe(409); expect(response).toBeDefined(); });