mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-19 08:50:29 +00:00
Privatize implementation details for updating shuttle ETA information
This commit is contained in:
@@ -525,7 +525,7 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async addTravelTimeDataPoint(
|
private async addTravelTimeDataPoint(
|
||||||
{ routeId, fromStopId, toStopId }: ShuttleTravelTimeDataIdentifier,
|
{ routeId, fromStopId, toStopId }: ShuttleTravelTimeDataIdentifier,
|
||||||
travelTimeSeconds: number,
|
travelTimeSeconds: number,
|
||||||
timestamp = Date.now(),
|
timestamp = Date.now(),
|
||||||
@@ -626,7 +626,7 @@ export class RedisShuttleRepository extends EventEmitter implements ShuttleGette
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateShuttleLastStopArrival(shuttleId: string, lastStopArrival: ShuttleStopArrival) {
|
private async updateShuttleLastStopArrival(shuttleId: string, lastStopArrival: ShuttleStopArrival) {
|
||||||
const key = this.createShuttleLastStopKey(shuttleId);
|
const key = this.createShuttleLastStopKey(shuttleId);
|
||||||
await this.redisClient.hSet(key, {
|
await this.redisClient.hSet(key, {
|
||||||
stopId: lastStopArrival.stopId,
|
stopId: lastStopArrival.stopId,
|
||||||
|
|||||||
@@ -205,19 +205,26 @@ 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 () => {
|
||||||
const mockShuttles = generateMockShuttles();
|
const { route, systemId, stop1 } = await setupRouteAndOrderedStops();
|
||||||
const shuttle = mockShuttles[0];
|
|
||||||
const stopArrival = {
|
const shuttle = {
|
||||||
stopId: "st1",
|
id: "sh1",
|
||||||
timestamp: new Date("2024-01-15T10:30:00Z"),
|
name: "Shuttle 1",
|
||||||
|
routeId: route.id,
|
||||||
|
systemId: systemId,
|
||||||
|
coordinates: stop1.coordinates,
|
||||||
|
orientationInDegrees: 0,
|
||||||
|
updatedTime: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
await repository.updateShuttleLastStopArrival(shuttle.id, stopArrival);
|
const stopArrivalTime = new Date("2024-01-15T10:30:00Z");
|
||||||
|
await repository.addOrUpdateShuttle(shuttle, stopArrivalTime.getTime());
|
||||||
|
|
||||||
const result = await repository.getShuttleLastStopArrival(shuttle.id);
|
const result = await repository.getShuttleLastStopArrival(shuttle.id);
|
||||||
|
|
||||||
expect(result).toBeDefined();
|
expect(result).toBeDefined();
|
||||||
expect(result?.stopId).toBe(stopArrival.stopId);
|
expect(result?.stopId).toBe(stop1.id);
|
||||||
expect(result?.timestamp.getTime()).toBe(stopArrival.timestamp.getTime());
|
expect(result?.timestamp.getTime()).toBe(stopArrivalTime.getTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns undefined if the data has never been initialized", async () => {
|
it("returns undefined if the data has never been initialized", async () => {
|
||||||
@@ -230,45 +237,55 @@ describe("RedisShuttleRepository", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns the most recent stop arrival when updated multiple times", async () => {
|
it("returns the most recent stop arrival when updated multiple times", async () => {
|
||||||
const mockShuttles = generateMockShuttles();
|
const { route, systemId, stop1, stop2 } = await setupRouteAndOrderedStops();
|
||||||
const shuttle = mockShuttles[0];
|
|
||||||
|
|
||||||
const firstArrival = {
|
const shuttle = {
|
||||||
stopId: "st1",
|
id: "sh1",
|
||||||
timestamp: new Date("2024-01-15T10:30:00Z"),
|
name: "Shuttle 1",
|
||||||
|
routeId: route.id,
|
||||||
|
systemId: systemId,
|
||||||
|
coordinates: stop1.coordinates,
|
||||||
|
orientationInDegrees: 0,
|
||||||
|
updatedTime: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const secondArrival = {
|
const firstArrivalTime = new Date("2024-01-15T10:30:00Z");
|
||||||
stopId: "st2",
|
await repository.addOrUpdateShuttle(shuttle, firstArrivalTime.getTime());
|
||||||
timestamp: new Date("2024-01-15T10:35:00Z"),
|
|
||||||
};
|
|
||||||
|
|
||||||
await repository.updateShuttleLastStopArrival(shuttle.id, firstArrival);
|
shuttle.coordinates = stop2.coordinates;
|
||||||
await repository.updateShuttleLastStopArrival(shuttle.id, secondArrival);
|
const secondArrivalTime = new Date("2024-01-15T10:35:00Z");
|
||||||
|
await repository.addOrUpdateShuttle(shuttle, secondArrivalTime.getTime());
|
||||||
|
|
||||||
const result = await repository.getShuttleLastStopArrival(shuttle.id);
|
const result = await repository.getShuttleLastStopArrival(shuttle.id);
|
||||||
|
|
||||||
expect(result).toBeDefined();
|
expect(result).toBeDefined();
|
||||||
expect(result?.stopId).toBe(secondArrival.stopId);
|
expect(result?.stopId).toBe(stop2.id);
|
||||||
expect(result?.timestamp.getTime()).toBe(secondArrival.timestamp.getTime());
|
expect(result?.timestamp.getTime()).toBe(secondArrivalTime.getTime());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getAverageTravelTimeSeconds", () => {
|
describe("getAverageTravelTimeSeconds", () => {
|
||||||
it("returns the average travel time when historical data exists", async () => {
|
it("returns the average travel time when historical data exists", async () => {
|
||||||
const { route, stop2, stop1 } = await setupRouteAndOrderedStops();
|
const { route, systemId, stop1, stop2 } = await setupRouteAndOrderedStops();
|
||||||
|
|
||||||
// Add a single data point: 15 minutes travel time
|
const shuttle = {
|
||||||
const timestamp = new Date(2025, 0, 1, 12, 15, 0);
|
id: "sh1",
|
||||||
await repository.addTravelTimeDataPoint(
|
name: "Shuttle 1",
|
||||||
{
|
routeId: route.id,
|
||||||
routeId: route.id,
|
systemId: systemId,
|
||||||
fromStopId: stop1.id,
|
coordinates: stop1.coordinates,
|
||||||
toStopId: stop2.id,
|
orientationInDegrees: 0,
|
||||||
},
|
updatedTime: new Date(),
|
||||||
15 * 60, // 15 minutes in seconds
|
};
|
||||||
timestamp.getTime()
|
|
||||||
);
|
// Shuttle arrives at stop1
|
||||||
|
const firstStopTime = new Date(2025, 0, 1, 12, 0, 0);
|
||||||
|
await repository.addOrUpdateShuttle(shuttle, firstStopTime.getTime());
|
||||||
|
|
||||||
|
// Shuttle moves to stop2 (15 minutes later)
|
||||||
|
shuttle.coordinates = stop2.coordinates;
|
||||||
|
const secondStopTime = new Date(2025, 0, 1, 12, 15, 0);
|
||||||
|
await repository.addOrUpdateShuttle(shuttle, secondStopTime.getTime());
|
||||||
|
|
||||||
const travelTime = await repository.getAverageTravelTimeSeconds({
|
const travelTime = await repository.getAverageTravelTimeSeconds({
|
||||||
routeId: route.id,
|
routeId: route.id,
|
||||||
@@ -283,29 +300,28 @@ describe("RedisShuttleRepository", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns average of multiple data points", async () => {
|
it("returns average of multiple data points", async () => {
|
||||||
const { route, stop2, stop1 } = await setupRouteAndOrderedStops();
|
const { route, systemId, stop1, stop2 } = await setupRouteAndOrderedStops();
|
||||||
|
|
||||||
|
const shuttle = {
|
||||||
|
id: "sh1",
|
||||||
|
name: "Shuttle 1",
|
||||||
|
routeId: route.id,
|
||||||
|
systemId: systemId,
|
||||||
|
coordinates: stop1.coordinates,
|
||||||
|
orientationInDegrees: 0,
|
||||||
|
updatedTime: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
// First trip: 10 minutes travel time
|
// First trip: 10 minutes travel time
|
||||||
await repository.addTravelTimeDataPoint(
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 0, 0).getTime());
|
||||||
{
|
shuttle.coordinates = stop2.coordinates;
|
||||||
routeId: route.id,
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 10, 0).getTime());
|
||||||
fromStopId: stop1.id,
|
|
||||||
toStopId: stop2.id,
|
|
||||||
},
|
|
||||||
10 * 60, // 10 minutes
|
|
||||||
new Date(2025, 0, 1, 12, 0, 0).getTime()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Second trip: 20 minutes travel time
|
// Second trip: 20 minutes travel time
|
||||||
await repository.addTravelTimeDataPoint(
|
shuttle.coordinates = stop1.coordinates;
|
||||||
{
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 30, 0).getTime());
|
||||||
routeId: route.id,
|
shuttle.coordinates = stop2.coordinates;
|
||||||
fromStopId: stop1.id,
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 50, 0).getTime());
|
||||||
toStopId: stop2.id,
|
|
||||||
},
|
|
||||||
20 * 60, // 20 minutes
|
|
||||||
new Date(2025, 0, 1, 13, 0, 0).getTime()
|
|
||||||
);
|
|
||||||
|
|
||||||
const averageTravelTime = await repository.getAverageTravelTimeSeconds({
|
const averageTravelTime = await repository.getAverageTravelTimeSeconds({
|
||||||
routeId: route.id,
|
routeId: route.id,
|
||||||
@@ -337,18 +353,22 @@ describe("RedisShuttleRepository", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns undefined when querying outside the time range of data", async () => {
|
it("returns undefined when querying outside the time range of data", async () => {
|
||||||
const { route, stop2, stop1 } = await setupRouteAndOrderedStops();
|
const { route, systemId, stop1, stop2 } = await setupRouteAndOrderedStops();
|
||||||
|
|
||||||
|
const shuttle = {
|
||||||
|
id: "sh1",
|
||||||
|
name: "Shuttle 1",
|
||||||
|
routeId: route.id,
|
||||||
|
systemId: systemId,
|
||||||
|
coordinates: stop1.coordinates,
|
||||||
|
orientationInDegrees: 0,
|
||||||
|
updatedTime: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
// Add data on Jan 1
|
// Add data on Jan 1
|
||||||
await repository.addTravelTimeDataPoint(
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 0, 0).getTime());
|
||||||
{
|
shuttle.coordinates = stop2.coordinates;
|
||||||
routeId: route.id,
|
await repository.addOrUpdateShuttle(shuttle, new Date(2025, 0, 1, 12, 15, 0).getTime());
|
||||||
fromStopId: stop1.id,
|
|
||||||
toStopId: stop2.id,
|
|
||||||
},
|
|
||||||
15 * 60, // 15 minutes
|
|
||||||
new Date(2025, 0, 1, 12, 15, 0).getTime()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Query for Jan 2 (no data should exist in this range)
|
// Query for Jan 2 (no data should exist in this range)
|
||||||
const averageTravelTime = await repository.getAverageTravelTimeSeconds({
|
const averageTravelTime = await repository.getAverageTravelTimeSeconds({
|
||||||
|
|||||||
Reference in New Issue
Block a user