diff --git a/package.json b/package.json index 3a42808..94dc9e6 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ "test:unit": "jest --testPathPattern 'tests/unit/' --verbose", "test:unit:watch": "jest --testPathPattern 'tests/unit/' --verbose --watch", "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage", - "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose --watch", - "test:integration:watch": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose", + "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose", + "test:integration:watch": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose --watch", "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'", "test:cov": "jest --testPathPattern 'tests/unit/' --coverage", "test:e2e": "jest --config ./test/jest-e2e.json", diff --git a/src/modules/ad/adapters/primaries/ad.controller.ts b/src/modules/ad/adapters/primaries/ad.controller.ts index f0ce22d..9f82c1b 100644 --- a/src/modules/ad/adapters/primaries/ad.controller.ts +++ b/src/modules/ad/adapters/primaries/ad.controller.ts @@ -41,6 +41,8 @@ export class AdController { @GrpcMethod('AdsService', 'Create') async createAd(data: CreateAdRequest): Promise { + console.log('controler'); + console.log(data); try { const ad = await this._commandBus.execute(new CreateAdCommand(data)); return this._mapper.map(ad, Ad, AdPresenter); diff --git a/src/modules/ad/domain/dtos/create-ad.request.ts b/src/modules/ad/domain/dtos/create-ad.request.ts index 9de8a83..90c3714 100644 --- a/src/modules/ad/domain/dtos/create-ad.request.ts +++ b/src/modules/ad/domain/dtos/create-ad.request.ts @@ -20,6 +20,7 @@ import { AddressRequestDTO } from './create.address.request'; import { HasProperPassengerSeats } from './validators/has-passenger-seats.validator'; import { HasProperDriverSeats } from './validators/has-driver-seats.validator'; import { HasProperPositionIndexes } from './validators/address-position.validator'; +import { IsPunctualOrRecurrent } from './validators/is-punctual-or-recurrent.validator'; export class CreateAdRequest { @IsOptional() @@ -48,28 +49,30 @@ export class CreateAdRequest { @AutoMap() frequency: Frequency; - @ValidateIf((ad) => ad.frequency === 'PUNCTUAL') + @IsOptional() + @IsPunctualOrRecurrent() @Type(() => Date) @IsDate() @AutoMap() departure?: Date; - @ValidateIf((ad) => ad.frequency === 'RECURRENT') + @IsOptional() + @IsPunctualOrRecurrent() @Type(() => Date) @IsDate() @AutoMap() fromDate?: Date; - @ValidateIf((ad) => ad.frequency === 'RECURRENT') + @IsOptional() + @IsPunctualOrRecurrent() @Type(() => Date) @IsDate() @AutoMap() toDate?: Date; - @ValidateIf((ad) => ad.frequency === 'RECURRENT') @Type(() => ScheduleDTO) + @IsPunctualOrRecurrent() @ValidateNested({ each: true }) - @IsNotEmptyObject() @AutoMap() schedule: ScheduleDTO = {}; diff --git a/src/modules/ad/domain/dtos/validators/is-punctual-or-recurrent.validator.ts b/src/modules/ad/domain/dtos/validators/is-punctual-or-recurrent.validator.ts index 4e0e56d..a97d696 100644 --- a/src/modules/ad/domain/dtos/validators/is-punctual-or-recurrent.validator.ts +++ b/src/modules/ad/domain/dtos/validators/is-punctual-or-recurrent.validator.ts @@ -4,35 +4,53 @@ import { ValidationOptions, buildMessage, } from 'class-validator'; +import { Frequency } from '../../types/frequency.enum'; -function isPunctual(): boolean { - throw new Error('Function not implemented.'); +function isPunctual(args: ValidationArguments): boolean { + if ( + args.object['frequency'] === Frequency.PUNCTUAL && + args.object['departure'] instanceof Date && + !Object.keys(args.object['schedule']).length + ) + return true; + return false; } -function isRecurrent(): boolean { - throw new Error('Function not implemented.'); +function isRecurrent(args: ValidationArguments): boolean { + if ( + args.object['frequency'] === Frequency.RECURRENT && + args.object['fromDate'] instanceof Date && + args.object['toDate'] instanceof Date && + Object.keys(args.object['schedule']).length + ) + return true; + return false; } -export const isPunctualOrRecurrent = (): boolean => { - return isPunctual() || isRecurrent(); +export const isPunctualOrRecurrent = (args: ValidationArguments): boolean => { + console.log('validator '); + console.log(args.object); + return isPunctual(args) || isRecurrent(args); }; + /* istanbul ignore next */ -// export function IsPunctualOrRecurrent( -// validationOptions?: ValidationOptions, -// ): PropertyDecorator { -// return ValidateBy( -// { -// name: '', -// constraints: [], -// validator: { -// validate: (value, args: ValidationArguments): boolean => -// isPunctualOrRecurrent(value, args), -// defaultMessage: buildMessage( -// () => `driver and driver seats are not correct`, -// validationOptions, -// ), -// }, -// }, -// validationOptions, -// ); -// } +export function IsPunctualOrRecurrent( + validationOptions?: ValidationOptions, +): PropertyDecorator { + return ValidateBy( + { + name: '', + constraints: [], + validator: { + validate: (value, args: ValidationArguments): boolean => + isPunctualOrRecurrent(args), + defaultMessage: buildMessage( + () => + `the departure, from date, to date and schedule must be properly set on reccurent or punctual ad `, + validationOptions, + ), + }, + }, + validationOptions, + ); +} diff --git a/src/modules/ad/domain/entities/recurrent-normaliser.ts b/src/modules/ad/domain/entities/recurrent-normaliser.ts index 40cbf68..f51dfd3 100644 --- a/src/modules/ad/domain/entities/recurrent-normaliser.ts +++ b/src/modules/ad/domain/entities/recurrent-normaliser.ts @@ -3,11 +3,7 @@ import { CreateAdRequest } from '../dtos/create-ad.request'; import { Frequency } from '../types/frequency.enum'; export class RecurrentNormaliser { - constructor() { - console.log('resolver call'); - } fromDateResolver(createAdRequest: CreateAdRequest): Date { - console.log('resolver call'); if (createAdRequest.frequency === Frequency.PUNCTUAL) return createAdRequest.departure; return createAdRequest.fromDate; diff --git a/src/modules/ad/domain/usecases/create-ad.usecase.ts b/src/modules/ad/domain/usecases/create-ad.usecase.ts index 757081e..f8755a5 100644 --- a/src/modules/ad/domain/usecases/create-ad.usecase.ts +++ b/src/modules/ad/domain/usecases/create-ad.usecase.ts @@ -27,8 +27,6 @@ export class CreateAdUseCase { } async execute(command: CreateAdCommand): Promise { - console.log('usecase'); - console.log(command.createAdRequest); this.ad = this._mapper.map( command.createAdRequest, CreateAdRequest, diff --git a/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts b/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts new file mode 100644 index 0000000..869fe2c --- /dev/null +++ b/src/modules/ad/tests/unit/domain/is-punctual-or-reccurent.spec.ts @@ -0,0 +1,113 @@ +import { isPunctualOrRecurrent } from '../../../domain/dtos/validators/is-punctual-or-recurrent.validator'; +import { Frequency } from '../../../domain/types/frequency.enum'; + +describe('punctual or reccurent validators', () => { + describe('punctual case ', () => { + describe('valid cases', () => { + it('should validate with valid departure and empty schedule ', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.PUNCTUAL, + departure: new Date('01-02-2023'), + schedule: {}, + }, + property: '', + }), + ).toBeTruthy(); + }); + }); + describe('invalid cases ', () => { + it('should not validate with invalid departure and empty schedule and margin', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.PUNCTUAL, + fromDate: new Date('20-10-2023'), + toDate: new Date('30-10-2023'), + }, + property: '', + }), + ).toBeFalsy(); + }); + it('should not validate with no empty schedule', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.PUNCTUAL, + departure: new Date('01-02-2023'), + schedule: { + mon: '08:30', + }, + }, + property: '', + }), + ).toBeFalsy(); + }); + }); + }); + describe('reccurent case ', () => { + describe('valid cases', () => { + it('should validate with valid from date, to date and non empty schedule ', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.RECURRENT, + fromDate: new Date('01-15-2023'), + toDate: new Date('06-30-2023'), + schedule: { + mon: '08:30', + }, + }, + property: '', + }), + ).toBeTruthy(); + }); + }); + describe('invalid cases ', () => { + it('should not validate with empty schedule ', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.RECURRENT, + fromDate: new Date('01-15-2023'), + toDate: new Date('06-30-2023'), + schedule: {}, + }, + property: '', + }), + ).toBeFalsy(); + }); + it('should not validate with invalid from date to date and empty schedule and margin', () => { + expect( + isPunctualOrRecurrent({ + value: undefined, + constraints: [], + targetName: '', + object: { + frequency: Frequency.RECURRENT, + departure: new Date('20-10-2023'), + toDate: new Date('30-10-2023'), + }, + property: '', + }), + ).toBeFalsy(); + }); + }); + }); +}); diff --git a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts index 98937eb..c43dfec 100644 --- a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts +++ b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts @@ -87,7 +87,6 @@ export abstract class PrismaRepository implements IRepository { }); return res; } catch (e) { - console.log(e); if (e instanceof Prisma.PrismaClientKnownRequestError) { throw new DatabaseException( Prisma.PrismaClientKnownRequestError.name,