mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-17 07:50:31 +00:00
Merge pull request #4 from brendan-ch/feat/integrate-apibasedrepository
feat/integrate-apibasedrepository
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { GetterRepository } from "./repositories/GetterRepository";
|
||||
|
||||
export interface ServerContext {
|
||||
repository: GetterRepository
|
||||
repository: GetterRepository;
|
||||
apiBasedRepository: GetterRepository;
|
||||
}
|
||||
10
src/index.ts
10
src/index.ts
@@ -6,6 +6,7 @@ import { loadTestData } from "./loaders/loadTestData";
|
||||
import { ServerContext } from "./ServerContext";
|
||||
import { UnoptimizedInMemoryRepository } from "./repositories/UnoptimizedInMemoryRepository";
|
||||
import { RepositoryDataLoader } from "./loaders/RepositoryDataLoader";
|
||||
import { ApiBasedRepository } from "./repositories/ApiBasedRepository";
|
||||
|
||||
const typeDefs = readFileSync("./schema.graphqls", "utf8");
|
||||
|
||||
@@ -24,6 +25,14 @@ async function main() {
|
||||
);
|
||||
await repositoryDataUpdater.start();
|
||||
|
||||
// TODO: Migrate all logic over to this repository
|
||||
const apiBasedRepository = new ApiBasedRepository();
|
||||
|
||||
const systemIds = ["263"];
|
||||
await Promise.all(systemIds.map(async (systemId) => {
|
||||
await apiBasedRepository.seedCacheForSystemId(systemId);
|
||||
}));
|
||||
|
||||
const { url } = await startStandaloneServer(server, {
|
||||
listen: {
|
||||
port: process.env.PORT ? parseInt(process.env.PORT) : 4000,
|
||||
@@ -31,6 +40,7 @@ async function main() {
|
||||
context: async ({ req, res }) => {
|
||||
return {
|
||||
repository,
|
||||
apiBasedRepository,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -68,10 +68,9 @@ export class ApiBasedRepository implements GetterRepository {
|
||||
* @param systemId
|
||||
*/
|
||||
public async seedCacheForSystemId(systemId: string): Promise<void> {
|
||||
await this.getShuttlesBySystemId(systemId);
|
||||
await this.getShuttlesByRouteId(systemId);
|
||||
await this.getStopsBySystemId(systemId);
|
||||
await this.getSystemById(systemId);
|
||||
await this.updateShuttlesForSystemIfTTL(systemId);
|
||||
await this.updateEtasForSystemIfTTL(systemId);
|
||||
await this.updateStopsForSystemIdIfTTL(systemId);
|
||||
}
|
||||
|
||||
public async getEtaForShuttleAndStopId(shuttleId: string, stopId: string): Promise<IEta | null> {
|
||||
@@ -84,7 +83,7 @@ export class ApiBasedRepository implements GetterRepository {
|
||||
|
||||
if (this.cache?.etasForStopId && this.cache.etasForStopId[stopId]) {
|
||||
const etas = this.cache.etasForStopId[stopId];
|
||||
const foundEta = etas.find((eta) => eta.stopId === stopId);
|
||||
const foundEta = etas.find((eta) => eta.shuttleId === shuttleId);
|
||||
if (foundEta) {
|
||||
return foundEta;
|
||||
}
|
||||
@@ -306,7 +305,7 @@ ${json}`);
|
||||
public async getStopsBySystemId(systemId: string): Promise<IStop[]> {
|
||||
await this.updateStopsForSystemIdIfTTL(systemId);
|
||||
|
||||
if (!this.cache.stopsBySystemId || this.cache.stopsBySystemId[systemId]) {
|
||||
if (!this.cache.stopsBySystemId || !this.cache.stopsBySystemId[systemId]) {
|
||||
return [];
|
||||
}
|
||||
return this.cache.stopsBySystemId[systemId];
|
||||
@@ -340,6 +339,10 @@ ${json}`);
|
||||
if (json.stops) {
|
||||
const jsonStops = Object.values(json.stops);
|
||||
|
||||
// TODO: restore normal cache behavior
|
||||
this.cache.stopsBySystemId = {};
|
||||
this.cache.stopByStopId = {};
|
||||
|
||||
await Promise.all(jsonStops.map(async (stop: any) => {
|
||||
const constructedStop: IStop = {
|
||||
name: stop.name,
|
||||
@@ -351,13 +354,21 @@ ${json}`);
|
||||
},
|
||||
};
|
||||
|
||||
if (this.cache.stopsBySystemId) {
|
||||
this.cache.stopsBySystemId[systemId]?.push(constructedStop);
|
||||
if (!this.cache.stopsBySystemId) {
|
||||
this.cache.stopsBySystemId = {};
|
||||
}
|
||||
|
||||
if (this.cache.stopByStopId) {
|
||||
this.cache.stopByStopId[constructedStop.id] = constructedStop;
|
||||
if (!this.cache.stopsBySystemId[systemId]) {
|
||||
this.cache.stopsBySystemId[systemId] = [];
|
||||
}
|
||||
|
||||
this.cache.stopsBySystemId[systemId].push(constructedStop);
|
||||
|
||||
if (!this.cache.stopByStopId) {
|
||||
this.cache.stopByStopId = {};
|
||||
}
|
||||
|
||||
this.cache.stopByStopId[constructedStop.id] = constructedStop;
|
||||
}));
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -132,10 +132,10 @@ export const resolvers: Resolvers<ServerContext> = {
|
||||
Shuttle: {
|
||||
eta: async (parent, args, contextValue, info) => {
|
||||
if (!args.forStopId) return null;
|
||||
const etaForStopId = await contextValue.repository.getEtaForShuttleAndStopId(parent.id, args.forStopId);
|
||||
const etaForStopId = await contextValue.apiBasedRepository.getEtaForShuttleAndStopId(parent.id, args.forStopId);
|
||||
if (etaForStopId === null) return null;
|
||||
|
||||
const stop = await contextValue.repository.getStopById(etaForStopId.stopId);
|
||||
const stop = await contextValue.apiBasedRepository.getStopById(etaForStopId.stopId);
|
||||
if (stop === null) return null;
|
||||
|
||||
return {
|
||||
@@ -149,14 +149,14 @@ export const resolvers: Resolvers<ServerContext> = {
|
||||
};
|
||||
},
|
||||
etas: async (parent, args, contextValue, info) => {
|
||||
const etasForShuttle = await contextValue.repository.getEtasForShuttleId(parent.id);
|
||||
const etasForShuttle = await contextValue.apiBasedRepository.getEtasForShuttleId(parent.id);
|
||||
if (!etasForShuttle) return null;
|
||||
|
||||
const computedEtas = await Promise.all(etasForShuttle.map(async ({
|
||||
secondsRemaining,
|
||||
stopId,
|
||||
}): Promise<Eta | null> => {
|
||||
const stop = await contextValue.repository.getStopById(stopId);
|
||||
const stop = await contextValue.apiBasedRepository.getStopById(stopId);
|
||||
if (stop === null) return null;
|
||||
|
||||
return {
|
||||
|
||||
115
test/jsonSnapshots/genericEtaDataBySystemId.ts
Normal file
115
test/jsonSnapshots/genericEtaDataBySystemId.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
// Snapshot taken from the Passio GO! API
|
||||
export const genericEtaDataByStopId = {
|
||||
"ETAs": {
|
||||
"177666": [
|
||||
{
|
||||
"OOS": 0,
|
||||
"busName": "08",
|
||||
"distance": 1,
|
||||
"speed": 10.028535400123669,
|
||||
"routeBlockId": "142270",
|
||||
"actualRouteBlockId": "142270",
|
||||
"arrived": null,
|
||||
"eta": "10 min ",
|
||||
"color": "#000000",
|
||||
"bg": "#ffea3f",
|
||||
"order": 0,
|
||||
"dwell": null,
|
||||
"stopsAmount": 2,
|
||||
"secondsSpent": 587,
|
||||
"etaR": "10",
|
||||
"error": null,
|
||||
"outdated": 0,
|
||||
"routeId": "53966",
|
||||
"serviceTime": "",
|
||||
"scheduleTimes": [],
|
||||
"goShowSchedule": 0,
|
||||
"looping": "1",
|
||||
"routeGroupId": "6703",
|
||||
"busId": 5577,
|
||||
"tripId": 751430,
|
||||
"deviceId": 402840,
|
||||
"created": "2025-01-07 15:00:09",
|
||||
"routePointPosition": 6,
|
||||
"routeStopPosition": 1,
|
||||
"stopRoutePointPosition": 217,
|
||||
"timezoneOffset": -10800,
|
||||
"busLatLng": [
|
||||
33.7933406,
|
||||
-117.8539321
|
||||
],
|
||||
"busProjectionLatlng": {
|
||||
"lat": 33.79331052666975,
|
||||
"lng": -117.85392945849208
|
||||
},
|
||||
"busProjectionError": 3,
|
||||
"stopId": "177666",
|
||||
"theStop": {
|
||||
"name": "Chapman Court",
|
||||
"position": 3,
|
||||
"userId": "263",
|
||||
"routeStopId": "1348785",
|
||||
"busId": 5577,
|
||||
"routeName": "Red Route",
|
||||
"shortName": null,
|
||||
"routeId": "53966",
|
||||
"stopId": "177666"
|
||||
}
|
||||
},
|
||||
{
|
||||
"OOS": 0,
|
||||
"busName": "07",
|
||||
"distance": 1,
|
||||
"speed": 12.160256921380398,
|
||||
"routeBlockId": "142270",
|
||||
"actualRouteBlockId": "142270",
|
||||
"arrived": null,
|
||||
"eta": "11 min ",
|
||||
"color": "#000000",
|
||||
"bg": "#ffea3f",
|
||||
"order": 0,
|
||||
"dwell": null,
|
||||
"stopsAmount": 2,
|
||||
"secondsSpent": 635,
|
||||
"etaR": "11",
|
||||
"error": null,
|
||||
"outdated": 0,
|
||||
"routeId": "53966",
|
||||
"serviceTime": "",
|
||||
"scheduleTimes": [],
|
||||
"goShowSchedule": 0,
|
||||
"looping": "1",
|
||||
"routeGroupId": "6703",
|
||||
"busId": 5576,
|
||||
"tripId": 751430,
|
||||
"deviceId": 441065,
|
||||
"created": "2025-01-07 15:00:10",
|
||||
"routePointPosition": 448,
|
||||
"routeStopPosition": 4,
|
||||
"stopRoutePointPosition": 217,
|
||||
"timezoneOffset": -10800,
|
||||
"busLatLng": [
|
||||
33.7933284,
|
||||
-117.855132
|
||||
],
|
||||
"busProjectionLatlng": {
|
||||
"lat": 33.79332033922653,
|
||||
"lng": -117.85513217762522
|
||||
},
|
||||
"busProjectionError": 1,
|
||||
"stopId": "177666",
|
||||
"theStop": {
|
||||
"name": "Chapman Court",
|
||||
"position": 3,
|
||||
"userId": "263",
|
||||
"routeStopId": "1348785",
|
||||
"busId": 5576,
|
||||
"routeName": "Red Route",
|
||||
"shortName": null,
|
||||
"routeId": "53966",
|
||||
"stopId": "177666"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
106
test/jsonSnapshots/genericShuttleDataBySystemId.ts
Normal file
106
test/jsonSnapshots/genericShuttleDataBySystemId.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
// Snapshot taken from the Passio GO! API
|
||||
export const genericShuttleDataBySystemId = {
|
||||
"alertCRC": "23c1b91c",
|
||||
"buses": {
|
||||
"402840": [
|
||||
{
|
||||
"deviceId": 402840,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "08",
|
||||
"busId": 5577,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.791781800",
|
||||
"longitude": "-117.858964600",
|
||||
"calculatedCourse": "351.796001302109",
|
||||
"outOfService": 0,
|
||||
"more": "102",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "08",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"404873": [
|
||||
{
|
||||
"deviceId": 404873,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "10",
|
||||
"busId": 7105,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.789331300",
|
||||
"longitude": "-117.888790600",
|
||||
"calculatedCourse": "76.005762226701",
|
||||
"outOfService": 0,
|
||||
"more": "101",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "10",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"421421": [
|
||||
{
|
||||
"deviceId": 421421,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "17",
|
||||
"busId": 12502,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142660",
|
||||
"latitude": "33.790699500",
|
||||
"longitude": "-117.890385500",
|
||||
"calculatedCourse": "10.65684824528148",
|
||||
"outOfService": 0,
|
||||
"more": "101",
|
||||
"totalCap": 32,
|
||||
"color": "#bd9e39",
|
||||
"busName": "17",
|
||||
"busType": "Shuttle Bus",
|
||||
"routeId": "54256",
|
||||
"route": "Gold Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"441065": [
|
||||
{
|
||||
"deviceId": 441065,
|
||||
"created": "08:19 PM",
|
||||
"createdTime": "08:19 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "07",
|
||||
"busId": 5576,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.793278900",
|
||||
"longitude": "-117.852629400",
|
||||
"calculatedCourse": "299.74488110904485",
|
||||
"outOfService": 0,
|
||||
"more": "22",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "07",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"microtime": 0.023222923278808594,
|
||||
"time": {
|
||||
"263": "08:24 PM"
|
||||
}
|
||||
};
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
ApiBasedRepositoryMillisecondTTLs
|
||||
} from "../../src/repositories/ApiBasedRepository";
|
||||
import { IEta, IShuttle, IStop } from "../../src/entities/entities";
|
||||
import { genericEtaDataByStopId } from "../jsonSnapshots/genericEtaDataBySystemId";
|
||||
import { genericShuttleDataBySystemId } from "../jsonSnapshots/genericShuttleDataBySystemId";
|
||||
|
||||
/**
|
||||
* Update the global fetch function to return a specific object.
|
||||
@@ -31,226 +33,6 @@ beforeEach(() => {
|
||||
resetGlobalFetchMockJson();
|
||||
})
|
||||
|
||||
// Snapshots taken from the Passio GO! API
|
||||
const genericEtaDataByStopId = {
|
||||
"ETAs": {
|
||||
"177666": [
|
||||
{
|
||||
"OOS": 0,
|
||||
"busName": "08",
|
||||
"distance": 1,
|
||||
"speed": 10.028535400123669,
|
||||
"routeBlockId": "142270",
|
||||
"actualRouteBlockId": "142270",
|
||||
"arrived": null,
|
||||
"eta": "10 min ",
|
||||
"color": "#000000",
|
||||
"bg": "#ffea3f",
|
||||
"order": 0,
|
||||
"dwell": null,
|
||||
"stopsAmount": 2,
|
||||
"secondsSpent": 587,
|
||||
"etaR": "10",
|
||||
"error": null,
|
||||
"outdated": 0,
|
||||
"routeId": "53966",
|
||||
"serviceTime": "",
|
||||
"scheduleTimes": [],
|
||||
"goShowSchedule": 0,
|
||||
"looping": "1",
|
||||
"routeGroupId": "6703",
|
||||
"busId": 5577,
|
||||
"tripId": 751430,
|
||||
"deviceId": 402840,
|
||||
"created": "2025-01-07 15:00:09",
|
||||
"routePointPosition": 6,
|
||||
"routeStopPosition": 1,
|
||||
"stopRoutePointPosition": 217,
|
||||
"timezoneOffset": -10800,
|
||||
"busLatLng": [
|
||||
33.7933406,
|
||||
-117.8539321
|
||||
],
|
||||
"busProjectionLatlng": {
|
||||
"lat": 33.79331052666975,
|
||||
"lng": -117.85392945849208
|
||||
},
|
||||
"busProjectionError": 3,
|
||||
"stopId": "177666",
|
||||
"theStop": {
|
||||
"name": "Chapman Court",
|
||||
"position": 3,
|
||||
"userId": "263",
|
||||
"routeStopId": "1348785",
|
||||
"busId": 5577,
|
||||
"routeName": "Red Route",
|
||||
"shortName": null,
|
||||
"routeId": "53966",
|
||||
"stopId": "177666"
|
||||
}
|
||||
},
|
||||
{
|
||||
"OOS": 0,
|
||||
"busName": "07",
|
||||
"distance": 1,
|
||||
"speed": 12.160256921380398,
|
||||
"routeBlockId": "142270",
|
||||
"actualRouteBlockId": "142270",
|
||||
"arrived": null,
|
||||
"eta": "11 min ",
|
||||
"color": "#000000",
|
||||
"bg": "#ffea3f",
|
||||
"order": 0,
|
||||
"dwell": null,
|
||||
"stopsAmount": 2,
|
||||
"secondsSpent": 635,
|
||||
"etaR": "11",
|
||||
"error": null,
|
||||
"outdated": 0,
|
||||
"routeId": "53966",
|
||||
"serviceTime": "",
|
||||
"scheduleTimes": [],
|
||||
"goShowSchedule": 0,
|
||||
"looping": "1",
|
||||
"routeGroupId": "6703",
|
||||
"busId": 5576,
|
||||
"tripId": 751430,
|
||||
"deviceId": 441065,
|
||||
"created": "2025-01-07 15:00:10",
|
||||
"routePointPosition": 448,
|
||||
"routeStopPosition": 4,
|
||||
"stopRoutePointPosition": 217,
|
||||
"timezoneOffset": -10800,
|
||||
"busLatLng": [
|
||||
33.7933284,
|
||||
-117.855132
|
||||
],
|
||||
"busProjectionLatlng": {
|
||||
"lat": 33.79332033922653,
|
||||
"lng": -117.85513217762522
|
||||
},
|
||||
"busProjectionError": 1,
|
||||
"stopId": "177666",
|
||||
"theStop": {
|
||||
"name": "Chapman Court",
|
||||
"position": 3,
|
||||
"userId": "263",
|
||||
"routeStopId": "1348785",
|
||||
"busId": 5576,
|
||||
"routeName": "Red Route",
|
||||
"shortName": null,
|
||||
"routeId": "53966",
|
||||
"stopId": "177666"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
const genericShuttleDataBySystemId = {
|
||||
"alertCRC": "23c1b91c",
|
||||
"buses": {
|
||||
"402840": [
|
||||
{
|
||||
"deviceId": 402840,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "08",
|
||||
"busId": 5577,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.791781800",
|
||||
"longitude": "-117.858964600",
|
||||
"calculatedCourse": "351.796001302109",
|
||||
"outOfService": 0,
|
||||
"more": "102",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "08",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"404873": [
|
||||
{
|
||||
"deviceId": 404873,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "10",
|
||||
"busId": 7105,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.789331300",
|
||||
"longitude": "-117.888790600",
|
||||
"calculatedCourse": "76.005762226701",
|
||||
"outOfService": 0,
|
||||
"more": "101",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "10",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"421421": [
|
||||
{
|
||||
"deviceId": 421421,
|
||||
"created": "08:24 PM",
|
||||
"createdTime": "08:24 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "17",
|
||||
"busId": 12502,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142660",
|
||||
"latitude": "33.790699500",
|
||||
"longitude": "-117.890385500",
|
||||
"calculatedCourse": "10.65684824528148",
|
||||
"outOfService": 0,
|
||||
"more": "101",
|
||||
"totalCap": 32,
|
||||
"color": "#bd9e39",
|
||||
"busName": "17",
|
||||
"busType": "Shuttle Bus",
|
||||
"routeId": "54256",
|
||||
"route": "Gold Route",
|
||||
"outdated": 0
|
||||
}
|
||||
],
|
||||
"441065": [
|
||||
{
|
||||
"deviceId": 441065,
|
||||
"created": "08:19 PM",
|
||||
"createdTime": "08:19 PM",
|
||||
"paxLoad": 0,
|
||||
"bus": "07",
|
||||
"busId": 5576,
|
||||
"userId": "263",
|
||||
"routeBlockId": "142270",
|
||||
"latitude": "33.793278900",
|
||||
"longitude": "-117.852629400",
|
||||
"calculatedCourse": "299.74488110904485",
|
||||
"outOfService": 0,
|
||||
"more": "22",
|
||||
"totalCap": 20,
|
||||
"color": "#d62728",
|
||||
"busName": "07",
|
||||
"busType": "",
|
||||
"routeId": "53966",
|
||||
"route": "Red Route",
|
||||
"outdated": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"microtime": 0.023222923278808594,
|
||||
"time": {
|
||||
"263": "08:24 PM"
|
||||
}
|
||||
}
|
||||
|
||||
describe("getEtaForShuttleAndStopId", () => {
|
||||
test("getEtaForShuttleAndStopId returns correct ETA data", async () => {
|
||||
@@ -264,6 +46,12 @@ describe("getEtaForShuttleAndStopId", () => {
|
||||
shuttleId: "5577",
|
||||
stopId: "177666",
|
||||
millisecondsSinceEpoch: Date.now(),
|
||||
},
|
||||
{
|
||||
secondsRemaining: 226,
|
||||
shuttleId: "9909",
|
||||
stopId: "177666",
|
||||
millisecondsSinceEpoch: Date.now(),
|
||||
}
|
||||
],
|
||||
},
|
||||
@@ -292,6 +80,8 @@ describe("getEtaForShuttleAndStopId", () => {
|
||||
|
||||
expect(result?.secondsRemaining).toEqual(587);
|
||||
expect(result?.millisecondsSinceEpoch).toBeDefined();
|
||||
expect(result?.shuttleId).toEqual("5577");
|
||||
expect(result?.stopId).toEqual("177666");
|
||||
});
|
||||
|
||||
test("getEtaForShuttleAndStopId returns null if API call is invalid and cache is empty", async () => {
|
||||
|
||||
Reference in New Issue
Block a user