Files
Checkmate/server/tests/controllers/monitorController.test.js
2025-04-20 11:29:53 -07:00

1125 lines
34 KiB
JavaScript
Executable File

import {
getAllMonitors,
getAllMonitorsWithUptimeStats,
getMonitorStatsById,
getMonitorCertificate,
getMonitorById,
getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
checkEndpointResolution,
deleteMonitor,
deleteAllMonitors,
editMonitor,
pauseMonitor,
addDemoMonitors,
} from "../../controllers/monitorController.js";
import jwt from "jsonwebtoken";
import sinon from "sinon";
import { successMessages } from "../../utils/messages.js";
import logger from "../../utils/logger.js";
import axios from "axios";
const SERVICE_NAME = "monitorController";
describe("Monitor Controller - getAllMonitors", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {},
query: {},
body: {},
db: {
getAllMonitors: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if DB operations fail", async function () {
req.db.getAllMonitors.throws(new Error("DB error"));
await getAllMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed", async function () {
const data = [{ monitor: "data" }];
req.db.getAllMonitors.returns(data);
await getAllMonitors(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_GET_ALL,
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - getAllMonitorsWithUptimeStats", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {},
query: {},
body: {},
db: {
getAllMonitorsWithUptimeStats: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if DB operations fail", async function () {
req.db.getAllMonitorsWithUptimeStats.throws(new Error("DB error"));
await getAllMonitorsWithUptimeStats(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed", async function () {
const data = [{ monitor: "data" }];
req.db.getAllMonitorsWithUptimeStats.returns(data);
await getAllMonitorsWithUptimeStats(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_GET_ALL,
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - getMonitorStatsById", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
getMonitorStatsById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await getMonitorStatsById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if query validation fails", async function () {
req.query = { invalid: 1 };
await getMonitorStatsById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB operations fail", async function () {
req.db.getMonitorStatsById.throws(new Error("DB error"));
await getMonitorStatsById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed", async function () {
const data = [{ monitorStats: "data" }];
req.db.getMonitorStatsById.returns(data);
await getMonitorStatsById(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_STATS_BY_ID,
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - getMonitorCertificate", function () {
let req, res, next, fetchMonitorCertificate;
beforeEach(function () {
req = {
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
getMonitorById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
fetchMonitorCertificate = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await getMonitorCertificate(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if getMonitorById operation fails", async function () {
req.db.getMonitorById.throws(new Error("DB error"));
await getMonitorCertificate(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed with a valid cert", async function () {
req.db.getMonitorById.returns({ url: "https://www.google.com" });
const data = { certificate: "cert", validTo: "2024/08/08" };
fetchMonitorCertificate.returns(data);
await getMonitorCertificate(req, res, next, fetchMonitorCertificate);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_CERTIFICATE,
data: { certificateDate: new Date(data.validTo) },
})
).to.be.true;
});
it("should return an error if fetchMonitorCertificate fails", async function () {
req.db.getMonitorById.returns({ url: "https://www.google.com" });
fetchMonitorCertificate.throws(new Error("Certificate error"));
await getMonitorCertificate(req, res, next, fetchMonitorCertificate);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Certificate error");
});
});
describe("Monitor Controller - getMonitorById", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
getMonitorById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await getMonitorById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if query param validation fails", async function () {
req.query = { invalid: 1 };
await getMonitorById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB operations fail", async function () {
req.db.getMonitorById.throws(new Error("DB error"));
await getMonitorById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return 404 if a monitor is not found", async function () {
const error = new Error("Monitor not found");
error.status = 404;
req.db.getMonitorById.throws(error);
await getMonitorById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(404);
});
it("should return success message and data if all operations succeed", async function () {
const data = { monitor: "data" };
req.db.getMonitorById.returns(data);
await getMonitorById(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_GET_BY_ID,
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - getMonitorsAndSummaryByTeamId", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {
teamId: "123",
},
query: {},
body: {},
db: {
getMonitorsAndSummaryByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await getMonitorsAndSummaryByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if query validation fails", async function () {
req.query = { invalid: 1 };
await getMonitorsAndSummaryByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB operations fail", async function () {
req.db.getMonitorsAndSummaryByTeamId.throws(new Error("DB error"));
await getMonitorsAndSummaryByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed", async function () {
const data = { monitors: "data", summary: "data" };
req.db.getMonitorsAndSummaryByTeamId.returns(data);
await getMonitorsAndSummaryByTeamId(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_GET_BY_USER_ID(req.params.teamId),
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - getMonitorsByTeamId", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {
teamId: "123",
},
query: {},
body: {},
db: {
getMonitorsByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await getMonitorsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if query validation fails", async function () {
req.query = { invalid: 1 };
await getMonitorsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB operations fail", async function () {
req.db.getMonitorsByTeamId.throws(new Error("DB error"));
await getMonitorsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should return success message and data if all operations succeed", async function () {
const data = { monitors: "data" };
req.db.getMonitorsByTeamId.returns(data);
await getMonitorsByTeamId(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_GET_BY_USER_ID(req.params.teamId),
data: data,
})
).to.be.true;
});
});
describe("Monitor Controller - createMonitor", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {},
query: {},
body: {
userId: "123",
teamId: "123",
name: "test_monitor",
description: "test_monitor_desc",
type: "http",
url: "https://example.com",
notifications: [{ email: "example@example.com" }],
},
db: {
createMonitor: sinon.stub(),
createNotification: sinon.stub(),
},
jobQueue: {
addJob: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if body validation fails", async function () {
req.body = {};
await createMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB createMonitor operation fail", async function () {
req.db.createMonitor.throws(new Error("DB error"));
await createMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if DB createNotification operation fail", async function () {
req.db.createNotification.throws(new Error("DB error"));
req.db.createMonitor.returns({ _id: "123" });
await createMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if monitor.save operation fail", async function () {
req.db.createMonitor.returns({
_id: "123",
save: sinon.stub().throws(new Error("Monitor save error")),
});
await createMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Monitor save error");
});
it("should throw an error if addJob operation fails", async function () {
req.db.createMonitor.returns({ _id: "123", save: sinon.stub() });
req.jobQueue.addJob.throws(new Error("Job error"));
await createMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Job error");
});
it("should return success message and data if all operations succeed", async function () {
const monitor = { _id: "123", save: sinon.stub() };
req.db.createMonitor.returns(monitor);
await createMonitor(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(201);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_CREATE,
data: monitor,
})
).to.be.true;
});
});
describe("Monitor Controller - checkEndpointResolution", function () {
let req, res, next, axiosGetStub;
beforeEach(function () {
req = { query: { monitorURL: "https://example.com" } };
res = { status: sinon.stub().returnsThis(), json: sinon.stub() };
next = sinon.stub();
axiosGetStub = sinon.stub(axios, "get");
});
afterEach(function () {
sinon.restore();
});
it("should resolve the URL successfully", async function () {
axiosGetStub.resolves({ status: 200, statusText: "OK" });
await checkEndpointResolution(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
code: 200,
statusText: "OK",
msg: "URL resolved successfully",
})
).to.be.true;
expect(next.called).to.be.false;
});
it("should return an error if endpoint resolution fails", async function () {
const axiosError = new Error("resolution failed");
axiosError.code = "ENOTFOUND";
axiosGetStub.rejects(axiosError);
await checkEndpointResolution(req, res, next);
expect(next.calledOnce).to.be.true;
const errorPassedToNext = next.getCall(0).args[0];
expect(errorPassedToNext).to.be.an.instanceOf(Error);
expect(errorPassedToNext.message).to.include("resolution failed");
expect(errorPassedToNext.code).to.equal("ENOTFOUND");
expect(errorPassedToNext.status).to.equal(500);
});
it("should reject with an error if query validation fails", async function () {
req.query.monitorURL = "invalid-url";
await checkEndpointResolution(req, res, next);
expect(next.calledOnce).to.be.true;
const error = next.getCall(0).args[0];
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
expect(error.message).to.equal('"monitorURL" must be a valid uri');
});
});
describe("Monitor Controller - deleteMonitor", function () {
let req, res, next;
beforeEach(function () {
req = {
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
deleteMonitor: sinon.stub(),
deleteChecks: sinon.stub(),
deletePageSpeedChecksByMonitorId: sinon.stub(),
deleteNotificationsByMonitorId: sinon.stub(),
},
jobQueue: {
deleteJob: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
sinon.stub(logger, "error");
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await deleteMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if DB deleteMonitor operation fail", async function () {
req.db.deleteMonitor.throws(new Error("DB error"));
await deleteMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should log an error if deleteJob throws an error", async function () {
const error = new Error("Job error");
const monitor = { name: "test_monitor", _id: "123" };
req.db.deleteMonitor.returns(monitor);
req.jobQueue.deleteJob.rejects(error);
await deleteMonitor(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deleteChecks throws an error", async function () {
const error = new Error("Checks error");
const monitor = { name: "test_monitor", _id: "123" };
req.db.deleteMonitor.returns(monitor);
req.db.deleteChecks.rejects(error);
await deleteMonitor(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deletePageSpeedChecksByMonitorId throws an error", async function () {
const error = new Error("PageSpeed error");
const monitor = { name: "test_monitor", _id: "123" };
req.db.deleteMonitor.returns(monitor);
req.db.deletePageSpeedChecksByMonitorId.rejects(error);
await deleteMonitor(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deleteNotificationsByMonitorId throws an error", async function () {
const error = new Error("Notifications error");
const monitor = { name: "test_monitor", _id: "123" };
req.db.deleteMonitor.returns(monitor);
req.db.deleteNotificationsByMonitorId.rejects(error);
await deleteMonitor(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should return success message if all operations succeed", async function () {
const monitor = { name: "test_monitor", _id: "123" };
req.db.deleteMonitor.returns(monitor);
await deleteMonitor(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_DELETE,
})
).to.be.true;
});
});
describe("Monitor Controller - deleteAllMonitors", function () {
let req, res, next, stub;
beforeEach(function () {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req = {
headers: {
authorization: "Bearer token",
},
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
deleteAllMonitors: sinon.stub(),
deleteChecks: sinon.stub(),
deletePageSpeedChecksByMonitorId: sinon.stub(),
deleteNotificationsByMonitorId: sinon.stub(),
},
jobQueue: {
deleteJob: sinon.stub(),
},
settingsService: {
getSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
sinon.stub(logger, "error");
});
afterEach(function () {
sinon.restore();
stub.restore();
});
it("should reject with an error if getTokenFromHeaders throws an error", async function () {
req.headers = {};
await deleteAllMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("No auth headers");
expect(next.firstCall.args[0].status).to.equal(500);
});
it("should reject with an error if token validation fails", async function () {
stub.restore();
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
await deleteAllMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
});
it("should reject with an error if DB deleteAllMonitors operation fail", async function () {
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.deleteAllMonitors.throws(new Error("DB error"));
await deleteAllMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should log an error if deleteChecks throws an error", async function () {
const monitors = [{ name: "test_monitor", _id: "123" }];
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.deleteAllMonitors.returns({ monitors, deletedCount: 1 });
const error = new Error("Check error");
req.db.deleteChecks.rejects(error);
await deleteAllMonitors(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}`
);
});
it("should log an error if deletePageSpeedChecksByMonitorId throws an error", async function () {
const monitors = [{ name: "test_monitor", _id: "123" }];
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.deleteAllMonitors.returns({ monitors, deletedCount: 1 });
const error = new Error("Pagespeed Check error");
req.db.deletePageSpeedChecksByMonitorId.rejects(error);
await deleteAllMonitors(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}`
);
});
it("should log an error if deleteNotificationsByMonitorId throws an error", async function () {
const monitors = [{ name: "test_monitor", _id: "123" }];
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.deleteAllMonitors.returns({ monitors, deletedCount: 1 });
const error = new Error("Notifications Check error");
req.db.deleteNotificationsByMonitorId.rejects(error);
await deleteAllMonitors(req, res, next);
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal(
`Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}`
);
});
it("should return success message if all operations succeed", async function () {
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.deleteAllMonitors.returns({
monitors: [{ name: "test_monitor", _id: "123" }],
deletedCount: 1,
});
await deleteAllMonitors(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: "Deleted 1 monitors",
})
).to.be.true;
});
});
describe("Monitor Controller - editMonitor", function () {
let req, res, next;
beforeEach(function () {
req = {
headers: {},
params: {
monitorId: "123",
},
query: {},
body: {
notifications: [{ email: "example@example.com" }],
},
db: {
getMonitorById: sinon.stub(),
editMonitor: sinon.stub(),
deleteNotificationsByMonitorId: sinon.stub(),
createNotification: sinon.stub(),
},
jobQueue: {
deleteJob: sinon.stub(),
addJob: sinon.stub(),
},
settingsService: {
getSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if body validation fails", async function () {
req.body = { invalid: 1 };
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if getMonitorById operation fails", async function () {
req.db.getMonitorById.throws(new Error("DB error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if editMonitor operation fails", async function () {
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.throws(new Error("DB error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if deleteNotificationsByMonitorId operation fails", async function () {
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.returns({ _id: "123" });
req.db.deleteNotificationsByMonitorId.throws(new Error("DB error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if createNotification operation fails", async function () {
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.returns({ _id: "123" });
req.db.createNotification.throws(new Error("DB error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if deleteJob operation fails", async function () {
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.returns({ _id: "123" });
req.jobQueue.deleteJob.throws(new Error("Job error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Job error");
});
it("should reject with an error if addJob operation fails", async function () {
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.returns({ _id: "123" });
req.jobQueue.addJob.throws(new Error("Add Job error"));
await editMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Add Job error");
});
it("should return success message with data if all operations succeed", async function () {
const monitor = { _id: "123" };
req.db.getMonitorById.returns({ teamId: "123" });
req.db.editMonitor.returns(monitor);
await editMonitor(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_EDIT,
data: monitor,
})
).to.be.true;
});
});
describe("Monitor Controller - pauseMonitor", function () {
let req, res, next;
beforeEach(function () {
req = {
headers: {},
params: {
monitorId: "123",
},
query: {},
body: {},
db: {
getMonitorById: sinon.stub(),
},
jobQueue: {
deleteJob: sinon.stub(),
addJob: sinon.stub(),
},
settingsService: {
getSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
});
it("should reject with an error if param validation fails", async function () {
req.params = {};
await pauseMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject with an error if getMonitorById operation fails", async function () {
req.db.getMonitorById.throws(new Error("DB error"));
await pauseMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if deleteJob operation fails", async function () {
const monitor = { _id: req.params.monitorId, isActive: true };
req.db.getMonitorById.returns(monitor);
req.jobQueue.deleteJob.throws(new Error("Delete Job error"));
await pauseMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Delete Job error");
});
it("should reject with an error if addJob operation fails", async function () {
const monitor = { _id: req.params.monitorId, isActive: false };
req.db.getMonitorById.returns(monitor);
req.jobQueue.addJob.throws(new Error("Add Job error"));
await pauseMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Add Job error");
});
it("should reject with an error if monitor.save operation fails", async function () {
const monitor = {
_id: req.params.monitorId,
active: false,
save: sinon.stub().throws(new Error("Save error")),
};
req.db.getMonitorById.returns(monitor);
await pauseMonitor(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Save error");
});
it("should return success pause message with data if all operations succeed with inactive monitor", async function () {
const monitor = {
_id: req.params.monitorId,
isActive: false,
save: sinon.stub().resolves(),
};
req.db.getMonitorById.returns(monitor);
await pauseMonitor(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_PAUSE,
data: monitor,
})
).to.be.true;
});
it("should return success resume message with data if all operations succeed with active monitor", async function () {
const monitor = {
_id: req.params.monitorId,
isActive: true,
save: sinon.stub().resolves(),
};
req.db.getMonitorById.returns(monitor);
await pauseMonitor(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_RESUME,
data: monitor,
})
).to.be.true;
});
});
describe("Monitor Controller - addDemoMonitors", function () {
let req, res, next, stub;
beforeEach(function () {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { _id: "123", teamId: "123" };
});
req = {
headers: {
authorization: "Bearer token",
},
params: {},
query: {},
body: {},
db: {
addDemoMonitors: sinon.stub(),
},
settingsService: {
getSettings: sinon.stub(),
},
jobQueue: {
addJob: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(function () {
sinon.restore();
stub.restore();
});
it("should reject with an error if getTokenFromHeaders fails", async function () {
req.headers = {};
await addDemoMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("No auth headers");
expect(next.firstCall.args[0].status).to.equal(500);
});
it("should reject with an error if getting settings fails", async function () {
req.settingsService.getSettings.throws(new Error("Settings error"));
await addDemoMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Settings error");
});
it("should reject with an error if JWT validation fails", async function () {
stub.restore();
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
await addDemoMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
});
it("should reject with an error if addDemoMonitors operation fails", async function () {
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.addDemoMonitors.throws(new Error("DB error"));
await addDemoMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should reject with an error if addJob operation fails", async function () {
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.addDemoMonitors.returns([{ _id: "123" }]);
req.jobQueue.addJob.throws(new Error("Add Job error"));
await addDemoMonitors(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("Add Job error");
});
it("should return success message with data if all operations succeed", async function () {
const monitors = [{ _id: "123" }];
req.settingsService.getSettings.returns({ jwtSecret: "my_secret" });
req.db.addDemoMonitors.returns(monitors);
await addDemoMonitors(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MONITOR_DEMO_ADDED,
data: monitors.length,
})
).to.be.true;
});
});