From bee5fef9ff08b27e6a9a99637f0a40436e481b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Chevalier?= Date: Mon, 22 May 2023 17:23:46 +0200 Subject: [PATCH] WIP ad creation mapping --- .../ad/adapters/primaries/ad.controller.ts | 4 - .../ad/adapters/secondaries/ads.repository.ts | 27 --- src/modules/ad/domain/dtos/ad.creation.ts | 125 +++++++++++ .../ad/domain/dtos/address.creation.ts | 32 +++ .../ad/domain/dtos/create-ad.request.ts | 8 +- ...dress.dto.ts => create.address.request.ts} | 2 +- .../dtos/utils/address-position.validator.ts | 6 +- .../ad/domain/usecases/create-ad.usecase.ts | 208 ++++++------------ src/modules/ad/mappers/ad.profile.ts | 25 ++- src/modules/ad/mappers/address.profile.ts | 17 ++ .../ad/tests/unit/create-ad.usecase.spec.ts | 106 ++++++--- .../unit/has-proper-addresses-indexes.spec.ts | 8 +- .../secondaries/prisma-repository.abstract.ts | 7 - 13 files changed, 348 insertions(+), 227 deletions(-) create mode 100644 src/modules/ad/domain/dtos/ad.creation.ts create mode 100644 src/modules/ad/domain/dtos/address.creation.ts rename src/modules/ad/domain/dtos/{create.address.dto.ts => create.address.request.ts} (95%) create mode 100644 src/modules/ad/mappers/address.profile.ts diff --git a/src/modules/ad/adapters/primaries/ad.controller.ts b/src/modules/ad/adapters/primaries/ad.controller.ts index 27010e4..f0ce22d 100644 --- a/src/modules/ad/adapters/primaries/ad.controller.ts +++ b/src/modules/ad/adapters/primaries/ad.controller.ts @@ -11,7 +11,6 @@ import { Ad } from '../../domain/entities/ad'; import { CreateAdRequest } from '../../domain/dtos/create-ad.request'; import { CreateAdCommand } from '../../commands/create-ad.command'; import { DatabaseException } from '../../../database/exceptions/database.exception'; -import { AddressDTO } from '../../domain/dtos/create.address.dto'; @UsePipes( new RpcValidationPipe({ @@ -43,9 +42,6 @@ export class AdController { @GrpcMethod('AdsService', 'Create') async createAd(data: CreateAdRequest): Promise { try { - console.log('controler--------------------------------'); - console.log(data); - console.log('-----------------------------------------'); const ad = await this._commandBus.execute(new CreateAdCommand(data)); return this._mapper.map(ad, Ad, AdPresenter); } catch (e) { diff --git a/src/modules/ad/adapters/secondaries/ads.repository.ts b/src/modules/ad/adapters/secondaries/ads.repository.ts index 6456808..a46acd3 100644 --- a/src/modules/ad/adapters/secondaries/ads.repository.ts +++ b/src/modules/ad/adapters/secondaries/ads.repository.ts @@ -1,34 +1,7 @@ import { Injectable } from '@nestjs/common'; import { AdRepository } from '../../../database/domain/ad-repository'; import { Ad } from '../../domain/entities/ad'; -import { DatabaseException } from '../../../database/exceptions/database.exception'; -import { Prisma } from '@prisma/client'; @Injectable() export class AdsRepository extends AdRepository { protected _model = 'ad'; - - async create(entity: Partial | any, include?: any): Promise { - console.log('custom ad repo '); - console.log(entity); - console.log('*****************************************'); - try { - const res = await this._prisma[this._model].create({ - data: entity, - include: include, - }); - return res; - } catch (e) { - console.log('repo error '); - console.log(e); - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - } } diff --git a/src/modules/ad/domain/dtos/ad.creation.ts b/src/modules/ad/domain/dtos/ad.creation.ts new file mode 100644 index 0000000..48356f5 --- /dev/null +++ b/src/modules/ad/domain/dtos/ad.creation.ts @@ -0,0 +1,125 @@ +import { AutoMap } from '@automapper/classes'; +import { + IsOptional, + IsString, + IsBoolean, + IsDate, + IsInt, + IsEnum, + ValidateNested, + IsUUID, +} from 'class-validator'; +import { Frequency } from '../types/frequency.enum'; +import { AddressCreation } from './address.creation'; +export class AdCreation { + @IsUUID(4) + @AutoMap() + userUuid: string; + + @IsBoolean() + @AutoMap() + driver: boolean; + + @IsBoolean() + @AutoMap() + passenger: boolean; + + @IsEnum(Frequency) + @AutoMap() + frequency: Frequency; + + @IsDate() + @AutoMap() + fromDate: Date; + + @IsDate() + @AutoMap() + toDate: Date; + + @IsOptional() + @IsDate() + @AutoMap() + monTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + tueTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + wedTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + thuTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + friTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + satTime?: string; + + @IsOptional() + @IsString() + @AutoMap() + sunTime?: string; + + @IsInt() + @AutoMap() + monMargin: number; + + @IsInt() + @AutoMap() + tueMargin: number; + + @IsInt() + @AutoMap() + wedMargin: number; + + @IsInt() + @AutoMap() + thuMargin: number; + + @IsInt() + @AutoMap() + friMargin: number; + + @IsInt() + @AutoMap() + satMargin: number; + + @IsInt() + @AutoMap() + sunMargin: number; + + @IsInt() + @AutoMap() + seatsDriver: number; + + @IsInt() + @AutoMap() + seatsPassenger: number; + + @IsBoolean() + @AutoMap() + strict: boolean; + + @IsDate() + @AutoMap() + createdAt: Date; + + @IsDate() + @AutoMap() + updatedAt?: Date; + + @ValidateNested({ each: true }) + @AutoMap() + addresses: { create: AddressCreation[] }; +} diff --git a/src/modules/ad/domain/dtos/address.creation.ts b/src/modules/ad/domain/dtos/address.creation.ts new file mode 100644 index 0000000..90622db --- /dev/null +++ b/src/modules/ad/domain/dtos/address.creation.ts @@ -0,0 +1,32 @@ +import { AutoMap } from '@automapper/classes'; +import { IsInt } from 'class-validator'; + +export class AddressCreation { + @IsInt() + @AutoMap() + position: number; + + @AutoMap() + lon: number; + + @AutoMap() + lat: number; + + @AutoMap() + name?: string; + + @AutoMap() + houseNumber?: string; + + @AutoMap() + street?: string; + + @AutoMap() + locality: string; + + @AutoMap() + postalCode: string; + + @AutoMap() + country: string; +} diff --git a/src/modules/ad/domain/dtos/create-ad.request.ts b/src/modules/ad/domain/dtos/create-ad.request.ts index 6014f21..1ae4c87 100644 --- a/src/modules/ad/domain/dtos/create-ad.request.ts +++ b/src/modules/ad/domain/dtos/create-ad.request.ts @@ -16,7 +16,7 @@ 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 { AddressRequestDTO } from './create.address.request'; import { HasProperPassengerSeats } from './utils/has-passenger-seats.validator'; import { HasProperDriverSeats } from './utils/has-driver-seats.validator'; import { HasProperPositionIndexes } from './utils/address-position.validator'; @@ -27,7 +27,6 @@ export class CreateAdRequest { @AutoMap() uuid?: string; - // TODO create validation rule to verify is user exists ?? @IsUUID(4) @AutoMap() userUuid: string; @@ -51,6 +50,7 @@ export class CreateAdRequest { @AutoMap() frequency: Frequency; + // TODO create a proper validator @ValidateIf((ad) => ad.frequency === 'PUNCTUAL') @Type(() => Date) @IsDate() @@ -98,9 +98,9 @@ export class CreateAdRequest { strict?: boolean; @ArrayMinSize(2) - @Type(() => AddressDTO) + @Type(() => AddressRequestDTO) @HasProperPositionIndexes() @ValidateNested({ each: true }) @AutoMap() - addresses: AddressDTO[]; + addresses: AddressRequestDTO[]; } diff --git a/src/modules/ad/domain/dtos/create.address.dto.ts b/src/modules/ad/domain/dtos/create.address.request.ts similarity index 95% rename from src/modules/ad/domain/dtos/create.address.dto.ts rename to src/modules/ad/domain/dtos/create.address.request.ts index 17a7b79..59d6e8f 100644 --- a/src/modules/ad/domain/dtos/create.address.dto.ts +++ b/src/modules/ad/domain/dtos/create.address.request.ts @@ -8,7 +8,7 @@ import { IsUUID, } from 'class-validator'; -export class AddressDTO { +export class AddressRequestDTO { @IsOptional() @IsUUID(4) @AutoMap() diff --git a/src/modules/ad/domain/dtos/utils/address-position.validator.ts b/src/modules/ad/domain/dtos/utils/address-position.validator.ts index 1452f0f..873790c 100644 --- a/src/modules/ad/domain/dtos/utils/address-position.validator.ts +++ b/src/modules/ad/domain/dtos/utils/address-position.validator.ts @@ -1,7 +1,7 @@ import { ValidateBy, ValidationOptions, buildMessage } from 'class-validator'; -import { AddressDTO } from '../create.address.dto'; +import { AddressRequestDTO } from '../create.address.request'; -export function hasProperPositionIndexes(value: AddressDTO[]) { +export function hasProperPositionIndexes(value: AddressRequestDTO[]) { if (value.every((address) => address.position === undefined)) return true; else if (value.every((address) => typeof address.position === 'number')) { value.sort((a, b) => a.position - b.position); @@ -21,7 +21,7 @@ export function HasProperPositionIndexes( name: '', constraints: [], validator: { - validate: (value: AddressDTO[]): boolean => + validate: (value: AddressRequestDTO[]): boolean => hasProperPositionIndexes(value), defaultMessage: buildMessage( () => diff --git a/src/modules/ad/domain/usecases/create-ad.usecase.ts b/src/modules/ad/domain/usecases/create-ad.usecase.ts index 88a991c..93c970a 100644 --- a/src/modules/ad/domain/usecases/create-ad.usecase.ts +++ b/src/modules/ad/domain/usecases/create-ad.usecase.ts @@ -6,15 +6,16 @@ import { Messager } from '../../adapters/secondaries/messager'; import { AdsRepository } from '../../adapters/secondaries/ads.repository'; import { CreateAdCommand } from '../../commands/create-ad.command'; import { CreateAdRequest } from '../dtos/create-ad.request'; -import { Ad } from '../entities/ad'; + import { IProvideParams } from '../interfaces/param-provider.interface'; import { DefaultParams } from '../types/default-params.type'; -import { Address } from '../entities/address'; +import { AdCreation } from '../dtos/ad.creation'; +import { Ad } from '../entities/ad'; @CommandHandler(CreateAdCommand) export class CreateAdUseCase { private readonly defaultParams: DefaultParams; - private ad: Ad; + private ad: AdCreation; constructor( private readonly _repository: AdsRepository, private readonly _messager: Messager, @@ -26,50 +27,25 @@ export class CreateAdUseCase { } async execute(command: CreateAdCommand): Promise { - console.log('before mapping '); - const entity: Ad = this._mapper.map( + this.ad = this._mapper.map( command.createAdRequest, CreateAdRequest, - Ad, + AdCreation, ); - typeof entity.monMargin === 'number' - ? entity.monMargin - : (entity.monMargin = this.defaultParams.MON_MARGIN); - typeof entity.tueMargin === 'number' - ? entity.tueMargin - : (entity.tueMargin = this.defaultParams.TUE_MARGIN); - typeof entity.wedMargin === 'number' - ? entity.wedMargin - : (entity.wedMargin = this.defaultParams.WED_MARGIN); - typeof entity.thuMargin === 'number' - ? entity.thuMargin - : (entity.thuMargin = this.defaultParams.THU_MARGIN); - typeof entity.friMargin === 'number' - ? entity.friMargin - : (entity.friMargin = this.defaultParams.FRI_MARGIN); - typeof entity.satMargin === 'number' - ? entity.satMargin - : (entity.satMargin = this.defaultParams.SAT_MARGIN); - typeof entity.sunMargin === 'number' - ? entity.sunMargin - : (entity.sunMargin = this.defaultParams.SUN_MARGIN); - typeof entity.strict === 'boolean' - ? entity.strict - : (entity.strict = this.defaultParams.STRICT); + this.setDefaultSchedule(); + this.setDefaultAddressesPosition(); + this.setDefaultDriverAndPassengerParameters(); + this.setDefaultDistanceMargin(); - if (typeof entity.addresses[0].position === 'undefined') { - for (let i = 0; i < entity.addresses.length; i++) { - entity.addresses[i].position = i; - } - } try { - console.log('before ***********************************'); - console.log(entity); - console.log('******************************************'); - this.ad = await this._repository.create(entity); - // this._messager.publish('ad.create', JSON.stringify(ad)); - // this._messager.publish('logging.ad.create.info', JSON.stringify(ad)); - return this.ad; + console.log(this.ad); + const adCreated: Ad = await this._repository.create(this.ad); + this._messager.publish('ad.create', JSON.stringify(adCreated)); + this._messager.publish( + 'logging.ad.create.info', + JSON.stringify(adCreated), + ); + return adCreated; } catch (error) { let key = 'logging.ad.create.crit'; if (error.message.includes('Already exists')) { @@ -85,107 +61,49 @@ export class CreateAdUseCase { throw error; } } + setDefaultSchedule(): void { + if (this.ad.monMargin === undefined) + this.ad.monMargin = this.defaultParams.MON_MARGIN; + if (this.ad.tueMargin === undefined) + this.ad.tueMargin = this.defaultParams.TUE_MARGIN; + if (this.ad.wedMargin === undefined) + this.ad.wedMargin = this.defaultParams.WED_MARGIN; + if (this.ad.thuMargin === undefined) + this.ad.thuMargin = this.defaultParams.THU_MARGIN; + if (this.ad.friMargin === undefined) + this.ad.friMargin = this.defaultParams.FRI_MARGIN; + if (this.ad.satMargin === undefined) + this.ad.satMargin = this.defaultParams.SAT_MARGIN; + if (this.ad.sunMargin === undefined) + this.ad.sunMargin = this.defaultParams.SUN_MARGIN; + } + setDefaultDistanceMargin(): void { + if (this.ad.strict === undefined) + this.ad.strict = this.defaultParams.STRICT; + } + setDefaultDriverAndPassengerParameters(): void { + if (!this.ad.driver && !this.ad.passenger) { + this.ad.driver = this.defaultParams.DRIVER; + this.ad.seatsDriver = this.defaultParams.DRIVER_SEAT; + this.ad.passenger = this.defaultParams.PASSENGER; + this.ad.seatsPassenger = this.defaultParams.PASSENGER_SEATS; + } else { + if (!this.ad.driver) { + this.ad.driver = false; + this.ad.seatsDriver = 0; + } + if (!this.ad.passenger) { + this.ad.passenger = false; + this.ad.seatsPassenger = 0; + } + } + } + setDefaultAddressesPosition(): void { + if (this.ad.addresses.create[0].position === undefined) { + for (let i = 0; i < this.ad.addresses.create.length; i++) { + this.ad.addresses.create[i].position = i; + } + } + } + TransformPunctualToReccurent(): void {} } -/* - repo error - PrismaClientValidationError: - Invalid `this._prisma[this._model].create()` invocation in - /usr/src/app/src/modules/ad/adapters/secondaries/ads.repository.ts:15:51 - - 12 console.log(entity); - 13 console.log('*****************************************'); - 14 try { - → 15 const res = await this._prisma[this._model].create({ - data: { - uuid: undefined, - userUuid: '113e0000-0000-4000-a000-000000000000', - driver: true, - passenger: false, - frequency: 'RECURRENT', - fromDate: new Date('2023-01-15T00:00:00.000Z'), - toDate: new Date('2023-08-01T00:00:00.000Z'), - seatsDriver: 3, - seatsPassenger: 0, - strict: false, - monMargin: 800, - tueMargin: 900, - wedMargin: 900, - thuMargin: 900, - friMargin: 900, - satMargin: 900, - sunMargin: 900, - monTime: '04:40', - tueTime: undefined, - wedTime: undefined, - thuTime: undefined, - friTime: undefined, - satTime: undefined, - sunTime: undefined, - addresses: [ - { - lon: 48.68944549560547, - lat: 6.176510334014893, - houseNumber: '5', - street: 'Avenue Foch', - locality: 'Nancy', - postalCode: '54000', - country: 'France', - position: 0 - }, - { - lon: 48.85660171508789, - lat: 2.3522000312805176, - locality: 'Paris', - postalCode: '75000', - country: 'France', - position: 1 - } - ] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - }, - include: undefined - }) - - Argument addresses: Got invalid value - [ - { - lon: 48.68944549560547, - lat: 6.176510334014893, - houseNumber: '5', - street: 'Avenue Foch', - locality: 'Nancy', - postalCode: '54000', - country: 'France', - position: 0 - }, - { - lon: 48.85660171508789, - lat: 2.3522000312805176, - locality: 'Paris', - postalCode: '75000', - country: 'France', - position: 1 - } - ] - on prisma.createOneAd. Provided List, expected AddressCreateNestedManyWithoutAdInput: - type AddressCreateNestedManyWithoutAdInput { - create?: AddressCreateWithoutAdInput | List | AddressUncheckedCreateWithoutAdInput | List - connectOrCreate?: AddressCreateOrConnectWithoutAdInput | List - createMany?: AddressCreateManyAdInputEnvelope - connect?: AddressWhereUniqueInput | List - } - - - at mi.validate (/usr/src/app/node_modules/@prisma/client/runtime/library.js:149:91) - at tn.createMessage (/usr/src/app/node_modules/@prisma/client/runtime/library.js:166:1205) - at /usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10962 - at runInChildSpan (/usr/src/app/node_modules/@prisma/client/runtime/library.js:70:25817) - at PrismaService._executeRequest (/usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10951) - at PrismaService._request (/usr/src/app/node_modules/@prisma/client/runtime/library.js:179:10484) - at AdsRepository.create (/usr/src/app/src/modules/ad/adapters/secondaries/ads.repository.ts:15:19) - at CreateAdUseCase.execute (/usr/src/app/src/modules/ad/domain/usecases/create-ad.usecase.ts:69:17) - at AdController.createAd (/usr/src/app/src/modules/ad/adapters/primaries/ad.controller.ts:49:18) - at /usr/src/app/node_modules/@nestjs/microservices/context/rpc-proxy.js:11:32 - at Object.Create (/usr/src/app/node_modules/@nestjs/microservices/server/server-grpc.js:148:40) { - clientVersion: '4.13.0' -*/ diff --git a/src/modules/ad/mappers/ad.profile.ts b/src/modules/ad/mappers/ad.profile.ts index 3b2e4a6..cc9704a 100644 --- a/src/modules/ad/mappers/ad.profile.ts +++ b/src/modules/ad/mappers/ad.profile.ts @@ -1,11 +1,17 @@ -import { createMap, forMember, mapFrom, Mapper } from '@automapper/core'; +import { + condition, + 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 { Address } from '../domain/entities/address'; -import { AddressDTO } from '../domain/dtos/create.address.dto'; +import { AdCreation } from '../domain/dtos/ad.creation'; +import { Frequency } from '@prisma/client'; @Injectable() export class AdProfile extends AutomapperProfile { @@ -15,12 +21,11 @@ export class AdProfile extends AutomapperProfile { override get profile() { return (mapper) => { - createMap(mapper, Address, AddressDTO); createMap(mapper, Ad, AdPresenter); createMap( mapper, CreateAdRequest, - Ad, + AdCreation, forMember( (destination) => destination.monMargin, mapFrom((source) => source.marginDurations.mon), @@ -78,9 +83,17 @@ export class AdProfile extends AutomapperProfile { mapFrom((source) => source.schedule.sun), ), forMember( - (destination) => destination.addresses, + (destination) => destination.addresses.create, mapFrom((source) => source.addresses), ), + //TODO use custom resolver + // forMember( + // (destination) => destination.fromDate, + // condition( + // (source) => source.frequency == Frequency.PUNCTUAL, + // source.departure, + // ), + // ), ); }; } diff --git a/src/modules/ad/mappers/address.profile.ts b/src/modules/ad/mappers/address.profile.ts new file mode 100644 index 0000000..6170935 --- /dev/null +++ b/src/modules/ad/mappers/address.profile.ts @@ -0,0 +1,17 @@ +import { Mapper, createMap } from '@automapper/core'; +import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; +import { Injectable } from '@nestjs/common'; +import { AddressRequestDTO } from '../domain/dtos/create.address.request'; +import { AddressCreation } from '../domain/dtos/address.creation'; +@Injectable() +export class AdProfile extends AutomapperProfile { + constructor(@InjectMapper() mapper: Mapper) { + super(mapper); + } + + override get profile() { + return (mapper) => { + createMap(mapper, AddressRequestDTO, AddressCreation); + }; + } +} 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 a483a0d..a966f0f 100644 --- a/src/modules/ad/tests/unit/create-ad.usecase.spec.ts +++ b/src/modules/ad/tests/unit/create-ad.usecase.spec.ts @@ -9,9 +9,11 @@ import { classes } from '@automapper/classes'; import { Frequency } from '../../domain/types/frequency.enum'; import { Ad } from '../../domain/entities/ad'; import { AdProfile } from '../../mappers/ad.profile'; -import { AddressDTO } from '../../domain/dtos/create.address.dto'; +import { AddressRequestDTO } from '../../domain/dtos/create.address.request'; +import { AdCreation } from '../../domain/dtos/ad.creation'; +import { AddressCreation } from '../../domain/dtos/address.creation'; -const mockAddress1: AddressDTO = { +const mockAddress1: AddressRequestDTO = { position: 0, lon: 48.68944505415954, lat: 6.176510296462267, @@ -21,7 +23,7 @@ const mockAddress1: AddressDTO = { postalCode: '54000', country: 'France', }; -const mockAddress2: AddressDTO = { +const mockAddress2: AddressRequestDTO = { position: 1, lon: 48.8566, lat: 2.3522, @@ -29,25 +31,29 @@ const mockAddress2: AddressDTO = { postalCode: '75000', country: 'France', }; +const mockAddressWithoutPos1: AddressRequestDTO = { + lon: 43.2965, + lat: 5.3698, + locality: 'Marseille', + postalCode: '13000', + country: 'France', +}; +const mockAddressWithoutPos2: AddressRequestDTO = { + lon: 43.7102, + lat: 7.262, + locality: 'Marseille', + postalCode: '06000', + country: 'France', +}; const minimalReccurentAdREquest: CreateAdRequest = { userUuid: '224e0000-0000-4000-a000-000000000000', - driver: undefined, - passenger: undefined, frequency: Frequency.RECURRENT, fromDate: new Date('01-05-2023'), toDate: new Date('01-05-2024'), schedule: { mon: '08:00', }, - marginDurations: { - mon: undefined, - tue: undefined, - wed: undefined, - thu: undefined, - fri: undefined, - sat: undefined, - sun: undefined, - }, + marginDurations: {}, addresses: [mockAddress1, mockAddress2], }; const newAdRequest: CreateAdRequest = { @@ -70,9 +76,26 @@ const newAdRequest: CreateAdRequest = { sat: undefined, sun: undefined, }, - seatsPassenger: 2, + seatsDriver: 2, addresses: [mockAddress1, mockAddress2], }; +const newPunctualPassengerAdRequest: CreateAdRequest = { + userUuid: '113e0000-0000-4000-a000-000000000000', + passenger: true, + frequency: Frequency.PUNCTUAL, + departure: new Date('05-22-2023'), + marginDurations: { + mon: undefined, + tue: undefined, + wed: undefined, + thu: undefined, + fri: undefined, + sat: undefined, + sun: undefined, + }, + seatsPassenger: 1, + addresses: [mockAddressWithoutPos1, mockAddressWithoutPos2], +}; const mockMessager = { publish: jest.fn().mockImplementation(), @@ -109,7 +132,7 @@ let mockAdRepository = { .mockImplementationOnce(() => { throw new Error('Already exists'); }) - .mockImplementation(), + .mockImplementation((command?: CreateAdCommand) => {}), }; describe('CreateAdUseCase', () => { let createAdUseCase: CreateAdUseCase; @@ -154,17 +177,48 @@ describe('CreateAdUseCase', () => { }); describe('Ad parameter default setting ', () => { - const newAdCommand = new CreateAdCommand(minimalReccurentAdREquest); + beforeEach(() => { + mockAdRepository.create.mockClear(); + }); + it('should define mimimal ad as 1 passager add', async () => { - const newAd: Ad = await createAdUseCase.execute(newAdCommand); - expect(mockAdRepository).toBeCalledWith({ - userUuid: '113e0000-0000-4000-a000-000000000000', - driver: true, - passenger: false, - frequency: Frequency.RECURRENT, - fromDate: new Date('01-05-2023'), - toDate: new Date('20-08-2023'), - }); + const newAdCommand = new CreateAdCommand(minimalReccurentAdREquest); + await createAdUseCase.execute(newAdCommand); + const expectedAdCreation = { + userUuid: minimalReccurentAdREquest.userUuid, + frequency: minimalReccurentAdREquest.frequency, + fromDate: minimalReccurentAdREquest.fromDate, + toDate: minimalReccurentAdREquest.toDate, + monTime: minimalReccurentAdREquest.schedule.mon, + tueTime: undefined, + wedTime: undefined, + thuTime: undefined, + friTime: undefined, + satTime: undefined, + sunTime: undefined, + monMargin: mockDefaultParamsProvider.getParams().MON_MARGIN, + tueMargin: mockDefaultParamsProvider.getParams().TUE_MARGIN, + wedMargin: mockDefaultParamsProvider.getParams().WED_MARGIN, + thuMargin: mockDefaultParamsProvider.getParams().THU_MARGIN, + friMargin: mockDefaultParamsProvider.getParams().FRI_MARGIN, + satMargin: mockDefaultParamsProvider.getParams().SAT_MARGIN, + sunMargin: mockDefaultParamsProvider.getParams().SUN_MARGIN, + driver: mockDefaultParamsProvider.getParams().DRIVER, + seatsDriver: mockDefaultParamsProvider.getParams().DRIVER_SEAT, + passenger: mockDefaultParamsProvider.getParams().PASSENGER, + seatsPassenger: mockDefaultParamsProvider.getParams().PASSENGER_SEATS, + strict: mockDefaultParamsProvider.getParams().STRICT, + addresses: { + create: minimalReccurentAdREquest.addresses as AddressCreation[], + }, + createdAt: undefined, + } as AdCreation; + + expect(mockAdRepository.create).toBeCalledWith(expectedAdCreation); + }); + it('should create an passengerAd with addresses without position ', async () => { + const newAdCommand = new CreateAdCommand(newPunctualPassengerAdRequest); + await createAdUseCase.execute(newAdCommand); }); }); }); diff --git a/src/modules/ad/tests/unit/has-proper-addresses-indexes.spec.ts b/src/modules/ad/tests/unit/has-proper-addresses-indexes.spec.ts index 9010706..7bf1efe 100644 --- a/src/modules/ad/tests/unit/has-proper-addresses-indexes.spec.ts +++ b/src/modules/ad/tests/unit/has-proper-addresses-indexes.spec.ts @@ -1,7 +1,7 @@ -import { AddressDTO } from '../../domain/dtos/create.address.dto'; +import { AddressRequestDTO } from '../../domain/dtos/create.address.request'; import { hasProperPositionIndexes } from '../../domain/dtos/utils/address-position.validator'; describe('addresses position validators', () => { - const mockAddress1: AddressDTO = { + const mockAddress1: AddressRequestDTO = { lon: 48.68944505415954, lat: 6.176510296462267, houseNumber: '5', @@ -10,7 +10,7 @@ describe('addresses position validators', () => { postalCode: '54000', country: 'France', }; - const mockAddress2: AddressDTO = { + const mockAddress2: AddressRequestDTO = { lon: 48.8566, lat: 2.3522, locality: 'Paris', @@ -18,7 +18,7 @@ describe('addresses position validators', () => { country: 'France', }; - const mockAddress3: AddressDTO = { + const mockAddress3: AddressRequestDTO = { lon: 49.2628, lat: 4.0347, locality: 'Reims', diff --git a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts index a431b1d..c43dfec 100644 --- a/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts +++ b/src/modules/database/adapters/secondaries/prisma-repository.abstract.ts @@ -80,20 +80,13 @@ export abstract class PrismaRepository implements IRepository { // TODO : using any is not good, but needed for nested entities // TODO : Refactor for good clean architecture ? async create(entity: Partial | any, include?: any): Promise { - console.log('repo entity '); - console.log(entity); - console.log('-----------------------------------------'); try { const res = await this._prisma[this._model].create({ data: entity, include: include, }); - console.log('result'); - console.log(res); return res; } catch (e) { - console.log('repo error '); - console.log(e); if (e instanceof Prisma.PrismaClientKnownRequestError) { throw new DatabaseException( Prisma.PrismaClientKnownRequestError.name,