From bdde060f7f8a1c7f62f25c5cabd68a17080ab5f7 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 14 Oct 2024 11:06:45 +0800 Subject: [PATCH] Add tests for deleteAllMonitors --- Server/controllers/controllerUtils.js | 4 +- Server/controllers/monitorController.js | 25 ++-- .../controllers/monitorController.test.js | 108 ++++++++++++++++++ 3 files changed, 127 insertions(+), 10 deletions(-) diff --git a/Server/controllers/controllerUtils.js b/Server/controllers/controllerUtils.js index 1b3994f2f..3238cd2a1 100644 --- a/Server/controllers/controllerUtils.js +++ b/Server/controllers/controllerUtils.js @@ -6,8 +6,8 @@ const handleValidationError = (error, serviceName) => { return error; }; -const handleError = (error, serviceName, method, code = 500) => { - error.code === undefined ? (error.code = code) : null; +const handleError = (error, serviceName, method, status = 500) => { + error.status === undefined ? (error.status = status) : null; error.service === undefined ? (error.service = serviceName) : null; error.method === undefined ? (error.method = method) : null; return error; diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 06800d5fc..99d86a947 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -325,14 +325,23 @@ const deleteAllMonitors = async (req, res, next) => { const { jwtSecret } = req.settingsService.getSettings(); const { teamId } = jwt.verify(token, jwtSecret); const { monitors, deletedCount } = await req.db.deleteAllMonitors(teamId); - await monitors.forEach(async (monitor) => { - await req.jobQueue.deleteJob(monitor); - await req.db.deleteChecks(monitor._id); - await req.db.deleteAlertByMonitorId(monitor._id); - await req.db.deletePageSpeedChecksByMonitorId(monitor._id); - await req.db.deleteNotificationsByMonitorId(monitor._id); - }); - + await Promise.all( + monitors.map(async (monitor) => { + try { + await req.jobQueue.deleteJob(monitor); + await req.db.deleteChecks(monitor._id); + await req.db.deletePageSpeedChecksByMonitorId(monitor._id); + await req.db.deleteNotificationsByMonitorId(monitor._id); + } catch (error) { + logger.error( + `Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`, + { + method: "deleteAllMonitors", + } + ); + } + }) + ); return res .status(200) .json({ success: true, msg: `Deleted ${deletedCount} monitors` }); diff --git a/Server/tests/controllers/monitorController.test.js b/Server/tests/controllers/monitorController.test.js index 2a2e6d040..d2c77bc9d 100644 --- a/Server/tests/controllers/monitorController.test.js +++ b/Server/tests/controllers/monitorController.test.js @@ -553,3 +553,111 @@ describe("Monitor Controller - deleteMonitor", () => { ).to.be.true; }); }); + +describe("Monitor Controller - deleteAllMonitors", () => { + beforeEach(() => { + 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(() => { + sinon.restore(); + stub.restore(); + }); + it("should reject with an error if getTokenFromHeaders throws an error", async () => { + req.headers = {}; + await monitorController.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 () => { + stub.restore(); + req.settingsService.getSettings.returns({ jwtSecret: "my_secret" }); + await monitorController.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 () => { + req.settingsService.getSettings.returns({ jwtSecret: "my_secret" }); + req.db.deleteAllMonitors.throws(new Error("DB error")); + await monitorController.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 deleteJob throws an error", async () => { + 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("Job error"); + req.jobQueue.deleteJob.rejects(error); + await monitorController.deleteAllMonitors(req, res, next); + expect(logger.error.calledOnce).to.be.true; + expect(logger.error.firstCall.args[0]).to.deep.equal( + `Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}` + ); + }); + it("should log an error if deleteChecks throws an error", async () => { + 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 monitorController.deleteAllMonitors(req, res, next); + expect(logger.error.calledOnce).to.be.true; + expect(logger.error.firstCall.args[0]).to.deep.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 () => { + 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 monitorController.deleteAllMonitors(req, res, next); + expect(logger.error.calledOnce).to.be.true; + expect(logger.error.firstCall.args[0]).to.deep.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 () => { + 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 monitorController.deleteAllMonitors(req, res, next); + expect(logger.error.calledOnce).to.be.true; + expect(logger.error.firstCall.args[0]).to.deep.equal( + `Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}` + ); + }); +});