route tests

This commit is contained in:
sbriat 2023-08-21 17:06:28 +02:00
parent e93d8b0c9d
commit dad964b39c
9 changed files with 290 additions and 21 deletions

View File

@ -1,5 +1,5 @@
export type GeorouterSettings = {
withPoints: boolean;
withTime: boolean;
withDistance: boolean;
points: boolean;
detailedDuration: boolean;
detailedDistance: boolean;
};

View File

@ -1,7 +1,7 @@
import { PathType } from '../../domain/route.types';
import { Point } from './point.type';
import { Coordinates } from './coordinates.type';
export type Path = {
type: PathType;
points: Point[];
points: Coordinates[];
};

View File

@ -1,6 +0,0 @@
import { PointContext } from '../../domain/route.types';
import { Coordinates } from './coordinates.type';
export type Point = Coordinates & {
context?: PointContext;
};

View File

@ -1,5 +1,5 @@
import { PathType } from '../../domain/route.types';
import { Point } from './point.type';
import { Coordinates } from './coordinates.type';
import { SpacetimePoint } from './spacetime-point.type';
export type Route = {
@ -9,6 +9,6 @@ export type Route = {
fwdAzimuth: number;
backAzimuth: number;
distanceAzimuth: number;
points: Point[];
points: Coordinates[];
spacetimePoints: SpacetimePoint[];
};

View File

@ -1,6 +1,6 @@
import { Point } from './point.type';
import { Coordinates } from './coordinates.type';
export type SpacetimePoint = Point & {
export type SpacetimePoint = Coordinates & {
duration: number;
distance: number;
};

View File

@ -1,5 +1,5 @@
import { Point } from './point.type';
import { Coordinates } from './coordinates.type';
export type Waypoint = Point & {
export type Waypoint = Coordinates & {
position: number;
};

View File

@ -10,15 +10,23 @@ import {
import { WaypointProps } from './value-objects/waypoint.value-object';
import { Route } from '../application/types/route.type';
import { v4 } from 'uuid';
import { RouteNotFoundException } from './route.errors';
export class RouteEntity extends AggregateRoot<RouteProps> {
protected readonly _id: AggregateID;
static create = async (create: CreateRouteProps): Promise<RouteEntity> => {
const directions: Direction[] = await create.georouter.routes(
let directions: Direction[];
try {
directions = await create.georouter.routes(
this.getPaths(create.roles, create.waypoints),
create.georouterSettings,
);
if (!directions || directions.length == 0)
throw new RouteNotFoundException();
} catch (e: any) {
throw e;
}
let driverRoute: Route;
let passengerRoute: Route;
if (directions.some((route: Route) => route.type == PathType.GENERIC)) {

View File

@ -0,0 +1,11 @@
import { ExceptionBase } from '@mobicoop/ddd-library';
export class RouteNotFoundException extends ExceptionBase {
static readonly message = 'Route not found';
public readonly code = 'ROUTE.NOT_FOUND';
constructor(cause?: Error, metadata?: unknown) {
super(RouteNotFoundException.message, cause, metadata);
}
}

View File

@ -0,0 +1,256 @@
import { GeorouterPort } from '@modules/geography/core/application/ports/georouter.port';
import { Coordinates } from '@modules/geography/core/application/types/coordinates.type';
import { RouteEntity } from '@modules/geography/core/domain/route.entity';
import { RouteNotFoundException } from '@modules/geography/core/domain/route.errors';
import {
CreateRouteProps,
PathType,
Role,
} from '@modules/geography/core/domain/route.types';
const originCoordinates: Coordinates = {
lon: 48.689445,
lat: 6.17651,
};
const destinationCoordinates: Coordinates = {
lon: 48.8566,
lat: 2.3522,
};
const additionalCoordinates: Coordinates = {
lon: 48.7566,
lat: 4.4498,
};
const mockGeorouter: GeorouterPort = {
routes: jest
.fn()
.mockImplementationOnce(() => [
{
type: PathType.DRIVER,
distance: 350101,
duration: 14422,
fwdAzimuth: 273,
backAzimuth: 93,
distanceAzimuth: 336544,
points: [
{
lon: 6.1765102,
lat: 48.689445,
},
{
lon: 4.984578,
lat: 48.725687,
},
{
lon: 2.3522,
lat: 48.8566,
},
],
spacetimePoints: [],
},
])
.mockImplementationOnce(() => [
{
type: PathType.PASSENGER,
distance: 350102,
duration: 14423,
fwdAzimuth: 273,
backAzimuth: 93,
distanceAzimuth: 336545,
points: [
{
lon: 6.1765103,
lat: 48.689446,
},
{
lon: 4.984579,
lat: 48.725688,
},
{
lon: 2.3523,
lat: 48.8567,
},
],
spacetimePoints: [],
},
])
.mockImplementationOnce(() => [
{
type: PathType.GENERIC,
distance: 350100,
duration: 14421,
fwdAzimuth: 273,
backAzimuth: 93,
distanceAzimuth: 336543,
points: [
{
lon: 6.1765101,
lat: 48.689444,
},
{
lon: 4.984577,
lat: 48.725686,
},
{
lon: 2.3521,
lat: 48.8565,
},
],
spacetimePoints: [],
},
])
.mockImplementationOnce(() => [
{
type: PathType.GENERIC,
distance: 350108,
duration: 14428,
fwdAzimuth: 273,
backAzimuth: 93,
distanceAzimuth: 336548,
points: [
{
lon: 6.1765101,
lat: 48.689444,
},
{
lon: 4.984577,
lat: 48.725686,
},
{
lon: 2.3521,
lat: 48.8565,
},
],
spacetimePoints: [],
},
])
.mockImplementationOnce(() => []),
};
const createDriverRouteProps: CreateRouteProps = {
roles: [Role.DRIVER],
waypoints: [
{
position: 0,
...originCoordinates,
},
{
position: 1,
...destinationCoordinates,
},
],
georouter: mockGeorouter,
georouterSettings: {
points: true,
detailedDistance: false,
detailedDuration: false,
},
};
const createPassengerRouteProps: CreateRouteProps = {
roles: [Role.PASSENGER],
waypoints: [
{
position: 0,
...originCoordinates,
},
{
position: 1,
...destinationCoordinates,
},
],
georouter: mockGeorouter,
georouterSettings: {
points: true,
detailedDistance: false,
detailedDuration: false,
},
};
const createSimpleDriverAndPassengerRouteProps: CreateRouteProps = {
roles: [Role.DRIVER, Role.PASSENGER],
waypoints: [
{
position: 0,
...originCoordinates,
},
{
position: 1,
...destinationCoordinates,
},
],
georouter: mockGeorouter,
georouterSettings: {
points: true,
detailedDistance: false,
detailedDuration: false,
},
};
const createComplexDriverAndPassengerRouteProps: CreateRouteProps = {
roles: [Role.DRIVER, Role.PASSENGER],
waypoints: [
{
position: 0,
...originCoordinates,
},
{
position: 1,
...additionalCoordinates,
},
{
position: 2,
...destinationCoordinates,
},
],
georouter: mockGeorouter,
georouterSettings: {
points: true,
detailedDistance: false,
detailedDuration: false,
},
};
describe('Route entity create', () => {
it('should create a new entity for a driver only', async () => {
const route: RouteEntity = await RouteEntity.create(createDriverRouteProps);
expect(route.id.length).toBe(36);
expect(route.getProps().driverDuration).toBe(14422);
expect(route.getProps().passengerDistance).toBeUndefined();
});
it('should create a new entity for a passenger only', async () => {
const route: RouteEntity = await RouteEntity.create(
createPassengerRouteProps,
);
expect(route.id.length).toBe(36);
expect(route.getProps().passengerDuration).toBe(14423);
expect(route.getProps().driverDistance).toBeUndefined();
});
it('should create a new entity for a simple driver and passenger route', async () => {
const route: RouteEntity = await RouteEntity.create(
createSimpleDriverAndPassengerRouteProps,
);
expect(route.id.length).toBe(36);
expect(route.getProps().driverDuration).toBe(14421);
expect(route.getProps().driverDistance).toBe(350100);
expect(route.getProps().passengerDuration).toBe(14421);
expect(route.getProps().passengerDistance).toBe(350100);
});
it('should create a new entity for a complex driver and passenger route', async () => {
const route: RouteEntity = await RouteEntity.create(
createComplexDriverAndPassengerRouteProps,
);
expect(route.id.length).toBe(36);
expect(route.getProps().driverDuration).toBe(14428);
expect(route.getProps().driverDistance).toBe(350108);
expect(route.getProps().passengerDuration).toBe(14428);
expect(route.getProps().passengerDistance).toBe(350108);
});
it('should throw an exception if route is not found', async () => {
try {
await RouteEntity.create(createDriverRouteProps);
} catch (e: any) {
expect(e).toBeInstanceOf(RouteNotFoundException);
}
});
});