Files
Checkmate/server/test/integration/heartbeatJobNotificationFailure.test.ts
2026-04-11 14:45:36 -07:00

62 lines
2.0 KiB
TypeScript

import { describe, expect, it, beforeEach } from "@jest/globals";
import { createHeartbeatTestHarness, makeMonitor, type HeartbeatTestHarness } from "../helpers/heartbeatTestHarness.ts";
describe("Heartbeat job: notification failure isolation", () => {
let h: HeartbeatTestHarness;
beforeEach(() => {
h = createHeartbeatTestHarness();
});
it("creates incident even when notification dispatch throws", async () => {
const monitor = makeMonitor();
h.monitorsRepo.seed(monitor);
// Make notifications throw
h.notificationsService.handleNotifications.mockRejectedValue(new Error("SMTP connection refused"));
// Drive monitor down
h.setNextResponse(false, 503);
for (let i = 0; i < 3; i++) {
await h.heartbeatJob(monitor);
}
// Incident should still have been created
const incidents = h.incidentsRepo.getAll();
expect(incidents).toHaveLength(1);
expect(incidents[0].status).toBe(true);
expect(incidents[0].statusCode).toBe(503);
// Monitor should still be marked down
const storedMonitor = await h.monitorsRepo.findById("mon-1", "team-1");
expect(storedMonitor.status).toBe("down");
});
it("auto-resolves incident even when recovery notification throws", async () => {
const monitor = makeMonitor();
h.monitorsRepo.seed(monitor);
// Drive monitor down (notifications succeed here)
h.setNextResponse(false, 503);
for (let i = 0; i < 3; i++) {
await h.heartbeatJob(monitor);
}
expect(h.incidentsRepo.getAll()[0].status).toBe(true);
// Now make notifications throw for the recovery
h.notificationsService.handleNotifications.mockRejectedValue(new Error("Slack API timeout"));
// Recover
h.setNextResponse(true, 200);
for (let i = 0; i < 5; i++) {
await h.heartbeatJob(monitor);
}
// Incident should still be resolved despite notification failure
const incidents = h.incidentsRepo.getAll();
expect(incidents).toHaveLength(1);
expect(incidents[0].status).toBe(false);
expect(incidents[0].resolutionType).toBe("automatic");
});
});