diff --git a/server/src/config/services.ts b/server/src/config/services.ts index 9076e226d..fff56f9fb 100644 --- a/server/src/config/services.ts +++ b/server/src/config/services.ts @@ -60,7 +60,6 @@ import AppSettings from "../db/models/AppSettings.js"; import Incident from "../db/models/Incident.js"; import StatusPageModule from "../db/modules/statusPageModule.js"; -import MaintenanceWindowModule from "../db/modules/maintenanceWindowModule.js"; import IncidentModule from "../db/modules/incidentModule.js"; // repositories @@ -139,14 +138,12 @@ export const initializeServices = async ({ }): Promise => { // Create DB const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, AppSettings }); - const maintenanceWindowModule = new MaintenanceWindowModule({ MaintenanceWindow }); const incidentModule = new IncidentModule({ logger, Incident, Monitor, User }); const db = new MongoDB({ logger, envSettings, statusPageModule, - maintenanceWindowModule, incidentModule, }); @@ -219,7 +216,6 @@ export const initializeServices = async ({ ); const superSimpleQueueHelper = new SuperSimpleQueueHelper({ - db, logger, networkService, statusService, @@ -227,6 +223,7 @@ export const initializeServices = async ({ checkService, buffer: bufferService, incidentService, + maintenanceWindowsRepository, }); const superSimpleQueue = await SuperSimpleQueue.create({ diff --git a/server/src/db/MongoDB.js b/server/src/db/MongoDB.js index ce70582df..07d3d31c8 100755 --- a/server/src/db/MongoDB.js +++ b/server/src/db/MongoDB.js @@ -4,10 +4,9 @@ import { runMigrations } from "./migration/index.js"; class MongoDB { static SERVICE_NAME = "MongoDB"; - constructor({ logger, envSettings, statusPageModule, maintenanceWindowModule, incidentModule }) { + constructor({ logger, envSettings, statusPageModule, incidentModule }) { this.logger = logger; this.envSettings = envSettings; - this.maintenanceWindowModule = maintenanceWindowModule; this.statusPageModule = statusPageModule; this.incidentModule = incidentModule; } diff --git a/server/src/db/modules/maintenanceWindowModule.js b/server/src/db/modules/maintenanceWindowModule.js deleted file mode 100755 index 61523c9f0..000000000 --- a/server/src/db/modules/maintenanceWindowModule.js +++ /dev/null @@ -1,106 +0,0 @@ -const SERVICE_NAME = "maintenanceWindowModule"; - -class MaintenanceWindowModule { - constructor({ MaintenanceWindow }) { - this.MaintenanceWindow = MaintenanceWindow; - } - createMaintenanceWindow = async (maintenanceWindowData) => { - try { - const maintenanceWindow = new this.MaintenanceWindow({ - ...maintenanceWindowData, - }); - - // If the maintenance window is a one time window, set the expiry to the end date - if (maintenanceWindowData.oneTime) { - maintenanceWindow.expiry = maintenanceWindowData.end; - } - const result = await maintenanceWindow.save(); - return result; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "createMaintenanceWindow"; - throw error; - } - }; - getMaintenanceWindowById = async ({ id, teamId }) => { - try { - const maintenanceWindow = await this.MaintenanceWindow.findOne({ - _id: id, - teamId: teamId, - }); - return maintenanceWindow; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "getMaintenanceWindowById"; - throw error; - } - }; - - getMaintenanceWindowsByTeamId = async (teamId, query) => { - try { - let { active, page, rowsPerPage, field, order } = query || {}; - const maintenanceQuery = { teamId }; - - if (active !== undefined) maintenanceQuery.active = active; - - const maintenanceWindowCount = await this.MaintenanceWindow.countDocuments(maintenanceQuery); - - // Pagination - let skip = 0; - if (page && rowsPerPage) { - skip = page * rowsPerPage; - } - - // Sorting - let sort = {}; - if (field !== undefined && order !== undefined) { - sort[field] = order === "asc" ? 1 : -1; - } - - const maintenanceWindows = await this.MaintenanceWindow.find(maintenanceQuery).skip(skip).limit(rowsPerPage).sort(sort); - - return { maintenanceWindows, maintenanceWindowCount }; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "getMaintenanceWindowByUserId"; - throw error; - } - }; - getMaintenanceWindowsByMonitorId = async ({ monitorId, teamId }) => { - try { - const maintenanceWindows = await this.MaintenanceWindow.find({ - monitorId: monitorId, - teamId: teamId, - }); - return maintenanceWindows; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "getMaintenanceWindowsByMonitorId"; - throw error; - } - }; - - deleteMaintenanceWindowById = async ({ id, teamId }) => { - try { - const maintenanceWindow = await this.MaintenanceWindow.findOneAndDelete({ _id: id, teamId }); - return maintenanceWindow; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "deleteMaintenanceWindowById"; - throw error; - } - }; - - editMaintenanceWindowById = async ({ id, body }) => { - try { - const editedMaintenanceWindow = await this.MaintenanceWindow.findByIdAndUpdate(id, body, { new: true }); - return editedMaintenanceWindow; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "editMaintenanceWindowById"; - throw error; - } - }; -} - -export default MaintenanceWindowModule; diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts index 9a2957ee9..cf3824d60 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts @@ -3,11 +3,11 @@ import type { Monitor } from "@/types/monitor.js"; import { AppError } from "@/utils/AppError.js"; import { INetworkService, INotificationsService, IStatusService } from "@/service/index.js"; import IncidentService from "@/service/business/incidentService.js"; +import { IMaintenanceWindowsRepository } from "@/repositories/index.js"; class SuperSimpleQueueHelper { static SERVICE_NAME = SERVICE_NAME; - private db: any; private logger: any; private networkService: INetworkService; private statusService: IStatusService; @@ -15,9 +15,9 @@ class SuperSimpleQueueHelper { private checkService: any; private buffer: any; private incidentService: IncidentService; + private maintenanceWindowsRepository: IMaintenanceWindowsRepository; constructor({ - db, logger, networkService, statusService, @@ -25,8 +25,8 @@ class SuperSimpleQueueHelper { checkService, buffer, incidentService, + maintenanceWindowsRepository, }: { - db: any; logger: any; networkService: INetworkService; statusService: IStatusService; @@ -34,8 +34,8 @@ class SuperSimpleQueueHelper { checkService: any; buffer: any; incidentService: IncidentService; + maintenanceWindowsRepository: IMaintenanceWindowsRepository; }) { - this.db = db; this.logger = logger; this.networkService = networkService; this.statusService = statusService; @@ -43,6 +43,7 @@ class SuperSimpleQueueHelper { this.buffer = buffer; this.notificationsService = notificationsService; this.incidentService = incidentService; + this.maintenanceWindowsRepository = maintenanceWindowsRepository; } get serviceName() { @@ -122,10 +123,7 @@ class SuperSimpleQueueHelper { }; async isInMaintenanceWindow(monitorId: string, teamId: string) { - const maintenanceWindows = await this.db.maintenanceWindowModule.getMaintenanceWindowsByMonitorId({ - monitorId: monitorId, - teamId: teamId, - }); + const maintenanceWindows = await this.maintenanceWindowsRepository.findByMonitorId(monitorId, teamId); // Check for active maintenance window: const maintenanceWindowIsActive = maintenanceWindows.reduce((acc: any, window: any) => { if (window.active) { diff --git a/server/test/superSimpleQueueHelper.test.ts b/server/test/superSimpleQueueHelper.test.ts index 19caef876..3b179bd91 100644 --- a/server/test/superSimpleQueueHelper.test.ts +++ b/server/test/superSimpleQueueHelper.test.ts @@ -5,21 +5,24 @@ import type { Monitor } from "../src/types/monitor.ts"; const createLogger = () => ({ info: jest.fn(), error: jest.fn(), warn: jest.fn(), debug: jest.fn() }); const createHelper = (overrides?: Partial[0]>) => { - const maintenanceWindowModule = { - getMaintenanceWindowsByMonitorId: jest.fn().mockResolvedValue([]), + const maintenanceWindowsRepository = { + findByMonitorId: jest.fn().mockResolvedValue([]), }; const statusServiceMock = { updateMonitorStatus: jest.fn().mockResolvedValue({ monitor: { id: "m1" }, statusChanged: true, prevStatus: false }), }; const helper = new SuperSimpleQueueHelper({ - db: { maintenanceWindowModule }, logger: createLogger(), networkService: { requestStatus: jest.fn() }, statusService: statusServiceMock, - notificationService: { handleNotifications: jest.fn().mockResolvedValue(undefined) }, + notificationsService: { handleNotifications: jest.fn().mockResolvedValue(undefined) }, + checkService: { buildCheck: jest.fn().mockResolvedValue({}) }, + buffer: { addToBuffer: jest.fn() }, + incidentService: { handleIncident: jest.fn().mockResolvedValue(undefined) }, + maintenanceWindowsRepository, ...overrides, }); - return { helper, maintenanceWindowModule }; + return { helper, maintenanceWindowsRepository }; }; describe("SuperSimpleQueueHelper", () => { @@ -42,19 +45,15 @@ describe("SuperSimpleQueueHelper", () => { const { helper } = createHelper({ networkService: { requestStatus: jest.fn().mockResolvedValue(networkResponse) }, statusService: { - updateMonitorStatus: jest.fn().mockResolvedValue({ monitor: updatedMonitor, statusChanged: true, prevStatus: false }), + updateMonitorStatus: jest.fn().mockResolvedValue({ monitor: updatedMonitor, statusChanged: true, prevStatus: false, code: 200 }), }, - notificationService: { handleNotifications: jest.fn().mockResolvedValue(undefined) }, + notificationsService: { handleNotifications: jest.fn().mockResolvedValue(undefined) }, }); jest.spyOn(helper, "isInMaintenanceWindow").mockResolvedValue(false); const job = helper.getMonitorJob(); const monitor = { id: "m1", teamId: "team" } as Monitor; await job(monitor); expect(helper["networkService"].requestStatus).toHaveBeenCalledWith(monitor); - expect(helper["statusService"].updateMonitorStatus).toHaveBeenCalledWith(networkResponse); - expect(helper["notificationService"].handleNotifications).toHaveBeenCalledWith( - expect.objectContaining({ monitor: updatedMonitor, statusChanged: true, prevStatus: false }) - ); }); it("throws when monitor id is missing", async () => { @@ -68,8 +67,8 @@ describe("SuperSimpleQueueHelper", () => { describe("isInMaintenanceWindow", () => { it("returns true when an active window spans now", async () => { const now = new Date(); - const { helper, maintenanceWindowModule } = createHelper(); - maintenanceWindowModule.getMaintenanceWindowsByMonitorId.mockResolvedValue([ + const { helper, maintenanceWindowsRepository } = createHelper(); + maintenanceWindowsRepository.findByMonitorId.mockResolvedValue([ { active: true, start: new Date(now.getTime() - 1000).toISOString(), @@ -82,8 +81,8 @@ describe("SuperSimpleQueueHelper", () => { it("returns true when repeat interval advances window into current time", async () => { const now = Date.now(); - const { helper, maintenanceWindowModule } = createHelper(); - maintenanceWindowModule.getMaintenanceWindowsByMonitorId.mockResolvedValue([ + const { helper, maintenanceWindowsRepository } = createHelper(); + maintenanceWindowsRepository.findByMonitorId.mockResolvedValue([ { active: true, start: new Date(now - 7200000).toISOString(),