first working e2e version

This commit is contained in:
sbriat 2023-09-26 09:51:26 +02:00
parent eafa3c8bdd
commit 528ecfb3f9
10 changed files with 323 additions and 7 deletions

View File

@ -2,6 +2,10 @@ import { CandidateEntity } from '@modules/ad/core/domain/candidate.entity';
import { MatchEntity } from '../../../domain/match.entity';
import { MatchQuery } from './match.query';
import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
import {
Journey,
JourneyProps,
} from '@modules/ad/core/domain/value-objects/journey.value-object';
export abstract class Algorithm {
protected candidates: CandidateEntity[];
@ -22,7 +26,13 @@ export abstract class Algorithm {
}
// console.log(JSON.stringify(this.candidates, null, 2));
return this.candidates.map((candidate: CandidateEntity) =>
MatchEntity.create({ adId: candidate.id }),
MatchEntity.create({
adId: candidate.id,
role: candidate.getProps().role,
distance: candidate.getProps().distance as number,
duration: candidate.getProps().duration as number,
journeys: candidate.getProps().journeys as Journey[],
}),
);
};
}

View File

@ -1,13 +1,23 @@
import { AlgorithmType } from '../application/types/algorithm.types';
import { Role } from './ad.types';
import { JourneyProps } from './value-objects/journey.value-object';
// All properties that a Match has
export interface MatchProps {
adId: string;
role: Role;
distance: number;
duration: number;
journeys: JourneyProps[];
}
// Properties that are needed for a Match creation
export interface CreateMatchProps {
adId: string;
role: Role;
distance: number;
duration: number;
journeys: JourneyProps[];
}
export interface DefaultMatchQueryProps {

View File

@ -0,0 +1,10 @@
export class ActorResponseDto {
role: string;
target: string;
firstDatetime: string;
firstMinDatetime: string;
firstMaxDatetime: string;
lastDatetime: string;
lastMinDatetime: string;
lastMaxDatetime: string;
}

View File

@ -0,0 +1,7 @@
import { StepResponseDto } from './step.response.dto';
export class JourneyResponseDto {
firstDate: string;
lastDate: string;
steps: StepResponseDto[];
}

View File

@ -1,5 +1,10 @@
import { ResponseBase } from '@mobicoop/ddd-library';
import { JourneyResponseDto } from './journey.response.dto';
export class MatchResponseDto extends ResponseBase {
adId: string;
role: string;
distance: number;
duration: number;
journeys: JourneyResponseDto[];
}

View File

@ -0,0 +1,9 @@
import { ActorResponseDto } from './actor.response.dto';
export class StepResponseDto {
duration: number;
distance: number;
lon: number;
lat: number;
actors: ActorResponseDto[];
}

View File

@ -9,6 +9,9 @@ import { MatchQuery } from '@modules/ad/core/application/queries/match/match.que
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
import { AD_ROUTE_PROVIDER } from '@modules/ad/ad.di-tokens';
import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port';
import { Journey } from '@modules/ad/core/domain/value-objects/journey.value-object';
import { JourneyItem } from '@modules/ad/core/domain/value-objects/journey-item.value-object';
import { ActorTime } from '@modules/ad/core/domain/value-objects/actor-time.value-object';
@UsePipes(
new RpcValidationPipe({
@ -34,6 +37,29 @@ export class MatchGrpcController {
data: matches.map((match: MatchEntity) => ({
...new ResponseBase(match),
adId: match.getProps().adId,
role: match.getProps().role,
distance: match.getProps().distance,
duration: match.getProps().duration,
journeys: match.getProps().journeys.map((journey: Journey) => ({
firstDate: journey.firstDate.toUTCString(),
lastDate: journey.lastDate.toUTCString(),
steps: journey.journeyItems.map((journeyItem: JourneyItem) => ({
duration: journeyItem.duration,
distance: journeyItem.distance as number,
lon: journeyItem.lon,
lat: journeyItem.lat,
actors: journeyItem.actorTimes.map((actorTime: ActorTime) => ({
role: actorTime.role,
target: actorTime.target,
firstDatetime: actorTime.firstMinDatetime.toUTCString(),
firstMinDatetime: actorTime.firstMinDatetime.toUTCString(),
firstMaxDatetime: actorTime.firstMaxDatetime.toUTCString(),
lastDatetime: actorTime.lastDatetime.toUTCString(),
lastMinDatetime: actorTime.lastMinDatetime.toUTCString(),
lastMaxDatetime: actorTime.lastMaxDatetime.toUTCString(),
})),
})),
})),
})),
page: 1,
perPage: 5,

View File

@ -56,6 +56,35 @@ enum AlgorithmType {
message Match {
string id = 1;
string adId = 2;
string role = 3;
int32 duration = 4;
int32 distance = 5;
repeated Journey journeys = 6;
}
message Journey {
string firstDate = 1;
string lastDate = 2;
repeated Step steps = 3;
}
message Step {
int32 duration = 1;
int32 distance = 2;
double lon = 3;
double lat = 4;
repeated Actor actors = 5;
}
message Actor {
string role = 1;
string target = 2;
string firstDatetime = 3;
string firstMinDatetime = 4;
string firstMaxDatetime = 5;
string lastDatetime = 6;
string lastMinDatetime = 7;
string lastMaxDatetime = 8;
}
message Matches {

View File

@ -1,9 +1,116 @@
import { 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 { ActorTime } from '@modules/ad/core/domain/value-objects/actor-time.value-object';
import { JourneyItem } from '@modules/ad/core/domain/value-objects/journey-item.value-object';
describe('Match entity create', () => {
it('should create a new match entity', async () => {
const match: MatchEntity = MatchEntity.create({
adId: '53a0bf71-4132-4f7b-a4cc-88c796b6bdf1',
role: Role.DRIVER,
distance: 356041,
duration: 12647,
journeys: [
{
firstDate: new Date('2023-09-01'),
lastDate: new Date('2024-08-30'),
journeyItems: [
new JourneyItem({
lat: 48.689445,
lon: 6.17651,
duration: 0,
distance: 0,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.START,
firstDatetime: new Date('2023-09-01 07:00'),
firstMinDatetime: new Date('2023-09-01 06:45'),
firstMaxDatetime: new Date('2023-09-01 07:15'),
lastDatetime: new Date('2024-08-30 07:00'),
lastMinDatetime: new Date('2024-08-30 06:45'),
lastMaxDatetime: new Date('2024-08-30 07:15'),
}),
],
}),
new JourneyItem({
lat: 48.369445,
lon: 6.67487,
duration: 2100,
distance: 56878,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.NEUTRAL,
firstDatetime: new Date('2023-09-01 07:35'),
firstMinDatetime: new Date('2023-09-01 07:20'),
firstMaxDatetime: new Date('2023-09-01 07:50'),
lastDatetime: new Date('2024-08-30 07:35'),
lastMinDatetime: new Date('2024-08-30 07:20'),
lastMaxDatetime: new Date('2024-08-30 07:50'),
}),
new ActorTime({
role: Role.PASSENGER,
target: Target.START,
firstDatetime: new Date('2023-09-01 07:32'),
firstMinDatetime: new Date('2023-09-01 07:17'),
firstMaxDatetime: new Date('2023-09-01 07:47'),
lastDatetime: new Date('2024-08-30 07:32'),
lastMinDatetime: new Date('2024-08-30 07:17'),
lastMaxDatetime: new Date('2024-08-30 07:47'),
}),
],
}),
new JourneyItem({
lat: 47.98487,
lon: 6.9427,
duration: 3840,
distance: 76491,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.NEUTRAL,
firstDatetime: new Date('2023-09-01 08:04'),
firstMinDatetime: new Date('2023-09-01 07:51'),
firstMaxDatetime: new Date('2023-09-01 08:19'),
lastDatetime: new Date('2024-08-30 08:04'),
lastMinDatetime: new Date('2024-08-30 07:51'),
lastMaxDatetime: new Date('2024-08-30 08:19'),
}),
new ActorTime({
role: Role.PASSENGER,
target: Target.FINISH,
firstDatetime: new Date('2023-09-01 08:01'),
firstMinDatetime: new Date('2023-09-01 07:46'),
firstMaxDatetime: new Date('2023-09-01 08:16'),
lastDatetime: new Date('2024-08-30 08:01'),
lastMinDatetime: new Date('2024-08-30 07:46'),
lastMaxDatetime: new Date('2024-08-30 08:16'),
}),
],
}),
new JourneyItem({
lat: 47.365987,
lon: 7.02154,
duration: 4980,
distance: 96475,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.FINISH,
firstDatetime: new Date('2023-09-01 08:23'),
firstMinDatetime: new Date('2023-09-01 08:08'),
firstMaxDatetime: new Date('2023-09-01 08:38'),
lastDatetime: new Date('2024-08-30 08:23'),
lastMinDatetime: new Date('2024-08-30 08:08'),
lastMaxDatetime: new Date('2024-08-30 08:38'),
}),
],
}),
],
},
],
});
expect(match.id.length).toBe(36);
});

