Files
edr-platform/apps/edr-freight-api/src/modules/bookings/booking-transition.operation.spec.ts
2026-06-29 10:58:12 +00:00

82 lines
3.1 KiB
TypeScript

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' }),
);
});
});