From 657f8e7a032624ff9addde6bb41a7595c3b0205f Mon Sep 17 00:00:00 2001 From: sbriat Date: Thu, 31 Aug 2023 11:09:56 +0200 Subject: [PATCH] upgrade tests --- .../queries/match/match.query-handler.ts | 28 ++-- .../application/queries/match/match.query.ts | 60 ++++++++- .../unit/core/match.query-handler.spec.ts | 18 ++- .../ad/tests/unit/core/match.query.spec.ts | 127 ++++++++++++++++++ .../default-param.provider.spec.ts | 69 +++++++--- 5 files changed, 273 insertions(+), 29 deletions(-) create mode 100644 src/modules/ad/tests/unit/core/match.query.spec.ts diff --git a/src/modules/ad/core/application/queries/match/match.query-handler.ts b/src/modules/ad/core/application/queries/match/match.query-handler.ts index a0fe915..23cac57 100644 --- a/src/modules/ad/core/application/queries/match/match.query-handler.ts +++ b/src/modules/ad/core/application/queries/match/match.query-handler.ts @@ -5,10 +5,15 @@ import { PassengerOrientedAlgorithm } from './passenger-oriented-algorithm'; import { AlgorithmType } from '../../types/algorithm.types'; import { Inject } from '@nestjs/common'; 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 { DefaultParamsProviderPort } from '../../ports/default-params-provider.port'; import { DefaultParams } from '../../ports/default-params.type'; +import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port'; @QueryHandler(MatchQuery) export class MatchQueryHandler implements IQueryHandler { @@ -18,6 +23,8 @@ export class MatchQueryHandler implements IQueryHandler { @Inject(PARAMS_PROVIDER) private readonly defaultParamsProvider: DefaultParamsProviderPort, @Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort, + @Inject(INPUT_DATETIME_TRANSFORMER) + private readonly datetimeTransformer: DateTimeTransformerPort, ) { this._defaultParams = defaultParamsProvider.getParams(); } @@ -34,14 +41,17 @@ export class MatchQueryHandler implements IQueryHandler { }) .setDefaultAlgorithmParameters({ algorithmType: this._defaultParams.ALGORITHM_TYPE, - remoteness: 0, - useProportion: false, - proportion: 0, - useAzimuth: false, - azimuthMargin: 0, - maxDetourDistanceRatio: 0, - maxDetourDurationRatio: 0, - }); + remoteness: this._defaultParams.REMOTENESS, + useProportion: this._defaultParams.USE_PROPORTION, + proportion: this._defaultParams.PROPORTION, + useAzimuth: this._defaultParams.USE_AZIMUTH, + azimuthMargin: this._defaultParams.AZIMUTH_MARGIN, + maxDetourDistanceRatio: this._defaultParams.MAX_DETOUR_DISTANCE_RATIO, + maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO, + }) + .setDatesAndSchedule(this.datetimeTransformer); + + console.log(query); let algorithm: Algorithm; switch (query.algorithmType) { diff --git a/src/modules/ad/core/application/queries/match/match.query.ts b/src/modules/ad/core/application/queries/match/match.query.ts index d2348ae..b79e613 100644 --- a/src/modules/ad/core/application/queries/match/match.query.ts +++ b/src/modules/ad/core/application/queries/match/match.query.ts @@ -3,13 +3,14 @@ import { AlgorithmType } from '../../types/algorithm.types'; import { Waypoint } from '../../types/waypoint.type'; import { Frequency } from '@modules/ad/core/domain/ad.types'; import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto'; +import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port'; export class MatchQuery extends QueryBase { driver?: boolean; passenger?: boolean; readonly frequency: Frequency; - readonly fromDate: string; - readonly toDate: string; + fromDate: string; + toDate: string; schedule: ScheduleItem[]; seatsProposed?: number; seatsRequested?: number; @@ -104,6 +105,61 @@ export class MatchQuery extends QueryBase { defaultAlgorithmParameters.maxDetourDurationRatio; 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 = { diff --git a/src/modules/ad/tests/unit/core/match.query-handler.spec.ts b/src/modules/ad/tests/unit/core/match.query-handler.spec.ts index 394cf41..801c3a1 100644 --- a/src/modules/ad/tests/unit/core/match.query-handler.spec.ts +++ b/src/modules/ad/tests/unit/core/match.query-handler.spec.ts @@ -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 { MatchQuery } from '@modules/ad/core/application/queries/match/match.query'; 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', () => { let matchQueryHandler: MatchQueryHandler; @@ -75,6 +87,10 @@ describe('Match Query Handler', () => { provide: PARAMS_PROVIDER, useValue: mockDefaultParamsProvider, }, + { + provide: INPUT_DATETIME_TRANSFORMER, + useValue: mockInputDateTimeTransformer, + }, ], }).compile(); diff --git a/src/modules/ad/tests/unit/core/match.query.spec.ts b/src/modules/ad/tests/unit/core/match.query.spec.ts new file mode 100644 index 0000000..aea2933 --- /dev/null +++ b/src/modules/ad/tests/unit/core/match.query.spec.ts @@ -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); + }); +}); diff --git a/src/modules/ad/tests/unit/infrastructure/default-param.provider.spec.ts b/src/modules/ad/tests/unit/infrastructure/default-param.provider.spec.ts index cfc0b1f..105358a 100644 --- a/src/modules/ad/tests/unit/infrastructure/default-param.provider.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/default-param.provider.spec.ts @@ -3,15 +3,15 @@ import { DefaultParamsProvider } from '@modules/ad/infrastructure/default-params import { ConfigService } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; -const mockConfigService = { +const mockConfigServiceWithDefaults = { get: jest.fn().mockImplementation((value: string) => { switch (value) { case 'DEPARTURE_TIME_MARGIN': - return 900; + return 600; case 'ROLE': return 'passenger'; case 'SEATS_PROPOSED': - return 3; + return 2; case 'SEATS_REQUESTED': return 1; case 'STRICT_FREQUENCY': @@ -21,51 +21,86 @@ const mockConfigService = { case 'ALGORITHM_TYPE': return 'PASSENGER_ORIENTED'; case 'REMOTENESS': - return 15000; + return 10000; case 'USE_PROPORTION': return 'true'; case 'PROPORTION': - return 0.3; + return 0.4; case 'USE_AZIMUTH': return 'true'; case 'AZIMUTH_MARGIN': - return 10; + return 15; case 'MAX_DETOUR_DISTANCE_RATIO': - return 0.3; + return 0.5; case 'MAX_DETOUR_DURATION_RATIO': - return 0.3; + return 0.6; default: return 'some_default_value'; } }), }; +const mockConfigServiceWithoutDefaults = { + get: jest.fn(), +}; + describe('DefaultParamsProvider', () => { - let defaultParamsProvider: DefaultParamsProvider; + let defaultParamsProviderWithDefaults: DefaultParamsProvider; + let defaultParamsProviderWithoutDefaults: DefaultParamsProvider; beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ + const moduleWithDefaults: TestingModule = await Test.createTestingModule({ imports: [], providers: [ DefaultParamsProvider, { provide: ConfigService, - useValue: mockConfigService, + useValue: mockConfigServiceWithDefaults, }, ], }).compile(); - defaultParamsProvider = module.get( - DefaultParamsProvider, - ); + defaultParamsProviderWithDefaults = + moduleWithDefaults.get(DefaultParamsProvider); + + const moduleWithoutDefault: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + DefaultParamsProvider, + { + provide: ConfigService, + useValue: mockConfigServiceWithoutDefaults, + }, + ], + }).compile(); + + defaultParamsProviderWithoutDefaults = + moduleWithoutDefault.get(DefaultParamsProvider); }); it('should be defined', () => { - expect(defaultParamsProvider).toBeDefined(); + expect(defaultParamsProviderWithDefaults).toBeDefined(); }); - it('should provide default params', async () => { - const params: DefaultParams = defaultParamsProvider.getParams(); + it('should provide default params if defaults are set', async () => { + 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.PASSENGER).toBeTruthy(); expect(params.DRIVER).toBeFalsy();