diff --git a/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts b/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts index eec4f0f..29ad295 100644 --- a/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts +++ b/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts @@ -132,11 +132,37 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader } public async updateShuttleDataForSystem() { - const systemId = this.passioSystemId; + try { + const json = await this.fetchShuttleDataJson(); + const shuttles = this.constructShuttlesFromJson(json); + if (shuttles !== null) { + await this.updateShuttleDataInRepository(shuttles); + } else { + console.warn(`Shuttle update failed for the following JSON: ${JSON.stringify(json)}`) + } + } catch(e: any) { + throw new ApiResponseError(e.message); + } + } + + private async updateShuttleDataInRepository(shuttles: IShuttle[]) { const shuttleIdsToPrune = await this.constructExistingEntityIdSet(async () => { return await this.repository.getShuttles(); }); + await Promise.all(shuttles.map(async (shuttle) => { + await this.repository.addOrUpdateShuttle(shuttle); + shuttleIdsToPrune.delete(shuttle.id); + })); + + await Promise.all(Array.from(shuttleIdsToPrune).map(async (shuttleId) => { + await this.repository.removeShuttleIfExists(shuttleId); + })); + } + + private async fetchShuttleDataJson() { + const systemId = this.passioSystemId; + const params = { getBuses: "2" }; @@ -151,44 +177,37 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader const query = new URLSearchParams(params).toString(); - try { - const response = await fetch(`${this.baseUrl}?${query}`, { - method: "POST", - body: formData, + const response = await fetch(`${this.baseUrl}?${query}`, { + method: "POST", + body: formData, + }); + return await response.json(); + } + + private constructShuttlesFromJson(json: any): IShuttle[] | null { + if (json.buses && json.buses["-1"] === undefined) { + const jsonBuses = Object.values(json.buses).map((busesArr: any) => { + return busesArr[0]; }); - const json = await response.json(); - if (json.buses && json.buses["-1"] === undefined) { - const jsonBuses = Object.values(json.buses).map((busesArr: any) => { - return busesArr[0]; - }); - - await Promise.all(jsonBuses.map(async (jsonBus: any) => { - const constructedShuttle: IShuttle = { - name: jsonBus.bus, - coordinates: { - latitude: parseFloat(jsonBus.latitude), - longitude: parseFloat(jsonBus.longitude), - }, - routeId: jsonBus.routeId, - systemId: this.systemIdForConstructedData, - id: `${jsonBus.busId}`, - orientationInDegrees: parseFloat(jsonBus.calculatedCourse), - updatedTime: new Date(), - } - - await this.repository.addOrUpdateShuttle(constructedShuttle); - - shuttleIdsToPrune.delete(constructedShuttle.id); - })); - } - - await Promise.all(Array.from(shuttleIdsToPrune).map(async (shuttleId) => { - await this.repository.removeShuttleIfExists(shuttleId); - })); - } catch(e: any) { - throw new ApiResponseError(e.message); + return jsonBuses.map((jsonBus: any) => { + const constructedShuttle: IShuttle = { + name: jsonBus.bus, + coordinates: { + latitude: parseFloat(jsonBus.latitude), + longitude: parseFloat(jsonBus.longitude), + }, + routeId: jsonBus.routeId, + systemId: this.systemIdForConstructedData, + id: `${jsonBus.busId}`, + orientationInDegrees: parseFloat(jsonBus.calculatedCourse), + updatedTime: new Date(), + } + return constructedShuttle; + }); } + + return null; } public async updateEtaDataForExistingStopsForSystem() { @@ -331,4 +350,5 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader })) } } + } diff --git a/src/loaders/shuttle/__tests__/ApiBasedShuttleRepositoryLoaderTests.test.ts b/src/loaders/shuttle/__tests__/ApiBasedShuttleRepositoryLoaderTests.test.ts index ddcf095..d62f91b 100644 --- a/src/loaders/shuttle/__tests__/ApiBasedShuttleRepositoryLoaderTests.test.ts +++ b/src/loaders/shuttle/__tests__/ApiBasedShuttleRepositoryLoaderTests.test.ts @@ -34,10 +34,10 @@ describe("ApiBasedShuttleRepositoryLoader", () => { describe("fetchAndUpdateAll", () => { it("calls all the correct methods", async () => { const spies = { - fetchAndUpdateRouteDataForSystem: jest.spyOn(loader, "fetchAndUpdateRouteDataForSystem"), - fetchAndUpdateStopAndPolylineDataForRoutesInSystem: jest.spyOn(loader, "fetchAndUpdateStopAndPolylineDataForRoutesInSystem"), - fetchAndUpdateShuttleDataForSystem: jest.spyOn(loader, "fetchAndUpdateShuttleDataForSystem"), - fetchAndUpdateEtaDataForExistingStopsForSystem: jest.spyOn(loader, "fetchAndUpdateEtaDataForExistingStopsForSystem"), + updateRouteDataForSystem: jest.spyOn(loader, "updateRouteDataForSystem"), + updateStopAndPolylineDataForRoutesInSystem: jest.spyOn(loader, "updateStopAndPolylineDataForRoutesInSystem"), + updateShuttleDataForSystem: jest.spyOn(loader, "updateShuttleDataForSystem"), + updateEtaDataForExistingStopsForSystem: jest.spyOn(loader, "updateEtaDataForExistingStopsForSystem"), }; Object.values(spies).forEach((spy: any) => { @@ -153,7 +153,7 @@ describe("ApiBasedShuttleRepositoryLoader", () => { describe("fetchAndUpdateEtaDataForExistingStopsForSystem", () => { it("calls fetchAndUpdateEtaDataForStopId for every stop in repository", async () => { - const spy = jest.spyOn(loader, "fetchAndUpdateEtaDataForStopId"); + const spy = jest.spyOn(loader, "updateEtaDataForStopId"); const stops = generateMockStops(); stops.forEach((stop) => {