first working e2e version
This commit is contained in:
parent
eafa3c8bdd
commit
528ecfb3f9
|
@ -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[],
|
||||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
export class ActorResponseDto {
|
||||
role: string;
|
||||
target: string;
|
||||
firstDatetime: string;
|
||||
firstMinDatetime: string;
|
||||
firstMaxDatetime: string;
|
||||
lastDatetime: string;
|
||||
lastMinDatetime: string;
|
||||
lastMaxDatetime: string;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { StepResponseDto } from './step.response.dto';
|
||||
|
||||
export class JourneyResponseDto {
|
||||
firstDate: string;
|
||||
lastDate: string;
|
||||
steps: StepResponseDto[];
|
||||
}
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { ActorResponseDto } from './actor.response.dto';
|
||||
|
||||
export class StepResponseDto {
|
||||
duration: number;
|
||||
distance: number;
|
||||
lon: number;
|
||||
lat: number;
|
||||
actors: ActorResponseDto[];
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue