import { BadRequestException } from '@nestjs/common'; import { BookingTransitionService } from './booking-transition.service'; /** * Operation-request review for general-contract drawdown orders: * - ACCEPT a train order → FULLY_EXECUTED and enqueued into the batch pool. * - ACCEPT a road order → ROAD_DISPATCH_PENDING, NOT enqueued. * - REQUEST_CHANGES requires a note → OPERATION_CHANGES_REQUESTED. */ describe('BookingTransitionService — operation review', () => { function makeService(serviceTypeCode: string) { const booking = { id: 'b-1', status: 'OPERATION_REQUEST_PENDING', originYardId: 'o-1', destinationYardId: 'd-1', scheduledDate: new Date('2026-07-01T00:00:00.000Z'), serviceType: { code: serviceTypeCode }, }; const bookingsRepository = { update: jest.fn().mockResolvedValue({ id: 'b-1' }), createReviewNote: jest.fn().mockResolvedValue(undefined), }; const bookingsService = { findById: jest.fn().mockResolvedValue(booking), }; const bookingBatchService = { enqueueRouteDayProcessing: jest.fn(), }; const service = new BookingTransitionService( bookingsRepository as never, {} as never, // ruleEngineService {} as never, // pricingService {} as never, // contractService {} as never, // invoiceService {} as never, // filesService {} as never, // fileUploadSettingsService bookingBatchService as never, bookingsService as never, ); return { service, bookingsRepository, bookingBatchService }; } it('ACCEPT of a train order → FULLY_EXECUTED and enqueues the batch pool', async () => { const { service, bookingsRepository, bookingBatchService } = makeService('RAIL_CONTAINER'); await service.reviewOperationRequest('b-1', 'ACCEPT', 'staff-1'); expect(bookingsRepository.update).toHaveBeenCalledWith( 'b-1', expect.objectContaining({ status: 'FULLY_EXECUTED' }), ); expect(bookingBatchService.enqueueRouteDayProcessing).toHaveBeenCalledTimes(1); }); it('ACCEPT of a road order → ROAD_DISPATCH_PENDING and does NOT enqueue', async () => { const { service, bookingsRepository, bookingBatchService } = makeService('ROAD_CONTAINER'); await service.reviewOperationRequest('b-1', 'ACCEPT', 'staff-1'); expect(bookingsRepository.update).toHaveBeenCalledWith( 'b-1', expect.objectContaining({ status: 'ROAD_DISPATCH_PENDING' }), ); expect(bookingBatchService.enqueueRouteDayProcessing).not.toHaveBeenCalled(); }); it('REQUEST_CHANGES requires a note → OPERATION_CHANGES_REQUESTED', async () => { const { service, bookingsRepository } = makeService('RAIL_CONTAINER'); await expect( service.reviewOperationRequest('b-1', 'REQUEST_CHANGES', 'staff-1', {}), ).rejects.toBeInstanceOf(BadRequestException); await service.reviewOperationRequest('b-1', 'REQUEST_CHANGES', 'staff-1', { note: 'Fix the schedule', }); expect(bookingsRepository.update).toHaveBeenCalledWith( 'b-1', expect.objectContaining({ status: 'OPERATION_CHANGES_REQUESTED' }), ); }); });