diff --git a/src/entities/ParkingRepositoryEntities.ts b/src/entities/ParkingRepositoryEntities.ts index 36ca488..1f722c6 100644 --- a/src/entities/ParkingRepositoryEntities.ts +++ b/src/entities/ParkingRepositoryEntities.ts @@ -9,7 +9,7 @@ export interface IParkingStructure extends IEntityWithTimestamp, IEntityWithId { } export interface IParkingStructureTimestampRecord { - timestampMs: number; + timestampMs: Date; id: string; spotsAvailable: number; } diff --git a/src/notifications/senders/AppleNotificationSender.ts b/src/notifications/senders/AppleNotificationSender.ts index ba03989..3ed298d 100644 --- a/src/notifications/senders/AppleNotificationSender.ts +++ b/src/notifications/senders/AppleNotificationSender.ts @@ -16,7 +16,7 @@ export interface NotificationAlertArguments { export class AppleNotificationSender { private apnsToken: string | undefined = undefined; - private _lastRefreshedTimeMs: number | undefined = undefined; + private _lastRefreshedTimeMs: Date | undefined = undefined; constructor( private shouldActuallySendNotifications = true, @@ -34,13 +34,13 @@ export class AppleNotificationSender { } } - get lastRefreshedTimeMs(): number | undefined { + get lastRefreshedTimeMs(): Date | undefined { return this._lastRefreshedTimeMs; } private lastReloadedTimeForAPNsIsTooRecent() { const thirtyMinutesMs = 1800000; - return this._lastRefreshedTimeMs && Date.now() - this._lastRefreshedTimeMs < thirtyMinutesMs; + return this._lastRefreshedTimeMs && Date.now() - this._lastRefreshedTimeMs.getTime() < thirtyMinutesMs; } public reloadAPNsTokenIfTimePassed() { @@ -70,7 +70,7 @@ export class AppleNotificationSender { algorithm: "ES256", header: tokenHeader }); - this._lastRefreshedTimeMs = nowMs; + this._lastRefreshedTimeMs = new Date(nowMs); } /** diff --git a/src/repositories/parking/InMemoryParkingRepository.ts b/src/repositories/parking/InMemoryParkingRepository.ts index 1aedad1..7ad25f6 100644 --- a/src/repositories/parking/InMemoryParkingRepository.ts +++ b/src/repositories/parking/InMemoryParkingRepository.ts @@ -80,7 +80,7 @@ export class InMemoryParkingRepository implements ParkingGetterSetterRepository private createTimestampRecord = (structure: IParkingStructure, timestampMs: number): IParkingStructureTimestampRecord => ({ id: structure.id, spotsAvailable: structure.spotsAvailable, - timestampMs, + timestampMs: new Date(timestampMs), }); private ensureHistoricalDataExists = (structureId: string): void => { @@ -90,7 +90,7 @@ export class InMemoryParkingRepository implements ParkingGetterSetterRepository }; private addRecordToHistoricalData = (structureId: string, record: IParkingStructureTimestampRecord): void => { - const sortingCallback = (a: IParkingStructureTimestampRecord, b: IParkingStructureTimestampRecord) => a.timestampMs - b.timestampMs; + const sortingCallback = (a: IParkingStructureTimestampRecord, b: IParkingStructureTimestampRecord) => a.timestampMs.getTime() - b.timestampMs.getTime(); this.historicalData.get(structureId)?.appendWithSorting(record, sortingCallback); }; @@ -112,10 +112,11 @@ export class InMemoryParkingRepository implements ParkingGetterSetterRepository const results: HistoricalParkingAverageQueryResult[] = []; const { startUnixEpochMs, endUnixEpochMs, intervalMs } = options; - let currentIntervalStart = startUnixEpochMs; + let currentIntervalStart = startUnixEpochMs.getTime(); + const endTime = endUnixEpochMs.getTime(); - while (currentIntervalStart < endUnixEpochMs) { - const currentIntervalEnd = Math.min(currentIntervalStart + intervalMs, endUnixEpochMs); + while (currentIntervalStart < endTime) { + const currentIntervalEnd = Math.min(currentIntervalStart + intervalMs, endTime); const recordsInInterval = this.getRecordsInTimeRange(records, currentIntervalStart, currentIntervalEnd); if (recordsInInterval.length > 0) { @@ -135,7 +136,7 @@ export class InMemoryParkingRepository implements ParkingGetterSetterRepository endMs: number ): IParkingStructureTimestampRecord[] => { return records.filter(record => - record.timestampMs >= startMs && record.timestampMs < endMs + record.timestampMs.getTime() >= startMs && record.timestampMs.getTime() < endMs ); }; @@ -148,8 +149,8 @@ export class InMemoryParkingRepository implements ParkingGetterSetterRepository const averageSpotsAvailable = totalSpotsAvailable / records.length; return { - fromUnixEpochMs: fromMs, - toUnixEpochMs: toMs, + fromUnixEpochMs: new Date(fromMs), + toUnixEpochMs: new Date(toMs), averageSpotsAvailable }; }; diff --git a/src/repositories/parking/ParkingGetterRepository.ts b/src/repositories/parking/ParkingGetterRepository.ts index 3f464c2..315702c 100644 --- a/src/repositories/parking/ParkingGetterRepository.ts +++ b/src/repositories/parking/ParkingGetterRepository.ts @@ -1,14 +1,14 @@ import { IParkingStructure } from "../../entities/ParkingRepositoryEntities"; export interface ParkingStructureCountOptions { - startUnixEpochMs: number; - endUnixEpochMs: number; + startUnixEpochMs: Date; + endUnixEpochMs: Date; intervalMs: number; } export interface HistoricalParkingAverageQueryResult { - fromUnixEpochMs: number; - toUnixEpochMs: number; + fromUnixEpochMs: Date; + toUnixEpochMs: Date; averageSpotsAvailable: number; } diff --git a/src/repositories/parking/RedisParkingRepository.ts b/src/repositories/parking/RedisParkingRepository.ts index 0e18d47..e5f85fd 100644 --- a/src/repositories/parking/RedisParkingRepository.ts +++ b/src/repositories/parking/RedisParkingRepository.ts @@ -163,10 +163,11 @@ export class RedisParkingRepository extends BaseRedisRepository implements Parki const { startUnixEpochMs, endUnixEpochMs, intervalMs } = options; const results: HistoricalParkingAverageQueryResult[] = []; - let currentIntervalStart = startUnixEpochMs; + let currentIntervalStart = startUnixEpochMs.getTime(); + const endTime = endUnixEpochMs.getTime(); - while (currentIntervalStart < endUnixEpochMs) { - const currentIntervalEnd = Math.min(currentIntervalStart + intervalMs, endUnixEpochMs); + while (currentIntervalStart < endTime) { + const currentIntervalEnd = Math.min(currentIntervalStart + intervalMs, endTime); try { const aggregationResult = await this.redisClient.sendCommand([ @@ -182,8 +183,8 @@ export class RedisParkingRepository extends BaseRedisRepository implements Parki if (aggregationResult && aggregationResult.length > 0) { const [, averageValue] = aggregationResult[0]; results.push({ - fromUnixEpochMs: currentIntervalStart, - toUnixEpochMs: currentIntervalEnd, + fromUnixEpochMs: new Date(currentIntervalStart), + toUnixEpochMs: new Date(currentIntervalEnd), averageSpotsAvailable: parseFloat(averageValue) }); } diff --git a/test/repositories/ParkingRepositorySharedTests.test.ts b/test/repositories/ParkingRepositorySharedTests.test.ts index e920083..1d97041 100644 --- a/test/repositories/ParkingRepositorySharedTests.test.ts +++ b/test/repositories/ParkingRepositorySharedTests.test.ts @@ -152,8 +152,8 @@ describe.each(repositoryImplementations)('$name', (holder) => { describe("getHistoricalAveragesOfParkingStructureCounts", () => { it("should return empty array for non-existent structure or no data", async () => { const options: ParkingStructureCountOptions = { - startUnixEpochMs: 1000, - endUnixEpochMs: 2000, + startUnixEpochMs: new Date(1000), + endUnixEpochMs: new Date(2000), intervalMs: 500 }; @@ -183,8 +183,8 @@ describe.each(repositoryImplementations)('$name', (holder) => { const now = Date.now(); const options: ParkingStructureCountOptions = { - startUnixEpochMs: now - 10000, // Look back 10 seconds - endUnixEpochMs: now + 10000, // Look forward 10 seconds + startUnixEpochMs: new Date(now - 10000), // Look back 10 seconds + endUnixEpochMs: new Date(now + 10000), // Look forward 10 seconds intervalMs: 20000 // Single large interval }; @@ -195,6 +195,8 @@ describe.each(repositoryImplementations)('$name', (holder) => { if (result.length > 0) { expect(result[0]).toHaveProperty('fromUnixEpochMs'); expect(result[0]).toHaveProperty('toUnixEpochMs'); + expect(result[0].fromUnixEpochMs).toBeInstanceOf(Date); + expect(result[0].toUnixEpochMs).toBeInstanceOf(Date); expect(result[0]).toHaveProperty('averageSpotsAvailable'); expect(result[0].averageSpotsAvailable).toBeCloseTo(52.5); }