mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-17 07:50:31 +00:00
Merge pull request #21 from brendan-ch/feat/notifications-state
feat/notifications-state
This commit is contained in:
@@ -63,6 +63,8 @@ type Shuttle {
|
||||
type Query {
|
||||
systems: [System!]!
|
||||
system(id: ID): System
|
||||
|
||||
isNotificationScheduled(input: NotificationInput!): Boolean
|
||||
}
|
||||
|
||||
# Mutations
|
||||
|
||||
@@ -15,6 +15,10 @@ export const QueryResolvers: Resolvers<ServerContext> = {
|
||||
name: system.name,
|
||||
id: system.id,
|
||||
};
|
||||
},
|
||||
isNotificationScheduled: async (_parent, args, contextValue, _info) => {
|
||||
const notificationData = args.input;
|
||||
return contextValue.notificationService.isNotificationScheduled(notificationData);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -250,4 +250,28 @@ export class NotificationService {
|
||||
}
|
||||
return this.deviceIdsToDeliverTo[tuple.toString()].has(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all scheduled notification for the given device ID.
|
||||
* @param deviceId
|
||||
*/
|
||||
public async getAllScheduledNotificationsForDevice(deviceId: string): Promise<ScheduledNotificationData[]> {
|
||||
const scheduledNotifications: ScheduledNotificationData[] = [];
|
||||
|
||||
for (const key of Object.keys(this.deviceIdsToDeliverTo)) {
|
||||
if (this.deviceIdsToDeliverTo[key].has(deviceId)) {
|
||||
const tupleKey = TupleKey.fromExistingStringKey(key);
|
||||
const shuttleId = tupleKey.tuple[0]
|
||||
const stopId = tupleKey.tuple[1];
|
||||
|
||||
scheduledNotifications.push({
|
||||
shuttleId,
|
||||
stopId,
|
||||
deviceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return scheduledNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,9 @@ export class TupleKey<T extends any[]> {
|
||||
valueOf(): string {
|
||||
return this.strKey;
|
||||
}
|
||||
|
||||
static fromExistingStringKey(strKey: string) {
|
||||
const tuple = strKey.split(separator);
|
||||
return new TupleKey(...tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import { describe, expect, it } from "@jest/globals";
|
||||
import { generateMockSystems } from "../testHelpers/mockDataGenerators";
|
||||
import { setupTestServerContext, setupTestServerHolder } from "../testHelpers/apolloTestServerHelpers";
|
||||
import assert = require("node:assert");
|
||||
import { ScheduledNotificationData } from "../../src/services/NotificationService";
|
||||
import { addMockShuttleToRepository, addMockStopToRepository } from "../testHelpers/repositorySetupHelpers";
|
||||
|
||||
// See Apollo documentation for integration test guide
|
||||
// https://www.apollographql.com/docs/apollo-server/testing/testing
|
||||
@@ -93,4 +95,63 @@ describe("QueryResolvers", () => {
|
||||
expect(response.body.singleResult.data?.system).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("isNotificationScheduled", () => {
|
||||
const query = `
|
||||
query IsNotificationScheduled($input: NotificationInput!) {
|
||||
isNotificationScheduled(input: $input)
|
||||
}
|
||||
`
|
||||
|
||||
it("returns true if the notification is scheduled", async () => {
|
||||
// Arrange
|
||||
const shuttle = await addMockShuttleToRepository(context.repository, "1");
|
||||
const stop = await addMockStopToRepository(context.repository, "1")
|
||||
|
||||
const notification: ScheduledNotificationData = {
|
||||
shuttleId: shuttle.id,
|
||||
stopId: stop.id,
|
||||
deviceId: "1",
|
||||
};
|
||||
await context.notificationService.scheduleNotification(notification);
|
||||
|
||||
// Act
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
input: {
|
||||
...notification,
|
||||
},
|
||||
}
|
||||
}, {
|
||||
contextValue: context,
|
||||
});
|
||||
|
||||
// Assert
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
expect(response.body.singleResult.data?.isNotificationScheduled).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false if the notification isn't scheduled", async () => {
|
||||
// Act
|
||||
const response = await holder.testServer.executeOperation({
|
||||
query,
|
||||
variables: {
|
||||
input: {
|
||||
shuttleId: "1",
|
||||
stopId: "1",
|
||||
deviceId: "1",
|
||||
},
|
||||
}
|
||||
}, {
|
||||
contextValue: context,
|
||||
});
|
||||
|
||||
// Assert
|
||||
assert(response.body.kind === "single");
|
||||
expect(response.body.singleResult.errors).toBeUndefined();
|
||||
expect(response.body.singleResult.data?.isNotificationScheduled).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -230,4 +230,38 @@ describe("NotificationService", () => {
|
||||
expect(http2.connect as jest.Mock).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAllScheduledNotificationsForDevice", () => {
|
||||
it("returns scheduled notifications for the device ID", async () => {
|
||||
// Arrange
|
||||
const shuttle1 = await addMockShuttleToRepository(repository, "1");
|
||||
const stop = await addMockStopToRepository(repository, "1");
|
||||
const { eta, notificationData1 } = generateNotificationDataAndEta(shuttle1, stop);
|
||||
await notificationService.scheduleNotification(notificationData1);
|
||||
|
||||
const shuttle2 = {
|
||||
...shuttle1,
|
||||
id: "2",
|
||||
}
|
||||
await repository.addOrUpdateShuttle(shuttle2);
|
||||
|
||||
const notificationData2 = {
|
||||
...notificationData1,
|
||||
shuttleId: shuttle2.id,
|
||||
}
|
||||
await notificationService.scheduleNotification(notificationData2);
|
||||
|
||||
// Act
|
||||
const notifications = await notificationService.getAllScheduledNotificationsForDevice(notificationData1.deviceId);
|
||||
|
||||
// Assert
|
||||
expect(notifications.length).toBe(2);
|
||||
});
|
||||
|
||||
it("returns an empty array if there are no notifications", async () => {
|
||||
// Act
|
||||
const notifications = await notificationService.getAllScheduledNotificationsForDevice("1");
|
||||
expect(notifications.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,4 +28,18 @@ describe("TupleKey", () => {
|
||||
expect(sampleObject[tupleKey1.toString()]).toEqual("value1");
|
||||
expect(sampleObject[(new TupleKey("1", "2")).toString()]).toEqual("value1");
|
||||
});
|
||||
|
||||
describe("fromExistingStringKey", () => {
|
||||
it("creates a new TupleKey from an existing string key", () => {
|
||||
const strKey = "hello|there";
|
||||
const tupleKey = TupleKey.fromExistingStringKey(strKey);
|
||||
expect(tupleKey.toString()).toEqual(strKey);
|
||||
});
|
||||
|
||||
it("creates an empty tuple if there is no string", () => {
|
||||
const strKey = "";
|
||||
const tupleKey = TupleKey.fromExistingStringKey(strKey);
|
||||
expect(tupleKey.toString()).toEqual(strKey);
|
||||
})
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user