From ade550871397ac42af2a801a54277e00ef213664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Chevalier?= Date: Tue, 23 May 2023 14:01:04 +0200 Subject: [PATCH] adding reccurent normaliser and tests --- .../ad/domain/dtos/create-ad.request.ts | 2 +- .../ad/domain/entities/ReccurentNormaliser.ts | 97 +++++++++++++++++++ .../ad/domain/usecases/create-ad.usecase.ts | 7 +- src/modules/ad/mappers/ad.profile.ts | 73 ++++++++++---- .../ad/tests/unit/create-ad.usecase.spec.ts | 2 + .../ad/tests/unit/reccurentNormaliser.spec.ts | 92 ++++++++++++++++++ 6 files changed, 253 insertions(+), 20 deletions(-) create mode 100644 src/modules/ad/domain/entities/ReccurentNormaliser.ts create mode 100644 src/modules/ad/tests/unit/reccurentNormaliser.spec.ts diff --git a/src/modules/ad/domain/dtos/create-ad.request.ts b/src/modules/ad/domain/dtos/create-ad.request.ts index 1ae4c87..1da5052 100644 --- a/src/modules/ad/domain/dtos/create-ad.request.ts +++ b/src/modules/ad/domain/dtos/create-ad.request.ts @@ -74,7 +74,7 @@ export class CreateAdRequest { @ValidateNested({ each: true }) @IsNotEmptyObject() @AutoMap() - schedule?: ScheduleDTO; + schedule: ScheduleDTO = {}; @IsOptional() @Type(() => MarginDTO) diff --git a/src/modules/ad/domain/entities/ReccurentNormaliser.ts b/src/modules/ad/domain/entities/ReccurentNormaliser.ts new file mode 100644 index 0000000..2a1fcbd --- /dev/null +++ b/src/modules/ad/domain/entities/ReccurentNormaliser.ts @@ -0,0 +1,97 @@ +import { CreateAdRequest } from '../dtos/create-ad.request'; + +import { Frequency } from '../types/frequency.enum'; + +export class ReccurentNormaliser { + constructor() {} + + fromDateResolver(createAdRequest: CreateAdRequest): Date { + if (createAdRequest.frequency === Frequency.PUNCTUAL) + return createAdRequest.departure; + return createAdRequest.fromDate; + } + toDateResolver(createAdRequest: CreateAdRequest): Date { + if (createAdRequest.frequency === Frequency.PUNCTUAL) + return createAdRequest.departure; + return createAdRequest.toDate; + } + scheduleSunResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 0 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.sun; + } + scheduleMonResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 1 + ) { + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + } + + return createAdRequest.schedule.mon; + } + scheduleTueResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 2 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.tue; + } + scheduleWedResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 3 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.wed; + } + scheduleThuResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 4 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.thu; + } + scheduleFriResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 5 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.fri; + } + scheduleSatResolver(createAdRequest: CreateAdRequest): string { + if ( + Object.keys(createAdRequest.schedule).length === 0 && + createAdRequest.frequency == Frequency.PUNCTUAL && + createAdRequest.departure.getDay() === 6 + ) + return `${('0' + createAdRequest.departure.getHours()).slice(-2)}:${( + '0' + createAdRequest.departure.getMinutes() + ).slice(-2)}`; + return createAdRequest.schedule.sat; + } +} diff --git a/src/modules/ad/domain/usecases/create-ad.usecase.ts b/src/modules/ad/domain/usecases/create-ad.usecase.ts index 93c970a..ad80775 100644 --- a/src/modules/ad/domain/usecases/create-ad.usecase.ts +++ b/src/modules/ad/domain/usecases/create-ad.usecase.ts @@ -11,6 +11,7 @@ import { IProvideParams } from '../interfaces/param-provider.interface'; import { DefaultParams } from '../types/default-params.type'; import { AdCreation } from '../dtos/ad.creation'; import { Ad } from '../entities/ad'; +import { Frequency } from '../types/frequency.enum'; @CommandHandler(CreateAdCommand) export class CreateAdUseCase { @@ -38,7 +39,6 @@ export class CreateAdUseCase { this.setDefaultDistanceMargin(); try { - console.log(this.ad); const adCreated: Ad = await this._repository.create(this.ad); this._messager.publish('ad.create', JSON.stringify(adCreated)); this._messager.publish( @@ -105,5 +105,8 @@ export class CreateAdUseCase { } } } - TransformPunctualToReccurent(): void {} + TransformPunctualToReccurent(): void { + if (this.ad.frequency === Frequency.PUNCTUAL) { + } + } } diff --git a/src/modules/ad/mappers/ad.profile.ts b/src/modules/ad/mappers/ad.profile.ts index cc9704a..6763a29 100644 --- a/src/modules/ad/mappers/ad.profile.ts +++ b/src/modules/ad/mappers/ad.profile.ts @@ -1,24 +1,18 @@ -import { - condition, - createMap, - forMember, - mapFrom, - Mapper, -} from '@automapper/core'; +import { createMap, forMember, mapFrom, Mapper } from '@automapper/core'; import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; import { Injectable } from '@nestjs/common'; import { Ad } from '../domain/entities/ad'; import { AdPresenter } from '../adapters/primaries/ad.presenter'; import { CreateAdRequest } from '../domain/dtos/create-ad.request'; import { AdCreation } from '../domain/dtos/ad.creation'; -import { Frequency } from '@prisma/client'; +import { ReccurentNormaliser } from '../domain/entities/ReccurentNormaliser'; @Injectable() export class AdProfile extends AutomapperProfile { + reccurentNormaliser = new ReccurentNormaliser(); constructor(@InjectMapper() mapper: Mapper) { super(mapper); } - override get profile() { return (mapper) => { createMap(mapper, Ad, AdPresenter); @@ -26,6 +20,7 @@ export class AdProfile extends AutomapperProfile { mapper, CreateAdRequest, AdCreation, + forMember( (destination) => destination.monMargin, mapFrom((source) => source.marginDurations.mon), @@ -86,14 +81,58 @@ export class AdProfile extends AutomapperProfile { (destination) => destination.addresses.create, mapFrom((source) => source.addresses), ), - //TODO use custom resolver - // forMember( - // (destination) => destination.fromDate, - // condition( - // (source) => source.frequency == Frequency.PUNCTUAL, - // source.departure, - // ), - // ), + forMember( + (destination) => destination.fromDate, + mapFrom((source) => + this.reccurentNormaliser.fromDateResolver(source), + ), + ), + forMember( + (destination) => destination.toDate, + mapFrom((source) => this.reccurentNormaliser.toDateResolver(source)), + ), + forMember( + (destination) => destination.monTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleMonResolver(source), + ), + ), + forMember( + (destination) => destination.tueTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleTueResolver(source), + ), + ), + forMember( + (destination) => destination.wedTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleWedResolver(source), + ), + ), + forMember( + (destination) => destination.thuTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleThuResolver(source), + ), + ), + forMember( + (destination) => destination.friTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleFriResolver(source), + ), + ), + forMember( + (destination) => destination.satTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleSatResolver(source), + ), + ), + forMember( + (destination) => destination.sunTime, + mapFrom((source) => + this.reccurentNormaliser.scheduleSunResolver(source), + ), + ), ); }; } diff --git a/src/modules/ad/tests/unit/create-ad.usecase.spec.ts b/src/modules/ad/tests/unit/create-ad.usecase.spec.ts index a966f0f..6db136d 100644 --- a/src/modules/ad/tests/unit/create-ad.usecase.spec.ts +++ b/src/modules/ad/tests/unit/create-ad.usecase.spec.ts @@ -84,6 +84,7 @@ const newPunctualPassengerAdRequest: CreateAdRequest = { passenger: true, frequency: Frequency.PUNCTUAL, departure: new Date('05-22-2023'), + marginDurations: { mon: undefined, tue: undefined, @@ -95,6 +96,7 @@ const newPunctualPassengerAdRequest: CreateAdRequest = { }, seatsPassenger: 1, addresses: [mockAddressWithoutPos1, mockAddressWithoutPos2], + schedule: {}, }; const mockMessager = { diff --git a/src/modules/ad/tests/unit/reccurentNormaliser.spec.ts b/src/modules/ad/tests/unit/reccurentNormaliser.spec.ts new file mode 100644 index 0000000..f507c73 --- /dev/null +++ b/src/modules/ad/tests/unit/reccurentNormaliser.spec.ts @@ -0,0 +1,92 @@ +import { CreateAdRequest } from '../../domain/dtos/create-ad.request'; +import { ScheduleDTO } from '../../domain/dtos/create.schedule.dto'; +import { ReccurentNormaliser } from '../../domain/entities/ReccurentNormaliser'; +import { Frequency } from '../../domain/types/frequency.enum'; +describe('reccurent normalizer transformer for punctual ad ', () => { + const reccurentNormaliser = new ReccurentNormaliser(); + it('should transform punctual ad into reccurent ad ', () => { + const punctualAd: CreateAdRequest = { + userUuid: '', + frequency: Frequency.PUNCTUAL, + departure: new Date('05-03-2023 12:39:39 '), + schedule: {} as ScheduleDTO, + addresses: [], + }; + expect(reccurentNormaliser.fromDateResolver(punctualAd)).toBe( + punctualAd.departure, + ); + expect(reccurentNormaliser.toDateResolver(punctualAd)).toBe( + punctualAd.departure, + ); + expect(reccurentNormaliser.scheduleMonResolver(punctualAd)).toBeUndefined(); + expect(reccurentNormaliser.scheduleTueResolver(punctualAd)).toBeUndefined(); + expect(reccurentNormaliser.scheduleWedResolver(punctualAd)).toBe('12:39'); + expect(reccurentNormaliser.scheduleThuResolver(punctualAd)).toBeUndefined(); + expect(reccurentNormaliser.scheduleFriResolver(punctualAd)).toBeUndefined(); + expect(reccurentNormaliser.scheduleSatResolver(punctualAd)).toBeUndefined(); + expect(reccurentNormaliser.scheduleSunResolver(punctualAd)).toBeUndefined(); + }); + it('should leave reccurent ad as is', () => { + const reccurentAd: CreateAdRequest = { + userUuid: '', + frequency: Frequency.RECURRENT, + schedule: { + mon: '08:30', + tue: '08:30', + wed: '09:00', + fri: '09:00', + }, + addresses: [], + }; + expect(reccurentNormaliser.fromDateResolver(reccurentAd)).toBe( + reccurentAd.departure, + ); + expect(reccurentNormaliser.toDateResolver(reccurentAd)).toBe( + reccurentAd.departure, + ); + expect(reccurentNormaliser.scheduleMonResolver(reccurentAd)).toBe( + reccurentAd.schedule.mon, + ); + expect(reccurentNormaliser.scheduleTueResolver(reccurentAd)).toBe( + reccurentAd.schedule.tue, + ); + expect(reccurentNormaliser.scheduleWedResolver(reccurentAd)).toBe( + reccurentAd.schedule.wed, + ); + expect(reccurentNormaliser.scheduleThuResolver(reccurentAd)).toBe( + reccurentAd.schedule.thu, + ); + expect(reccurentNormaliser.scheduleFriResolver(reccurentAd)).toBe( + reccurentAd.schedule.fri, + ); + expect(reccurentNormaliser.scheduleSatResolver(reccurentAd)).toBe( + reccurentAd.schedule.sat, + ); + expect(reccurentNormaliser.scheduleSunResolver(reccurentAd)).toBe( + reccurentAd.schedule.sun, + ); + }); + it('should pass for each day of the week of a deprarture ', () => { + const punctualAd: CreateAdRequest = { + userUuid: '', + frequency: Frequency.PUNCTUAL, + departure: undefined, + schedule: {} as ScheduleDTO, + addresses: [], + }; + punctualAd.departure = new Date('05-01-2023 '); + expect(reccurentNormaliser.scheduleMonResolver(punctualAd)).toBe('00:00'); + punctualAd.departure = new Date('05-02-2023 06:32:45'); + expect(reccurentNormaliser.scheduleTueResolver(punctualAd)).toBe('06:32'); + punctualAd.departure = new Date('05-03-2023 10:21'); + expect(reccurentNormaliser.scheduleWedResolver(punctualAd)).toBe('10:21'); + punctualAd.departure = new Date('05-04-2023 11:06:00'); + expect(reccurentNormaliser.scheduleThuResolver(punctualAd)).toBe('11:06'); + punctualAd.departure = new Date('05-05-2023 05:20'); + expect(reccurentNormaliser.scheduleFriResolver(punctualAd)).toBe('05:20'); + punctualAd.departure = new Date('05-06-2023'); + expect(reccurentNormaliser.scheduleSatResolver(punctualAd)).toBe('00:00'); + punctualAd.departure = new Date('05-07-2023'); + expect(reccurentNormaliser.scheduleSunResolver(punctualAd)).toBe('00:00'); + }); +});