add tests for mw and monitor services

This commit is contained in:
Alex Holliday committed 2026-05-25 09:57:34 -07:00
1 parent d1f46aba9e
commit a415c75eb4
2 files changed
+112

No files matched your search

@@ -296,6 +296,45 @@ describe("MaintenanceWindowService", () => {
expect(monitorsRepository.updateByIds).toHaveBeenCalledTimes(1);
expect(monitorsRepository.updateByIds).toHaveBeenCalledWith(["mon-1"], "team-1", { status: "initializing" }, ["paused"]);
});
it("skips the overlap lookup when an active window with no monitorIds is deleted", async () => {
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: [] }));
const { service, monitorsRepository } = createService({ maintenanceWindowsRepository });
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
expect(maintenanceWindowsRepository.findByMonitorIds).not.toHaveBeenCalled();
expect(monitorsRepository.updateByIds).not.toHaveBeenCalled();
});
it("ignores monitorIds in overlapping windows that are outside the leaving set", async () => {
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: ["mon-1"] }));
// overlapping window covers mon-1 (in the leaving set) plus mon-99 (unrelated, must be skipped)
(maintenanceWindowsRepository.findByMonitorIds as jest.Mock).mockResolvedValue([
makeActiveWindow({ id: "mw-2", monitorIds: ["mon-1", "mon-99"] }),
]);
const { service, monitorsRepository } = createService({ maintenanceWindowsRepository });
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
// mon-1 is still covered by mw-2; mon-99 must not leak into the update
expect(monitorsRepository.updateByIds).not.toHaveBeenCalled();
});
it("makes no monitor updates when every leaving monitor is still covered by another active window", async () => {
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: ["mon-1", "mon-2"] }));
(maintenanceWindowsRepository.findByMonitorIds as jest.Mock).mockResolvedValue([
makeActiveWindow({ id: "mw-2", monitorIds: ["mon-1", "mon-2"] }),
]);
const { service, monitorsRepository } = createService({ maintenanceWindowsRepository });
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
expect(monitorsRepository.updateByIds).not.toHaveBeenCalled();
});
});
// ── editMaintenanceWindow ────────────────────────────────────────────────
@@ -973,6 +973,79 @@ describe("MonitorService", () => {
})
);
});
it("logs a resume failure with undefined stack when rejection is not an Error instance", async () => {
const monitorsRepository = createMonitorsRepositoryMock();
const monitors = [makeMonitor({ id: "m1", isActive: true })];
(monitorsRepository.bulkTogglePause as jest.Mock).mockResolvedValue(monitors);
const jobQueue = createJobQueueMock();
// Reject with a non-Error value to exercise the `instanceof Error` false branch
(jobQueue.resumeJob as jest.Mock).mockRejectedValueOnce("queue blew up");
const logger = createMockLogger();
const { service } = createService({ monitorsRepository, jobQueue, logger });
const result = await service.bulkPauseMonitors({
teamId: TEAM_ID,
monitorIds: ["m1"],
pause: false,
});
expect(result.failedCount).toBe(1);
expect(logger.error).toHaveBeenCalledTimes(1);
expect(logger.error).toHaveBeenCalledWith({
message: "Failed to sync job queue for monitor m1 during bulk resume",
service: "MonitorService",
method: "bulkPauseMonitors",
stack: undefined,
});
});
it("logs 'unknown' when the failing monitor has no id", async () => {
const monitorsRepository = createMonitorsRepositoryMock();
const monitors = [makeMonitor({ id: "", isActive: false })];
(monitorsRepository.bulkTogglePause as jest.Mock).mockResolvedValue(monitors);
const jobQueue = createJobQueueMock();
(jobQueue.pauseJob as jest.Mock).mockRejectedValueOnce(new Error("boom"));
const logger = createMockLogger();
const { service } = createService({ monitorsRepository, jobQueue, logger });
const result = await service.bulkPauseMonitors({
teamId: TEAM_ID,
monitorIds: ["m1"],
pause: true,
});
expect(result.failedCount).toBe(1);
expect(logger.error).toHaveBeenCalledWith(
expect.objectContaining({
message: "Failed to sync job queue for monitor unknown during bulk pause",
})
);
});
it("logs 'unknown' when the failing monitor at the rejected index is nullish", async () => {
const monitorsRepository = createMonitorsRepositoryMock();
// Defensive: bulkTogglePause returns an array containing a nullish entry; the
// inner map throws TypeError, the forEach hits the `?.` short-circuit branch.
(monitorsRepository.bulkTogglePause as jest.Mock).mockResolvedValue([undefined]);
const logger = createMockLogger();
const { service } = createService({ monitorsRepository, logger });
const result = await service.bulkPauseMonitors({
teamId: TEAM_ID,
monitorIds: ["m1"],
pause: true,
});
expect(result.failedCount).toBe(1);
expect(logger.error).toHaveBeenCalledWith(
expect.objectContaining({
message: "Failed to sync job queue for monitor unknown during bulk pause",
})
);
});
});
describe("deleteMonitor", () => {