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

View File

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