import { BadRequestException } from '@nestjs/common'; import { BookingTransitionService } from './booking-transition.service'; /** * Focused tests for the contract validity window set at the accept step. * The backoffice must supply a number of days; the window runs from the accept * moment through accept + N days. */ describe('BookingTransitionService — acceptIntake validity window', () => { const booking = { id: 'b-1', status: 'SUBMITTED', freightType: 'CONTAINER', cargoTypeId: null, }; function makeService() { const bookingsRepository = { update: jest.fn().mockResolvedValue({ id: 'b-1' }), }; const bookingsService = { findById: jest.fn().mockResolvedValue(booking), }; const ruleEngineService = { instantiateApprovalSteps: jest.fn().mockResolvedValue([]), }; const service = new BookingTransitionService( bookingsRepository as never, ruleEngineService as never, {} as never, // pricingService {} as never, // contractService {} as never, // filesService {} as never, // fileUploadSettingsService {} as never, // bookingBatchService bookingsService as never, ); return { service, bookingsRepository, ruleEngineService }; } it('rejects accept when validity days is missing or non-positive', async () => { const { service } = makeService(); await expect( service.acceptIntake('b-1', 'staff-1', 0), ).rejects.toBeInstanceOf(BadRequestException); await expect( service.acceptIntake('b-1', 'staff-1', -5), ).rejects.toBeInstanceOf(BadRequestException); await expect( service.acceptIntake('b-1', 'staff-1', 1.5), ).rejects.toBeInstanceOf(BadRequestException); }); it('sets a validity window of validFrom..validFrom + N days', async () => { const { service, bookingsRepository } = makeService(); await service.acceptIntake('b-1', 'staff-1', 10); expect(bookingsRepository.update).toHaveBeenCalledTimes(1); const [id, updates] = bookingsRepository.update.mock.calls[0]; expect(id).toBe('b-1'); expect(updates).toMatchObject({ status: 'PENDING_APPROVAL', approvedByStaffId: 'staff-1', contractValidityDays: 10, }); const from = updates.contractValidFrom as Date; const until = updates.contractValidUntil as Date; const diffDays = Math.round( (until.getTime() - from.getTime()) / (1000 * 60 * 60 * 24), ); expect(diffDays).toBe(10); // The accept timestamp and the validity start are the same moment. expect((updates.approvedByStaffAt as Date).getTime()).toBe(from.getTime()); }); it('instantiates the approval chain when accepting', async () => { const { service, ruleEngineService } = makeService(); await service.acceptIntake('b-1', 'staff-1', 30); expect(ruleEngineService.instantiateApprovalSteps).toHaveBeenCalledWith( 'b-1', expect.objectContaining({ freightType: 'CONTAINER' }), ); }); });