Implement getShuttleLastStopArrival and updateShuttleLastStopArrival

This commit is contained in:
2025-11-10 15:36:33 -08:00
parent 2a80a049bd
commit cba91dae55
2 changed files with 62 additions and 8 deletions

View File

@@ -105,6 +105,7 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette
private createShuttleKey = (shuttleId: string) => `shuttle:shuttle:${shuttleId}`; private createShuttleKey = (shuttleId: string) => `shuttle:shuttle:${shuttleId}`;
private createEtaKey = (shuttleId: string, stopId: string) => `shuttle:eta:${shuttleId}:${stopId}`; private createEtaKey = (shuttleId: string, stopId: string) => `shuttle:eta:${shuttleId}:${stopId}`;
private createOrderedStopKey = (routeId: string, stopId: string) => `shuttle:orderedstop:${routeId}:${stopId}`; private createOrderedStopKey = (routeId: string, stopId: string) => `shuttle:orderedstop:${routeId}:${stopId}`;
private createShuttleLastStopKey = (shuttleId: string) => `shuttle:laststop:${shuttleId}`;
// Helper methods for converting entities to Redis hashes // Helper methods for converting entities to Redis hashes
private createRedisHashFromStop = (stop: IStop): Record<string, string> => ({ private createRedisHashFromStop = (stop: IStop): Record<string, string> => ({
@@ -453,13 +454,25 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette
} }
public async getShuttleLastStopArrival(shuttle: IShuttle): Promise<ShuttleStopArrival | undefined> { public async getShuttleLastStopArrival(shuttle: IShuttle): Promise<ShuttleStopArrival | undefined> {
// Get the *time* of the most recent time series entry for the key const key = this.createShuttleLastStopKey(shuttle.id);
throw Error("not implemented"); const data = await this.redisClient.hGetAll(key);
if (Object.keys(data).length === 0) {
return undefined;
}
return {
stopId: data.stopId,
timestamp: new Date(data.timestamp),
};
} }
public async updateShuttleLastStopArrival(shuttle: IShuttle, lastStopArrival: ShuttleStopArrival) { public async updateShuttleLastStopArrival(shuttle: IShuttle, lastStopArrival: ShuttleStopArrival) {
// Key: shuttleId:stopId: const key = this.createShuttleLastStopKey(shuttle.id);
// Value: just a marker (no numerical value) await this.redisClient.hSet(key, {
stopId: lastStopArrival.stopId,
timestamp: lastStopArrival.timestamp.toISOString(),
});
} }
public async addOrUpdateStop(stop: IStop): Promise<void> { public async addOrUpdateStop(stop: IStop): Promise<void> {

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, it } from "@jest/globals"; import { beforeEach, describe, it, expect, afterEach } from "@jest/globals";
import { RedisShuttleRepository } from "../RedisShuttleRepository"; import { RedisShuttleRepository } from "../RedisShuttleRepository";
import { afterEach } from "node:test"; import { generateMockShuttles } from "../../../../testHelpers/mockDataGenerators";
describe("RedisShuttleRepository", () => { describe("RedisShuttleRepository", () => {
let repository: RedisShuttleRepository; let repository: RedisShuttleRepository;
@@ -27,11 +27,52 @@ describe("RedisShuttleRepository", () => {
describe("getShuttleLastStopArrival", () => { describe("getShuttleLastStopArrival", () => {
it("gets the shuttle's last stop if existing in the data", async () => { it("gets the shuttle's last stop if existing in the data", async () => {
// Use updateShuttleLastStopArrival to populate data const mockShuttles = generateMockShuttles();
const shuttle = mockShuttles[0];
const stopArrival = {
stopId: "st1",
timestamp: new Date("2024-01-15T10:30:00Z"),
};
await repository.updateShuttleLastStopArrival(shuttle, stopArrival);
const result = await repository.getShuttleLastStopArrival(shuttle);
expect(result).toBeDefined();
expect(result?.stopId).toBe(stopArrival.stopId);
expect(result?.timestamp.getTime()).toBe(stopArrival.timestamp.getTime());
}); });
it("returns undefined if the data has never been initialized", async () => { it("returns undefined if the data has never been initialized", async () => {
const mockShuttles = generateMockShuttles();
const shuttle = mockShuttles[0];
const result = await repository.getShuttleLastStopArrival(shuttle);
expect(result).toBeUndefined();
});
it("returns the most recent stop arrival when updated multiple times", async () => {
const mockShuttles = generateMockShuttles();
const shuttle = mockShuttles[0];
const firstArrival = {
stopId: "st1",
timestamp: new Date("2024-01-15T10:30:00Z"),
};
const secondArrival = {
stopId: "st2",
timestamp: new Date("2024-01-15T10:35:00Z"),
};
await repository.updateShuttleLastStopArrival(shuttle, firstArrival);
await repository.updateShuttleLastStopArrival(shuttle, secondArrival);
const result = await repository.getShuttleLastStopArrival(shuttle);
expect(result).toBeDefined();
expect(result?.stopId).toBe(secondArrival.stopId);
expect(result?.timestamp.getTime()).toBe(secondArrival.timestamp.getTime());
}); });
}); });
}); });