fixed bad ad mapping
This commit is contained in:
parent
2058bfce4c
commit
1939f62049
|
@ -7,10 +7,14 @@ import {
|
||||||
AdWriteExtraModel,
|
AdWriteExtraModel,
|
||||||
} from './infrastructure/ad.repository';
|
} from './infrastructure/ad.repository';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object';
|
import {
|
||||||
|
ScheduleItem,
|
||||||
|
ScheduleItemProps,
|
||||||
|
} from './core/domain/value-objects/schedule-item.value-object';
|
||||||
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
||||||
import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
||||||
import { ExtendedMapper } from '@mobicoop/ddd-library';
|
import { ExtendedMapper } from '@mobicoop/ddd-library';
|
||||||
|
import { Waypoint } from './core/domain/value-objects/waypoint.value-object';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapper constructs objects that are used in different layers:
|
* Mapper constructs objects that are used in different layers:
|
||||||
|
@ -76,28 +80,12 @@ export class AdMapper
|
||||||
return record;
|
return record;
|
||||||
};
|
};
|
||||||
|
|
||||||
toDomain = (record: AdReadModel): AdEntity => {
|
toDomain = (record: AdReadModel): AdEntity =>
|
||||||
const entity = new AdEntity({
|
new AdEntity({
|
||||||
id: record.uuid,
|
id: record.uuid,
|
||||||
createdAt: new Date(record.createdAt),
|
createdAt: new Date(record.createdAt),
|
||||||
updatedAt: new Date(record.updatedAt),
|
updatedAt: new Date(record.updatedAt),
|
||||||
props: {
|
props: {
|
||||||
driver: record.driver,
|
|
||||||
passenger: record.passenger,
|
|
||||||
frequency: record.frequency,
|
|
||||||
fromDate: record.fromDate.toISOString().split('T')[0],
|
|
||||||
toDate: record.toDate.toISOString().split('T')[0],
|
|
||||||
schedule: record.schedule.map((scheduleItem: ScheduleItemModel) => ({
|
|
||||||
day: scheduleItem.day,
|
|
||||||
time: `${scheduleItem.time
|
|
||||||
.getUTCHours()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}:${scheduleItem.time
|
|
||||||
.getUTCMinutes()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}`,
|
|
||||||
margin: scheduleItem.margin,
|
|
||||||
})),
|
|
||||||
seatsProposed: record.seatsProposed,
|
seatsProposed: record.seatsProposed,
|
||||||
seatsRequested: record.seatsRequested,
|
seatsRequested: record.seatsRequested,
|
||||||
strict: record.strict,
|
strict: record.strict,
|
||||||
|
@ -105,19 +93,37 @@ export class AdMapper
|
||||||
driverDistance: record.driverDistance,
|
driverDistance: record.driverDistance,
|
||||||
passengerDuration: record.passengerDuration,
|
passengerDuration: record.passengerDuration,
|
||||||
passengerDistance: record.passengerDistance,
|
passengerDistance: record.passengerDistance,
|
||||||
waypoints: this.directionEncoder
|
driver: record.driver,
|
||||||
.decode(record.waypoints)
|
passenger: record.passenger,
|
||||||
.map((coordinates, index) => ({
|
frequency: record.frequency,
|
||||||
position: index,
|
fromDate: record.fromDate.toISOString().split('T')[0],
|
||||||
...coordinates,
|
toDate: record.toDate.toISOString().split('T')[0],
|
||||||
})),
|
schedule: record.schedule.map(
|
||||||
|
(scheduleItem: ScheduleItemModel) =>
|
||||||
|
new ScheduleItem({
|
||||||
|
day: scheduleItem.day,
|
||||||
|
time: `${scheduleItem.time
|
||||||
|
.getUTCHours()
|
||||||
|
.toString()
|
||||||
|
.padStart(2, '0')}:${scheduleItem.time
|
||||||
|
.getUTCMinutes()
|
||||||
|
.toString()
|
||||||
|
.padStart(2, '0')}`,
|
||||||
|
margin: scheduleItem.margin,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
waypoints: this.directionEncoder.decode(record.waypoints).map(
|
||||||
|
(coordinates, index) =>
|
||||||
|
new Waypoint({
|
||||||
|
position: index,
|
||||||
|
...coordinates,
|
||||||
|
}),
|
||||||
|
),
|
||||||
fwdAzimuth: record.fwdAzimuth,
|
fwdAzimuth: record.fwdAzimuth,
|
||||||
backAzimuth: record.backAzimuth,
|
backAzimuth: record.backAzimuth,
|
||||||
points: [],
|
points: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return entity;
|
|
||||||
};
|
|
||||||
|
|
||||||
toPersistenceExtra = (entity: AdEntity): AdWriteExtraModel => ({
|
toPersistenceExtra = (entity: AdEntity): AdWriteExtraModel => ({
|
||||||
waypoints: this.directionEncoder.encode(entity.getProps().waypoints),
|
waypoints: this.directionEncoder.encode(entity.getProps().waypoints),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { ExtendedRepositoryPort } from '@mobicoop/ddd-library';
|
import { ExtendedRepositoryPort } from '@mobicoop/ddd-library';
|
||||||
import { AdEntity } from '../../domain/ad.entity';
|
import { AdEntity } from '../../domain/ad.entity';
|
||||||
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
|
|
||||||
|
|
||||||
export type AdRepositoryPort = ExtendedRepositoryPort<AdEntity> & {
|
export type AdRepositoryPort = ExtendedRepositoryPort<AdEntity> & {
|
||||||
getCandidates(queryString: string): Promise<AdReadModel[]>;
|
getCandidateAds(queryString: string): Promise<AdEntity[]>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||||
import { Selector } from '../algorithm.abstract';
|
import { Selector } from '../algorithm.abstract';
|
||||||
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
|
|
||||||
import { ScheduleItem } from '../match.query';
|
import { ScheduleItem } from '../match.query';
|
||||||
import { Waypoint } from '../../../types/waypoint.type';
|
import { Waypoint } from '../../../types/waypoint.type';
|
||||||
import { Point } from '../../../types/point.type';
|
import { Point } from '../../../types/point.type';
|
||||||
import { CandidateEntity } from '@modules/ad/core/domain/candidate.entity';
|
import { CandidateEntity } from '@modules/ad/core/domain/candidate.entity';
|
||||||
|
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
||||||
|
|
||||||
export class PassengerOrientedSelector extends Selector {
|
export class PassengerOrientedSelector extends Selector {
|
||||||
select = async (): Promise<CandidateEntity[]> => {
|
select = async (): Promise<CandidateEntity[]> => {
|
||||||
|
@ -25,17 +25,18 @@ export class PassengerOrientedSelector extends Selector {
|
||||||
queryStringRoles.map<Promise<AdsRole>>(
|
queryStringRoles.map<Promise<AdsRole>>(
|
||||||
async (queryStringRole: QueryStringRole) =>
|
async (queryStringRole: QueryStringRole) =>
|
||||||
<AdsRole>{
|
<AdsRole>{
|
||||||
ads: await this.repository.getCandidates(queryStringRole.query),
|
ads: await this.repository.getCandidateAds(queryStringRole.query),
|
||||||
role: queryStringRole.role,
|
role: queryStringRole.role,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.map((adsRole: AdsRole) =>
|
.map((adsRole: AdsRole) =>
|
||||||
adsRole.ads.map((adReadModel: AdReadModel) =>
|
adsRole.ads.map((adEntity: AdEntity) =>
|
||||||
CandidateEntity.create({
|
CandidateEntity.create({
|
||||||
id: adReadModel.uuid,
|
id: adEntity.id,
|
||||||
role: adsRole.role,
|
role: adsRole.role,
|
||||||
|
waypoints: adEntity.getProps().waypoints,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -60,7 +61,8 @@ export class PassengerOrientedSelector extends Selector {
|
||||||
"seatsProposed","seatsRequested",\
|
"seatsProposed","seatsRequested",\
|
||||||
strict,\
|
strict,\
|
||||||
"fwdAzimuth","backAzimuth",\
|
"fwdAzimuth","backAzimuth",\
|
||||||
si.day,si.time,si.margin`,
|
ad."createdAt",ad."updatedAt",\
|
||||||
|
si.uuid as "scheduleItemUuid",si.day,si.time,si.margin,si."createdAt" as "scheduleItemCreatedAt",si."updatedAt" as "scheduleItemUpdatedAt"`,
|
||||||
role == Role.DRIVER ? this._selectAsDriver() : this._selectAsPassenger(),
|
role == Role.DRIVER ? this._selectAsDriver() : this._selectAsPassenger(),
|
||||||
].join();
|
].join();
|
||||||
|
|
||||||
|
@ -295,6 +297,6 @@ export type QueryStringRole = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type AdsRole = {
|
type AdsRole = {
|
||||||
ads: AdReadModel[];
|
ads: AdEntity[];
|
||||||
role: Role;
|
role: Role;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,12 +3,14 @@ import { Role } from './ad.types';
|
||||||
// All properties that a Candidate has
|
// All properties that a Candidate has
|
||||||
export interface CandidateProps {
|
export interface CandidateProps {
|
||||||
role: Role;
|
role: Role;
|
||||||
|
waypoints: Waypoint[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties that are needed for a Candidate creation
|
// Properties that are needed for a Candidate creation
|
||||||
export interface CreateCandidateProps {
|
export interface CreateCandidateProps {
|
||||||
id: string;
|
id: string;
|
||||||
role: Role;
|
role: Role;
|
||||||
|
waypoints: Waypoint[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Waypoint = {
|
export type Waypoint = {
|
||||||
|
|
|
@ -29,11 +29,17 @@ export type AdModel = {
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The record as returned by the peristence system
|
||||||
|
*/
|
||||||
export type AdReadModel = AdModel & {
|
export type AdReadModel = AdModel & {
|
||||||
waypoints: string;
|
waypoints: string;
|
||||||
schedule: ScheduleItemModel[];
|
schedule: ScheduleItemModel[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The record ready to be sent to the peristence system
|
||||||
|
*/
|
||||||
export type AdWriteModel = AdModel & {
|
export type AdWriteModel = AdModel & {
|
||||||
schedule: {
|
schedule: {
|
||||||
create: ScheduleItemModel[];
|
create: ScheduleItemModel[];
|
||||||
|
@ -59,11 +65,14 @@ export type ScheduleItemModel = ScheduleItem & {
|
||||||
|
|
||||||
export type UngroupedAdModel = AdModel &
|
export type UngroupedAdModel = AdModel &
|
||||||
ScheduleItem & {
|
ScheduleItem & {
|
||||||
|
scheduleItemUuid: string;
|
||||||
|
scheduleItemCreatedAt: Date;
|
||||||
|
scheduleItemUpdatedAt: Date;
|
||||||
waypoints: string;
|
waypoints: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GroupedAdModel = AdModel & {
|
export type GroupedAdModel = AdModel & {
|
||||||
schedule: ScheduleItem[];
|
schedule: ScheduleItemModel[];
|
||||||
waypoints: string;
|
waypoints: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,14 +109,18 @@ export class AdRepository
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCandidates = async (queryString: string): Promise<AdReadModel[]> => {
|
getCandidateAds = async (queryString: string): Promise<AdEntity[]> =>
|
||||||
// console.log(queryString);
|
this._toAdReadModels(
|
||||||
return this.toAdReadModels(
|
|
||||||
(await this.prismaRaw.$queryRawUnsafe(queryString)) as UngroupedAdModel[],
|
(await this.prismaRaw.$queryRawUnsafe(queryString)) as UngroupedAdModel[],
|
||||||
);
|
)
|
||||||
};
|
.map((adReadModel: AdReadModel) => {
|
||||||
|
if (this.mapper.toDomain) return this.mapper.toDomain(adReadModel);
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(adEntity: AdEntity | undefined) => adEntity !== undefined,
|
||||||
|
) as AdEntity[];
|
||||||
|
|
||||||
private toAdReadModels = (
|
private _toAdReadModels = (
|
||||||
ungroupedAds: UngroupedAdModel[],
|
ungroupedAds: UngroupedAdModel[],
|
||||||
): AdReadModel[] => {
|
): AdReadModel[] => {
|
||||||
const groupedAdModels: GroupedAdModel[] = ungroupedAds.map(
|
const groupedAdModels: GroupedAdModel[] = ungroupedAds.map(
|
||||||
|
@ -120,9 +133,12 @@ export class AdRepository
|
||||||
toDate: ungroupedAd.toDate,
|
toDate: ungroupedAd.toDate,
|
||||||
schedule: [
|
schedule: [
|
||||||
{
|
{
|
||||||
|
uuid: ungroupedAd.scheduleItemUuid,
|
||||||
day: ungroupedAd.day,
|
day: ungroupedAd.day,
|
||||||
time: ungroupedAd.time,
|
time: ungroupedAd.time,
|
||||||
margin: ungroupedAd.margin,
|
margin: ungroupedAd.margin,
|
||||||
|
createdAt: ungroupedAd.scheduleItemCreatedAt,
|
||||||
|
updatedAt: ungroupedAd.scheduleItemUpdatedAt,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
seatsProposed: ungroupedAd.seatsProposed,
|
seatsProposed: ungroupedAd.seatsProposed,
|
||||||
|
@ -140,14 +156,14 @@ export class AdRepository
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const adReadModels: AdReadModel[] = [];
|
const adReadModels: AdReadModel[] = [];
|
||||||
groupedAdModels.forEach((adReadModel: AdReadModel) => {
|
groupedAdModels.forEach((groupdeAdModel: GroupedAdModel) => {
|
||||||
const ad: AdReadModel | undefined = adReadModels.find(
|
const adReadModel: AdReadModel | undefined = adReadModels.find(
|
||||||
(arm: AdReadModel) => arm.uuid == adReadModel.uuid,
|
(arm: AdReadModel) => arm.uuid == groupdeAdModel.uuid,
|
||||||
);
|
);
|
||||||
if (ad) {
|
if (adReadModel) {
|
||||||
ad.schedule.push(...adReadModel.schedule);
|
adReadModel.schedule.push(...groupdeAdModel.schedule);
|
||||||
} else {
|
} else {
|
||||||
adReadModels.push(adReadModel);
|
adReadModels.push(groupdeAdModel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return adReadModels;
|
return adReadModels;
|
||||||
|
|
|
@ -35,12 +35,12 @@ const destinationWaypoint: Waypoint = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockAdRepository = {
|
const mockAdRepository = {
|
||||||
getCandidates: jest.fn().mockImplementation(() => [
|
getCandidateAds: jest.fn().mockImplementation(() => [
|
||||||
{
|
{
|
||||||
ad: {
|
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
getProps: jest.fn().mockImplementation(() => ({
|
||||||
},
|
role: Role.DRIVER,
|
||||||
role: Role.DRIVER,
|
})),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { MatchQuery } from '@modules/ad/core/application/queries/match/match.que
|
||||||
import { PassengerOrientedAlgorithm } from '@modules/ad/core/application/queries/match/passenger-oriented-algorithm';
|
import { PassengerOrientedAlgorithm } from '@modules/ad/core/application/queries/match/passenger-oriented-algorithm';
|
||||||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||||
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
||||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||||
|
|
||||||
const originWaypoint: Waypoint = {
|
const originWaypoint: Waypoint = {
|
||||||
|
@ -51,12 +51,12 @@ const mockMatcherRepository: AdRepositoryPort = {
|
||||||
delete: jest.fn(),
|
delete: jest.fn(),
|
||||||
count: jest.fn(),
|
count: jest.fn(),
|
||||||
healthCheck: jest.fn(),
|
healthCheck: jest.fn(),
|
||||||
getCandidates: jest.fn().mockImplementation(() => [
|
getCandidateAds: jest.fn().mockImplementation(() => [
|
||||||
{
|
{
|
||||||
ad: {
|
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
getProps: jest.fn().mockImplementation(() => ({
|
||||||
},
|
waypoints: [],
|
||||||
role: Role.DRIVER,
|
})),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,10 +44,34 @@ const candidates: CandidateEntity[] = [
|
||||||
CandidateEntity.create({
|
CandidateEntity.create({
|
||||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
role: Role.DRIVER,
|
role: Role.DRIVER,
|
||||||
|
waypoints: [
|
||||||
|
{
|
||||||
|
position: 0,
|
||||||
|
lat: 48.678454,
|
||||||
|
lon: 6.189745,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: 1,
|
||||||
|
lat: 48.84877,
|
||||||
|
lon: 2.398457,
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
CandidateEntity.create({
|
CandidateEntity.create({
|
||||||
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
||||||
role: Role.PASSENGER,
|
role: Role.PASSENGER,
|
||||||
|
waypoints: [
|
||||||
|
{
|
||||||
|
position: 0,
|
||||||
|
lat: 48.668487,
|
||||||
|
lon: 6.178457,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: 1,
|
||||||
|
lat: 48.897457,
|
||||||
|
lon: 2.3688487,
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -99,33 +99,35 @@ const mockMatcherRepository: AdRepositoryPort = {
|
||||||
delete: jest.fn(),
|
delete: jest.fn(),
|
||||||
count: jest.fn(),
|
count: jest.fn(),
|
||||||
healthCheck: jest.fn(),
|
healthCheck: jest.fn(),
|
||||||
getCandidates: jest.fn().mockImplementation(() => [
|
getCandidateAds: jest.fn().mockImplementation(() => [
|
||||||
{
|
{
|
||||||
uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
driver: true,
|
getProps: jest.fn().mockImplementation(() => ({
|
||||||
passenger: true,
|
driver: true,
|
||||||
frequency: Frequency.PUNCTUAL,
|
passenger: true,
|
||||||
fromDate: new Date('2023-06-21'),
|
frequency: Frequency.PUNCTUAL,
|
||||||
toDate: new Date('2023-06-21'),
|
fromDate: new Date('2023-06-21'),
|
||||||
seatsProposed: 3,
|
toDate: new Date('2023-06-21'),
|
||||||
seatsRequested: 1,
|
seatsProposed: 3,
|
||||||
strict: false,
|
seatsRequested: 1,
|
||||||
ddriverDistance: 350000,
|
strict: false,
|
||||||
driverDuration: 14400,
|
ddriverDistance: 350000,
|
||||||
passengerDistance: 350000,
|
driverDuration: 14400,
|
||||||
passengerDuration: 14400,
|
passengerDistance: 350000,
|
||||||
fwdAzimuth: 273,
|
passengerDuration: 14400,
|
||||||
backAzimuth: 93,
|
fwdAzimuth: 273,
|
||||||
createdAt: new Date('2023-06-20T17:05:00Z'),
|
backAzimuth: 93,
|
||||||
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
createdAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
schedule: [
|
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
||||||
{
|
schedule: [
|
||||||
day: 3,
|
{
|
||||||
time: new Date('2023-06-21T07:05:00Z'),
|
day: 3,
|
||||||
margin: 900,
|
time: new Date('2023-06-21T07:05:00Z'),
|
||||||
},
|
margin: 900,
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,10 +44,34 @@ const candidates: CandidateEntity[] = [
|
||||||
CandidateEntity.create({
|
CandidateEntity.create({
|
||||||
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
id: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
role: Role.DRIVER,
|
role: Role.DRIVER,
|
||||||
|
waypoints: [
|
||||||
|
{
|
||||||
|
position: 0,
|
||||||
|
lat: 48.678454,
|
||||||
|
lon: 6.189745,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: 1,
|
||||||
|
lat: 48.84877,
|
||||||
|
lon: 2.398457,
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
CandidateEntity.create({
|
CandidateEntity.create({
|
||||||
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0',
|
||||||
role: Role.PASSENGER,
|
role: Role.PASSENGER,
|
||||||
|
waypoints: [
|
||||||
|
{
|
||||||
|
position: 0,
|
||||||
|
lat: 48.668487,
|
||||||
|
lon: 6.178457,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: 1,
|
||||||
|
lat: 48.897457,
|
||||||
|
lon: 2.3688487,
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,9 @@ import {
|
||||||
} from '@modules/ad/ad.di-tokens';
|
} from '@modules/ad/ad.di-tokens';
|
||||||
import { AdMapper } from '@modules/ad/ad.mapper';
|
import { AdMapper } from '@modules/ad/ad.mapper';
|
||||||
import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port';
|
import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port';
|
||||||
|
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
||||||
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
import {
|
import { AdRepository } from '@modules/ad/infrastructure/ad.repository';
|
||||||
AdReadModel,
|
|
||||||
AdRepository,
|
|
||||||
} from '@modules/ad/infrastructure/ad.repository';
|
|
||||||
import { PrismaService } from '@modules/ad/infrastructure/prisma.service';
|
import { PrismaService } from '@modules/ad/infrastructure/prisma.service';
|
||||||
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
||||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||||
|
@ -21,7 +19,58 @@ const mockMessagePublisher = {
|
||||||
|
|
||||||
const mockDirectionEncoder: DirectionEncoderPort = {
|
const mockDirectionEncoder: DirectionEncoderPort = {
|
||||||
encode: jest.fn(),
|
encode: jest.fn(),
|
||||||
decode: jest.fn(),
|
decode: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{
|
||||||
|
lon: 6.1765102,
|
||||||
|
lat: 48.689445,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 2.3522,
|
||||||
|
lat: 48.8566,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{
|
||||||
|
lon: 6.1765109,
|
||||||
|
lat: 48.689455,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 2.3598,
|
||||||
|
lat: 48.8589,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{
|
||||||
|
lon: 6.1765102,
|
||||||
|
lat: 48.689445,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 2.3522,
|
||||||
|
lat: 48.8566,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{
|
||||||
|
lon: 6.1765102,
|
||||||
|
lat: 48.689445,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 2.3522,
|
||||||
|
lat: 48.8566,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.mockImplementationOnce(() => [
|
||||||
|
{
|
||||||
|
lon: 6.1765102,
|
||||||
|
lat: 48.689445,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 2.3522,
|
||||||
|
lat: 48.8566,
|
||||||
|
},
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockRouteProvider: RouteProviderPort = {
|
const mockRouteProvider: RouteProviderPort = {
|
||||||
|
@ -43,7 +92,7 @@ const mockPrismaService = {
|
||||||
seatsProposed: 3,
|
seatsProposed: 3,
|
||||||
seatsRequested: 1,
|
seatsRequested: 1,
|
||||||
strict: false,
|
strict: false,
|
||||||
ddriverDistance: 350000,
|
driverDistance: 350000,
|
||||||
driverDuration: 14400,
|
driverDuration: 14400,
|
||||||
passengerDistance: 350000,
|
passengerDistance: 350000,
|
||||||
passengerDuration: 14400,
|
passengerDuration: 14400,
|
||||||
|
@ -52,9 +101,12 @@ const mockPrismaService = {
|
||||||
createdAt: new Date('2023-06-20T17:05:00Z'),
|
createdAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
||||||
|
scheduleItemUuid: 'b6bfac1f-e62e-4622-9641-a3475e15fc00',
|
||||||
day: 3,
|
day: 3,
|
||||||
time: new Date('2023-06-21T07:05:00Z'),
|
time: new Date('2023-06-21T07:05:00Z'),
|
||||||
margin: 900,
|
margin: 900,
|
||||||
|
scheduleItemCreatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
|
scheduleItemUpdatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uuid: '84af18ff-8779-4cac-9651-1ed5ab0713c4',
|
uuid: '84af18ff-8779-4cac-9651-1ed5ab0713c4',
|
||||||
|
@ -66,7 +118,7 @@ const mockPrismaService = {
|
||||||
seatsProposed: 3,
|
seatsProposed: 3,
|
||||||
seatsRequested: 1,
|
seatsRequested: 1,
|
||||||
strict: false,
|
strict: false,
|
||||||
ddriverDistance: 349000,
|
driverDistance: 349000,
|
||||||
driverDuration: 14300,
|
driverDuration: 14300,
|
||||||
passengerDistance: 350000,
|
passengerDistance: 350000,
|
||||||
passengerDuration: 14400,
|
passengerDuration: 14400,
|
||||||
|
@ -75,9 +127,12 @@ const mockPrismaService = {
|
||||||
createdAt: new Date('2023-06-18T14:16:10Z'),
|
createdAt: new Date('2023-06-18T14:16:10Z'),
|
||||||
updatedAt: new Date('2023-06-18T14:16:10Z'),
|
updatedAt: new Date('2023-06-18T14:16:10Z'),
|
||||||
waypoints: 'LINESTRING(6.1765109 48.689455,2.3598 48.8589)',
|
waypoints: 'LINESTRING(6.1765109 48.689455,2.3598 48.8589)',
|
||||||
|
scheduleItemUuid: '01524541-2044-49dc-8be6-1a3ccdc653b0',
|
||||||
day: 3,
|
day: 3,
|
||||||
time: new Date('2023-06-21T07:14:00Z'),
|
time: new Date('2023-06-21T07:14:00Z'),
|
||||||
margin: 900,
|
margin: 900,
|
||||||
|
scheduleItemCreatedAt: new Date('2023-06-18T14:16:10Z'),
|
||||||
|
scheduleItemUpdatedAt: new Date('2023-06-18T14:16:10Z'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
@ -93,7 +148,7 @@ const mockPrismaService = {
|
||||||
seatsProposed: 3,
|
seatsProposed: 3,
|
||||||
seatsRequested: 1,
|
seatsRequested: 1,
|
||||||
strict: false,
|
strict: false,
|
||||||
ddriverDistance: 350000,
|
driverDistance: 350000,
|
||||||
driverDuration: 14400,
|
driverDuration: 14400,
|
||||||
passengerDistance: 350000,
|
passengerDistance: 350000,
|
||||||
passengerDuration: 14400,
|
passengerDuration: 14400,
|
||||||
|
@ -102,9 +157,12 @@ const mockPrismaService = {
|
||||||
createdAt: new Date('2023-06-20T17:05:00Z'),
|
createdAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
||||||
|
scheduleItemUuid: '1387b34f-8ab1-46e0-8d0f-803af0f40f28',
|
||||||
day: 3,
|
day: 3,
|
||||||
time: new Date('2023-06-21T07:05:00Z'),
|
time: new Date('2023-06-21T07:05:00Z'),
|
||||||
margin: 900,
|
margin: 900,
|
||||||
|
scheduleItemCreatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
|
scheduleItemUpdatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
|
@ -116,7 +174,7 @@ const mockPrismaService = {
|
||||||
seatsProposed: 3,
|
seatsProposed: 3,
|
||||||
seatsRequested: 1,
|
seatsRequested: 1,
|
||||||
strict: false,
|
strict: false,
|
||||||
ddriverDistance: 350000,
|
driverDistance: 350000,
|
||||||
driverDuration: 14400,
|
driverDuration: 14400,
|
||||||
passengerDistance: 350000,
|
passengerDistance: 350000,
|
||||||
passengerDuration: 14400,
|
passengerDuration: 14400,
|
||||||
|
@ -125,9 +183,12 @@ const mockPrismaService = {
|
||||||
createdAt: new Date('2023-06-20T17:05:00Z'),
|
createdAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
||||||
|
scheduleItemUuid: '1fa88104-c50b-4f10-b8ce-389df765f3a6',
|
||||||
day: 4,
|
day: 4,
|
||||||
time: new Date('2023-06-21T07:15:00Z'),
|
time: new Date('2023-06-21T07:15:00Z'),
|
||||||
margin: 900,
|
margin: 900,
|
||||||
|
scheduleItemCreatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
|
scheduleItemUpdatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777',
|
||||||
|
@ -139,7 +200,7 @@ const mockPrismaService = {
|
||||||
seatsProposed: 3,
|
seatsProposed: 3,
|
||||||
seatsRequested: 1,
|
seatsRequested: 1,
|
||||||
strict: false,
|
strict: false,
|
||||||
ddriverDistance: 350000,
|
driverDistance: 350000,
|
||||||
driverDuration: 14400,
|
driverDuration: 14400,
|
||||||
passengerDistance: 350000,
|
passengerDistance: 350000,
|
||||||
passengerDuration: 14400,
|
passengerDuration: 14400,
|
||||||
|
@ -148,9 +209,12 @@ const mockPrismaService = {
|
||||||
createdAt: new Date('2023-06-20T17:05:00Z'),
|
createdAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
updatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
waypoints: 'LINESTRING(6.1765102 48.689445,2.3522 48.8566)',
|
||||||
|
scheduleItemUuid: '760bb1bb-256b-4e79-9d82-6d13011118f1',
|
||||||
day: 5,
|
day: 5,
|
||||||
time: new Date('2023-06-21T07:16:00Z'),
|
time: new Date('2023-06-21T07:16:00Z'),
|
||||||
margin: 900,
|
margin: 900,
|
||||||
|
scheduleItemCreatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
|
scheduleItemUpdatedAt: new Date('2023-06-20T17:05:00Z'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
@ -194,22 +258,22 @@ describe('Ad repository', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get candidates if query returns punctual Ads', async () => {
|
it('should get candidates if query returns punctual Ads', async () => {
|
||||||
const candidates: AdReadModel[] = await adRepository.getCandidates(
|
const candidates: AdEntity[] = await adRepository.getCandidateAds(
|
||||||
'somePunctualQueryString',
|
'somePunctualQueryString',
|
||||||
);
|
);
|
||||||
expect(candidates.length).toBe(2);
|
expect(candidates.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get candidates if query returns recurrent Ads', async () => {
|
it('should get candidates if query returns recurrent Ads', async () => {
|
||||||
const candidates: AdReadModel[] = await adRepository.getCandidates(
|
const candidates: AdEntity[] = await adRepository.getCandidateAds(
|
||||||
'someRecurrentQueryString',
|
'someRecurrentQueryString',
|
||||||
);
|
);
|
||||||
expect(candidates.length).toBe(1);
|
expect(candidates.length).toBe(1);
|
||||||
expect(candidates[0].schedule.length).toBe(3);
|
expect(candidates[0].getProps().schedule.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an empty array of candidates if query does not return Ads', async () => {
|
it('should return an empty array of candidates if query does not return Ads', async () => {
|
||||||
const candidates: AdReadModel[] = await adRepository.getCandidates(
|
const candidates: AdEntity[] = await adRepository.getCandidateAds(
|
||||||
'someQueryString',
|
'someQueryString',
|
||||||
);
|
);
|
||||||
expect(candidates.length).toBe(0);
|
expect(candidates.length).toBe(0);
|
||||||
|
|
|
@ -29,47 +29,4 @@ export class RouteEntity extends AggregateRoot<RouteProps> {
|
||||||
validate(): void {
|
validate(): void {
|
||||||
// entity business rules validation to protect it's invariant before saving entity to a database
|
// entity business rules validation to protect it's invariant before saving entity to a database
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static getPaths = (
|
|
||||||
// roles: Role[],
|
|
||||||
// waypoints: WaypointProps[],
|
|
||||||
// ): Path[] => {
|
|
||||||
// const paths: Path[] = [];
|
|
||||||
// if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
|
|
||||||
// if (waypoints.length == 2) {
|
|
||||||
// // 2 points => same route for driver and passenger
|
|
||||||
// paths.push(this.createGenericPath(waypoints));
|
|
||||||
// } else {
|
|
||||||
// paths.push(
|
|
||||||
// this.createDriverPath(waypoints),
|
|
||||||
// this.createPassengerPath(waypoints),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// } else if (roles.includes(Role.DRIVER)) {
|
|
||||||
// paths.push(this.createDriverPath(waypoints));
|
|
||||||
// } else if (roles.includes(Role.PASSENGER)) {
|
|
||||||
// paths.push(this.createPassengerPath(waypoints));
|
|
||||||
// }
|
|
||||||
// return paths;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// private static createGenericPath = (waypoints: WaypointProps[]): Path =>
|
|
||||||
// this.createPath(waypoints, PathType.GENERIC);
|
|
||||||
|
|
||||||
// private static createDriverPath = (waypoints: WaypointProps[]): Path =>
|
|
||||||
// this.createPath(waypoints, PathType.DRIVER);
|
|
||||||
|
|
||||||
// private static createPassengerPath = (waypoints: WaypointProps[]): Path =>
|
|
||||||
// this.createPath(
|
|
||||||
// [waypoints[0], waypoints[waypoints.length - 1]],
|
|
||||||
// PathType.PASSENGER,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// private static createPath = (
|
|
||||||
// points: WaypointProps[],
|
|
||||||
// type: PathType,
|
|
||||||
// ): Path => ({
|
|
||||||
// type,
|
|
||||||
// points,
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,5 +45,3 @@ export type Spacetime = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Step = Point & Spacetime;
|
export type Step = Point & Spacetime;
|
||||||
|
|
||||||
export type Waystep = Waypoint & Spacetime;
|
|
||||||
|
|
Loading…
Reference in New Issue