Files
edr-platform/apps/edr-freight-api/src/modules/contracts/contract-duplicate-guard.spec.ts
Marshal 2429f6b629 implement contract cancellation feature and update contract statuses
- Added functionality to cancel contracts, allowing users to provide a reason for cancellation.
- Updated contract statuses to include SUSPENDED and changed CLOSED to COMPLETED.
- Enhanced the UI to reflect the new cancellation option and updated messaging for contract statuses.
- Refactored contract booking actions to accommodate changes in booking logic for ONE_TIME and GENERAL contracts.
- Removed clearance document management from the contract detail page, as it is now handled per booking.
- Introduced a SQL script to reset bookings and train schedules for development purposes.
2026-07-28 05:02:58 +00:00

80 lines
2.6 KiB
TypeScript

import { ConflictException } from '@nestjs/common';
import { ContractsService } from './contracts.service';
import type { CreateContractDto } from './dto/create-contract.dto';
/**
* The duplicate guard blocks a new request only when EVERY commercial
* dimension matches a live contract — service type, operation type, contract
* kind, cargo scope and route. Any one differing must let the request through.
*/
describe('ContractsService duplicate guard', () => {
const LANE = { originYardId: 'yard-dj', destinationYardId: 'yard-mj' };
const existing = {
id: 'c-1',
reference: 'CTR-2026-00001',
status: 'PENDING_APPROVAL',
contractValidUntil: null,
tradeDirection: 'IMPORT',
contractKind: 'ONE_TIME',
freightType: 'CONTAINER',
routes: [LANE],
cargoScope: [{ containerSize: '20ft' }, { containerSize: '40ft' }],
};
const dto = (overrides: Partial<CreateContractDto> = {}) =>
({
serviceTypeId: 'svc-1',
tradeDirection: 'IMPORT',
contractKind: 'ONE_TIME',
freightType: 'CONTAINER',
routes: [LANE],
cargoScope: [{ containerSize: '20ft' }, { containerSize: '40ft' }],
...overrides,
}) as CreateContractDto;
const guard = (input: CreateContractDto) => {
const service = new ContractsService(
{} as never,
{ findDuplicateCandidates: async () => [existing] } as never,
{} as never,
{} as never,
{} as never,
{} as never,
);
return (
service as unknown as {
assertNoDuplicateContract(companyId: string, dto: CreateContractDto): Promise<void>;
}
).assertNoDuplicateContract('company-1', input);
};
it('blocks an identical request', async () => {
await expect(guard(dto())).rejects.toBeInstanceOf(ConflictException);
});
it.each([
['operation type', { tradeDirection: 'EXPORT' }],
['contract kind', { contractKind: 'GENERAL' }],
['freight type', { freightType: 'BULK' }],
['cargo scope', { cargoScope: [{ containerSize: '20ft' }] }],
['route', { routes: [{ originYardId: 'yard-dj', destinationYardId: 'yard-aa' }] }],
])('allows a request with a different %s', async (_label, overrides) => {
await expect(guard(dto(overrides as Partial<CreateContractDto>))).resolves.toBeUndefined();
});
it('ignores quantity caps when comparing cargo scope', async () => {
await expect(
guard(
dto({
cargoScope: [
{ containerSize: '20ft', quantityCap: 10 },
{ containerSize: '40ft', quantityCap: 5 },
],
}),
),
).rejects.toBeInstanceOf(ConflictException);
});
});