View File

@ -2,8 +2,11 @@ import { RpcExceptionCode } from '@mobicoop/ddd-library';
import { AD_ROUTE_PROVIDER } from '@modules/ad/ad.di-tokens';
import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port';
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
import { Frequency } from '@modules/ad/core/domain/ad.types';
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 { ActorTime } from '@modules/ad/core/domain/value-objects/actor-time.value-object';
import { JourneyItem } from '@modules/ad/core/domain/value-objects/journey-item.value-object';
import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto';
import { WaypointDto } from '@modules/ad/interface/grpc-controllers/dtos/waypoint.dto';
import { MatchGrpcController } from '@modules/ad/interface/grpc-controllers/match.grpc-controller';
@ -53,10 +56,110 @@ const mockQueryBus = {
.fn()
.mockImplementationOnce(() => [
MatchEntity.create({
adId: '0cc87f3b-7a27-4eff-9850-a5d642c2a0c3',
}),
MatchEntity.create({
adId: 'e4cc156f-aaa5-4270-bf6f-82f5a230d748',
adId: '53a0bf71-4132-4f7b-a4cc-88c796b6bdf1',
role: Role.DRIVER,
distance: 356041,
duration: 12647,
journeys: [
{
firstDate: new Date('2023-09-01'),
lastDate: new Date('2024-08-30'),
journeyItems: [
new JourneyItem({
lat: 48.689445,
lon: 6.17651,
duration: 0,
distance: 0,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.START,
firstDatetime: new Date('2023-09-01 07:00'),
firstMinDatetime: new Date('2023-09-01 06:45'),
firstMaxDatetime: new Date('2023-09-01 07:15'),
lastDatetime: new Date('2024-08-30 07:00'),
lastMinDatetime: new Date('2024-08-30 06:45'),
lastMaxDatetime: new Date('2024-08-30 07:15'),
}),
],
}),
new JourneyItem({
lat: 48.369445,
lon: 6.67487,
duration: 2100,
distance: 56878,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.NEUTRAL,
firstDatetime: new Date('2023-09-01 07:35'),
firstMinDatetime: new Date('2023-09-01 07:20'),
firstMaxDatetime: new Date('2023-09-01 07:50'),
lastDatetime: new Date('2024-08-30 07:35'),
lastMinDatetime: new Date('2024-08-30 07:20'),
lastMaxDatetime: new Date('2024-08-30 07:50'),
}),
new ActorTime({
role: Role.PASSENGER,
target: Target.START,
firstDatetime: new Date('2023-09-01 07:32'),
firstMinDatetime: new Date('2023-09-01 07:17'),
firstMaxDatetime: new Date('2023-09-01 07:47'),
lastDatetime: new Date('2024-08-30 07:32'),
lastMinDatetime: new Date('2024-08-30 07:17'),
lastMaxDatetime: new Date('2024-08-30 07:47'),
}),
],
}),
new JourneyItem({
lat: 47.98487,
lon: 6.9427,
duration: 3840,
distance: 76491,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.NEUTRAL,
firstDatetime: new Date('2023-09-01 08:04'),
firstMinDatetime: new Date('2023-09-01 07:51'),
firstMaxDatetime: new Date('2023-09-01 08:19'),
lastDatetime: new Date('2024-08-30 08:04'),
lastMinDatetime: new Date('2024-08-30 07:51'),
lastMaxDatetime: new Date('2024-08-30 08:19'),
}),
new ActorTime({
role: Role.PASSENGER,
target: Target.FINISH,
firstDatetime: new Date('2023-09-01 08:01'),
firstMinDatetime: new Date('2023-09-01 07:46'),
firstMaxDatetime: new Date('2023-09-01 08:16'),
lastDatetime: new Date('2024-08-30 08:01'),
lastMinDatetime: new Date('2024-08-30 07:46'),
lastMaxDatetime: new Date('2024-08-30 08:16'),
}),
],
}),
new JourneyItem({
lat: 47.365987,
lon: 7.02154,
duration: 4980,
distance: 96475,
actorTimes: [
new ActorTime({
role: Role.DRIVER,
target: Target.FINISH,
firstDatetime: new Date('2023-09-01 08:23'),
firstMinDatetime: new Date('2023-09-01 08:08'),
firstMaxDatetime: new Date('2023-09-01 08:38'),
lastDatetime: new Date('2024-08-30 08:23'),
lastMinDatetime: new Date('2024-08-30 08:08'),
lastMaxDatetime: new Date('2024-08-30 08:38'),
}),
],
}),
],
},
],
}),
])
.mockImplementationOnce(() => {
@ -103,7 +206,7 @@ describe('Match Grpc Controller', () => {
const matchPaginatedResponseDto = await matchGrpcController.match(
punctualMatchRequestDto,
);
expect(matchPaginatedResponseDto.data).toHaveLength(2);
expect(matchPaginatedResponseDto.data).toHaveLength(1);
expect(mockQueryBus.execute).toHaveBeenCalledTimes(1);
});