Merge pull request #39 from brendan-ch/feat/parking-data-models

[INT-60] feat/parking-data-models
This commit is contained in:
2025-04-08 16:32:52 -07:00
committed by GitHub
20 changed files with 70 additions and 48 deletions

View File

@@ -1,4 +1,3 @@
# Base types
type System {
id: ID!
name: String!
@@ -8,6 +7,19 @@ type System {
stop(id: ID): Stop
shuttles: [Shuttle!]
shuttle(id: ID): Shuttle
# TODO: Implement these in system resolvers
parkingStructures: [ParkingStructure!]
parkingStructure(id: ID): ParkingStructure
}
type ParkingStructure {
id: ID!
name: String!
capacity: Int!
spotsAvailable: Int!
coordinates: Coordinates!
address: String!
}
type Route {

View File

@@ -0,0 +1,11 @@
import { ICoordinates, IEntityWithId, IEntityWithOptionalTimestamp } from "./SharedEntities";
export interface IParkingStructure extends IEntityWithOptionalTimestamp, IEntityWithId {
address: string;
capacity: number;
spotsAvailable: number;
coordinates: ICoordinates;
name: string;
}
// In the future, add support for viewing different levels of the structure

View File

@@ -0,0 +1,13 @@
export interface IEntityWithOptionalTimestamp {
millisecondsSinceEpoch?: number;
}
export interface IEntityWithId {
id: string;
}
export interface ICoordinates {
latitude: number;
longitude: number;
}

View File

@@ -1,19 +1,4 @@
export interface IEntityWithOptionalTimestamp {
millisecondsSinceEpoch?: number;
}
export interface IEntityWithId {
id: string;
}
export interface IPassioSystem extends IEntityWithId, IEntityWithOptionalTimestamp {
name: string;
}
export interface ICoordinates {
latitude: number;
longitude: number;
}
import { ICoordinates, IEntityWithId, IEntityWithOptionalTimestamp } from "./SharedEntities";
export interface IRoute extends IEntityWithId, IEntityWithOptionalTimestamp {
name: string;

View File

@@ -1,6 +1,7 @@
import { ShuttleGetterSetterRepository } from "../repositories/ShuttleGetterSetterRepository";
import { IEntityWithId, IEta, IRoute, IShuttle, IStop } from "../entities/entities";
import { IEta, IRoute, IShuttle, IStop } from "../entities/ShuttleRepositoryEntities";
import { ShuttleRepositoryLoader } from "./ShuttleRepositoryLoader";
import { IEntityWithId } from "../entities/SharedEntities";
export class ApiResponseError extends Error {
constructor(message: string) {

View File

@@ -1,5 +1,5 @@
// Mock data
import { IEta, IOrderedStop, IRoute, IShuttle, IStop, IPassioSystem } from "../entities/entities";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/ShuttleRepositoryEntities";
import { ShuttleGetterSetterRepository } from "../repositories/ShuttleGetterSetterRepository";
import { InterchangeSystemBuilderArguments } from "../entities/InterchangeSystem";

View File

@@ -1,5 +1,5 @@
import { ShuttleGetterRepository } from "../../repositories/ShuttleGetterRepository";
import { IEta } from "../../entities/entities";
import { IEta } from "../../entities/ShuttleRepositoryEntities";
import { AppleNotificationSender, NotificationAlertArguments } from "../senders/AppleNotificationSender";
import {
NotificationRepository,

View File

@@ -1,4 +1,4 @@
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/entities";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/ShuttleRepositoryEntities";
/**
* Shuttle getter repository to be linked to a system.

View File

@@ -2,7 +2,7 @@
// to convert from data repo to GraphQL schema
import { ShuttleGetterRepository } from "./ShuttleGetterRepository";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/entities";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/ShuttleRepositoryEntities";
/**
* ShuttleGetterRepository interface for data derived from Passio API.

View File

@@ -1,5 +1,6 @@
import { ShuttleGetterSetterRepository } from "./ShuttleGetterSetterRepository";
import { IEntityWithId, IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/entities";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../entities/ShuttleRepositoryEntities";
import { IEntityWithId } from "../entities/SharedEntities";
/**
* An unoptimized in memory repository.

View File

@@ -70,13 +70,19 @@ export const SystemResolvers: Resolvers<ServerContext> = {
return shuttle;
},
shuttles: async (parent, args, contextValue, _info) => {
shuttles: async (parent, _args, contextValue, _info) => {
const system = contextValue.findSystemById(parent.id);
if (!system) {
return [];
}
return await system.shuttleRepository.getShuttles();
}
},
parkingStructures: async (_parent, _args, _contextValue, _info) => {
return [];
},
parkingStructure: async (_parent, _args, _contextValue, _info) => {
return null;
},
},
}

View File

@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
import { ETANotificationScheduler } from "../../../src/notifications/schedulers/ETANotificationScheduler";
import { UnoptimizedInMemoryShuttleRepository } from "../../../src/repositories/UnoptimizedInMemoryShuttleRepository";
import { IEta, IShuttle, IStop } from "../../../src/entities/entities";
import { IEta, IShuttle, IStop } from "../../../src/entities/ShuttleRepositoryEntities";
import { addMockShuttleToRepository, addMockStopToRepository } from "../../testHelpers/repositorySetupHelpers";
import { AppleNotificationSender } from "../../../src/notifications/senders/AppleNotificationSender";
import { InMemoryNotificationRepository } from "../../../src/repositories/InMemoryNotificationRepository";

View File

@@ -1,8 +1,9 @@
import { beforeEach, describe, expect, it } from "@jest/globals";
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
import { IEta, IShuttle, IStop, IPassioSystem } from "../../src/entities/entities";
import { IEta, IShuttle, IStop } from "../../src/entities/ShuttleRepositoryEntities";
import {
addMockEtaToRepository, addMockShuttleToRepository,
addMockEtaToRepository,
addMockShuttleToRepository,
addMockStopToRepository,
} from "../testHelpers/repositorySetupHelpers";
import assert = require("node:assert");
@@ -22,7 +23,7 @@ describe("EtaResolvers", () => {
});
async function getResponseForEtaQuery(query: string) {
const response = await holder.testServer.executeOperation({
return await holder.testServer.executeOperation({
query,
variables: {
systemId: context.systems[0].id,
@@ -32,7 +33,6 @@ describe("EtaResolvers", () => {
contextValue: context
});
return response;
}
describe("stop", () => {

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it } from "@jest/globals";
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
import { IRoute, IStop, IPassioSystem } from "../../src/entities/entities";
import { IRoute, IStop } from "../../src/entities/ShuttleRepositoryEntities";
import { generateMockOrderedStops, generateMockStops } from "../testHelpers/mockDataGenerators";
import { addMockRouteToRepository } from "../testHelpers/repositorySetupHelpers";
import assert = require("node:assert");

View File

@@ -1,5 +1,4 @@
import { describe, expect, it } from "@jest/globals";
import { generateMockPassioSystems } from "../testHelpers/mockDataGenerators";
import {
buildSystemForTesting,
setupTestServerContext,

View File

@@ -5,14 +5,15 @@ import {
addMockStopToRepository
} from "../testHelpers/repositorySetupHelpers";
import { generateMockOrderedStops, generateMockShuttles } from "../testHelpers/mockDataGenerators";
import { IRoute, IStop, IPassioSystem } from "../../src/entities/entities";
import { IRoute, IStop } from "../../src/entities/ShuttleRepositoryEntities";
import assert = require("node:assert");
import { InterchangeSystem } from "../../src/entities/InterchangeSystem";
describe("RouteResolvers", () => {
const holder = setupTestServerHolder();
const context = setupTestServerContext();
let mockSystem: IPassioSystem;
let mockSystem: InterchangeSystem;
let mockRoute: IRoute;
let mockStop: IStop;

View File

@@ -1,16 +1,17 @@
import { beforeEach, describe, expect, it } from "@jest/globals";
import { generateMockEtas, generateMockRoutes } from "../testHelpers/mockDataGenerators";
import { IShuttle, IPassioSystem } from "../../src/entities/entities";
import { IShuttle } from "../../src/entities/ShuttleRepositoryEntities";
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
import { addMockShuttleToRepository } from "../testHelpers/repositorySetupHelpers";
import assert = require("node:assert");
import { InterchangeSystem } from "../../src/entities/InterchangeSystem";
describe("ShuttleResolvers", () => {
const holder = setupTestServerHolder();
const context = setupTestServerContext();
let mockSystem: IPassioSystem;
let mockSystem: InterchangeSystem;
let mockShuttle: IShuttle;
beforeEach(async () => {

View File

@@ -4,7 +4,7 @@ import {
setupTestServerHolder
} from "../testHelpers/apolloTestServerHelpers";
import { generateMockEtas, generateMockOrderedStops } from "../testHelpers/mockDataGenerators";
import { IStop } from "../../src/entities/entities";
import { IStop } from "../../src/entities/ShuttleRepositoryEntities";
import { addMockStopToRepository } from "../testHelpers/repositorySetupHelpers";
import assert = require("node:assert");

View File

@@ -6,14 +6,14 @@ import {
addMockShuttleToRepository,
addMockStopToRepository,
} from "../testHelpers/repositorySetupHelpers";
import { IPassioSystem } from "../../src/entities/entities";
import assert = require("node:assert");
import { InterchangeSystem } from "../../src/entities/InterchangeSystem";
describe("SystemResolvers", () => {
const holder = setupTestServerHolder();
const context = setupTestServerContext();
let mockSystem: IPassioSystem;
let mockSystem: InterchangeSystem;
beforeEach(async () => {
mockSystem = context.systems[0];

View File

@@ -1,16 +1,8 @@
import { IEta, IOrderedStop, IRoute, IShuttle, IStop, IPassioSystem } from "../../src/entities/entities";
import { IEta, IOrderedStop, IRoute, IShuttle, IStop } from "../../src/entities/ShuttleRepositoryEntities";
// Use a single set of generators in case any of the
// interfaces change in the future
export function generateMockPassioSystems(): IPassioSystem[] {
return [
{ id: "1", name: "System A" },
{ id: "2", name: "System B" },
{ id: "3", name: "System C" },
];
}
export function generateMockShuttles(): IShuttle[] {
return [
{