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 { AutoMap } from '@automapper/classes';
|
||||||
import {
|
import {
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsDate,
|
IsDate,
|
||||||
IsInt,
|
IsInt,
|
||||||
|
@ -20,6 +19,7 @@ import { ScheduleDTO } from './create.schedule.dto';
|
||||||
import { AddressDTO } from './create.address.dto';
|
import { AddressDTO } from './create.address.dto';
|
||||||
import { HasProperPassengerSeats } from './utils/has-passenger-seats.validator';
|
import { HasProperPassengerSeats } from './utils/has-passenger-seats.validator';
|
||||||
import { HasProperDriverSeats } from './utils/has-driver-seats.validator';
|
import { HasProperDriverSeats } from './utils/has-driver-seats.validator';
|
||||||
|
import { HasProperPositionIndexes } from './utils/address-position.validator';
|
||||||
|
|
||||||
export class CreateAdRequest {
|
export class CreateAdRequest {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ -27,6 +27,7 @@ export class CreateAdRequest {
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
uuid?: string;
|
uuid?: string;
|
||||||
|
|
||||||
|
// TODO create validation rule to verify is user exists ??
|
||||||
@IsUUID(4)
|
@IsUUID(4)
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
userUuid: string;
|
userUuid: string;
|
||||||
|
@ -97,6 +98,8 @@ export class CreateAdRequest {
|
||||||
strict?: boolean;
|
strict?: boolean;
|
||||||
|
|
||||||
@ArrayMinSize(2)
|
@ArrayMinSize(2)
|
||||||
|
@Type(() => AddressDTO)
|
||||||
|
@HasProperPositionIndexes()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@AutoMap(() => [AddressDTO])
|
@AutoMap(() => [AddressDTO])
|
||||||
addresses: AddressDTO[];
|
addresses: AddressDTO[];
|
||||||
|
|
|
@ -19,9 +19,10 @@ export class AddressDTO {
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
adUuid?: string;
|
adUuid?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
position: number;
|
position?: number;
|
||||||
|
|
||||||
@IsLongitude()
|
@IsLongitude()
|
||||||
@AutoMap()
|
@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,
|
IsEnum,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
ArrayMinSize,
|
ArrayMinSize,
|
||||||
|
IsUUID,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Address } from '../entities/address';
|
import { Address } from '../entities/address';
|
||||||
import { Frequency } from '../types/frequency.enum';
|
import { Frequency } from '../types/frequency.enum';
|
||||||
import { Type } from 'class-transformer';
|
|
||||||
|
|
||||||
export class Ad {
|
export class Ad {
|
||||||
@IsString()
|
@IsUUID(4)
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
|
||||||
@IsString()
|
@IsUUID(4)
|
||||||
@AutoMap()
|
@AutoMap()
|
||||||
userUuid: string;
|
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