functional ad insert
This commit is contained in:
parent
39cebda0b9
commit
9799f78bd2
File diff suppressed because it is too large
Load Diff
|
@ -34,7 +34,7 @@
|
||||||
"@grpc/proto-loader": "^0.7.6",
|
"@grpc/proto-loader": "^0.7.6",
|
||||||
"@liaoliaots/nestjs-redis": "^9.0.5",
|
"@liaoliaots/nestjs-redis": "^9.0.5",
|
||||||
"@mobicoop/configuration-module": "^1.2.0",
|
"@mobicoop/configuration-module": "^1.2.0",
|
||||||
"@mobicoop/ddd-library": "^1.0.0",
|
"@mobicoop/ddd-library": "^1.1.0",
|
||||||
"@mobicoop/health-module": "^2.0.0",
|
"@mobicoop/health-module": "^2.0.0",
|
||||||
"@mobicoop/message-broker-module": "^1.2.0",
|
"@mobicoop/message-broker-module": "^1.2.0",
|
||||||
"@nestjs/axios": "^2.0.0",
|
"@nestjs/axios": "^2.0.0",
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
-- CreateExtension
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "postgis";
|
||||||
|
|
||||||
|
-- Required to use postgis extension :
|
||||||
|
-- set the search_path to both public (where is postgis) AND the current schema
|
||||||
|
SET search_path TO matcher, public;
|
||||||
|
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "Frequency" AS ENUM ('PUNCTUAL', 'RECURRENT');
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "ad" (
|
||||||
|
"uuid" UUID NOT NULL,
|
||||||
|
"driver" BOOLEAN NOT NULL,
|
||||||
|
"passenger" BOOLEAN NOT NULL,
|
||||||
|
"frequency" "Frequency" NOT NULL,
|
||||||
|
"fromDate" DATE NOT NULL,
|
||||||
|
"toDate" DATE NOT NULL,
|
||||||
|
"seatsProposed" SMALLINT NOT NULL,
|
||||||
|
"seatsRequested" SMALLINT NOT NULL,
|
||||||
|
"strict" BOOLEAN NOT NULL,
|
||||||
|
"driverDuration" INTEGER,
|
||||||
|
"driverDistance" INTEGER,
|
||||||
|
"passengerDuration" INTEGER,
|
||||||
|
"passengerDistance" INTEGER,
|
||||||
|
"waypoints" geography(LINESTRING),
|
||||||
|
"direction" geography(LINESTRING),
|
||||||
|
"fwdAzimuth" INTEGER NOT NULL,
|
||||||
|
"backAzimuth" INTEGER NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
CONSTRAINT "ad_pkey" PRIMARY KEY ("uuid")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "schedule_item" (
|
||||||
|
"uuid" UUID NOT NULL,
|
||||||
|
"adUuid" UUID NOT NULL,
|
||||||
|
"day" INTEGER NOT NULL,
|
||||||
|
"time" TIME(4) NOT NULL,
|
||||||
|
"margin" INTEGER NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
CONSTRAINT "schedule_item_pkey" PRIMARY KEY ("uuid")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "ad_driver_idx" ON "ad"("driver");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "ad_passenger_idx" ON "ad"("passenger");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "ad_fromDate_idx" ON "ad"("fromDate");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "ad_toDate_idx" ON "ad"("toDate");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "ad_fwdAzimuth_idx" ON "ad"("fwdAzimuth");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "direction_idx" ON "ad" USING GIST ("direction");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "schedule_item" ADD CONSTRAINT "schedule_item_adUuid_fkey" FOREIGN KEY ("adUuid") REFERENCES "ad"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Please do not edit this file manually
|
||||||
|
# It should be added in your version-control system (i.e. Git)
|
||||||
|
provider = "postgresql"
|
|
@ -23,7 +23,6 @@ model Ad {
|
||||||
schedule ScheduleItem[]
|
schedule ScheduleItem[]
|
||||||
seatsProposed Int @db.SmallInt
|
seatsProposed Int @db.SmallInt
|
||||||
seatsRequested Int @db.SmallInt
|
seatsRequested Int @db.SmallInt
|
||||||
seatsUsed Int @db.SmallInt
|
|
||||||
strict Boolean
|
strict Boolean
|
||||||
driverDuration Int?
|
driverDuration Int?
|
||||||
driverDistance Int?
|
driverDistance Int?
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { Mapper } from '@mobicoop/ddd-library';
|
|
||||||
import { Inject, 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,
|
||||||
AdReadModel,
|
AdReadModel,
|
||||||
ScheduleItemModel,
|
ScheduleItemModel,
|
||||||
|
AdUnsupportedWriteModel,
|
||||||
} from './infrastructure/ad.repository';
|
} from './infrastructure/ad.repository';
|
||||||
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 { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
||||||
import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
||||||
|
import { ExtendedMapper } from '@mobicoop/ddd-library';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapper constructs objects that are used in different layers:
|
* Mapper constructs objects that are used in different layers:
|
||||||
|
@ -21,7 +22,14 @@ import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdMapper
|
export class AdMapper
|
||||||
implements Mapper<AdEntity, AdReadModel, AdWriteModel, undefined>
|
implements
|
||||||
|
ExtendedMapper<
|
||||||
|
AdEntity,
|
||||||
|
AdReadModel,
|
||||||
|
AdWriteModel,
|
||||||
|
AdUnsupportedWriteModel,
|
||||||
|
undefined
|
||||||
|
>
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(AD_DIRECTION_ENCODER)
|
@Inject(AD_DIRECTION_ENCODER)
|
||||||
|
@ -61,8 +69,6 @@ export class AdMapper
|
||||||
driverDistance: copy.driverDistance,
|
driverDistance: copy.driverDistance,
|
||||||
passengerDuration: copy.passengerDuration,
|
passengerDuration: copy.passengerDuration,
|
||||||
passengerDistance: copy.passengerDistance,
|
passengerDistance: copy.passengerDistance,
|
||||||
waypoints: this.directionEncoder.encode(copy.waypoints),
|
|
||||||
direction: this.directionEncoder.encode(copy.points),
|
|
||||||
fwdAzimuth: copy.fwdAzimuth,
|
fwdAzimuth: copy.fwdAzimuth,
|
||||||
backAzimuth: copy.backAzimuth,
|
backAzimuth: copy.backAzimuth,
|
||||||
createdAt: copy.createdAt,
|
createdAt: copy.createdAt,
|
||||||
|
@ -118,4 +124,9 @@ export class AdMapper
|
||||||
toResponse = (entity: AdEntity): undefined => {
|
toResponse = (entity: AdEntity): undefined => {
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toUnsupportedPersistence = (entity: AdEntity): AdUnsupportedWriteModel => ({
|
||||||
|
waypoints: this.directionEncoder.encode(entity.getProps().waypoints),
|
||||||
|
direction: this.directionEncoder.encode(entity.getProps().points),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,12 @@ import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/post
|
||||||
import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller';
|
import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller';
|
||||||
import { RouteProvider } from './infrastructure/route-provider';
|
import { RouteProvider } from './infrastructure/route-provider';
|
||||||
import { GeographyModule } from '@modules/geography/geography.module';
|
import { GeographyModule } from '@modules/geography/geography.module';
|
||||||
|
import { CreateAdService } from './core/application/commands/create-ad/create-ad.service';
|
||||||
|
|
||||||
const messageHandlers = [AdCreatedMessageHandler];
|
const messageHandlers = [AdCreatedMessageHandler];
|
||||||
|
|
||||||
|
const commandHandlers: Provider[] = [CreateAdService];
|
||||||
|
|
||||||
const mappers: Provider[] = [AdMapper];
|
const mappers: Provider[] = [AdMapper];
|
||||||
|
|
||||||
const repositories: Provider[] = [
|
const repositories: Provider[] = [
|
||||||
|
@ -56,6 +59,7 @@ const adapters: Provider[] = [
|
||||||
imports: [CqrsModule, GeographyModule],
|
imports: [CqrsModule, GeographyModule],
|
||||||
providers: [
|
providers: [
|
||||||
...messageHandlers,
|
...messageHandlers,
|
||||||
|
...commandHandlers,
|
||||||
...mappers,
|
...mappers,
|
||||||
...repositories,
|
...repositories,
|
||||||
...messagePublishers,
|
...messagePublishers,
|
||||||
|
|
|
@ -49,7 +49,7 @@ export class CreateAdService implements ICommandHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.repository.insert(ad);
|
await this.repository.insertWithUnsupportedFields(ad, 'ad');
|
||||||
return ad.id;
|
return ad.id;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error instanceof ConflictException) {
|
if (error instanceof ConflictException) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { RepositoryPort } from '@mobicoop/ddd-library';
|
import { ExtendedRepositoryPort } from '@mobicoop/ddd-library';
|
||||||
import { AdEntity } from '../../domain/ad.entity';
|
import { AdEntity } from '../../domain/ad.entity';
|
||||||
|
|
||||||
export type AdRepositoryPort = RepositoryPort<AdEntity>;
|
export type AdRepositoryPort = ExtendedRepositoryPort<AdEntity>;
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { AdRepositoryPort } from '../core/application/ports/ad.repository.port';
|
import { AdRepositoryPort } from '../core/application/ports/ad.repository.port';
|
||||||
import {
|
import { LoggerBase, MessagePublisherPort } from '@mobicoop/ddd-library';
|
||||||
LoggerBase,
|
|
||||||
MessagePublisherPort,
|
|
||||||
PrismaRepositoryBase,
|
|
||||||
} from '@mobicoop/ddd-library';
|
|
||||||
import { PrismaService } from './prisma.service';
|
import { PrismaService } from './prisma.service';
|
||||||
import { AD_MESSAGE_PUBLISHER } from '../ad.di-tokens';
|
import { AD_MESSAGE_PUBLISHER } from '../ad.di-tokens';
|
||||||
import { AdEntity } from '../core/domain/ad.entity';
|
import { AdEntity } from '../core/domain/ad.entity';
|
||||||
import { AdMapper } from '../ad.mapper';
|
import { AdMapper } from '../ad.mapper';
|
||||||
|
import { ExtendedPrismaRepositoryBase } from '@mobicoop/ddd-library/dist/db/prisma-repository.base';
|
||||||
|
|
||||||
export type AdBaseModel = {
|
export type AdBaseModel = {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
@ -25,8 +22,6 @@ export type AdBaseModel = {
|
||||||
driverDistance: number;
|
driverDistance: number;
|
||||||
passengerDuration: number;
|
passengerDuration: number;
|
||||||
passengerDistance: number;
|
passengerDistance: number;
|
||||||
waypoints: string;
|
|
||||||
direction: string;
|
|
||||||
fwdAzimuth: number;
|
fwdAzimuth: number;
|
||||||
backAzimuth: number;
|
backAzimuth: number;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
@ -34,6 +29,8 @@ export type AdBaseModel = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AdReadModel = AdBaseModel & {
|
export type AdReadModel = AdBaseModel & {
|
||||||
|
waypoints: string;
|
||||||
|
direction: string;
|
||||||
schedule: ScheduleItemModel[];
|
schedule: ScheduleItemModel[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,6 +40,11 @@ export type AdWriteModel = AdBaseModel & {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AdUnsupportedWriteModel = {
|
||||||
|
waypoints: string;
|
||||||
|
direction: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ScheduleItemModel = {
|
export type ScheduleItemModel = {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
day: number;
|
day: number;
|
||||||
|
@ -57,7 +59,12 @@ export type ScheduleItemModel = {
|
||||||
* */
|
* */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdRepository
|
export class AdRepository
|
||||||
extends PrismaRepositoryBase<AdEntity, AdReadModel, AdWriteModel>
|
extends ExtendedPrismaRepositoryBase<
|
||||||
|
AdEntity,
|
||||||
|
AdReadModel,
|
||||||
|
AdWriteModel,
|
||||||
|
AdUnsupportedWriteModel
|
||||||
|
>
|
||||||
implements AdRepositoryPort
|
implements AdRepositoryPort
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
|
|
|
@ -12,8 +12,8 @@ export class AdCreatedMessageHandler {
|
||||||
name: 'adCreated',
|
name: 'adCreated',
|
||||||
})
|
})
|
||||||
public async adCreated(message: string) {
|
public async adCreated(message: string) {
|
||||||
const createdAd: Ad = JSON.parse(message);
|
|
||||||
try {
|
try {
|
||||||
|
const createdAd: Ad = JSON.parse(message);
|
||||||
await this.commandBus.execute(
|
await this.commandBus.execute(
|
||||||
new CreateAdCommand({
|
new CreateAdCommand({
|
||||||
id: createdAd.id,
|
id: createdAd.id,
|
||||||
|
|
|
@ -4,6 +4,7 @@ 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';
|
||||||
import {
|
import {
|
||||||
AdReadModel,
|
AdReadModel,
|
||||||
|
AdUnsupportedWriteModel,
|
||||||
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 { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
||||||
|
@ -143,14 +144,19 @@ 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.driverDuration).toBe(14422);
|
||||||
|
expect(mapped.fwdAzimuth).toBe(273);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should map domain entity to unsupported db persistence data', async () => {
|
||||||
|
const mapped: AdUnsupportedWriteModel =
|
||||||
|
adMapper.toUnsupportedPersistence(adEntity);
|
||||||
expect(mapped.waypoints).toBe(
|
expect(mapped.waypoints).toBe(
|
||||||
"'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'",
|
"'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'",
|
||||||
);
|
);
|
||||||
expect(mapped.direction).toBe(
|
expect(mapped.direction).toBe(
|
||||||
"'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'",
|
"'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'",
|
||||||
);
|
);
|
||||||
expect(mapped.driverDuration).toBe(14422);
|
|
||||||
expect(mapped.fwdAzimuth).toBe(273);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should map persisted data to domain entity', async () => {
|
it('should map persisted data to domain entity', async () => {
|
||||||
|
|
|
@ -4,13 +4,13 @@ import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.va
|
||||||
|
|
||||||
const originWaypointProps: WaypointProps = {
|
const originWaypointProps: WaypointProps = {
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
};
|
};
|
||||||
const destinationWaypointProps: WaypointProps = {
|
const destinationWaypointProps: WaypointProps = {
|
||||||
position: 1,
|
position: 1,
|
||||||
lon: 48.8566,
|
lat: 48.8566,
|
||||||
lat: 2.3522,
|
lon: 2.3522,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createAdProps: CreateAdProps = {
|
const createAdProps: CreateAdProps = {
|
||||||
|
|
|
@ -12,13 +12,13 @@ import { RouteProviderPort } from '@modules/ad/core/application/ports/route-prov
|
||||||
|
|
||||||
const originWaypoint: WaypointProps = {
|
const originWaypoint: WaypointProps = {
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
};
|
};
|
||||||
const destinationWaypoint: WaypointProps = {
|
const destinationWaypoint: WaypointProps = {
|
||||||
position: 1,
|
position: 1,
|
||||||
lon: 48.8566,
|
lat: 48.8566,
|
||||||
lat: 2.3522,
|
lon: 2.3522,
|
||||||
};
|
};
|
||||||
const createAdProps: CreateAdProps = {
|
const createAdProps: CreateAdProps = {
|
||||||
id: '4eb6a6af-ecfd-41c3-9118-473a507014d4',
|
id: '4eb6a6af-ecfd-41c3-9118-473a507014d4',
|
||||||
|
@ -48,7 +48,7 @@ const createAdProps: CreateAdProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockAdRepository = {
|
const mockAdRepository = {
|
||||||
insert: jest
|
insertWithUnsupportedFields: jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockImplementationOnce(() => ({}))
|
.mockImplementationOnce(() => ({}))
|
||||||
.mockImplementationOnce(() => {
|
.mockImplementationOnce(() => {
|
||||||
|
|
|
@ -4,25 +4,25 @@ import { Point } from '@modules/ad/core/domain/value-objects/point.value-object'
|
||||||
describe('Point value object', () => {
|
describe('Point value object', () => {
|
||||||
it('should create a point value object', () => {
|
it('should create a point value object', () => {
|
||||||
const pointVO = new Point({
|
const pointVO = new Point({
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
expect(pointVO.lon).toBe(48.689445);
|
expect(pointVO.lat).toBe(48.689445);
|
||||||
expect(pointVO.lat).toBe(6.17651);
|
expect(pointVO.lon).toBe(6.17651);
|
||||||
});
|
});
|
||||||
it('should throw an exception if longitude is invalid', () => {
|
it('should throw an exception if longitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Point({
|
new Point({
|
||||||
lon: 348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new Point({
|
new Point({
|
||||||
lon: -348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: -186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -31,16 +31,16 @@ describe('Point value object', () => {
|
||||||
it('should throw an exception if latitude is invalid', () => {
|
it('should throw an exception if latitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Point({
|
new Point({
|
||||||
lon: 48.689445,
|
lat: 148.689445,
|
||||||
lat: 96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new Point({
|
new Point({
|
||||||
lon: 48.689445,
|
lat: -148.689445,
|
||||||
lat: -96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
|
|
@ -8,19 +8,19 @@ describe('Waypoint value object', () => {
|
||||||
it('should create a waypoint value object', () => {
|
it('should create a waypoint value object', () => {
|
||||||
const waypointVO = new Waypoint({
|
const waypointVO = new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
expect(waypointVO.position).toBe(0);
|
expect(waypointVO.position).toBe(0);
|
||||||
expect(waypointVO.lon).toBe(48.689445);
|
expect(waypointVO.lat).toBe(48.689445);
|
||||||
expect(waypointVO.lat).toBe(6.17651);
|
expect(waypointVO.lon).toBe(6.17651);
|
||||||
});
|
});
|
||||||
it('should throw an exception if position is invalid', () => {
|
it('should throw an exception if position is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: -1,
|
position: -1,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
||||||
|
@ -30,8 +30,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -39,8 +39,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: -348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: -186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -50,8 +50,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 148.689445,
|
||||||
lat: 96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -59,8 +59,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: -148.689445,
|
||||||
lat: -96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
|
|
@ -13,6 +13,9 @@ import { RouteMapper } from './route.mapper';
|
||||||
import { Geodesic } from './infrastructure/geodesic';
|
import { Geodesic } from './infrastructure/geodesic';
|
||||||
import { GraphhopperGeorouter } from './infrastructure/graphhopper-georouter';
|
import { GraphhopperGeorouter } from './infrastructure/graphhopper-georouter';
|
||||||
import { HttpModule } from '@nestjs/axios';
|
import { HttpModule } from '@nestjs/axios';
|
||||||
|
import { GetRouteQueryHandler } from './core/application/queries/get-route/get-route.query-handler';
|
||||||
|
|
||||||
|
const queryHandlers: Provider[] = [GetRouteQueryHandler];
|
||||||
|
|
||||||
const mappers: Provider[] = [RouteMapper];
|
const mappers: Provider[] = [RouteMapper];
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ const adapters: Provider[] = [
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [CqrsModule, HttpModule],
|
imports: [CqrsModule, HttpModule],
|
||||||
providers: [...mappers, ...adapters],
|
providers: [...queryHandlers, ...mappers, ...adapters],
|
||||||
exports: [RouteMapper, DIRECTION_ENCODER, GetBasicRouteController],
|
exports: [RouteMapper, DIRECTION_ENCODER, GetBasicRouteController],
|
||||||
})
|
})
|
||||||
export class GeographyModule {}
|
export class GeographyModule {}
|
||||||
|
|
|
@ -26,13 +26,17 @@ export class RouteMapper
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
toResponse = (entity: RouteEntity): RouteResponseDto => {
|
toResponse = (entity: RouteEntity): RouteResponseDto => {
|
||||||
const response = new RouteResponseDto();
|
const response = new RouteResponseDto();
|
||||||
response.driverDistance = entity.getProps().driverDistance;
|
response.driverDistance = Math.round(entity.getProps().driverDistance);
|
||||||
response.driverDuration = entity.getProps().driverDuration;
|
response.driverDuration = Math.round(entity.getProps().driverDuration);
|
||||||
response.passengerDistance = entity.getProps().passengerDistance;
|
response.passengerDistance = Math.round(
|
||||||
response.passengerDuration = entity.getProps().passengerDuration;
|
entity.getProps().passengerDistance,
|
||||||
response.fwdAzimuth = entity.getProps().fwdAzimuth;
|
);
|
||||||
response.backAzimuth = entity.getProps().backAzimuth;
|
response.passengerDuration = Math.round(
|
||||||
response.distanceAzimuth = entity.getProps().distanceAzimuth;
|
entity.getProps().passengerDuration,
|
||||||
|
);
|
||||||
|
response.fwdAzimuth = Math.round(entity.getProps().fwdAzimuth);
|
||||||
|
response.backAzimuth = Math.round(entity.getProps().backAzimuth);
|
||||||
|
response.distanceAzimuth = Math.round(entity.getProps().distanceAzimuth);
|
||||||
response.points = entity.getProps().points;
|
response.points = entity.getProps().points;
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,25 +4,25 @@ import { Coordinates } from '@modules/geography/core/domain/value-objects/coordi
|
||||||
describe('Waypoint value object', () => {
|
describe('Waypoint value object', () => {
|
||||||
it('should create a waypoint value object', () => {
|
it('should create a waypoint value object', () => {
|
||||||
const coordinatesVO = new Coordinates({
|
const coordinatesVO = new Coordinates({
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
expect(coordinatesVO.lon).toBe(48.689445);
|
expect(coordinatesVO.lat).toBe(48.689445);
|
||||||
expect(coordinatesVO.lat).toBe(6.17651);
|
expect(coordinatesVO.lon).toBe(6.17651);
|
||||||
});
|
});
|
||||||
it('should throw an exception if longitude is invalid', () => {
|
it('should throw an exception if longitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Coordinates({
|
new Coordinates({
|
||||||
lon: 348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new Coordinates({
|
new Coordinates({
|
||||||
lon: -348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: -186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -31,16 +31,16 @@ describe('Waypoint value object', () => {
|
||||||
it('should throw an exception if latitude is invalid', () => {
|
it('should throw an exception if latitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Coordinates({
|
new Coordinates({
|
||||||
lon: 48.689445,
|
lat: 148.689445,
|
||||||
lat: 96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new Coordinates({
|
new Coordinates({
|
||||||
lon: 48.689445,
|
lat: -148.689445,
|
||||||
lat: -96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
|
|
@ -8,13 +8,13 @@ import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
const originWaypoint: Waypoint = {
|
const originWaypoint: Waypoint = {
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
};
|
};
|
||||||
const destinationWaypoint: Waypoint = {
|
const destinationWaypoint: Waypoint = {
|
||||||
position: 1,
|
position: 1,
|
||||||
lon: 48.8566,
|
lat: 48.8566,
|
||||||
lat: 2.3522,
|
lon: 2.3522,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockGeorouter: GeorouterPort = {
|
const mockGeorouter: GeorouterPort = {
|
||||||
|
|
|
@ -9,12 +9,12 @@ import {
|
||||||
} from '@modules/geography/core/domain/route.types';
|
} from '@modules/geography/core/domain/route.types';
|
||||||
|
|
||||||
const originCoordinates: Coordinates = {
|
const originCoordinates: Coordinates = {
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
};
|
};
|
||||||
const destinationCoordinates: Coordinates = {
|
const destinationCoordinates: Coordinates = {
|
||||||
lon: 48.8566,
|
lat: 48.8566,
|
||||||
lat: 2.3522,
|
lon: 2.3522,
|
||||||
};
|
};
|
||||||
const additionalCoordinates: Coordinates = {
|
const additionalCoordinates: Coordinates = {
|
||||||
lon: 48.7566,
|
lon: 48.7566,
|
||||||
|
|
|
@ -7,21 +7,21 @@ import { SpacetimePoint } from '@modules/geography/core/domain/value-objects/spa
|
||||||
describe('Timepoint value object', () => {
|
describe('Timepoint value object', () => {
|
||||||
it('should create a timepoint value object', () => {
|
it('should create a timepoint value object', () => {
|
||||||
const timepointVO = new SpacetimePoint({
|
const timepointVO = new SpacetimePoint({
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
expect(timepointVO.duration).toBe(150);
|
expect(timepointVO.duration).toBe(150);
|
||||||
expect(timepointVO.distance).toBe(12000);
|
expect(timepointVO.distance).toBe(12000);
|
||||||
expect(timepointVO.lon).toBe(48.689445);
|
expect(timepointVO.lat).toBe(48.689445);
|
||||||
expect(timepointVO.lat).toBe(6.17651);
|
expect(timepointVO.lon).toBe(6.17651);
|
||||||
});
|
});
|
||||||
it('should throw an exception if longitude is invalid', () => {
|
it('should throw an exception if longitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: 348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 186.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
|
@ -30,8 +30,8 @@ describe('Timepoint value object', () => {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: -348.689445,
|
lon: 48.689445,
|
||||||
lat: 6.17651,
|
lat: -186.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
|
@ -42,8 +42,8 @@ describe('Timepoint value object', () => {
|
||||||
it('should throw an exception if latitude is invalid', () => {
|
it('should throw an exception if latitude is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: 48.689445,
|
lat: 248.689445,
|
||||||
lat: 96.17651,
|
lon: 6.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
|
@ -52,8 +52,8 @@ describe('Timepoint value object', () => {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: 48.689445,
|
lon: -148.689445,
|
||||||
lat: -96.17651,
|
lat: 6.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
|
@ -64,8 +64,8 @@ describe('Timepoint value object', () => {
|
||||||
it('should throw an exception if distance is invalid', () => {
|
it('should throw an exception if distance is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
duration: 150,
|
duration: 150,
|
||||||
distance: -12000,
|
distance: -12000,
|
||||||
});
|
});
|
||||||
|
@ -76,8 +76,8 @@ describe('Timepoint value object', () => {
|
||||||
it('should throw an exception if duration is invalid', () => {
|
it('should throw an exception if duration is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new SpacetimePoint({
|
new SpacetimePoint({
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
duration: -150,
|
duration: -150,
|
||||||
distance: 12000,
|
distance: 12000,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,19 +8,19 @@ describe('Waypoint value object', () => {
|
||||||
it('should create a waypoint value object', () => {
|
it('should create a waypoint value object', () => {
|
||||||
const waypointVO = new Waypoint({
|
const waypointVO = new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
expect(waypointVO.position).toBe(0);
|
expect(waypointVO.position).toBe(0);
|
||||||
expect(waypointVO.lon).toBe(48.689445);
|
expect(waypointVO.lat).toBe(48.689445);
|
||||||
expect(waypointVO.lat).toBe(6.17651);
|
expect(waypointVO.lon).toBe(6.17651);
|
||||||
});
|
});
|
||||||
it('should throw an exception if position is invalid', () => {
|
it('should throw an exception if position is invalid', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: -1,
|
position: -1,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
expect(e).toBeInstanceOf(ArgumentInvalidException);
|
||||||
|
@ -30,8 +30,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -39,8 +39,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: -348.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: -186.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -50,8 +50,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 148.689445,
|
||||||
lat: 96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
@ -59,8 +59,8 @@ describe('Waypoint value object', () => {
|
||||||
try {
|
try {
|
||||||
new Waypoint({
|
new Waypoint({
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: -148.689445,
|
||||||
lat: -96.17651,
|
lon: 6.17651,
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||||
|
|
|
@ -52,13 +52,13 @@ describe('Get Basic Route Controller', () => {
|
||||||
waypoints: [
|
waypoints: [
|
||||||
{
|
{
|
||||||
position: 0,
|
position: 0,
|
||||||
lon: 48.689445,
|
lat: 48.689445,
|
||||||
lat: 6.17651,
|
lon: 6.17651,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
position: 1,
|
position: 1,
|
||||||
lon: 48.8566,
|
lat: 48.8566,
|
||||||
lat: 2.3522,
|
lon: 2.3522,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue