get cached matching
This commit is contained in:
parent
09efe313ba
commit
b810bc86e6
|
@ -60,6 +60,44 @@ export class MatchQueryHandler implements IQueryHandler {
|
|||
perPage: this._defaultParams.PER_PAGE,
|
||||
})
|
||||
.setDatesAndSchedule(this.datetimeTransformer);
|
||||
let matchingEntity: MatchingEntity | undefined = await this._cachedMatching(
|
||||
query.id,
|
||||
);
|
||||
if (!matchingEntity)
|
||||
matchingEntity = (await this._createMatching(query)) as MatchingEntity;
|
||||
const perPage: number = query.perPage as number;
|
||||
const page: number = Paginator.pageNumber(
|
||||
matchingEntity.getProps().matches.length,
|
||||
perPage,
|
||||
query.page as number,
|
||||
);
|
||||
return {
|
||||
id: matchingEntity.id,
|
||||
matches: Paginator.pageItems(
|
||||
matchingEntity.getProps().matches,
|
||||
page,
|
||||
perPage,
|
||||
),
|
||||
total: matchingEntity.getProps().matches.length,
|
||||
page,
|
||||
perPage,
|
||||
};
|
||||
};
|
||||
|
||||
private _cachedMatching = async (
|
||||
id?: string,
|
||||
): Promise<MatchingEntity | undefined> => {
|
||||
if (!id) return undefined;
|
||||
try {
|
||||
return await this.matchingRepository.get(id);
|
||||
} catch (e: any) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
private _createMatching = async (
|
||||
query: MatchQuery,
|
||||
): Promise<MatchingEntity> => {
|
||||
await query.setRoutes();
|
||||
|
||||
let algorithm: Algorithm;
|
||||
|
@ -70,30 +108,8 @@ export class MatchQueryHandler implements IQueryHandler {
|
|||
}
|
||||
|
||||
const matches: MatchEntity[] = await algorithm.match();
|
||||
const perPage: number = query.perPage as number;
|
||||
const page: number = Paginator.pageNumber(
|
||||
matches.length,
|
||||
perPage,
|
||||
query.page as number,
|
||||
);
|
||||
// create Matching Entity for persistence
|
||||
const matchingEntity: MatchingEntity = MatchingEntity.create({
|
||||
matches: matches.map((matchEntity: MatchEntity) => ({
|
||||
adId: matchEntity.getProps().adId,
|
||||
role: matchEntity.getProps().role,
|
||||
frequency: matchEntity.getProps().frequency,
|
||||
distance: matchEntity.getProps().distance,
|
||||
duration: matchEntity.getProps().duration,
|
||||
initialDistance: matchEntity.getProps().initialDistance,
|
||||
initialDuration: matchEntity.getProps().initialDuration,
|
||||
distanceDetour: matchEntity.getProps().distanceDetour,
|
||||
durationDetour: matchEntity.getProps().durationDetour,
|
||||
distanceDetourPercentage:
|
||||
matchEntity.getProps().distanceDetourPercentage,
|
||||
durationDetourPercentage:
|
||||
matchEntity.getProps().durationDetourPercentage,
|
||||
journeys: matchEntity.getProps().journeys,
|
||||
})),
|
||||
const matchingEntity = MatchingEntity.create({
|
||||
matches,
|
||||
query: {
|
||||
driver: query.driver as boolean,
|
||||
passenger: query.passenger as boolean,
|
||||
|
@ -120,13 +136,7 @@ export class MatchQueryHandler implements IQueryHandler {
|
|||
},
|
||||
});
|
||||
await this.matchingRepository.save(matchingEntity);
|
||||
return {
|
||||
id: matchingEntity.id,
|
||||
matches: Paginator.pageItems(matches, page, perPage),
|
||||
total: matches.length,
|
||||
page,
|
||||
perPage,
|
||||
};
|
||||
return matchingEntity;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import { Point } from '@modules/ad/core/domain/value-objects/point.value-object'
|
|||
import { Route } from '../../types/route.type';
|
||||
|
||||
export class MatchQuery extends QueryBase {
|
||||
id?: string;
|
||||
driver?: boolean;
|
||||
passenger?: boolean;
|
||||
readonly frequency: Frequency;
|
||||
|
@ -43,6 +44,7 @@ export class MatchQuery extends QueryBase {
|
|||
|
||||
constructor(props: MatchRequestDto, routeProvider: RouteProviderPort) {
|
||||
super();
|
||||
this.id = props.id;
|
||||
this.driver = props.driver;
|
||||
this.passenger = props.passenger;
|
||||
this.frequency = props.frequency;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { MatchProps } from './match.types';
|
||||
import { MatchEntity } from './match.entity';
|
||||
import { MatchQueryProps } from './value-objects/match-query.value-object';
|
||||
|
||||
// All properties that a Matching has
|
||||
export interface MatchingProps {
|
||||
query: MatchQueryProps; // the query that induced the matches
|
||||
matches: MatchProps[];
|
||||
matches: MatchEntity[];
|
||||
}
|
||||
|
||||
// Properties that are needed for a Matching creation
|
||||
export interface CreateMatchingProps {
|
||||
query: MatchQueryProps;
|
||||
matches: MatchProps[];
|
||||
matches: MatchEntity[];
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
IsISO8601,
|
||||
IsInt,
|
||||
IsOptional,
|
||||
IsUUID,
|
||||
Max,
|
||||
Min,
|
||||
ValidateNested,
|
||||
|
@ -21,6 +22,10 @@ import { Frequency } from '@modules/ad/core/domain/ad.types';
|
|||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||
|
||||
export class MatchRequestDto {
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
id?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
driver?: boolean;
|
||||
|
|
|
@ -7,25 +7,26 @@ service MatcherService {
|
|||
}
|
||||
|
||||
message MatchRequest {
|
||||
bool driver = 1;
|
||||
bool passenger = 2;
|
||||
Frequency frequency = 3;
|
||||
string fromDate = 4;
|
||||
string toDate = 5;
|
||||
repeated ScheduleItem schedule = 6;
|
||||
bool strict = 7;
|
||||
repeated Waypoint waypoints = 8;
|
||||
AlgorithmType algorithmType = 9;
|
||||
int32 remoteness = 10;
|
||||
bool useProportion = 11;
|
||||
int32 proportion = 12;
|
||||
bool useAzimuth = 13;
|
||||
int32 azimuthMargin = 14;
|
||||
float maxDetourDistanceRatio = 15;
|
||||
float maxDetourDurationRatio = 16;
|
||||
int32 identifier = 22;
|
||||
optional int32 page = 23;
|
||||
optional int32 perPage = 24;
|
||||
string id = 1;
|
||||
bool driver = 2;
|
||||
bool passenger = 3;
|
||||
Frequency frequency = 4;
|
||||
string fromDate = 5;
|
||||
string toDate = 6;
|
||||
repeated ScheduleItem schedule = 7;
|
||||
bool strict = 8;
|
||||
repeated Waypoint waypoints = 9;
|
||||
AlgorithmType algorithmType = 10;
|
||||
int32 remoteness = 11;
|
||||
bool useProportion = 12;
|
||||
int32 proportion = 13;
|
||||
bool useAzimuth = 14;
|
||||
int32 azimuthMargin = 15;
|
||||
float maxDetourDistanceRatio = 16;
|
||||
float maxDetourDurationRatio = 17;
|
||||
int32 identifier = 18;
|
||||
optional int32 page = 19;
|
||||
optional int32 perPage = 20;
|
||||
}
|
||||
|
||||
message ScheduleItem {
|
||||
|
|
|
@ -15,22 +15,32 @@ export class MatchMapper {
|
|||
private readonly outputDatetimeTransformer: DateTimeTransformerPort,
|
||||
) {}
|
||||
|
||||
toResponse = (match: MatchEntity): MatchResponseDto => ({
|
||||
...new ResponseBase(match),
|
||||
adId: match.getProps().adId,
|
||||
role: match.getProps().role,
|
||||
frequency: match.getProps().frequency,
|
||||
distance: match.getProps().distance,
|
||||
duration: match.getProps().duration,
|
||||
initialDistance: match.getProps().initialDistance,
|
||||
initialDuration: match.getProps().initialDuration,
|
||||
distanceDetour: match.getProps().distanceDetour,
|
||||
durationDetour: match.getProps().durationDetour,
|
||||
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
|
||||
durationDetourPercentage: match.getProps().durationDetourPercentage,
|
||||
journeys: match.getProps().journeys.map((journey: Journey) => ({
|
||||
day: new Date(
|
||||
this.outputDatetimeTransformer.fromDate(
|
||||
toResponse = (match: MatchEntity): MatchResponseDto => {
|
||||
return {
|
||||
...new ResponseBase(match),
|
||||
adId: match.getProps().adId,
|
||||
role: match.getProps().role,
|
||||
frequency: match.getProps().frequency,
|
||||
distance: match.getProps().distance,
|
||||
duration: match.getProps().duration,
|
||||
initialDistance: match.getProps().initialDistance,
|
||||
initialDuration: match.getProps().initialDuration,
|
||||
distanceDetour: match.getProps().distanceDetour,
|
||||
durationDetour: match.getProps().durationDetour,
|
||||
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
|
||||
durationDetourPercentage: match.getProps().durationDetourPercentage,
|
||||
journeys: match.getProps().journeys.map((journey: Journey) => ({
|
||||
day: new Date(
|
||||
this.outputDatetimeTransformer.fromDate(
|
||||
{
|
||||
date: journey.firstDate.toISOString().split('T')[0],
|
||||
time: journey.firstDriverDepartureTime(),
|
||||
coordinates: journey.driverOrigin(),
|
||||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
).getDay(),
|
||||
firstDate: this.outputDatetimeTransformer.fromDate(
|
||||
{
|
||||
date: journey.firstDate.toISOString().split('T')[0],
|
||||
time: journey.firstDriverDepartureTime(),
|
||||
|
@ -38,41 +48,33 @@ export class MatchMapper {
|
|||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
).getDay(),
|
||||
firstDate: this.outputDatetimeTransformer.fromDate(
|
||||
{
|
||||
date: journey.firstDate.toISOString().split('T')[0],
|
||||
time: journey.firstDriverDepartureTime(),
|
||||
coordinates: journey.driverOrigin(),
|
||||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
lastDate: this.outputDatetimeTransformer.fromDate(
|
||||
{
|
||||
date: journey.lastDate.toISOString().split('T')[0],
|
||||
time: journey.firstDriverDepartureTime(),
|
||||
coordinates: journey.driverOrigin(),
|
||||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
steps: journey.journeyItems.map((journeyItem: JourneyItem) => ({
|
||||
duration: journeyItem.duration,
|
||||
distance: journeyItem.distance as number,
|
||||
lon: journeyItem.lon,
|
||||
lat: journeyItem.lat,
|
||||
time: this.outputDatetimeTransformer.time(
|
||||
lastDate: this.outputDatetimeTransformer.fromDate(
|
||||
{
|
||||
date: journey.firstDate.toISOString().split('T')[0],
|
||||
time: journeyItem.driverTime(),
|
||||
date: journey.lastDate.toISOString().split('T')[0],
|
||||
time: journey.firstDriverDepartureTime(),
|
||||
coordinates: journey.driverOrigin(),
|
||||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
actors: journeyItem.actorTimes.map((actorTime: ActorTime) => ({
|
||||
role: actorTime.role,
|
||||
target: actorTime.target,
|
||||
steps: journey.journeyItems.map((journeyItem: JourneyItem) => ({
|
||||
duration: journeyItem.duration,
|
||||
distance: journeyItem.distance as number,
|
||||
lon: journeyItem.lon,
|
||||
lat: journeyItem.lat,
|
||||
time: this.outputDatetimeTransformer.time(
|
||||
{
|
||||
date: journey.firstDate.toISOString().split('T')[0],
|
||||
time: journeyItem.driverTime(),
|
||||
coordinates: journey.driverOrigin(),
|
||||
},
|
||||
match.getProps().frequency,
|
||||
),
|
||||
actors: journeyItem.actorTimes.map((actorTime: ActorTime) => ({
|
||||
role: actorTime.role,
|
||||
target: actorTime.target,
|
||||
})),
|
||||
})),
|
||||
})),
|
||||
})),
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,13 +1,234 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Mapper } from '@mobicoop/ddd-library';
|
||||
import { MatchingEntity } from './core/domain/matching.entity';
|
||||
import { Frequency, Role } from './core/domain/ad.types';
|
||||
import { MatchEntity } from './core/domain/match.entity';
|
||||
import { Target } from './core/domain/candidate.types';
|
||||
import { Waypoint } from './core/application/types/waypoint.type';
|
||||
import { ScheduleItem } from './core/application/types/schedule-item.type';
|
||||
import { Journey } from './core/domain/value-objects/journey.value-object';
|
||||
import { JourneyItem } from './core/domain/value-objects/journey-item.value-object';
|
||||
import { ActorTime } from './core/domain/value-objects/actor-time.value-object';
|
||||
|
||||
@Injectable()
|
||||
export class MatchingMapper
|
||||
implements Mapper<MatchingEntity, string, string, undefined>
|
||||
{
|
||||
toPersistence = (entity: MatchingEntity): string => JSON.stringify(entity);
|
||||
toPersistence = (entity: MatchingEntity): string =>
|
||||
JSON.stringify(<PersistedMatching>{
|
||||
id: entity.id,
|
||||
createdAt: entity.createdAt.toISOString(),
|
||||
updatedAt: entity.updatedAt.toISOString(),
|
||||
matches: entity.getProps().matches.map((match: MatchEntity) => ({
|
||||
adId: match.getProps().adId,
|
||||
role: match.getProps().role,
|
||||
frequency: match.getProps().frequency,
|
||||
distance: match.getProps().distance,
|
||||
duration: match.getProps().duration,
|
||||
initialDistance: match.getProps().initialDistance,
|
||||
initialDuration: match.getProps().initialDuration,
|
||||
distanceDetour: match.getProps().distanceDetour,
|
||||
durationDetour: match.getProps().durationDetour,
|
||||
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
|
||||
durationDetourPercentage: match.getProps().durationDetourPercentage,
|
||||
journeys: match.getProps().journeys.map((journey: Journey) => ({
|
||||
firstDate: journey.firstDate.toISOString(),
|
||||
lastDate: journey.lastDate.toISOString(),
|
||||
journeyItems: journey.journeyItems.map(
|
||||
(journeyItem: JourneyItem) => ({
|
||||
lon: journeyItem.lon,
|
||||
lat: journeyItem.lat,
|
||||
duration: journeyItem.duration,
|
||||
distance: journeyItem.distance,
|
||||
actorTimes: journeyItem.actorTimes.map(
|
||||
(actorTime: ActorTime) => ({
|
||||
role: actorTime.role,
|
||||
target: actorTime.target,
|
||||
firstDatetime: actorTime.firstDatetime.toISOString(),
|
||||
firstMinDatetime: actorTime.firstMinDatetime.toISOString(),
|
||||
firstMaxDatetime: actorTime.firstMaxDatetime.toISOString(),
|
||||
lastDatetime: actorTime.lastDatetime.toISOString(),
|
||||
lastMinDatetime: actorTime.lastMinDatetime.toISOString(),
|
||||
lastMaxDatetime: actorTime.lastMaxDatetime.toISOString(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
})),
|
||||
})),
|
||||
query: {
|
||||
driver: entity.getProps().query.driver,
|
||||
passenger: entity.getProps().query.passenger,
|
||||
frequency: entity.getProps().query.frequency,
|
||||
fromDate: entity.getProps().query.fromDate,
|
||||
toDate: entity.getProps().query.toDate,
|
||||
schedule: entity
|
||||
.getProps()
|
||||
.query.schedule.map((scheduleItem: ScheduleItem) => ({
|
||||
day: scheduleItem.day,
|
||||
time: scheduleItem.time,
|
||||
margin: scheduleItem.margin,
|
||||
})),
|
||||
seatsProposed: entity.getProps().query.seatsProposed,
|
||||
seatsRequested: entity.getProps().query.seatsRequested,
|
||||
strict: entity.getProps().query.strict,
|
||||
waypoints: entity
|
||||
.getProps()
|
||||
.query.waypoints.map((waypoint: Waypoint) => ({
|
||||
lon: waypoint.lon,
|
||||
lat: waypoint.lat,
|
||||
position: waypoint.position,
|
||||
houseNumber: waypoint.houseNumber,
|
||||
street: waypoint.street,
|
||||
postalCode: waypoint.postalCode,
|
||||
locality: waypoint.locality,
|
||||
country: waypoint.country,
|
||||
})),
|
||||
algorithmType: entity.getProps().query.algorithmType,
|
||||
remoteness: entity.getProps().query.remoteness,
|
||||
useProportion: entity.getProps().query.useProportion,
|
||||
proportion: entity.getProps().query.proportion,
|
||||
useAzimuth: entity.getProps().query.useAzimuth,
|
||||
azimuthMargin: entity.getProps().query.azimuthMargin,
|
||||
maxDetourDistanceRatio: entity.getProps().query.maxDetourDistanceRatio,
|
||||
maxDetourDurationRatio: entity.getProps().query.maxDetourDurationRatio,
|
||||
},
|
||||
});
|
||||
|
||||
toDomain = (record: string): MatchingEntity =>
|
||||
new MatchingEntity(JSON.parse(record));
|
||||
toDomain = (record: string): MatchingEntity => {
|
||||
const parsedRecord: PersistedMatching = JSON.parse(record);
|
||||
const matchingEntity: MatchingEntity = new MatchingEntity({
|
||||
id: parsedRecord.id,
|
||||
createdAt: new Date(parsedRecord.createdAt),
|
||||
updatedAt: new Date(parsedRecord.updatedAt),
|
||||
props: {
|
||||
query: parsedRecord.query,
|
||||
matches: parsedRecord.matches.map((match: PersistedMatch) =>
|
||||
MatchEntity.create({
|
||||
adId: match.adId,
|
||||
role: match.role,
|
||||
frequency: match.frequency,
|
||||
distance: match.distance,
|
||||
duration: match.duration,
|
||||
initialDistance: match.initialDistance,
|
||||
initialDuration: match.initialDuration,
|
||||
journeys: match.journeys.map(
|
||||
(journey: PersistedJourney) =>
|
||||
new Journey({
|
||||
firstDate: new Date(journey.firstDate),
|
||||
lastDate: new Date(journey.lastDate),
|
||||
journeyItems: journey.journeyItems.map(
|
||||
(journeyItem: PersistedJourneyItem) =>
|
||||
new JourneyItem({
|
||||
lon: journeyItem.lon,
|
||||
lat: journeyItem.lat,
|
||||
duration: journeyItem.duration,
|
||||
distance: journeyItem.distance,
|
||||
actorTimes: journeyItem.actorTimes.map(
|
||||
(actorTime: PersistedActorTime) =>
|
||||
new ActorTime({
|
||||
role: actorTime.role,
|
||||
target: actorTime.target,
|
||||
firstDatetime: new Date(actorTime.firstDatetime),
|
||||
firstMinDatetime: new Date(
|
||||
actorTime.firstMinDatetime,
|
||||
),
|
||||
firstMaxDatetime: new Date(
|
||||
actorTime.firstMaxDatetime,
|
||||
),
|
||||
lastDatetime: new Date(actorTime.lastDatetime),
|
||||
lastMinDatetime: new Date(
|
||||
actorTime.lastMinDatetime,
|
||||
),
|
||||
lastMaxDatetime: new Date(
|
||||
actorTime.lastMaxDatetime,
|
||||
),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
},
|
||||
});
|
||||
return matchingEntity;
|
||||
};
|
||||
}
|
||||
|
||||
type PersistedMatching = {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
matches: PersistedMatch[];
|
||||
query: {
|
||||
driver: boolean;
|
||||
passenger: boolean;
|
||||
frequency: Frequency;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
schedule: {
|
||||
day: number;
|
||||
time: string;
|
||||
margin: number;
|
||||
}[];
|
||||
seatsProposed: number;
|
||||
seatsRequested: number;
|
||||
strict: boolean;
|
||||
waypoints: {
|
||||
houseNumber: string;
|
||||
street: string;
|
||||
postalCode: string;
|
||||
locality: string;
|
||||
lon: number;
|
||||
lat: number;
|
||||
country: string;
|
||||
position: number;
|
||||
}[];
|
||||
algorithmType: string;
|
||||
remoteness: number;
|
||||
useProportion: boolean;
|
||||
proportion: number;
|
||||
useAzimuth: boolean;
|
||||
azimuthMargin: number;
|
||||
maxDetourDistanceRatio: number;
|
||||
maxDetourDurationRatio: number;
|
||||
};
|
||||
};
|
||||
|
||||
type PersistedMatch = {
|
||||
adId: string;
|
||||
role: Role;
|
||||
frequency: Frequency;
|
||||
distance: number;
|
||||
duration: number;
|
||||
initialDistance: number;
|
||||
initialDuration: number;
|
||||
journeys: PersistedJourney[];
|
||||
};
|
||||
|
||||
type PersistedJourney = {
|
||||
firstDate: string;
|
||||
lastDate: string;
|
||||
journeyItems: PersistedJourneyItem[];
|
||||
};
|
||||
|
||||
type PersistedJourneyItem = {
|
||||
lon: number;
|
||||
lat: number;
|
||||
duration: number;
|
||||
distance: number;
|
||||
actorTimes: PersistedActorTime[];
|
||||
};
|
||||
|
||||
type PersistedActorTime = {
|
||||
role: Role;
|
||||
target: Target;
|
||||
firstDatetime: string;
|
||||
firstMinDatetime: string;
|
||||
firstMaxDatetime: string;
|
||||
lastDatetime: string;
|
||||
lastMinDatetime: string;
|
||||
lastMaxDatetime: string;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,8 @@ import {
|
|||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
|
@ -76,7 +78,156 @@ const mockAdRepository = {
|
|||
};
|
||||
|
||||
const mockMatchingRepository: MatchingRepositoryPort = {
|
||||
get: jest.fn(),
|
||||
get: jest
|
||||
.fn()
|
||||
.mockImplementationOnce(
|
||||
() =>
|
||||
new MatchingEntity({
|
||||
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||
createdAt: new Date('2023-08-20T09:48:00Z'),
|
||||
updatedAt: new Date('2023-08-20T09:48:00Z'),
|
||||
props: {
|
||||
matches: [
|
||||
new MatchEntity({
|
||||
id: '4bd4e90b-ffba-4f5f-b904-48ad0667a1d7',
|
||||
createdAt: new Date('2023-08-30T08:45:00Z'),
|
||||
updatedAt: new Date('2023-08-30T08:45:00Z'),
|
||||
props: {
|
||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||
role: Role.DRIVER,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
distance: 356041,
|
||||
duration: 12647,
|
||||
initialDistance: 348745,
|
||||
initialDuration: 12105,
|
||||
distanceDetour: 7296,
|
||||
durationDetour: 542,
|
||||
distanceDetourPercentage: 4.1,
|
||||
durationDetourPercentage: 3.8,
|
||||
journeys: [
|
||||
{
|
||||
firstDate: new Date('2023-08-28'),
|
||||
lastDate: new Date('2023-08-28'),
|
||||
journeyItems: [
|
||||
{
|
||||
lon: 6.389745,
|
||||
lat: 48.32644,
|
||||
duration: 0,
|
||||
distance: 0,
|
||||
actorTimes: [
|
||||
{
|
||||
role: Role.DRIVER,
|
||||
target: Target.START,
|
||||
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
firstMinDatetime: new Date(
|
||||
'2023-08-28T06:45:00Z',
|
||||
),
|
||||
firstMaxDatetime: new Date(
|
||||
'2023-08-28T07:15:00Z',
|
||||
),
|
||||
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||
},
|
||||
{
|
||||
role: Role.PASSENGER,
|
||||
target: Target.START,
|
||||
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
firstMinDatetime: new Date(
|
||||
'2023-08-28T06:45:00Z',
|
||||
),
|
||||
firstMaxDatetime: new Date(
|
||||
'2023-08-28T07:15:00Z',
|
||||
),
|
||||
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lon: 6.984567,
|
||||
lat: 48.021548,
|
||||
distance: 356041,
|
||||
duration: 12647,
|
||||
actorTimes: [
|
||||
{
|
||||
role: Role.DRIVER,
|
||||
target: Target.FINISH,
|
||||
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
firstMinDatetime: new Date(
|
||||
'2023-08-28T06:45:00Z',
|
||||
),
|
||||
firstMaxDatetime: new Date(
|
||||
'2023-08-28T07:15:00Z',
|
||||
),
|
||||
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||
},
|
||||
{
|
||||
role: Role.PASSENGER,
|
||||
target: Target.FINISH,
|
||||
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
firstMinDatetime: new Date(
|
||||
'2023-08-28T06:45:00Z',
|
||||
),
|
||||
firstMaxDatetime: new Date(
|
||||
'2023-08-28T07:15:00Z',
|
||||
),
|
||||
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
query: {
|
||||
driver: false,
|
||||
passenger: true,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
fromDate: '2023-08-28',
|
||||
toDate: '2023-08-28',
|
||||
schedule: [
|
||||
{
|
||||
day: 1,
|
||||
time: '06:40',
|
||||
margin: 900,
|
||||
},
|
||||
],
|
||||
seatsProposed: 3,
|
||||
seatsRequested: 1,
|
||||
strict: true,
|
||||
waypoints: [
|
||||
{
|
||||
lon: 6.389745,
|
||||
lat: 48.32644,
|
||||
},
|
||||
{
|
||||
lon: 6.984567,
|
||||
lat: 48.021548,
|
||||
},
|
||||
],
|
||||
algorithmType: 'PASSENGER_ORIENTED',
|
||||
remoteness: 15000,
|
||||
useProportion: true,
|
||||
proportion: 0.3,
|
||||
useAzimuth: true,
|
||||
azimuthMargin: 10,
|
||||
maxDetourDistanceRatio: 0.3,
|
||||
maxDetourDurationRatio: 0.3,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error();
|
||||
}),
|
||||
save: jest.fn(),
|
||||
};
|
||||
|
||||
|
@ -151,6 +302,10 @@ describe('Match Query Handler', () => {
|
|||
matchQueryHandler = module.get<MatchQueryHandler>(MatchQueryHandler);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(matchQueryHandler).toBeDefined();
|
||||
});
|
||||
|
@ -183,4 +338,64 @@ describe('Match Query Handler', () => {
|
|||
expect(matching.id).toHaveLength(36);
|
||||
expect(MatchingEntity.create).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should return a valid saved Matching', async () => {
|
||||
jest.spyOn(MatchingEntity, 'create');
|
||||
const matchQuery = new MatchQuery(
|
||||
{
|
||||
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||
algorithmType: AlgorithmType.PASSENGER_ORIENTED,
|
||||
driver: false,
|
||||
passenger: true,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
fromDate: '2023-08-28',
|
||||
toDate: '2023-08-28',
|
||||
schedule: [
|
||||
{
|
||||
time: '07:05',
|
||||
day: 1,
|
||||
margin: 900,
|
||||
},
|
||||
],
|
||||
strict: false,
|
||||
waypoints: [originWaypoint, destinationWaypoint],
|
||||
},
|
||||
mockRouteProvider,
|
||||
);
|
||||
const matching: MatchingResult = await matchQueryHandler.execute(
|
||||
matchQuery,
|
||||
);
|
||||
expect(matching.id).toBe('a3b10efb-121e-4d08-9198-9f57afdb5e2d');
|
||||
expect(MatchingEntity.create).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should return a new matching if saved Matching is not found', async () => {
|
||||
jest.spyOn(MatchingEntity, 'create');
|
||||
const matchQuery = new MatchQuery(
|
||||
{
|
||||
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||
algorithmType: AlgorithmType.PASSENGER_ORIENTED,
|
||||
driver: false,
|
||||
passenger: true,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
fromDate: '2023-08-28',
|
||||
toDate: '2023-08-28',
|
||||
schedule: [
|
||||
{
|
||||
time: '07:05',
|
||||
day: 1,
|
||||
margin: 900,
|
||||
},
|
||||
],
|
||||
strict: false,
|
||||
waypoints: [originWaypoint, destinationWaypoint],
|
||||
},
|
||||
mockRouteProvider,
|
||||
);
|
||||
const matching: MatchingResult = await matchQueryHandler.execute(
|
||||
matchQuery,
|
||||
);
|
||||
expect(matching.id).toHaveLength(36);
|
||||
expect(MatchingEntity.create).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { getRedisToken } from '@liaoliaots/nestjs-redis';
|
||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||
import { MatchingNotFoundException } from '@modules/ad/core/domain/matching.errors';
|
||||
import { MatchingRepository } from '@modules/ad/infrastructure/matching.repository';
|
||||
|
@ -52,7 +53,7 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
|||
updatedAt: new Date(),
|
||||
props: {
|
||||
matches: [
|
||||
{
|
||||
MatchEntity.create({
|
||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||
role: Role.DRIVER,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
|
@ -60,10 +61,6 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
|||
duration: 12647,
|
||||
initialDistance: 348745,
|
||||
initialDuration: 12105,
|
||||
distanceDetour: 7296,
|
||||
durationDetour: 542,
|
||||
distanceDetourPercentage: 4.1,
|
||||
durationDetourPercentage: 3.8,
|
||||
journeys: [
|
||||
{
|
||||
firstDate: new Date('2023-09-01'),
|
||||
|
@ -91,7 +88,7 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
|||
},
|
||||
],
|
||||
// ...
|
||||
},
|
||||
}),
|
||||
],
|
||||
query: {
|
||||
driver: false,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||
import { MatchingMapper } from '@modules/ad/matching.mapper';
|
||||
import { Test } from '@nestjs/testing';
|
||||
|
@ -25,46 +26,88 @@ describe('Matching Mapper', () => {
|
|||
updatedAt: new Date('2023-08-20T09:48:00Z'),
|
||||
props: {
|
||||
matches: [
|
||||
{
|
||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||
role: Role.DRIVER,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
distance: 356041,
|
||||
duration: 12647,
|
||||
initialDistance: 348745,
|
||||
initialDuration: 12105,
|
||||
distanceDetour: 7296,
|
||||
durationDetour: 542,
|
||||
distanceDetourPercentage: 4.1,
|
||||
durationDetourPercentage: 3.8,
|
||||
journeys: [
|
||||
{
|
||||
firstDate: new Date('2023-09-01'),
|
||||
lastDate: new Date('2023-09-01'),
|
||||
journeyItems: [
|
||||
{
|
||||
lon: 6.35484,
|
||||
lat: 48.26587,
|
||||
duration: 0,
|
||||
distance: 0,
|
||||
actorTimes: [
|
||||
{
|
||||
role: Role.DRIVER,
|
||||
target: Target.START,
|
||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// ...
|
||||
},
|
||||
new MatchEntity({
|
||||
id: '4bd4e90b-ffba-4f5f-b904-48ad0667a1d7',
|
||||
createdAt: new Date('2023-08-30T08:45:00Z'),
|
||||
updatedAt: new Date('2023-08-30T08:45:00Z'),
|
||||
props: {
|
||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||
role: Role.DRIVER,
|
||||
frequency: Frequency.PUNCTUAL,
|
||||
distance: 356041,
|
||||
duration: 12647,
|
||||
initialDistance: 348745,
|
||||
initialDuration: 12105,
|
||||
distanceDetour: 7296,
|
||||
durationDetour: 542,
|
||||
distanceDetourPercentage: 4.1,
|
||||
durationDetourPercentage: 3.8,
|
||||
journeys: [
|
||||
{
|
||||
firstDate: new Date('2023-09-01'),
|
||||
lastDate: new Date('2023-09-01'),
|
||||
journeyItems: [
|
||||
{
|
||||
lon: 6.389745,
|
||||
lat: 48.32644,
|
||||
duration: 0,
|
||||
distance: 0,
|
||||
actorTimes: [
|
||||
{
|
||||
role: Role.DRIVER,
|
||||
target: Target.START,
|
||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
},
|
||||
{
|
||||
role: Role.PASSENGER,
|
||||
target: Target.START,
|
||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lon: 6.984567,
|
||||
lat: 48.021548,
|
||||
distance: 356041,
|
||||
duration: 12647,
|
||||
actorTimes: [
|
||||
{
|
||||
role: Role.DRIVER,
|
||||
target: Target.FINISH,
|
||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
},
|
||||
{
|
||||
role: Role.PASSENGER,
|
||||
target: Target.FINISH,
|
||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
query: {
|
||||
driver: false,
|
||||
|
@ -105,14 +148,17 @@ describe('Matching Mapper', () => {
|
|||
});
|
||||
const mapped: string = matchingMapper.toPersistence(matchingEntity);
|
||||
expect(mapped).toBe(
|
||||
'{"_id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","_createdAt":"2023-08-20T09:48:00.000Z","_updatedAt":"2023-08-20T09:48:00.000Z","props":{"matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.35484,"lat":48.26587,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}},"_domainEvents":[]}',
|
||||
'{"id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","createdAt":"2023-08-20T09:48:00.000Z","updatedAt":"2023-08-20T09:48:00.000Z","matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.389745,"lat":48.32644,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]},{"lon":6.984567,"lat":48.021548,"duration":12647,"distance":356041,"actorTimes":[{"role":"DRIVER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}}',
|
||||
);
|
||||
});
|
||||
|
||||
it('should map persisted string to domain entity', async () => {
|
||||
const matchingEntity: MatchingEntity = matchingMapper.toDomain(
|
||||
'{"_id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","_createdAt":"2023-08-20T09:48:00.000Z","_updatedAt":"2023-08-20T09:48:00.000Z","props":{"matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.35484,"lat":48.26587,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}},"_domainEvents":[]}',
|
||||
'{"id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","createdAt":"2023-08-20T09:48:00.000Z","updatedAt":"2023-08-20T09:48:00.000Z","matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.389745,"lat":48.32644,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]},{"lon":6.984567,"lat":48.021548,"duration":12647,"distance":356041,"actorTimes":[{"role":"DRIVER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}}',
|
||||
);
|
||||
expect(matchingEntity.getProps().query.fromDate).toBe('2023-09-01');
|
||||
expect(matchingEntity.getProps().matches[0].getProps().adId).toBe(
|
||||
'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue