add mode to match wip

This commit is contained in:
sbriat 2023-05-02 17:26:04 +02:00
parent e312a6c712
commit a6f7476599
47 changed files with 489 additions and 204 deletions

View File

@ -5,7 +5,7 @@ import { ConfigModule } from '@nestjs/config';
import { ConfigurationModule } from './modules/configuration/configuration.module'; import { ConfigurationModule } from './modules/configuration/configuration.module';
import { HealthModule } from './modules/health/health.module'; import { HealthModule } from './modules/health/health.module';
import { MatcherModule } from './modules/matcher/matcher.module'; import { MatcherModule } from './modules/matcher/matcher.module';
import { AdModule } from './modules/ad/ad.modules'; import { AdModule } from './modules/ad/ad.module';
@Module({ @Module({
imports: [ imports: [

View File

@ -43,37 +43,37 @@ export class CreateAdRequest {
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
monTime: string | null; monTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
tueTime: string | null; tueTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
wedTime: string | null; wedTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
thuTime!: string | null; thuTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
friTime: string | null; friTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
satTime: string | null; satTime?: string | null;
@IsOptional() @IsOptional()
@IsString() @IsString()
@AutoMap() @AutoMap()
sunTime: string | null; sunTime?: string | null;
@IsNumber() @IsNumber()
@AutoMap() @AutoMap()
@ -127,7 +127,7 @@ export class CreateAdRequest {
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()
@AutoMap() @AutoMap()
seatsUsed: number; seatsUsed?: number;
@IsString() @IsString()
@AutoMap() @AutoMap()
@ -137,5 +137,5 @@ export class CreateAdRequest {
@AutoMap() @AutoMap()
updatedAt: string; updatedAt: string;
timezone: string; timezone?: string;
} }

View File

@ -4,13 +4,16 @@ export class TimeConverter {
static toUtcDatetime = ( static toUtcDatetime = (
date: string, date: string,
time: string, time: string,
ianaTimezone: string, timezone: string,
): Date => ): Date => {
date && time try {
? new Date( return new Date(
new DateTime(`${date}T${time}:00`, TimeZone.zone(ianaTimezone, false)) new DateTime(`${date}T${time}:00`, TimeZone.zone(timezone, false))
.convert(TimeZone.zone('UTC')) .convert(TimeZone.zone('UTC'))
.toIsoString(), .toIsoString(),
) );
: undefined; } catch (e) {
return undefined;
}
};
} }

View File

@ -55,72 +55,44 @@ export class AdProfile extends AutomapperProfile {
), ),
forMember( forMember(
(dest) => dest.monTime, (dest) => dest.monTime,
mapFrom((source) => mapFrom(({ monTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.monTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.tueTime, (dest) => dest.tueTime,
mapFrom((source) => mapFrom(({ tueTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.tueTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.wedTime, (dest) => dest.wedTime,
mapFrom((source) => mapFrom(({ wedTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.wedTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.thuTime, (dest) => dest.thuTime,
mapFrom((source) => mapFrom(({ thuTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.thuTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.friTime, (dest) => dest.friTime,
mapFrom((source) => mapFrom(({ friTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.friTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.satTime, (dest) => dest.satTime,
mapFrom((source) => mapFrom(({ satTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.satTime,
source.timezone,
),
), ),
), ),
forMember( forMember(
(dest) => dest.sunTime, (dest) => dest.sunTime,
mapFrom((source) => mapFrom(({ sunTime: time, fromDate: date, timezone }) =>
TimeConverter.toUtcDatetime( TimeConverter.toUtcDatetime(date, time, timezone),
source.fromDate,
source.sunTime,
source.timezone,
),
), ),
), ),
); );

View File

@ -0,0 +1,47 @@
import { AmqpConnection } from '@golevelup/nestjs-rabbitmq';
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { Messager } from '../../../../adapters/secondaries/messager';
const mockAmqpConnection = {
publish: jest.fn().mockImplementation(),
};
const mockConfigService = {
get: jest.fn().mockResolvedValue({
RMQ_EXCHANGE: 'mobicoop',
}),
};
describe('Messager', () => {
let messager: Messager;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [],
providers: [
Messager,
{
provide: AmqpConnection,
useValue: mockAmqpConnection,
},
{
provide: ConfigService,
useValue: mockConfigService,
},
],
}).compile();
messager = module.get<Messager>(Messager);
});
it('should be defined', () => {
expect(messager).toBeDefined();
});
it('should publish a message', async () => {
jest.spyOn(mockAmqpConnection, 'publish');
messager.publish('test.create.info', 'my-test');
expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1);
});
});

View File

@ -0,0 +1,35 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TimezoneFinder } from '../../../../adapters/secondaries/timezone-finder';
import { GeoTimezoneFinder } from '../../../../../geography/adapters/secondaries/geo-timezone-finder';
const mockGeoTimezoneFinder = {
timezones: jest.fn().mockImplementation(() => ['Europe/Paris']),
};
describe('Timezone Finder', () => {
let timezoneFinder: TimezoneFinder;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [],
providers: [
TimezoneFinder,
{
provide: GeoTimezoneFinder,
useValue: mockGeoTimezoneFinder,
},
],
}).compile();
timezoneFinder = module.get<TimezoneFinder>(TimezoneFinder);
});
it('should be defined', () => {
expect(timezoneFinder).toBeDefined();
});
it('should get timezone for Nancy(France) as Europe/Paris', () => {
const timezones = timezoneFinder.timezones(6.179373, 48.687913);
expect(timezones.length).toBe(1);
expect(timezones[0]).toBe('Europe/Paris');
});
});

View File

@ -0,0 +1,91 @@
import { CreateAdRequest } from '../../../domain/dtos/create-ad.request';
import { PointType } from '../../../../geography/domain/types/point-type.enum';
import { CreateAdUseCase } from '../../../domain/usecases/create-ad.usecase';
import { Test, TestingModule } from '@nestjs/testing';
import { AutomapperModule } from '@automapper/nestjs';
import { classes } from '@automapper/classes';
import { AdRepository } from '../../../adapters/secondaries/ad.repository';
import { CreateAdCommand } from '../../../commands/create-ad.command';
import { Ad } from '../../../domain/entities/ad';
import { AdProfile } from '../../../mappers/ad.profile';
const mockAdRepository = {};
const createAdRequest: CreateAdRequest = {
uuid: '77c55dfc-c28b-4026-942e-f94e95401fb1',
driver: true,
passenger: false,
frequency: 2,
fromDate: '2023-04-26',
toDate: '2024-04-25',
monTime: '07:00',
tueTime: '07:00',
wedTime: '07:00',
thuTime: '07:00',
friTime: '07:00',
satTime: null,
sunTime: null,
monMargin: 900,
tueMargin: 900,
wedMargin: 900,
thuMargin: 900,
friMargin: 900,
satMargin: 900,
sunMargin: 900,
originType: PointType.OTHER,
destinationType: PointType.OTHER,
seatsDriver: 3,
seatsPassenger: 1,
createdAt: '2023-04-01 12:45',
updatedAt: '2023-04-01 12:45',
waypoints: [
{ lon: 6, lat: 45 },
{ lon: 6.5, lat: 45.5 },
],
};
describe('CreateAdUseCase', () => {
let createAdUseCase: CreateAdUseCase;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })],
providers: [
{
provide: AdRepository,
useValue: mockAdRepository,
},
AdProfile,
CreateAdUseCase,
],
}).compile();
createAdUseCase = module.get<CreateAdUseCase>(CreateAdUseCase);
});
it('should be defined', () => {
expect(createAdUseCase).toBeDefined();
});
describe('execute', () => {
it('should create an ad', async () => {
const ad = await createAdUseCase.execute(
new CreateAdCommand(createAdRequest),
);
expect(ad).toBeInstanceOf(Ad);
});
// it('should throw an exception when error occurs', async () => {
// await expect(
// createAdUseCase.execute(
// new MatchQuery(
// matchRequest,
// defaultParams,
// mockGeorouterCreator,
// mockTimezoneFinder,
// ),
// ),
// ).rejects.toBeInstanceOf(MatcherException);
// });
});
});

View File

@ -0,0 +1,35 @@
import { TimeConverter } from '../../../domain/entities/time-converter';
describe('TimeConverter', () => {
it('should be defined', () => {
expect(new TimeConverter()).toBeDefined();
});
it('should convert a Europe/Paris datetime to utc datetime', () => {
expect(
TimeConverter.toUtcDatetime(
'2023-05-01',
'07:00',
'Europe/Paris',
).getUTCHours(),
).toBe(6);
});
it('should return undefined when trying to convert a Europe/Paris datetime to utc datetime without a valid date, time or timezone', () => {
expect(
TimeConverter.toUtcDatetime(undefined, '07:00', 'Europe/Paris'),
).toBeUndefined();
expect(
TimeConverter.toUtcDatetime('2023-13-01', '07:00', 'Europe/Paris'),
).toBeUndefined();
expect(
TimeConverter.toUtcDatetime('2023-05-01', undefined, 'Europe/Paris'),
).toBeUndefined();
expect(
TimeConverter.toUtcDatetime('2023-05-01', 'a', 'Europe/Paris'),
).toBeUndefined();
expect(
TimeConverter.toUtcDatetime('2023-13-01', '07:00', 'OlympusMons/Mars'),
).toBeUndefined();
});
});

View File

@ -12,6 +12,7 @@ import { DefaultParamsProvider } from '../secondaries/default-params.provider';
import { GeorouterCreator } from '../secondaries/georouter-creator'; import { GeorouterCreator } from '../secondaries/georouter-creator';
import { Match } from '../../domain/entities/ecosystem/match'; import { Match } from '../../domain/entities/ecosystem/match';
import { GeoTimezoneFinder } from '../../../geography/adapters/secondaries/geo-timezone-finder'; import { GeoTimezoneFinder } from '../../../geography/adapters/secondaries/geo-timezone-finder';
import { TimeConverter } from '../secondaries/time-converter';
@UsePipes( @UsePipes(
new RpcValidationPipe({ new RpcValidationPipe({
@ -27,6 +28,7 @@ export class MatcherController {
@InjectMapper() private readonly _mapper: Mapper, @InjectMapper() private readonly _mapper: Mapper,
private readonly georouterCreator: GeorouterCreator, private readonly georouterCreator: GeorouterCreator,
private readonly timezoneFinder: GeoTimezoneFinder, private readonly timezoneFinder: GeoTimezoneFinder,
private readonly timeConverter: TimeConverter,
) {} ) {}
@GrpcMethod('MatcherService', 'Match') @GrpcMethod('MatcherService', 'Match')
@ -38,6 +40,7 @@ export class MatcherController {
this.defaultParamsProvider.getParams(), this.defaultParamsProvider.getParams(),
this.georouterCreator, this.georouterCreator,
this.timezoneFinder, this.timezoneFinder,
this.timeConverter,
), ),
); );
return Promise.resolve({ return Promise.resolve({

View File

@ -7,31 +7,32 @@ service MatcherService {
} }
message MatchRequest { message MatchRequest {
repeated Point waypoints = 1; Mode mode = 1;
string departure = 2; string uuid = 2;
string fromDate = 3; repeated Coordinates waypoints = 3;
Schedule schedule = 4; string departure = 4;
bool driver = 5; string fromDate = 5;
bool passenger = 6; Schedule schedule = 6;
string toDate = 7; bool driver = 7;
int32 marginDuration = 8; bool passenger = 8;
MarginDurations marginDurations = 9; string toDate = 9;
int32 seatsPassenger = 10; int32 marginDuration = 10;
int32 seatsDriver = 11; MarginDurations marginDurations = 11;
bool strict = 12; int32 seatsPassenger = 12;
Algorithm algorithm = 13; int32 seatsDriver = 13;
int32 remoteness = 14; bool strict = 14;
bool useProportion = 15; Algorithm algorithm = 15;
int32 proportion = 16; int32 remoteness = 16;
bool useAzimuth = 17; bool useProportion = 17;
int32 azimuthMargin = 18; int32 proportion = 18;
float maxDetourDistanceRatio = 19; bool useAzimuth = 19;
float maxDetourDurationRatio = 20; int32 azimuthMargin = 20;
repeated int32 exclusions = 21; float maxDetourDistanceRatio = 21;
int32 identifier = 22; float maxDetourDurationRatio = 22;
repeated int32 exclusions = 23;
} }
message Point { message Coordinates {
float lon = 1; float lon = 1;
float lat = 2; float lat = 2;
} }
@ -68,3 +69,9 @@ message Matches {
repeated Match data = 1; repeated Match data = 1;
int32 total = 2; int32 total = 2;
} }
enum Mode {
MATCH = 0;
PUBLISH = 1;
PUBLISH_AND_MATCH = 2;
}

View File

@ -8,9 +8,7 @@ export class DefaultParamsProvider {
getParams = (): IDefaultParams => { getParams = (): IDefaultParams => {
return { return {
DEFAULT_IDENTIFIER: parseInt( DEFAULT_UUID: this.configService.get('DEFAULT_UUID'),
this.configService.get('DEFAULT_IDENTIFIER'),
),
MARGIN_DURATION: parseInt(this.configService.get('MARGIN_DURATION')), MARGIN_DURATION: parseInt(this.configService.get('MARGIN_DURATION')),
VALIDITY_DURATION: parseInt(this.configService.get('VALIDITY_DURATION')), VALIDITY_DURATION: parseInt(this.configService.get('VALIDITY_DURATION')),
DEFAULT_TIMEZONE: this.configService.get('DEFAULT_TIMEZONE'), DEFAULT_TIMEZONE: this.configService.get('DEFAULT_TIMEZONE'),

View File

@ -0,0 +1,21 @@
import { Injectable } from '@nestjs/common';
import { DateTime, TimeZone } from 'timezonecomplete';
import { IConvertTime } from '../../domain/interfaces/time-converter.interface';
@Injectable()
export class TimeConverter implements IConvertTime {
toUtcDate = (date: Date, timezone: string): Date => {
try {
return new Date(
new DateTime(
`${date.getFullYear()}-${date.getMonth()}-${date.getDate()}T${date.getHours()}:${date.getMinutes()}`,
TimeZone.zone(timezone, false),
)
.convert(TimeZone.zone('UTC'))
.toIsoString(),
);
} catch (e) {
return undefined;
}
};
}

View File

@ -15,19 +15,30 @@ import { Schedule } from '../types/schedule.type';
import { MarginDurations } from '../types/margin-durations.type'; import { MarginDurations } from '../types/margin-durations.type';
import { AlgorithmType } from '../types/algorithm.enum'; import { AlgorithmType } from '../types/algorithm.enum';
import { IRequestTime } from '../interfaces/time-request.interface'; import { IRequestTime } from '../interfaces/time-request.interface';
import { IRequestPerson } from '../interfaces/person-request.interface'; import { IRequestAd } from '../interfaces/ad-request.interface';
import { IRequestGeography } from '../interfaces/geography-request.interface'; import { IRequestGeography } from '../interfaces/geography-request.interface';
import { IRequestRequirement } from '../interfaces/requirement-request.interface'; import { IRequestRequirement } from '../interfaces/requirement-request.interface';
import { IRequestAlgorithmSettings } from '../interfaces/algorithm-settings-request.interface'; import { IRequestAlgorithmSettings } from '../interfaces/algorithm-settings-request.interface';
import { Mode } from '../types/mode.enum';
export class MatchRequest export class MatchRequest
implements implements
IRequestTime, IRequestTime,
IRequestPerson, IRequestAd,
IRequestGeography, IRequestGeography,
IRequestRequirement, IRequestRequirement,
IRequestAlgorithmSettings IRequestAlgorithmSettings
{ {
@IsOptional()
@IsString()
@AutoMap()
uuid: string;
@IsOptional()
@IsEnum(Mode)
@AutoMap()
mode: Mode;
@IsArray() @IsArray()
@AutoMap() @AutoMap()
waypoints: Point[]; waypoints: Point[];
@ -138,10 +149,7 @@ export class MatchRequest
@IsOptional() @IsOptional()
@IsArray() @IsArray()
exclusions: number[]; exclusions: string[];
@IsOptional() timezone?: string;
@IsInt()
@AutoMap()
identifier: number;
} }

View File

@ -1,14 +1,14 @@
import { Role } from '../../types/role.enum'; import { Role } from '../../types/role.enum';
import { Step } from '../../types/step.enum'; import { Step } from '../../types/step.enum';
import { Person } from './person'; import { Ad } from './ad';
export class Actor { export class Actor {
person: Person; ad: Ad;
role: Role; role: Role;
step: Step; step: Step;
constructor(person: Person, role: Role, step: Step) { constructor(ad: Ad, role: Role, step: Step) {
this.person = person; this.ad = ad;
this.role = role; this.role = role;
this.step = step; this.step = step;
} }

View File

@ -1,24 +1,24 @@
import { IRequestPerson } from '../../interfaces/person-request.interface'; import { IRequestAd } from '../../interfaces/ad-request.interface';
export class Person { export class Ad {
private personRequest: IRequestPerson; private adRequest: IRequestAd;
private defaultIdentifier: number; private defaultUuid: string;
private defaultMarginDuration: number; private defaultMarginDuration: number;
identifier: number; uuid: string;
marginDurations: number[]; marginDurations: number[];
constructor( constructor(
personRequest: IRequestPerson, adRequest: IRequestAd,
defaultIdentifier: number, defaultUuid: string,
defaultMarginDuration: number, defaultMarginDuration: number,
) { ) {
this.personRequest = personRequest; this.adRequest = adRequest;
this.defaultIdentifier = defaultIdentifier; this.defaultUuid = defaultUuid;
this.defaultMarginDuration = defaultMarginDuration; this.defaultMarginDuration = defaultMarginDuration;
} }
init = (): void => { init = (): void => {
this.setIdentifier(this.personRequest.identifier ?? this.defaultIdentifier); this.setUuid(this.adRequest.uuid ?? this.defaultUuid);
this.setMarginDurations([ this.setMarginDurations([
this.defaultMarginDuration, this.defaultMarginDuration,
this.defaultMarginDuration, this.defaultMarginDuration,
@ -30,8 +30,8 @@ export class Person {
]); ]);
}; };
setIdentifier = (identifier: number): void => { setUuid = (uuid: string): void => {
this.identifier = identifier; this.uuid = uuid;
}; };
setMarginDurations = (marginDurations: number[]): void => { setMarginDurations = (marginDurations: number[]): void => {

View File

@ -10,7 +10,7 @@ import { Role } from '../../types/role.enum';
import { IGeorouter } from '../../interfaces/georouter.interface'; import { IGeorouter } from '../../interfaces/georouter.interface';
import { Waypoint } from './waypoint'; import { Waypoint } from './waypoint';
import { Actor } from './actor'; import { Actor } from './actor';
import { Person } from './person'; import { Ad } from './ad';
import { Step } from '../../types/step.enum'; import { Step } from '../../types/step.enum';
import { Path } from '../../types/path.type'; import { Path } from '../../types/path.type';
import { IFindTimezone } from '../../../../geography/domain/interfaces/timezone-finder.interface'; import { IFindTimezone } from '../../../../geography/domain/interfaces/timezone-finder.interface';
@ -18,7 +18,7 @@ import { Timezoner } from './timezoner';
export class Geography { export class Geography {
private geographyRequest: IRequestGeography; private geographyRequest: IRequestGeography;
private person: Person; private ad: Ad;
private points: Point[]; private points: Point[];
originType: PointType; originType: PointType;
destinationType: PointType; destinationType: PointType;
@ -30,10 +30,10 @@ export class Geography {
constructor( constructor(
geographyRequest: IRequestGeography, geographyRequest: IRequestGeography,
timezoner: Timezoner, timezoner: Timezoner,
person: Person, ad: Ad,
) { ) {
this.geographyRequest = geographyRequest; this.geographyRequest = geographyRequest;
this.person = person; this.ad = ad;
this.points = []; this.points = [];
this.originType = undefined; this.originType = undefined;
this.destinationType = undefined; this.destinationType = undefined;
@ -178,11 +178,11 @@ export class Geography {
return points.map((point, index) => { return points.map((point, index) => {
const waypoint = new Waypoint(point); const waypoint = new Waypoint(point);
if (index == 0) { if (index == 0) {
waypoint.addActor(new Actor(this.person, role, Step.START)); waypoint.addActor(new Actor(this.ad, role, Step.START));
} else if (index == points.length - 1) { } else if (index == points.length - 1) {
waypoint.addActor(new Actor(this.person, role, Step.FINISH)); waypoint.addActor(new Actor(this.ad, role, Step.FINISH));
} else { } else {
waypoint.addActor(new Actor(this.person, role, Step.INTERMEDIATE)); waypoint.addActor(new Actor(this.ad, role, Step.INTERMEDIATE));
} }
return waypoint; return waypoint;
}); });

View File

@ -5,26 +5,30 @@ import {
import { MarginDurations } from '../../types/margin-durations.type'; import { MarginDurations } from '../../types/margin-durations.type';
import { IRequestTime } from '../../interfaces/time-request.interface'; import { IRequestTime } from '../../interfaces/time-request.interface';
import { DAYS } from '../../types/days.const'; import { DAYS } from '../../types/days.const';
import { Schedule } from '../../types/schedule.type'; import { TimeSchedule } from '../../types/time-schedule.type';
import { Frequency } from '../../../../ad/domain/types/frequency.enum'; import { Frequency } from '../../../../ad/domain/types/frequency.enum';
import { Day } from '../../types/day.type'; import { Day } from '../../types/day.type';
import { IConvertTime } from '../../interfaces/time-converter.interface';
export class Time { export class Time {
private timeRequest: IRequestTime; private timeRequest: IRequestTime;
private defaultValidityDuration: number; private defaultValidityDuration: number;
private timeConverter: IConvertTime;
frequency: Frequency; frequency: Frequency;
fromDate: Date; fromDate: Date;
toDate: Date; toDate: Date;
schedule: Schedule; schedule: TimeSchedule;
marginDurations: MarginDurations; marginDurations: MarginDurations;
constructor( constructor(
timeRequest: IRequestTime, timeRequest: IRequestTime,
defaultMarginDuration: number, defaultMarginDuration: number,
defaultValidityDuration: number, defaultValidityDuration: number,
timeConverter: IConvertTime,
) { ) {
this.timeRequest = timeRequest; this.timeRequest = timeRequest;
this.defaultValidityDuration = defaultValidityDuration; this.defaultValidityDuration = defaultValidityDuration;
this.timeConverter = timeConverter;
this.schedule = {}; this.schedule = {};
this.marginDurations = { this.marginDurations = {
mon: defaultMarginDuration, mon: defaultMarginDuration,
@ -128,8 +132,10 @@ export class Time {
private setPunctualRequest = (): void => { private setPunctualRequest = (): void => {
if (this.timeRequest.departure) { if (this.timeRequest.departure) {
this.frequency = Frequency.PUNCTUAL; this.frequency = Frequency.PUNCTUAL;
this.schedule[Day[this.fromDate.getDay()]] = this.schedule[Day[this.fromDate.getDay()]] = this.timeConverter.toUtcDate(
this.fromDate.getHours() + ':' + this.fromDate.getMinutes(); this.fromDate,
this.timeRequest.timezone,
);
} }
}; };

View File

@ -1,5 +1,5 @@
import { Person } from '../ecosystem/person'; import { Ad } from '../ecosystem/ad';
export class Candidate { export class Candidate {
person: Person; ad: Ad;
} }

View File

@ -0,0 +1,3 @@
export interface IRequestAd {
uuid?: string;
}

View File

@ -1,3 +0,0 @@
export interface IRequestPerson {
identifier?: number;
}

View File

@ -0,0 +1,3 @@
export interface IConvertTime {
toUtcDate(date: Date, timezone: string): Date;
}

View File

@ -8,4 +8,5 @@ export interface IRequestTime {
schedule?: Schedule; schedule?: Schedule;
marginDuration?: number; marginDuration?: number;
marginDurations?: MarginDurations; marginDurations?: MarginDurations;
timezone?: string;
} }

View File

@ -1,9 +1,9 @@
import { Person } from '../entities/ecosystem/person'; import { Ad } from '../entities/ecosystem/ad';
import { Role } from './role.enum'; import { Role } from './role.enum';
import { Step } from './step.enum'; import { Step } from './step.enum';
export type Actor = { export type Actor = {
person: Person; ad: Ad;
role: Role; role: Role;
step: Step; step: Step;
}; };

View File

@ -1,7 +1,7 @@
import { DefaultAlgorithmSettings } from './default-algorithm-settings.type'; import { DefaultAlgorithmSettings } from './default-algorithm-settings.type';
export type IDefaultParams = { export type IDefaultParams = {
DEFAULT_IDENTIFIER: number; DEFAULT_UUID: string;
MARGIN_DURATION: number; MARGIN_DURATION: number;
VALIDITY_DURATION: number; VALIDITY_DURATION: number;
DEFAULT_TIMEZONE: string; DEFAULT_TIMEZONE: string;

View File

@ -0,0 +1,5 @@
export enum Mode {
MATCH = 'MATCH',
PUBLISH = 'PUBLISH',
PUBLISH_AND_MATCH = 'PUBLISH_AND_MATCH',
}

View File

@ -0,0 +1,9 @@
export type TimeSchedule = {
mon?: Date;
tue?: Date;
wed?: Date;
thu?: Date;
fri?: Date;
sat?: Date;
sun?: Date;
};

View File

@ -1,6 +1,6 @@
import { MatchRequest } from '../domain/dtos/match.request'; import { MatchRequest } from '../domain/dtos/match.request';
import { Geography } from '../domain/entities/ecosystem/geography'; import { Geography } from '../domain/entities/ecosystem/geography';
import { Person } from '../domain/entities/ecosystem/person'; import { Ad } from '../domain/entities/ecosystem/ad';
import { Requirement } from '../domain/entities/ecosystem/requirement'; import { Requirement } from '../domain/entities/ecosystem/requirement';
import { Role } from '../domain/types/role.enum'; import { Role } from '../domain/types/role.enum';
import { AlgorithmSettings } from '../domain/entities/ecosystem/algorithm-settings'; import { AlgorithmSettings } from '../domain/entities/ecosystem/algorithm-settings';
@ -9,35 +9,42 @@ import { IDefaultParams } from '../domain/types/default-params.type';
import { IGeorouter } from '../domain/interfaces/georouter.interface'; import { IGeorouter } from '../domain/interfaces/georouter.interface';
import { ICreateGeorouter } from '../domain/interfaces/georouter-creator.interface'; import { ICreateGeorouter } from '../domain/interfaces/georouter-creator.interface';
import { IFindTimezone } from '../../geography/domain/interfaces/timezone-finder.interface'; import { IFindTimezone } from '../../geography/domain/interfaces/timezone-finder.interface';
import { Mode } from '../domain/types/mode.enum';
import { IConvertTime } from '../domain/interfaces/time-converter.interface';
export class MatchQuery { export class MatchQuery {
private readonly matchRequest: MatchRequest; private readonly matchRequest: MatchRequest;
private readonly defaultParams: IDefaultParams; private readonly defaultParams: IDefaultParams;
private readonly georouterCreator: ICreateGeorouter; private readonly georouterCreator: ICreateGeorouter;
person: Person; mode: Mode;
ad: Ad;
roles: Role[]; roles: Role[];
time: Time; time: Time;
geography: Geography; geography: Geography;
exclusions: number[]; exclusions: string[];
requirement: Requirement; requirement: Requirement;
algorithmSettings: AlgorithmSettings; algorithmSettings: AlgorithmSettings;
georouter: IGeorouter; georouter: IGeorouter;
timezoneFinder: IFindTimezone; timezoneFinder: IFindTimezone;
timeConverter: IConvertTime;
constructor( constructor(
matchRequest: MatchRequest, matchRequest: MatchRequest,
defaultParams: IDefaultParams, defaultParams: IDefaultParams,
georouterCreator: ICreateGeorouter, georouterCreator: ICreateGeorouter,
timezoneFinder: IFindTimezone, timezoneFinder: IFindTimezone,
timeConverter: IConvertTime,
) { ) {
this.matchRequest = matchRequest; this.matchRequest = matchRequest;
this.defaultParams = defaultParams; this.defaultParams = defaultParams;
this.georouterCreator = georouterCreator; this.georouterCreator = georouterCreator;
this.timezoneFinder = timezoneFinder; this.timezoneFinder = timezoneFinder;
this.setPerson(); this.timeConverter = timeConverter;
this.setMode();
this.setAd();
this.setRoles(); this.setRoles();
this.setTime();
this.setGeography(); this.setGeography();
this.setTime();
this.setRequirement(); this.setRequirement();
this.setAlgorithmSettings(); this.setAlgorithmSettings();
this.setExclusions(); this.setExclusions();
@ -47,13 +54,17 @@ export class MatchQuery {
this.geography.createRoutes(this.roles, this.algorithmSettings.georouter); this.geography.createRoutes(this.roles, this.algorithmSettings.georouter);
}; };
private setPerson = (): void => { private setMode = (): void => {
this.person = new Person( this.mode = this.matchRequest.mode ?? Mode.MATCH;
};
private setAd = (): void => {
this.ad = new Ad(
this.matchRequest, this.matchRequest,
this.defaultParams.DEFAULT_IDENTIFIER, this.defaultParams.DEFAULT_UUID,
this.defaultParams.MARGIN_DURATION, this.defaultParams.MARGIN_DURATION,
); );
this.person.init(); this.ad.init();
}; };
private setRoles = (): void => { private setRoles = (): void => {
@ -63,15 +74,6 @@ export class MatchQuery {
if (this.roles.length == 0) this.roles.push(Role.PASSENGER); if (this.roles.length == 0) this.roles.push(Role.PASSENGER);
}; };
private setTime = (): void => {
this.time = new Time(
this.matchRequest,
this.defaultParams.MARGIN_DURATION,
this.defaultParams.VALIDITY_DURATION,
);
this.time.init();
};
private setGeography = (): void => { private setGeography = (): void => {
this.geography = new Geography( this.geography = new Geography(
this.matchRequest, this.matchRequest,
@ -79,9 +81,20 @@ export class MatchQuery {
timezone: this.defaultParams.DEFAULT_TIMEZONE, timezone: this.defaultParams.DEFAULT_TIMEZONE,
finder: this.timezoneFinder, finder: this.timezoneFinder,
}, },
this.person, this.ad,
); );
this.geography.init(); this.geography.init();
if (this.geography.timezones.length > 0)
this.matchRequest.timezone = this.geography.timezones[0];
};
private setTime = (): void => {
this.time = new Time(
this.matchRequest,
this.defaultParams.MARGIN_DURATION,
this.defaultParams.VALIDITY_DURATION,
);
this.time.init();
}; };
private setRequirement = (): void => { private setRequirement = (): void => {
@ -102,8 +115,7 @@ export class MatchQuery {
private setExclusions = (): void => { private setExclusions = (): void => {
this.exclusions = []; this.exclusions = [];
if (this.matchRequest.identifier) if (this.matchRequest.uuid) this.exclusions.push(this.matchRequest.uuid);
this.exclusions.push(this.matchRequest.identifier);
if (this.matchRequest.exclusions) if (this.matchRequest.exclusions)
this.exclusions.push(...this.matchRequest.exclusions); this.exclusions.push(...this.matchRequest.exclusions);
}; };

View File

@ -33,6 +33,6 @@ describe('DefaultParamsProvider', () => {
it('should provide default params', async () => { it('should provide default params', async () => {
const params: IDefaultParams = defaultParamsProvider.getParams(); const params: IDefaultParams = defaultParamsProvider.getParams();
expect(params.DEFAULT_IDENTIFIER).toBe(99); expect(params.DEFAULT_UUID).toBe(99);
}); });
}); });

View File

@ -1,4 +1,4 @@
import { Person } from '../../../../domain/entities/ecosystem/person'; import { Ad } from '../../../../domain/entities/ecosystem/ad';
import { import {
Geography, Geography,
RouteKey, RouteKey,
@ -9,11 +9,11 @@ import { Route } from '../../../../domain/entities/ecosystem/route';
import { IGeodesic } from '../../../../../geography/domain/interfaces/geodesic.interface'; import { IGeodesic } from '../../../../../geography/domain/interfaces/geodesic.interface';
import { PointType } from '../../../../../geography/domain/types/point-type.enum'; import { PointType } from '../../../../../geography/domain/types/point-type.enum';
const person: Person = new Person( const ad: Ad = new Ad(
{ {
identifier: 1, uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc',
}, },
0, '00000000-0000-0000-0000-000000000000',
900, 900,
); );
@ -88,7 +88,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
expect(geography).toBeDefined(); expect(geography).toBeDefined();
}); });
@ -114,7 +114,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
geography.init(); geography.init();
expect(geography.originType).toBe(PointType.LOCALITY); expect(geography.originType).toBe(PointType.LOCALITY);
@ -129,7 +129,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
expect(() => geography.init()).toThrow(); expect(() => geography.init()).toThrow();
}); });
@ -147,7 +147,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
expect(() => geography.init()).toThrow(); expect(() => geography.init()).toThrow();
}); });
@ -169,7 +169,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
expect(() => geography.init()).toThrow(); expect(() => geography.init()).toThrow();
}); });
@ -191,7 +191,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
expect(() => geography.init()).toThrow(); expect(() => geography.init()).toThrow();
}); });
@ -216,7 +216,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
geography.init(); geography.init();
await geography.createRoutes( await geography.createRoutes(
@ -249,7 +249,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
geography.init(); geography.init();
await geography.createRoutes( await geography.createRoutes(
@ -278,7 +278,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
geography.init(); geography.init();
await geography.createRoutes([Role.DRIVER], mockGeorouter); await geography.createRoutes([Role.DRIVER], mockGeorouter);
@ -304,7 +304,7 @@ describe('Geography entity', () => {
timezone: 'Europe/Paris', timezone: 'Europe/Paris',
finder: mockTimezoneFinder, finder: mockTimezoneFinder,
}, },
person, ad,
); );
geography.init(); geography.init();
await geography.createRoutes([Role.PASSENGER], mockGeorouter); await geography.createRoutes([Role.PASSENGER], mockGeorouter);

View File

@ -1,40 +1,40 @@
import { Person } from '../../../../domain/entities/ecosystem/person'; import { Ad } from '../../../../domain/entities/ecosystem/ad';
const DEFAULT_IDENTIFIER = 0; const DEFAULT_UUID = '00000000-0000-0000-0000-000000000000';
const MARGIN_DURATION = 900; const MARGIN_DURATION = 900;
describe('Person entity', () => { describe('Ad entity', () => {
it('should be defined', () => { it('should be defined', () => {
const person = new Person( const ad = new Ad(
{ {
identifier: 1, uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc',
}, },
DEFAULT_IDENTIFIER, DEFAULT_UUID,
MARGIN_DURATION, MARGIN_DURATION,
); );
expect(person).toBeDefined(); expect(ad).toBeDefined();
}); });
describe('init', () => { describe('init', () => {
it('should initialize a person with an identifier', () => { it('should initialize an ad with a uuid', () => {
const person = new Person( const ad = new Ad(
{ {
identifier: 1, uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc',
}, },
DEFAULT_IDENTIFIER, DEFAULT_UUID,
MARGIN_DURATION, MARGIN_DURATION,
); );
person.init(); ad.init();
expect(person.identifier).toBe(1); expect(ad.uuid).toBe('774aaab2-77df-4c6c-b70d-7b9e972e5bbc');
expect(person.marginDurations[0]).toBe(900); expect(ad.marginDurations[0]).toBe(900);
expect(person.marginDurations[6]).toBe(900); expect(ad.marginDurations[6]).toBe(900);
}); });
it('should initialize a person without an identifier', () => { it('should initialize an ad without a uuid', () => {
const person = new Person({}, DEFAULT_IDENTIFIER, MARGIN_DURATION); const ad = new Ad({}, DEFAULT_UUID, MARGIN_DURATION);
person.init(); ad.init();
expect(person.identifier).toBe(0); expect(ad.uuid).toBe('00000000-0000-0000-0000-000000000000');
expect(person.marginDurations[0]).toBe(900); expect(ad.marginDurations[0]).toBe(900);
expect(person.marginDurations[6]).toBe(900); expect(ad.marginDurations[6]).toBe(900);
}); });
}); });
}); });

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -16,7 +16,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -26,7 +26,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -14,7 +14,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -39,7 +39,7 @@ const mockTimezoneFinder = {
}; };
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',

View File

@ -4,9 +4,10 @@ import { IDefaultParams } from '../../../domain/types/default-params.type';
import { MatchQuery } from '../../../queries/match.query'; import { MatchQuery } from '../../../queries/match.query';
import { AlgorithmType } from '../../../domain/types/algorithm.enum'; import { AlgorithmType } from '../../../domain/types/algorithm.enum';
import { Frequency } from '../../../../ad/domain/types/frequency.enum'; import { Frequency } from '../../../../ad/domain/types/frequency.enum';
import { Mode } from '../../../domain/types/mode.enum';
const defaultParams: IDefaultParams = { const defaultParams: IDefaultParams = {
DEFAULT_IDENTIFIER: 0, DEFAULT_UUID: '00000000-0000-0000-0000-000000000000',
MARGIN_DURATION: 900, MARGIN_DURATION: 900,
VALIDITY_DURATION: 365, VALIDITY_DURATION: 365,
DEFAULT_TIMEZONE: 'Europe/Paris', DEFAULT_TIMEZONE: 'Europe/Paris',
@ -55,6 +56,30 @@ describe('Match query', () => {
mockTimezoneFinder, mockTimezoneFinder,
); );
expect(matchQuery).toBeDefined(); expect(matchQuery).toBeDefined();
expect(matchQuery.mode).toBe(Mode.MATCH);
});
it('should create a query with publish and match mode', () => {
const matchRequest: MatchRequest = new MatchRequest();
matchRequest.departure = '2023-04-01 12:00';
matchRequest.waypoints = [
{
lat: 49.440041,
lon: 1.093912,
},
{
lat: 50.630992,
lon: 3.045432,
},
];
matchRequest.mode = Mode.PUBLISH_AND_MATCH;
const matchQuery: MatchQuery = new MatchQuery(
matchRequest,
defaultParams,
mockGeorouterCreator,
mockTimezoneFinder,
);
expect(matchQuery.mode).toBe(Mode.PUBLISH_AND_MATCH);
}); });
it('should create a query with excluded identifiers', () => { it('should create a query with excluded identifiers', () => {
@ -70,8 +95,12 @@ describe('Match query', () => {
lon: 3.045432, lon: 3.045432,
}, },
]; ];
matchRequest.identifier = 125; matchRequest.uuid = '445aa6e4-99e4-4899-9456-3be8c3ada368';
matchRequest.exclusions = [126, 127, 128]; matchRequest.exclusions = [
'eacf5e53-e63c-4551-860c-73f95b8a8895',
'a4098161-13a9-4e55-8999-de134fbf89c4',
'b18f7ffa-20b9-4a1a-89bc-e238ea8289f3',
];
const matchQuery: MatchQuery = new MatchQuery( const matchQuery: MatchQuery = new MatchQuery(
matchRequest, matchRequest,
defaultParams, defaultParams,