mirror of
https://gitlab.com/mobicoop/v3/service/matcher.git
synced 2026-01-01 08:22:41 +00:00
move route compute to create service as entity creation is not async
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import { GetRouteRequestDto } from '@modules/geography/interface/controllers/dtos/get-route.request.dto';
|
||||
import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto';
|
||||
|
||||
export interface GetBasicRouteControllerPort {
|
||||
get(data: GetRouteRequestDto): Promise<RouteResponseDto>;
|
||||
}
|
||||
@@ -9,6 +9,5 @@ export type Route = {
|
||||
fwdAzimuth: number;
|
||||
backAzimuth: number;
|
||||
distanceAzimuth: number;
|
||||
points: Coordinates[];
|
||||
spacetimePoints: SpacetimePoint[];
|
||||
points: Coordinates[] | SpacetimePoint[];
|
||||
};
|
||||
|
||||
@@ -60,9 +60,7 @@ export class RouteEntity extends AggregateRoot<RouteProps> {
|
||||
? driverRoute.distanceAzimuth
|
||||
: passengerRoute.distanceAzimuth,
|
||||
waypoints: create.waypoints,
|
||||
spacetimePoints: driverRoute
|
||||
? driverRoute.spacetimePoints
|
||||
: passengerRoute.spacetimePoints,
|
||||
points: driverRoute ? driverRoute.points : passengerRoute.points,
|
||||
};
|
||||
return new RouteEntity({
|
||||
id: v4(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { GeorouterPort } from '../application/ports/georouter.port';
|
||||
import { GeorouterSettings } from '../application/types/georouter-settings.type';
|
||||
import { CoordinatesProps } from './value-objects/coordinates.value-object';
|
||||
import { SpacetimePointProps } from './value-objects/spacetime-point.value-object';
|
||||
import { WaypointProps } from './value-objects/waypoint.value-object';
|
||||
|
||||
@@ -13,7 +14,7 @@ export interface RouteProps {
|
||||
backAzimuth: number;
|
||||
distanceAzimuth: number;
|
||||
waypoints: WaypointProps[];
|
||||
spacetimePoints: SpacetimePointProps[];
|
||||
points: SpacetimePointProps[] | CoordinatesProps[];
|
||||
}
|
||||
|
||||
// Properties that are needed for a Route creation
|
||||
@@ -31,8 +32,7 @@ export type Direction = {
|
||||
fwdAzimuth: number;
|
||||
backAzimuth: number;
|
||||
distanceAzimuth: number;
|
||||
points: Point[];
|
||||
spacetimePoints: SpacetimePoint[];
|
||||
points: SpacetimePoint[] | Point[];
|
||||
};
|
||||
|
||||
export type Path = {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import {
|
||||
ArgumentOutOfRangeException,
|
||||
ValueObject,
|
||||
} from '@mobicoop/ddd-library';
|
||||
|
||||
/** Note:
|
||||
* Value Objects with multiple properties can contain
|
||||
* other Value Objects inside if needed.
|
||||
* */
|
||||
|
||||
export interface CoordinatesProps {
|
||||
lon: number;
|
||||
lat: number;
|
||||
}
|
||||
|
||||
export class Coordinates extends ValueObject<CoordinatesProps> {
|
||||
get lon(): number {
|
||||
return this.props.lon;
|
||||
}
|
||||
|
||||
get lat(): number {
|
||||
return this.props.lat;
|
||||
}
|
||||
|
||||
protected validate(props: CoordinatesProps): void {
|
||||
if (props.lon > 180 || props.lon < -180)
|
||||
throw new ArgumentOutOfRangeException('lon must be between -180 and 180');
|
||||
if (props.lat > 90 || props.lat < -90)
|
||||
throw new ArgumentOutOfRangeException('lat must be between -90 and 90');
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens';
|
||||
import { DefaultParamsProvider } from './infrastructure/default-params-provider';
|
||||
import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder';
|
||||
import { GetRouteController } from './interface/controllers/get-route.controller';
|
||||
import { GetBasicRouteController } from './interface/controllers/get-basic-route.controller';
|
||||
|
||||
const adapters: Provider[] = [
|
||||
{
|
||||
@@ -14,12 +14,12 @@ const adapters: Provider[] = [
|
||||
provide: DIRECTION_ENCODER,
|
||||
useClass: PostgresDirectionEncoder,
|
||||
},
|
||||
GetRouteController,
|
||||
GetBasicRouteController,
|
||||
];
|
||||
|
||||
@Module({
|
||||
imports: [CqrsModule],
|
||||
providers: [...adapters],
|
||||
exports: [DIRECTION_ENCODER, GetRouteController],
|
||||
exports: [DIRECTION_ENCODER, GetBasicRouteController],
|
||||
})
|
||||
export class GeographyModule {}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { GeorouterSettings } from '@modules/geography/core/application/types/georouter-settings.type';
|
||||
import { Waypoint } from '@modules/geography/core/application/types/waypoint.type';
|
||||
import { Role } from '@modules/geography/core/domain/route.types';
|
||||
|
||||
export class GetRouteRequestDto {
|
||||
export type GetRouteRequestDto = {
|
||||
roles: Role[];
|
||||
waypoints: Waypoint[];
|
||||
georouterSettings: GeorouterSettings;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,10 +4,11 @@ import { GetRouteRequestDto } from './dtos/get-route.request.dto';
|
||||
import { RouteEntity } from '@modules/geography/core/domain/route.entity';
|
||||
import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query';
|
||||
import { RouteMapper } from '@modules/geography/route.mapper';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Controller } from '@nestjs/common';
|
||||
import { GetBasicRouteControllerPort } from '@modules/geography/core/application/ports/get-basic-route-controller.port';
|
||||
|
||||
@Injectable()
|
||||
export class GetRouteController {
|
||||
@Controller()
|
||||
export class GetBasicRouteController implements GetBasicRouteControllerPort {
|
||||
constructor(
|
||||
private readonly queryBus: QueryBus,
|
||||
private readonly mapper: RouteMapper,
|
||||
@@ -15,7 +16,11 @@ export class GetRouteController {
|
||||
|
||||
async get(data: GetRouteRequestDto): Promise<RouteResponseDto> {
|
||||
const route: RouteEntity = await this.queryBus.execute(
|
||||
new GetRouteQuery(data.roles, data.waypoints, data.georouterSettings),
|
||||
new GetRouteQuery(data.roles, data.waypoints, {
|
||||
detailedDistance: false,
|
||||
detailedDuration: false,
|
||||
points: true,
|
||||
}),
|
||||
);
|
||||
return this.mapper.toResponse(route);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Coordinates } from '@modules/geography/core/application/types/coordinates.type';
|
||||
import { SpacetimePoint } from '@modules/geography/core/application/types/spacetime-point.type';
|
||||
|
||||
export class RouteResponseDto {
|
||||
@@ -8,5 +9,5 @@ export class RouteResponseDto {
|
||||
fwdAzimuth: number;
|
||||
backAzimuth: number;
|
||||
distanceAzimuth: number;
|
||||
spacetimePoints: SpacetimePoint[];
|
||||
points: SpacetimePoint[] | Coordinates[];
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export class RouteMapper
|
||||
response.fwdAzimuth = entity.getProps().fwdAzimuth;
|
||||
response.backAzimuth = entity.getProps().backAzimuth;
|
||||
response.distanceAzimuth = entity.getProps().distanceAzimuth;
|
||||
response.spacetimePoints = entity.getProps().spacetimePoints;
|
||||
response.points = entity.getProps().points;
|
||||
return response;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { ArgumentOutOfRangeException } from '@mobicoop/ddd-library';
|
||||
import { Coordinates } from '@modules/geography/core/domain/value-objects/coordinates.value-object';
|
||||
|
||||
describe('Waypoint value object', () => {
|
||||
it('should create a waypoint value object', () => {
|
||||
const coordinatesVO = new Coordinates({
|
||||
lon: 48.689445,
|
||||
lat: 6.17651,
|
||||
});
|
||||
expect(coordinatesVO.lon).toBe(48.689445);
|
||||
expect(coordinatesVO.lat).toBe(6.17651);
|
||||
});
|
||||
it('should throw an exception if longitude is invalid', () => {
|
||||
try {
|
||||
new Coordinates({
|
||||
lon: 348.689445,
|
||||
lat: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Coordinates({
|
||||
lon: -348.689445,
|
||||
lat: 6.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if latitude is invalid', () => {
|
||||
try {
|
||||
new Coordinates({
|
||||
lon: 48.689445,
|
||||
lat: 96.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
try {
|
||||
new Coordinates({
|
||||
lon: 48.689445,
|
||||
lat: -96.17651,
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -46,7 +46,7 @@ describe('Waypoint value object', () => {
|
||||
expect(e).toBeInstanceOf(ArgumentOutOfRangeException);
|
||||
}
|
||||
});
|
||||
it('should throw an exception if longitude is invalid', () => {
|
||||
it('should throw an exception if latitude is invalid', () => {
|
||||
try {
|
||||
new Waypoint({
|
||||
position: 0,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Role } from '@modules/geography/core/domain/route.types';
|
||||
import { GetRouteController } from '@modules/geography/interface/controllers/get-route.controller';
|
||||
import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller';
|
||||
import { RouteMapper } from '@modules/geography/route.mapper';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
@@ -14,8 +14,8 @@ const mockRouteMapper = {
|
||||
toResponse: jest.fn(),
|
||||
};
|
||||
|
||||
describe('Get Route Controller', () => {
|
||||
let getRouteController: GetRouteController;
|
||||
describe('Get Basic Route Controller', () => {
|
||||
let getBasicRouteController: GetBasicRouteController;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
@@ -28,11 +28,13 @@ describe('Get Route Controller', () => {
|
||||
provide: RouteMapper,
|
||||
useValue: mockRouteMapper,
|
||||
},
|
||||
GetRouteController,
|
||||
GetBasicRouteController,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
getRouteController = module.get<GetRouteController>(GetRouteController);
|
||||
getBasicRouteController = module.get<GetBasicRouteController>(
|
||||
GetBasicRouteController,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -40,12 +42,12 @@ describe('Get Route Controller', () => {
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(getRouteController).toBeDefined();
|
||||
expect(getBasicRouteController).toBeDefined();
|
||||
});
|
||||
|
||||
it('should get a route', async () => {
|
||||
jest.spyOn(mockQueryBus, 'execute');
|
||||
await getRouteController.get({
|
||||
await getBasicRouteController.get({
|
||||
roles: [Role.DRIVER],
|
||||
waypoints: [
|
||||
{
|
||||
@@ -59,11 +61,6 @@ describe('Get Route Controller', () => {
|
||||
lat: 2.3522,
|
||||
},
|
||||
],
|
||||
georouterSettings: {
|
||||
points: true,
|
||||
detailedDistance: false,
|
||||
detailedDuration: false,
|
||||
},
|
||||
});
|
||||
expect(mockQueryBus.execute).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -38,7 +38,7 @@ describe('Route Mapper', () => {
|
||||
fwdAzimuth: 283,
|
||||
backAzimuth: 93,
|
||||
distanceAzimuth: 19840,
|
||||
spacetimePoints: [],
|
||||
points: [],
|
||||
waypoints: [
|
||||
{
|
||||
position: 0,
|
||||
|
||||
Reference in New Issue
Block a user