rename existing repository to shuttle repository

This commit is contained in:
2025-03-27 09:32:29 -07:00
parent 3a85f3da8b
commit fab99db755
15 changed files with 46 additions and 47 deletions

View File

@@ -1,7 +1,7 @@
import { ETANotificationScheduler } from "./notifications/schedulers/ETANotificationScheduler";
import { GetterSetterRepository } from "./repositories/GetterSetterRepository";
import { ShuttleGetterSetterRepository } from "./repositories/ShuttleGetterSetterRepository";
export interface ServerContext {
repository: GetterSetterRepository;
repository: ShuttleGetterSetterRepository;
notificationService: ETANotificationScheduler;
}

View File

@@ -3,7 +3,7 @@ import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { MergedResolvers } from "./MergedResolvers";
import { ServerContext } from "./ServerContext";
import { UnoptimizedInMemoryRepository } from "./repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "./repositories/UnoptimizedInMemoryShuttleRepository";
import { TimedApiBasedRepositoryLoader } from "./loaders/TimedApiBasedRepositoryLoader";
import { ETANotificationScheduler } from "./notifications/schedulers/ETANotificationScheduler";
import { loadTestData } from "./loaders/loadTestData";
@@ -18,7 +18,7 @@ async function main() {
introspection: process.env.NODE_ENV !== "production",
});
const repository = new UnoptimizedInMemoryRepository();
const repository = new UnoptimizedInMemoryShuttleRepository();
let notificationService: ETANotificationScheduler;
if (process.argv.length > 2 && process.argv[2] == "integration-testing") {
console.log("Using integration testing setup")
@@ -37,7 +37,7 @@ async function main() {
listen: {
port: process.env.PORT ? parseInt(process.env.PORT) : 4000,
},
context: async ({ req, res }) => {
context: async () => {
return {
repository,
notificationService,

View File

@@ -1,4 +1,4 @@
import { GetterSetterRepository } from "../repositories/GetterSetterRepository";
import { ShuttleGetterSetterRepository } from "../repositories/ShuttleGetterSetterRepository";
import { IEntityWithId, IEta, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
import { RepositoryLoader } from "./RepositoryLoader";
@@ -19,7 +19,7 @@ export class ApiBasedRepositoryLoader implements RepositoryLoader {
baseUrl = "https://passiogo.com/mapGetData.php";
constructor(
public repository: GetterSetterRepository,
public repository: ShuttleGetterSetterRepository,
) {
}

View File

@@ -1,5 +1,4 @@
import { GetterSetterRepository } from "../repositories/GetterSetterRepository";
import { IEta, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
import { ShuttleGetterSetterRepository } from "../repositories/ShuttleGetterSetterRepository";
import { ApiBasedRepositoryLoader } from "./ApiBasedRepositoryLoader";
// Ideas to break this into smaller pieces in the future:
@@ -23,7 +22,7 @@ export class TimedApiBasedRepositoryLoader extends ApiBasedRepositoryLoader {
readonly timeout = 10000;
constructor(
repository: GetterSetterRepository,
repository: ShuttleGetterSetterRepository,
) {
super(repository);
this.startFetchDataAndUpdate = this.startFetchDataAndUpdate.bind(this);

View File

@@ -1,6 +1,6 @@
// Mock data
import { IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
import { GetterSetterRepository } from "../repositories/GetterSetterRepository";
import { ShuttleGetterSetterRepository } from "../repositories/ShuttleGetterSetterRepository";
const systems: ISystem[] = [
{
@@ -4454,7 +4454,7 @@ const etas: IEta[] = [
}
];
export async function loadTestData(repository: GetterSetterRepository) {
export async function loadTestData(repository: ShuttleGetterSetterRepository) {
await Promise.all(systems.map(async (system) => {
await repository.addOrUpdateSystem(system);
}));

View File

@@ -1,4 +1,4 @@
import { GetterRepository } from "../../repositories/GetterRepository";
import { ShuttleGetterRepository } from "../../repositories/ShuttleGetterRepository";
import { TupleKey } from "../../types/TupleKey";
import { IEta } from "../../entities/entities";
import { AppleNotificationSender, NotificationAlertArguments } from "../senders/AppleNotificationSender";
@@ -24,7 +24,7 @@ type DeviceIdSecondsThresholdAssociation = { [key: string]: number };
export class ETANotificationScheduler {
public static readonly defaultSecondsThresholdForNotificationToFire = 180;
constructor(private repository: GetterRepository,
constructor(private shuttleRepository: ShuttleGetterRepository,
private appleNotificationSender = new AppleNotificationSender()
) {
this.etaSubscriberCallback = this.etaSubscriberCallback.bind(this);
@@ -50,9 +50,9 @@ export class ETANotificationScheduler {
private async sendEtaNotificationImmediately(notificationData: NotificationSchedulingArguments): Promise<boolean> {
const { deviceId, shuttleId, stopId } = notificationData;
const shuttle = await this.repository.getShuttleById(shuttleId);
const stop = await this.repository.getStopById(stopId);
const eta = await this.repository.getEtaForShuttleAndStopId(shuttleId, stopId);
const shuttle = await this.shuttleRepository.getShuttleById(shuttleId);
const stop = await this.shuttleRepository.getStopById(stopId);
const eta = await this.shuttleRepository.getEtaForShuttleAndStopId(shuttleId, stopId);
if (!shuttle) {
console.warn(`Notification ${notificationData} fell through; no associated shuttle`);
return false;
@@ -127,8 +127,8 @@ export class ETANotificationScheduler {
this.deviceIdsToDeliverTo[tuple.toString()][deviceId] = secondsThreshold;
this.repository.unsubscribeFromEtaUpdates(this.etaSubscriberCallback);
this.repository.subscribeToEtaUpdates(this.etaSubscriberCallback);
this.shuttleRepository.unsubscribeFromEtaUpdates(this.etaSubscriberCallback);
this.shuttleRepository.subscribeToEtaUpdates(this.etaSubscriberCallback);
}
/**

View File

@@ -1,6 +1,6 @@
import { IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
export interface GetterRepository {
export interface ShuttleGetterRepository {
getSystems(): Promise<ISystem[]>;
getSystemById(systemId: string): Promise<ISystem | null>;

View File

@@ -1,16 +1,16 @@
// If types match closely, we can use TypeScript "casting"
// to convert from data repo to GraphQL schema
import { GetterRepository } from "./GetterRepository";
import { ShuttleGetterRepository } from "./ShuttleGetterRepository";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
/**
* GetterRepository interface for data derived from Passio API.
* ShuttleGetterRepository interface for data derived from Passio API.
* The repository is not designed to have write locks in place.
* Objects passed from/to the repository should be treated
* as disposable.
*/
export interface GetterSetterRepository extends GetterRepository {
export interface ShuttleGetterSetterRepository extends ShuttleGetterRepository {
// Setter methods
addOrUpdateSystem(system: ISystem): Promise<void>;
addOrUpdateRoute(route: IRoute): Promise<void>;

View File

@@ -1,4 +1,4 @@
import { GetterSetterRepository } from "./GetterSetterRepository";
import { ShuttleGetterSetterRepository } from "./ShuttleGetterSetterRepository";
import { IEntityWithId, IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../entities/entities";
/**
@@ -6,7 +6,7 @@ import { IEntityWithId, IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } f
* (I would optimize it with actual data structures, but I'm
* switching to another data store later anyways)
*/
export class UnoptimizedInMemoryRepository implements GetterSetterRepository {
export class UnoptimizedInMemoryShuttleRepository implements ShuttleGetterSetterRepository {
private systems: ISystem[] = [];
private stops: IStop[] = [];
private routes: IRoute[] = [];

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, jest, test } from "@jest/globals";
import { ApiBasedRepositoryLoader, ApiResponseError } from "../../src/loaders/ApiBasedRepositoryLoader";
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "../../src/repositories/UnoptimizedInMemoryShuttleRepository";
import { fetchSystemDataSuccessfulResponse } from "../jsonSnapshots/fetchSystemData/fetchSystemDataSuccessfulResponse";
import { fetchSystemDataFailedResponse } from "../jsonSnapshots/fetchSystemData/fetchSystemDataFailedResponse";
import { fetchRouteDataSuccessfulResponse } from "../jsonSnapshots/fetchRouteData/fetchRouteDataSuccessfulResponse";
@@ -26,7 +26,7 @@ describe("ApiBasedRepositoryLoader", () => {
let loader: ApiBasedRepositoryLoader;
beforeEach(() => {
loader = new ApiBasedRepositoryLoader(new UnoptimizedInMemoryRepository());
loader = new ApiBasedRepositoryLoader(new UnoptimizedInMemoryShuttleRepository());
resetGlobalFetchMockJson();
});

View File

@@ -1,7 +1,7 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, jest } from "@jest/globals";
import { TimedApiBasedRepositoryLoader } from "../../src/loaders/TimedApiBasedRepositoryLoader";
import { resetGlobalFetchMockJson } from "../testHelpers/fetchMockHelpers";
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "../../src/repositories/UnoptimizedInMemoryShuttleRepository";
describe("TimedApiBasedRepositoryLoader", () => {
let loader: TimedApiBasedRepositoryLoader;
@@ -15,7 +15,7 @@ describe("TimedApiBasedRepositoryLoader", () => {
beforeEach(() => {
resetGlobalFetchMockJson();
loader = new TimedApiBasedRepositoryLoader(new UnoptimizedInMemoryRepository());
loader = new TimedApiBasedRepositoryLoader(new UnoptimizedInMemoryShuttleRepository());
spies = {
fetchAndUpdateSystemData: jest.spyOn(loader, 'fetchAndUpdateSystemData'),

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
import { ETANotificationScheduler } from "../../../src/notifications/schedulers/ETANotificationScheduler";
import { UnoptimizedInMemoryRepository } from "../../../src/repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "../../../src/repositories/UnoptimizedInMemoryShuttleRepository";
import http2 from "http2";
import { IEta, IShuttle, IStop } from "../../../src/entities/entities";
import { addMockShuttleToRepository, addMockStopToRepository } from "../../testHelpers/repositorySetupHelpers";
@@ -42,11 +42,11 @@ async function waitForMilliseconds(ms: number): Promise<void> {
describe("ETANotificationScheduler", () => {
let repository: UnoptimizedInMemoryRepository
let repository: UnoptimizedInMemoryShuttleRepository
let notificationService: ETANotificationScheduler;
beforeEach(() => {
repository = new UnoptimizedInMemoryRepository();
repository = new UnoptimizedInMemoryShuttleRepository();
mockNotificationSenderMethods(true);

View File

@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, jest, test } from "@jest/globals";
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "../../src/repositories/UnoptimizedInMemoryShuttleRepository";
import {
generateMockEtas,
generateMockOrderedStops,
@@ -11,14 +11,14 @@ import {
// For repositories created in the future, reuse core testing
// logic from here and differentiate setup (e.g. creating mocks)
// Do this by creating a function which takes a GetterRepository
// or GetterSetterRepository instance
// Do this by creating a function which takes a ShuttleGetterRepository
// or ShuttleGetterSetterRepository instance
describe("UnoptimizedInMemoryRepository", () => {
let repository: UnoptimizedInMemoryRepository;
let repository: UnoptimizedInMemoryShuttleRepository;
beforeEach(() => {
repository = new UnoptimizedInMemoryRepository();
repository = new UnoptimizedInMemoryShuttleRepository();
});
describe("getSystems", () => {

View File

@@ -1,7 +1,7 @@
import { readFileSync } from "fs";
import { ApolloServer } from "@apollo/server";
import { MergedResolvers } from "../../src/MergedResolvers";
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
import { UnoptimizedInMemoryShuttleRepository } from "../../src/repositories/UnoptimizedInMemoryShuttleRepository";
import { beforeEach } from "@jest/globals";
import { ServerContext } from "../../src/ServerContext";
import { ETANotificationScheduler } from "../../src/notifications/schedulers/ETANotificationScheduler";
@@ -25,7 +25,7 @@ export function setupTestServerContext() {
const context: { [key: string] : any } = {};
beforeEach(() => {
context.repository = new UnoptimizedInMemoryRepository();
context.repository = new UnoptimizedInMemoryShuttleRepository();
context.notificationService = new ETANotificationScheduler(context.repository);
});

View File

@@ -5,9 +5,9 @@ import {
generateMockStops,
generateMockSystems
} from "./mockDataGenerators";
import { GetterSetterRepository } from "../../src/repositories/GetterSetterRepository";
import { ShuttleGetterSetterRepository } from "../../src/repositories/ShuttleGetterSetterRepository";
export async function addMockSystemToRepository(repository: GetterSetterRepository) {
export async function addMockSystemToRepository(repository: ShuttleGetterSetterRepository) {
const mockSystems = generateMockSystems();
const mockSystem = mockSystems[0];
mockSystem.id = "1";
@@ -16,7 +16,7 @@ export async function addMockSystemToRepository(repository: GetterSetterReposito
return mockSystem;
}
export async function addMockRouteToRepository(repository: GetterSetterRepository, systemId: string) {
export async function addMockRouteToRepository(repository: ShuttleGetterSetterRepository, systemId: string) {
const mockRoutes = generateMockRoutes();
const mockRoute = mockRoutes[0];
mockRoute.systemId = systemId;
@@ -25,7 +25,7 @@ export async function addMockRouteToRepository(repository: GetterSetterRepositor
return mockRoute;
}
export async function addMockStopToRepository(repository: GetterSetterRepository, systemId: string) {
export async function addMockStopToRepository(repository: ShuttleGetterSetterRepository, systemId: string) {
const mockStops = generateMockStops();
const mockStop = mockStops[0];
mockStop.systemId = systemId;
@@ -34,7 +34,7 @@ export async function addMockStopToRepository(repository: GetterSetterRepository
return mockStop;
}
export async function addMockShuttleToRepository(repository: GetterSetterRepository, systemId: string) {
export async function addMockShuttleToRepository(repository: ShuttleGetterSetterRepository, systemId: string) {
const mockShuttles = generateMockShuttles();
const mockShuttle = mockShuttles[0];
mockShuttle.systemId = systemId;
@@ -42,7 +42,7 @@ export async function addMockShuttleToRepository(repository: GetterSetterReposit
return mockShuttle;
}
export async function addMockEtaToRepository(repository: GetterSetterRepository, stopId: string, shuttleId: string) {
export async function addMockEtaToRepository(repository: ShuttleGetterSetterRepository, stopId: string, shuttleId: string) {
const etas = generateMockEtas();
const expectedEta = etas[0];
expectedEta.stopId = stopId;