update repository loader and tests to support only one system

This commit is contained in:
2025-04-06 10:14:24 -07:00
parent 5936c2b743
commit d584d1f58b
4 changed files with 52 additions and 67 deletions

View File

@@ -15,7 +15,7 @@ export class ApiResponseError extends Error {
* which inherit from `IEntityWithId`.
*/
export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader {
supportedSystemIds = ["263"];
systemId = "263";
baseUrl = "https://passiogo.com/mapGetData.php";
constructor(
@@ -38,9 +38,7 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
};
const query = new URLSearchParams(params).toString();
const systemIds = await this.constructExistingEntityIdSet(async () => {
return await this.repository.getSystemIfExists();
})
const system = await this.repository.getSystemIfExists();
try {
const response = await fetch(`${this.baseUrl}?${query}`);
@@ -52,34 +50,28 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
if (typeof json.all === "object") {
// filter down to supported systems
const filteredSystems = json.all.filter((jsonSystem: any) => this.supportedSystemIds.includes(jsonSystem.id));
await Promise.all(filteredSystems.map(async (system: any) => {
const filteredSystem = json.all.find((jsonSystem: any) => jsonSystem.id === this.systemId);
if (filteredSystem !== undefined) {
const constructedSystem: ISystem = {
id: system.id,
name: system.fullname,
id: filteredSystem.id,
name: filteredSystem.fullname,
};
await this.repository.updateSystem(constructedSystem);
systemIds.delete(constructedSystem.id);
}));
}
} else {
throw new Error("Received JSON object does not contain `all` field")
}
// Prune systems
await Promise.all(Array.from(systemIds).map(async (systemId) => {
await this.repository.removeSystemIfExists(systemId);
}));
} catch(e: any) {
throw new ApiResponseError(e.message);
}
}
public async fetchAndUpdateRouteDataForExistingSystemsInRepository() {
const systems = await this.repository.getSystemIfExists();
await Promise.all(systems.map(async (system) => {
public async fetchAndUpdateRouteDataForExistingSystemInRepository() {
const system = await this.repository.getSystemIfExists();
if (system !== null) {
await this.fetchAndUpdateRouteDataForSystemId(system.id);
}));
}
}
public async fetchAndUpdateRouteDataForSystemId(systemId: string) {
@@ -131,11 +123,11 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
}
}
public async fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemsInRepository() {
const systems = await this.repository.getSystemIfExists();
await Promise.all(systems.map(async (system: ISystem) => {
public async fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemInRepository() {
const system = await this.repository.getSystemIfExists();
if (system !== null) {
await this.fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId(system.id);
}));
}
}
public async fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId(systemId: string) {
@@ -177,12 +169,13 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
}
}
public async fetchAndUpdateShuttleDataForExistingSystemsInRepository() {
const systems = await this.repository.getSystemIfExists();
await Promise.all(systems.map(async (system: ISystem) => {
public async fetchAndUpdateShuttleDataForExistingSystemInRepository() {
const system = await this.repository.getSystemIfExists();
if (system !== null) {
const systemId = system.id;
await this.fetchAndUpdateShuttleDataForSystemId(systemId);
}));
}
}
public async fetchAndUpdateShuttleDataForSystemId(systemId: string) {
@@ -243,12 +236,12 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader
}
}
public async fetchAndUpdateEtaDataForExistingStopsForSystemsInRepository() {
const systems = await this.repository.getSystemIfExists()
await Promise.all(systems.map(async (system: ISystem) => {
public async fetchAndUpdateEtaDataForExistingStopsForSystemInRepository() {
const system = await this.repository.getSystemIfExists()
if (system !== null) {
const systemId = system.id;
await this.fetchAndUpdateEtaDataForExistingStopsForSystemId(systemId);
}))
}
}
public async fetchAndUpdateEtaDataForExistingStopsForSystemId(systemId: string) {

View File

@@ -1,12 +1,12 @@
export interface ShuttleRepositoryLoader {
fetchAndUpdateSystemData(): Promise<void>;
fetchAndUpdateRouteDataForExistingSystemsInRepository(): Promise<void>;
fetchAndUpdateRouteDataForExistingSystemInRepository(): Promise<void>;
fetchAndUpdateRouteDataForSystemId(systemId: string): Promise<void>;
fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemsInRepository(): Promise<void>;
fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemInRepository(): Promise<void>;
fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId(systemId: string): Promise<void>;
fetchAndUpdateShuttleDataForExistingSystemsInRepository(): Promise<void>;
fetchAndUpdateShuttleDataForExistingSystemInRepository(): Promise<void>;
fetchAndUpdateShuttleDataForSystemId(systemId: string): Promise<void>;
fetchAndUpdateEtaDataForExistingStopsForSystemsInRepository(): Promise<void>;
fetchAndUpdateEtaDataForExistingStopsForSystemInRepository(): Promise<void>;
fetchAndUpdateEtaDataForExistingStopsForSystemId(systemId: string): Promise<void>;
fetchAndUpdateEtaDataForStopId(stopId: string): Promise<void>;
}

View File

@@ -47,14 +47,14 @@ export class TimedApiBasedShuttleRepositoryLoader extends ApiBasedShuttleReposit
try {
await this.fetchAndUpdateSystemData();
await this.fetchAndUpdateRouteDataForExistingSystemsInRepository();
await this.fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemsInRepository();
await this.fetchAndUpdateShuttleDataForExistingSystemsInRepository();
await this.fetchAndUpdateRouteDataForExistingSystemInRepository();
await this.fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemInRepository();
await this.fetchAndUpdateShuttleDataForExistingSystemInRepository();
// Because ETA method doesn't support pruning yet,
// add a call to the clear method here
await this.repository.clearEtaData();
await this.fetchAndUpdateEtaDataForExistingStopsForSystemsInRepository();
await this.fetchAndUpdateEtaDataForExistingStopsForSystemInRepository();
} catch (e) {
console.error(e);
}

View File

@@ -45,12 +45,8 @@ describe("ApiBasedRepositoryLoader", () => {
await loader.fetchAndUpdateSystemData();
// Assert
const systems = await loader.repository.getSystemIfExists();
if (loader.supportedSystemIds.length < numberOfSystemsInResponse) {
expect(systems).toHaveLength(loader.supportedSystemIds.length);
} else {
expect(systems).toHaveLength(numberOfSystemsInResponse);
}
const system = await loader.repository.getSystemIfExists();
expect(system).not.toBeNull();
});
it("throws the correct error if the API response contains no data", async () => {
@@ -72,18 +68,17 @@ describe("ApiBasedRepositoryLoader", () => {
describe("fetchAndUpdateRouteDataForExistingSystemsInRepository", () => {
test("calls fetchAndUpdateRouteDataForSystemId for all systems in repository", async () => {
test("calls fetchAndUpdateRouteDataForSystemId for system in repository", async () => {
const spy = jest.spyOn(loader, "fetchAndUpdateRouteDataForSystemId");
const systems = generateMockSystems();
await Promise.all(systems.map(async (system) => {
await loader.repository.updateSystem(system);
}));
await loader.repository.updateSystem(systems[0]);
await loader.fetchAndUpdateRouteDataForExistingSystemsInRepository();
await loader.fetchAndUpdateRouteDataForExistingSystemInRepository();
expect(spy.mock.calls.length).toBe(systems.length);
expect(spy.mock.calls.length).toBe(1);
expect(spy).toHaveBeenCalledWith(systems[0].id)
});
});
@@ -122,18 +117,17 @@ describe("ApiBasedRepositoryLoader", () => {
});
describe("fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemsInRepository", () => {
it("calls fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId for every system", async () => {
it("calls fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId for system", async () => {
const spy = jest.spyOn(loader, "fetchAndUpdateStopAndPolylineDataForRoutesWithSystemId");
const systems = generateMockSystems();
await Promise.all(systems.map(async (system) => {
await loader.repository.updateSystem(system);
}));
await loader.repository.updateSystem(systems[0]);
await loader.fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemsInRepository();
await loader.fetchAndUpdateStopAndPolylineDataForRoutesInExistingSystemInRepository();
expect(spy.mock.calls.length).toBe(systems.length);
expect(spy.mock.calls.length).toBe(1);
expect(spy).toHaveBeenCalledWith(systems[0].id)
});
})
@@ -182,13 +176,12 @@ describe("ApiBasedRepositoryLoader", () => {
const spy = jest.spyOn(loader, "fetchAndUpdateShuttleDataForSystemId");
const systems = generateMockSystems();
await Promise.all(systems.map(async (system) => {
await loader.repository.updateSystem(system);
}))
await loader.repository.updateSystem(systems[0]);
await loader.fetchAndUpdateShuttleDataForExistingSystemsInRepository();
await loader.fetchAndUpdateShuttleDataForExistingSystemInRepository();
expect(spy.mock.calls.length).toBe(systems.length);
expect(spy.mock.calls.length).toBe(1);
expect(spy).toHaveBeenCalledWith(systems[0].id)
});
});
@@ -225,13 +218,12 @@ describe("ApiBasedRepositoryLoader", () => {
const spy = jest.spyOn(loader, "fetchAndUpdateEtaDataForExistingStopsForSystemId");
const systems = generateMockSystems();
await Promise.all(systems.map(async (system) => {
await loader.repository.updateSystem(system);
}));
await loader.repository.updateSystem(systems[0]);
await loader.fetchAndUpdateEtaDataForExistingStopsForSystemsInRepository();
await loader.fetchAndUpdateEtaDataForExistingStopsForSystemInRepository();
expect(spy.mock.calls.length).toBe(systems.length);
expect(spy.mock.calls.length).toBe(1);
expect(spy).toHaveBeenCalledWith(systems[0].id)
});
});