Merge branch 'develop' into enhancement/check-if-url-resolves

This commit is contained in:
om-3004 committed 2024-10-18 11:39:07 +05:30
commit 34a13530b3
202 files changed
+33101 -32065

No files matched your search

+323 -325
View File
@@ -1,375 +1,373 @@
import {
createCheck,
getChecks,
getTeamChecks,
deleteChecks,
deleteChecksByTeamId,
updateChecksTTL,
createCheck,
getChecks,
getTeamChecks,
deleteChecks,
deleteChecksByTeamId,
updateChecksTTL,
} from "../../controllers/checkController.js";
import jwt from "jsonwebtoken";
import { errorMessages, successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Check Controller - createCheck", () => {
let req, res, next, handleError;
beforeEach(() => {
req = {
params: {},
body: {},
db: {
createCheck: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
handleError = sinon.stub();
});
let req, res, next, handleError;
beforeEach(() => {
req = {
params: {},
body: {},
db: {
createCheck: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
handleError = sinon.stub();
});
afterEach(() => {
sinon.restore(); // Restore the original methods after each test
});
afterEach(() => {
sinon.restore(); // Restore the original methods after each test
});
it("should reject with a validation if params are invalid", async () => {
await createCheck(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 a validation if params are invalid", async () => {
await createCheck(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 a validation error if body is invalid", async () => {
req.params = {
monitorId: "monitorId",
};
await createCheck(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 a validation error if body is invalid", async () => {
req.params = {
monitorId: "monitorId",
};
await createCheck(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should call next with error if data retrieval fails", async () => {
req.params = {
monitorId: "monitorId",
};
req.body = {
monitorId: "monitorId",
status: true,
responseTime: 100,
statusCode: 200,
message: "message",
};
req.db.createCheck.rejects(new Error("error"));
await createCheck(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should call next with error if data retrieval fails", async () => {
req.params = {
monitorId: "monitorId",
};
req.body = {
monitorId: "monitorId",
status: true,
responseTime: 100,
statusCode: 200,
message: "message",
};
req.db.createCheck.rejects(new Error("error"));
await createCheck(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should return a success message if check is created", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.createCheck.resolves({ id: "123" });
req.body = {
monitorId: "monitorId",
status: true,
responseTime: 100,
statusCode: 200,
message: "message",
};
await createCheck(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: successMessages.CHECK_CREATE,
data: { id: "123" },
})
).to.be.true;
expect(next.notCalled).to.be.true;
});
it("should return a success message if check is created", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.createCheck.resolves({ id: "123" });
req.body = {
monitorId: "monitorId",
status: true,
responseTime: 100,
statusCode: 200,
message: "message",
};
await createCheck(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: successMessages.CHECK_CREATE,
data: { id: "123" },
})
).to.be.true;
expect(next.notCalled).to.be.true;
});
});
describe("Check Controller - getChecks", () => {
let req, res, next;
beforeEach(() => {
req = {
params: {},
query: {},
db: {
getChecks: sinon.stub(),
getChecksCount: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
params: {},
query: {},
db: {
getChecks: sinon.stub(),
getChecksCount: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with a validation error if params are invalid", async () => {
await getChecks(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 a validation error if params are invalid", async () => {
await getChecks(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should return a success message if checks are found", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.getChecks.resolves([{ id: "123" }]);
req.db.getChecksCount.resolves(1);
await getChecks(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: successMessages.CHECK_GET,
data: { checksCount: 1, checks: [{ id: "123" }] },
})
).to.be.true;
expect(next.notCalled).to.be.true;
});
it("should return a success message if checks are found", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.getChecks.resolves([{ id: "123" }]);
req.db.getChecksCount.resolves(1);
await getChecks(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: successMessages.CHECK_GET,
data: { checksCount: 1, checks: [{ id: "123" }] },
})
).to.be.true;
expect(next.notCalled).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.getChecks.rejects(new Error("error"));
await getChecks(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should call next with error if data retrieval fails", async () => {
req.params = {
monitorId: "monitorId",
};
req.db.getChecks.rejects(new Error("error"));
await getChecks(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
});
describe("Check Controller - getTeamChecks", () => {
let req, res, next;
beforeEach(() => {
req = {
params: {},
query: {},
db: {
getTeamChecks: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
params: {},
query: {},
db: {
getTeamChecks: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with a validation error if params are invalid", async () => {
await getTeamChecks(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 a validation error if params are invalid", async () => {
await getTeamChecks(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should return 200 and check data on successful validation and data retrieval", async () => {
req.params = { teamId: "1" };
const checkData = [{ id: 1, name: "Check 1" }];
req.db.getTeamChecks.resolves(checkData);
it("should return 200 and check data on successful validation and data retrieval", async () => {
req.params = { teamId: "1" };
const checkData = [{ id: 1, name: "Check 1" }];
req.db.getTeamChecks.resolves(checkData);
await getTeamChecks(req, res, next);
expect(req.db.getTeamChecks.calledOnceWith(req)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_GET,
data: checkData,
})
).to.be.true;
});
await getTeamChecks(req, res, next);
expect(req.db.getTeamChecks.calledOnceWith(req)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_GET,
data: checkData,
})
).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
req.params = { teamId: "1" };
req.db.getTeamChecks.rejects(new Error("Retrieval Error"));
await getTeamChecks(req, res, next);
expect(req.db.getTeamChecks.calledOnceWith(req)).to.be.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
req.params = { teamId: "1" };
req.db.getTeamChecks.rejects(new Error("Retrieval Error"));
await getTeamChecks(req, res, next);
expect(req.db.getTeamChecks.calledOnceWith(req)).to.be.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
});
describe("Check Controller - deleteChecks", () => {
let req, res, next;
beforeEach(() => {
req = {
params: {},
db: {
deleteChecks: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
params: {},
db: {
deleteChecks: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
await deleteChecks(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 param validation fails", async () => {
await deleteChecks(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should call next with error if data retrieval fails", async () => {
req.params = { monitorId: "1" };
req.db.deleteChecks.rejects(new Error("Deletion Error"));
await deleteChecks(req, res, next);
expect(req.db.deleteChecks.calledOnceWith(req.params.monitorId)).to.be.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
req.params = { monitorId: "1" };
req.db.deleteChecks.rejects(new Error("Deletion Error"));
await deleteChecks(req, res, next);
expect(req.db.deleteChecks.calledOnceWith(req.params.monitorId)).to.be.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
it("should delete checks successfully", async () => {
req.params = { monitorId: "123" };
req.db.deleteChecks.resolves(1);
await deleteChecks(req, res, next);
expect(req.db.deleteChecks.calledOnceWith(req.params.monitorId)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_DELETE,
data: { deletedCount: 1 },
})
).to.be.true;
});
it("should delete checks successfully", async () => {
req.params = { monitorId: "123" };
req.db.deleteChecks.resolves(1);
await deleteChecks(req, res, next);
expect(req.db.deleteChecks.calledOnceWith(req.params.monitorId)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_DELETE,
data: { deletedCount: 1 },
})
).to.be.true;
});
});
describe("Check Controller - deleteChecksByTeamId", () => {
let req, res, next;
beforeEach(() => {
req = {
params: {},
db: {
deleteChecksByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
params: {},
db: {
deleteChecksByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
await deleteChecksByTeamId(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 param validation fails", async () => {
await deleteChecksByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should call next with error if data retrieval fails", async () => {
req.params = { teamId: "1" };
req.db.deleteChecksByTeamId.rejects(new Error("Deletion Error"));
await deleteChecksByTeamId(req, res, next);
expect(req.db.deleteChecksByTeamId.calledOnceWith(req.params.teamId)).to.be
.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
req.params = { teamId: "1" };
req.db.deleteChecksByTeamId.rejects(new Error("Deletion Error"));
await deleteChecksByTeamId(req, res, next);
expect(req.db.deleteChecksByTeamId.calledOnceWith(req.params.teamId)).to.be.true;
expect(next.firstCall.args[0]).to.be.an("error");
expect(res.status.notCalled).to.be.true;
expect(res.json.notCalled).to.be.true;
});
it("should delete checks successfully", async () => {
req.params = { teamId: "123" };
req.db.deleteChecksByTeamId.resolves(1);
await deleteChecksByTeamId(req, res, next);
expect(req.db.deleteChecksByTeamId.calledOnceWith(req.params.teamId)).to.be
.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_DELETE,
data: { deletedCount: 1 },
})
).to.be.true;
});
it("should delete checks successfully", async () => {
req.params = { teamId: "123" };
req.db.deleteChecksByTeamId.resolves(1);
await deleteChecksByTeamId(req, res, next);
expect(req.db.deleteChecksByTeamId.calledOnceWith(req.params.teamId)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_DELETE,
data: { deletedCount: 1 },
})
).to.be.true;
});
});
describe("Check Controller - updateCheckTTL", () => {
let stub, req, res, next;
beforeEach(() => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
let stub, req, res, next;
beforeEach(() => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req = {
body: {},
headers: { authorization: "Bearer token" },
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "my_secret" }),
},
db: {
updateChecksTTL: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
req = {
body: {},
headers: { authorization: "Bearer token" },
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "my_secret" }),
},
db: {
updateChecksTTL: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
stub.restore();
});
afterEach(() => {
sinon.restore();
stub.restore();
});
it("should reject if body validation fails", async () => {
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if body validation fails", async () => {
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should throw a JwtError if verification fails", async () => {
stub.restore();
req.body = {
ttl: 1,
};
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
});
it("should throw a JwtError if verification fails", async () => {
stub.restore();
req.body = {
ttl: 1,
};
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
});
it("should call next with error if data retrieval fails", async () => {
req.body = {
ttl: 1,
};
req.db.updateChecksTTL.rejects(new Error("Update Error"));
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should call next with error if data retrieval fails", async () => {
req.body = {
ttl: 1,
};
req.db.updateChecksTTL.rejects(new Error("Update Error"));
await updateChecksTTL(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should update TTL successfully", async () => {
req.body = {
ttl: 1,
};
req.db.updateChecksTTL.resolves();
await updateChecksTTL(req, res, next);
expect(req.db.updateChecksTTL.calledOnceWith("123", 1 * 86400)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_UPDATE_TTL,
})
).to.be.true;
});
it("should update TTL successfully", async () => {
req.body = {
ttl: 1,
};
req.db.updateChecksTTL.resolves();
await updateChecksTTL(req, res, next);
expect(req.db.updateChecksTTL.calledOnceWith("123", 1 * 86400)).to.be.true;
expect(res.status.calledOnceWith(200)).to.be.true;
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.CHECK_UPDATE_TTL,
})
).to.be.true;
});
});
@@ -6,6 +6,9 @@ import {
fetchMonitorCertificate,
} from "../../controllers/controllerUtils.js";
import { expect } from "chai";
import sslChecker from "ssl-checker";
import { afterEach } from "node:test";
import exp from "constants";
describe("controllerUtils - handleValidationError", () => {
it("should set status to 422", () => {
@@ -109,102 +112,40 @@ describe("controllerUtils - handleError", () => {
});
describe("controllerUtils - fetchMonitorCertificate", () => {
const originalTls = {
connect: sinon.stub().callsFake((options, callback) => {
// Create socket stub with sinon stubs for all methods
socket = {
getPeerX509Certificate: sinon.stub().returns({
subject: "CN=fake-cert",
validTo: "Dec 31 23:59:59 2023 GMT",
}),
end: sinon.stub(),
on: sinon.stub(),
};
// Use process.nextTick to ensure async behavior
process.nextTick(() => {
callback.call(socket); // Ensure correct 'this' binding
});
return socket;
}),
};
let tls, monitor, socket;
let sslChecker, monitor;
beforeEach(() => {
monitor = { url: "https://www.google.com" };
tls = {
connect: sinon.stub().callsFake((options, callback) => {
// Create socket stub with sinon stubs for all methods
socket = {
getPeerX509Certificate: sinon.stub().returns({
subject: "CN=fake-cert",
validTo: "Dec 31 23:59:59 2023 GMT",
}),
end: sinon.stub(),
on: sinon.stub(),
};
// Use process.nextTick to ensure async behavior
process.nextTick(() => {
callback.call(socket); // Ensure correct 'this' binding
});
return socket;
}),
monitor = {
url: "https://www.google.com",
};
sslChecker = sinon.stub();
});
afterEach(() => {
tls = { ...originalTls };
sinon.restore();
});
it("should resolve with the certificate when the connection is successful", async () => {
const certificate = await fetchMonitorCertificate(tls, monitor);
expect(certificate.validTo).to.equal("Dec 31 23:59:59 2023 GMT");
expect(socket.end.calledOnce).to.be.true;
});
it("should reject with an error when the connection fails", async () => {
tls.connect = sinon.stub().throws(new Error("Connection error"));
it("should reject with an error if a URL does not parse", async () => {
monitor.url = "invalidurl";
try {
await fetchMonitorCertificate(tls, monitor);
} catch (error) {
expect(error.message).to.equal("Connection error");
}
});
it("should reject with an error if monitorURL is invalid", async () => {
monitor.url = "invalid-url";
try {
await fetchMonitorCertificate(tls, monitor);
await fetchMonitorCertificate(sslChecker, monitor);
} catch (error) {
expect(error).to.be.an("error");
expect(error.message).to.equal("Invalid URL");
}
});
it("should do a thing", async () => {
tls = {
connect: sinon.stub().callsFake((options, callback) => {
// Create socket stub with sinon stubs for all methods
socket = {
getPeerX509Certificate: sinon.stub().throws(new Error("Certificate error")),
end: sinon.stub(),
on: sinon.stub(),
};
// Use process.nextTick to ensure async behavior
process.nextTick(() => {
callback.call(socket); // Ensure correct 'this' binding
});
return socket;
}),
};
it("should reject with an error if sslChecker throws an error", async () => {
sslChecker.rejects(new Error("Test error"));
try {
await fetchMonitorCertificate(tls, monitor);
await fetchMonitorCertificate(sslChecker, monitor);
} catch (error) {
expect(error.message).to.equal("Certificate error");
expect(error).to.be.an("error");
expect(error.message).to.equal("Test error");
}
});
it("should return a certificate if sslChecker resolves", async () => {
sslChecker.resolves({ validTo: "2022-01-01" });
const result = await fetchMonitorCertificate(sslChecker, monitor);
expect(result).to.deep.equal({ validTo: "2022-01-01" });
});
});
+178 -178
View File
@@ -1,203 +1,203 @@
import {
issueInvitation,
inviteVerifyController,
issueInvitation,
inviteVerifyController,
} from "../../controllers/inviteController.js";
import jwt from "jsonwebtoken";
import sinon from "sinon";
import joi from "joi";
describe("inviteController - issueInvitation", () => {
let req, res, next, stub;
beforeEach(() => {
req = {
headers: { authorization: "Bearer token" },
body: {
email: "test@test.com",
role: ["admin"],
teamId: "123",
},
db: { requestInviteToken: sinon.stub() },
settingsService: { getSettings: sinon.stub() },
emailService: { buildAndSendEmail: sinon.stub() },
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next, stub;
beforeEach(() => {
req = {
headers: { authorization: "Bearer token" },
body: {
email: "test@test.com",
role: ["admin"],
teamId: "123",
},
db: { requestInviteToken: sinon.stub() },
settingsService: { getSettings: sinon.stub() },
emailService: { buildAndSendEmail: sinon.stub() },
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if role validation fails", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["bad_role"], firstname: "first_name", teamId: "1" };
});
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0]).to.be.instanceOf(joi.ValidationError);
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if role validation fails", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["bad_role"], firstname: "first_name", teamId: "1" };
});
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0]).to.be.instanceOf(joi.ValidationError);
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if body validation fails", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
req.body = {};
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if body validation fails", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
req.body = {};
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if DB operations fail", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
req.db.requestInviteToken.throws(new Error("DB error"));
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should reject with an error if DB operations fail", async () => {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
req.db.requestInviteToken.throws(new Error("DB error"));
await issueInvitation(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should send an invite successfully", async () => {
const token = "token";
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
it("should send an invite successfully", async () => {
const token = "token";
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
req.emailService.buildAndSendEmail.resolves();
await issueInvitation(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: "Invite sent",
data: inviteToken,
})
).to.be.true;
stub.restore();
});
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
req.emailService.buildAndSendEmail.resolves();
await issueInvitation(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: "Invite sent",
data: inviteToken,
})
).to.be.true;
stub.restore();
});
it("should send an email successfully", async () => {
const token = "token";
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
it("should send an email successfully", async () => {
const token = "token";
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
req.emailService.buildAndSendEmail.resolves();
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
req.emailService.buildAndSendEmail.resolves();
await issueInvitation(req, res, next);
expect(req.emailService.buildAndSendEmail.calledOnce).to.be.true;
expect(
req.emailService.buildAndSendEmail.calledWith(
"employeeActivationTemplate",
{
name: "John",
link: "http://localhost/register/inviteToken",
},
"test@test.com",
"Welcome to Uptime Monitor"
)
).to.be.true;
stub.restore();
});
await issueInvitation(req, res, next);
expect(req.emailService.buildAndSendEmail.calledOnce).to.be.true;
expect(
req.emailService.buildAndSendEmail.calledWith(
"employeeActivationTemplate",
{
name: "John",
link: "http://localhost/register/inviteToken",
},
"test@test.com",
"Welcome to Uptime Monitor"
)
).to.be.true;
stub.restore();
});
it("should continue executing if sending an email fails", async () => {
const token = "token";
req.emailService.buildAndSendEmail.rejects(new Error("Email error"));
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
it("should continue executing if sending an email fails", async () => {
const token = "token";
req.emailService.buildAndSendEmail.rejects(new Error("Email error"));
const decodedToken = {
role: "admin",
firstname: "John",
teamId: "team123",
};
const inviteToken = { token: "inviteToken" };
const clientHost = "http://localhost";
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
await issueInvitation(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: "Invite sent",
data: inviteToken,
})
).to.be.true;
stub.restore();
});
stub = sinon.stub(jwt, "decode").callsFake(() => {
return decodedToken;
});
req.db.requestInviteToken.resolves(inviteToken);
req.settingsService.getSettings.returns({ clientHost });
await issueInvitation(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
success: true,
msg: "Invite sent",
data: inviteToken,
})
).to.be.true;
stub.restore();
});
});
describe("inviteController - inviteVerifyController", () => {
let req, res, next;
beforeEach(() => {
req = {
body: { token: "token" },
db: {
getInviteToken: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
body: { token: "token" },
db: {
getInviteToken: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
req.body = {};
await inviteVerifyController(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 () => {
req.body = {};
await inviteVerifyController(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 () => {
req.db.getInviteToken.throws(new Error("DB error"));
await inviteVerifyController(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 operations fail", async () => {
req.db.getInviteToken.throws(new Error("DB error"));
await inviteVerifyController(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 200 and invite data when validation and invite retrieval are successful", async () => {
req.db.getInviteToken.resolves({ invite: "data" });
await inviteVerifyController(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
status: "success",
msg: "Invite verified",
data: { invite: "data" },
})
).to.be.true;
expect(next.called).to.be.false;
});
it("should return 200 and invite data when validation and invite retrieval are successful", async () => {
req.db.getInviteToken.resolves({ invite: "data" });
await inviteVerifyController(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
expect(
res.json.calledWith({
status: "success",
msg: "Invite verified",
data: { invite: "data" },
})
).to.be.true;
expect(next.called).to.be.false;
});
});
@@ -1,10 +1,10 @@
import {
createMaintenanceWindows,
getMaintenanceWindowById,
getMaintenanceWindowsByTeamId,
getMaintenanceWindowsByMonitorId,
deleteMaintenanceWindow,
editMaintenanceWindow,
createMaintenanceWindows,
getMaintenanceWindowById,
getMaintenanceWindowsByTeamId,
getMaintenanceWindowsByMonitorId,
deleteMaintenanceWindow,
editMaintenanceWindow,
} from "../../controllers/maintenanceWindowController.js";
import jwt from "jsonwebtoken";
@@ -12,405 +12,399 @@ import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("maintenanceWindowController - createMaintenanceWindows", () => {
let req, res, next, stub;
beforeEach(() => {
req = {
body: {
monitors: ["66ff52e7c5911c61698ac724"],
name: "window",
active: true,
start: "2024-10-11T05:27:13.747Z",
end: "2024-10-11T05:27:14.747Z",
repeat: "123",
},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
createMaintenanceWindow: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next, stub;
beforeEach(() => {
req = {
body: {
monitors: ["66ff52e7c5911c61698ac724"],
name: "window",
active: true,
start: "2024-10-11T05:27:13.747Z",
end: "2024-10-11T05:27:14.747Z",
repeat: "123",
},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
createMaintenanceWindow: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.body = {};
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if body validation fails", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.body = {};
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
stub.restore();
});
it("should reject with an error if jwt.verify fails", async () => {
stub = sinon.stub(jwt, "verify").throws(new jwt.JsonWebTokenError());
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
stub.restore();
});
it("should reject with an error if jwt.verify fails", async () => {
stub = sinon.stub(jwt, "verify").throws(new jwt.JsonWebTokenError());
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
stub.restore();
});
it("should reject with an error DB operations fail", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.createMaintenanceWindow.throws(new Error("DB error"));
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should return success message if all operations are successful", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
await createMaintenanceWindows(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(201);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_CREATE,
})
).to.be.true;
stub.restore();
});
it("should return success message if all operations are successful with active set to undefined", async () => {
req.body.active = undefined;
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
await createMaintenanceWindows(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(201);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_CREATE,
})
).to.be.true;
stub.restore();
});
it("should reject with an error DB operations fail", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.createMaintenanceWindow.throws(new Error("DB error"));
await createMaintenanceWindows(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should return success message if all operations are successful", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
await createMaintenanceWindows(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(201);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_CREATE,
})
).to.be.true;
stub.restore();
});
it("should return success message if all operations are successful with active set to undefined", async () => {
req.body.active = undefined;
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
await createMaintenanceWindows(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(201);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_CREATE,
})
).to.be.true;
stub.restore();
});
});
describe("maintenanceWindowController - getMaintenanceWindowById", () => {
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
id: "123",
},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
id: "123",
},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
it("should reject if param validation fails", async () => {
req.params = {};
await getMaintenanceWindowById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if param validation fails", async () => {
req.params = {};
await getMaintenanceWindowById(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if DB operations fail", async () => {
req.db.getMaintenanceWindowById.throws(new Error("DB error"));
await getMaintenanceWindowById(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 with data if all operations are successful", async () => {
req.db.getMaintenanceWindowById.returns({ id: "123" });
await getMaintenanceWindowById(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_ID,
data: { id: "123" },
})
).to.be.true;
});
it("should reject if DB operations fail", async () => {
req.db.getMaintenanceWindowById.throws(new Error("DB error"));
await getMaintenanceWindowById(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 with data if all operations are successful", async () => {
req.db.getMaintenanceWindowById.returns({ id: "123" });
await getMaintenanceWindowById(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_ID,
data: { id: "123" },
})
).to.be.true;
});
});
describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
let req, res, next, stub;
beforeEach(() => {
req = {
body: {},
params: {},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowsByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
it("should reject if query validation fails", async () => {
req.query = {
invalid: 1,
};
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if jwt.verify fails", async () => {
stub = sinon.stub(jwt, "verify").throws(new jwt.JsonWebTokenError());
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
stub.restore();
});
let req, res, next, stub;
beforeEach(() => {
req = {
body: {},
params: {},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowsByTeamId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
it("should reject if query validation fails", async () => {
req.query = {
invalid: 1,
};
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if jwt.verify fails", async () => {
stub = sinon.stub(jwt, "verify").throws(new jwt.JsonWebTokenError());
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
stub.restore();
});
it("should reject with an error if DB operations fail", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.getMaintenanceWindowsByTeamId.throws(new Error("DB error"));
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should reject with an error if DB operations fail", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.getMaintenanceWindowsByTeamId.throws(new Error("DB error"));
await getMaintenanceWindowsByTeamId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should return success message with data if all operations are successful", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.getMaintenanceWindowsByTeamId.returns([{ id: "123" }]);
await getMaintenanceWindowsByTeamId(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_TEAM,
data: [{ id: jwt.verify().teamId }],
})
).to.be.true;
stub.restore();
});
it("should return success message with data if all operations are successful", async () => {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
req.db.getMaintenanceWindowsByTeamId.returns([{ id: "123" }]);
await getMaintenanceWindowsByTeamId(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_TEAM,
data: [{ id: jwt.verify().teamId }],
})
).to.be.true;
stub.restore();
});
});
describe("maintenanceWindowController - getMaintenanceWindowsByMonitorId", () => {
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
monitorId: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowsByMonitorId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
monitorId: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
getMaintenanceWindowsByMonitorId: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject if param validation fails", async () => {
req.params = {};
await getMaintenanceWindowsByMonitorId(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if param validation fails", async () => {
req.params = {};
await getMaintenanceWindowsByMonitorId(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 () => {
req.db.getMaintenanceWindowsByMonitorId.throws(new Error("DB error"));
await getMaintenanceWindowsByMonitorId(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 operations fail", async () => {
req.db.getMaintenanceWindowsByMonitorId.throws(new Error("DB error"));
await getMaintenanceWindowsByMonitorId(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 with data if all operations are successful", async () => {
const data = [{ monitorId: "123" }];
req.db.getMaintenanceWindowsByMonitorId.returns(data);
await getMaintenanceWindowsByMonitorId(req, res, next);
expect(
req.db.getMaintenanceWindowsByMonitorId.calledOnceWith(
req.params.monitorId
)
);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_MONITOR,
data: data,
})
).to.be.true;
});
it("should return success message with data if all operations are successful", async () => {
const data = [{ monitorId: "123" }];
req.db.getMaintenanceWindowsByMonitorId.returns(data);
await getMaintenanceWindowsByMonitorId(req, res, next);
expect(req.db.getMaintenanceWindowsByMonitorId.calledOnceWith(req.params.monitorId));
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_GET_BY_MONITOR,
data: data,
})
).to.be.true;
});
});
describe("maintenanceWindowController - deleteMaintenanceWindow", () => {
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
id: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
deleteMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
let req, res, next;
beforeEach(() => {
req = {
body: {},
params: {
id: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
deleteMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject if param validation fails", async () => {
req.params = {};
await deleteMaintenanceWindow(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if param validation fails", async () => {
req.params = {};
await deleteMaintenanceWindow(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 () => {
req.db.deleteMaintenanceWindowById.throws(new Error("DB error"));
await deleteMaintenanceWindow(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 operations fail", async () => {
req.db.deleteMaintenanceWindowById.throws(new Error("DB error"));
await deleteMaintenanceWindow(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 if all operations are successful", async () => {
await deleteMaintenanceWindow(req, res, next);
expect(req.db.deleteMaintenanceWindowById.calledOnceWith(req.params.id));
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_DELETE,
})
).to.be.true;
});
it("should return success message if all operations are successful", async () => {
await deleteMaintenanceWindow(req, res, next);
expect(req.db.deleteMaintenanceWindowById.calledOnceWith(req.params.id));
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_DELETE,
})
).to.be.true;
});
});
describe("maintenanceWindowController - editMaintenanceWindow", () => {
let req, res, next;
beforeEach(() => {
req = {
body: {
active: true,
name: "test",
},
params: {
id: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
editMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
let req, res, next;
beforeEach(() => {
req = {
body: {
active: true,
name: "test",
},
params: {
id: "123",
},
query: {},
headers: {
authorization: "Bearer token",
},
settingsService: {
getSettings: sinon.stub().returns({ jwtSecret: "jwtSecret" }),
},
db: {
editMaintenanceWindowById: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
afterEach(() => {
sinon.restore();
});
it("should reject if param validation fails", async () => {
req.params = {};
await editMaintenanceWindow(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if param validation fails", async () => {
req.params = {};
await editMaintenanceWindow(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if body validation fails", async () => {
req.body = { invalid: 1 };
await editMaintenanceWindow(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should reject if body validation fails", async () => {
req.body = { invalid: 1 };
await editMaintenanceWindow(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 () => {
req.db.editMaintenanceWindowById.throws(new Error("DB error"));
await editMaintenanceWindow(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 operations fail", async () => {
req.db.editMaintenanceWindowById.throws(new Error("DB error"));
await editMaintenanceWindow(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 with data if all operations are successful", async () => {
const data = { id: "123" };
req.db.editMaintenanceWindowById.returns(data);
it("should return success message with data if all operations are successful", async () => {
const data = { id: "123" };
req.db.editMaintenanceWindowById.returns(data);
await editMaintenanceWindow(req, res, next);
expect(
req.db.editMaintenanceWindowById.calledOnceWith(req.params.id, req.body)
);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_EDIT,
data: data,
})
).to.be.true;
});
await editMaintenanceWindow(req, res, next);
expect(req.db.editMaintenanceWindowById.calledOnceWith(req.params.id, req.body));
expect(res.status.firstCall.args[0]).to.equal(200);
expect(
res.json.calledOnceWith({
success: true,
msg: successMessages.MAINTENANCE_WINDOW_EDIT,
data: data,
})
).to.be.true;
});
});
+148 -148
View File
@@ -1,166 +1,166 @@
import { afterEach } from "node:test";
import {
getMetrics,
getJobs,
addJob,
obliterateQueue,
getMetrics,
getJobs,
addJob,
obliterateQueue,
} from "../../controllers/queueController.js";
import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Queue Controller - getMetrics", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
getMetrics: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getMetrics throws an error", async () => {
req.jobQueue.getMetrics.throws(new Error("getMetrics error"));
await getMetrics(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getMetrics error");
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
getMetrics: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getMetrics throws an error", async () => {
req.jobQueue.getMetrics.throws(new Error("getMetrics error"));
await getMetrics(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getMetrics error");
});
it("should return a success message and data if getMetrics is successful", async () => {
const data = { data: "metrics" };
req.jobQueue.getMetrics.returns(data);
await getMetrics(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_GET_METRICS,
data,
});
});
it("should return a success message and data if getMetrics is successful", async () => {
const data = { data: "metrics" };
req.jobQueue.getMetrics.returns(data);
await getMetrics(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_GET_METRICS,
data,
});
});
});
describe("Queue Controller - getJobs", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
getJobStats: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if getJobs throws an error", async () => {
req.jobQueue.getJobStats.throws(new Error("getJobs error"));
await getJobs(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getJobs error");
});
it("should return a success message and data if getJobs is successful", async () => {
const data = { data: "jobs" };
req.jobQueue.getJobStats.returns(data);
await getJobs(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_GET_METRICS,
data,
});
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
getJobStats: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if getJobs throws an error", async () => {
req.jobQueue.getJobStats.throws(new Error("getJobs error"));
await getJobs(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getJobs error");
});
it("should return a success message and data if getJobs is successful", async () => {
const data = { data: "jobs" };
req.jobQueue.getJobStats.returns(data);
await getJobs(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_GET_METRICS,
data,
});
});
});
describe("Queue Controller - addJob", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
addJob: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if addJob throws an error", async () => {
req.jobQueue.addJob.throws(new Error("addJob error"));
await addJob(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("addJob error");
});
it("should return a success message if addJob is successful", async () => {
req.jobQueue.addJob.resolves();
await addJob(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_ADD_JOB,
});
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
addJob: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if addJob throws an error", async () => {
req.jobQueue.addJob.throws(new Error("addJob error"));
await addJob(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("addJob error");
});
it("should return a success message if addJob is successful", async () => {
req.jobQueue.addJob.resolves();
await addJob(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_ADD_JOB,
});
});
});
describe("Queue Controller - obliterateQueue", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
obliterate: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if obliterateQueue throws an error", async () => {
req.jobQueue.obliterate.throws(new Error("obliterateQueue error"));
await obliterateQueue(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("obliterateQueue error");
});
it("should return a success message if obliterateQueue is successful", async () => {
req.jobQueue.obliterate.resolves();
await obliterateQueue(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_OBLITERATE,
});
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
jobQueue: {
obliterate: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if obliterateQueue throws an error", async () => {
req.jobQueue.obliterate.throws(new Error("obliterateQueue error"));
await obliterateQueue(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("obliterateQueue error");
});
it("should return a success message if obliterateQueue is successful", async () => {
req.jobQueue.obliterate.resolves();
await obliterateQueue(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.QUEUE_OBLITERATE,
});
});
});
@@ -1,105 +1,103 @@
import { afterEach } from "node:test";
import {
getAppSettings,
updateAppSettings,
getAppSettings,
updateAppSettings,
} from "../../controllers/settingsController.js";
import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Settings Controller - getAppSettings", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
settingsService: {
getSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getSettings throws an error", async () => {
req.settingsService.getSettings.throws(new Error("getSettings error"));
await getAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getSettings error");
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {},
settingsService: {
getSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getSettings throws an error", async () => {
req.settingsService.getSettings.throws(new Error("getSettings error"));
await getAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getSettings error");
});
it("should return a success message and data if getSettings is successful", async () => {
const data = { data: "settings" };
req.settingsService.getSettings.returns(data);
await getAppSettings(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.GET_APP_SETTINGS,
data,
});
});
it("should return a success message and data if getSettings is successful", async () => {
const data = { data: "settings" };
req.settingsService.getSettings.returns(data);
await getAppSettings(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.GET_APP_SETTINGS,
data,
});
});
});
describe("Settings Controller - updateAppSettings", () => {
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {
updateAppSettings: sinon.stub(),
},
settingsService: {
reloadSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
req.body = { invalid: 1 };
await updateAppSettings(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 updateAppSettings throws an error", async () => {
req.db.updateAppSettings.throws(new Error("updateAppSettings error"));
await updateAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("updateAppSettings error");
});
it("should reject with an error if reloadSettings throws an error", async () => {
req.settingsService.reloadSettings.throws(
new Error("reloadSettings error")
);
await updateAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("reloadSettings error");
});
it("should return a success message and data if updateAppSettings is successful", async () => {
const data = { data: "settings" };
req.settingsService.reloadSettings.returns(data);
await updateAppSettings(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.UPDATE_APP_SETTINGS,
data,
});
});
let req, res, next;
beforeEach(() => {
req = {
headers: {},
params: {},
body: {},
db: {
updateAppSettings: sinon.stub(),
},
settingsService: {
reloadSettings: sinon.stub(),
},
};
res = {
status: sinon.stub().returnsThis(),
json: sinon.stub(),
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
req.body = { invalid: 1 };
await updateAppSettings(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 updateAppSettings throws an error", async () => {
req.db.updateAppSettings.throws(new Error("updateAppSettings error"));
await updateAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("updateAppSettings error");
});
it("should reject with an error if reloadSettings throws an error", async () => {
req.settingsService.reloadSettings.throws(new Error("reloadSettings error"));
await updateAppSettings(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("reloadSettings error");
});
it("should return a success message and data if updateAppSettings is successful", async () => {
const data = { data: "settings" };
req.settingsService.reloadSettings.returns(data);
await updateAppSettings(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0]).to.deep.equal({
success: true,
msg: successMessages.UPDATE_APP_SETTINGS,
data,
});
});
});
+218
View File
@@ -0,0 +1,218 @@
import sinon from "sinon";
import EmailService from "../../service/emailService.js";
describe("EmailService - Constructor", () => {
let settingsServiceMock;
let fsMock;
let pathMock;
let compileMock;
let mjml2htmlMock;
let nodemailerMock;
let loggerMock;
beforeEach(() => {
settingsServiceMock = {
getSettings: sinon.stub().returns({
systemEmailHost: "smtp.example.com",
systemEmailPort: 465,
systemEmailAddress: "test@example.com",
systemEmailPassword: "password",
}),
};
fsMock = {
readFileSync: sinon.stub().returns("<mjml><body></body></mjml>"),
};
pathMock = {
join: sinon.stub().callsFake((...args) => args.join("/")),
};
compileMock = sinon.stub().returns(() => "<mjml><body></body></mjml>");
mjml2htmlMock = sinon.stub().returns({ html: "<html></html>" });
nodemailerMock = {
createTransport: sinon.stub().returns({
sendMail: sinon.stub().resolves({ messageId: "12345" }),
}),
};
loggerMock = {
error: sinon.stub(),
};
});
afterEach(() => {
sinon.restore();
});
it("should initialize template loaders and email transporter", () => {
const emailService = new EmailService(
settingsServiceMock,
fsMock,
pathMock,
compileMock,
mjml2htmlMock,
nodemailerMock,
loggerMock
);
// Verify that the settingsService is assigned correctly
expect(emailService.settingsService).to.equal(settingsServiceMock);
// Verify that the template loaders are initialized
expect(emailService.templateLookup.welcomeEmailTemplate).to.be.a("function");
expect(emailService.templateLookup.employeeActivationTemplate).to.be.a("function");
// Verify that the email transporter is initialized
expect(nodemailerMock.createTransport.calledOnce).to.be.true;
const emailConfig = nodemailerMock.createTransport.getCall(0).args[0];
expect(emailConfig).to.deep.equal({
host: "smtp.example.com",
port: 465,
secure: true,
auth: {
user: "test@example.com",
pass: "password",
},
});
});
it("should have undefined templates if FS fails", () => {
fsMock = {
readFileSync: sinon.stub().throws(new Error("File read error")),
};
const emailService = new EmailService(
settingsServiceMock,
fsMock,
pathMock,
compileMock,
mjml2htmlMock,
nodemailerMock,
loggerMock
);
expect(loggerMock.error.called).to.be.true;
const errorCalls = loggerMock.error.getCalls();
const errorCall = errorCalls.find(
(call) => call.args[0] === "Error loading Email templates"
);
expect(errorCall).to.not.be.undefined;
expect(emailService.settingsService).to.equal(settingsServiceMock);
expect(emailService.templateLookup.welcomeEmailTemplate).to.be.undefined;
expect(emailService.templateLookup.employeeActivationTemplate).to.be.undefined;
});
});
describe("EmailService - buildAndSendEmail", () => {
let settingsServiceMock;
let fsMock;
let pathMock;
let compileMock;
let mjml2htmlMock;
let nodemailerMock;
let loggerMock;
let emailService;
beforeEach(() => {
settingsServiceMock = {
getSettings: sinon.stub().returns({
systemEmailHost: "smtp.example.com",
systemEmailPort: 465,
systemEmailAddress: "test@example.com",
systemEmailPassword: "password",
}),
};
fsMock = {
readFileSync: sinon.stub().returns("<mjml><body></body></mjml>"),
};
pathMock = {
join: sinon.stub().callsFake((...args) => args.join("/")),
};
compileMock = sinon.stub().returns(() => "<mjml><body></body></mjml>");
mjml2htmlMock = sinon.stub().returns({ html: "<html></html>" });
nodemailerMock = {
createTransport: sinon.stub().returns({
sendMail: sinon.stub().resolves({ messageId: "12345" }),
}),
};
loggerMock = {
error: sinon.stub(),
};
emailService = new EmailService(
settingsServiceMock,
fsMock,
pathMock,
compileMock,
mjml2htmlMock,
nodemailerMock,
loggerMock
);
});
afterEach(() => {
sinon.restore();
});
it("should build and send email successfully", async () => {
const messageId = await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
{},
"recipient@example.com",
"Welcome"
);
expect(messageId).to.equal("12345");
expect(nodemailerMock.createTransport().sendMail.calledOnce).to.be.true;
});
it("should log error if building HTML fails", async () => {
mjml2htmlMock.throws(new Error("MJML error"));
const messageId = await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
{},
"recipient@example.com",
"Welcome"
);
expect(loggerMock.error.calledOnce).to.be.true;
expect(loggerMock.error.getCall(0).args[0]).to.equal("Error building Email HTML");
});
it("should log error if sending email fails", async () => {
nodemailerMock.createTransport().sendMail.rejects(new Error("SMTP error"));
await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
{},
"recipient@example.com",
"Welcome"
);
expect(loggerMock.error.calledOnce).to.be.true;
expect(loggerMock.error.getCall(0).args[0]).to.equal("Error sending Email");
});
it("should log error if both building HTML and sending email fail", async () => {
mjml2htmlMock.throws(new Error("MJML error"));
nodemailerMock.createTransport().sendMail.rejects(new Error("SMTP error"));
const messageId = await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
{},
"recipient@example.com",
"Welcome"
);
expect(messageId).to.be.undefined;
expect(loggerMock.error.calledTwice).to.be.true;
expect(loggerMock.error.getCall(0).args[0]).to.equal("Error building Email HTML");
expect(loggerMock.error.getCall(1).args[0]).to.equal("Error sending Email");
});
it("should log an error if buildHtml fails", async () => {});
});
+68
View File
@@ -0,0 +1,68 @@
import { NormalizeData, calculatePercentile } from "../../utils/dataUtils.js";
import sinon from "sinon";
describe("NormalizeData", () => {
it("should normalize response times when checks length is greater than 1", () => {
const checks = [
{ responseTime: 20, _doc: { id: 1 } },
{ responseTime: 40, _doc: { id: 2 } },
{ responseTime: 60, _doc: { id: 3 } },
];
const rangeMin = 1;
const rangeMax = 100;
const result = NormalizeData(checks, rangeMin, rangeMax);
expect(result).to.be.an("array");
expect(result).to.have.lengthOf(3);
result.forEach((check) => {
expect(check).to.have.property("responseTime").that.is.a("number");
expect(check).to.have.property("originalResponseTime").that.is.a("number");
});
});
it("should return checks with original response times when checks length is 1", () => {
const checks = [{ responseTime: 20, _doc: { id: 1 } }];
const rangeMin = 1;
const rangeMax = 100;
const result = NormalizeData(checks, rangeMin, rangeMax);
expect(result).to.be.an("array");
expect(result).to.have.lengthOf(1);
expect(result[0]).to.have.property("originalResponseTime", 20);
});
it("should handle edge cases with extreme response times", () => {
const checks = [
{ responseTime: 5, _doc: { id: 1 } },
{ responseTime: 95, _doc: { id: 2 } },
];
const rangeMin = 1;
const rangeMax = 100;
const result = NormalizeData(checks, rangeMin, rangeMax);
expect(result).to.be.an("array");
expect(result).to.have.lengthOf(2);
expect(result[0]).to.have.property("responseTime").that.is.at.least(rangeMin);
expect(result[1]).to.have.property("responseTime").that.is.at.most(rangeMax);
});
});
describe("calculatePercentile", () => {
it("should return the lower value when upper is greater than or equal to the length of the sorted array", () => {
const checks = [
{ responseTime: 10 },
{ responseTime: 20 },
{ responseTime: 30 },
{ responseTime: 40 },
{ responseTime: 50 },
];
const percentile = 100;
const result = calculatePercentile(checks, percentile);
const expected = 50;
console.log(result);
expect(result).to.equal(expected);
});
});
@@ -0,0 +1,57 @@
import { expect } from "chai";
import sinon from "sinon";
import sharp from "sharp";
import { GenerateAvatarImage } from "../../utils/imageProcessing.js";
describe("imageProcessing - GenerateAvatarImage", () => {
it("should resize the image to 64x64 and return a base64 string", async () => {
const file = {
buffer: Buffer.from("test image buffer"),
};
// Stub the sharp function
const toBufferStub = sinon.stub().resolves(Buffer.from("resized image buffer"));
const resizeStub = sinon.stub().returns({ toBuffer: toBufferStub });
const sharpStub = sinon
.stub(sharp.prototype, "resize")
.returns({ toBuffer: toBufferStub });
const result = await GenerateAvatarImage(file);
// Verify the result
const expected = Buffer.from("resized image buffer").toString("base64");
expect(result).to.equal(expected);
// Verify that the sharp function was called with the correct arguments
expect(sharpStub.calledOnceWith({ width: 64, height: 64, fit: "cover" })).to.be.true;
expect(toBufferStub.calledOnce).to.be.true;
// Restore the stubbed functions
sharpStub.restore();
});
it("should throw an error if resizing fails", async () => {
const file = {
buffer: Buffer.from("test image buffer"),
};
// Stub the sharp function to throw an error
const toBufferStub = sinon.stub().rejects(new Error("Resizing failed"));
const resizeStub = sinon.stub().returns({ toBuffer: toBufferStub });
const sharpStub = sinon
.stub(sharp.prototype, "resize")
.returns({ toBuffer: toBufferStub });
try {
await GenerateAvatarImage(file);
// If no error is thrown, fail the test
expect.fail("Expected error to be thrown");
} catch (error) {
// Verify that the error message is correct
expect(error.message).to.equal("Resizing failed");
}
// Restore the stubbed functions
sharpStub.restore();
});
});
+29
View File
@@ -0,0 +1,29 @@
import { errorMessages, successMessages } from "../../utils/messages.js";
describe("Messages", () => {
describe("messages - errorMessages", () => {
it("should have a DB_FIND_MONITOR_BY_ID function", () => {
const monitorId = "12345";
expect(errorMessages.DB_FIND_MONITOR_BY_ID(monitorId)).to.equal(
`Monitor with id ${monitorId} not found`
);
});
it("should have a DB_DELETE_CHECKS function", () => {
const monitorId = "12345";
expect(errorMessages.DB_DELETE_CHECKS(monitorId)).to.equal(
`No checks found for monitor with id ${monitorId}`
);
});
});
describe("messages - successMessages", () => {
it("should have a MONITOR_GET_BY_USER_ID function", () => {
const userId = "12345";
expect(successMessages.MONITOR_GET_BY_USER_ID(userId)).to.equal(
`Got monitor for ${userId} successfully"`
);
});
// Add more tests for other success messages as needed
});
});
+50
View File
@@ -0,0 +1,50 @@
import { ParseBoolean, getTokenFromHeaders } from "../../utils/utils.js";
describe("utils - ParseBoolean", () => {
it("should return true", () => {
const result = ParseBoolean("true");
expect(result).to.be.true;
});
it("should return false", () => {
const result = ParseBoolean("false");
expect(result).to.be.false;
});
it("should return false", () => {
const result = ParseBoolean(null);
expect(result).to.be.false;
});
it("should return false", () => {
const result = ParseBoolean(undefined);
expect(result).to.be.false;
});
});
describe("utils - getTokenFromHeaders", () => {
it("should throw an error if authorization header is missing", () => {
const headers = {};
expect(() => getTokenFromHeaders(headers)).to.throw("No auth headers");
});
it("should throw an error if authorization header does not start with Bearer", () => {
const headers = { authorization: "Basic abcdef" };
expect(() => getTokenFromHeaders(headers)).to.throw("Invalid auth headers");
});
it("should return the token if authorization header is correctly formatted", () => {
const headers = { authorization: "Bearer abcdef" };
expect(getTokenFromHeaders(headers)).to.equal("abcdef");
});
it("should throw an error if authorization header has more than two parts", () => {
const headers = { authorization: "Bearer abc def" };
expect(() => getTokenFromHeaders(headers)).to.throw("Invalid auth headers");
});
it("should throw an error if authorization header has less than two parts", () => {
const headers = { authorization: "Bearer" };
expect(() => getTokenFromHeaders(headers)).to.throw("Invalid auth headers");
});
});