upgrade tests

This commit is contained in:
sbriat 2023-08-31 11:09:56 +02:00
parent cde1760099
commit 657f8e7a03
5 changed files with 273 additions and 29 deletions

View File

@ -5,10 +5,15 @@ import { PassengerOrientedAlgorithm } from './passenger-oriented-algorithm';
import { AlgorithmType } from '../../types/algorithm.types'; import { AlgorithmType } from '../../types/algorithm.types';
import { Inject } from '@nestjs/common'; import { Inject } from '@nestjs/common';
import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port'; import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
import { AD_REPOSITORY, PARAMS_PROVIDER } from '@modules/ad/ad.di-tokens'; import {
AD_REPOSITORY,
INPUT_DATETIME_TRANSFORMER,
PARAMS_PROVIDER,
} from '@modules/ad/ad.di-tokens';
import { MatchEntity } from '@modules/ad/core/domain/match.entity'; import { MatchEntity } from '@modules/ad/core/domain/match.entity';
import { DefaultParamsProviderPort } from '../../ports/default-params-provider.port'; import { DefaultParamsProviderPort } from '../../ports/default-params-provider.port';
import { DefaultParams } from '../../ports/default-params.type'; import { DefaultParams } from '../../ports/default-params.type';
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
@QueryHandler(MatchQuery) @QueryHandler(MatchQuery)
export class MatchQueryHandler implements IQueryHandler { export class MatchQueryHandler implements IQueryHandler {
@ -18,6 +23,8 @@ export class MatchQueryHandler implements IQueryHandler {
@Inject(PARAMS_PROVIDER) @Inject(PARAMS_PROVIDER)
private readonly defaultParamsProvider: DefaultParamsProviderPort, private readonly defaultParamsProvider: DefaultParamsProviderPort,
@Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort, @Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort,
@Inject(INPUT_DATETIME_TRANSFORMER)
private readonly datetimeTransformer: DateTimeTransformerPort,
) { ) {
this._defaultParams = defaultParamsProvider.getParams(); this._defaultParams = defaultParamsProvider.getParams();
} }
@ -34,14 +41,17 @@ export class MatchQueryHandler implements IQueryHandler {
}) })
.setDefaultAlgorithmParameters({ .setDefaultAlgorithmParameters({
algorithmType: this._defaultParams.ALGORITHM_TYPE, algorithmType: this._defaultParams.ALGORITHM_TYPE,
remoteness: 0, remoteness: this._defaultParams.REMOTENESS,
useProportion: false, useProportion: this._defaultParams.USE_PROPORTION,
proportion: 0, proportion: this._defaultParams.PROPORTION,
useAzimuth: false, useAzimuth: this._defaultParams.USE_AZIMUTH,
azimuthMargin: 0, azimuthMargin: this._defaultParams.AZIMUTH_MARGIN,
maxDetourDistanceRatio: 0, maxDetourDistanceRatio: this._defaultParams.MAX_DETOUR_DISTANCE_RATIO,
maxDetourDurationRatio: 0, maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO,
}); })
.setDatesAndSchedule(this.datetimeTransformer);
console.log(query);
let algorithm: Algorithm; let algorithm: Algorithm;
switch (query.algorithmType) { switch (query.algorithmType) {

View File

@ -3,13 +3,14 @@ import { AlgorithmType } from '../../types/algorithm.types';
import { Waypoint } from '../../types/waypoint.type'; import { Waypoint } from '../../types/waypoint.type';
import { Frequency } from '@modules/ad/core/domain/ad.types'; import { Frequency } from '@modules/ad/core/domain/ad.types';
import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto'; import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto';
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
export class MatchQuery extends QueryBase { export class MatchQuery extends QueryBase {
driver?: boolean; driver?: boolean;
passenger?: boolean; passenger?: boolean;
readonly frequency: Frequency; readonly frequency: Frequency;
readonly fromDate: string; fromDate: string;
readonly toDate: string; toDate: string;
schedule: ScheduleItem[]; schedule: ScheduleItem[];
seatsProposed?: number; seatsProposed?: number;
seatsRequested?: number; seatsRequested?: number;
@ -104,6 +105,61 @@ export class MatchQuery extends QueryBase {
defaultAlgorithmParameters.maxDetourDurationRatio; defaultAlgorithmParameters.maxDetourDurationRatio;
return this; return this;
}; };
setDatesAndSchedule = (
datetimeTransformer: DateTimeTransformerPort,
): MatchQuery => {
this.fromDate = datetimeTransformer.fromDate(
{
date: this.fromDate,
time: this.schedule[0].time,
coordinates: {
lon: this.waypoints[0].lon,
lat: this.waypoints[0].lat,
},
},
this.frequency,
);
this.toDate = datetimeTransformer.toDate(
this.toDate,
{
date: this.fromDate,
time: this.schedule[0].time,
coordinates: {
lon: this.waypoints[0].lon,
lat: this.waypoints[0].lat,
},
},
this.frequency,
);
this.schedule = this.schedule.map((scheduleItem: ScheduleItem) => ({
day: datetimeTransformer.day(
scheduleItem.day ?? new Date(this.fromDate).getDay(),
{
date: this.fromDate,
time: scheduleItem.time,
coordinates: {
lon: this.waypoints[0].lon,
lat: this.waypoints[0].lat,
},
},
this.frequency,
),
time: datetimeTransformer.time(
{
date: this.fromDate,
time: scheduleItem.time,
coordinates: {
lon: this.waypoints[0].lon,
lat: this.waypoints[0].lat,
},
},
this.frequency,
),
margin: scheduleItem.margin,
}));
return this;
};
} }
type ScheduleItem = { type ScheduleItem = {

View File

@ -1,4 +1,9 @@
import { AD_REPOSITORY, PARAMS_PROVIDER } from '@modules/ad/ad.di-tokens'; import {
AD_REPOSITORY,
INPUT_DATETIME_TRANSFORMER,
PARAMS_PROVIDER,
} from '@modules/ad/ad.di-tokens';
import { DateTimeTransformerPort } from '@modules/ad/core/application/ports/datetime-transformer.port';
import { DefaultParamsProviderPort } from '@modules/ad/core/application/ports/default-params-provider.port'; import { DefaultParamsProviderPort } from '@modules/ad/core/application/ports/default-params-provider.port';
import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query'; import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query';
import { MatchQueryHandler } from '@modules/ad/core/application/queries/match/match.query-handler'; import { MatchQueryHandler } from '@modules/ad/core/application/queries/match/match.query-handler';
@ -60,6 +65,13 @@ const mockDefaultParamsProvider: DefaultParamsProviderPort = {
}, },
}; };
const mockInputDateTimeTransformer: DateTimeTransformerPort = {
fromDate: jest.fn(),
toDate: jest.fn(),
day: jest.fn(),
time: jest.fn(),
};
describe('Match Query Handler', () => { describe('Match Query Handler', () => {
let matchQueryHandler: MatchQueryHandler; let matchQueryHandler: MatchQueryHandler;
@ -75,6 +87,10 @@ describe('Match Query Handler', () => {
provide: PARAMS_PROVIDER, provide: PARAMS_PROVIDER,
useValue: mockDefaultParamsProvider, useValue: mockDefaultParamsProvider,
}, },
{
provide: INPUT_DATETIME_TRANSFORMER,
useValue: mockInputDateTimeTransformer,
},
], ],
}).compile(); }).compile();

