mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 15:58:18 +00:00
80 lines
3.6 KiB
TypeScript
80 lines
3.6 KiB
TypeScript
import { WarehouseInventoryService } from './warehouse-inventory.service';
|
|
|
|
/**
|
|
* A mid-corridor booking (import destined at an intermediate yard, or any
|
|
* DOMESTIC/intercity ride-along) used to have its booking.status flipped by
|
|
* the checkpoint-driven unload but never got a warehouse_inventory row — the
|
|
* Arrival Queue's unload count never moved and the booking was effectively
|
|
* stranded. handleBookingUnloadedAtYard reacts to the 'booking.unloadedAtYard'
|
|
* event BookingJourneyService.unloadBooking() emits and creates that row.
|
|
*/
|
|
function makeService(opts: {
|
|
existingInventory?: unknown;
|
|
booking?: Record<string, unknown> | null;
|
|
}) {
|
|
const created: Record<string, unknown>[] = [];
|
|
|
|
const inventoryRepository = {
|
|
findAll: jest.fn().mockResolvedValue(opts.existingInventory ? [opts.existingInventory] : []),
|
|
create: jest.fn((row: Record<string, unknown>) => {
|
|
created.push(row);
|
|
return Promise.resolve({ id: 'new-inv', ...row });
|
|
}),
|
|
};
|
|
|
|
const bookingRow =
|
|
opts.booking === undefined
|
|
? [{ weight: '10', freightType: 'CONTAINER', cargoTypeCode: 'GEN', customer: 'Acme' }]
|
|
: opts.booking
|
|
? [opts.booking]
|
|
: [];
|
|
|
|
const service = Object.create(WarehouseInventoryService.prototype) as Record<string, unknown>;
|
|
service.inventoryRepository = inventoryRepository;
|
|
service.dataSource = { query: jest.fn().mockResolvedValue(bookingRow), manager: {} };
|
|
service.allocation = { resolveLocation: jest.fn().mockResolvedValue(null) };
|
|
service.pickDefaultLocation = jest.fn().mockResolvedValue({ warehouseId: 'w1', yardId: 'y1', zoneId: 'z1' });
|
|
service.applyCapacityDelta = jest.fn().mockResolvedValue(undefined);
|
|
service.activityLog = { record: jest.fn().mockResolvedValue(undefined) };
|
|
service.logger = { warn: jest.fn() };
|
|
|
|
return { service: service as unknown as WarehouseInventoryService, created };
|
|
}
|
|
|
|
describe('handleBookingUnloadedAtYard', () => {
|
|
it('creates an UNLOADED row with an IMPORT GRN for a fresh import booking', async () => {
|
|
const { service, created } = makeService({});
|
|
await (service as unknown as { handleBookingUnloadedAtYard: (p: unknown) => Promise<void> })
|
|
.handleBookingUnloadedAtYard({ bookingId: 'b1', tradeDirection: 'IMPORT' });
|
|
|
|
expect(created).toHaveLength(1);
|
|
expect(created[0]).toMatchObject({ bookingId: 'b1', status: 'UNLOADED' });
|
|
expect(created[0].grnNumber).toMatch(/^GRN-IMPORT-/);
|
|
});
|
|
|
|
it('creates one for a DOMESTIC/intercity ride-along too', async () => {
|
|
const { service, created } = makeService({});
|
|
await (service as unknown as { handleBookingUnloadedAtYard: (p: unknown) => Promise<void> })
|
|
.handleBookingUnloadedAtYard({ bookingId: 'b2', tradeDirection: 'DOMESTIC' });
|
|
|
|
expect(created).toHaveLength(1);
|
|
expect(created[0].grnNumber).toMatch(/^GRN-DOMESTIC-/);
|
|
});
|
|
|
|
it('skips EXPORT — its warehouse record already exists from the origin receive', async () => {
|
|
const { service, created } = makeService({});
|
|
await (service as unknown as { handleBookingUnloadedAtYard: (p: unknown) => Promise<void> })
|
|
.handleBookingUnloadedAtYard({ bookingId: 'b3', tradeDirection: 'EXPORT' });
|
|
|
|
expect(created).toHaveLength(0);
|
|
});
|
|
|
|
it('is idempotent — a booking that already has an inventory row is left alone', async () => {
|
|
const { service, created } = makeService({ existingInventory: { id: 'existing' } });
|
|
await (service as unknown as { handleBookingUnloadedAtYard: (p: unknown) => Promise<void> })
|
|
.handleBookingUnloadedAtYard({ bookingId: 'b4', tradeDirection: 'IMPORT' });
|
|
|
|
expect(created).toHaveLength(0);
|
|
});
|
|
});
|