adding driver and passenger seats validator

This commit is contained in:
Grégoire Chevalier 2023-05-15 13:42:48 +02:00
parent 7270ecb44b
commit bf08260403
12 changed files with 321 additions and 10 deletions

View File

@ -11,12 +11,14 @@ import {
ArrayMinSize,
IsNotEmptyObject,
} from 'class-validator';
import { Frequency } from '../entities/frequency.enum';
import { Frequency } from '../types/frequency.enum';
import { Transform, Type } from 'class-transformer';
import { mappingKeyToFrequency } from './utils/frequency.mapping';
import { MarginDTO } from './create.margin.dto';
import { ScheduleDTO } from './create.schedule.dto';
import { AddressDTO } from './create.address.dto';
import { HasProperPassengerSeats } from './has-passenger-seats.validator';
import { HasProperDriverSeats } from './has-driver-seats.validator';
export class CreateAdRequest {
@IsString()
@ -24,11 +26,13 @@ export class CreateAdRequest {
userUuid: string;
@IsOptional()
@HasProperDriverSeats()
@IsBoolean()
@AutoMap()
driver?: boolean;
@IsOptional()
@HasProperPassengerSeats()
@IsBoolean()
@AutoMap()
passenger?: boolean;
@ -63,13 +67,13 @@ export class CreateAdRequest {
@ValidateNested({ each: true })
@IsNotEmptyObject()
@AutoMap()
schedule: ScheduleDTO;
schedule?: ScheduleDTO;
@IsOptional()
@Type(() => MarginDTO)
@ValidateNested({ each: true })
@AutoMap()
marginDurations: MarginDTO;
marginDurations?: MarginDTO;
@ValidateIf((ad) => ad.driver)
@IsInt()

View File

@ -0,0 +1,43 @@
import {
ValidateBy,
ValidationArguments,
ValidationOptions,
buildMessage,
} from 'class-validator';
// TODO refactor ??
// TODO propely set driver max limit
export function hasProperDriverSeats(value: any, args: ValidationArguments) {
console.log('here ');
console.log(value);
console.log(args.object);
if (value === true && typeof args.object['seatsDriver'] === 'number')
return args.object['seatsDriver'] > 0;
else if (
(value === false || value === null || value === undefined) &&
(args.object['seatsDriver'] === 0 ||
args.object['seatsDriver'] === null ||
args.object['seatsDriver'] === undefined)
)
return true;
else return false;
}
export function HasProperDriverSeats(
validationOptions?: ValidationOptions,
): PropertyDecorator {
return ValidateBy(
{
name: '',
constraints: [],
validator: {
validate: (value, args: ValidationArguments): boolean =>
hasProperDriverSeats(value, args),
defaultMessage: buildMessage(
() => `driver and driver seats are not correct`,
validationOptions,
),
},
},
validationOptions,
);
}

View File

@ -0,0 +1,43 @@
import {
ValidateBy,
ValidationArguments,
ValidationOptions,
buildMessage,
} from 'class-validator';
// TODO refactor ??
// TODO propely set passenger max limit
export function hasProperPassengerSeats(value: any, args: ValidationArguments) {
console.log('here ');
console.log(value);
console.log(args.object);
if (value === true && typeof args.object['seatsPassenger'] === 'number')
return args.object['seatsPassenger'] > 0;
else if (
(value === false || value === null || value === undefined) &&
(args.object['seatsPassenger'] === 0 ||
args.object['seatsPassenger'] === null ||
args.object['seatsPassenger'] === undefined)
)
return true;
else return false;
}
export function HasProperPassengerSeats(
validationOptions?: ValidationOptions,
): PropertyDecorator {
return ValidateBy(
{
name: '',
constraints: [],
validator: {
validate: (value, args: ValidationArguments): boolean =>
hasProperPassengerSeats(value, args),
defaultMessage: buildMessage(
() => `passenger and passenger seats are not correct`,
validationOptions,
),
},
},
validationOptions,
);
}

View File

@ -1,4 +1,4 @@
import { Frequency } from '../../entities/frequency.enum';
import { Frequency } from '../../types/frequency.enum';
export const mappingKeyToFrequency = (index: number): string => {
return Frequency[index - 1];
};

View File

@ -8,7 +8,7 @@ import {
IsEnum,
} from 'class-validator';
import { Address } from '../entities/address';
import { Frequency } from './frequency.enum';
import { Frequency } from '../types/frequency.enum';
export class Ad {
@IsString()

View File

@ -0,0 +1,4 @@
import { DefaultParams } from '../types/default-params.type';
export interface IProvideParams {
getParams(): DefaultParams;
}

View File

@ -0,0 +1,3 @@
export type DefaultParams = {
DEFAULT_MARGIN: number;
};

View File

@ -21,7 +21,6 @@ export class CreateAdUseCase {
CreateAdRequest,
Ad,
);
try {
const ad = await this._repository.create(entity);
// this._messager.publish('ad.create', JSON.stringify(ad));

View File

@ -7,9 +7,11 @@ import { AdsRepository } from '../../adapters/secondaries/ads.repository';
import { CreateAdCommand } from '../../commands/create-ad.command';
import { AutomapperModule } from '@automapper/nestjs';
import { classes } from '@automapper/classes';
import { Frequency } from '../../domain/entities/frequency.enum';
import { Frequency } from '../../domain/types/frequency.enum';
import { Ad } from '../../domain/entities/ad';
import { AdProfile } from '../../mappers/ad.profile';
import { ScheduleDTO } from '../../domain/dtos/create.schedule.dto';
import { ObjectUnsubscribedError } from 'rxjs';
const mockAddress1: Address = {
position: 0,
@ -37,8 +39,19 @@ const newAdRequest: CreateAdRequest = {
frequency: Frequency.RECURRENT,
fromDate: new Date('01-05-2023'),
toDate: new Date('20-08-2023'),
tueTime: '08:00',
wedTime: '08:30',
schedule: {
tue: '08:00',
wed: '08:30',
},
marginDurations: {
mon: undefined,
tue: undefined,
wed: undefined,
thu: undefined,
fri: undefined,
sat: undefined,
sun: undefined,
},
seatsPassenger: 2,
addresses: [mockAddress1, mockAddress2],
};
@ -63,7 +76,6 @@ const mockAdRepository = {
throw new Error('Already exists');
}),
};
describe('CreateAdUseCase', () => {
let createAdUseCase: CreateAdUseCase;
beforeAll(async () => {
@ -89,6 +101,9 @@ describe('CreateAdUseCase', () => {
expect(createAdUseCase).toBeDefined();
});
// describe('Ad parameters validation', () => {
// it('should throw an error if ');
// });
describe('execution', () => {
it('should create an new ad', async () => {
const newAd: Ad = await createAdUseCase.execute(newAdCommand);

View File

@ -0,0 +1,100 @@
import { hasProperDriverSeats } from '../../domain/dtos/has-driver-seats.validator';
describe('driver and/or driver seats validator', () => {
it('should validate if driver and drivers seats is not provided ', () => {
expect(
hasProperDriverSeats(undefined, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
expect(
hasProperDriverSeats(false, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
expect(
hasProperDriverSeats(null, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
});
it('should not validate if driver is set to true but not the related seats is not provided or 0', () => {
expect(
hasProperDriverSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(false);
expect(
hasProperDriverSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: 0 },
property: '',
}),
).toBe(false);
expect(
hasProperDriverSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: undefined },
property: '',
}),
).toBe(false);
expect(
hasProperDriverSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: null },
property: '',
}),
).toBe(false);
});
it('should not validate if driver seats are provided but driver is not set or set to false ', () => {
expect(
hasProperDriverSeats(false, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: 1 },
property: '',
}),
).toBe(false);
expect(
hasProperDriverSeats(undefined, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: 1 },
property: '',
}),
).toBe(false);
expect(
hasProperDriverSeats(null, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsDriver: 1 },
property: '',
}),
).toBe(false);
});
});

View File

@ -0,0 +1,100 @@
import { hasProperPassengerSeats } from '../../domain/dtos/has-passenger-seats.validator';
describe('driver and/or passenger seats validator', () => {
it('should validate if passenger and passengers seats is not provided ', () => {
expect(
hasProperPassengerSeats(undefined, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
expect(
hasProperPassengerSeats(false, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
expect(
hasProperPassengerSeats(null, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(true);
});
it('should not validate if passenger is set to true but not the related seats is not provided or 0', () => {
expect(
hasProperPassengerSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: {},
property: '',
}),
).toBe(false);
expect(
hasProperPassengerSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: 0 },
property: '',
}),
).toBe(false);
expect(
hasProperPassengerSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: undefined },
property: '',
}),
).toBe(false);
expect(
hasProperPassengerSeats(true, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: null },
property: '',
}),
).toBe(false);
});
it('should not validate if passenger seats are provided but passenger is not set or set to false ', () => {
expect(
hasProperPassengerSeats(false, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: 1 },
property: '',
}),
).toBe(false);
expect(
hasProperPassengerSeats(undefined, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: 1 },
property: '',
}),
).toBe(false);
expect(
hasProperPassengerSeats(null, {
value: undefined,
constraints: [],
targetName: '',
object: { seatsPassenger: 1 },
property: '',
}),
).toBe(false);
});
});