View File

@ -0,0 +1,127 @@
import { DateTimeTransformerPort } from '@modules/ad/core/application/ports/datetime-transformer.port';
import { DefaultParams } from '@modules/ad/core/application/ports/default-params.type';
import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query';
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
import { Frequency } from '@modules/ad/core/domain/ad.types';
const originWaypoint: Waypoint = {
position: 0,
lat: 48.689445,
lon: 6.17651,
houseNumber: '5',
street: 'Avenue Foch',
locality: 'Nancy',
postalCode: '54000',
country: 'France',
};
const destinationWaypoint: Waypoint = {
position: 1,
lat: 48.8566,
lon: 2.3522,
locality: 'Paris',
postalCode: '75000',
country: 'France',
};
const defaultParams: DefaultParams = {
DEPARTURE_TIME_MARGIN: 900,
DRIVER: false,
SEATS_PROPOSED: 3,
PASSENGER: true,
SEATS_REQUESTED: 1,
STRICT: false,
TIMEZONE: 'Europe/Paris',
ALGORITHM_TYPE: AlgorithmType.PASSENGER_ORIENTED,
REMOTENESS: 15000,
USE_PROPORTION: true,
PROPORTION: 0.3,
USE_AZIMUTH: true,
AZIMUTH_MARGIN: 10,
MAX_DETOUR_DISTANCE_RATIO: 0.3,
MAX_DETOUR_DURATION_RATIO: 0.3,
};
const mockInputDateTimeTransformer: DateTimeTransformerPort = {
fromDate: jest.fn().mockImplementation(() => '2023-08-27'),
toDate: jest.fn().mockImplementation(() => '2023-08-27'),
day: jest.fn().mockImplementation(() => 0),
time: jest.fn().mockImplementation(() => '23:05'),
};
describe('Match Query', () => {
it('should set default values', async () => {
const matchQuery = new MatchQuery({
frequency: Frequency.PUNCTUAL,
fromDate: '2023-08-28',
toDate: '2023-08-28',
schedule: [
{
time: '01:05',
},
],
waypoints: [originWaypoint, destinationWaypoint],
});
matchQuery
.setMissingMarginDurations(defaultParams.DEPARTURE_TIME_MARGIN)
.setMissingStrict(defaultParams.STRICT)
.setDefaultDriverAndPassengerParameters({
driver: defaultParams.DRIVER,
passenger: defaultParams.PASSENGER,
seatsProposed: defaultParams.SEATS_PROPOSED,
seatsRequested: defaultParams.SEATS_REQUESTED,
})
.setDefaultAlgorithmParameters({
algorithmType: defaultParams.ALGORITHM_TYPE,
remoteness: defaultParams.REMOTENESS,
useProportion: defaultParams.USE_PROPORTION,
proportion: defaultParams.PROPORTION,
useAzimuth: defaultParams.USE_AZIMUTH,
azimuthMargin: defaultParams.AZIMUTH_MARGIN,
maxDetourDistanceRatio: defaultParams.MAX_DETOUR_DISTANCE_RATIO,
maxDetourDurationRatio: defaultParams.MAX_DETOUR_DURATION_RATIO,
})
.setDatesAndSchedule(mockInputDateTimeTransformer);
expect(matchQuery.strict).toBeFalsy();
expect(matchQuery.driver).toBeFalsy();
expect(matchQuery.seatsProposed).toBe(3);
expect(matchQuery.seatsRequested).toBe(1);
expect(matchQuery.algorithmType).toBe(AlgorithmType.PASSENGER_ORIENTED);
expect(matchQuery.remoteness).toBe(15000);
expect(matchQuery.useProportion).toBeTruthy();
expect(matchQuery.proportion).toBe(0.3);
expect(matchQuery.useAzimuth).toBeTruthy();
expect(matchQuery.azimuthMargin).toBe(10);
expect(matchQuery.maxDetourDistanceRatio).toBe(0.3);
expect(matchQuery.maxDetourDurationRatio).toBe(0.3);
expect(matchQuery.fromDate).toBe('2023-08-27');
expect(matchQuery.toDate).toBe('2023-08-27');
expect(matchQuery.schedule[0].day).toBe(0);
expect(matchQuery.schedule[0].time).toBe('23:05');
expect(matchQuery.schedule[0].margin).toBe(900);
});
it('should set good values for seats', async () => {
const matchQuery = new MatchQuery({
frequency: Frequency.PUNCTUAL,
fromDate: '2023-08-28',
toDate: '2023-08-28',
seatsProposed: -1,
seatsRequested: -1,
schedule: [
{
time: '07:05',
},
],
waypoints: [originWaypoint, destinationWaypoint],
});
matchQuery.setDefaultDriverAndPassengerParameters({
driver: defaultParams.DRIVER,
passenger: defaultParams.PASSENGER,
seatsProposed: defaultParams.SEATS_PROPOSED,
seatsRequested: defaultParams.SEATS_REQUESTED,
});
expect(matchQuery.seatsProposed).toBe(3);
expect(matchQuery.seatsRequested).toBe(1);
});
});

