diff --git a/src/repositories/shuttle/RedisShuttleRepository.ts b/src/repositories/shuttle/RedisShuttleRepository.ts index dc321da..03376ba 100644 --- a/src/repositories/shuttle/RedisShuttleRepository.ts +++ b/src/repositories/shuttle/RedisShuttleRepository.ts @@ -105,6 +105,7 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette private createShuttleKey = (shuttleId: string) => `shuttle:shuttle:${shuttleId}`; private createEtaKey = (shuttleId: string, stopId: string) => `shuttle:eta:${shuttleId}:${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 private createRedisHashFromStop = (stop: IStop): Record => ({ @@ -453,13 +454,25 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette } public async getShuttleLastStopArrival(shuttle: IShuttle): Promise { - // Get the *time* of the most recent time series entry for the key - throw Error("not implemented"); + const key = this.createShuttleLastStopKey(shuttle.id); + 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) { - // Key: shuttleId:stopId: - // Value: just a marker (no numerical value) + const key = this.createShuttleLastStopKey(shuttle.id); + await this.redisClient.hSet(key, { + stopId: lastStopArrival.stopId, + timestamp: lastStopArrival.timestamp.toISOString(), + }); } public async addOrUpdateStop(stop: IStop): Promise { diff --git a/src/repositories/shuttle/__tests__/RedisShuttleRepository.test.ts b/src/repositories/shuttle/__tests__/RedisShuttleRepository.test.ts index c0d1614..bee1208 100644 --- a/src/repositories/shuttle/__tests__/RedisShuttleRepository.test.ts +++ b/src/repositories/shuttle/__tests__/RedisShuttleRepository.test.ts @@ -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 { afterEach } from "node:test"; +import { generateMockShuttles } from "../../../../testHelpers/mockDataGenerators"; describe("RedisShuttleRepository", () => { let repository: RedisShuttleRepository; @@ -27,11 +27,52 @@ describe("RedisShuttleRepository", () => { describe("getShuttleLastStopArrival", () => { 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 () => { - + 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()); }); }); });