mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-19 08:50:29 +00:00
Merge pull request #18 from brendan-ch/feat/notification-service-integration
feat/notification-service-integration
This commit is contained in:
6
package-lock.json
generated
6
package-lock.json
generated
@@ -9,7 +9,6 @@
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@apollo/server": "^4.11.2",
|
||||
"@types/jsonwebtoken": "^9.0.8",
|
||||
"graphql": "^16.10.0",
|
||||
"jsonwebtoken": "^9.0.2"
|
||||
},
|
||||
@@ -18,6 +17,7 @@
|
||||
"@graphql-codegen/typescript": "4.1.2",
|
||||
"@graphql-codegen/typescript-resolvers": "4.4.1",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@types/jsonwebtoken": "^9.0.8",
|
||||
"@types/node": "^22.10.2",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.2.5",
|
||||
@@ -3571,6 +3571,7 @@
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz",
|
||||
"integrity": "sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/ms": "*",
|
||||
"@types/node": "*"
|
||||
@@ -3589,7 +3590,8 @@
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
||||
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="
|
||||
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.10.2",
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
type Query {
|
||||
systems: [System!]!
|
||||
system(id: ID): System
|
||||
}
|
||||
|
||||
# Base types
|
||||
type System {
|
||||
id: ID!
|
||||
name: String!
|
||||
@@ -62,3 +58,33 @@ type Shuttle {
|
||||
etas: [ETA!]
|
||||
eta(forStopId: ID): ETA
|
||||
}
|
||||
|
||||
# Queries
|
||||
type Query {
|
||||
systems: [System!]!
|
||||
system(id: ID): System
|
||||
}
|
||||
|
||||
# Mutations
|
||||
type Mutation {
|
||||
scheduleNotification(input: NotificationInput!): NotificationResponse!
|
||||
cancelNotification(input: NotificationInput!): NotificationResponse!
|
||||
}
|
||||
|
||||
input NotificationInput {
|
||||
deviceId: ID!
|
||||
shuttleId: ID!
|
||||
stopId: ID!
|
||||
}
|
||||
|
||||
type NotificationResponse {
|
||||
success: Boolean!
|
||||
message: String!
|
||||
data: Notification
|
||||
}
|
||||
|
||||
type Notification {
|
||||
deviceId: ID!
|
||||
shuttleId: ID!
|
||||
stopId: ID!
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { OrderedStopResolvers } from "./resolvers/OrderedStopResolvers";
|
||||
import { StopResolvers } from "./resolvers/StopResolvers";
|
||||
import { ShuttleResolvers } from "./resolvers/ShuttleResolvers";
|
||||
import { RouteResolvers } from "./resolvers/RouteResolvers";
|
||||
import { MutationResolvers } from "./resolvers/MutationResolvers";
|
||||
|
||||
export const MergedResolvers: Resolvers<ServerContext> = {
|
||||
...QueryResolvers,
|
||||
@@ -16,4 +17,5 @@ export const MergedResolvers: Resolvers<ServerContext> = {
|
||||
...StopResolvers,
|
||||
...OrderedStopResolvers,
|
||||
...EtaResolvers,
|
||||
};
|
||||
...MutationResolvers,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { GetterRepository } from "./repositories/GetterRepository";
|
||||
import { NotificationService } from "./services/NotificationService";
|
||||
import { GetterSetterRepository } from "./repositories/GetterSetterRepository";
|
||||
|
||||
export interface ServerContext {
|
||||
repository: GetterRepository;
|
||||
}
|
||||
repository: GetterSetterRepository;
|
||||
notificationService: NotificationService;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { MergedResolvers } from "./MergedResolvers";
|
||||
import { ServerContext } from "./ServerContext";
|
||||
import { UnoptimizedInMemoryRepository } from "./repositories/UnoptimizedInMemoryRepository";
|
||||
import { TimedApiBasedRepositoryLoader } from "./loaders/TimedApiBasedRepositoryLoader";
|
||||
import { NotificationService } from "./services/NotificationService";
|
||||
|
||||
const typeDefs = readFileSync("./schema.graphqls", "utf8");
|
||||
|
||||
@@ -16,13 +17,13 @@ async function main() {
|
||||
});
|
||||
|
||||
const repository = new UnoptimizedInMemoryRepository();
|
||||
// await loadTestData(repository);
|
||||
|
||||
const repositoryDataUpdater = new TimedApiBasedRepositoryLoader(
|
||||
repository
|
||||
);
|
||||
await repositoryDataUpdater.start();
|
||||
|
||||
const notificationService = new NotificationService(repository);
|
||||
|
||||
const { url } = await startStandaloneServer(server, {
|
||||
listen: {
|
||||
port: process.env.PORT ? parseInt(process.env.PORT) : 4000,
|
||||
@@ -30,6 +31,7 @@ async function main() {
|
||||
context: async ({ req, res }) => {
|
||||
return {
|
||||
repository,
|
||||
notificationService,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
47
src/resolvers/MutationResolvers.ts
Normal file
47
src/resolvers/MutationResolvers.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { NotificationInput, NotificationResponse, Resolvers } from "../generated/graphql";
|
||||
import { ServerContext } from "../ServerContext";
|
||||
|
||||
export const MutationResolvers: Resolvers<ServerContext> = {
|
||||
Mutation: {
|
||||
scheduleNotification: async (_parent, args, context, _info) => {
|
||||
const shuttle = await context.repository.getShuttleById(args.input.shuttleId);
|
||||
if (!shuttle) {
|
||||
return {
|
||||
message: "Shuttle ID doesn't exist",
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
const stop = await context.repository.getStopById(args.input.stopId);
|
||||
if (!stop) {
|
||||
return {
|
||||
message: "Stop ID doesn't exist",
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
|
||||
await context.notificationService.scheduleNotification(args.input);
|
||||
|
||||
const response: NotificationResponse = {
|
||||
message: "Notification scheduled",
|
||||
success: true,
|
||||
data: args.input,
|
||||
}
|
||||
return response;
|
||||
},
|
||||
cancelNotification: async (_parent, args, context, _info) => {
|
||||
if (context.notificationService.isNotificationScheduled(args.input)) {
|
||||
await context.notificationService.cancelNotificationIfExists(args.input);
|
||||
return {
|
||||
success: true,
|
||||
message: "Notification cancelled",
|
||||
data: args.input,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: "Notification doesn't exist"
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { IEta, IShuttle, IStop, ISystem } from "../../src/entities/entities";
|
||||
import {
|
||||
addMockEtaToRepository, addMockShuttleToRepository,
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import assert = require("node:assert");
|
||||
|
||||
describe("EtaResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockSystem: ISystem;
|
||||
@@ -24,7 +25,7 @@ describe("EtaResolvers", () => {
|
||||
});
|
||||
|
||||
async function getResponseForEtaQuery(query: string) {
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -87,4 +88,4 @@ describe("EtaResolvers", () => {
|
||||
expect(eta.shuttle.id).toEqual(expectedEta.shuttleId);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
156
test/resolvers/MutationResolverTests.test.ts
Normal file
156
test/resolvers/MutationResolverTests.test.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import {
|
||||
addMockShuttleToRepository,
|
||||
addMockStopToRepository,
|
||||
addMockSystemToRepository
|
||||
} from "../testHelpers/repositorySetupHelpers";
|
||||
import assert = require("node:assert");
|
||||
import { NotificationInput } from "../../src/generated/graphql";
|
||||
|
||||
describe("MutationResolvers", () => {
|
||||
const holder = setupTestServerHolder()
|
||||
const context = setupTestServerContext();
|
||||
|
||||
async function getServerResponse(query: string, notificationInput: { deviceId: string; shuttleId: string; stopId: string }) {
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
input: notificationInput,
|
||||
}
|
||||
}, {
|
||||
contextValue: context
|
||||
});
|
||||
}
|
||||
|
||||
describe("scheduleNotification", () => {
|
||||
const query = `
|
||||
mutation ScheduleNotification($input: NotificationInput!) {
|
||||
scheduleNotification(input: $input) {
|
||||
success
|
||||
message
|
||||
data {
|
||||
deviceId
|
||||
shuttleId
|
||||
stopId
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
function assertFailedResponse(response: any, notificationInput: NotificationInput) {
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
const notificationResponse = response.body.singleResult.data?.scheduleNotification as any;
|
||||
expect(notificationResponse.success).toBe(false);
|
||||
|
||||
expect(context.notificationService.isNotificationScheduled(notificationInput)).toBe(false);
|
||||
}
|
||||
|
||||
|
||||
it("adds a notification to the notification service", async () => {
|
||||
const system = await addMockSystemToRepository(context.repository);
|
||||
const shuttle = await addMockShuttleToRepository(context.repository, system.id);
|
||||
const stop = await addMockStopToRepository(context.repository, system.id);
|
||||
|
||||
const notificationInput = {
|
||||
deviceId: "1",
|
||||
shuttleId: shuttle.id,
|
||||
stopId: stop.id,
|
||||
};
|
||||
const response = await getServerResponse(query, notificationInput);
|
||||
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
|
||||
const notificationResponse = response.body.singleResult.data?.scheduleNotification as any;
|
||||
expect(notificationResponse?.success).toBe(true);
|
||||
expect(notificationResponse?.data).toEqual(notificationInput);
|
||||
|
||||
expect(context.notificationService.isNotificationScheduled(notificationInput)).toBe(true);
|
||||
});
|
||||
|
||||
it("fails if the shuttle ID doesn't exist", async () => {
|
||||
const system = await addMockSystemToRepository(context.repository);
|
||||
const stop = await addMockStopToRepository(context.repository, system.id);
|
||||
|
||||
const notificationInput = {
|
||||
deviceId: "1",
|
||||
shuttleId: "1",
|
||||
stopId: stop.id,
|
||||
}
|
||||
const response = await getServerResponse(query, notificationInput);
|
||||
assertFailedResponse(response, notificationInput);
|
||||
});
|
||||
|
||||
it("fails if the stop ID doesn't exist", async () => {
|
||||
const system = await addMockSystemToRepository(context.repository);
|
||||
const shuttle = await addMockShuttleToRepository(context.repository, system.id);
|
||||
|
||||
const notificationInput = {
|
||||
deviceId: "1",
|
||||
shuttleId: shuttle.id,
|
||||
stopId: "1",
|
||||
}
|
||||
const response = await getServerResponse(query, notificationInput);
|
||||
|
||||
assertFailedResponse(response, notificationInput);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancelNotification", () => {
|
||||
const query = `
|
||||
mutation CancelNotification($input: NotificationInput!) {
|
||||
cancelNotification(input: $input) {
|
||||
success
|
||||
message
|
||||
data {
|
||||
deviceId
|
||||
shuttleId
|
||||
stopId
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
it("removes the notification from the notification service", async () => {
|
||||
const system = await addMockSystemToRepository(context.repository);
|
||||
const shuttle = await addMockShuttleToRepository(context.repository, system.id);
|
||||
const stop = await addMockStopToRepository(context.repository, system.id);
|
||||
|
||||
const notificationInput = {
|
||||
deviceId: "1",
|
||||
shuttleId: shuttle.id,
|
||||
stopId: stop.id,
|
||||
}
|
||||
await context.notificationService.scheduleNotification(notificationInput);
|
||||
|
||||
const response = await getServerResponse(query, notificationInput);
|
||||
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
|
||||
const notificationResponse = response.body.singleResult.data?.cancelNotification as any;
|
||||
expect(notificationResponse.success).toBe(true);
|
||||
expect(notificationResponse.data).toEqual(notificationInput);
|
||||
|
||||
expect(context.notificationService.isNotificationScheduled(notificationInput)).toBe(false);
|
||||
});
|
||||
|
||||
it("fails if the notification doesn't exist", async () => {
|
||||
const notificationInput = {
|
||||
deviceId: "1",
|
||||
shuttleId: "1",
|
||||
stopId: "1",
|
||||
}
|
||||
|
||||
const response = await getServerResponse(query, notificationInput);
|
||||
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
|
||||
const notificationResponse = response.body.singleResult.data?.cancelNotification as any;
|
||||
expect(notificationResponse.success).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +1,12 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { IRoute, IStop, ISystem } from "../../src/entities/entities";
|
||||
import { generateMockOrderedStops, generateMockStops } from "../testHelpers/mockDataGenerators";
|
||||
import { addMockRouteToRepository, addMockSystemToRepository } from "../testHelpers/repositorySetupHelpers";
|
||||
import assert = require("node:assert");
|
||||
|
||||
describe("OrderedStopResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockSystem: ISystem;
|
||||
@@ -59,7 +60,7 @@ describe("OrderedStopResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -131,7 +132,7 @@ describe("OrderedStopResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -206,7 +207,7 @@ describe("OrderedStopResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -256,7 +257,7 @@ describe("OrderedStopResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { generateMockSystems } from "../testHelpers/mockDataGenerators";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import assert = require("node:assert");
|
||||
|
||||
// See Apollo documentation for integration test guide
|
||||
// https://www.apollographql.com/docs/apollo-server/testing/testing
|
||||
|
||||
describe("QueryResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
async function addMockSystems() {
|
||||
@@ -30,7 +31,7 @@ describe("QueryResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
}, {
|
||||
contextValue: {
|
||||
@@ -59,7 +60,7 @@ describe("QueryResolvers", () => {
|
||||
const systems = await addMockSystems();
|
||||
const systemToGet = systems[1];
|
||||
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
id: systemToGet.id,
|
||||
@@ -76,7 +77,7 @@ describe("QueryResolvers", () => {
|
||||
});
|
||||
|
||||
it("returns null if there is no system", async () => {
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
id: "nonexistent-id",
|
||||
@@ -92,4 +93,4 @@ describe("QueryResolvers", () => {
|
||||
expect(response.body.singleResult.data?.system).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import {
|
||||
addMockRouteToRepository,
|
||||
addMockStopToRepository,
|
||||
@@ -10,6 +10,7 @@ import { IRoute, IStop, ISystem } from "../../src/entities/entities";
|
||||
import assert = require("node:assert");
|
||||
|
||||
describe("RouteResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockSystem: ISystem;
|
||||
@@ -40,7 +41,7 @@ describe("RouteResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -95,7 +96,7 @@ describe("RouteResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -145,4 +146,4 @@ describe("RouteResolvers", () => {
|
||||
expect(orderedStop).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { generateMockEtas, generateMockRoutes } from "../testHelpers/mockDataGenerators";
|
||||
import { IShuttle, ISystem } from "../../src/entities/entities";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { addMockShuttleToRepository, addMockSystemToRepository } from "../testHelpers/repositorySetupHelpers";
|
||||
import assert = require("node:assert");
|
||||
|
||||
|
||||
describe("ShuttleResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockSystem: ISystem;
|
||||
@@ -47,7 +48,7 @@ describe("ShuttleResolvers", () => {
|
||||
const mockEta = etas[1];
|
||||
|
||||
// Act
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -68,7 +69,7 @@ describe("ShuttleResolvers", () => {
|
||||
});
|
||||
|
||||
it("returns null if it doesn't exist", async () => {
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -106,7 +107,7 @@ describe("ShuttleResolvers", () => {
|
||||
it("returns associated ETAs if they exist for the shuttle", async () => {
|
||||
const etas = await addMockEtas(mockShuttle.id);
|
||||
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -125,7 +126,7 @@ describe("ShuttleResolvers", () => {
|
||||
});
|
||||
|
||||
it("returns empty array if no ETAs exist", async () => {
|
||||
const response = await context.testServer.executeOperation({
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -164,7 +165,7 @@ describe("ShuttleResolvers", () => {
|
||||
`
|
||||
|
||||
async function getResponseForQuery() {
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -197,4 +198,4 @@ describe("ShuttleResolvers", () => {
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { generateMockEtas, generateMockOrderedStops } from "../testHelpers/mockDataGenerators";
|
||||
import { IStop, ISystem } from "../../src/entities/entities";
|
||||
import { addMockStopToRepository, addMockSystemToRepository } from "../testHelpers/repositorySetupHelpers";
|
||||
import assert = require("node:assert");
|
||||
|
||||
describe("StopResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockStop: IStop;
|
||||
@@ -17,7 +18,7 @@ describe("StopResolvers", () => {
|
||||
})
|
||||
|
||||
async function getResponseForQuery(query: string) {
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -105,4 +106,4 @@ describe("StopResolvers", () => {
|
||||
expect((response.body.singleResult.data as any).system.stop.etas).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { beforeEach, describe, expect, it } from "@jest/globals";
|
||||
import { setupTestServerContext } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import { generateMockRoutes, generateMockShuttles, generateMockStops } from "../testHelpers/mockDataGenerators";
|
||||
import {
|
||||
addMockRouteToRepository,
|
||||
@@ -11,6 +11,7 @@ import { ISystem } from "../../src/entities/entities";
|
||||
import assert = require("node:assert");
|
||||
|
||||
describe("SystemResolvers", () => {
|
||||
const holder = setupTestServerHolder();
|
||||
const context = setupTestServerContext();
|
||||
|
||||
let mockSystem: ISystem;
|
||||
@@ -21,7 +22,7 @@ describe("SystemResolvers", () => {
|
||||
|
||||
// TODO: Consolidate these into one single method taking an object
|
||||
async function getResponseFromQueryNeedingSystemId(query: string) {
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -102,7 +103,7 @@ describe("SystemResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -169,7 +170,7 @@ describe("SystemResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -237,7 +238,7 @@ describe("SystemResolvers", () => {
|
||||
}
|
||||
`;
|
||||
|
||||
return await context.testServer.executeOperation({
|
||||
return await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
systemId: mockSystem.id,
|
||||
@@ -318,4 +319,4 @@ describe("SystemResolvers", () => {
|
||||
expect(shuttles.length === expectedShuttles.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import { MergedResolvers } from "../../src/MergedResolvers";
|
||||
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
|
||||
import { beforeEach } from "@jest/globals";
|
||||
import { ServerContext } from "../../src/ServerContext";
|
||||
import { NotificationService } from "../../src/services/NotificationService";
|
||||
|
||||
|
||||
function setUpTestServer() {
|
||||
@@ -16,15 +17,33 @@ function setUpTestServer() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a `ServerContext` object which can be passed to requests
|
||||
* for testing.
|
||||
*/
|
||||
export function setupTestServerContext() {
|
||||
// @ts-ignore
|
||||
const context: { testServer: ApolloServer<ServerContext>; repository: UnoptimizedInMemoryRepository } = {};
|
||||
const context: { [key: string] : any } = {};
|
||||
|
||||
beforeEach(() => {
|
||||
context.testServer = setUpTestServer();
|
||||
context.repository = new UnoptimizedInMemoryRepository();
|
||||
context.notificationService = new NotificationService(context.repository);
|
||||
});
|
||||
|
||||
// Return a reference, not destructured values
|
||||
return context;
|
||||
}
|
||||
return context as ServerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object which holds a test server.
|
||||
* This server is reset before every test.
|
||||
* Tests should keep a reference to the holder object,
|
||||
* and not destructure it.
|
||||
*/
|
||||
export function setupTestServerHolder() {
|
||||
const holder: { [key: string]: any } = {};
|
||||
|
||||
beforeEach(() => {
|
||||
holder.testServer = setUpTestServer();
|
||||
});
|
||||
|
||||
return holder as { testServer: ApolloServer };
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository";
|
||||
import {
|
||||
generateMockEtas,
|
||||
generateMockRoutes,
|
||||
@@ -6,8 +5,9 @@ import {
|
||||
generateMockStops,
|
||||
generateMockSystems
|
||||
} from "./mockDataGenerators";
|
||||
import { GetterSetterRepository } from "../../src/repositories/GetterSetterRepository";
|
||||
|
||||
export async function addMockSystemToRepository(repository: UnoptimizedInMemoryRepository) {
|
||||
export async function addMockSystemToRepository(repository: GetterSetterRepository) {
|
||||
const mockSystems = generateMockSystems();
|
||||
const mockSystem = mockSystems[0];
|
||||
mockSystem.id = "1";
|
||||
@@ -16,7 +16,7 @@ export async function addMockSystemToRepository(repository: UnoptimizedInMemoryR
|
||||
return mockSystem;
|
||||
}
|
||||
|
||||
export async function addMockRouteToRepository(repository: UnoptimizedInMemoryRepository, systemId: string) {
|
||||
export async function addMockRouteToRepository(repository: GetterSetterRepository, systemId: string) {
|
||||
const mockRoutes = generateMockRoutes();
|
||||
const mockRoute = mockRoutes[0];
|
||||
mockRoute.systemId = systemId;
|
||||
@@ -25,7 +25,7 @@ export async function addMockRouteToRepository(repository: UnoptimizedInMemoryRe
|
||||
return mockRoute;
|
||||
}
|
||||
|
||||
export async function addMockStopToRepository(repository: UnoptimizedInMemoryRepository, systemId: string) {
|
||||
export async function addMockStopToRepository(repository: GetterSetterRepository, systemId: string) {
|
||||
const mockStops = generateMockStops();
|
||||
const mockStop = mockStops[0];
|
||||
mockStop.systemId = systemId;
|
||||
@@ -34,7 +34,7 @@ export async function addMockStopToRepository(repository: UnoptimizedInMemoryRep
|
||||
return mockStop;
|
||||
}
|
||||
|
||||
export async function addMockShuttleToRepository(repository: UnoptimizedInMemoryRepository, systemId: string) {
|
||||
export async function addMockShuttleToRepository(repository: GetterSetterRepository, systemId: string) {
|
||||
const mockShuttles = generateMockShuttles();
|
||||
const mockShuttle = mockShuttles[0];
|
||||
mockShuttle.systemId = systemId;
|
||||
@@ -42,7 +42,7 @@ export async function addMockShuttleToRepository(repository: UnoptimizedInMemory
|
||||
return mockShuttle;
|
||||
}
|
||||
|
||||
export async function addMockEtaToRepository(repository: UnoptimizedInMemoryRepository, stopId: string, shuttleId: string) {
|
||||
export async function addMockEtaToRepository(repository: GetterSetterRepository, stopId: string, shuttleId: string) {
|
||||
const etas = generateMockEtas();
|
||||
const expectedEta = etas[0];
|
||||
expectedEta.stopId = stopId;
|
||||
|
||||
Reference in New Issue
Block a user