diff --git a/src/modules/ad/core/application/queries/match/selector/passenger-oriented.selector.ts b/src/modules/ad/core/application/queries/match/selector/passenger-oriented.selector.ts index 86ae892..f3d202b 100644 --- a/src/modules/ad/core/application/queries/match/selector/passenger-oriented.selector.ts +++ b/src/modules/ad/core/application/queries/match/selector/passenger-oriented.selector.ts @@ -19,13 +19,16 @@ export class PassengerOrientedSelector extends Selector { return ( await Promise.all( - queryStringRoles.map(async (queryStringRole: QueryStringRole) => ({ - ads: await this.repository.getCandidates(queryStringRole.query), - role: queryStringRole.role, - })), + queryStringRoles.map>( + async (queryStringRole: QueryStringRole) => + { + ads: await this.repository.getCandidates(queryStringRole.query), + role: queryStringRole.role, + }, + ), ) ) - .map((adsRole) => + .map((adsRole: AdsRole) => adsRole.ads.map( (adReadModel: AdReadModel) => { @@ -68,3 +71,8 @@ export type QueryStringRole = { query: string; role: Role; }; + +type AdsRole = { + ads: AdReadModel[]; + role: Role; +}; diff --git a/src/modules/ad/tests/unit/core/passenger-oriented-geo-filter.spec.ts b/src/modules/ad/tests/unit/core/passenger-oriented-geo-filter.spec.ts new file mode 100644 index 0000000..6d58d08 --- /dev/null +++ b/src/modules/ad/tests/unit/core/passenger-oriented-geo-filter.spec.ts @@ -0,0 +1,68 @@ +import { PassengerOrientedGeoFilter } from '@modules/ad/core/application/queries/match/filter/passenger-oriented-geo.filter'; +import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query'; +import { + AlgorithmType, + Candidate, +} from '@modules/ad/core/application/types/algorithm.types'; +import { Waypoint } from '@modules/ad/core/application/types/waypoint.type'; +import { Frequency, Role } 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 matchQuery = new MatchQuery({ + algorithmType: AlgorithmType.PASSENGER_ORIENTED, + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: '2023-08-28', + toDate: '2023-08-28', + schedule: [ + { + time: '07:05', + }, + ], + strict: false, + waypoints: [originWaypoint, destinationWaypoint], +}); + +const candidates: Candidate[] = [ + { + ad: { + id: 'cc260669-1c6d-441f-80a5-19cd59afb777', + }, + role: Role.DRIVER, + }, + { + ad: { + id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0', + }, + role: Role.PASSENGER, + }, +]; + +describe('Passenger oriented geo filter', () => { + it('should filter candidates', async () => { + const passengerOrientedGeoFilter: PassengerOrientedGeoFilter = + new PassengerOrientedGeoFilter(matchQuery); + const filteredCandidates: Candidate[] = + await passengerOrientedGeoFilter.filter(candidates); + expect(filteredCandidates.length).toBe(2); + }); +}); diff --git a/src/modules/ad/tests/unit/core/passenger-oriented-selector.spec.ts b/src/modules/ad/tests/unit/core/passenger-oriented-selector.spec.ts new file mode 100644 index 0000000..3c187f3 --- /dev/null +++ b/src/modules/ad/tests/unit/core/passenger-oriented-selector.spec.ts @@ -0,0 +1,94 @@ +import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port'; +import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query'; +import { PassengerOrientedSelector } from '@modules/ad/core/application/queries/match/selector/passenger-oriented.selector'; +import { + AlgorithmType, + Candidate, +} 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 matchQuery = new MatchQuery({ + algorithmType: AlgorithmType.PASSENGER_ORIENTED, + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: '2023-08-28', + toDate: '2023-08-28', + schedule: [ + { + time: '07:05', + }, + ], + strict: false, + waypoints: [originWaypoint, destinationWaypoint], +}); + +const mockMatcherRepository: AdRepositoryPort = { + insertExtra: jest.fn(), + findOneById: jest.fn(), + findOne: jest.fn(), + insert: jest.fn(), + update: jest.fn(), + updateWhere: jest.fn(), + delete: jest.fn(), + count: jest.fn(), + healthCheck: jest.fn(), + getCandidates: jest.fn().mockImplementation(() => [ + { + uuid: 'cc260669-1c6d-441f-80a5-19cd59afb777', + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: new Date('2023-06-21'), + toDate: new Date('2023-06-21'), + seatsProposed: 3, + seatsRequested: 1, + strict: false, + ddriverDistance: 350000, + driverDuration: 14400, + passengerDistance: 350000, + passengerDuration: 14400, + fwdAzimuth: 273, + backAzimuth: 93, + createdAt: 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)', + schedule: [ + { + day: 3, + time: new Date('2023-06-21T07:05:00Z'), + margin: 900, + }, + ], + }, + ]), +}; + +describe('Passenger oriented selector', () => { + it('should select candidates', async () => { + const passengerOrientedSelector: PassengerOrientedSelector = + new PassengerOrientedSelector(matchQuery, mockMatcherRepository); + const candidates: Candidate[] = await passengerOrientedSelector.select(); + expect(candidates.length).toBe(2); + }); +}); diff --git a/src/modules/ad/tests/unit/core/passenger-oriented-waypoints-completer.spec.ts b/src/modules/ad/tests/unit/core/passenger-oriented-waypoints-completer.spec.ts new file mode 100644 index 0000000..097c89f --- /dev/null +++ b/src/modules/ad/tests/unit/core/passenger-oriented-waypoints-completer.spec.ts @@ -0,0 +1,68 @@ +import { PassengerOrientedWaypointsCompleter } from '@modules/ad/core/application/queries/match/completer/passenger-oriented-waypoints.completer'; +import { MatchQuery } from '@modules/ad/core/application/queries/match/match.query'; +import { + AlgorithmType, + Candidate, +} from '@modules/ad/core/application/types/algorithm.types'; +import { Waypoint } from '@modules/ad/core/application/types/waypoint.type'; +import { Frequency, Role } 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 matchQuery = new MatchQuery({ + algorithmType: AlgorithmType.PASSENGER_ORIENTED, + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: '2023-08-28', + toDate: '2023-08-28', + schedule: [ + { + time: '07:05', + }, + ], + strict: false, + waypoints: [originWaypoint, destinationWaypoint], +}); + +const candidates: Candidate[] = [ + { + ad: { + id: 'cc260669-1c6d-441f-80a5-19cd59afb777', + }, + role: Role.DRIVER, + }, + { + ad: { + id: '5600ccfb-ab69-4d03-aa30-0fbe84fcedc0', + }, + role: Role.PASSENGER, + }, +]; + +describe('Passenger oriented waypoints completer', () => { + it('should complete candidates', async () => { + const passengerOrientedWaypointsCompleter: PassengerOrientedWaypointsCompleter = + new PassengerOrientedWaypointsCompleter(matchQuery); + const completedCandidates: Candidate[] = + await passengerOrientedWaypointsCompleter.complete(candidates); + expect(completedCandidates.length).toBe(2); + }); +});