From 88326dcf6f8c06e00612aefcf01705787198b8b2 Mon Sep 17 00:00:00 2001 From: sbriat Date: Fri, 18 Aug 2023 16:50:55 +0200 Subject: [PATCH] basic ad entity without direction --- package-lock.json | 7 +++++++ package.json | 1 + src/app.module.ts | 2 +- src/modules/ad/ad.di-tokens.ts | 1 + src/modules/ad/ad.mapper.ts | 11 ++++++++-- src/modules/ad/ad.module.ts | 18 ++++++++++++++-- src/modules/ad/tests/unit/ad.mapper.spec.ts | 21 ++++++++++++++++++- .../unit/infrastructure/ad.repository.spec.ts | 15 ++++++++++++- .../infrastructure/default-params-provider.ts | 6 +++--- .../postgres-direction-encoder.ts | 2 ++ 10 files changed, 74 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5639504..b798ee2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "@types/jest": "29.5.0", "@types/node": "18.15.11", "@types/supertest": "^2.0.11", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "dotenv-cli": "^7.2.1", @@ -2655,6 +2656,12 @@ "@types/superagent": "*" } }, + "node_modules/@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, "node_modules/@types/validator": { "version": "13.11.1", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz", diff --git a/package.json b/package.json index 3c727a9..64b005d 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@types/jest": "29.5.0", "@types/node": "18.15.11", "@types/supertest": "^2.0.11", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "dotenv-cli": "^7.2.1", diff --git a/src/app.module.ts b/src/app.module.ts index 2df816c..4fcc186 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -63,6 +63,6 @@ import { GeographyModule } from '@modules/geography/geography.module'; GeographyModule, MessagerModule, ], - exports: [AdModule, MessagerModule], + exports: [AdModule, GeographyModule, MessagerModule], }) export class AppModule {} diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts index d87cfdd..d4d5d64 100644 --- a/src/modules/ad/ad.di-tokens.ts +++ b/src/modules/ad/ad.di-tokens.ts @@ -1,3 +1,4 @@ export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); export const GEOROUTER = Symbol('GEOROUTER'); +export const AD_DIRECTION_ENCODER = Symbol('AD_DIRECTION_ENCODER'); export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index b4915c7..ba6dafe 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -1,5 +1,5 @@ import { Mapper } from '@mobicoop/ddd-library'; -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { AdEntity } from './core/domain/ad.entity'; import { AdWriteModel, @@ -9,6 +9,8 @@ import { import { Frequency } from './core/domain/ad.types'; import { v4 } from 'uuid'; import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; +import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; /** * Mapper constructs objects that are used in different layers: @@ -21,6 +23,11 @@ import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.val export class AdMapper implements Mapper { + constructor( + @Inject(AD_DIRECTION_ENCODER) + private readonly directionEncoder: DirectionEncoderPort, + ) {} + toPersistence = (entity: AdEntity): AdWriteModel => { const copy = entity.getProps(); const now = new Date(); @@ -54,7 +61,7 @@ export class AdMapper driverDistance: copy.driverDistance, passengerDuration: copy.passengerDuration, passengerDistance: copy.passengerDistance, - waypoints: '', + waypoints: this.directionEncoder.encode(copy.waypoints), direction: '', fwdAzimuth: copy.fwdAzimuth, backAzimuth: copy.backAzimuth, diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index c846631..2106fba 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -1,11 +1,16 @@ import { Module, Provider } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; -import { AD_MESSAGE_PUBLISHER, AD_REPOSITORY } from './ad.di-tokens'; +import { + AD_MESSAGE_PUBLISHER, + AD_REPOSITORY, + AD_DIRECTION_ENCODER, +} from './ad.di-tokens'; import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; import { AdRepository } from './infrastructure/ad.repository'; import { PrismaService } from './infrastructure/prisma.service'; import { AdMapper } from './ad.mapper'; import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; +import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; const messageHandlers = [AdCreatedMessageHandler]; @@ -24,8 +29,16 @@ const messagePublishers: Provider[] = [ useExisting: MessageBrokerPublisher, }, ]; + const orms: Provider[] = [PrismaService]; +const adapters: Provider[] = [ + { + provide: AD_DIRECTION_ENCODER, + useClass: PostgresDirectionEncoder, + }, +]; + @Module({ imports: [CqrsModule], providers: [ @@ -34,7 +47,8 @@ const orms: Provider[] = [PrismaService]; ...repositories, ...messagePublishers, ...orms, + ...adapters, ], - exports: [PrismaService, AdMapper, AD_REPOSITORY], + exports: [PrismaService, AdMapper, AD_REPOSITORY, AD_DIRECTION_ENCODER], }) export class AdModule {} diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index bbb1143..a740a4b 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -1,3 +1,4 @@ +import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { Frequency } from '@modules/ad/core/domain/ad.types'; @@ -5,6 +6,7 @@ import { AdReadModel, AdWriteModel, } from '@modules/ad/infrastructure/ad.repository'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { Test } from '@nestjs/testing'; const now = new Date('2023-06-21 06:00:00'); @@ -76,12 +78,26 @@ const adReadModel: AdReadModel = { updatedAt: now, }; +const mockDirectionEncoder: DirectionEncoderPort = { + encode: jest + .fn() + .mockImplementation( + () => "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + ), +}; + describe('Ad Mapper', () => { let adMapper: AdMapper; beforeAll(async () => { const module = await Test.createTestingModule({ - providers: [AdMapper], + providers: [ + AdMapper, + { + provide: AD_DIRECTION_ENCODER, + useValue: mockDirectionEncoder, + }, + ], }).compile(); adMapper = module.get(AdMapper); }); @@ -93,6 +109,9 @@ describe('Ad Mapper', () => { it('should map domain entity to persistence data', async () => { const mapped: AdWriteModel = adMapper.toPersistence(adEntity); expect(mapped.schedule.create.length).toBe(1); + expect(mapped.waypoints).toBe( + "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + ); }); it('should map persisted data to domain entity', async () => { diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts index 43ed4ac..3d12f92 100644 --- a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -1,6 +1,8 @@ +import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; import { AdRepository } from '@modules/ad/infrastructure/ad.repository'; import { PrismaService } from '@modules/ad/infrastructure/prisma.service'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; import { Test, TestingModule } from '@nestjs/testing'; @@ -8,6 +10,10 @@ const mockMessagePublisher = { publish: jest.fn().mockImplementation(), }; +const mockDirectionEncoder: DirectionEncoderPort = { + encode: jest.fn(), +}; + describe('Ad repository', () => { let prismaService: PrismaService; let adMapper: AdMapper; @@ -16,7 +22,14 @@ describe('Ad repository', () => { beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [EventEmitterModule.forRoot()], - providers: [PrismaService, AdMapper], + providers: [ + PrismaService, + AdMapper, + { + provide: AD_DIRECTION_ENCODER, + useValue: mockDirectionEncoder, + }, + ], }).compile(); prismaService = module.get(PrismaService); diff --git a/src/modules/geography/infrastructure/default-params-provider.ts b/src/modules/geography/infrastructure/default-params-provider.ts index 962468b..53261c3 100644 --- a/src/modules/geography/infrastructure/default-params-provider.ts +++ b/src/modules/geography/infrastructure/default-params-provider.ts @@ -5,9 +5,9 @@ import { DefaultParams } from '../core/application/types/default-params.type'; @Injectable() export class DefaultParamsProvider implements DefaultParamsProviderPort { - constructor(private readonly _configService: ConfigService) {} + constructor(private readonly configService: ConfigService) {} getParams = (): DefaultParams => ({ - GEOROUTER_TYPE: this._configService.get('GEOROUTER_TYPE'), - GEOROUTER_URL: this._configService.get('GEOROUTER_URL'), + GEOROUTER_TYPE: this.configService.get('GEOROUTER_TYPE'), + GEOROUTER_URL: this.configService.get('GEOROUTER_URL'), }); } diff --git a/src/modules/geography/infrastructure/postgres-direction-encoder.ts b/src/modules/geography/infrastructure/postgres-direction-encoder.ts index 9ffbcba..5d4aa3b 100644 --- a/src/modules/geography/infrastructure/postgres-direction-encoder.ts +++ b/src/modules/geography/infrastructure/postgres-direction-encoder.ts @@ -1,6 +1,8 @@ import { Coordinates } from '../core/application/types/coordinates.type'; import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port'; +import { Injectable } from '@nestjs/common'; +@Injectable() export class PostgresDirectionEncoder implements DirectionEncoderPort { encode = (coordinates: Coordinates[]): string => [