update tests
This commit is contained in:
1 parent
85f674ee08
commit
08e9c02a3a
4 files changed
+91
-112
No files matched your search
@@ -0,0 +1,87 @@
|
||||
import { describe, expect, it, jest } from "@jest/globals";
|
||||
import { CheckEvaluator } from "../../../src/worker/worker.check-evaluator.ts";
|
||||
import { MonitorStatusPolicy } from "../../../src/worker/worker.monitor-status-policy.ts";
|
||||
import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts";
|
||||
|
||||
const makeMonitor = (overrides?: Partial<Monitor>): Monitor =>
|
||||
({
|
||||
id: "m1",
|
||||
teamId: "team",
|
||||
type: "http",
|
||||
interval: 60000,
|
||||
status: "up",
|
||||
...overrides,
|
||||
}) as Monitor;
|
||||
|
||||
const createEvaluator = (overrides?: Record<string, any>) => {
|
||||
const defaults = {
|
||||
statusService: {
|
||||
updateMonitorStatus: jest.fn().mockResolvedValue({ monitor: makeMonitor({ status: "up" }), statusChanged: false, prevStatus: "up", code: 200 }),
|
||||
},
|
||||
monitorStatusPolicy: new MonitorStatusPolicy(),
|
||||
...overrides,
|
||||
};
|
||||
const evaluator = new CheckEvaluator(defaults.statusService as any, defaults.monitorStatusPolicy as any);
|
||||
return { evaluator, defaults };
|
||||
};
|
||||
|
||||
describe("CheckEvaluator", () => {
|
||||
it("threads status, check, and monitor through to the status service", async () => {
|
||||
const { evaluator, defaults } = createEvaluator();
|
||||
const status = { monitorId: "m1", status: true, code: 200, message: "OK" } as any;
|
||||
const check = { id: "check-1" } as any;
|
||||
const monitor = makeMonitor({ status: "up" });
|
||||
|
||||
await evaluator.evaluate(status, check, monitor);
|
||||
|
||||
expect(defaults.statusService.updateMonitorStatus).toHaveBeenCalledWith(status, check, monitor);
|
||||
});
|
||||
|
||||
it("returns an evaluation that opens an incident on a down transition", async () => {
|
||||
const status = { monitorId: "m1", status: false, code: 500, message: "Error" } as any;
|
||||
const check = { id: "check-1" } as any;
|
||||
const statusChange = { monitor: makeMonitor({ status: "down" }), statusChanged: true, prevStatus: "up", code: 500 };
|
||||
const { evaluator } = createEvaluator({
|
||||
statusService: { updateMonitorStatus: jest.fn().mockResolvedValue(statusChange) },
|
||||
});
|
||||
|
||||
const result = await evaluator.evaluate(status, check, makeMonitor());
|
||||
|
||||
expect(result).toMatchObject({
|
||||
monitor: statusChange.monitor,
|
||||
status,
|
||||
check,
|
||||
statusChange,
|
||||
decision: expect.objectContaining({
|
||||
shouldCreateIncident: true,
|
||||
shouldSendNotification: true,
|
||||
incidentReason: "status_down",
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it("returns an evaluation that resolves an incident on recovery", async () => {
|
||||
const status = { monitorId: "m1", status: true, code: 200, message: "OK" } as any;
|
||||
const statusChange = { monitor: makeMonitor({ status: "up" }), statusChanged: true, prevStatus: "down", code: 200 };
|
||||
const { evaluator } = createEvaluator({
|
||||
statusService: { updateMonitorStatus: jest.fn().mockResolvedValue(statusChange) },
|
||||
});
|
||||
|
||||
const result = await evaluator.evaluate(status, { id: "check-1" } as any, makeMonitor({ status: "down" }));
|
||||
|
||||
expect(result.decision).toMatchObject({ shouldResolveIncident: true, shouldSendNotification: true });
|
||||
});
|
||||
|
||||
it("produces a no-op decision when status did not change", async () => {
|
||||
const status = { monitorId: "m1", status: true, code: 200, message: "OK" } as any;
|
||||
const { evaluator } = createEvaluator();
|
||||
|
||||
const result = await evaluator.evaluate(status, { id: "check-1" } as any, makeMonitor());
|
||||
|
||||
expect(result.decision).toMatchObject({
|
||||
shouldCreateIncident: false,
|
||||
shouldResolveIncident: false,
|
||||
shouldSendNotification: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -20,114 +20,6 @@ const activeWindow = () => {
|
||||
return { active: true, start: new Date(now - 1000).toISOString(), end: new Date(now + 1000).toISOString(), repeat: 0 };
|
||||
};
|
||||
|
||||
// ── CheckPipeline ────────────────────────────────────────────────────────────
|
||||
|
||||
const createCheckPipeline = (overrides?: Record<string, any>) => {
|
||||
const defaults = {
|
||||
logger: createMockLogger(),
|
||||
networkService: { requestStatus: jest.fn().mockResolvedValue({ monitorId: "m1", status: true, code: 200, message: "OK" }) },
|
||||
statusService: {
|
||||
updateMonitorStatus: jest.fn().mockResolvedValue({ monitor: { id: "m1", status: "up" }, statusChanged: false, prevStatus: "up", code: 200 }),
|
||||
},
|
||||
checkService: { toCheck: jest.fn().mockReturnValue({ id: "check-1" }) },
|
||||
buffer: { addToBuffer: jest.fn() },
|
||||
monitorsRepository: { updateById: jest.fn().mockResolvedValue({}) },
|
||||
maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([]) },
|
||||
monitorStatusPolicy: new MonitorStatusPolicy(),
|
||||
...overrides,
|
||||
};
|
||||
const checkProducer = new CheckProducer(
|
||||
defaults.monitorsRepository as any,
|
||||
defaults.maintenanceWindowsRepository as any,
|
||||
defaults.checkService as any,
|
||||
defaults.networkService as any,
|
||||
defaults.buffer as any,
|
||||
defaults.logger as any
|
||||
);
|
||||
const checkEvaluator = new CheckEvaluator(defaults.statusService as any, defaults.monitorStatusPolicy as any);
|
||||
const pipeline = new CheckPipeline(checkProducer, checkEvaluator);
|
||||
return { pipeline, defaults };
|
||||
};
|
||||
|
||||
describe("CheckPipeline", () => {
|
||||
it("throws when monitor id is missing", async () => {
|
||||
const { pipeline } = createCheckPipeline();
|
||||
await expect(pipeline.run({} as Monitor)).rejects.toThrow("No monitor id");
|
||||
});
|
||||
|
||||
it("skips and sets maintenance status when in maintenance window", async () => {
|
||||
const { pipeline, defaults } = createCheckPipeline({
|
||||
maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([activeWindow()]) },
|
||||
});
|
||||
|
||||
const result = await pipeline.run(makeMonitor({ status: "up" }));
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(defaults.networkService.requestStatus).not.toHaveBeenCalled();
|
||||
expect(defaults.monitorsRepository.updateById).toHaveBeenCalledWith("m1", "team", { status: "maintenance", statusWindow: [] });
|
||||
});
|
||||
|
||||
it("does not re-write status when already in maintenance", async () => {
|
||||
const { pipeline, defaults } = createCheckPipeline({
|
||||
maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([activeWindow()]) },
|
||||
});
|
||||
|
||||
await pipeline.run(makeMonitor({ status: "maintenance" }));
|
||||
|
||||
expect(defaults.monitorsRepository.updateById).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("throws when network response is null", async () => {
|
||||
const { pipeline } = createCheckPipeline({
|
||||
networkService: { requestStatus: jest.fn().mockResolvedValue(null) },
|
||||
});
|
||||
await expect(pipeline.run(makeMonitor())).rejects.toThrow("No network response");
|
||||
});
|
||||
|
||||
it("returns null and warns when toCheck returns null", async () => {
|
||||
const { pipeline, defaults } = createCheckPipeline({
|
||||
checkService: { toCheck: jest.fn().mockReturnValue(null) },
|
||||
});
|
||||
|
||||
const result = await pipeline.run(makeMonitor());
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(defaults.logger.warn).toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringContaining("No check could be built") }));
|
||||
expect(defaults.statusService.updateMonitorStatus).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("buffers the check, updates status, and returns an evaluation", async () => {
|
||||
const status = { monitorId: "m1", status: false, code: 500, message: "Error" };
|
||||
const statusChange = { monitor: { id: "m1", status: "down" }, statusChanged: true, prevStatus: "up", code: 500 };
|
||||
const { pipeline, defaults } = createCheckPipeline({
|
||||
networkService: { requestStatus: jest.fn().mockResolvedValue(status) },
|
||||
statusService: { updateMonitorStatus: jest.fn().mockResolvedValue(statusChange) },
|
||||
});
|
||||
|
||||
const result = await pipeline.run(makeMonitor());
|
||||
|
||||
expect(defaults.buffer.addToBuffer).toHaveBeenCalledWith({ id: "check-1" });
|
||||
expect(defaults.statusService.updateMonitorStatus).toHaveBeenCalled();
|
||||
expect(result).toMatchObject({
|
||||
monitor: statusChange.monitor,
|
||||
status,
|
||||
check: { id: "check-1" },
|
||||
statusChange,
|
||||
decision: expect.objectContaining({ shouldCreateIncident: true, shouldSendNotification: true, incidentReason: "status_down" }),
|
||||
});
|
||||
});
|
||||
|
||||
it("proceeds with the check when no maintenance window is active", async () => {
|
||||
const { pipeline, defaults } = createCheckPipeline({
|
||||
maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([{ ...activeWindow(), active: false }]) },
|
||||
});
|
||||
|
||||
await pipeline.run(makeMonitor());
|
||||
|
||||
expect(defaults.networkService.requestStatus).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
// ── GeoChecksPipeline ──────────────────────────────────────────────────────────
|
||||
|
||||
const createGeoPipeline = (overrides?: Record<string, any>) => {
|
||||
|
||||
@@ -56,7 +56,7 @@ describe("CheckProducer", () => {
|
||||
const result = await producer.produce(makeMonitor({ status: "up" }));
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(defaults.monitorsRepository.updateById).toHaveBeenCalledWith("m1", "team", { status: "maintenance" });
|
||||
expect(defaults.monitorsRepository.updateById).toHaveBeenCalledWith("m1", "team", { status: "maintenance", statusWindow: [] });
|
||||
expect(defaults.networkService.requestStatus).not.toHaveBeenCalled();
|
||||
expect(defaults.buffer.addToBuffer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -564,7 +564,7 @@ describe("StatusService", () => {
|
||||
const { service, monitorsRepository } = createService();
|
||||
(monitorsRepository.findById as jest.Mock).mockResolvedValue(monitor);
|
||||
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: true }), makeCheck({ status: true }));
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: true }), makeCheck({ status: true }), monitor);
|
||||
|
||||
expect(result.statusChanged).toBe(false);
|
||||
expect(result.monitor.status).toBe("up");
|
||||
@@ -579,7 +579,7 @@ describe("StatusService", () => {
|
||||
const { service, monitorsRepository } = createService();
|
||||
(monitorsRepository.findById as jest.Mock).mockResolvedValue(monitor);
|
||||
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: false }), makeCheck({ status: false }));
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: false }), makeCheck({ status: false }), monitor);
|
||||
|
||||
expect(result.statusChanged).toBe(true);
|
||||
expect(result.monitor.status).toBe("down");
|
||||
@@ -599,7 +599,7 @@ describe("StatusService", () => {
|
||||
const { service, monitorsRepository } = createService();
|
||||
(monitorsRepository.findById as jest.Mock).mockResolvedValue(monitor);
|
||||
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: true }), makeCheck({ status: true }));
|
||||
const result = await service.updateMonitorStatus(makeStatusResponse({ status: true }), makeCheck({ status: true }), monitor);
|
||||
|
||||
expect(result.monitor.status).toBe("up");
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user