adding position index validation and unit test

This commit is contained in:
Grégoire Chevalier 2023-05-16 16:12:35 +02:00
parent 8544b2f54e
commit 30c70b9f17
5 changed files with 114 additions and 6 deletions

View File

@ -1,7 +1,6 @@
import { AutoMap } from '@automapper/classes';
import {
IsOptional,
IsString,
IsBoolean,
IsDate,
IsInt,
@ -20,6 +19,7 @@ import { ScheduleDTO } from './create.schedule.dto';
import { AddressDTO } from './create.address.dto';
import { HasProperPassengerSeats } from './utils/has-passenger-seats.validator';
import { HasProperDriverSeats } from './utils/has-driver-seats.validator';
import { HasProperPositionIndexes } from './utils/address-position.validator';
export class CreateAdRequest {
@IsOptional()
@ -27,6 +27,7 @@ export class CreateAdRequest {
@AutoMap()
uuid?: string;
// TODO create validation rule to verify is user exists ??
@IsUUID(4)
@AutoMap()
userUuid: string;
@ -97,6 +98,8 @@ export class CreateAdRequest {
strict?: boolean;
@ArrayMinSize(2)
@Type(() => AddressDTO)
@HasProperPositionIndexes()
@ValidateNested({ each: true })
@AutoMap(() => [AddressDTO])
addresses: AddressDTO[];

View File

@ -19,9 +19,10 @@ export class AddressDTO {
@AutoMap()
adUuid?: string;
@IsOptional()
@IsInt()
@AutoMap()
position: number;
position?: number;
@IsLongitude()
@AutoMap()

View File

@ -0,0 +1,35 @@
import { ValidateBy, ValidationOptions, buildMessage } from 'class-validator';
import { AddressDTO } from '../create.address.dto';
export function hasProperPositionIndexes(value: AddressDTO[]) {
if (value.every((address) => address.position === undefined)) return true;
else if (value.every((address) => typeof address.position === 'number')) {
value.sort((a, b) => a.position - b.position);
for (let i = 1; i < value.length; i++) {
if (value[i - 1].position >= value[i].position) return false;
}
return true;
}
return false;
}
export function HasProperPositionIndexes(
validationOptions?: ValidationOptions,
): PropertyDecorator {
return ValidateBy(
{
name: '',
constraints: [],
validator: {
validate: (value: AddressDTO[]): boolean =>
hasProperPositionIndexes(value),
defaultMessage: buildMessage(
() =>
`indexes position incorrect, please provide a complete list of indexes or ordened list of adresses from start to end of journey`,
validationOptions,
),
},
},
validationOptions,
);
}

View File

@ -8,17 +8,16 @@ import {
IsEnum,
ValidateNested,
ArrayMinSize,
IsUUID,
} from 'class-validator';
import { Address } from '../entities/address';
import { Frequency } from '../types/frequency.enum';
import { Type } from 'class-transformer';
export class Ad {
@IsString()
@IsUUID(4)
@AutoMap()
uuid: string;
@IsString()
@IsUUID(4)
@AutoMap()
userUuid: string;

View File

@ -0,0 +1,70 @@
import { AddressDTO } from '../../domain/dtos/create.address.dto';
import { hasProperPositionIndexes } from '../../domain/dtos/utils/address-position.validator';
describe('addresses position validators', () => {
const mockAddress1: AddressDTO = {
lon: 48.68944505415954,
lat: 6.176510296462267,
houseNumber: '5',
street: 'Avenue Foch',
locality: 'Nancy',
postalCode: '54000',
country: 'France',
};
const mockAddress2: AddressDTO = {
lon: 48.8566,
lat: 2.3522,
locality: 'Paris',
postalCode: '75000',
country: 'France',
};
const mockAddress3: AddressDTO = {
lon: 49.2628,
lat: 4.0347,
locality: 'Reims',
postalCode: '51454',
country: 'France',
};
it('should validate if none of position is definded ', () => {
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
});
it('should throw an error if position are partialy defined ', () => {
mockAddress1.position = 0;
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeFalsy();
});
it('should throw an error if position are partialy defined ', () => {
mockAddress1.position = 0;
mockAddress2.position = null;
mockAddress3.position = undefined;
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeFalsy();
});
it('should throw an error if positions are not incremented ', () => {
mockAddress1.position = 0;
mockAddress2.position = 1;
mockAddress3.position = 1;
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeFalsy();
});
it('should validate if all positions are defined and incremented', () => {
mockAddress1.position = 0;
mockAddress2.position = 1;
mockAddress3.position = 2;
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
mockAddress1.position = 10;
mockAddress2.position = 0;
mockAddress3.position = 3;
expect(
hasProperPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
});
});