validator tests

This commit is contained in:
sbriat 2023-06-23 14:41:06 +02:00
parent 211bee2c70
commit 0409670eec
12 changed files with 129 additions and 17 deletions

View File

@ -1,7 +1,7 @@
import { AutoMap } from '@automapper/classes';
import { Transform } from 'class-transformer';
import { IsLatitude, IsLongitude } from 'class-validator';
import { toPrecision } from './validators/to-precision';
import { toPrecision } from './transformers/to-precision';
export class CoordinatesDto {
@Transform(({ value }) => toPrecision(value, 6), {

View File

@ -14,9 +14,9 @@ import { Transform, Type } from 'class-transformer';
import { ScheduleDto } from './schedule.dto';
import { MarginDurationsDto } from './margin-durations.dto';
import { WaypointDto } from './waypoint.dto';
import { intToFrequency } from './validators/frequency.mapping';
import { IsSchedule } from './validators/decorators/is-schedule.validator';
import { HasValidPositionIndexes } from './validators/decorators/valid-position-indexes.validator';
import { intToFrequency } from './transformers/int-to-frequency';
import { IsSchedule } from './validators/decorators/is-schedule.decorator';
import { HasValidPositionIndexes } from './validators/decorators/has-valid-position-indexes.decorator';
import { Frequency } from '@modules/ad/core/ad.types';
export class CreateAdRequestDto {

View File

@ -1,5 +1,5 @@
import { ValidateBy, ValidationOptions, buildMessage } from 'class-validator';
import { hasValidPositionIndexes } from '../waypoint-position';
import { hasValidPositionIndexes } from '../has-valid-position-indexes.validator';
import { WaypointDto } from '../../waypoint.dto';
export const HasValidPositionIndexes = (

View File

@ -1,14 +1,16 @@
import { WaypointDto } from '../waypoint.dto';
export const hasValidPositionIndexes = (waypoints: WaypointDto[]): boolean => {
if (!waypoints) return;
if (!waypoints) return false;
if (waypoints.length == 0) return false;
if (waypoints.every((waypoint) => waypoint.position === undefined))
return true;
return false;
if (waypoints.every((waypoint) => typeof waypoint.position === 'number')) {
waypoints.sort((a, b) => a.position - b.position);
for (let i = 1; i < waypoints.length; i++) {
if (waypoints[i - 1].position >= waypoints[i].position) return false;
}
const positions = Array.from(waypoints, (waypoint) => waypoint.position);
positions.sort();
for (let i = 1; i < positions.length; i++)
if (positions[i] != positions[i - 1] + 1) return false;
return true;
}
return false;

View File

@ -0,0 +1,62 @@
import { HasValidPositionIndexes } from '@modules/ad/interface/grpc-controllers/dtos/validators/decorators/has-valid-position-indexes.decorator';
import { WaypointDto } from '@modules/ad/interface/grpc-controllers/dtos/waypoint.dto';
import { Validator } from 'class-validator';
describe('valid position indexes decorator', () => {
class MyClass {
@HasValidPositionIndexes()
waypoints: WaypointDto[];
}
it('should return a property decorator has a function', () => {
const hasValidPositionIndexes = HasValidPositionIndexes();
expect(typeof hasValidPositionIndexes).toBe('function');
});
it('should validate an array of waypoints with valid positions', async () => {
const myClassInstance = new MyClass();
myClassInstance.waypoints = [
{
position: 0,
lon: 48.8566,
lat: 2.3522,
locality: 'Paris',
postalCode: '75000',
country: 'France',
},
{
position: 1,
lon: 49.2628,
lat: 4.0347,
locality: 'Reims',
postalCode: '51454',
country: 'France',
},
];
const validator = new Validator();
const validation = await validator.validate(myClassInstance);
expect(validation.length).toBe(0);
});
it('should not validate an array of waypoints with invalid positions', async () => {
const myClassInstance = new MyClass();
myClassInstance.waypoints = [
{
position: 1,
lon: 48.8566,
lat: 2.3522,
locality: 'Paris',
postalCode: '75000',
country: 'France',
},
{
position: 1,
lon: 49.2628,
lat: 4.0347,
locality: 'Reims',
postalCode: '51454',
country: 'France',
},
];
const validator = new Validator();
const validation = await validator.validate(myClassInstance);
expect(validation.length).toBe(1);
});
});

View File

@ -1,4 +1,4 @@
import { hasValidPositionIndexes } from '@modules/ad/interface/grpc-controllers/dtos/validators/waypoint-position';
import { hasValidPositionIndexes } from '@modules/ad/interface/grpc-controllers/dtos/validators/has-valid-position-indexes.validator';
import { WaypointDto } from '@modules/ad/interface/grpc-controllers/dtos/waypoint.dto';
describe('addresses position validator', () => {
@ -26,10 +26,10 @@ describe('addresses position validator', () => {
country: 'France',
};
it('should validate if no position is defined', () => {
it('should not validate if no position is defined', () => {
expect(
hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
).toBeFalsy();
});
it('should not validate if only one position is defined', () => {
mockAddress1.position = 0;
@ -61,11 +61,15 @@ describe('addresses position validator', () => {
expect(
hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
mockAddress1.position = 10;
mockAddress2.position = 0;
mockAddress1.position = 1;
mockAddress2.position = 2;
mockAddress3.position = 3;
expect(
hasValidPositionIndexes([mockAddress1, mockAddress2, mockAddress3]),
).toBeTruthy();
});
it('should not validate if no waypoints are defined', () => {
expect(hasValidPositionIndexes(undefined)).toBeFalsy();
expect(hasValidPositionIndexes([])).toBeFalsy();
});
});

View File

@ -1,5 +1,5 @@
import { Frequency } from '@modules/ad/core/ad.types';
import { intToFrequency } from '@modules/ad/interface/grpc-controllers/dtos/validators/frequency.mapping';
import { intToFrequency } from '@modules/ad/interface/grpc-controllers/dtos/transformers/int-to-frequency';
describe('frequency mapping', () => {
it('should return punctual if frequency is 1', () => {

View File

@ -0,0 +1,30 @@
import { ScheduleDto } from '@modules/ad/interface/grpc-controllers/dtos/schedule.dto';
import { IsSchedule } from '@modules/ad/interface/grpc-controllers/dtos/validators/decorators/is-schedule.decorator';
import { Validator } from 'class-validator';
describe('schedule decorator', () => {
class MyClass {
@IsSchedule()
schedule: ScheduleDto;
}
it('should return a property decorator has a function', () => {
const isSchedule = IsSchedule();
expect(typeof isSchedule).toBe('function');
});
it('should validate a valid schedule', async () => {
const myClassInstance = new MyClass();
myClassInstance.schedule = {
mon: '07:15',
};
const validator = new Validator();
const validation = await validator.validate(myClassInstance);
expect(validation.length).toBe(0);
});
it('should not validate a invalid schedule', async () => {
const myClassInstance = new MyClass();
myClassInstance.schedule = {};
const validator = new Validator();
const validation = await validator.validate(myClassInstance);
expect(validation.length).toBe(1);
});
});

View File

@ -0,0 +1,14 @@
import { toPrecision } from '@modules/ad/interface/grpc-controllers/dtos/transformers/to-precision';
describe('precision handler', () => {
it('should return a 6 digits float number for a 10 digits float input number and 6 as precision', () => {
const precised = toPrecision(1.1234567891, 6);
const stringPrecised = precised.toString().split('.')[1];
expect(stringPrecised.length).toBe(6);
});
it('should return a 2 digits float number for a 2 digits float input number and 4 as precision', () => {
const precised = toPrecision(1.12, 4);
const stringPrecised = precised.toString().split('.')[1];
expect(stringPrecised.length).toBe(2);
});
});