import { ConflictException } from '@nestjs/common'; import type { DataSource } from 'typeorm'; import { RoutesService } from './routes.service'; import type { RoutesRepository } from './routes.repository'; type StopSeq = Array<{ yardId: string; sequenceNo: number }>; /** DataSource stub whose Route repository returns the given existing routes. */ const serviceWith = ( existing: Array<{ id: string; milestones: StopSeq }>, ): RoutesService => { const dataSource = { getRepository: () => ({ find: async () => existing }), } as unknown as DataSource; return new RoutesService(dataSource, {} as RoutesRepository); }; const assertNotDuplicate = ( service: RoutesService, yardIds: string[], excludeRouteId?: string, ): Promise => ( service as unknown as { assertNotDuplicate: ( m: Array<{ yardId: string }>, id?: string, ) => Promise; } ).assertNotDuplicate( yardIds.map((yardId) => ({ yardId })), excludeRouteId, ); describe('RoutesService duplicate guard', () => { const addisAdamaDire: StopSeq = [ { yardId: 'addis', sequenceNo: 1 }, { yardId: 'adama', sequenceNo: 2 }, { yardId: 'dire', sequenceNo: 3 }, ]; it('rejects an identical stop sequence', async () => { const service = serviceWith([{ id: 'r1', milestones: addisAdamaDire }]); await expect( assertNotDuplicate(service, ['addis', 'adama', 'dire']), ).rejects.toBeInstanceOf(ConflictException); }); it('allows the same endpoints with a different corridor', async () => { // Same origin + destination, but skipping Adama is a genuinely other route. const service = serviceWith([{ id: 'r1', milestones: addisAdamaDire }]); await expect( assertNotDuplicate(service, ['addis', 'dire']), ).resolves.toBeUndefined(); }); it('does not flag the route being edited against itself', async () => { const service = serviceWith([{ id: 'r1', milestones: addisAdamaDire }]); await expect( assertNotDuplicate(service, ['addis', 'adama', 'dire'], 'r1'), ).resolves.toBeUndefined(); }); it('compares stops by sequence, not storage order', async () => { const shuffled: StopSeq = [ { yardId: 'dire', sequenceNo: 3 }, { yardId: 'addis', sequenceNo: 1 }, { yardId: 'adama', sequenceNo: 2 }, ]; const service = serviceWith([{ id: 'r1', milestones: shuffled }]); await expect( assertNotDuplicate(service, ['addis', 'adama', 'dire']), ).rejects.toBeInstanceOf(ConflictException); }); });