mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
102 lines
3.5 KiB
TypeScript
102 lines
3.5 KiB
TypeScript
import { BookingSplitService } from './booking-split.service';
|
|
import { Booking } from '../bookings/entities/booking.entity';
|
|
import { BookingContainer } from '../bookings/entities/booking-container.entity';
|
|
import { BookingContainerUnit } from '../bookings/entities/booking-container-unit.entity';
|
|
import { Contract } from '../contracts/entities/contract.entity';
|
|
import { BookingBatchOffer } from './entities/booking-batch-offer.entity';
|
|
|
|
/**
|
|
* applySplit promotion behaviour: a ONE_TIME contract must be flipped to GENERAL
|
|
* (both the parent contract row and the booking's denormalized copy) so the split
|
|
* remainder can be rebooked. A GENERAL booking is left untouched.
|
|
*/
|
|
describe('BookingSplitService — applySplit ONE_TIME promotion', () => {
|
|
const bookingId = 'bk-1';
|
|
const contractId = 'ct-1';
|
|
const offerId = 'of-1';
|
|
|
|
const buildService = (bookingContractKind: 'ONE_TIME' | 'GENERAL') => {
|
|
const offer = {
|
|
id: offerId,
|
|
bookingId,
|
|
status: 'OFFERED',
|
|
offeredWagons: 3,
|
|
totalWagons: 5,
|
|
offeredWeightTons: 30,
|
|
offeredAmount: 300,
|
|
offeredPricingBreakdown: {},
|
|
offeredLines: null,
|
|
} as unknown as BookingBatchOffer;
|
|
|
|
const bookingRepo = {
|
|
update: jest.fn().mockResolvedValue(undefined),
|
|
findOne: jest.fn().mockResolvedValue({
|
|
id: bookingId,
|
|
contractId,
|
|
contractKind: bookingContractKind,
|
|
}),
|
|
find: jest.fn().mockResolvedValue([]),
|
|
softDelete: jest.fn().mockResolvedValue(undefined),
|
|
};
|
|
const contractRepo = { update: jest.fn().mockResolvedValue(undefined) };
|
|
const offerRepo = {
|
|
findOne: jest.fn().mockResolvedValue(offer),
|
|
update: jest.fn().mockResolvedValue(undefined),
|
|
};
|
|
const containerRepo = {
|
|
find: jest.fn().mockResolvedValue([]),
|
|
update: jest.fn(),
|
|
softDelete: jest.fn(),
|
|
};
|
|
const unitRepo = { find: jest.fn().mockResolvedValue([]), softDelete: jest.fn() };
|
|
|
|
const repoFor = (entity: unknown) => {
|
|
if (entity === Booking) return bookingRepo;
|
|
if (entity === Contract) return contractRepo;
|
|
if (entity === BookingBatchOffer) return offerRepo;
|
|
if (entity === BookingContainer) return containerRepo;
|
|
if (entity === BookingContainerUnit) return unitRepo;
|
|
return { find: jest.fn().mockResolvedValue([]), update: jest.fn() };
|
|
};
|
|
|
|
const dataSource = {
|
|
getRepository: jest.fn(repoFor),
|
|
transaction: jest.fn(async (fn: (m: unknown) => Promise<void>) => {
|
|
await fn({ getRepository: repoFor });
|
|
}),
|
|
};
|
|
|
|
const service = new BookingSplitService(
|
|
dataSource as never,
|
|
{} as never,
|
|
{} as never,
|
|
{ expirePayable: jest.fn() } as never,
|
|
{ payNowPartial: jest.fn() } as never,
|
|
);
|
|
return { service, bookingRepo, contractRepo };
|
|
};
|
|
|
|
it('promotes a ONE_TIME booking + parent contract to GENERAL', async () => {
|
|
const { service, bookingRepo, contractRepo } = buildService('ONE_TIME');
|
|
|
|
await service.applySplit(bookingId);
|
|
|
|
expect(bookingRepo.update).toHaveBeenCalledWith(
|
|
bookingId,
|
|
expect.objectContaining({ contractKind: 'GENERAL' }),
|
|
);
|
|
expect(contractRepo.update).toHaveBeenCalledWith(
|
|
contractId,
|
|
expect.objectContaining({ contractKind: 'GENERAL' }),
|
|
);
|
|
});
|
|
|
|
it('leaves a GENERAL booking untouched (no contract promotion)', async () => {
|
|
const { service, contractRepo } = buildService('GENERAL');
|
|
|
|
await service.applySplit(bookingId);
|
|
|
|
expect(contractRepo.update).not.toHaveBeenCalled();
|
|
});
|
|
});
|