From 64fb15c6fdc3fbd4dd9ed3894a198d7e1f37d9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-L=C3=A9o=20Bourbonnais?= Date: Tue, 19 Nov 2024 15:36:37 -0500 Subject: [PATCH] Bump i18next, opentelemetry and remove need for jest-fetch-mock in some tests update opentelemetry packages yarn.lock update to get only one version of @babel/runtime update i18next, closes #1071 replace jest-fetch-mock in chaire-lib-backend and OSMOverpassDownloader tests in chaire-lib-common by node-fetch in tests See packages/chaire-lib-common/src/utils/osm/__tests__/OsmOverpassDownloader.test.ts for the new mocking strategy. --- packages/chaire-lib-backend/package.json | 21 +- .../__tests__/Json2CapnpService.test.ts | 87 +++- .../src/utils/osrm/__tests__/OSRMMode.test.ts | 444 +++++++++++++----- .../__tests__/TrRoutingServerBackend.test.ts | 120 +++-- .../__tests__/OsmOverpassDownloader.test.ts | 196 ++++---- packages/chaire-lib-frontend/package.json | 9 +- packages/transition-backend/package.json | 2 +- packages/transition-frontend/package.json | 4 +- yarn.lock | 333 ++++++------- 9 files changed, 754 insertions(+), 462 deletions(-) diff --git a/packages/chaire-lib-backend/package.json b/packages/chaire-lib-backend/package.json index 0a1d1824..e522ae9a 100644 --- a/packages/chaire-lib-backend/package.json +++ b/packages/chaire-lib-backend/package.json @@ -28,14 +28,14 @@ "dependencies": { "@casl/ability": "^5.4.4", "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.27.0", - "@opentelemetry/exporter-trace-otlp-grpc": "^0.54.2", - "@opentelemetry/instrumentation": "^0.54.2", - "@opentelemetry/instrumentation-express": "^0.44.0", - "@opentelemetry/instrumentation-http": "^0.54.2", - "@opentelemetry/resources": "^1.27.0", - "@opentelemetry/sdk-trace-node": "^1.27.0", - "@opentelemetry/sdk-trace-base": "^1.27.0", + "@opentelemetry/core": "^1.28.0", + "@opentelemetry/exporter-trace-otlp-grpc": "^0.55.0", + "@opentelemetry/instrumentation": "^0.55.0", + "@opentelemetry/instrumentation-express": "^0.45.0", + "@opentelemetry/instrumentation-http": "^0.55.0", + "@opentelemetry/resources": "^1.28.0", + "@opentelemetry/sdk-trace-node": "^1.28.0", + "@opentelemetry/sdk-trace-base": "^1.28.0", "@turf/turf": "^7.1.0", "@zeit/fetch-retry": "^5.0.1", "bcryptjs": "^2.4.3", @@ -48,8 +48,8 @@ "fs-extra": "^11.2.0", "geojson": "^0.5.0", "glob": "^7.2.3", - "i18next": "^22.4.15", - "i18next-fs-backend": "^2.1.1", + "i18next": "^23.16.5", + "i18next-fs-backend": "^2.3.2", "inquirer": "^7.3.3", "inquirer-file-tree-selection-prompt": "^1.0.7", "knex": "^3.1.0", @@ -103,7 +103,6 @@ "eslint-plugin-n": "^15.7.0", "jest": "^29.7.0", "jest-each": "^29.7.0", - "jest-fetch-mock": "^3.0.3", "mock-spawn": "^0.2.6", "nodemailer-mock": "^1.5.8", "prettier-eslint-cli": "^8.0.1", diff --git a/packages/chaire-lib-backend/src/utils/json2capnp/__tests__/Json2CapnpService.test.ts b/packages/chaire-lib-backend/src/utils/json2capnp/__tests__/Json2CapnpService.test.ts index 9a9e06c5..1a88cdcc 100644 --- a/packages/chaire-lib-backend/src/utils/json2capnp/__tests__/Json2CapnpService.test.ts +++ b/packages/chaire-lib-backend/src/utils/json2capnp/__tests__/Json2CapnpService.test.ts @@ -5,25 +5,37 @@ * License text available at https://opensource.org/licenses/MIT */ import json2CapnpService from '../Json2CapnpService'; -import fetchMock from 'jest-fetch-mock'; import Preferences from 'chaire-lib-common/lib/config/Preferences'; +import fetch from 'node-fetch'; + +jest.mock('node-fetch', () => jest.fn()); +const mockedFetch = fetch as jest.MockedFunction; const jsonCapnpDefaultPrefs = Preferences.get('json2Capnp'); beforeEach(() => { - fetchMock.doMock(); - fetchMock.mockClear(); + jest.resetAllMocks(); }); describe('Valid calls and return values', () => { test('Read value', async () => { + const jsonObject = { field1: 3 }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + const result = await json2CapnpService.readCache('test', {}); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:2000/test?', expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:2000/test?', expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -32,10 +44,21 @@ describe('Valid calls and return values', () => { field: 3, data: 'hello' }; - fetchMock.mockOnce('{ "status": "OK" }'); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue({ + status: 'OK' + }); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + + //fetchMock.mockOnce('{ "status": "OK" }'); const result = await json2CapnpService.writeCache('test', jsonObject); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:2000/test', expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:2000/test', expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); }); }); @@ -54,10 +77,17 @@ describe('Valid calls, with default preferences changes', () => { const jsonObject = { field1: 3 }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const result = await json2CapnpService.readCache('test', {}); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`${host}:${port}/test?`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`${host}:${port}/test?`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -66,21 +96,30 @@ describe('Valid calls, with default preferences changes', () => { field: 3, data: 'hello' }; - fetchMock.mockOnce('{ "status": "OK" }'); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue({ + status: 'OK' + }); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const result = await json2CapnpService.writeCache('test', jsonObject); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`${host}:${port}/test`, expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`${host}:${port}/test`, expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); }); }); describe('Call errors', () => { beforeEach(() => { - fetchMock.mockReject(new Error('wrong')); + mockedFetch.mockRejectedValue(new Error('wrong')); }); afterEach(() => { jest.setTimeout(5000); - fetchMock.mockClear(); + mockedFetch.mockClear(); }); test('Read value', async () => { @@ -89,9 +128,9 @@ describe('Call errors', () => { jest.setTimeout(10000); await expect(json2CapnpService.readCache('test', {})) .rejects - .toThrowError(); - expect(fetchMock).toHaveBeenCalledTimes(5); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:2000/test?', expect.objectContaining({ method: 'GET' })); + .toThrow(); + expect(mockedFetch).toHaveBeenCalledTimes(5); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:2000/test?', expect.objectContaining({ method: 'GET' })); }); test('Read value', async () => { @@ -104,8 +143,8 @@ describe('Call errors', () => { }; await expect(json2CapnpService.writeCache('test', jsonObject)) .rejects - .toThrowError(); - expect(fetchMock).toHaveBeenCalledTimes(5); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:2000/test', expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); + .toThrow(); + expect(mockedFetch).toHaveBeenCalledTimes(5); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:2000/test', expect.objectContaining({ method: 'POST', headers: expect.anything(), body: JSON.stringify(jsonObject) })); }); -}); \ No newline at end of file +}); diff --git a/packages/chaire-lib-backend/src/utils/osrm/__tests__/OSRMMode.test.ts b/packages/chaire-lib-backend/src/utils/osrm/__tests__/OSRMMode.test.ts index 1315e41e..b3bfd104 100644 --- a/packages/chaire-lib-backend/src/utils/osrm/__tests__/OSRMMode.test.ts +++ b/packages/chaire-lib-backend/src/utils/osrm/__tests__/OSRMMode.test.ts @@ -5,8 +5,10 @@ * License text available at https://opensource.org/licenses/MIT */ import OSRMMode from '../OSRMMode'; -import fetchMock from 'jest-fetch-mock'; +import fetch from 'node-fetch'; +jest.mock('node-fetch', () => jest.fn()); +const mockedFetch = fetch as jest.MockedFunction; import TestUtils from 'chaire-lib-common/src/test/TestUtils'; import * as Status from 'chaire-lib-common/lib/utils/Status'; @@ -14,186 +16,404 @@ import osrm from 'osrm'; // Setup fetch mock beforeEach(() => { - fetchMock.doMock(); - fetchMock.mockClear(); + jest.resetAllMocks(); }); -afterAll(() => { - fetchMock.mockClear(); - -}); - -describe('OSRM Mode tests', function() { +describe('OSRM Mode tests', () => { /********************************/ /* Constructor validation tests */ - + test('Create valid Mode', async () => { - let aMode = new OSRMMode('Walking', 'localhost', 4000); + const aMode = new OSRMMode('Walking', 'localhost', 4000); const hostPort = aMode.getHostPort(); - expect(hostPort).toStrictEqual({host:'localhost', port:4000}); - + expect(hostPort).toStrictEqual({ host: 'localhost', port: 4000 }); + }); test('Create invalid mode', async () => { - await expect(() => {let aMode = new OSRMMode('', 'localhost', 4000);}) - .toThrow('OSRMMode: invalid empty mode'); + await expect(() => { const aMode = new OSRMMode('', 'localhost', 4000); }) + .toThrow('OSRMMode: invalid empty mode'); }); - + test('Create invalid port', async () => { - await expect(() => {let aMode =new OSRMMode('walking', 'localhost', -1);}) - .toThrow('OSRMMode: port number must be valid'); + await expect(() => { const aMode = new OSRMMode('walking', 'localhost', -1); }) + .toThrow('OSRMMode: port number must be valid'); }); - + test('Create default localhost', async () => { - let aMode = new OSRMMode('walking', '', 4000); + const aMode = new OSRMMode('walking', '', 4000); //No expect since variable are all private, basically validate that nothing throws }); test('Test basic fetch', async () => { - let aMode = new OSRMMode('walking', '', 4000); + const aMode = new OSRMMode('walking', '', 4000); const origin = TestUtils.makePoint([-73, 45]); const destination1 = TestUtils.makePoint([-73.1, 45.1]); - - let params = {mode: 'walking' as const, - points: [origin, destination1] }; - fetchMock.mockOnce('{ "status": "OK" }'); - let result = await aMode.route(params); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:4000/route/v1/walking/-73,45;-73.1,45.1?alternatives=false&steps=false&annotations=false&continue_straight=default&geometries=geojson&overview=full', {}); + const params = { + mode: 'walking' as const, + points: [origin, destination1] + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue({ + status: 'OK' + }); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + + const result = await aMode.route(params); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:4000/route/v1/walking/-73,45;-73.1,45.1?alternatives=false&steps=false&annotations=false&continue_straight=default&geometries=geojson&overview=full', {}); + - }); - test('Test invalid fetch with bad json', async () => { - let aMode = new OSRMMode('walking', '', 4000); + test('Test invalid fetch with bad json', async () => { + + // TODO: This test should be updated when a better way to manage errors is implemented + const aMode = new OSRMMode('walking', '', 4000); const origin = TestUtils.makePoint([-73, 45]); const destination1 = TestUtils.makePoint([-73.1, 45.1]); - - let params = {mode: 'walking' as const, - points: [origin, destination1] }; + const params = { + mode: 'walking' as const, + points: [origin, destination1] + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockRejectedValueOnce(new Error('invalid json response body at TEST reason: Unexpected end of JSON input')); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse as any + }); + mockedFetch.mockResolvedValue(response); + + await expect(aMode.route(params)).rejects.toThrow('invalid json response body at TEST reason: Unexpected end of JSON input'); + + }); - fetchMock.mockOnce('{ "status":'); - await expect(aMode.route(params)).rejects.toThrow('invalid json response body at reason: Unexpected end of JSON input'); - - }); - test('Test basic fetch with result validation', async () => { - let aMode = new OSRMMode('walking', '', 4000); + const aMode = new OSRMMode('walking', '', 4000); const origin = TestUtils.makePoint([-73, 45]); const destination1 = TestUtils.makePoint([-73.1, 45.1]); - - let params = {mode: 'walking' as const, - points: [origin, destination1] }; - - fetchMock.mockOnce('{"code":"Ok","waypoints":[{"hint":"8qsBgFWuAYAAAAAA8gIAAAAAAABidQAAAAAAAI0LzUIAAAAARm9_RQAAAADyAgAAAAAAAGJ1AAACAAAATZ-j-xcnswLAG6b7QKWuAgAATwCKE53A","distance":35241.065949,"location":[-73.162931,45.295383],"name":"Rang Double"},{"hint":"8qsBgFWuAYAAAAAA8gIAAAAAAABidQAAAAAAAI0LzUIAAAAARm9_RQAAAADyAgAAAAAAAGJ1AAACAAAATZ-j-xcnswIglaT74CuwAgAATwCKE53A","distance":22270.150032,"location":[-73.162931,45.295383],"name":"Rang Double"}],"routes":[{"legs":[{"steps":[],"weight":0,"distance":0,"summary":"","duration":0}],"weight_name":"routability","geometry":"cwmsGhsp}L??","weight":0,"distance":0,"duration":0}]}'); - let result = await aMode.route(params); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:4000/route/v1/walking/-73,45;-73.1,45.1?alternatives=false&steps=false&annotations=false&continue_straight=default&geometries=geojson&overview=full', {}); + const params = { + mode: 'walking' as const, + points: [origin, destination1] + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue({ + code: 'Ok', + waypoints: [ + { + hint: '8qsBgFWuAYAAAAAA8gIAAAAAAABidQAAAAAAAI0LzUIAAAAARm9_RQAAAADyAgAAAAAAAGJ1AAACAAAATZ-j-xcnswLAG6b7QKWuAgAATwCKE53A', + distance: 35241.065949, + location: [-73.162931, 45.295383], + name: 'Rang Double' + }, + { + hint: '8qsBgFWuAYAAAAAA8gIAAAAAAABidQAAAAAAAI0LzUIAAAAARm9_RQAAAADyAgAAAAAAAGJ1AAACAAAATZ-j-xcnswIglaT74CuwAgAATwCKE53A', + distance: 22270.150032, + location: [-73.162931, 45.295383], + name: 'Rang Double' + } + ], + routes: [ + { + legs: [ + { + steps: [], + weight: 0, + distance: 0, + summary: '', + duration: 0 + } + ], + weight_name: 'routability', + geometry: 'cwmsGhsp}L??', + weight: 0, + distance: 0, + duration: 0 + } + ] + }); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + const result = await aMode.route(params); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:4000/route/v1/walking/-73,45;-73.1,45.1?alternatives=false&steps=false&annotations=false&continue_straight=default&geometries=geojson&overview=full', {}); //Check result expect(Status.unwrap(result)).toHaveProperty('waypoints'); expect(Status.unwrap(result)).toHaveProperty('routes'); expect(Status.unwrap(result).waypoints).toHaveLength(2); expect(Status.unwrap(result).routes).toHaveLength(1); - - }); - test('Test simple match call', async () => { - - let aMode = new OSRMMode('bus_urban', '', 4000); - - const origin = TestUtils.makePoint([-73.576361,45.454669]); - const destination1 = TestUtils.makePoint([-73.576504,45.454872]); - - let params = {mode: 'bus_urban' as const, - points: [origin, destination1], - radiuses: [17,17], - timestamps: [0,189], - }; + }); - fetchMock.mockOnce('{"code":"Ok","tracepoints":[{"alternatives_count":5,"location":[-73.576449,45.454673],"distance":6.895504,"hint":"qUsCgKxLAgBCAAAAAgAAAAAAAAAAAAAAfwWVQibOnD8AAAAAAAAAAEIAAAACAAAAAAAAAAAAAAC0AAAA_0-d-1GVtQJXUJ37TZW1AgAAPwBSmAUi","name":"Rue Bannantyne","matchings_index":0,"waypoint_index":0},{"alternatives_count":10,"location":[-73.576431,45.454876],"distance":5.725519,"hint":"GgkAgP___38AAAAARQAAAAAAAADOAAAAAAAAADIXKUIAAAAAJq_7QgAAAABFAAAAAAAAAM4AAAC0AAAAEVCd-xyWtQLIT537GJa1AgAAzwVSmAUi","name":"Avenue Desmarchais","matchings_index":0,"waypoint_index":1}],"matchings":[{"duration":5,"distance":22.6,"weight":5,"geometry":{"coordinates":[[-73.576449,45.454673],[-73.576448,45.454684],[-73.576431,45.454876]],"type":"LineString"},"confidence":0.09066,"weight_name":"routability","legs":[{"steps":[{"intersections":[{"out":0,"entry":[true],"location":[-73.576449,45.454673],"bearings":[4]},{"out":0,"in":1,"entry":[true,false,false],"location":[-73.576448,45.454684],"bearings":[0,180,270]}],"driving_side":"right","geometry":{"coordinates":[[-73.576449,45.454673],[-73.576448,45.454684],[-73.576431,45.454876]],"type":"LineString"},"duration":5,"distance":22.6,"name":"Rue Bannantyne","weight":5,"mode":"driving","maneuver":{"bearing_after":4,"location":[-73.576449,45.454673],"type":"depart","bearing_before":0,"modifier":"right"}},{"intersections":[{"in":0,"entry":[true],"location":[-73.576431,45.454876],"bearings":[180]}],"driving_side":"right","geometry":{"coordinates":[[-73.576431,45.454876],[-73.576431,45.454876]],"type":"LineString"},"duration":0,"distance":0,"name":"Rue Bannantyne","weight":0,"mode":"driving","maneuver":{"bearing_after":0,"location":[-73.576431,45.454876],"type":"arrive","bearing_before":2,"modifier":"left"}}],"weight":5,"distance":22.6,"summary":"Rue Bannantyne","duration":5}]}]}'); + test('Test simple match call', async () => { + + const aMode = new OSRMMode('bus_urban', '', 4000); + + const origin = TestUtils.makePoint([-73.576361, 45.454669]); + const destination1 = TestUtils.makePoint([-73.576504, 45.454872]); + + const params = { + mode: 'bus_urban' as const, + points: [origin, destination1], + radiuses: [17, 17], + timestamps: [0, 189], + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue({ + code: 'Ok', + tracepoints: [ + { + alternatives_count: 5, + location: [-73.576449, 45.454673], + distance: 6.895504, + hint: 'qUsCgKxLAgBCAAAAAgAAAAAAAAAAAAAAfwWVQibOnD8AAAAAAAAAAEIAAAACAAAAAAAAAAAAAAC0AAAA_0-d-1GVtQJXUJ37TZW1AgAAPwBSmAUi', + name: 'Rue Bannantyne', + matchings_index: 0, + waypoint_index: 0 + }, + { + alternatives_count: 10, + location: [-73.576431, 45.454876], + distance: 5.725519, + hint: 'GgkAgP___38AAAAARQAAAAAAAADOAAAAAAAAADIXKUIAAAAAJq_7QgAAAABFAAAAAAAAAM4AAAC0AAAAEVCd-xyWtQLIT537GJa1AgAAzwVSmAUi', + name: 'Avenue Desmarchais', + matchings_index: 0, + waypoint_index: 1 + } + ], + matchings: [ + { + duration: 5, + distance: 22.6, + weight: 5, + geometry: { + coordinates: [[-73.576449, 45.454673], [-73.576448, 45.454684], [-73.576431, 45.454876]], + type: 'LineString' + }, + confidence: 0.09066, + weight_name: 'routability', + legs: [ + { + steps: [ + { + intersections: [ + { + out: 0, + entry: [true], + location: [-73.576449, 45.454673], + bearings: [4] + }, { + out: 0, + in: 1, + entry: [true, false, false], + location: [-73.576448, 45.454684], + bearings: [0, 180, 270] + } + ], + driving_side: 'right', + geometry: { + coordinates: [[-73.576449, 45.454673], [-73.576448, 45.454684], [-73.576431, 45.454876]], + type: 'LineString' + }, + duration: 5, + distance: 22.6, + name: 'Rue Bannantyne', + weight: 5, + mode: 'driving', + maneuver: { + bearing_after: 4, + location: [-73.576449, 45.454673], + type: 'depart', + bearing_before: 0, + modifier: 'right' + } + }, + { + intersections: [], + geometry: { + coordinates: [[-73.576448, 45.454684], [-73.576431, 45.454876]], + type: 'LineString' + } + } + ] + } + ] + } + ] + }); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + + const result = await aMode.match(params); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://localhost:4000/match/v1/busUrban/-73.576361,45.454669;-73.576504,45.454872?radiuses=17;17×tamps=0;189&steps=true&annotations=false&gaps=ignore&geometries=geojson&overview=full', {}); - let result = await aMode.match(params); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith('http://localhost:4000/match/v1/busUrban/-73.576361,45.454669;-73.576504,45.454872?radiuses=17;17×tamps=0;189&steps=true&annotations=false&gaps=ignore&geometries=geojson&overview=full', {}); - - //Check result + //Check result expect(Status.unwrap(result)).toHaveProperty('tracepoints'); expect(Status.unwrap(result)).toHaveProperty('matchings'); expect(Status.unwrap(result).tracepoints).toHaveLength(2); expect(Status.unwrap(result).matchings).toHaveLength(1); expect(Status.unwrap(result).matchings[0].legs[0].steps).toHaveLength(2); - + }); test('Test simple tableFrom call', async () => { - let aMode = new OSRMMode('walking', '', 5000); - - const origin = TestUtils.makePoint([-73.663473,45.611544]); - const destinations = [TestUtils.makePoint([-73.663473,45.611544]), - TestUtils.makePoint([-73.663473,45.611544]), - TestUtils.makePoint([-73.663083,45.612892]), - TestUtils.makePoint([-73.660853,45.612142]), - ]; - - let params = {mode: 'walking' as const, - origin: origin, - destinations: destinations - }; + const aMode = new OSRMMode('walking', '', 5000); + + const origin = TestUtils.makePoint([-73.663473, 45.611544]); + const destinations = [ + TestUtils.makePoint([-73.663473, 45.611544]), + TestUtils.makePoint([-73.663473, 45.611544]), + TestUtils.makePoint([-73.663083, 45.612892]), + TestUtils.makePoint([-73.660853, 45.612142]), + ]; + + const params = { + mode: 'walking' as const, + origin: origin, + destinations: destinations + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue( + { + code: 'Ok', + distances: [[0, 0, 0, 235.1, 438.6]], + durations: [[0, 0, 0, 205.7, 389.3]], + sources: [{ + hint: '2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3', + distance: 0.322722, + location: [-73.66347, 45.611546], + name: '' + }], + destinations: [{ + hint: '2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3', + distance: 0.322722, + location: [-73.66347, 45.611546], + name: '' + }, { + hint: '2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3', + distance: 0.322722, + location: [-73.66347, 45.611546], + name: '' + }, { + hint: '2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3', + distance: 0.322722, + location: [-73.66347, 45.611546], + name: '' + }, { + hint: 'zzkMgP45DIA8AAAABQAAACMCAACqAQAAw4gJQUDCIz_LFJtCpmVxQjwAAAAFAAAAIwIAAKoBAAABAAAAlf2b-1v_twKV_Zv7XP-3AgQAzwN8GkX3', + distance: 0.111143, + location: [-73.663083, 45.612891], + name: 'Boulevard Saint-Martin Est' + }, { + hint: 'CjoMgCU6DICzAAAAiQAAAAAAAABoAAAAshjMQUvCmkEAAAAADJ9rQbMAAACJAAAAAAAAAGgAAAABAAAAUAac-3H8twJLBpz7bvy3AgAA3wh8GkX3', + distance: 0.513055, + location: [-73.660848, 45.612145], + name: '' + } + ] + } + ); + + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + + const result = await aMode.tableFrom(params); - fetchMock.mockOnce('{"code":"Ok","distances":[[0,0,0,235.1,438.6]],"durations":[[0,0,0,205.7,389.3]],"sources":[{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""}],"destinations":[{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"zzkMgP45DIA8AAAABQAAACMCAACqAQAAw4gJQUDCIz_LFJtCpmVxQjwAAAAFAAAAIwIAAKoBAAABAAAAlf2b-1v_twKV_Zv7XP-3AgQAzwN8GkX3","distance":0.111143,"location":[-73.663083,45.612891],"name":"Boulevard Saint-Martin Est"},{"hint":"CjoMgCU6DICzAAAAiQAAAAAAAABoAAAAshjMQUvCmkEAAAAADJ9rQbMAAACJAAAAAAAAAGgAAAABAAAAUAac-3H8twJLBpz7bvy3AgAA3wh8GkX3","distance":0.513055,"location":[-73.660848,45.612145],"name":""}]}'); + const EXPECTED_QUERY = 'http://localhost:5000/table/v1/walking/-73.663473,45.611544;-73.663473,45.611544;-73.663473,45.611544;-73.663083,45.612892;-73.660853,45.612142?sources=0&annotations=duration,distance'; - let result = await aMode.tableFrom(params); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(EXPECTED_QUERY, {}); - const EXPECTED_QUERY = 'http://localhost:5000/table/v1/walking/-73.663473,45.611544;-73.663473,45.611544;-73.663473,45.611544;-73.663083,45.612892;-73.660853,45.612142?sources=0&annotations=duration,distance'; - - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(EXPECTED_QUERY, {}); - //Check result expect(Status.unwrap(result)).toHaveProperty('query'); expect(Status.unwrap(result)).toHaveProperty('distances'); expect(Status.unwrap(result)).toHaveProperty('durations'); expect(Status.unwrap(result).durations).toHaveLength(4); expect(Status.unwrap(result).distances).toHaveLength(4); - expect(Status.unwrap(result).distances).toStrictEqual([0,0,235.1,438.6]); + expect(Status.unwrap(result).distances).toStrictEqual([0, 0, 235.1, 438.6]); }); test('Test simple tableTo call', async () => { - let aMode = new OSRMMode('walking', '', 5000); - - const destination = TestUtils.makePoint([-73.663473,45.611544]); - const origins = [TestUtils.makePoint([-73.663473,45.611544]), - TestUtils.makePoint([-73.663473,45.611544]), - TestUtils.makePoint([-73.663083,45.612892]), - TestUtils.makePoint([-73.660853,45.612142]), - ]; - - let params = {mode: 'walking' as const, - origins: origins, - destination: destination - }; + const aMode = new OSRMMode('walking', '', 5000); + + const destination = TestUtils.makePoint([-73.663473, 45.611544]); + const origins = [TestUtils.makePoint([-73.663473, 45.611544]), + TestUtils.makePoint([-73.663473, 45.611544]), + TestUtils.makePoint([-73.663083, 45.612892]), + TestUtils.makePoint([-73.660853, 45.612142]), + ]; + + const params = { + mode: 'walking' as const, + origins: origins, + destination: destination + }; + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue( + { + code: 'Ok', + distances: [[0], [0], [0], [235.1], [438.6]], + durations: [[0], [0], [0], [205.7], [389.3]], + sources: [{ + hint: '2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3', + distance: 0.322722, + location: [-73.66347, 45.611546], + name: '' + }] + } + ); + + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + + const result = await aMode.tableTo(params); - fetchMock.mockOnce('{"code":"Ok","distances":[[0],[0],[0],[235.1],[438.6]],"durations":[[0],[0],[0],[205.7],[389.3]],"sources":[{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""},{"hint":"zzkMgP45DIA8AAAABQAAACMCAACqAQAAw4gJQUDCIz_LFJtCpmVxQjwAAAAFAAAAIwIAAKoBAAABAAAAlf2b-1v_twKV_Zv7XP-3AgQAzwN8GkX3","distance":0.111143,"location":[-73.663083,45.612891],"name":"Boulevard Saint-Martin Est"},{"hint":"CjoMgCU6DICzAAAAiQAAAAAAAABoAAAAshjMQUvCmkEAAAAADJ9rQbMAAACJAAAAAAAAAGgAAAABAAAAUAac-3H8twJLBpz7bvy3AgAA3wh8GkX3","distance":0.513055,"location":[-73.660848,45.612145],"name":""}],"destinations":[{"hint":"2TkMgL48DIAAAAAA5wEAAHMCAAAaAQAAAAAAAJQfikLY5bFCdh8gQgAAAADnAQAAcwIAABoBAAABAAAAEvyb-xr6twIP_Jv7GPq3AgUA3wh8GkX3","distance":0.322722,"location":[-73.66347,45.611546],"name":""}]}'); + const EXPECTED_QUERY = 'http://localhost:5000/table/v1/walking/-73.663473,45.611544;-73.663473,45.611544;-73.663473,45.611544;-73.663083,45.612892;-73.660853,45.612142?destinations=0&annotations=duration,distance'; - let result = await aMode.tableTo(params); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(EXPECTED_QUERY, {}); - const EXPECTED_QUERY = 'http://localhost:5000/table/v1/walking/-73.663473,45.611544;-73.663473,45.611544;-73.663473,45.611544;-73.663083,45.612892;-73.660853,45.612142?destinations=0&annotations=duration,distance'; - - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(EXPECTED_QUERY, {}); - //Check result expect(Status.unwrap(result)).toHaveProperty('query'); expect(Status.unwrap(result)).toHaveProperty('distances'); @@ -201,8 +421,8 @@ describe('OSRM Mode tests', function() { expect(Status.unwrap(result).durations).toHaveLength(4); expect(Status.unwrap(result).distances).toHaveLength(4); expect(Status.unwrap(result).query).toBe(EXPECTED_QUERY); - expect(Status.unwrap(result).distances).toStrictEqual([0,0,235.1,438.6]); + expect(Status.unwrap(result).distances).toStrictEqual([0, 0, 235.1, 438.6]); }); - + }); diff --git a/packages/chaire-lib-backend/src/utils/trRouting/__tests__/TrRoutingServerBackend.test.ts b/packages/chaire-lib-backend/src/utils/trRouting/__tests__/TrRoutingServerBackend.test.ts index 6e2b687b..202d6118 100644 --- a/packages/chaire-lib-backend/src/utils/trRouting/__tests__/TrRoutingServerBackend.test.ts +++ b/packages/chaire-lib-backend/src/utils/trRouting/__tests__/TrRoutingServerBackend.test.ts @@ -5,12 +5,14 @@ * License text available at https://opensource.org/licenses/MIT */ import TrRoutingServiceBackend from '../TrRoutingServiceBackend'; -import fetchMock from 'jest-fetch-mock'; import TestUtils from 'chaire-lib-common/lib/test/TestUtils'; +import fetch from 'node-fetch'; + +jest.mock('node-fetch', () => jest.fn()); +const mockedFetch = fetch as jest.MockedFunction; beforeEach(() => { - fetchMock.doMock(); - fetchMock.mockClear(); + jest.resetAllMocks(); // otherwise the mocks will accumulate the calls and haveBeenCalledTimes will not be accurate }); const defaultParameters = { @@ -26,17 +28,24 @@ describe('Route queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const expectedQueryString = `origin=${defaultParameters.originDestination[0].geometry.coordinates[0]},${defaultParameters.originDestination[0].geometry.coordinates[1]}&` + `destination=${defaultParameters.originDestination[1].geometry.coordinates[0]},${defaultParameters.originDestination[1].geometry.coordinates[1]}&` + `scenario_id=${defaultParameters.scenarioId}&` + `time_of_trip=${defaultParameters.timeOfTrip}&` + - `time_type=0&` + - `alternatives=false`; + 'time_type=0&' + + 'alternatives=false'; const result = await TrRoutingServiceBackend.route(defaultParameters); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`http://localhost:4000/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`http://localhost:4000/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -47,17 +56,24 @@ describe('Route queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const expectedQueryString = `origin=${defaultParameters.originDestination[0].geometry.coordinates[0]},${defaultParameters.originDestination[0].geometry.coordinates[1]}&` + `destination=${defaultParameters.originDestination[1].geometry.coordinates[0]},${defaultParameters.originDestination[1].geometry.coordinates[1]}&` + `scenario_id=${defaultParameters.scenarioId}&` + `time_of_trip=${defaultParameters.timeOfTrip}&` + - `time_type=0&` + - `alternatives=false`; + 'time_type=0&' + + 'alternatives=false'; const result = await TrRoutingServiceBackend.route(defaultParameters, { host, port }); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`${host}:${port}/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`${host}:${port}/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -65,7 +81,14 @@ describe('Route queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const params = { originDestination: [TestUtils.makePoint([-73, 45]), TestUtils.makePoint([-74, 45.5])] as [GeoJSON.Feature, GeoJSON.Feature], @@ -79,14 +102,14 @@ describe('Route queries', () => { maxTransferTravelTime: 200, maxTravelTime: 1800, maxFirstWaitingTime: 180 - } - + }; + const expectedQueryString = `origin=${params.originDestination[0].geometry.coordinates[0]},${params.originDestination[0].geometry.coordinates[1]}&` + `destination=${params.originDestination[1].geometry.coordinates[0]},${params.originDestination[1].geometry.coordinates[1]}&` + `scenario_id=${params.scenarioId}&` + `time_of_trip=${params.timeOfTrip}&` + - `time_type=1&` + - `alternatives=true&` + + 'time_type=1&' + + 'alternatives=true&' + `min_waiting_time=${params.minWaitingTime}&` + `max_access_travel_time=${params.maxAccessTravelTime}&` + `max_egress_travel_time=${params.maxEgressTravelTime}&` + @@ -94,8 +117,8 @@ describe('Route queries', () => { `max_travel_time=${params.maxTravelTime}&` + `max_first_waiting_time=${params.maxFirstWaitingTime}`; const result = await TrRoutingServiceBackend.route(params); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`http://localhost:4000/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`http://localhost:4000/v2/route?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -109,22 +132,29 @@ describe('Legacy transit queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const params = { originDestination: [TestUtils.makePoint([-73, 45]), TestUtils.makePoint([-74, 45.5])] as [GeoJSON.Feature, GeoJSON.Feature], scenarioId: 'arbitraryId', alternatives: true, departureTime: 36000, - } + }; const queryString = `origin=${params.originDestination[0].geometry.coordinates[1]},${params.originDestination[0].geometry.coordinates[0]}&` + `destination=${params.originDestination[1].geometry.coordinates[1]},${params.originDestination[1].geometry.coordinates[0]}&` + `scenario_uuid=${params.scenarioId}&` + - `alternatives=1&` + + 'alternatives=1&' + `departure_time=${params.departureTime}`; const result = await TrRoutingServiceBackend.v1TransitCall(queryString, host, port); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`${host}:${port}/route/v1/transit?${queryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`${host}:${port}/route/v1/transit?${queryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -136,17 +166,24 @@ describe('Summary queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); - + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); + const expectedQueryString = `origin=${defaultParameters.originDestination[0].geometry.coordinates[0]},${defaultParameters.originDestination[0].geometry.coordinates[1]}&` + `destination=${defaultParameters.originDestination[1].geometry.coordinates[0]},${defaultParameters.originDestination[1].geometry.coordinates[1]}&` + `scenario_id=${defaultParameters.scenarioId}&` + `time_of_trip=${defaultParameters.timeOfTrip}&` + - `time_type=0&` + - `alternatives=false`; + 'time_type=0&' + + 'alternatives=false'; const result = await TrRoutingServiceBackend.summary(defaultParameters); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`http://localhost:4000/v2/summary?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`http://localhost:4000/v2/summary?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); @@ -154,7 +191,14 @@ describe('Summary queries', () => { const jsonObject = { status: 'success' }; - fetchMock.mockOnce(JSON.stringify(jsonObject)); + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonObject); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const params = { originDestination: [TestUtils.makePoint([-73, 45]), TestUtils.makePoint([-74, 45.5])] as [GeoJSON.Feature, GeoJSON.Feature], @@ -168,14 +212,14 @@ describe('Summary queries', () => { maxTransferTravelTime: 200, maxTravelTime: 1800, maxFirstWaitingTime: 180 - } - + }; + const expectedQueryString = `origin=${params.originDestination[0].geometry.coordinates[0]},${params.originDestination[0].geometry.coordinates[1]}&` + `destination=${params.originDestination[1].geometry.coordinates[0]},${params.originDestination[1].geometry.coordinates[1]}&` + `scenario_id=${params.scenarioId}&` + `time_of_trip=${params.timeOfTrip}&` + - `time_type=1&` + - `alternatives=true&` + + 'time_type=1&' + + 'alternatives=true&' + `min_waiting_time=${params.minWaitingTime}&` + `max_access_travel_time=${params.maxAccessTravelTime}&` + `max_egress_travel_time=${params.maxEgressTravelTime}&` + @@ -183,8 +227,8 @@ describe('Summary queries', () => { `max_travel_time=${params.maxTravelTime}&` + `max_first_waiting_time=${params.maxFirstWaitingTime}`; const result = await TrRoutingServiceBackend.summary(params); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith(`http://localhost:4000/v2/summary?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith(`http://localhost:4000/v2/summary?${expectedQueryString}`, expect.objectContaining({ method: 'GET' })); expect(result).toEqual(jsonObject); }); diff --git a/packages/chaire-lib-common/src/utils/osm/__tests__/OsmOverpassDownloader.test.ts b/packages/chaire-lib-common/src/utils/osm/__tests__/OsmOverpassDownloader.test.ts index 8a99c654..6bf3c4b2 100644 --- a/packages/chaire-lib-common/src/utils/osm/__tests__/OsmOverpassDownloader.test.ts +++ b/packages/chaire-lib-common/src/utils/osm/__tests__/OsmOverpassDownloader.test.ts @@ -7,7 +7,10 @@ import OsmOverpassDownloader from '../OsmOverpassDownloader'; import GeoJSON from 'geojson'; -import fetchMock from 'jest-fetch-mock' +import fetch from 'node-fetch'; + +jest.mock('node-fetch', () => jest.fn()); +const mockedFetch = fetch as jest.MockedFunction; const overpassQuery = ` @@ -18,86 +21,86 @@ const overpassQuery = ` +const xmlData = ` The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. @@ -118,36 +121,54 @@ const xmlResponse = ` `; beforeEach(() => { - fetchMock.doMock(); - fetchMock.mockIf(/^https?:\/\/overpass-api\.de\/api\/interpreter.*$/, async req => { - const body = await req.text(); - - // Make sure the polyboundary is in the query - if (!body.includes(`bounds="${polyboundary}"`)) { - throw "Invalid poly boundary in request body: " + body; - } - - // Return proper response depending on output - if (body.includes('output="xml"')) { - return xmlResponse; - } else if (body.includes('output="json"')) { - return JSON.stringify(responseObject); - } - throw "No valid output specified in request body: " + body; - }) + jest.resetAllMocks(); // otherwise the mocks will accumulate the calls and haveBeenCalledTimes will not be accurate }); -test('download json data from overpass', async function() { +test('download json data from overpass', async () => { + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonData); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const jsonContent = await OsmOverpassDownloader.downloadJson(geojsonBoundaryPolygon, overpassQuery); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://overpass-api.de/api/interpreter', { + method: 'POST', + headers: { + 'Content-Type': 'application/xml' + }, + body: overpassQuery.replace('BOUNDARY', polyboundary).replace('OUTPUT', 'json') + }); expect(jsonContent.elements).toBeDefined(); - expect(jsonContent.elements).toEqual(responseObject.elements); + expect(jsonContent.elements).toEqual(jsonData.elements); }); -test('download geojson data from overpass', async function() { +test('download geojson data from overpass', async () => { + + const jsonResponse = jest.fn() as jest.MockedFunction; + jsonResponse.mockResolvedValue(jsonData); + const response = Promise.resolve({ + ok: true, + status: 200, + json: jsonResponse + }); + mockedFetch.mockResolvedValue(response); const geojsonContent = await OsmOverpassDownloader.downloadGeojson(geojsonBoundaryPolygon, overpassQuery); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://overpass-api.de/api/interpreter', { + method: 'POST', + headers: { + 'Content-Type': 'application/xml' + }, + body: overpassQuery.replace('BOUNDARY', polyboundary).replace('OUTPUT', 'json') + }); expect(geojsonContent.type).toBe('FeatureCollection'); expect(geojsonContent.features).toBeDefined(); expect(geojsonContent.features.length).toEqual(1); @@ -161,9 +182,26 @@ test('download geojson data from overpass', async function() { }); -test('download xml data from overpass', async function() { +test('download xml data from overpass', async () => { + + const xmlResponse = jest.fn() as jest.MockedFunction; + xmlResponse.mockResolvedValue(xmlData); + const response = Promise.resolve({ + ok: true, + status: 200, + text: xmlResponse + }); + mockedFetch.mockResolvedValue(response); const xmlContent = await OsmOverpassDownloader.downloadXml(geojsonBoundaryPolygon, overpassQuery); - expect(xmlContent).toEqual(xmlResponse); + expect(mockedFetch).toHaveBeenCalledTimes(1); + expect(mockedFetch).toHaveBeenCalledWith('http://overpass-api.de/api/interpreter', { + method: 'POST', + headers: { + 'Content-Type': 'application/xml' + }, + body: overpassQuery.replace('BOUNDARY', polyboundary).replace('OUTPUT', 'xml') + }); + expect(xmlContent).toEqual(xmlData); -}); \ No newline at end of file +}); diff --git a/packages/chaire-lib-frontend/package.json b/packages/chaire-lib-frontend/package.json index faba1303..075aaa9f 100644 --- a/packages/chaire-lib-frontend/package.json +++ b/packages/chaire-lib-frontend/package.json @@ -36,9 +36,9 @@ "font-awesome": "^4.7.0", "geojson": "^0.5.0", "history": "^4.9.0", - "i18next": "^22.4.15", - "i18next-browser-languagedetector": "^7.0.1", - "i18next-http-backend": "^2.1.0", + "i18next": "^23.16.5", + "i18next-browser-languagedetector": "^8.0.0", + "i18next-http-backend": "^2.6.2", "json-loader": "^0.5.7", "lodash": "^4.17.21", "mapbox-gl": "chairemobilite/mapbox-gl-js#39bbf9aeb1859424e29cff2584715fddc9d018b9", @@ -50,7 +50,7 @@ "react-color": "^2.18.1", "react-datepicker": "^3.1.3", "react-dom": "^16.13.1", - "react-i18next": "^12.2.2", + "react-i18next": "^12.3.1", "react-loadable": "^5.5.0", "react-markdown": "^8.0.7", "react-modal": "^3.12.1", @@ -96,7 +96,6 @@ "jest": "^29.7.0", "jest-each": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "jest-fetch-mock": "^3.0.3", "mockdate": "^3.0.2", "prettier-eslint-cli": "^8.0.1", "react-select-event": "^5.0.0", diff --git a/packages/transition-backend/package.json b/packages/transition-backend/package.json index 923e8212..d8e5f481 100644 --- a/packages/transition-backend/package.json +++ b/packages/transition-backend/package.json @@ -41,7 +41,7 @@ "geokdbush": "^1.1.0", "glob": "^7.2.3", "gtfs-types": "^2.1.0", - "i18next": "^22.4.15", + "i18next": "^23.16.5", "inquirer": "^8.2.4", "jszip": "^3.10.1", "knex": "^3.1.0", diff --git a/packages/transition-frontend/package.json b/packages/transition-frontend/package.json index 82816c1f..1284c677 100644 --- a/packages/transition-frontend/package.json +++ b/packages/transition-frontend/package.json @@ -38,7 +38,7 @@ "date-fns": "^2.30.0", "element-resize-event": "^3.0.6", "history": "^4.9.0", - "i18next": "^22.4.15", + "i18next": "^23.16.5", "lodash": "^4.17.21", "mapbox-gl": "chairemobilite/mapbox-gl-js#39bbf9aeb1859424e29cff2584715fddc9d018b9", "moment": "^2.29.4", @@ -50,7 +50,7 @@ "react-color": "^2.18.1", "react-datepicker": "^3.1.3", "react-dom": "^16.13.1", - "react-i18next": "^12.2.2", + "react-i18next": "^12.3.1", "react-mathjax": "^1.0.1", "react-redux": "^7.2.0", "react-router-dom": "^5.2.0", diff --git a/yarn.lock b/yarn.lock index b80d8ab0..9f12a506 100644 --- a/yarn.lock +++ b/yarn.lock @@ -391,62 +391,13 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7": - version "7.9.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" - integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.5.tgz#303d8bd440ecd5a491eae6117fd3367698674c5c" - integrity sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.12.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" - integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.18.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" - integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" - integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/runtime@^7.21.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" - integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.9.2": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" @@ -1359,10 +1310,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@opentelemetry/api-logs@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.54.2.tgz#bb8aa11cdc69b327b58d7e10cc2bc26bf540421f" - integrity sha512-4MTVwwmLgUh5QrJnZpYo6YRO5IBLAggf2h8gWDblwRagDStY13aEvt7gGk3jewrMaPlHiF83fENhIx0HO97/cQ== +"@opentelemetry/api-logs@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.55.0.tgz#5cd7461820d864600250deb3803c32367a6bb2d2" + integrity sha512-3cpa+qI45VHYcA5c0bHM6VHo9gicv3p5mlLHNG3rLyjQU8b7e0st1rWtrUn3JbZ3DwwCfhKop4eQ9UuYlC6Pkg== dependencies: "@opentelemetry/api" "^1.3.0" @@ -1371,15 +1322,15 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== -"@opentelemetry/context-async-hooks@1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.27.0.tgz#a18c288ac586f5385d156003d67851465b34fb73" - integrity sha512-CdZ3qmHCwNhFAzjTgHqrDQ44Qxcpz43cVxZRhOs+Ns/79ug+Mr84Bkb626bkJLkA3+BLimA5YAEVRlJC6pFb7g== +"@opentelemetry/context-async-hooks@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.28.0.tgz#287afda2b75cb226f70d433244c3ef6f6dd8abdd" + integrity sha512-igcl4Ve+F1N2063PJUkesk/GkYyuGIWinYkSyAFTnIj3gzrOgvOA4k747XNdL47HRRL1w/qh7UW8NDuxOLvKFA== -"@opentelemetry/core@1.27.0", "@opentelemetry/core@^1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.27.0.tgz#9f1701a654ab01abcebb12931b418f3393b94b75" - integrity sha512-yQPKnK5e+76XuiqUH/gKyS8wv/7qITd5ln56QkBTf3uggr0VkXOXfcaAuG330UfdYu83wsyoBwqwxigpIG+Jkg== +"@opentelemetry/core@1.28.0", "@opentelemetry/core@^1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.28.0.tgz#e97290a3e36c59480ffb2287fe2713c66749274c" + integrity sha512-ZLwRMV+fNDpVmF2WYUdBHlq0eOWtEaUJSusrzjGnBt7iSRvfjFE3RXYUZJrqou/wIDWV0DwQ5KIfYe9WXg9Xqw== dependencies: "@opentelemetry/semantic-conventions" "1.27.0" @@ -1390,44 +1341,44 @@ dependencies: "@opentelemetry/semantic-conventions" "1.25.1" -"@opentelemetry/exporter-trace-otlp-grpc@^0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.54.2.tgz#96b952df147b57dae1316865b034d784db545048" - integrity sha512-tmxiCYhQdPrzwlM6O7VQeNP9PBjKhaiOo54wFxQFZQcoVaDiOOES4+6PwHU1eW+43mDsgdQHN5AHSRHVLe9jDA== +"@opentelemetry/exporter-trace-otlp-grpc@^0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.55.0.tgz#c1b142bae7144eb2be45332de60a2f48a782ed06" + integrity sha512-ohIkCLn2Wc3vhhFuf1bH8kOXHMEdcWiD847x7f3Qfygc+CGiatGLzQYscTcEYsWGMV22gVwB/kVcNcx5a3o8gA== dependencies: "@grpc/grpc-js" "^1.7.1" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/otlp-grpc-exporter-base" "0.54.2" - "@opentelemetry/otlp-transformer" "0.54.2" - "@opentelemetry/resources" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/otlp-grpc-exporter-base" "0.55.0" + "@opentelemetry/otlp-transformer" "0.55.0" + "@opentelemetry/resources" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" -"@opentelemetry/instrumentation-express@^0.44.0": - version "0.44.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.44.0.tgz#51dc11e3152ffbee1c4e389298aac30231c8270a" - integrity sha512-GWgibp6Q0wxyFaaU8ERIgMMYgzcHmGrw3ILUtGchLtLncHNOKk0SNoWGqiylXWWT4HTn5XdV8MGawUgpZh80cA== +"@opentelemetry/instrumentation-express@^0.45.0": + version "0.45.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.45.0.tgz#e7c34843f3a9f7b46e67b6bafea77561d46cc749" + integrity sha512-7NY+HsETxEP5Rtlhy8Z3pPJdiz6wPmJuFVb9bRDdThKk72ATryox2ozV3t+aMeOdDsVgQiPHpgPzU150/uovOQ== dependencies: "@opentelemetry/core" "^1.8.0" - "@opentelemetry/instrumentation" "^0.54.0" + "@opentelemetry/instrumentation" "^0.55.0" "@opentelemetry/semantic-conventions" "^1.27.0" -"@opentelemetry/instrumentation-http@^0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-http/-/instrumentation-http-0.54.2.tgz#0756a404453c37bf07c010faaac06079f8b39dda" - integrity sha512-mABjJ34UcU32pg8g18L9xBh0U3JON/2F6/57BYYy8AZJp2a71lZjcKr0T00pICoic50TW5HvcTrmyfMil+AiXQ== +"@opentelemetry/instrumentation-http@^0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-http/-/instrumentation-http-0.55.0.tgz#954a1f52ae5fcf8f2ad355c2dfc2d7c7b68478d7" + integrity sha512-AO27XSjkgNicfy/YBthskFAwx9VfaO7tChrLaTONTfOWv14GlB3Rs2eTYpywZIHWsW2cR5hvVkcDte4GV0stoA== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/instrumentation" "0.54.2" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/instrumentation" "0.55.0" "@opentelemetry/semantic-conventions" "1.27.0" forwarded-parse "2.1.2" semver "^7.5.2" -"@opentelemetry/instrumentation@0.54.2", "@opentelemetry/instrumentation@^0.54.0", "@opentelemetry/instrumentation@^0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.54.2.tgz#29693a33bbaaf0156634ac5d9e774636b8f17f73" - integrity sha512-go6zpOVoZVztT9r1aPd79Fr3OWiD4N24bCPJsIKkBses8oyFo12F/Ew3UBTdIu6hsW4HC4MVEJygG6TEyJI/lg== +"@opentelemetry/instrumentation@0.55.0", "@opentelemetry/instrumentation@^0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.55.0.tgz#ecac8afd8706f6e99b3bb6951b9e07c4c81533f0" + integrity sha512-YDCMlaQRZkziLL3t6TONRgmmGxDx6MyQDXRD0dknkkgUZtOK5+8MWft1OXzmNu6XfBOdT12MKN5rz+jHUkafKQ== dependencies: - "@opentelemetry/api-logs" "0.54.2" + "@opentelemetry/api-logs" "0.55.0" "@types/shimmer" "^1.2.0" import-in-the-middle "^1.8.1" require-in-the-middle "^7.1.1" @@ -1443,95 +1394,95 @@ semver "^7.3.2" shimmer "^1.2.1" -"@opentelemetry/otlp-exporter-base@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.54.2.tgz#fb2361665baec9e9600c5408747fc03124889f0a" - integrity sha512-NrNyxu6R/bGAwanhz1HI0aJWKR6xUED4TjCH4iWMlAfyRukGbI9Kt/Akd2sYLwRKNhfS+sKetKGCUQPMDyYYMA== +"@opentelemetry/otlp-exporter-base@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.55.0.tgz#db17332497e4a97e4ca85d394fb91cbbcfd76d84" + integrity sha512-iHQI0Zzq3h1T6xUJTVFwmFl5Dt5y1es+fl4kM+k5T/3YvmVyeYkSiF+wHCg6oKrlUAJfk+t55kaAu3sYmt7ZYA== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/otlp-transformer" "0.54.2" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/otlp-transformer" "0.55.0" -"@opentelemetry/otlp-grpc-exporter-base@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.54.2.tgz#cbcf53ddb92320d4260b1612d4fa9dd54da6caa5" - integrity sha512-HZtACQuLhgDcgNa9arGnVVGV28sSGQ+iwRgICWikFKiVxUsoWffqBvTxPa6G3DUTg5R+up97j/zxubEyxSAOHg== +"@opentelemetry/otlp-grpc-exporter-base@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.55.0.tgz#33644b96eeaa6a53431f45cd4b8180c887a6a8d7" + integrity sha512-gebbjl9FiSp52igWXuGjcWQKfB6IBwFGt5z1VFwTcVZVeEZevB6bJIqoFrhH4A02m7OUlpJ7l4EfRi3UtkNANQ== dependencies: "@grpc/grpc-js" "^1.7.1" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/otlp-exporter-base" "0.54.2" - "@opentelemetry/otlp-transformer" "0.54.2" - -"@opentelemetry/otlp-transformer@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.54.2.tgz#5952072cf37a7d5da0ac5491426126459c13c839" - integrity sha512-2tIjahJlMRRUz0A2SeE+qBkeBXBFkSjR0wqJ08kuOqaL8HNGan5iZf+A8cfrfmZzPUuMKCyY9I+okzFuFs6gKQ== - dependencies: - "@opentelemetry/api-logs" "0.54.2" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" - "@opentelemetry/sdk-logs" "0.54.2" - "@opentelemetry/sdk-metrics" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/otlp-exporter-base" "0.55.0" + "@opentelemetry/otlp-transformer" "0.55.0" + +"@opentelemetry/otlp-transformer@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.55.0.tgz#316b9325983e660cb4f18cb76fa84ce1c0cdad42" + integrity sha512-kVqEfxtp6mSN2Dhpy0REo1ghP4PYhC1kMHQJ2qVlO99Pc+aigELjZDfg7/YKmL71gR6wVGIeJfiql/eXL7sQPA== + dependencies: + "@opentelemetry/api-logs" "0.55.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" + "@opentelemetry/sdk-logs" "0.55.0" + "@opentelemetry/sdk-metrics" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" protobufjs "^7.3.0" -"@opentelemetry/propagator-b3@1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-1.27.0.tgz#6433b3fb2486548e94af7af37ab8b7932f198597" - integrity sha512-pTsko3gnMioe3FeWcwTQR3omo5C35tYsKKwjgTCTVCgd3EOWL9BZrMfgLBmszrwXABDfUrlAEFN/0W0FfQGynQ== +"@opentelemetry/propagator-b3@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-1.28.0.tgz#5e4c87c2097a18f88a5a4d19a57350f55517bb8a" + integrity sha512-Q7HVDIMwhN5RxL4bECMT4BdbyYSAKkC6U/RGn4NpO/cbqP6ZRg+BS7fPo/pGZi2w8AHfpIGQFXQmE8d2PC5xxQ== dependencies: - "@opentelemetry/core" "1.27.0" + "@opentelemetry/core" "1.28.0" -"@opentelemetry/propagator-jaeger@1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.27.0.tgz#8387d64805bd8edf72ed3267cf759c7887220201" - integrity sha512-EI1bbK0wn0yIuKlc2Qv2LKBRw6LiUWevrjCF80fn/rlaB+7StAi8Y5s8DBqAYNpY7v1q86+NjU18v7hj2ejU3A== +"@opentelemetry/propagator-jaeger@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.28.0.tgz#427158c3d0f8ea77c205c7b9cde09091c7f25ae3" + integrity sha512-wKJ94+s8467CnIRgoSRh0yXm/te0QMOwTq9J01PfG/RzYZvlvN8aRisN2oZ9SznB45dDGnMj3BhUlchSA9cEKA== dependencies: - "@opentelemetry/core" "1.27.0" + "@opentelemetry/core" "1.28.0" -"@opentelemetry/resources@1.27.0", "@opentelemetry/resources@^1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.27.0.tgz#1f91c270eb95be32f3511e9e6624c1c0f993c4ac" - integrity sha512-jOwt2VJ/lUD5BLc+PMNymDrUCpm5PKi1E9oSVYAvz01U/VdndGmrtV3DU1pG4AwlYhJRHbHfOUIlpBeXCPw6QQ== +"@opentelemetry/resources@1.28.0", "@opentelemetry/resources@^1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.28.0.tgz#c8c27ae7559c817f9d117f1bf96d76f893fb29f5" + integrity sha512-cIyXSVJjGeTICENN40YSvLDAq4Y2502hGK3iN7tfdynQLKWb3XWZQEkPc+eSx47kiy11YeFAlYkEfXwR1w8kfw== dependencies: - "@opentelemetry/core" "1.27.0" + "@opentelemetry/core" "1.28.0" "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/sdk-logs@0.54.2": - version "0.54.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.54.2.tgz#07cc61135b5acb09affa8cd290966027ee8c886a" - integrity sha512-yIbYqDLS/AtBbPjCjh6eSToGNRMqW2VR8RrKEy+G+J7dFG7pKoptTH5T+XlKPleP9NY8JZYIpgJBlI+Osi0rFw== +"@opentelemetry/sdk-logs@0.55.0": + version "0.55.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.55.0.tgz#78844e502167723a258c75a6b4f3de3900c13ea3" + integrity sha512-TSx+Yg/d48uWW6HtjS1AD5x6WPfLhDWLl/WxC7I2fMevaiBuKCuraxTB8MDXieCNnBI24bw9ytyXrDCswFfWgA== dependencies: - "@opentelemetry/api-logs" "0.54.2" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/api-logs" "0.55.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" -"@opentelemetry/sdk-metrics@1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.27.0.tgz#fb4f55017dc95a95ee00260262952b18e3e7c25c" - integrity sha512-JzWgzlutoXCydhHWIbLg+r76m+m3ncqvkCcsswXAQ4gqKS+LOHKhq+t6fx1zNytvLuaOUBur7EvWxECc4jPQKg== +"@opentelemetry/sdk-metrics@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.28.0.tgz#257b5295bbe9de1ad31c5e8cb43a660c25911d20" + integrity sha512-43tqMK/0BcKTyOvm15/WQ3HLr0Vu/ucAl/D84NO7iSlv6O4eOprxSHa3sUtmYkaZWHqdDJV0AHVz/R6u4JALVQ== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" -"@opentelemetry/sdk-trace-base@1.27.0", "@opentelemetry/sdk-trace-base@^1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.27.0.tgz#2276e4cd0d701a8faba77382b2938853a0907b54" - integrity sha512-btz6XTQzwsyJjombpeqCX6LhiMQYpzt2pIYNPnw0IPO/3AhT6yjnf8Mnv3ZC2A4eRYOjqrg+bfaXg9XHDRJDWQ== +"@opentelemetry/sdk-trace-base@1.28.0", "@opentelemetry/sdk-trace-base@^1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.28.0.tgz#6195dc8cd78bd74394cf54c67c5cbd8d1528516c" + integrity sha512-ceUVWuCpIao7Y5xE02Xs3nQi0tOGmMea17ecBdwtCvdo9ekmO+ijc9RFDgfifMl7XCBf41zne/1POM3LqSTZDA== dependencies: - "@opentelemetry/core" "1.27.0" - "@opentelemetry/resources" "1.27.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/resources" "1.28.0" "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/sdk-trace-node@^1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.27.0.tgz#ee890a1fedba6a2a313190ada80e5077865a8684" - integrity sha512-dWZp/dVGdUEfRBjBq2BgNuBlFqHCxyyMc8FsN0NX15X07mxSUO0SZRLyK/fdAVrde8nqFI/FEdMH4rgU9fqJfQ== - dependencies: - "@opentelemetry/context-async-hooks" "1.27.0" - "@opentelemetry/core" "1.27.0" - "@opentelemetry/propagator-b3" "1.27.0" - "@opentelemetry/propagator-jaeger" "1.27.0" - "@opentelemetry/sdk-trace-base" "1.27.0" +"@opentelemetry/sdk-trace-node@^1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.28.0.tgz#e3384802e12c689bb7a84809a732d091a2fbda09" + integrity sha512-N0sYfYXvHpP0FNIyc+UfhLnLSTOuZLytV0qQVrDWIlABeD/DWJIGttS7nYeR14gQLXch0M1DW8zm3VeN6Opwtg== + dependencies: + "@opentelemetry/context-async-hooks" "1.28.0" + "@opentelemetry/core" "1.28.0" + "@opentelemetry/propagator-b3" "1.28.0" + "@opentelemetry/propagator-jaeger" "1.28.0" + "@opentelemetry/sdk-trace-base" "1.28.0" semver "^7.5.2" "@opentelemetry/semantic-conventions@1.25.1": @@ -3338,7 +3289,7 @@ "@types/jsonfile" "*" "@types/node" "*" -"@types/geojson@*", "@types/geojson@^7946.0.10", "@types/geojson@^7946.0.14": +"@types/geojson@*", "@types/geojson@^7946.0", "@types/geojson@^7946.0.10", "@types/geojson@^7946.0.14", "@types/geojson@^7946.0.7": version "7946.0.14" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613" integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg== @@ -5524,7 +5475,14 @@ cross-env@^7.0.3: dependencies: cross-spawn "^7.0.1" -cross-fetch@3.1.5, cross-fetch@^3.0.4: +cross-fetch@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + +cross-fetch@^3.0.4: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== @@ -7805,31 +7763,31 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -i18next-browser-languagedetector@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz#ead34592edc96c6c3a618a51cb57ad027c5b5d87" - integrity sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g== +i18next-browser-languagedetector@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz#b6fdd9b43af67c47f2c26c9ba27710a1eaf31e2f" + integrity sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw== dependencies: - "@babel/runtime" "^7.19.4" + "@babel/runtime" "^7.23.2" -i18next-fs-backend@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-2.1.1.tgz#07c6393be856c5a398e3dfc1257bf8439841cd89" - integrity sha512-FTnj+UmNgT3YRml5ruRv0jMZDG7odOL/OP5PF5mOqvXud2vHrPOOs68Zdk6iqzL47cnnM0ZVkK2BAvpFeDJToA== +i18next-fs-backend@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-2.3.2.tgz#580b91c9a306b452112e0a1ad3b07e9fd266e567" + integrity sha512-LIwUlkqDZnUI8lnUxBnEj8K/FrHQTT/Sc+1rvDm9E8YvvY5YxzoEAASNx+W5M9DfD5s77lI5vSAFWeTp26B/3Q== -i18next-http-backend@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.2.0.tgz#f77c06dc8e766c7588bb38da2f5fa0614ba67b3f" - integrity sha512-Z4sM7R6tzdLknSPER9GisEBxKPg5FkI07UrQniuroZmS15PHQrcCPLyuGKj8SS68tf+O2aEDYSUnmy1TZqZSbw== +i18next-http-backend@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.6.2.tgz#b25516446ae6f251ce8231e70e6ffbca833d46a5" + integrity sha512-Hp/kd8/VuoxIHmxsknJXjkTYYHzivAyAF15pzliKzk2TiXC25rZCEerb1pUFoxz4IVrG3fCvQSY51/Lu4ECV4A== dependencies: - cross-fetch "3.1.5" + cross-fetch "4.0.0" -i18next@^22.4.15: - version "22.4.15" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.15.tgz#951882b751872994f8502b5a6ef6f796e6a7d7f8" - integrity sha512-yYudtbFrrmWKLEhl6jvKUYyYunj4bTBCe2qIUYAxbXoPusY7YmdwPvOE6fx6UIfWvmlbCWDItr7wIs8KEBZ5Zg== +i18next@^23.16.5: + version "23.16.6" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.6.tgz#85d09d66ec1334fdcc73ca11aa28409ea45df3ab" + integrity sha512-wGdE5rUfkZtrL5k6MCptxbpjmgwku4rBRVU/YOJ7Xfd841fgaZjlxHpVJ5NIz8sfSvAJhEhJrvJ8qE7AWXE4Xg== dependencies: - "@babel/runtime" "^7.20.6" + "@babel/runtime" "^7.23.2" iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" @@ -10174,7 +10132,7 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.7.0: +node-fetch@^2.6.12, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -11559,10 +11517,10 @@ react-html-parser@^2.0.2: dependencies: htmlparser2 "^3.9.0" -react-i18next@^12.2.2: - version "12.2.2" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.2.2.tgz#38a6fad11acf4f2abfc5611bdb6b1918d0f47578" - integrity sha512-KBB6buBmVKXUWNxXHdnthp+38gPyBT46hJCAIQ8rX19NFL/m2ahte2KARfIDf2tMnSAL7wwck6eDOd/9zn6aFg== +react-i18next@^12.3.1: + version "12.3.1" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.3.1.tgz#30134a41a2a71c61dc69c6383504929aed1c99e7" + integrity sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA== dependencies: "@babel/runtime" "^7.20.6" html-parse-stringify "^3.0.1" @@ -11918,11 +11876,6 @@ reflect.ownkeys@^0.2.0: resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - regenerator-runtime@^0.13.4: version "0.13.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"