adding position index validation and unit test
This commit is contained in:
parent
8544b2f54e
commit
30c70b9f17
|
@ -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[];
|
||||
|
|
|
@ -19,9 +19,10 @@ export class AddressDTO {
|
|||
@AutoMap()
|
||||
adUuid?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@AutoMap()
|
||||
position: number;
|
||||
position?: number;
|
||||
|
||||
@IsLongitude()
|
||||
@AutoMap()
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue