import { Test, TestingModule } from '@nestjs/testing'; import { HttpService } from '@nestjs/axios'; import { of } from 'rxjs'; import { AxiosError } from 'axios'; import { GeorouterCreator } from '../../adapters/secondaries/georouter-creator'; import { IGeorouter } from '../../domain/interfaces/georouter.interface'; import { Geodesic } from '../../adapters/secondaries/geodesic'; const mockHttpService = { get: jest .fn() .mockImplementationOnce(() => { throw new AxiosError('Axios error !'); }) .mockImplementationOnce(() => { return of({ status: 200, data: { paths: [ { distance: 50000, time: 1800000, snapped_waypoints: { coordinates: [ [0, 0], [10, 10], ], }, }, ], }, }); }) .mockImplementationOnce(() => { return of({ status: 200, data: { paths: [ { distance: 50000, time: 1800000, points: { coordinates: [ [0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [10, 10], ], }, snapped_waypoints: { coordinates: [ [0, 0], [10, 10], ], }, }, ], }, }); }) .mockImplementationOnce(() => { return of({ status: 200, data: { paths: [ { distance: 50000, time: 1800000, points: { coordinates: [ [0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [10, 10], ], }, details: { time: [ [0, 1, 180000], [1, 2, 180000], [2, 3, 180000], [3, 4, 180000], [4, 5, 180000], [5, 6, 180000], [6, 7, 180000], [7, 9, 360000], [9, 10, 180000], ], }, snapped_waypoints: { coordinates: [ [0, 0], [10, 10], ], }, }, ], }, }); }) .mockImplementationOnce(() => { return of({ status: 200, data: { paths: [ { distance: 50000, time: 1800000, points: { coordinates: [ [0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [7, 7], [8, 8], [9, 9], [10, 10], ], }, snapped_waypoints: { coordinates: [ [0, 0], [5, 5], [10, 10], ], }, details: { time: [ [0, 1, 180000], [1, 2, 180000], [2, 3, 180000], [3, 4, 180000], [4, 7, 540000], [7, 9, 360000], [9, 10, 180000], ], }, }, ], }, }); }) .mockImplementationOnce(() => { return of({ status: 200, data: { paths: [ { distance: 50000, time: 1800000, points: { coordinates: [ [0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [10, 10], ], }, snapped_waypoints: { coordinates: [ [0, 0], [5, 5], [10, 10], ], }, details: { time: [ [0, 1, 180000], [1, 2, 180000], [2, 3, 180000], [3, 4, 180000], [4, 7, 540000], [7, 9, 360000], [9, 10, 180000], ], }, instructions: [ { distance: 25000, sign: 0, interval: [0, 5], text: 'Some instructions', time: 900000, }, { distance: 0, sign: 5, interval: [5, 5], text: 'Waypoint 1', time: 0, }, { distance: 25000, sign: 2, interval: [5, 10], text: 'Some instructions', time: 900000, }, { distance: 0.0, sign: 4, interval: [10, 10], text: 'Arrive at destination', time: 0, }, ], }, ], }, }); }), }; const mockGeodesic = { // eslint-disable-next-line @typescript-eslint/no-unused-vars inverse: jest.fn().mockImplementation(() => ({ azimuth: 45, distance: 50000, })), }; describe('Graphhopper Georouter', () => { let georouterCreator: GeorouterCreator; let graphhopperGeorouter: IGeorouter; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [], providers: [ GeorouterCreator, { provide: HttpService, useValue: mockHttpService, }, { provide: Geodesic, useValue: mockGeodesic, }, ], }).compile(); georouterCreator = module.get(GeorouterCreator); graphhopperGeorouter = georouterCreator.create( 'graphhopper', 'http://localhost', ); }); it('should be defined', () => { expect(graphhopperGeorouter).toBeDefined(); }); describe('route function', () => { it('should fail on axios error', async () => { await expect( graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 1, lon: 1, }, ], }, ], { withDistance: false, withPoints: false, withTime: false, }, ), ).rejects.toBeInstanceOf(Error); }); it('should create one route with all settings to false', async () => { const routes = await graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 10, lon: 10, }, ], }, ], { withDistance: false, withPoints: false, withTime: false, }, ); expect(routes).toHaveLength(1); expect(routes[0].route.distance).toBe(50000); }); it('should create one route with points', async () => { const routes = await graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 10, lon: 10, }, ], }, ], { withDistance: false, withPoints: true, withTime: false, }, ); expect(routes).toHaveLength(1); expect(routes[0].route.distance).toBe(50000); expect(routes[0].route.duration).toBe(1800); expect(routes[0].route.fwdAzimuth).toBe(45); expect(routes[0].route.backAzimuth).toBe(225); expect(routes[0].route.points.length).toBe(11); }); it('should create one route with points and time', async () => { const routes = await graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 10, lon: 10, }, ], }, ], { withDistance: false, withPoints: true, withTime: true, }, ); expect(routes).toHaveLength(1); expect(routes[0].route.spacetimePoints.length).toBe(2); expect(routes[0].route.spacetimePoints[1].duration).toBe(1800); expect(routes[0].route.spacetimePoints[1].distance).toBeUndefined(); }); it('should create one route with points and missed waypoints extrapolations', async () => { const routes = await graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 5, lon: 5, }, { lat: 10, lon: 10, }, ], }, ], { withDistance: false, withPoints: true, withTime: true, }, ); expect(routes).toHaveLength(1); expect(routes[0].route.spacetimePoints.length).toBe(3); expect(routes[0].route.distance).toBe(50000); expect(routes[0].route.duration).toBe(1800); expect(routes[0].route.fwdAzimuth).toBe(45); expect(routes[0].route.backAzimuth).toBe(225); expect(routes[0].route.points.length).toBe(9); }); it('should create one route with points, time and distance', async () => { const routes = await graphhopperGeorouter.route( [ { key: 'route1', points: [ { lat: 0, lon: 0, }, { lat: 10, lon: 10, }, ], }, ], { withDistance: true, withPoints: true, withTime: true, }, ); expect(routes).toHaveLength(1); expect(routes[0].route.spacetimePoints.length).toBe(3); expect(routes[0].route.spacetimePoints[1].duration).toBe(990); expect(routes[0].route.spacetimePoints[1].distance).toBe(25000); }); }); });