View File

@ -3,15 +3,15 @@ import { DefaultParamsProvider } from '@modules/ad/infrastructure/default-params
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
const mockConfigService = { const mockConfigServiceWithDefaults = {
get: jest.fn().mockImplementation((value: string) => { get: jest.fn().mockImplementation((value: string) => {
switch (value) { switch (value) {
case 'DEPARTURE_TIME_MARGIN': case 'DEPARTURE_TIME_MARGIN':
return 900; return 600;
case 'ROLE': case 'ROLE':
return 'passenger'; return 'passenger';
case 'SEATS_PROPOSED': case 'SEATS_PROPOSED':
return 3; return 2;
case 'SEATS_REQUESTED': case 'SEATS_REQUESTED':
return 1; return 1;
case 'STRICT_FREQUENCY': case 'STRICT_FREQUENCY':
@ -21,51 +21,86 @@ const mockConfigService = {
case 'ALGORITHM_TYPE': case 'ALGORITHM_TYPE':
return 'PASSENGER_ORIENTED'; return 'PASSENGER_ORIENTED';
case 'REMOTENESS': case 'REMOTENESS':
return 15000; return 10000;
case 'USE_PROPORTION': case 'USE_PROPORTION':
return 'true'; return 'true';
case 'PROPORTION': case 'PROPORTION':
return 0.3; return 0.4;
case 'USE_AZIMUTH': case 'USE_AZIMUTH':
return 'true'; return 'true';
case 'AZIMUTH_MARGIN': case 'AZIMUTH_MARGIN':
return 10; return 15;
case 'MAX_DETOUR_DISTANCE_RATIO': case 'MAX_DETOUR_DISTANCE_RATIO':
return 0.3; return 0.5;
case 'MAX_DETOUR_DURATION_RATIO': case 'MAX_DETOUR_DURATION_RATIO':
return 0.3; return 0.6;
default: default:
return 'some_default_value'; return 'some_default_value';
} }
}), }),
}; };
const mockConfigServiceWithoutDefaults = {
get: jest.fn(),
};
describe('DefaultParamsProvider', () => { describe('DefaultParamsProvider', () => {
let defaultParamsProvider: DefaultParamsProvider; let defaultParamsProviderWithDefaults: DefaultParamsProvider;
let defaultParamsProviderWithoutDefaults: DefaultParamsProvider;
beforeAll(async () => { beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({ const moduleWithDefaults: TestingModule = await Test.createTestingModule({
imports: [], imports: [],
providers: [ providers: [
DefaultParamsProvider, DefaultParamsProvider,
{ {
provide: ConfigService, provide: ConfigService,
useValue: mockConfigService, useValue: mockConfigServiceWithDefaults,
}, },
], ],
}).compile(); }).compile();
defaultParamsProvider = module.get<DefaultParamsProvider>( defaultParamsProviderWithDefaults =
DefaultParamsProvider, moduleWithDefaults.get<DefaultParamsProvider>(DefaultParamsProvider);
);
const moduleWithoutDefault: TestingModule = await Test.createTestingModule({
imports: [],
providers: [
DefaultParamsProvider,
{
provide: ConfigService,
useValue: mockConfigServiceWithoutDefaults,
},
],
}).compile();
defaultParamsProviderWithoutDefaults =
moduleWithoutDefault.get<DefaultParamsProvider>(DefaultParamsProvider);
}); });
it('should be defined', () => { it('should be defined', () => {
expect(defaultParamsProvider).toBeDefined(); expect(defaultParamsProviderWithDefaults).toBeDefined();
}); });
it('should provide default params', async () => { it('should provide default params if defaults are set', async () => {
const params: DefaultParams = defaultParamsProvider.getParams(); const params: DefaultParams = defaultParamsProviderWithDefaults.getParams();
expect(params.DEPARTURE_TIME_MARGIN).toBe(600);
expect(params.PASSENGER).toBeTruthy();
expect(params.DRIVER).toBeFalsy();
expect(params.TIMEZONE).toBe('Europe/Paris');
expect(params.ALGORITHM_TYPE).toBe('PASSENGER_ORIENTED');
expect(params.REMOTENESS).toBe(10000);
expect(params.USE_PROPORTION).toBeTruthy();
expect(params.PROPORTION).toBe(0.4);
expect(params.USE_AZIMUTH).toBeTruthy();
expect(params.AZIMUTH_MARGIN).toBe(15);
expect(params.MAX_DETOUR_DISTANCE_RATIO).toBe(0.5);
expect(params.MAX_DETOUR_DURATION_RATIO).toBe(0.6);
});
it('should provide default params if defaults are not set', async () => {
const params: DefaultParams =
defaultParamsProviderWithoutDefaults.getParams();
expect(params.DEPARTURE_TIME_MARGIN).toBe(900); expect(params.DEPARTURE_TIME_MARGIN).toBe(900);
expect(params.PASSENGER).toBeTruthy(); expect(params.PASSENGER).toBeTruthy();
expect(params.DRIVER).toBeFalsy(); expect(params.DRIVER).toBeFalsy();