mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-19 17:00:30 +00:00
Move all tests to subdirectories underneath code to be tested
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import { InMemoryNotificationRepository } from "../InMemoryNotificationRepository";
|
||||
import { NotificationEvent, NotificationRepository } from "../NotificationRepository";
|
||||
import { RedisNotificationRepository } from "../RedisNotificationRepository";
|
||||
|
||||
interface RepositoryHolder {
|
||||
name: string;
|
||||
factory(): Promise<NotificationRepository>,
|
||||
teardown(): Promise<void>,
|
||||
}
|
||||
|
||||
class InMemoryRepositoryHolder implements RepositoryHolder {
|
||||
name = 'InMemoryNotificationRepository';
|
||||
factory = async () => {
|
||||
return new InMemoryNotificationRepository();
|
||||
}
|
||||
teardown = async () => {}
|
||||
}
|
||||
|
||||
class RedisNotificationRepositoryHolder implements RepositoryHolder {
|
||||
repo: RedisNotificationRepository | undefined;
|
||||
|
||||
name = 'RedisNotificationRepository';
|
||||
factory = async () => {
|
||||
this.repo = new RedisNotificationRepository();
|
||||
await this.repo.connect();
|
||||
return this.repo;
|
||||
}
|
||||
teardown = async () => {
|
||||
if (this.repo) {
|
||||
await this.repo.clearAllData();
|
||||
await this.repo.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const repositoryImplementations = [
|
||||
new InMemoryRepositoryHolder(),
|
||||
new RedisNotificationRepositoryHolder(),
|
||||
]
|
||||
|
||||
describe.each(repositoryImplementations)('$name', (holder) => {
|
||||
let repo: NotificationRepository;
|
||||
|
||||
beforeEach(async () => {
|
||||
repo = await holder.factory();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await holder.teardown();
|
||||
})
|
||||
|
||||
const notification = {
|
||||
deviceId: "device1",
|
||||
shuttleId: "shuttle1",
|
||||
stopId: "stop1",
|
||||
secondsThreshold: 180
|
||||
};
|
||||
|
||||
describe("getAllNotificationsForShuttleAndStopId", () => {
|
||||
it("gets notifications correctly", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
const result = await repo.getAllNotificationsForShuttleAndStopId("shuttle1", "stop1");
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toEqual(notification);
|
||||
});
|
||||
|
||||
it("returns empty array if no notifications", async () => {
|
||||
const result = await repo.getAllNotificationsForShuttleAndStopId("shuttle1", "stop1");
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getSecondsThresholdForNotificationIfExists", () => {
|
||||
it("gets the seconds threshold if exists", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
const result = await repo.getSecondsThresholdForNotificationIfExists({
|
||||
deviceId: "device1",
|
||||
shuttleId: "shuttle1",
|
||||
stopId: "stop1"
|
||||
});
|
||||
expect(result).toBe(180);
|
||||
});
|
||||
|
||||
it("returns null if there is no seconds threshold", async () => {
|
||||
const result = await repo.getSecondsThresholdForNotificationIfExists({
|
||||
deviceId: "device1",
|
||||
shuttleId: "shuttle1",
|
||||
stopId: "stop1"
|
||||
});
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("addOrUpdateNotification", () => {
|
||||
// Add/get flow is covered in getAllNotificationsForShuttleAndStopId
|
||||
|
||||
it("updates the seconds threshold if the notification exists already", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
await repo.addOrUpdateNotification({...notification, secondsThreshold: 300});
|
||||
|
||||
const result = await repo.getSecondsThresholdForNotificationIfExists({
|
||||
deviceId: "device1",
|
||||
shuttleId: "shuttle1",
|
||||
stopId: "stop1"
|
||||
});
|
||||
expect(result).toBe(300);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deleteNotificationIfExists", () => {
|
||||
it("deletes the notification", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
await repo.deleteNotificationIfExists(notification);
|
||||
|
||||
const result = await repo.getAllNotificationsForShuttleAndStopId("shuttle1", "stop1");
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
|
||||
|
||||
it("does nothing if there's no notification", async () => {
|
||||
await expect(repo.deleteNotificationIfExists({
|
||||
deviceId: "device1",
|
||||
shuttleId: "shuttle1",
|
||||
stopId: "stop1"
|
||||
})).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("subscribeToNotificationChanges", () => {
|
||||
it("calls subscribers when something is added", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
repo.subscribeToNotificationChanges(mockCallback);
|
||||
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
const expectedEvent: NotificationEvent = {
|
||||
event: 'addOrUpdate',
|
||||
notification,
|
||||
}
|
||||
expect(mockCallback).toHaveBeenCalledTimes(1);
|
||||
expect(mockCallback).toHaveBeenCalledWith(expectedEvent);
|
||||
});
|
||||
|
||||
it("calls subscribers when something is updated", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
repo.subscribeToNotificationChanges(mockCallback);
|
||||
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
const updatedNotification = {
|
||||
...notification,
|
||||
secondsThreshold: notification.secondsThreshold + 60,
|
||||
};
|
||||
|
||||
await repo.addOrUpdateNotification(updatedNotification);
|
||||
|
||||
const expectedEvent: NotificationEvent = {
|
||||
event: 'addOrUpdate',
|
||||
notification,
|
||||
}
|
||||
expect(mockCallback).toHaveBeenCalledTimes(2);
|
||||
expect(mockCallback).toHaveBeenCalledWith(expectedEvent);
|
||||
});
|
||||
|
||||
it("calls subscribers when something is deleted", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
const mockCallback = jest.fn();
|
||||
repo.subscribeToNotificationChanges(mockCallback);
|
||||
|
||||
await repo.deleteNotificationIfExists(notification);
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledTimes(1);
|
||||
|
||||
const expectedEvent: NotificationEvent = {
|
||||
event: 'delete',
|
||||
notification,
|
||||
};
|
||||
expect(mockCallback).toHaveBeenCalledWith(expectedEvent);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unsubscribeFromNotificationChanges", () => {
|
||||
it("stops calling subscribers when unsubscribed", async () => {
|
||||
const mockCallback = jest.fn();
|
||||
repo.subscribeToNotificationChanges(mockCallback);
|
||||
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
|
||||
repo.unsubscribeFromNotificationChanges(mockCallback);
|
||||
|
||||
await repo.deleteNotificationIfExists(notification);
|
||||
|
||||
expect(mockCallback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isNotificationScheduled", () => {
|
||||
it("returns true if the notification is in the repo", async () => {
|
||||
await repo.addOrUpdateNotification(notification);
|
||||
const result = await repo.isNotificationScheduled(notification);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false if the notification isn't in the repo", async () => {
|
||||
const result = await repo.isNotificationScheduled(notification);
|
||||
expect(result).toBe(false);
|
||||
})
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user