basic ad entity without direction
This commit is contained in:
parent
db13f4d87e
commit
88326dcf6f
|
@ -49,6 +49,7 @@
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/node": "18.15.11",
|
"@types/node": "18.15.11",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
|
"@types/uuid": "^9.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
"dotenv-cli": "^7.2.1",
|
"dotenv-cli": "^7.2.1",
|
||||||
|
@ -2655,6 +2656,12 @@
|
||||||
"@types/superagent": "*"
|
"@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": {
|
"node_modules/@types/validator": {
|
||||||
"version": "13.11.1",
|
"version": "13.11.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz",
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/node": "18.15.11",
|
"@types/node": "18.15.11",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
|
"@types/uuid": "^9.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
"dotenv-cli": "^7.2.1",
|
"dotenv-cli": "^7.2.1",
|
||||||
|
|
|
@ -63,6 +63,6 @@ import { GeographyModule } from '@modules/geography/geography.module';
|
||||||
GeographyModule,
|
GeographyModule,
|
||||||
MessagerModule,
|
MessagerModule,
|
||||||
],
|
],
|
||||||
exports: [AdModule, MessagerModule],
|
exports: [AdModule, GeographyModule, MessagerModule],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export const AD_REPOSITORY = Symbol('AD_REPOSITORY');
|
export const AD_REPOSITORY = Symbol('AD_REPOSITORY');
|
||||||
export const GEOROUTER = Symbol('GEOROUTER');
|
export const GEOROUTER = Symbol('GEOROUTER');
|
||||||
|
export const AD_DIRECTION_ENCODER = Symbol('AD_DIRECTION_ENCODER');
|
||||||
export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER');
|
export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Mapper } from '@mobicoop/ddd-library';
|
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 { AdEntity } from './core/domain/ad.entity';
|
||||||
import {
|
import {
|
||||||
AdWriteModel,
|
AdWriteModel,
|
||||||
|
@ -9,6 +9,8 @@ import {
|
||||||
import { Frequency } from './core/domain/ad.types';
|
import { Frequency } from './core/domain/ad.types';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object';
|
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:
|
* 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
|
export class AdMapper
|
||||||
implements Mapper<AdEntity, AdReadModel, AdWriteModel, undefined>
|
implements Mapper<AdEntity, AdReadModel, AdWriteModel, undefined>
|
||||||
{
|
{
|
||||||
|
constructor(
|
||||||
|
@Inject(AD_DIRECTION_ENCODER)
|
||||||
|
private readonly directionEncoder: DirectionEncoderPort,
|
||||||
|
) {}
|
||||||
|
|
||||||
toPersistence = (entity: AdEntity): AdWriteModel => {
|
toPersistence = (entity: AdEntity): AdWriteModel => {
|
||||||
const copy = entity.getProps();
|
const copy = entity.getProps();
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
@ -54,7 +61,7 @@ export class AdMapper
|
||||||
driverDistance: copy.driverDistance,
|
driverDistance: copy.driverDistance,
|
||||||
passengerDuration: copy.passengerDuration,
|
passengerDuration: copy.passengerDuration,
|
||||||
passengerDistance: copy.passengerDistance,
|
passengerDistance: copy.passengerDistance,
|
||||||
waypoints: '',
|
waypoints: this.directionEncoder.encode(copy.waypoints),
|
||||||
direction: '',
|
direction: '',
|
||||||
fwdAzimuth: copy.fwdAzimuth,
|
fwdAzimuth: copy.fwdAzimuth,
|
||||||
backAzimuth: copy.backAzimuth,
|
backAzimuth: copy.backAzimuth,
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import { Module, Provider } from '@nestjs/common';
|
import { Module, Provider } from '@nestjs/common';
|
||||||
import { CqrsModule } from '@nestjs/cqrs';
|
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 { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
|
||||||
import { AdRepository } from './infrastructure/ad.repository';
|
import { AdRepository } from './infrastructure/ad.repository';
|
||||||
import { PrismaService } from './infrastructure/prisma.service';
|
import { PrismaService } from './infrastructure/prisma.service';
|
||||||
import { AdMapper } from './ad.mapper';
|
import { AdMapper } from './ad.mapper';
|
||||||
import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler';
|
import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler';
|
||||||
|
import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder';
|
||||||
|
|
||||||
const messageHandlers = [AdCreatedMessageHandler];
|
const messageHandlers = [AdCreatedMessageHandler];
|
||||||
|
|
||||||
|
@ -24,8 +29,16 @@ const messagePublishers: Provider[] = [
|
||||||
useExisting: MessageBrokerPublisher,
|
useExisting: MessageBrokerPublisher,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const orms: Provider[] = [PrismaService];
|
const orms: Provider[] = [PrismaService];
|
||||||
|
|
||||||
|
const adapters: Provider[] = [
|
||||||
|
{
|
||||||
|
provide: AD_DIRECTION_ENCODER,
|
||||||
|
useClass: PostgresDirectionEncoder,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [CqrsModule],
|
imports: [CqrsModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -34,7 +47,8 @@ const orms: Provider[] = [PrismaService];
|
||||||
...repositories,
|
...repositories,
|
||||||
...messagePublishers,
|
...messagePublishers,
|
||||||
...orms,
|
...orms,
|
||||||
|
...adapters,
|
||||||
],
|
],
|
||||||
exports: [PrismaService, AdMapper, AD_REPOSITORY],
|
exports: [PrismaService, AdMapper, AD_REPOSITORY, AD_DIRECTION_ENCODER],
|
||||||
})
|
})
|
||||||
export class AdModule {}
|
export class AdModule {}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens';
|
||||||
import { AdMapper } from '@modules/ad/ad.mapper';
|
import { AdMapper } from '@modules/ad/ad.mapper';
|
||||||
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
||||||
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
|
@ -5,6 +6,7 @@ import {
|
||||||
AdReadModel,
|
AdReadModel,
|
||||||
AdWriteModel,
|
AdWriteModel,
|
||||||
} from '@modules/ad/infrastructure/ad.repository';
|
} from '@modules/ad/infrastructure/ad.repository';
|
||||||
|
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
|
|
||||||
const now = new Date('2023-06-21 06:00:00');
|
const now = new Date('2023-06-21 06:00:00');
|
||||||
|
@ -76,12 +78,26 @@ const adReadModel: AdReadModel = {
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mockDirectionEncoder: DirectionEncoderPort = {
|
||||||
|
encode: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(
|
||||||
|
() => "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'",
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
describe('Ad Mapper', () => {
|
describe('Ad Mapper', () => {
|
||||||
let adMapper: AdMapper;
|
let adMapper: AdMapper;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const module = await Test.createTestingModule({
|
const module = await Test.createTestingModule({
|
||||||
providers: [AdMapper],
|
providers: [
|
||||||
|
AdMapper,
|
||||||
|
{
|
||||||
|
provide: AD_DIRECTION_ENCODER,
|
||||||
|
useValue: mockDirectionEncoder,
|
||||||
|
},
|
||||||
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
adMapper = module.get<AdMapper>(AdMapper);
|
adMapper = module.get<AdMapper>(AdMapper);
|
||||||
});
|
});
|
||||||
|
@ -93,6 +109,9 @@ describe('Ad Mapper', () => {
|
||||||
it('should map domain entity to persistence data', async () => {
|
it('should map domain entity to persistence data', async () => {
|
||||||
const mapped: AdWriteModel = adMapper.toPersistence(adEntity);
|
const mapped: AdWriteModel = adMapper.toPersistence(adEntity);
|
||||||
expect(mapped.schedule.create.length).toBe(1);
|
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 () => {
|
it('should map persisted data to domain entity', async () => {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens';
|
||||||
import { AdMapper } from '@modules/ad/ad.mapper';
|
import { AdMapper } from '@modules/ad/ad.mapper';
|
||||||
import { AdRepository } from '@modules/ad/infrastructure/ad.repository';
|
import { AdRepository } from '@modules/ad/infrastructure/ad.repository';
|
||||||
import { PrismaService } from '@modules/ad/infrastructure/prisma.service';
|
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 { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
@ -8,6 +10,10 @@ const mockMessagePublisher = {
|
||||||
publish: jest.fn().mockImplementation(),
|
publish: jest.fn().mockImplementation(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mockDirectionEncoder: DirectionEncoderPort = {
|
||||||
|
encode: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
describe('Ad repository', () => {
|
describe('Ad repository', () => {
|
||||||
let prismaService: PrismaService;
|
let prismaService: PrismaService;
|
||||||
let adMapper: AdMapper;
|
let adMapper: AdMapper;
|
||||||
|
@ -16,7 +22,14 @@ describe('Ad repository', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
imports: [EventEmitterModule.forRoot()],
|
imports: [EventEmitterModule.forRoot()],
|
||||||
providers: [PrismaService, AdMapper],
|
providers: [
|
||||||
|
PrismaService,
|
||||||
|
AdMapper,
|
||||||
|
{
|
||||||
|
provide: AD_DIRECTION_ENCODER,
|
||||||
|
useValue: mockDirectionEncoder,
|
||||||
|
},
|
||||||
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
prismaService = module.get<PrismaService>(PrismaService);
|
prismaService = module.get<PrismaService>(PrismaService);
|
||||||
|
|
|
@ -5,9 +5,9 @@ import { DefaultParams } from '../core/application/types/default-params.type';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DefaultParamsProvider implements DefaultParamsProviderPort {
|
export class DefaultParamsProvider implements DefaultParamsProviderPort {
|
||||||
constructor(private readonly _configService: ConfigService) {}
|
constructor(private readonly configService: ConfigService) {}
|
||||||
getParams = (): DefaultParams => ({
|
getParams = (): DefaultParams => ({
|
||||||
GEOROUTER_TYPE: this._configService.get('GEOROUTER_TYPE'),
|
GEOROUTER_TYPE: this.configService.get('GEOROUTER_TYPE'),
|
||||||
GEOROUTER_URL: this._configService.get('GEOROUTER_URL'),
|
GEOROUTER_URL: this.configService.get('GEOROUTER_URL'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { Coordinates } from '../core/application/types/coordinates.type';
|
import { Coordinates } from '../core/application/types/coordinates.type';
|
||||||
import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port';
|
import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class PostgresDirectionEncoder implements DirectionEncoderPort {
|
export class PostgresDirectionEncoder implements DirectionEncoderPort {
|
||||||
encode = (coordinates: Coordinates[]): string =>
|
encode = (coordinates: Coordinates[]): string =>
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in New Issue