mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-17 07:50:31 +00:00
Add RedisParkingRepository.ts and convert existing tests to shared tests for both classes
This commit is contained in:
202
test/repositories/ParkingRepositorySharedTests.test.ts
Normal file
202
test/repositories/ParkingRepositorySharedTests.test.ts
Normal file
@@ -0,0 +1,202 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import { InMemoryParkingRepository, PARKING_LOGGING_INTERVAL_MS, ParkingStructureID } from "../../src/repositories/InMemoryParkingRepository";
|
||||
import { IParkingStructure, IParkingStructureTimestampRecord } from "../../src/entities/ParkingRepositoryEntities";
|
||||
import { CircularQueue } from "../../src/types/CircularQueue";
|
||||
import { ParkingStructureCountOptions } from "../../src/repositories/ParkingGetterRepository";
|
||||
import { ParkingGetterSetterRepository } from "../../src/repositories/ParkingGetterSetterRepository";
|
||||
import { RedisParkingRepository } from "../../src/repositories/RedisParkingRepository";
|
||||
|
||||
interface RepositoryHolder {
|
||||
name: string;
|
||||
factory(): Promise<ParkingGetterSetterRepository>;
|
||||
teardown(): Promise<void>;
|
||||
}
|
||||
|
||||
class InMemoryParkingRepositoryHolder implements RepositoryHolder {
|
||||
name = 'InMemoryParkingRepository';
|
||||
factory = async () => {
|
||||
return new InMemoryParkingRepository();
|
||||
};
|
||||
teardown = async () => {};
|
||||
}
|
||||
|
||||
class RedisParkingRepositoryHolder implements RepositoryHolder {
|
||||
repo: RedisParkingRepository | undefined;
|
||||
|
||||
name = 'RedisParkingRepository';
|
||||
factory = async () => {
|
||||
this.repo = new RedisParkingRepository();
|
||||
await this.repo.connect();
|
||||
return this.repo;
|
||||
};
|
||||
teardown = async () => {
|
||||
if (this.repo) {
|
||||
await this.repo.clearAllData();
|
||||
await this.repo.disconnect();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const repositoryImplementations = [
|
||||
// new InMemoryParkingRepositoryHolder(),
|
||||
new RedisParkingRepositoryHolder(),
|
||||
];
|
||||
|
||||
describe.each(repositoryImplementations)('$name', (holder) => {
|
||||
let repository: ParkingGetterSetterRepository;
|
||||
const testStructure: IParkingStructure = {
|
||||
coordinates: {
|
||||
latitude: 33.794795,
|
||||
longitude: -117.850807,
|
||||
},
|
||||
spotsAvailable: 0,
|
||||
id: "1",
|
||||
name: "Anderson Parking Structure",
|
||||
capacity: 100,
|
||||
address: "300 E Walnut Ave, Orange, CA 92867",
|
||||
updatedTime: new Date(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
repository = await holder.factory();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await holder.teardown();
|
||||
});
|
||||
|
||||
describe("addOrUpdateParkingStructure", () => {
|
||||
it("should add a new parking structure", async () => {
|
||||
await repository.addOrUpdateParkingStructure(testStructure);
|
||||
const result = await repository.getParkingStructureById(testStructure.id);
|
||||
expect(result).toEqual(testStructure);
|
||||
});
|
||||
|
||||
it("should update existing parking structure", async () => {
|
||||
await repository.addOrUpdateParkingStructure(testStructure);
|
||||
const updatedStructure = { ...testStructure, name: "Updated Garage" };
|
||||
await repository.addOrUpdateParkingStructure(updatedStructure);
|
||||
const result = await repository.getParkingStructureById(testStructure.id);
|
||||
expect(result).toEqual(updatedStructure);
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeParkingStructureIfExists", () => {
|
||||
it("should remove existing parking structure and return it", async () => {
|
||||
await repository.addOrUpdateParkingStructure(testStructure);
|
||||
const removed = await repository.removeParkingStructureIfExists(testStructure.id);
|
||||
expect(removed).toEqual(testStructure);
|
||||
const result = await repository.getParkingStructureById(testStructure.id);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("should return null when removing non-existent structure", async () => {
|
||||
const result = await repository.removeParkingStructureIfExists("non-existent");
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("clearParkingStructureData", () => {
|
||||
it("should remove all parking structures", async () => {
|
||||
const structures = [
|
||||
testStructure,
|
||||
{ ...testStructure, id: "test-id-2", name: "Second Garage" }
|
||||
];
|
||||
|
||||
for (const structure of structures) {
|
||||
await repository.addOrUpdateParkingStructure(structure);
|
||||
}
|
||||
|
||||
await repository.clearParkingStructureData();
|
||||
const result = await repository.getParkingStructures();
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getParkingStructures", () => {
|
||||
it("should return empty array when no structures exist", async () => {
|
||||
const result = await repository.getParkingStructures();
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return all added structures", async () => {
|
||||
const structures = [
|
||||
testStructure,
|
||||
{ ...testStructure, id: "test-id-2", name: "Second Garage" }
|
||||
];
|
||||
|
||||
for (const structure of structures) {
|
||||
await repository.addOrUpdateParkingStructure(structure);
|
||||
}
|
||||
|
||||
const result = await repository.getParkingStructures();
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result).toEqual(expect.arrayContaining(structures));
|
||||
});
|
||||
});
|
||||
|
||||
describe("getParkingStructureById", () => {
|
||||
it("should return null for non-existent structure", async () => {
|
||||
const result = await repository.getParkingStructureById("non-existent");
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("should return structure by id", async () => {
|
||||
await repository.addOrUpdateParkingStructure(testStructure);
|
||||
const result = await repository.getParkingStructureById(testStructure.id);
|
||||
expect(result).toEqual(testStructure);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getHistoricalAveragesOfParkingStructureCounts", () => {
|
||||
it("should return empty array for non-existent structure or no data", async () => {
|
||||
const options: ParkingStructureCountOptions = {
|
||||
startUnixEpochMs: 1000,
|
||||
endUnixEpochMs: 2000,
|
||||
intervalMs: 500
|
||||
};
|
||||
|
||||
// Non-existent structure
|
||||
expect(await repository.getHistoricalAveragesOfParkingStructureCounts("non-existent", options)).toEqual([]);
|
||||
|
||||
// Structure with no historical data
|
||||
await repository.addOrUpdateParkingStructure(testStructure);
|
||||
expect(await repository.getHistoricalAveragesOfParkingStructureCounts(testStructure.id, options)).toEqual([]);
|
||||
});
|
||||
|
||||
// it("should calculate averages for intervals with manual historical data", async () => {
|
||||
// await repository.addOrUpdateParkingStructure(testStructure);
|
||||
//
|
||||
// const now = Date.now();
|
||||
// jest.useFakeTimers().setSystemTime(now);
|
||||
//
|
||||
// const updates = [
|
||||
// { ...testStructure, spotsAvailable: 80, updatedTime: new Date(now + 1000) },
|
||||
// { ...testStructure, spotsAvailable: 70, updatedTime: new Date(now + 2000) },
|
||||
// ];
|
||||
//
|
||||
// for (let i = 0; i < updates.length; i++) {
|
||||
// jest.setSystemTime(now + (i + 1) * PARKING_LOGGING_INTERVAL_MS + 100);
|
||||
// await repository.addOrUpdateParkingStructure(updates[i]);
|
||||
// }
|
||||
//
|
||||
// const options: ParkingStructureCountOptions = {
|
||||
// startUnixEpochMs: now,
|
||||
// endUnixEpochMs: now + 4000000, // Large range to capture all data
|
||||
// intervalMs: 1000000
|
||||
// };
|
||||
//
|
||||
// const result = await repository.getHistoricalAveragesOfParkingStructureCounts(testStructure.id, options);
|
||||
//
|
||||
// // Should have at least some historical data
|
||||
// expect(result.length).toBeGreaterThan(0);
|
||||
// if (result.length > 0) {
|
||||
// expect(result[0]).toHaveProperty('fromUnixEpochMs');
|
||||
// expect(result[0]).toHaveProperty('toUnixEpochMs');
|
||||
// expect(result[0]).toHaveProperty('averageSpotsAvailable');
|
||||
// expect(typeof result[0].averageSpotsAvailable).toBe('number');
|
||||
// }
|
||||
// });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user