Merge branch 'develop' into feat/be/hardware-details

This commit is contained in:
Alex Holliday
2024-12-31 17:39:19 -08:00
39 changed files with 1377 additions and 913 deletions

View File

@@ -1,4 +1,4 @@
**(when sending your PR, only remove this line. Do not remove any lines below. Check all the items before sending your PR)**
**(when sending your PR, only remove this line. Do not remove any lines below. Check all the relevant items before sending your PR)**
## Describe your changes

View File

@@ -67,5 +67,8 @@ const BaseCheckSchema = mongoose.Schema({
*/
const CheckSchema = mongoose.Schema({ ...BaseCheckSchema.obj }, { timestamps: true });
CheckSchema.index({ createdAt: 1 });
CheckSchema.index({ monitorId: 1, createdAt: 1 });
CheckSchema.index({ monitorId: 1, createdAt: -1 });
export default mongoose.model("Check", CheckSchema);
export { BaseCheckSchema };

View File

@@ -64,5 +64,7 @@ const HardwareCheckSchema = mongoose.Schema(
);
HardwareCheckSchema.index({ createdAt: 1 });
HardwareCheckSchema.index({ monitorId: 1, createdAt: 1 });
HardwareCheckSchema.index({ monitorId: 1, createdAt: -1 });
export default mongoose.model("HardwareCheck", HardwareCheckSchema);

View File

@@ -91,6 +91,13 @@ class MongoDB {
appSettings = new AppSettings({});
await appSettings.save();
}
// Sync indexes
const models = mongoose.modelNames();
for (const modelName of models) {
const model = mongoose.model(modelName);
await model.syncIndexes();
}
logger.info({ message: "Connected to MongoDB" });
} catch (error) {
logger.error({

View File

@@ -224,15 +224,22 @@ const getDateRange = (dateRange) => {
* @returns {Promise<Object>} All checks and date-ranged checks
*/
const getMonitorChecks = async (monitorId, model, dateRange, sortOrder) => {
const indexSpec = {
monitorId: 1,
createdAt: sortOrder, // This will be 1 or -1
};
const [checksAll, checksForDateRange] = await Promise.all([
model.find({ monitorId }).sort({ createdAt: sortOrder }),
model.find({ monitorId }).sort({ createdAt: sortOrder }).hint(indexSpec).lean(),
model
.find({
monitorId,
createdAt: { $gte: dateRange.start, $lte: dateRange.end },
})
.sort({ createdAt: sortOrder }),
.hint(indexSpec)
.lean(),
]);
return { checksAll, checksForDateRange };
};

View File

@@ -14,6 +14,7 @@ export default [
languageOptions: {
globals: {
...globals.node, // Add Node.js globals
...globals.chai, // Add Chai globals
},
ecmaVersion: 2023,
sourceType: "module",

View File

@@ -5333,9 +5333,9 @@
}
},
"node_modules/mongoose": {
"version": "8.9.2",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.2.tgz",
"integrity": "sha512-mLWynmZS1v8HTeMxyLhskQncS1SkrjW1eLNuFDYGQMQ/5QrFrxTLNwWXeCRZeKT2lXyaxW8bnJC9AKPT9jYMkw==",
"version": "8.9.3",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.3.tgz",
"integrity": "sha512-G50GNPdMqhoiRAJ/24GYAzg13yxXDD3FOOFeYiFwtHmHpAJem3hxbYIxAhLJGWbYEiUZL0qFMu2LXYkgGAmo+Q==",
"license": "MIT",
"dependencies": {
"bson": "^6.10.1",

View File

@@ -18,14 +18,14 @@ import { getTokenFromHeaders, tokenType } from "../../utils/utils.js";
import logger from "../../utils/logger.js";
import e from "cors";
describe("Auth Controller - issueToken", () => {
describe("Auth Controller - issueToken", function() {
let stub;
afterEach(() => {
afterEach(function() {
sinon.restore(); // Restore stubs after each test
});
it("should reject with an error if jwt.sign fails", () => {
it("should reject with an error if jwt.sign fails", function() {
const error = new Error("jwt.sign error");
stub = sinon.stub(jwt, "sign").throws(error);
const payload = { id: "123" };
@@ -35,7 +35,7 @@ describe("Auth Controller - issueToken", () => {
);
});
it("should return a token if jwt.sign is successful and appSettings.jwtTTL is not defined", () => {
it("should return a token if jwt.sign is successful and appSettings.jwtTTL is not defined", function() {
const payload = { id: "123" };
const appSettings = { jwtSecret: "my_secret" };
const expectedToken = "mockToken";
@@ -45,7 +45,7 @@ describe("Auth Controller - issueToken", () => {
expect(token).to.equal(expectedToken);
});
it("should return a token if jwt.sign is successful and appSettings.jwtTTL is defined", () => {
it("should return a token if jwt.sign is successful and appSettings.jwtTTL is defined", function() {
const payload = { id: "123" };
const appSettings = { jwtSecret: "my_secret", jwtTTL: "1s" };
const expectedToken = "mockToken";
@@ -55,7 +55,7 @@ describe("Auth Controller - issueToken", () => {
expect(token).to.equal(expectedToken);
});
it("should return a refresh token if jwt.sign is successful and appSettings.refreshTokenTTL is not defined", () => {
it("should return a refresh token if jwt.sign is successful and appSettings.refreshTokenTTL is not defined", function() {
const payload = {};
const appSettings = { refreshTokenSecret: "my_refresh_secret" };
const expectedToken = "mockRefreshToken";
@@ -65,7 +65,7 @@ describe("Auth Controller - issueToken", () => {
expect(token).to.equal(expectedToken);
});
it("should return a refresh token if jwt.sign is successful and appSettings.refreshTokenTTL is defined", () => {
it("should return a refresh token if jwt.sign is successful and appSettings.refreshTokenTTL is defined", function() {
const payload = {};
const appSettings = {
refreshTokenSecret: "my_refresh_secret",
@@ -79,9 +79,10 @@ describe("Auth Controller - issueToken", () => {
});
});
describe("Auth Controller - registerUser", () => {
describe("Auth Controller - registerUser", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: {
firstName: "firstname",
@@ -116,25 +117,26 @@ describe("Auth Controller - registerUser", () => {
next = sinon.stub();
sinon.stub(logger, "error");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
it("should reject with an error if body validation fails", async function() {
req.body = {};
await registerUser(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 checkSuperadmin fails", async () => {
it("should reject with an error if checkSuperadmin fails", async function() {
req.db.checkSuperadmin.throws(new Error("checkSuperadmin error"));
await registerUser(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("checkSuperadmin error");
});
it("should reject with an error if getInviteTokenAndDelete fails", async () => {
it("should reject with an error if getInviteTokenAndDelete fails", async function() {
req.db.checkSuperadmin.returns(true);
req.db.getInviteTokenAndDelete.throws(new Error("getInviteTokenAndDelete error"));
await registerUser(req, res, next);
@@ -142,7 +144,7 @@ describe("Auth Controller - registerUser", () => {
expect(next.firstCall.args[0].message).to.equal("getInviteTokenAndDelete error");
});
it("should reject with an error if updateAppSettings fails", async () => {
it("should reject with an error if updateAppSettings fails", async function() {
req.db.checkSuperadmin.returns(false);
req.db.updateAppSettings.throws(new Error("updateAppSettings error"));
await registerUser(req, res, next);
@@ -150,7 +152,7 @@ describe("Auth Controller - registerUser", () => {
expect(next.firstCall.args[0].message).to.equal("updateAppSettings error");
});
it("should reject with an error if insertUser fails", async () => {
it("should reject with an error if insertUser fails", async function() {
req.db.checkSuperadmin.resolves(false);
req.db.updateAppSettings.resolves();
req.db.insertUser.rejects(new Error("insertUser error"));
@@ -159,7 +161,7 @@ describe("Auth Controller - registerUser", () => {
expect(next.firstCall.args[0].message).to.equal("insertUser error");
});
it("should reject with an error if settingsService.getSettings fails", async () => {
it("should reject with an error if settingsService.getSettings fails", async function() {
req.db.checkSuperadmin.resolves(false);
req.db.updateAppSettings.resolves();
req.db.insertUser.resolves({ _id: "123" });
@@ -171,7 +173,7 @@ describe("Auth Controller - registerUser", () => {
expect(next.firstCall.args[0].message).to.equal("settingsService.getSettings error");
});
it("should log an error if emailService.buildAndSendEmail fails", async () => {
it("should log an error if emailService.buildAndSendEmail fails", async function() {
req.db.checkSuperadmin.resolves(false);
req.db.updateAppSettings.resolves();
req.db.insertUser.returns({ _id: "123" });
@@ -184,7 +186,8 @@ describe("Auth Controller - registerUser", () => {
expect(logger.error.calledOnce).to.be.true;
expect(logger.error.firstCall.args[0].message).to.equal("emailService error");
});
it("should return a success message and data if all operations are successful", async () => {
it("should return a success message and data if all operations are successful", async function() {
const user = { _id: "123" };
req.db.checkSuperadmin.resolves(false);
req.db.updateAppSettings.resolves();
@@ -205,7 +208,8 @@ describe("Auth Controller - registerUser", () => {
).to.be.true;
expect(next.notCalled).to.be.true;
});
it("should return a success message and data if all operations are successful and superAdmin true", async () => {
it("should return a success message and data if all operations are successful and superAdmin true", async function() {
const user = { _id: "123" };
req.db.checkSuperadmin.resolves(true);
req.db.updateAppSettings.resolves();
@@ -228,9 +232,10 @@ describe("Auth Controller - registerUser", () => {
});
});
describe("Auth Controller - loginUser", () => {
describe("Auth Controller - loginUser", function() {
let req, res, next, user;
beforeEach(() => {
beforeEach(function() {
req = {
body: { email: "test@example.com", password: "Password123!" },
db: {
@@ -255,21 +260,22 @@ describe("Auth Controller - loginUser", () => {
comparePassword: sinon.stub(),
};
});
it("should reject with an error if validation fails", async () => {
it("should reject with an error if validation fails", async function() {
req.body = {};
await loginUser(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 getUserByEmail fails", async () => {
it("should reject with an error if getUserByEmail fails", async function() {
req.db.getUserByEmail.rejects(new Error("getUserByEmail error"));
await loginUser(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getUserByEmail error");
});
it("should login user successfully", async () => {
it("should login user successfully", async function() {
req.db.getUserByEmail.resolves(user);
user.comparePassword.resolves(true);
await loginUser(req, res, next);
@@ -290,7 +296,8 @@ describe("Auth Controller - loginUser", () => {
).to.be.true;
expect(next.notCalled).to.be.true;
});
it("should reject a user with an incorrect password", async () => {
it("should reject a user with an incorrect password", async function() {
req.body = {
email: "test@test.com",
password: "Password123!",
@@ -305,10 +312,10 @@ describe("Auth Controller - loginUser", () => {
});
});
describe("Auth Controller - refreshAuthToken", () => {
describe("Auth Controller - refreshAuthToken", function() {
let req, res, next, issueTokenStub;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {
"x-refresh-token": "valid_refresh_token",
@@ -332,11 +339,11 @@ describe("Auth Controller - refreshAuthToken", () => {
sinon.replace({ issueToken }, "issueToken", issueTokenStub);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject if no refresh token is provided", async () => {
it("should reject if no refresh token is provided", async function() {
delete req.headers["x-refresh-token"];
await refreshAuthToken(req, res, next);
@@ -345,7 +352,7 @@ describe("Auth Controller - refreshAuthToken", () => {
expect(next.firstCall.args[0].status).to.equal(401);
});
it("should reject if the refresh token is invalid", async () => {
it("should reject if the refresh token is invalid", async function() {
jwt.verify.yields(new Error("invalid token"));
await refreshAuthToken(req, res, next);
@@ -354,7 +361,7 @@ describe("Auth Controller - refreshAuthToken", () => {
expect(next.firstCall.args[0].status).to.equal(401);
});
it("should reject if the refresh token is expired", async () => {
it("should reject if the refresh token is expired", async function() {
const error = new Error("Token expired");
error.name = "TokenExpiredError";
jwt.verify.yields(error);
@@ -364,7 +371,7 @@ describe("Auth Controller - refreshAuthToken", () => {
expect(next.firstCall.args[0].status).to.equal(401);
});
it("should reject if settingsService.getSettings fails", async () => {
it("should reject if settingsService.getSettings fails", async function() {
req.settingsService.getSettings.rejects(
new Error("settingsService.getSettings error")
);
@@ -374,7 +381,7 @@ describe("Auth Controller - refreshAuthToken", () => {
expect(next.firstCall.args[0].message).to.equal("settingsService.getSettings error");
});
it("should generate a new auth token if the refresh token is valid", async () => {
it("should generate a new auth token if the refresh token is valid", async function() {
const decodedPayload = { expiresIn: "60" };
jwt.verify.callsFake(() => {
return decodedPayload;
@@ -396,9 +403,10 @@ describe("Auth Controller - refreshAuthToken", () => {
});
});
describe("Auth Controller - editUser", async () => {
describe("Auth Controller - editUser", function() {
let req, res, next, stub, user;
beforeEach(() => {
beforeEach(function() {
req = {
params: { userId: "123" },
body: { password: "Password1!", newPassword: "Password2!" },
@@ -419,40 +427,41 @@ describe("Auth Controller - editUser", async () => {
next = sinon.stub();
stub = sinon.stub(jwt, "verify").returns({ email: "test@example.com" });
});
afterEach(() => {
afterEach(function() {
sinon.restore();
stub.restore();
});
it("should reject with an error if param validation fails", async () => {
it("should reject with an error if param validation fails", async function() {
req.params = {};
await editUser(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 () => {
it("should reject with an error if body validation fails", async function() {
req.body = { invalid: 1 };
await editUser(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.userId !== req.user._id", async () => {
it("should reject with an error if param.userId !== req.user._id", async function() {
req.params = { userId: "456" };
await editUser(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].status).to.equal(401);
});
it("should reject with an error if !req.body.password and getUserByEmail fails", async () => {
it("should reject with an error if !req.body.password and getUserByEmail fails", async function() {
req.db.getUserByEmail.rejects(new Error("getUserByEmail error"));
await editUser(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getUserByEmail error");
});
it("should reject with an error if user.comparePassword fails", async () => {
it("should reject with an error if user.comparePassword fails", async function() {
req.db.getUserByEmail.returns({
comparePassword: sinon.stub().rejects(new Error("Bad Password Match")),
});
@@ -461,7 +470,7 @@ describe("Auth Controller - editUser", async () => {
expect(next.firstCall.args[0].message).to.equal("Bad Password Match");
});
it("should reject with an error if user.comparePassword returns false", async () => {
it("should reject with an error if user.comparePassword returns false", async function() {
req.db.getUserByEmail.returns({
comparePassword: sinon.stub().returns(false),
});
@@ -473,7 +482,7 @@ describe("Auth Controller - editUser", async () => {
);
});
it("should edit a user if it receives a proper request", async () => {
it("should edit a user if it receives a proper request", async function() {
const user = {
comparePassword: sinon.stub().resolves(true),
};
@@ -495,7 +504,7 @@ describe("Auth Controller - editUser", async () => {
expect(next.notCalled).to.be.true;
});
it("should edit a user if it receives a proper request and both password fields are undefined", async () => {
it("should edit a user if it receives a proper request and both password fields are undefined", async function() {
req.body.password = undefined;
req.body.newPassword = undefined;
req.db.getUserByEmail.resolves(user);
@@ -513,7 +522,7 @@ describe("Auth Controller - editUser", async () => {
expect(next.notCalled).to.be.true;
});
it("should reject an edit request if password format is incorrect", async () => {
it("should reject an edit request if password format is incorrect", async function() {
req.body = { password: "bad_password", newPassword: "bad_password" };
const user = {
comparePassword: sinon.stub().resolves(true),
@@ -527,9 +536,10 @@ describe("Auth Controller - editUser", async () => {
});
});
describe("Auth Controller - checkSuperadminExists", async () => {
describe("Auth Controller - checkSuperadminExists", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
db: {
checkSuperadmin: sinon.stub(),
@@ -542,14 +552,14 @@ describe("Auth Controller - checkSuperadminExists", async () => {
next = sinon.stub();
});
it("should reject with an error if checkSuperadmin fails", async () => {
it("should reject with an error if checkSuperadmin fails", async function() {
req.db.checkSuperadmin.rejects(new Error("checkSuperadmin error"));
await checkSuperadminExists(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("checkSuperadmin error");
});
it("should return true if a superadmin exists", async () => {
it("should return true if a superadmin exists", async function() {
req.db.checkSuperadmin.resolves(true);
await checkSuperadminExists(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
@@ -563,7 +573,7 @@ describe("Auth Controller - checkSuperadminExists", async () => {
expect(next.notCalled).to.be.true;
});
it("should return false if a superadmin does not exist", async () => {
it("should return false if a superadmin does not exist", async function() {
req.db.checkSuperadmin.resolves(false);
await checkSuperadminExists(req, res, next);
expect(res.status.calledWith(200)).to.be.true;
@@ -578,9 +588,10 @@ describe("Auth Controller - checkSuperadminExists", async () => {
});
});
describe("Auth Controller - requestRecovery", () => {
describe("Auth Controller - requestRecovery", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: { email: "test@test.com" },
db: {
@@ -601,21 +612,21 @@ describe("Auth Controller - requestRecovery", () => {
next = sinon.stub();
});
it("should reject with an error if validation fails", async () => {
it("should reject with an error if validation fails", async function() {
req.body = {};
await requestRecovery(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 getUserByEmail fails", async () => {
it("should reject with an error if getUserByEmail fails", async function() {
req.db.getUserByEmail.rejects(new Error("getUserByEmail error"));
await requestRecovery(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("getUserByEmail error");
});
it("should throw an error if the user is not found", async () => {
it("should throw an error if the user is not found", async function() {
req.db.getUserByEmail.resolves(null);
await requestRecovery(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
@@ -624,13 +635,14 @@ describe("Auth Controller - requestRecovery", () => {
// );
});
it("should throw an error if the email is not provided", async () => {
it("should throw an error if the email is not provided", async function() {
req.body = {};
await requestRecovery(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 the email is provided", async () => {
it("should return a success message if the email is provided", async function() {
const user = { firstName: "John" };
const recoveryToken = { token: "recovery-token" };
const msgId = "message-id";
@@ -664,9 +676,10 @@ describe("Auth Controller - requestRecovery", () => {
});
});
describe("Auth Controller - validateRecovery", () => {
describe("Auth Controller - validateRecovery", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: { recoveryToken: "recovery-token" },
db: {
@@ -680,21 +693,21 @@ describe("Auth Controller - validateRecovery", () => {
next = sinon.stub();
});
it("should reject with an error if validation fails", async () => {
it("should reject with an error if validation fails", async function() {
req.body = {};
await validateRecovery(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 validateRecoveryToken fails", async () => {
it("should reject with an error if validateRecoveryToken fails", async function() {
req.db.validateRecoveryToken.rejects(new Error("validateRecoveryToken error"));
await validateRecovery(req, res, next);
expect(next.firstCall.args[0]).to.be.an("error");
expect(next.firstCall.args[0].message).to.equal("validateRecoveryToken error");
});
it("should return a success message if the token is valid", async () => {
it("should return a success message if the token is valid", async function() {
req.db.validateRecoveryToken.resolves();
await validateRecovery(req, res, next);
expect(res.status.calledOnceWith(200)).to.be.true;
@@ -708,9 +721,10 @@ describe("Auth Controller - validateRecovery", () => {
});
});
describe("Auth Controller - resetPassword", () => {
describe("Auth Controller - resetPassword", function() {
let req, res, next, newPasswordValidation, handleValidationError, handleError;
beforeEach(() => {
beforeEach(function() {
req = {
body: {
recoveryToken: "recovery-token",
@@ -734,14 +748,15 @@ describe("Auth Controller - resetPassword", () => {
handleValidationError = sinon.stub();
handleError = sinon.stub();
});
it("should reject with an error if validation fails", async () => {
it("should reject with an error if validation fails", async function() {
req.body = { password: "bad_password" };
await resetPassword(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 resetPassword fails", async () => {
it("should reject with an error if resetPassword fails", async function() {
const error = new Error("resetPassword error");
newPasswordValidation.validateAsync.resolves();
req.db.resetPassword.rejects(error);
@@ -750,7 +765,7 @@ describe("Auth Controller - resetPassword", () => {
expect(next.firstCall.args[0].message).to.equal("resetPassword error");
});
it("should reset password successfully", async () => {
it("should reset password successfully", async function() {
const user = { _doc: {} };
const appSettings = { jwtSecret: "my_secret" };
const token = "token";
@@ -775,9 +790,10 @@ describe("Auth Controller - resetPassword", () => {
});
});
describe("Auth Controller - deleteUser", () => {
describe("Auth Controller - deleteUser", function() {
let req, res, next, handleError;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {
authorization: "Bearer token",
@@ -809,10 +825,11 @@ describe("Auth Controller - deleteUser", () => {
handleError = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should throw an error if user is not found", async () => {
it("should throw an error if user is not found", async function() {
jwt.decode.returns({ email: "test@example.com" });
req.db.getUserByEmail.throws(new Error(errorMessages.DB_USER_NOT_FOUND));
@@ -825,7 +842,7 @@ describe("Auth Controller - deleteUser", () => {
expect(res.json.notCalled).to.be.true;
});
it("should delete user and associated data if user is superadmin", async () => {
it("should delete user and associated data if user is superadmin", async function() {
const user = {
_id: "user_id",
email: "test@example.com",
@@ -865,7 +882,7 @@ describe("Auth Controller - deleteUser", () => {
expect(next.notCalled).to.be.true;
});
it("should delete user if user is not superadmin", async () => {
it("should delete user if user is not superadmin", async function() {
const user = {
_id: "user_id",
email: "test@example.com",
@@ -895,7 +912,7 @@ describe("Auth Controller - deleteUser", () => {
expect(next.notCalled).to.be.true;
});
it("should handle errors", async () => {
it("should handle errors", async function() {
const error = new Error("Something went wrong");
const SERVICE_NAME = "AuthController";
jwt.decode.returns({ email: "test@example.com" });
@@ -908,10 +925,10 @@ describe("Auth Controller - deleteUser", () => {
});
});
describe("Auth Controller - getAllUsers", () => {
describe("Auth Controller - getAllUsers", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
db: {
getAllUsers: sinon.stub(),
@@ -924,11 +941,11 @@ describe("Auth Controller - getAllUsers", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore(); // Restore the original methods after each test
});
it("should return 200 and all users", async () => {
it("should return 200 and all users", async function() {
const allUsers = [{ id: 1, name: "John Doe" }];
req.db.getAllUsers.resolves(allUsers);
@@ -946,7 +963,7 @@ describe("Auth Controller - getAllUsers", () => {
expect(next.notCalled).to.be.true;
});
it("should call next with error when an exception occurs", async () => {
it("should call next with error when an exception occurs", async function() {
const error = new Error("Something went wrong");
req.db.getAllUsers.rejects(error);
await getAllUsers(req, res, next);

View File

@@ -9,9 +9,10 @@ import {
import jwt from "jsonwebtoken";
import { errorMessages, successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Check Controller - createCheck", () => {
describe("Check Controller - createCheck", function() {
let req, res, next, handleError;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
body: {},
@@ -27,17 +28,17 @@ describe("Check Controller - createCheck", () => {
handleError = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore(); // Restore the original methods after each test
});
it("should reject with a validation if params are invalid", async () => {
it("should reject with a validation if params are invalid", async function() {
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 () => {
it("should reject with a validation error if body is invalid", async function() {
req.params = {
monitorId: "monitorId",
};
@@ -46,7 +47,7 @@ describe("Check Controller - createCheck", () => {
expect(next.firstCall.args[0].status).to.equal(422);
});
it("should call next with error if data retrieval fails", async () => {
it("should call next with error if data retrieval fails", async function() {
req.params = {
monitorId: "monitorId",
};
@@ -62,7 +63,7 @@ describe("Check Controller - createCheck", () => {
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should return a success message if check is created", async () => {
it("should return a success message if check is created", async function() {
req.params = {
monitorId: "monitorId",
};
@@ -87,9 +88,10 @@ describe("Check Controller - createCheck", () => {
});
});
describe("Check Controller - getChecks", () => {
describe("Check Controller - getChecks", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
query: {},
@@ -105,17 +107,17 @@ describe("Check Controller - getChecks", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with a validation error if params are invalid", async () => {
it("should reject with a validation error if params are invalid", async function() {
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 () => {
it("should return a success message if checks are found", async function() {
req.params = {
monitorId: "monitorId",
};
@@ -133,7 +135,7 @@ describe("Check Controller - getChecks", () => {
expect(next.notCalled).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
it("should call next with error if data retrieval fails", async function() {
req.params = {
monitorId: "monitorId",
};
@@ -143,9 +145,10 @@ describe("Check Controller - getChecks", () => {
});
});
describe("Check Controller - getTeamChecks", () => {
describe("Check Controller - getTeamChecks", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
query: {},
@@ -160,17 +163,17 @@ describe("Check Controller - getTeamChecks", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with a validation error if params are invalid", async () => {
it("should reject with a validation error if params are invalid", async function() {
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 () => {
it("should return 200 and check data on successful validation and data retrieval", async function() {
req.params = { teamId: "1" };
const checkData = [{ id: 1, name: "Check 1" }];
req.db.getTeamChecks.resolves(checkData);
@@ -187,7 +190,7 @@ describe("Check Controller - getTeamChecks", () => {
).to.be.true;
});
it("should call next with error if data retrieval fails", async () => {
it("should call next with error if data retrieval fails", async function() {
req.params = { teamId: "1" };
req.db.getTeamChecks.rejects(new Error("Retrieval Error"));
await getTeamChecks(req, res, next);
@@ -198,9 +201,10 @@ describe("Check Controller - getTeamChecks", () => {
});
});
describe("Check Controller - deleteChecks", () => {
describe("Check Controller - deleteChecks", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
db: {
@@ -214,17 +218,17 @@ describe("Check Controller - deleteChecks", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
it("should reject with an error if param validation fails", async function() {
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 () => {
it("should call next with error if data retrieval fails", async function() {
req.params = { monitorId: "1" };
req.db.deleteChecks.rejects(new Error("Deletion Error"));
await deleteChecks(req, res, next);
@@ -234,7 +238,7 @@ describe("Check Controller - deleteChecks", () => {
expect(res.json.notCalled).to.be.true;
});
it("should delete checks successfully", async () => {
it("should delete checks successfully", async function() {
req.params = { monitorId: "123" };
req.db.deleteChecks.resolves(1);
await deleteChecks(req, res, next);
@@ -250,9 +254,10 @@ describe("Check Controller - deleteChecks", () => {
});
});
describe("Check Controller - deleteChecksByTeamId", () => {
describe("Check Controller - deleteChecksByTeamId", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
db: {
@@ -266,17 +271,17 @@ describe("Check Controller - deleteChecksByTeamId", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
it("should reject with an error if param validation fails", async function() {
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 () => {
it("should call next with error if data retrieval fails", async function() {
req.params = { teamId: "1" };
req.db.deleteChecksByTeamId.rejects(new Error("Deletion Error"));
await deleteChecksByTeamId(req, res, next);
@@ -286,7 +291,7 @@ describe("Check Controller - deleteChecksByTeamId", () => {
expect(res.json.notCalled).to.be.true;
});
it("should delete checks successfully", async () => {
it("should delete checks successfully", async function() {
req.params = { teamId: "123" };
req.db.deleteChecksByTeamId.resolves(1);
await deleteChecksByTeamId(req, res, next);
@@ -302,9 +307,10 @@ describe("Check Controller - deleteChecksByTeamId", () => {
});
});
describe("Check Controller - updateCheckTTL", () => {
describe("Check Controller - updateCheckTTL", function() {
let stub, req, res, next;
beforeEach(() => {
beforeEach(function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -326,18 +332,18 @@ describe("Check Controller - updateCheckTTL", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
stub.restore();
});
it("should reject if body validation fails", async () => {
it("should reject if body validation fails", async function() {
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 () => {
it("should throw a JwtError if verification fails", async function() {
stub.restore();
req.body = {
ttl: 1,
@@ -346,7 +352,7 @@ describe("Check Controller - updateCheckTTL", () => {
expect(next.firstCall.args[0]).to.be.instanceOf(jwt.JsonWebTokenError);
});
it("should call next with error if data retrieval fails", async () => {
it("should call next with error if data retrieval fails", async function() {
req.body = {
ttl: 1,
};
@@ -355,7 +361,7 @@ describe("Check Controller - updateCheckTTL", () => {
expect(next.firstCall.args[0]).to.be.an("error");
});
it("should update TTL successfully", async () => {
it("should update TTL successfully", async function() {
req.body = {
ttl: 1,
};

View File

@@ -10,22 +10,22 @@ import sslChecker from "ssl-checker";
import { afterEach } from "node:test";
import exp from "constants";
describe("controllerUtils - handleValidationError", () => {
it("should set status to 422", () => {
describe("controllerUtils - handleValidationError", function() {
it("should set status to 422", function() {
const error = {};
const serviceName = "TestService";
const result = handleValidationError(error, serviceName);
expect(result.status).to.equal(422);
});
it("should set service to the provided serviceName", () => {
it("should set service to the provided serviceName", function() {
const error = {};
const serviceName = "TestService";
const result = handleValidationError(error, serviceName);
expect(result.service).to.equal(serviceName);
});
it("should set message to error.details[0].message if present", () => {
it("should set message to error.details[0].message if present", function() {
const error = {
details: [{ message: "Detail message" }],
};
@@ -34,7 +34,7 @@ describe("controllerUtils - handleValidationError", () => {
expect(result.message).to.equal("Detail message");
});
it("should set message to error.message if error.details is not present", () => {
it("should set message to error.message if error.details is not present", function() {
const error = {
message: "Error message",
};
@@ -43,7 +43,7 @@ describe("controllerUtils - handleValidationError", () => {
expect(result.message).to.equal("Error message");
});
it('should set message to "Validation Error" if neither error.details nor error.message is present', () => {
it('should set message to "Validation Error" if neither error.details nor error.message is present', function() {
const error = {};
const serviceName = "TestService";
const result = handleValidationError(error, serviceName);
@@ -51,8 +51,8 @@ describe("controllerUtils - handleValidationError", () => {
});
});
describe("controllerUtils - handleError", () => {
it("should set stats to the provided status if error.code is undefined", () => {
describe("controllerUtils - handleError", function() {
it("should set stats to the provided status if error.code is undefined", function() {
const error = {};
const serviceName = "TestService";
const method = "testMethod";
@@ -61,7 +61,7 @@ describe("controllerUtils - handleError", () => {
expect(result.status).to.equal(status);
});
it("should not overwrite error.code if it is already defined", () => {
it("should not overwrite error.code if it is already defined", function() {
const error = { status: 404 };
const serviceName = "TestService";
const method = "testMethod";
@@ -70,7 +70,7 @@ describe("controllerUtils - handleError", () => {
expect(result.status).to.equal(404);
});
it("should set service to the provided serviceName if error.service is undefined", () => {
it("should set service to the provided serviceName if error.service is undefined", function() {
const error = {};
const serviceName = "TestService";
const method = "testMethod";
@@ -78,7 +78,7 @@ describe("controllerUtils - handleError", () => {
expect(result.service).to.equal(serviceName);
});
it("should not overwrite error.service if it is already defined", () => {
it("should not overwrite error.service if it is already defined", function() {
const error = { service: "ExistingService" };
const serviceName = "TestService";
const method = "testMethod";
@@ -86,7 +86,7 @@ describe("controllerUtils - handleError", () => {
expect(result.service).to.equal("ExistingService");
});
it("should set method to the provided method if error.method is undefined", () => {
it("should set method to the provided method if error.method is undefined", function() {
const error = {};
const serviceName = "TestService";
const method = "testMethod";
@@ -94,7 +94,7 @@ describe("controllerUtils - handleError", () => {
expect(result.method).to.equal(method);
});
it("should not overwrite error.method if it is already defined", () => {
it("should not overwrite error.method if it is already defined", function() {
const error = { method: "existingMethod" };
const serviceName = "TestService";
const method = "testMethod";
@@ -102,7 +102,7 @@ describe("controllerUtils - handleError", () => {
expect(result.method).to.equal("existingMethod");
});
it("should set code to 500 if error.code is undefined and no code is provided", () => {
it("should set code to 500 if error.code is undefined and no code is provided", function() {
const error = {};
const serviceName = "TestService";
const method = "testMethod";
@@ -111,9 +111,10 @@ describe("controllerUtils - handleError", () => {
});
});
describe("controllerUtils - fetchMonitorCertificate", () => {
describe("controllerUtils - fetchMonitorCertificate", function() {
let sslChecker, monitor;
beforeEach(() => {
beforeEach(function() {
monitor = {
url: "https://www.google.com",
};
@@ -124,7 +125,7 @@ describe("controllerUtils - fetchMonitorCertificate", () => {
sinon.restore();
});
it("should reject with an error if a URL does not parse", async () => {
it("should reject with an error if a URL does not parse", async function() {
monitor.url = "invalidurl";
try {
await fetchMonitorCertificate(sslChecker, monitor);
@@ -134,7 +135,7 @@ describe("controllerUtils - fetchMonitorCertificate", () => {
}
});
it("should reject with an error if sslChecker throws an error", async () => {
it("should reject with an error if sslChecker throws an error", async function() {
sslChecker.rejects(new Error("Test error"));
try {
await fetchMonitorCertificate(sslChecker, monitor);
@@ -143,12 +144,14 @@ describe("controllerUtils - fetchMonitorCertificate", () => {
expect(error.message).to.equal("Test error");
}
});
it("should return a certificate if sslChecker resolves", async () => {
it("should return a certificate if sslChecker resolves", async function() {
sslChecker.resolves({ validTo: "2022-01-01" });
const result = await fetchMonitorCertificate(sslChecker, monitor);
expect(result).to.deep.equal({ validTo: "2022-01-01" });
});
it("should throw an error if a ssl-checker returns null", async () => {
it("should throw an error if a ssl-checker returns null", async function() {
sslChecker.returns(null);
await fetchMonitorCertificate(sslChecker, monitor).catch((error) => {
expect(error).to.be.an("error");

View File

@@ -5,9 +5,10 @@ import {
import jwt from "jsonwebtoken";
import sinon from "sinon";
import joi from "joi";
describe("inviteController - issueInvitation", () => {
describe("inviteController - issueInvitation", function() {
let req, res, next, stub;
beforeEach(() => {
beforeEach(function() {
req = {
headers: { authorization: "Bearer token" },
body: {
@@ -26,11 +27,11 @@ describe("inviteController - issueInvitation", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if role validation fails", async () => {
it("should reject with an error if role validation fails", async function() {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["bad_role"], firstname: "first_name", teamId: "1" };
});
@@ -41,7 +42,7 @@ describe("inviteController - issueInvitation", () => {
stub.restore();
});
it("should reject with an error if body validation fails", async () => {
it("should reject with an error if body validation fails", async function() {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
@@ -52,7 +53,7 @@ describe("inviteController - issueInvitation", () => {
stub.restore();
});
it("should reject with an error if DB operations fail", async () => {
it("should reject with an error if DB operations fail", async function() {
stub = sinon.stub(jwt, "decode").callsFake(() => {
return { role: ["admin"], firstname: "first_name", teamId: "1" };
});
@@ -63,7 +64,7 @@ describe("inviteController - issueInvitation", () => {
stub.restore();
});
it("should send an invite successfully", async () => {
it("should send an invite successfully", async function() {
const token = "token";
const decodedToken = {
role: "admin",
@@ -91,7 +92,7 @@ describe("inviteController - issueInvitation", () => {
stub.restore();
});
it("should send an email successfully", async () => {
it("should send an email successfully", async function() {
const token = "token";
const decodedToken = {
role: "admin",
@@ -124,7 +125,7 @@ describe("inviteController - issueInvitation", () => {
stub.restore();
});
it("should continue executing if sending an email fails", async () => {
it("should continue executing if sending an email fails", async function() {
const token = "token";
req.emailService.buildAndSendEmail.rejects(new Error("Email error"));
const decodedToken = {
@@ -153,9 +154,10 @@ describe("inviteController - issueInvitation", () => {
});
});
describe("inviteController - inviteVerifyController", () => {
describe("inviteController - inviteVerifyController", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: { token: "token" },
db: {
@@ -169,25 +171,25 @@ describe("inviteController - inviteVerifyController", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
it("should reject with an error if body validation fails", async function() {
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 () => {
it("should reject with an error if DB operations fail", async function() {
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 () => {
it("should return 200 and invite data when validation and invite retrieval are successful", async function() {
req.db.getInviteToken.resolves({ invite: "data" });
await inviteVerifyController(req, res, next);
expect(res.status.calledWith(200)).to.be.true;

View File

@@ -11,9 +11,10 @@ import jwt from "jsonwebtoken";
import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("maintenanceWindowController - createMaintenanceWindows", () => {
describe("maintenanceWindowController - createMaintenanceWindows", function() {
let req, res, next, stub;
beforeEach(() => {
beforeEach(function() {
req = {
body: {
monitors: ["66ff52e7c5911c61698ac724"],
@@ -40,11 +41,11 @@ describe("maintenanceWindowController - createMaintenanceWindows", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
it("should reject with an error if body validation fails", async function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -55,14 +56,14 @@ describe("maintenanceWindowController - createMaintenanceWindows", () => {
stub.restore();
});
it("should reject with an error if jwt.verify fails", async () => {
it("should reject with an error if jwt.verify fails", async function() {
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 () => {
it("should reject with an error DB operations fail", async function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -72,7 +73,8 @@ describe("maintenanceWindowController - createMaintenanceWindows", () => {
expect(next.firstCall.args[0].message).to.equal("DB error");
stub.restore();
});
it("should return success message if all operations are successful", async () => {
it("should return success message if all operations are successful", async function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -86,7 +88,8 @@ describe("maintenanceWindowController - createMaintenanceWindows", () => {
).to.be.true;
stub.restore();
});
it("should return success message if all operations are successful with active set to undefined", async () => {
it("should return success message if all operations are successful with active set to undefined", async function() {
req.body.active = undefined;
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
@@ -103,9 +106,10 @@ describe("maintenanceWindowController - createMaintenanceWindows", () => {
});
});
describe("maintenanceWindowController - getMaintenanceWindowById", () => {
describe("maintenanceWindowController - getMaintenanceWindowById", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: {},
params: {
@@ -128,20 +132,21 @@ describe("maintenanceWindowController - getMaintenanceWindowById", () => {
next = sinon.stub();
});
it("should reject if param validation fails", async () => {
it("should reject if param validation fails", async function() {
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 () => {
it("should reject if DB operations fail", async function() {
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 () => {
it("should return success message with data if all operations are successful", async function() {
req.db.getMaintenanceWindowById.returns({ id: "123" });
await getMaintenanceWindowById(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
@@ -155,9 +160,10 @@ describe("maintenanceWindowController - getMaintenanceWindowById", () => {
});
});
describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", function() {
let req, res, next, stub;
beforeEach(() => {
beforeEach(function() {
req = {
body: {},
params: {},
@@ -178,7 +184,8 @@ describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
};
next = sinon.stub();
});
it("should reject if query validation fails", async () => {
it("should reject if query validation fails", async function() {
req.query = {
invalid: 1,
};
@@ -186,14 +193,15 @@ describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
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 () => {
it("should reject if jwt.verify fails", async function() {
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 () => {
it("should reject with an error if DB operations fail", async function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -204,7 +212,7 @@ describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
stub.restore();
});
it("should return success message with data if all operations are successful", async () => {
it("should return success message with data if all operations are successful", async function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -222,9 +230,10 @@ describe("maintenanceWindowController - getMaintenanceWindowsByTeamId", () => {
});
});
describe("maintenanceWindowController - getMaintenanceWindowsByMonitorId", () => {
describe("maintenanceWindowController - getMaintenanceWindowsByMonitorId", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: {},
params: {
@@ -248,25 +257,25 @@ describe("maintenanceWindowController - getMaintenanceWindowsByMonitorId", () =>
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject if param validation fails", async () => {
it("should reject if param validation fails", async function() {
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 () => {
it("should reject with an error if DB operations fail", async function() {
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 () => {
it("should return success message with data if all operations are successful", async function() {
const data = [{ monitorId: "123" }];
req.db.getMaintenanceWindowsByMonitorId.returns(data);
await getMaintenanceWindowsByMonitorId(req, res, next);
@@ -282,9 +291,10 @@ describe("maintenanceWindowController - getMaintenanceWindowsByMonitorId", () =>
});
});
describe("maintenanceWindowController - deleteMaintenanceWindow", () => {
describe("maintenanceWindowController - deleteMaintenanceWindow", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: {},
params: {
@@ -307,25 +317,26 @@ describe("maintenanceWindowController - deleteMaintenanceWindow", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject if param validation fails", async () => {
it("should reject if param validation fails", async function() {
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 () => {
it("should reject with an error if DB operations fail", async function() {
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 () => {
it("should return success message if all operations are successful", async function() {
await deleteMaintenanceWindow(req, res, next);
expect(req.db.deleteMaintenanceWindowById.calledOnceWith(req.params.id));
expect(res.status.firstCall.args[0]).to.equal(200);
@@ -338,9 +349,10 @@ describe("maintenanceWindowController - deleteMaintenanceWindow", () => {
});
});
describe("maintenanceWindowController - editMaintenanceWindow", () => {
describe("maintenanceWindowController - editMaintenanceWindow", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
body: {
active: true,
@@ -367,32 +379,32 @@ describe("maintenanceWindowController - editMaintenanceWindow", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject if param validation fails", async () => {
it("should reject if param validation fails", async function() {
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 () => {
it("should reject if body validation fails", async function() {
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 () => {
it("should reject with an error if DB operations fail", async function() {
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 () => {
it("should return success message with data if all operations are successful", async function() {
const data = { id: "123" };
req.db.editMaintenanceWindowById.returns(data);

View File

@@ -21,9 +21,10 @@ import logger from "../../utils/logger.js";
import axios from "axios";
const SERVICE_NAME = "monitorController";
describe("Monitor Controller - getAllMonitors", () => {
describe("Monitor Controller - getAllMonitors", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
query: {},
@@ -38,17 +39,19 @@ describe("Monitor Controller - getAllMonitors", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if DB operations fail", async () => {
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 () => {
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);
@@ -62,9 +65,10 @@ describe("Monitor Controller - getAllMonitors", () => {
).to.be.true;
});
});
describe("Monitor Controller - getAllMonitorsWithUptimeStats", () => {
describe("Monitor Controller - getAllMonitorsWithUptimeStats", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
query: {},
@@ -79,17 +83,19 @@ describe("Monitor Controller - getAllMonitorsWithUptimeStats", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if DB operations fail", async () => {
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 () => {
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);
@@ -104,9 +110,10 @@ describe("Monitor Controller - getAllMonitorsWithUptimeStats", () => {
});
});
describe("Monitor Controller - getMonitorStatsById", () => {
describe("Monitor Controller - getMonitorStatsById", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
monitorId: "123",
@@ -123,29 +130,33 @@ describe("Monitor Controller - getMonitorStatsById", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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 () => {
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);
@@ -160,9 +171,10 @@ describe("Monitor Controller - getMonitorStatsById", () => {
});
});
describe("Monitor Controller - getMonitorCertificate", () => {
describe("Monitor Controller - getMonitorCertificate", function() {
let req, res, next, fetchMonitorCertificate;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
monitorId: "123",
@@ -181,23 +193,25 @@ describe("Monitor Controller - getMonitorCertificate", () => {
fetchMonitorCertificate = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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);
@@ -211,7 +225,8 @@ describe("Monitor Controller - getMonitorCertificate", () => {
})
).to.be.true;
});
it("should return an error if fetchMonitorCertificate fails", async () => {
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);
@@ -220,9 +235,10 @@ describe("Monitor Controller - getMonitorCertificate", () => {
});
});
describe("Monitor Controller - getMonitorById", () => {
describe("Monitor Controller - getMonitorById", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
monitorId: "123",
@@ -239,28 +255,33 @@ describe("Monitor Controller - getMonitorById", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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 () => {
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);
@@ -268,7 +289,8 @@ describe("Monitor Controller - getMonitorById", () => {
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 () => {
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);
@@ -283,9 +305,10 @@ describe("Monitor Controller - getMonitorById", () => {
});
});
describe("Monitor Controller - getMonitorsAndSummaryByTeamId", () => {
describe("Monitor Controller - getMonitorsAndSummaryByTeamId", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
teamId: "123",
@@ -302,29 +325,33 @@ describe("Monitor Controller - getMonitorsAndSummaryByTeamId", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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 () => {
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);
@@ -339,9 +366,10 @@ describe("Monitor Controller - getMonitorsAndSummaryByTeamId", () => {
});
});
describe("Monitor Controller - getMonitorsByTeamId", () => {
describe("Monitor Controller - getMonitorsByTeamId", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
teamId: "123",
@@ -358,28 +386,33 @@ describe("Monitor Controller - getMonitorsByTeamId", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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 () => {
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);
@@ -394,9 +427,10 @@ describe("Monitor Controller - getMonitorsByTeamId", () => {
});
});
describe("Monitor Controller - createMonitor", () => {
describe("Monitor Controller - createMonitor", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
query: {},
@@ -423,29 +457,34 @@ describe("Monitor Controller - createMonitor", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
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 () => {
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 () => {
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 () => {
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")),
@@ -454,14 +493,16 @@ describe("Monitor Controller - createMonitor", () => {
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 () => {
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 () => {
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);
@@ -476,18 +517,21 @@ describe("Monitor Controller - createMonitor", () => {
});
});
describe("Monitor Controller - checkEndpointResolution", () => {
describe("Monitor Controller - checkEndpointResolution", function() {
let req, res, next, axiosGetStub;
beforeEach(() => {
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(() => {
afterEach(function() {
sinon.restore();
});
it("should resolve the URL successfully", async () => {
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;
@@ -501,7 +545,8 @@ describe("Monitor Controller - checkEndpointResolution", () => {
).to.be.true;
expect(next.called).to.be.false;
});
it("should return an error if endpoint resolution fails", async () => {
it("should return an error if endpoint resolution fails", async function() {
const axiosError = new Error("resolution failed");
axiosError.code = "ENOTFOUND";
axiosGetStub.rejects(axiosError);
@@ -513,7 +558,8 @@ describe("Monitor Controller - checkEndpointResolution", () => {
expect(errorPassedToNext.code).to.equal("ENOTFOUND");
expect(errorPassedToNext.status).to.equal(500);
});
it("should reject with an error if query validation fails", async () => {
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;
@@ -524,9 +570,10 @@ describe("Monitor Controller - checkEndpointResolution", () => {
});
});
describe("Monitor Controller - deleteMonitor", () => {
describe("Monitor Controller - deleteMonitor", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
monitorId: "123",
@@ -550,22 +597,26 @@ describe("Monitor Controller - deleteMonitor", () => {
next = sinon.stub();
sinon.stub(logger, "error");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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);
@@ -576,7 +627,8 @@ describe("Monitor Controller - deleteMonitor", () => {
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deleteChecks throws an error", async () => {
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);
@@ -587,7 +639,8 @@ describe("Monitor Controller - deleteMonitor", () => {
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deletePageSpeedChecksByMonitorId throws an error", async () => {
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);
@@ -598,7 +651,8 @@ describe("Monitor Controller - deleteMonitor", () => {
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should log an error if deleteNotificationsByMonitorId throws an error", async () => {
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);
@@ -609,7 +663,8 @@ describe("Monitor Controller - deleteMonitor", () => {
`Error deleting associated records for monitor ${monitor._id} with name ${monitor.name}`
);
});
it("should return success message if all operations succeed", async () => {
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);
@@ -623,9 +678,10 @@ describe("Monitor Controller - deleteMonitor", () => {
});
});
describe("Monitor Controller - deleteAllMonitors", () => {
describe("Monitor Controller - deleteAllMonitors", function() {
let req, res, next, stub;
beforeEach(() => {
beforeEach(function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { teamId: "123" };
});
@@ -658,24 +714,28 @@ describe("Monitor Controller - deleteAllMonitors", () => {
next = sinon.stub();
sinon.stub(logger, "error");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
stub.restore();
});
it("should reject with an error if getTokenFromHeaders throws an error", async () => {
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 () => {
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 () => {
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);
@@ -683,7 +743,7 @@ describe("Monitor Controller - deleteAllMonitors", () => {
expect(next.firstCall.args[0].message).to.equal("DB error");
});
it("should log an error if deleteChecks throws an error", async () => {
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 });
@@ -695,7 +755,8 @@ describe("Monitor Controller - deleteAllMonitors", () => {
`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 () => {
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 });
@@ -707,7 +768,8 @@ describe("Monitor Controller - deleteAllMonitors", () => {
`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 () => {
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 });
@@ -719,7 +781,8 @@ describe("Monitor Controller - deleteAllMonitors", () => {
`Error deleting associated records for monitor ${monitors[0]._id} with name ${monitors[0].name}`
);
});
it("should return success message if all operations succeed", async () => {
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" }],
@@ -736,9 +799,10 @@ describe("Monitor Controller - deleteAllMonitors", () => {
});
});
describe("Monitor Controller - editMonitor", () => {
describe("Monitor Controller - editMonitor", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {
@@ -768,35 +832,41 @@ describe("Monitor Controller - editMonitor", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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 () => {
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 () => {
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"));
@@ -804,7 +874,8 @@ describe("Monitor Controller - editMonitor", () => {
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 () => {
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"));
@@ -812,7 +883,8 @@ describe("Monitor Controller - editMonitor", () => {
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 () => {
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"));
@@ -820,7 +892,8 @@ describe("Monitor Controller - editMonitor", () => {
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 () => {
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"));
@@ -828,7 +901,8 @@ describe("Monitor Controller - editMonitor", () => {
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 () => {
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);
@@ -844,9 +918,10 @@ describe("Monitor Controller - editMonitor", () => {
});
});
describe("Monitor Controller - pauseMonitor", () => {
describe("Monitor Controller - pauseMonitor", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {
@@ -871,23 +946,26 @@ describe("Monitor Controller - pauseMonitor", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should reject with an error if param validation fails", async () => {
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 () => {
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 () => {
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"));
@@ -896,7 +974,7 @@ describe("Monitor Controller - pauseMonitor", () => {
expect(next.firstCall.args[0].message).to.equal("Delete Job error");
});
it("should reject with an error if addJob operation fails", async () => {
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"));
@@ -904,7 +982,8 @@ describe("Monitor Controller - pauseMonitor", () => {
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 () => {
it("should reject with an error if monitor.save operation fails", async function() {
const monitor = {
_id: req.params.monitorId,
active: false,
@@ -915,7 +994,8 @@ describe("Monitor Controller - pauseMonitor", () => {
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 () => {
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,
@@ -932,7 +1012,8 @@ describe("Monitor Controller - pauseMonitor", () => {
})
).to.be.true;
});
it("should return success resume message with data if all operations succeed with active monitor", async () => {
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,
@@ -951,9 +1032,10 @@ describe("Monitor Controller - pauseMonitor", () => {
});
});
describe("Monitor Controller - addDemoMonitors", () => {
describe("Monitor Controller - addDemoMonitors", function() {
let req, res, next, stub;
beforeEach(() => {
beforeEach(function() {
stub = sinon.stub(jwt, "verify").callsFake(() => {
return { _id: "123", teamId: "123" };
});
@@ -980,37 +1062,43 @@ describe("Monitor Controller - addDemoMonitors", () => {
};
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
stub.restore();
});
it("should reject with an error if getTokenFromHeaders fails", async () => {
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 () => {
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 () => {
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 () => {
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 () => {
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"));
@@ -1018,7 +1106,8 @@ describe("Monitor Controller - addDemoMonitors", () => {
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 () => {
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);

View File

@@ -8,9 +8,10 @@ import {
import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Queue Controller - getMetrics", () => {
describe("Queue Controller - getMetrics", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -26,17 +27,19 @@ describe("Queue Controller - getMetrics", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getMetrics throws an error", async () => {
it("should throw an error if getMetrics throws an error", async function() {
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 () => {
it("should return a success message and data if getMetrics is successful", async function() {
const data = { data: "metrics" };
req.jobQueue.getMetrics.returns(data);
await getMetrics(req, res, next);
@@ -49,9 +52,10 @@ describe("Queue Controller - getMetrics", () => {
});
});
describe("Queue Controller - getJobs", () => {
describe("Queue Controller - getJobs", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -67,16 +71,19 @@ describe("Queue Controller - getJobs", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if getJobs throws an error", async () => {
it("should reject with an error if getJobs throws an error", async function() {
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 () => {
it("should return a success message and data if getJobs is successful", async function() {
const data = { data: "jobs" };
req.jobQueue.getJobStats.returns(data);
await getJobs(req, res, next);
@@ -89,9 +96,10 @@ describe("Queue Controller - getJobs", () => {
});
});
describe("Queue Controller - addJob", () => {
describe("Queue Controller - addJob", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -107,16 +115,19 @@ describe("Queue Controller - addJob", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if addJob throws an error", async () => {
it("should reject with an error if addJob throws an error", async function() {
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 () => {
it("should return a success message if addJob is successful", async function() {
req.jobQueue.addJob.resolves();
await addJob(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
@@ -127,9 +138,10 @@ describe("Queue Controller - addJob", () => {
});
});
describe("Queue Controller - obliterateQueue", () => {
describe("Queue Controller - obliterateQueue", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -145,16 +157,19 @@ describe("Queue Controller - obliterateQueue", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if obliterateQueue throws an error", async () => {
it("should reject with an error if obliterateQueue throws an error", async function() {
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 () => {
it("should return a success message if obliterateQueue is successful", async function() {
req.jobQueue.obliterate.resolves();
await obliterateQueue(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);

View File

@@ -7,9 +7,10 @@ import {
import { successMessages } from "../../utils/messages.js";
import sinon from "sinon";
describe("Settings Controller - getAppSettings", () => {
describe("Settings Controller - getAppSettings", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -25,17 +26,19 @@ describe("Settings Controller - getAppSettings", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if getSettings throws an error", async () => {
it("should throw an error if getSettings throws an error", async function() {
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 () => {
it("should return a success message and data if getSettings is successful", async function() {
const data = { data: "settings" };
req.settingsService.getSettings.returns(data);
await getAppSettings(req, res, next);
@@ -48,9 +51,10 @@ describe("Settings Controller - getAppSettings", () => {
});
});
describe("Settings Controller - updateAppSettings", () => {
describe("Settings Controller - updateAppSettings", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
headers: {},
params: {},
@@ -68,28 +72,33 @@ describe("Settings Controller - updateAppSettings", () => {
};
next = sinon.stub();
});
afterEach(() => {
sinon.restore();
});
it("should reject with an error if body validation fails", async () => {
it("should reject with an error if body validation fails", async function() {
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 () => {
it("should reject with an error if updateAppSettings throws an error", async function() {
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 () => {
it("should reject with an error if reloadSettings throws an error", async function() {
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 () => {
it("should return a success message and data if updateAppSettings is successful", async function() {
const data = { data: "settings" };
req.settingsService.reloadSettings.returns(data);
await updateAppSettings(req, res, next);

View File

@@ -4,9 +4,10 @@ import {
getStatusPageByUrl,
} from "../../controllers/statusPageController.js";
describe("statusPageController", () => {
describe("statusPageController", function() {
let req, res, next;
beforeEach(() => {
beforeEach(function() {
req = {
params: {},
body: {},
@@ -22,12 +23,12 @@ describe("statusPageController", () => {
next = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createStatusPage", () => {
beforeEach(() => {
describe("createStatusPage", function() {
beforeEach(function() {
req.body = {
companyName: "Test Company",
url: "123456",
@@ -38,11 +39,11 @@ describe("statusPageController", () => {
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should handle a validation error", async () => {
it("should handle a validation error", async function() {
req.body = {
// Invalid data that will trigger validation error
companyName: "",
@@ -60,7 +61,7 @@ describe("statusPageController", () => {
}
});
it("should handle a db error", async () => {
it("should handle a db error", async function() {
const err = new Error("DB error");
req.db.createStatusPage.throws(err);
@@ -71,24 +72,25 @@ describe("statusPageController", () => {
}
});
it("should insert a properly formatted status page", async () => {
it("should insert a properly formatted status page", async function() {
const result = await createStatusPage(req, res, next);
expect(res.status.firstCall.args[0]).to.equal(200);
expect(res.json.firstCall.args[0].success).to.be.true;
});
});
describe("getStatusPageByUrl", () => {
beforeEach(() => {
describe("getStatusPageByUrl", function() {
beforeEach(function() {
req.params = {
url: "123456",
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should handle a validation error", async () => {
it("should handle a validation error", async function() {
req.params = {
url: "",
};
@@ -101,7 +103,7 @@ describe("statusPageController", () => {
}
});
it("should handle a DB error", async () => {
it("should handle a DB error", async function() {
const err = new Error("DB error");
req.db.getStatusPageByUrl.throws(err);
@@ -112,7 +114,7 @@ describe("statusPageController", () => {
}
});
it("should return a status page", async () => {
it("should return a status page", async function() {
const statusPage = {
_id: "123456",
companyName: "Test Company",

View File

@@ -13,8 +13,8 @@ import Monitor from "../../db/models/Monitor.js";
import User from "../../db/models/User.js";
import logger from "../../utils/logger.js";
describe("checkModule", () => {
describe("createCheck", () => {
describe("checkModule", function() {
describe("createCheck", function() {
let checkCountDocumentsStub, checkSaveStub, monitorFindByIdStub, monitorSaveStub;
const mockMonitor = {
_id: "123",
@@ -23,31 +23,33 @@ describe("checkModule", () => {
save: () => this,
};
const mockCheck = { active: true };
beforeEach(() => {
beforeEach(function() {
checkSaveStub = sinon.stub(Check.prototype, "save");
checkCountDocumentsStub = sinon.stub(Check, "countDocuments");
monitorFindByIdStub = sinon.stub(Monitor, "findById");
monitorSaveStub = sinon.stub(Monitor.prototype, "save");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return undefined early if no monitor is found", async () => {
it("should return undefined early if no monitor is found", async function() {
monitorFindByIdStub.returns(null);
const check = await createCheck({ monitorId: "123" });
expect(check).to.be.undefined;
});
it("should return a check", async () => {
it("should return a check", async function() {
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
monitorSaveStub.returns(mockMonitor);
const check = await createCheck({ monitorId: "123", status: true });
expect(check).to.deep.equal(mockCheck);
});
it("should return a check if status is down", async () => {
it("should return a check if status is down", async function() {
mockMonitor.status = false;
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
@@ -55,7 +57,8 @@ describe("checkModule", () => {
const check = await createCheck({ monitorId: "123", status: false });
expect(check).to.deep.equal(mockCheck);
});
it("should return a check if uptimePercentage is undefined", async () => {
it("should return a check if uptimePercentage is undefined", async function() {
mockMonitor.uptimePercentage = undefined;
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
@@ -63,7 +66,8 @@ describe("checkModule", () => {
const check = await createCheck({ monitorId: "123", status: true });
expect(check).to.deep.equal(mockCheck);
});
it("should return a check if uptimePercentage is undefined and status is down", async () => {
it("should return a check if uptimePercentage is undefined and status is down", async function() {
mockMonitor.uptimePercentage = undefined;
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
@@ -71,7 +75,8 @@ describe("checkModule", () => {
const check = await createCheck({ monitorId: "123", status: false });
expect(check).to.deep.equal(mockCheck);
});
it("should monitor save error", async () => {
it("should monitor save error", async function() {
const err = new Error("Save Error");
monitorSaveStub.throws(err);
try {
@@ -80,7 +85,8 @@ describe("checkModule", () => {
expect(error).to.deep.equal(err);
}
});
it("should handle errors", async () => {
it("should handle errors", async function() {
const err = new Error("DB Error");
checkCountDocumentsStub.throws(err);
try {
@@ -90,18 +96,19 @@ describe("checkModule", () => {
}
});
});
describe("getChecksCount", () => {
describe("getChecksCount", function() {
let checkCountDocumentStub;
beforeEach(() => {
beforeEach(function() {
checkCountDocumentStub = sinon.stub(Check, "countDocuments");
});
afterEach(() => {
afterEach(function() {
checkCountDocumentStub.restore();
});
it("should return count with basic monitorId query", async () => {
it("should return count with basic monitorId query", async function() {
const req = {
params: { monitorId: "test123" },
query: {},
@@ -117,7 +124,7 @@ describe("checkModule", () => {
});
});
it("should include dateRange in query when provided", async () => {
it("should include dateRange in query when provided", async function() {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "day" },
@@ -131,7 +138,7 @@ describe("checkModule", () => {
expect(checkCountDocumentStub.firstCall.args[0].createdAt).to.have.property("$gte");
});
it('should handle "all" filter correctly', async () => {
it('should handle "all" filter correctly', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
@@ -147,7 +154,7 @@ describe("checkModule", () => {
});
});
it('should handle "down" filter correctly', async () => {
it('should handle "down" filter correctly', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
@@ -163,7 +170,7 @@ describe("checkModule", () => {
});
});
it('should handle "resolve" filter correctly', async () => {
it('should handle "resolve" filter correctly', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
@@ -179,7 +186,8 @@ describe("checkModule", () => {
statusCode: 5000,
});
});
it("should handle unknown filter correctly", async () => {
it("should handle unknown filter correctly", async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
@@ -195,7 +203,7 @@ describe("checkModule", () => {
});
});
it("should combine dateRange and filter in query", async () => {
it("should combine dateRange and filter in query", async function() {
const req = {
params: { monitorId: "test123" },
query: {
@@ -215,10 +223,11 @@ describe("checkModule", () => {
);
});
});
describe("getChecks", () => {
describe("getChecks", function() {
let checkFindStub, monitorFindStub;
beforeEach(() => {
beforeEach(function() {
checkFindStub = sinon.stub(Check, "find").returns({
skip: sinon.stub().returns({
limit: sinon.stub().returns({
@@ -228,11 +237,11 @@ describe("checkModule", () => {
});
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return checks with basic monitorId query", async () => {
it("should return checks with basic monitorId query", async function() {
const req = {
params: { monitorId: "test123" },
query: {},
@@ -242,7 +251,8 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should return checks with limit query", async () => {
it("should return checks with limit query", async function() {
const req = {
params: { monitorId: "test123" },
query: { limit: 10 },
@@ -253,7 +263,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle pagination correctly", async () => {
it("should handle pagination correctly", async function() {
const req = {
params: { monitorId: "test123" },
query: {
@@ -267,7 +277,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle dateRange filter", async () => {
it("should handle dateRange filter", async function() {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "week" },
@@ -277,7 +287,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "all" filter', async () => {
it('should handle "all" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
@@ -287,7 +297,8 @@ describe("checkModule", () => {
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "down" filter', async () => {
it('should handle "down" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
@@ -298,7 +309,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "resolve" filter', async () => {
it('should handle "resolve" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
@@ -308,7 +319,8 @@ describe("checkModule", () => {
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "unknown" filter', async () => {
it('should handle "unknown" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
@@ -319,7 +331,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle ascending sort order", async () => {
it("should handle ascending sort order", async function() {
const req = {
params: { monitorId: "test123" },
query: { sortOrder: "asc" },
@@ -330,7 +342,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle error case", async () => {
it("should handle error case", async function() {
const req = {
params: { monitorId: "test123" },
query: {},
@@ -347,10 +359,12 @@ describe("checkModule", () => {
}
});
});
describe("getTeamChecks", () => {
describe("getTeamChecks", function() {
let checkFindStub, checkCountDocumentsStub, monitorFindStub;
const mockMonitors = [{ _id: "123" }];
beforeEach(() => {
beforeEach(function() {
monitorFindStub = sinon.stub(Monitor, "find").returns({
select: sinon.stub().returns(mockMonitors),
});
@@ -366,11 +380,11 @@ describe("checkModule", () => {
});
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return checks with basic monitorId query", async () => {
it("should return checks with basic monitorId query", async function() {
const req = {
params: { teamId: "test123" },
query: {},
@@ -380,7 +394,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle pagination correctly", async () => {
it("should handle pagination correctly", async function() {
const req = {
params: { monitorId: "test123" },
query: { limit: 1, page: 2, rowsPerPage: 10 },
@@ -390,7 +404,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle dateRange filter", async () => {
it("should handle dateRange filter", async function() {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "week" },
@@ -399,7 +413,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "all" filter', async () => {
it('should handle "all" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
@@ -409,7 +423,8 @@ describe("checkModule", () => {
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "down" filter', async () => {
it('should handle "down" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
@@ -420,7 +435,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "resolve" filter', async () => {
it('should handle "resolve" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
@@ -430,7 +445,8 @@ describe("checkModule", () => {
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "unknown" filter', async () => {
it('should handle "unknown" filter', async function() {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
@@ -441,7 +457,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle ascending sort order", async () => {
it("should handle ascending sort order", async function() {
const req = {
params: { monitorId: "test123" },
query: { sortOrder: "asc" },
@@ -452,7 +468,7 @@ describe("checkModule", () => {
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle error case", async () => {
it("should handle error case", async function() {
const req = {
params: { monitorId: "test123" },
query: {},
@@ -469,20 +485,24 @@ describe("checkModule", () => {
}
});
});
describe("deleteChecks", () => {
describe("deleteChecks", function() {
let checkDeleteManyStub;
beforeEach(() => {
beforeEach(function() {
checkDeleteManyStub = sinon.stub(Check, "deleteMany").resolves({ deletedCount: 1 });
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return a value if a check is deleted", async () => {
it("should return a value if a check is deleted", async function() {
const result = await deleteChecks("123");
expect(result).to.equal(1);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
checkDeleteManyStub.throws(new Error("Database error"));
try {
await deleteChecks("123");
@@ -492,22 +512,27 @@ describe("checkModule", () => {
}
});
});
describe("deleteChecksByTeamId", () => {
describe("deleteChecksByTeamId", function() {
let mockMonitors = [{ _id: 123, save: () => this }];
let monitorFindStub, monitorSaveStub, checkDeleteManyStub;
beforeEach(() => {
beforeEach(function() {
monitorSaveStub = sinon.stub(Monitor.prototype, "save");
monitorFindStub = sinon.stub(Monitor, "find").returns(mockMonitors);
checkDeleteManyStub = sinon.stub(Check, "deleteMany").resolves({ deletedCount: 1 });
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return a deleted count", async () => {
it("should return a deleted count", async function() {
const result = await deleteChecksByTeamId("123");
expect(result).to.equal(1);
});
it("should handle errors", async () => {
it("should handle errors", async function() {
const err = new Error("DB Error");
monitorFindStub.throws(err);
try {
@@ -517,25 +542,27 @@ describe("checkModule", () => {
}
});
});
describe("updateChecksTTL", () => {
describe("updateChecksTTL", function() {
let userUpdateManyStub;
let loggerStub;
beforeEach(() => {
beforeEach(function() {
loggerStub = sinon.stub(logger, "error");
userUpdateManyStub = sinon.stub(User, "updateMany");
Check.collection = { dropIndex: sinon.stub(), createIndex: sinon.stub() };
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return undefined", async () => {
it("should return undefined", async function() {
const result = await updateChecksTTL("123", 10);
expect(result).to.be.undefined;
});
it("should log an error if dropIndex throws an error", async () => {
it("should log an error if dropIndex throws an error", async function() {
const err = new Error("Drop Index Error");
Check.collection.dropIndex.throws(err);
await updateChecksTTL("123", 10);
@@ -543,7 +570,7 @@ describe("checkModule", () => {
expect(loggerStub.firstCall.args[0].message).to.equal(err.message);
});
it("should throw an error if createIndex throws an error", async () => {
it("should throw an error if createIndex throws an error", async function() {
const err = new Error("Create Index Error");
Check.collection.createIndex.throws(err);
try {
@@ -552,7 +579,8 @@ describe("checkModule", () => {
expect(error).to.deep.equal(err);
}
});
it("should throw an error if User.updateMany throws an error", async () => {
it("should throw an error if User.updateMany throws an error", async function() {
const err = new Error("Update Many Error");
userUpdateManyStub.throws(err);
try {

View File

@@ -51,24 +51,25 @@ const mockMonitor = {
save: () => this,
};
describe("HardwareCheckModule", () => {
describe("HardwareCheckModule", function() {
let hardwareCheckSaveStub,
hardwareCheckCountDocumentsStub,
monitorFindByIdStub,
loggerStub;
beforeEach(() => {
beforeEach(function() {
loggerStub = sinon.stub(logger, "error");
hardwareCheckSaveStub = sinon.stub(HardwareCheck.prototype, "save");
monitorFindByIdStub = sinon.stub(Monitor, "findById");
hardwareCheckCountDocumentsStub = sinon.stub(HardwareCheck, "countDocuments");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createHardwareCheck", () => {
it("should return a hardware check", async () => {
describe("createHardwareCheck", function() {
it("should return a hardware check", async function() {
hardwareCheckSaveStub.resolves(mockHardwareCheck);
monitorFindByIdStub.resolves(mockMonitor);
hardwareCheckCountDocumentsStub.resolves(1);
@@ -76,7 +77,8 @@ describe("HardwareCheckModule", () => {
expect(hardwareCheck).to.exist;
expect(hardwareCheck).to.deep.equal(mockHardwareCheck);
});
it("should return a hardware check for a check with status false", async () => {
it("should return a hardware check for a check with status false", async function() {
hardwareCheckSaveStub.resolves(mockHardwareCheck);
monitorFindByIdStub.resolves(mockMonitor);
hardwareCheckCountDocumentsStub.resolves(1);
@@ -84,7 +86,8 @@ describe("HardwareCheckModule", () => {
expect(hardwareCheck).to.exist;
expect(hardwareCheck).to.deep.equal(mockHardwareCheck);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
monitorFindByIdStub.resolves(mockMonitor);
hardwareCheckSaveStub.rejects(err);
@@ -95,20 +98,23 @@ describe("HardwareCheckModule", () => {
expect(error).to.deep.equal(err);
}
});
it("should log an error if a monitor is not found", async () => {
it("should log an error if a monitor is not found", async function() {
monitorFindByIdStub.resolves(null);
const res = await createHardwareCheck({});
expect(loggerStub.calledOnce).to.be.true;
expect(res).to.be.null;
});
it("should handle a monitor with undefined uptimePercentage", async () => {
it("should handle a monitor with undefined uptimePercentage", async function() {
monitorFindByIdStub.resolves({ ...mockMonitor, uptimePercentage: undefined });
hardwareCheckSaveStub.resolves(mockHardwareCheck);
hardwareCheckCountDocumentsStub.resolves(1);
const res = await createHardwareCheck({});
expect(res).to.exist;
});
it("should handle a monitor with undefined uptimePercentage and true status", async () => {
it("should handle a monitor with undefined uptimePercentage and true status", async function() {
monitorFindByIdStub.resolves({
...mockMonitor,
uptimePercentage: undefined,
@@ -118,7 +124,8 @@ describe("HardwareCheckModule", () => {
const res = await createHardwareCheck({ status: true });
expect(res).to.exist;
});
it("should handle a monitor with undefined uptimePercentage and false status", async () => {
it("should handle a monitor with undefined uptimePercentage and false status", async function() {
monitorFindByIdStub.resolves({
...mockMonitor,
uptimePercentage: undefined,

View File

@@ -7,7 +7,7 @@ import {
} from "../../db/mongo/modules/inviteModule.js";
import { errorMessages } from "../../utils/messages.js";
describe("Invite Module", () => {
describe("Invite Module", function() {
const mockUserData = {
email: "test@test.com",
teamId: "123",
@@ -19,18 +19,20 @@ describe("Invite Module", () => {
inviteTokenSaveStub,
inviteTokenFindOneStub,
inviteTokenFindOneAndDeleteStub;
beforeEach(() => {
beforeEach(function() {
inviteTokenDeleteManyStub = sinon.stub(InviteToken, "deleteMany");
inviteTokenSaveStub = sinon.stub(InviteToken.prototype, "save");
inviteTokenFindOneStub = sinon.stub(InviteToken, "findOne");
inviteTokenFindOneAndDeleteStub = sinon.stub(InviteToken, "findOneAndDelete");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("requestInviteToken", () => {
it("should return a new invite token", async () => {
describe("requestInviteToken", function() {
it("should return a new invite token", async function() {
inviteTokenDeleteManyStub.resolves();
inviteTokenSaveStub.resolves();
const inviteToken = await requestInviteToken(mockUserData);
@@ -39,7 +41,7 @@ describe("Invite Module", () => {
expect(inviteToken.token).to.exist;
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
inviteTokenDeleteManyStub.rejects(err);
try {
@@ -50,14 +52,14 @@ describe("Invite Module", () => {
});
});
describe("getInviteToken", () => {
it("should return an invite token", async () => {
describe("getInviteToken", function() {
it("should return an invite token", async function() {
inviteTokenFindOneStub.resolves(mockInviteToken);
const inviteToken = await getInviteToken(mockUserData.token);
expect(inviteToken).to.deep.equal(mockInviteToken);
});
it("should handle a token not found", async () => {
it("should handle a token not found", async function() {
inviteTokenFindOneStub.resolves(null);
try {
await getInviteToken(mockUserData.token);
@@ -66,7 +68,7 @@ describe("Invite Module", () => {
}
});
it("should handle DB errors", async () => {
it("should handle DB errors", async function() {
const err = new Error("test error");
inviteTokenFindOneStub.rejects(err);
try {
@@ -78,14 +80,14 @@ describe("Invite Module", () => {
});
});
describe("getInviteTokenAndDelete", () => {
it("should return a deleted invite", async () => {
describe("getInviteTokenAndDelete", function() {
it("should return a deleted invite", async function() {
inviteTokenFindOneAndDeleteStub.resolves(mockInviteToken);
const deletedInvite = await getInviteTokenAndDelete(mockUserData.token);
expect(deletedInvite).to.deep.equal(mockInviteToken);
});
it("should handle a token not found", async () => {
it("should handle a token not found", async function() {
inviteTokenFindOneAndDeleteStub.resolves(null);
try {
await getInviteTokenAndDelete(mockUserData.token);
@@ -94,7 +96,7 @@ describe("Invite Module", () => {
}
});
it("should handle DB errors", async () => {
it("should handle DB errors", async function() {
const err = new Error("test error");
inviteTokenFindOneAndDeleteStub.rejects(err);
try {

View File

@@ -11,7 +11,7 @@ import {
editMaintenanceWindowById,
} from "../../db/mongo/modules/maintenanceWindowModule.js";
describe("MaintenanceWindow Module", () => {
describe("MaintenanceWindow Module", function() {
const mockMaintenanceWindow = {
monitorId: "123",
active: true,
@@ -29,7 +29,7 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowDeleteManyStub,
maintenanceWindowFindByIdAndUpdateStub;
beforeEach(() => {
beforeEach(function() {
maintenanceWindowSaveStub = sinon.stub(MaintenanceWindow.prototype, "save");
maintenanceWindowFindByIdStub = sinon.stub(MaintenanceWindow, "findById");
maintenanceWindowCountDocumentsStub = sinon.stub(MaintenanceWindow, "countDocuments");
@@ -51,18 +51,18 @@ describe("MaintenanceWindow Module", () => {
);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createMaintenanceWindow", () => {
it("should save a new maintenance window", async () => {
describe("createMaintenanceWindow", function() {
it("should save a new maintenance window", async function() {
maintenanceWindowSaveStub.resolves(mockMaintenanceWindow);
const result = await createMaintenanceWindow(mockMaintenanceWindow);
expect(result).to.deep.equal(mockMaintenanceWindow);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowSaveStub.rejects(err);
try {
@@ -72,13 +72,15 @@ describe("MaintenanceWindow Module", () => {
}
});
});
describe("getMaintenanceWindowById", () => {
it("should return a maintenance window", async () => {
describe("getMaintenanceWindowById", function() {
it("should return a maintenance window", async function() {
maintenanceWindowFindByIdStub.resolves(mockMaintenanceWindow);
const result = await getMaintenanceWindowById(mockMaintenanceWindow.id);
expect(result).to.deep.equal(mockMaintenanceWindow);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowFindByIdStub.rejects(err);
try {
@@ -89,9 +91,10 @@ describe("MaintenanceWindow Module", () => {
});
});
describe("getMaintenanceWindowsByTeamId", () => {
describe("getMaintenanceWindowsByTeamId", function() {
let query;
beforeEach(() => {
beforeEach(function() {
query = {
active: true,
page: 1,
@@ -101,11 +104,11 @@ describe("MaintenanceWindow Module", () => {
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return a list of maintenance windows and count", async () => {
it("should return a list of maintenance windows and count", async function() {
maintenanceWindowCountDocumentsStub.resolves(1);
const result = await getMaintenanceWindowsByTeamId(
mockMaintenanceWindow.teamId,
@@ -116,7 +119,8 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowCount: 1,
});
});
it("should return a list of maintenance windows and count with empty query", async () => {
it("should return a list of maintenance windows and count with empty query", async function() {
query = undefined;
maintenanceWindowCountDocumentsStub.resolves(1);
const result = await getMaintenanceWindowsByTeamId(
@@ -128,7 +132,8 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowCount: 1,
});
});
it("should return a list of maintenance windows and count with no pagination provided", async () => {
it("should return a list of maintenance windows and count with no pagination provided", async function() {
query.page = undefined;
query.rowsPerPage = undefined;
maintenanceWindowCountDocumentsStub.resolves(1);
@@ -141,7 +146,8 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowCount: 1,
});
});
it("should return a list of maintenance windows and count with field and desc order", async () => {
it("should return a list of maintenance windows and count with field and desc order", async function() {
query.order = "desc";
maintenanceWindowCountDocumentsStub.resolves(1);
const result = await getMaintenanceWindowsByTeamId(
@@ -153,7 +159,8 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowCount: 1,
});
});
it("should return a list of maintenance windows and count no field", async () => {
it("should return a list of maintenance windows and count no field", async function() {
query.field = undefined;
maintenanceWindowCountDocumentsStub.resolves(1);
const result = await getMaintenanceWindowsByTeamId(
@@ -165,7 +172,8 @@ describe("MaintenanceWindow Module", () => {
maintenanceWindowCount: 1,
});
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowCountDocumentsStub.rejects(err);
try {
@@ -175,15 +183,17 @@ describe("MaintenanceWindow Module", () => {
}
});
});
describe("getMaintenanceWindowsByMonitorId", () => {
it("should return a list of maintenance windows", async () => {
describe("getMaintenanceWindowsByMonitorId", function() {
it("should return a list of maintenance windows", async function() {
maintenanceWindowFindStub.resolves(mockMaintenanceWindows);
const result = await getMaintenanceWindowsByMonitorId(
mockMaintenanceWindow.monitorId
);
expect(result).to.deep.equal(mockMaintenanceWindows);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowFindStub.rejects(err);
try {
@@ -193,13 +203,15 @@ describe("MaintenanceWindow Module", () => {
}
});
});
describe("deleteMaintenanceWindowById", () => {
it("should delete a maintenance window", async () => {
describe("deleteMaintenanceWindowById", function() {
it("should delete a maintenance window", async function() {
maintenanceWindowFindByIdAndDeleteStub.resolves(mockMaintenanceWindow);
const result = await deleteMaintenanceWindowById(mockMaintenanceWindow.id);
expect(result).to.deep.equal(mockMaintenanceWindow);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowFindByIdAndDeleteStub.rejects(err);
try {
@@ -210,15 +222,16 @@ describe("MaintenanceWindow Module", () => {
});
});
describe("deleteMaintenanceWindowByMonitorId", () => {
it("should return the number of documents deleted", async () => {
describe("deleteMaintenanceWindowByMonitorId", function() {
it("should return the number of documents deleted", async function() {
maintenanceWindowDeleteManyStub.resolves({ deletedCount: 1 });
const result = await deleteMaintenanceWindowByMonitorId(
mockMaintenanceWindow.monitorId
);
expect(result).to.deep.equal({ deletedCount: 1 });
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowDeleteManyStub.rejects(err);
try {
@@ -229,13 +242,14 @@ describe("MaintenanceWindow Module", () => {
});
});
describe("deleteMaintenanceWindowByUserId", () => {
it("should return the number of documents deleted", async () => {
describe("deleteMaintenanceWindowByUserId", function() {
it("should return the number of documents deleted", async function() {
maintenanceWindowDeleteManyStub.resolves({ deletedCount: 1 });
const result = await deleteMaintenanceWindowByUserId(mockMaintenanceWindow.userId);
expect(result).to.deep.equal({ deletedCount: 1 });
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowDeleteManyStub.rejects(err);
try {
@@ -245,8 +259,9 @@ describe("MaintenanceWindow Module", () => {
}
});
});
describe("editMaintenanceWindowById", () => {
it("should return the updated maintenance window", async () => {
describe("editMaintenanceWindowById", function() {
it("should return the updated maintenance window", async function() {
maintenanceWindowFindByIdAndUpdateStub.resolves(mockMaintenanceWindow);
const result = await editMaintenanceWindowById(
mockMaintenanceWindow.id,
@@ -254,7 +269,8 @@ describe("MaintenanceWindow Module", () => {
);
expect(result).to.deep.equal(mockMaintenanceWindow);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
maintenanceWindowFindByIdAndUpdateStub.rejects(err);
try {

View File

@@ -31,7 +31,7 @@ import {
calculateGroupStats,
} from "../../db/mongo/modules/monitorModule.js";
describe("monitorModule", () => {
describe("monitorModule", function() {
let monitorFindStub,
monitorFindByIdStub,
monitorFindByIdAndUpdateStub,
@@ -42,7 +42,8 @@ describe("monitorModule", () => {
checkFindStub,
pageSpeedCheckFindStub,
hardwareCheckFindStub;
beforeEach(() => {
beforeEach(function() {
monitorFindStub = sinon.stub(Monitor, "find");
monitorFindByIdStub = sinon.stub(Monitor, "findById");
monitorFindByIdAndUpdateStub = sinon.stub(Monitor, "findByIdAndUpdate");
@@ -61,12 +62,13 @@ describe("monitorModule", () => {
sort: sinon.stub(),
});
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("getAllMonitors", () => {
it("should return all monitors", async () => {
describe("getAllMonitors", function() {
it("should return all monitors", async function() {
const mockMonitors = [
{ _id: "1", name: "Monitor 1", url: "test1.com" },
{ _id: "2", name: "Monitor 2", url: "test2.com" },
@@ -78,12 +80,14 @@ describe("monitorModule", () => {
expect(monitorFindStub.calledOnce).to.be.true;
expect(monitorFindStub.firstCall.args).to.deep.equal([]);
});
it("should handle empty results", async () => {
it("should handle empty results", async function() {
monitorFindStub.returns([]);
const result = await getAllMonitors();
expect(result).to.be.an("array").that.is.empty;
});
it("should throw error when database fails", async () => {
it("should throw error when database fails", async function() {
// Arrange
const error = new Error("Database error");
error.service = "MonitorModule";
@@ -101,8 +105,8 @@ describe("monitorModule", () => {
});
});
describe("getAllMonitorsWithUptimeStats", () => {
it("should return monitors with uptime stats for different time periods", async () => {
describe("getAllMonitorsWithUptimeStats", function() {
it("should return monitors with uptime stats for different time periods", async function() {
// Mock data
const mockMonitors = [
{
@@ -147,7 +151,8 @@ describe("monitorModule", () => {
expect(monitor["30"]).to.equal(75);
expect(monitor["90"]).to.equal(75);
});
it("should return monitors with stats for pagespeed type", async () => {
it("should return monitors with stats for pagespeed type", async function() {
// Mock data
const mockMonitors = [
{
@@ -192,7 +197,8 @@ describe("monitorModule", () => {
expect(monitor["30"]).to.equal(75);
expect(monitor["90"]).to.equal(75);
});
it("should return monitors with stats for hardware type", async () => {
it("should return monitors with stats for hardware type", async function() {
// Mock data
const mockMonitors = [
{
@@ -238,7 +244,7 @@ describe("monitorModule", () => {
expect(monitor["90"]).to.equal(75);
});
it("should handle errors appropriately", async () => {
it("should handle errors appropriately", async function() {
// Setup stub to throw error
monitorFindStub.rejects(new Error("Database error"));
@@ -251,7 +257,8 @@ describe("monitorModule", () => {
expect(error.method).to.equal("getAllMonitorsWithUptimeStats");
}
});
it("should handle empty monitor list", async () => {
it("should handle empty monitor list", async function() {
monitorFindStub.resolves([]);
const result = await getAllMonitorsWithUptimeStats();
@@ -260,7 +267,7 @@ describe("monitorModule", () => {
expect(result).to.have.lengthOf(0);
});
it("should handle monitor with no checks", async () => {
it("should handle monitor with no checks", async function() {
const mockMonitors = [
{
_id: "monitor1",
@@ -285,28 +292,28 @@ describe("monitorModule", () => {
});
});
describe("calculateUptimeDuration", () => {
describe("calculateUptimeDuration", function() {
let clock;
const NOW = new Date("2024-01-01T12:00:00Z").getTime();
beforeEach(() => {
beforeEach(function() {
// Fix the current time
clock = sinon.useFakeTimers(NOW);
});
afterEach(() => {
afterEach(function() {
clock.restore();
});
it("should return 0 when checks array is empty", () => {
it("should return 0 when checks array is empty", function() {
expect(calculateUptimeDuration([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(calculateUptimeDuration(null)).to.equal(0);
});
it("should calculate uptime from last down check to most recent check", () => {
it("should calculate uptime from last down check to most recent check", function() {
const checks = [
{ status: true, createdAt: "2024-01-01T11:00:00Z" }, // Most recent
{ status: true, createdAt: "2024-01-01T10:00:00Z" },
@@ -318,7 +325,7 @@ describe("monitorModule", () => {
expect(calculateUptimeDuration(checks)).to.equal(7200000);
});
it("should calculate uptime from first check when no down checks exist", () => {
it("should calculate uptime from first check when no down checks exist", function() {
const checks = [
{ status: true, createdAt: "2024-01-01T11:00:00Z" },
{ status: true, createdAt: "2024-01-01T10:00:00Z" },
@@ -330,28 +337,28 @@ describe("monitorModule", () => {
});
});
describe("getLastChecked", () => {
describe("getLastChecked", function() {
let clock;
const NOW = new Date("2024-01-01T12:00:00Z").getTime();
beforeEach(() => {
beforeEach(function() {
// Fix the current time
clock = sinon.useFakeTimers(NOW);
});
afterEach(() => {
afterEach(function() {
clock.restore();
});
it("should return 0 when checks array is empty", () => {
it("should return 0 when checks array is empty", function() {
expect(getLastChecked([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(getLastChecked(null)).to.equal(0);
});
it("should return time difference between now and most recent check", () => {
it("should return time difference between now and most recent check", function() {
const checks = [
{ createdAt: "2024-01-01T11:30:00Z" }, // 30 minutes ago
{ createdAt: "2024-01-01T11:00:00Z" },
@@ -362,7 +369,7 @@ describe("monitorModule", () => {
expect(getLastChecked(checks)).to.equal(1800000);
});
it("should handle checks from different days", () => {
it("should handle checks from different days", function() {
const checks = [
{ createdAt: "2023-12-31T12:00:00Z" }, // 24 hours ago
{ createdAt: "2023-12-30T12:00:00Z" },
@@ -372,16 +379,17 @@ describe("monitorModule", () => {
expect(getLastChecked(checks)).to.equal(86400000);
});
});
describe("getLatestResponseTime", () => {
it("should return 0 when checks array is empty", () => {
describe("getLatestResponseTime", function() {
it("should return 0 when checks array is empty", function() {
expect(getLatestResponseTime([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(getLatestResponseTime(null)).to.equal(0);
});
it("should return response time from most recent check", () => {
it("should return response time from most recent check", function() {
const checks = [
{ responseTime: 150, createdAt: "2024-01-01T11:30:00Z" }, // Most recent
{ responseTime: 200, createdAt: "2024-01-01T11:00:00Z" },
@@ -391,7 +399,7 @@ describe("monitorModule", () => {
expect(getLatestResponseTime(checks)).to.equal(150);
});
it("should handle missing responseTime in checks", () => {
it("should handle missing responseTime in checks", function() {
const checks = [
{ createdAt: "2024-01-01T11:30:00Z" },
{ responseTime: 200, createdAt: "2024-01-01T11:00:00Z" },
@@ -400,16 +408,17 @@ describe("monitorModule", () => {
expect(getLatestResponseTime(checks)).to.equal(0);
});
});
describe("getAverageResponseTime", () => {
it("should return 0 when checks array is empty", () => {
describe("getAverageResponseTime", function() {
it("should return 0 when checks array is empty", function() {
expect(getAverageResponseTime([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(getAverageResponseTime(null)).to.equal(0);
});
it("should calculate average response time from all checks", () => {
it("should calculate average response time from all checks", function() {
const checks = [
{ responseTime: 100, createdAt: "2024-01-01T11:30:00Z" },
{ responseTime: 200, createdAt: "2024-01-01T11:00:00Z" },
@@ -420,7 +429,7 @@ describe("monitorModule", () => {
expect(getAverageResponseTime(checks)).to.equal(200);
});
it("should handle missing responseTime in some checks", () => {
it("should handle missing responseTime in some checks", function() {
const checks = [
{ responseTime: 100, createdAt: "2024-01-01T11:30:00Z" },
{ createdAt: "2024-01-01T11:00:00Z" },
@@ -431,7 +440,7 @@ describe("monitorModule", () => {
expect(getAverageResponseTime(checks)).to.equal(200);
});
it("should return 0 when no checks have responseTime", () => {
it("should return 0 when no checks have responseTime", function() {
const checks = [
{ createdAt: "2024-01-01T11:30:00Z" },
{ createdAt: "2024-01-01T11:00:00Z" },
@@ -440,26 +449,27 @@ describe("monitorModule", () => {
expect(getAverageResponseTime(checks)).to.equal(0);
});
});
describe("getUptimePercentage", () => {
it("should return 0 when checks array is empty", () => {
describe("getUptimePercentage", function() {
it("should return 0 when checks array is empty", function() {
expect(getUptimePercentage([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(getUptimePercentage(null)).to.equal(0);
});
it("should return 100 when all checks are up", () => {
it("should return 100 when all checks are up", function() {
const checks = [{ status: true }, { status: true }, { status: true }];
expect(getUptimePercentage(checks)).to.equal(100);
});
it("should return 0 when all checks are down", () => {
it("should return 0 when all checks are down", function() {
const checks = [{ status: false }, { status: false }, { status: false }];
expect(getUptimePercentage(checks)).to.equal(0);
});
it("should calculate correct percentage for mixed status checks", () => {
it("should calculate correct percentage for mixed status checks", function() {
const checks = [
{ status: true },
{ status: false },
@@ -470,32 +480,33 @@ describe("monitorModule", () => {
expect(getUptimePercentage(checks)).to.equal(75);
});
it("should handle undefined status values", () => {
it("should handle undefined status values", function() {
const checks = [{ status: true }, { status: undefined }, { status: true }];
// 2 up out of 3 total ≈ 66.67%
expect(getUptimePercentage(checks)).to.equal((2 / 3) * 100);
});
});
describe("getIncidents", () => {
it("should return 0 when checks array is empty", () => {
describe("getIncidents", function() {
it("should return 0 when checks array is empty", function() {
expect(getIncidents([])).to.equal(0);
});
it("should return 0 when checks array is null", () => {
it("should return 0 when checks array is null", function() {
expect(getIncidents(null)).to.equal(0);
});
it("should return 0 when all checks are up", () => {
it("should return 0 when all checks are up", function() {
const checks = [{ status: true }, { status: true }, { status: true }];
expect(getIncidents(checks)).to.equal(0);
});
it("should count all incidents when all checks are down", () => {
it("should count all incidents when all checks are down", function() {
const checks = [{ status: false }, { status: false }, { status: false }];
expect(getIncidents(checks)).to.equal(3);
});
it("should count correct number of incidents for mixed status checks", () => {
it("should count correct number of incidents for mixed status checks", function() {
const checks = [
{ status: true },
{ status: false },
@@ -506,7 +517,7 @@ describe("monitorModule", () => {
expect(getIncidents(checks)).to.equal(2);
});
it("should handle undefined status values", () => {
it("should handle undefined status values", function() {
const checks = [
{ status: true },
{ status: undefined },
@@ -517,10 +528,11 @@ describe("monitorModule", () => {
expect(getIncidents(checks)).to.equal(2);
});
});
describe("getMonitorChecks", () => {
describe("getMonitorChecks", function() {
let mockModel;
beforeEach(() => {
beforeEach(function() {
// Create a mock model with chainable methods
const mockChecks = [
{ monitorId: "123", createdAt: new Date("2024-01-01") },
@@ -534,11 +546,11 @@ describe("monitorModule", () => {
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return all checks and date-ranged checks", async () => {
it("should return all checks and date-ranged checks", async function() {
// Arrange
const monitorId = "123";
const dateRange = {
@@ -567,7 +579,7 @@ describe("monitorModule", () => {
});
});
it("should handle empty results", async () => {
it("should handle empty results", async function() {
// Arrange
const emptyModel = {
find: sinon.stub().returns({
@@ -591,7 +603,7 @@ describe("monitorModule", () => {
expect(result.checksForDateRange).to.be.an("array").that.is.empty;
});
it("should maintain sort order", async () => {
it("should maintain sort order", async function() {
// Arrange
const sortedChecks = [
{ monitorId: "123", createdAt: new Date("2024-01-02") },
@@ -625,39 +637,39 @@ describe("monitorModule", () => {
});
});
describe("processChecksForDisplay", () => {
describe("processChecksForDisplay", function() {
let normalizeStub;
beforeEach(() => {
beforeEach(function() {
normalizeStub = sinon.stub();
});
it("should return original checks when numToDisplay is not provided", () => {
it("should return original checks when numToDisplay is not provided", function() {
const checks = [1, 2, 3, 4, 5];
const result = processChecksForDisplay(normalizeStub, checks);
expect(result).to.deep.equal(checks);
});
it("should return original checks when numToDisplay is greater than checks length", () => {
it("should return original checks when numToDisplay is greater than checks length", function() {
const checks = [1, 2, 3];
const result = processChecksForDisplay(normalizeStub, checks, 5);
expect(result).to.deep.equal(checks);
});
it("should filter checks based on numToDisplay", () => {
it("should filter checks based on numToDisplay", function() {
const checks = [1, 2, 3, 4, 5, 6];
const result = processChecksForDisplay(normalizeStub, checks, 3);
// Should return [1, 3, 5] as n = ceil(6/3) = 2
expect(result).to.deep.equal([1, 3, 5]);
});
it("should handle empty checks array", () => {
it("should handle empty checks array", function() {
const checks = [];
const result = processChecksForDisplay(normalizeStub, checks, 3);
expect(result).to.be.an("array").that.is.empty;
});
it("should call normalizeData when normalize is true", () => {
it("should call normalizeData when normalize is true", function() {
const checks = [1, 2, 3];
normalizeStub.returns([10, 20, 30]);
@@ -667,7 +679,7 @@ describe("monitorModule", () => {
expect(result).to.deep.equal([10, 20, 30]);
});
it("should handle both filtering and normalization", () => {
it("should handle both filtering and normalization", function() {
const checks = [1, 2, 3, 4, 5, 6];
normalizeStub.returns([10, 30, 50]);
@@ -677,7 +689,8 @@ describe("monitorModule", () => {
expect(result).to.deep.equal([10, 30, 50]);
});
});
describe("groupChecksByTime", () => {
describe("groupChecksByTime", function() {
const mockChecks = [
{ createdAt: "2024-01-15T10:30:45Z" },
{ createdAt: "2024-01-15T10:45:15Z" },
@@ -685,7 +698,7 @@ describe("monitorModule", () => {
{ createdAt: "2024-01-16T10:30:00Z" },
];
it("should group checks by hour when dateRange is 'day'", () => {
it("should group checks by hour when dateRange is 'day'", function() {
const result = groupChecksByTime(mockChecks, "day");
// Get timestamps for 10:00 and 11:00 on Jan 15
@@ -700,7 +713,7 @@ describe("monitorModule", () => {
expect(result[time3].checks).to.have.lengthOf(1);
});
it("should group checks by day when dateRange is not 'day'", () => {
it("should group checks by day when dateRange is not 'day'", function() {
const result = groupChecksByTime(mockChecks, "week");
expect(Object.keys(result)).to.have.lengthOf(2);
@@ -708,12 +721,12 @@ describe("monitorModule", () => {
expect(result["2024-01-16"].checks).to.have.lengthOf(1);
});
it("should handle empty checks array", () => {
it("should handle empty checks array", function() {
const result = groupChecksByTime([], "day");
expect(result).to.deep.equal({});
});
it("should handle single check", () => {
it("should handle single check", function() {
const singleCheck = [{ createdAt: "2024-01-15T10:30:45Z" }];
const result = groupChecksByTime(singleCheck, "day");
@@ -721,7 +734,8 @@ describe("monitorModule", () => {
expect(Object.keys(result)).to.have.lengthOf(1);
expect(result[expectedTime].checks).to.have.lengthOf(1);
});
it("should skip invalid dates and process valid ones", () => {
it("should skip invalid dates and process valid ones", function() {
const checksWithInvalidDate = [
{ createdAt: "invalid-date" },
{ createdAt: "2024-01-15T10:30:45Z" },
@@ -737,7 +751,8 @@ describe("monitorModule", () => {
expect(result[expectedTime].checks).to.have.lengthOf(1);
expect(result[expectedTime].checks[0].createdAt).to.equal("2024-01-15T10:30:45Z");
});
it("should handle checks in same time group", () => {
it("should handle checks in same time group", function() {
const checksInSameHour = [
{ createdAt: "2024-01-15T10:15:00Z" },
{ createdAt: "2024-01-15T10:45:00Z" },
@@ -750,16 +765,17 @@ describe("monitorModule", () => {
expect(result[expectedTime].checks).to.have.lengthOf(2);
});
});
describe("calculateGroupStats", () => {
describe("calculateGroupStats", function() {
// Mock getUptimePercentage function
let uptimePercentageStub;
beforeEach(() => {
beforeEach(function() {
uptimePercentageStub = sinon.stub();
uptimePercentageStub.returns(95); // Default return value
});
it("should calculate stats correctly for a group of checks", () => {
it("should calculate stats correctly for a group of checks", function() {
const mockGroup = {
time: "2024-01-15",
checks: [
@@ -780,7 +796,7 @@ describe("monitorModule", () => {
});
});
it("should handle empty checks array", () => {
it("should handle empty checks array", function() {
const mockGroup = {
time: "2024-01-15",
checks: [],
@@ -797,7 +813,7 @@ describe("monitorModule", () => {
});
});
it("should handle missing responseTime values", () => {
it("should handle missing responseTime values", function() {
const mockGroup = {
time: "2024-01-15",
checks: [
@@ -818,7 +834,7 @@ describe("monitorModule", () => {
});
});
it("should handle all checks with status false", () => {
it("should handle all checks with status false", function() {
const mockGroup = {
time: "2024-01-15",
checks: [
@@ -839,7 +855,7 @@ describe("monitorModule", () => {
});
});
it("should handle all checks with status true", () => {
it("should handle all checks with status true", function() {
const mockGroup = {
time: "2024-01-15",
checks: [
@@ -861,7 +877,7 @@ describe("monitorModule", () => {
});
});
describe("getMonitorStatsById", () => {
describe("getMonitorStatsById", function() {
const now = new Date();
const oneHourAgo = new Date(now - 3600000);
const twoHoursAgo = new Date(now - 7200000);
@@ -958,18 +974,18 @@ describe("monitorModule", () => {
},
};
beforeEach(() => {
beforeEach(function() {
checkFindStub.returns({
sort: () => checkDocs,
});
monitorFindByIdStub.returns(mockMonitor);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return monitor stats with calculated values, sort order desc", async () => {
it("should return monitor stats with calculated values, sort order desc", async function() {
req.query.sortOrder = "desc";
const result = await getMonitorStatsById(req);
expect(result).to.include.keys([
@@ -992,7 +1008,8 @@ describe("monitorModule", () => {
expect(result.periodUptime).to.be.a("number");
expect(result.aggregateData).to.be.an("array");
});
it("should return monitor stats with calculated values, ping type", async () => {
it("should return monitor stats with calculated values, ping type", async function() {
monitorFindByIdStub.returns(mockMonitorPing);
req.query.sortOrder = "desc";
const result = await getMonitorStatsById(req);
@@ -1016,7 +1033,8 @@ describe("monitorModule", () => {
expect(result.periodUptime).to.be.a("number");
expect(result.aggregateData).to.be.an("array");
});
it("should return monitor stats with calculated values, docker type", async () => {
it("should return monitor stats with calculated values, docker type", async function() {
monitorFindByIdStub.returns(mockMonitorDocker);
req.query.sortOrder = "desc";
const result = await getMonitorStatsById(req);
@@ -1040,7 +1058,8 @@ describe("monitorModule", () => {
expect(result.periodUptime).to.be.a("number");
expect(result.aggregateData).to.be.an("array");
});
it("should return monitor stats with calculated values", async () => {
it("should return monitor stats with calculated values", async function() {
req.query.sortOrder = "asc";
const result = await getMonitorStatsById(req);
expect(result).to.include.keys([
@@ -1063,7 +1082,8 @@ describe("monitorModule", () => {
expect(result.periodUptime).to.be.a("number");
expect(result.aggregateData).to.be.an("array");
});
it("should throw error when monitor is not found", async () => {
it("should throw error when monitor is not found", async function() {
monitorFindByIdStub.returns(Promise.resolve(null));
const req = {
@@ -1081,21 +1101,21 @@ describe("monitorModule", () => {
});
});
describe("getMonitorById", () => {
describe("getMonitorById", function() {
let notificationFindStub;
let monitorSaveStub;
beforeEach(() => {
beforeEach(function() {
// Create stubs
notificationFindStub = sinon.stub(Notification, "find");
monitorSaveStub = sinon.stub().resolves();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return monitor with notifications when found", async () => {
it("should return monitor with notifications when found", async function() {
// Arrange
const monitorId = "123";
const mockMonitor = {
@@ -1119,7 +1139,7 @@ describe("monitorModule", () => {
expect(monitorSaveStub.calledOnce).to.be.true;
});
it("should throw 404 error when monitor not found", async () => {
it("should throw 404 error when monitor not found", async function() {
// Arrange
const monitorId = "nonexistent";
monitorFindByIdStub.resolves(null);
@@ -1136,7 +1156,7 @@ describe("monitorModule", () => {
}
});
it("should handle database errors properly", async () => {
it("should handle database errors properly", async function() {
// Arrange
const monitorId = "123";
const dbError = new Error("Database connection failed");
@@ -1153,7 +1173,7 @@ describe("monitorModule", () => {
}
});
it("should handle notification fetch errors", async () => {
it("should handle notification fetch errors", async function() {
// Arrange
const monitorId = "123";
const mockMonitor = {
@@ -1177,7 +1197,7 @@ describe("monitorModule", () => {
}
});
it("should handle monitor save errors", async () => {
it("should handle monitor save errors", async function() {
// Arrange
const monitorId = "123";
const mockMonitor = {
@@ -1201,8 +1221,9 @@ describe("monitorModule", () => {
}
});
});
describe("getMonitorsAndSummaryByTeamId", () => {
it("should return monitors and correct summary counts", async () => {
describe("getMonitorsAndSummaryByTeamId", function() {
it("should return monitors and correct summary counts", async function() {
// Arrange
const teamId = "team123";
const type = "http";
@@ -1228,7 +1249,7 @@ describe("monitorModule", () => {
expect(monitorFindStub.calledOnceWith({ teamId, type })).to.be.true;
});
it("should return empty results for non-existent team", async () => {
it("should return empty results for non-existent team", async function() {
// Arrange
monitorFindStub.resolves([]);
@@ -1245,7 +1266,7 @@ describe("monitorModule", () => {
});
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
// Arrange
const error = new Error("Database error");
error.service = "MonitorModule";
@@ -1263,8 +1284,9 @@ describe("monitorModule", () => {
}
});
});
describe("getMonitorsByTeamId", () => {
beforeEach(() => {
describe("getMonitorsByTeamId", function() {
beforeEach(function() {
// Chain stubs for Monitor.find().skip().limit().sort()
// Stub for CHECK_MODEL_LOOKUP model find
@@ -1275,11 +1297,11 @@ describe("monitorModule", () => {
});
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should return monitors with basic query parameters", async () => {
it("should return monitors with basic query parameters", async function() {
const mockMonitors = [
{ _id: "1", type: "http", toObject: () => ({ _id: "1", type: "http" }) },
{ _id: "2", type: "ping", toObject: () => ({ _id: "2", type: "ping" }) },
@@ -1312,7 +1334,7 @@ describe("monitorModule", () => {
expect(result).to.have.property("monitorCount", 2);
});
it("should return monitors with basic query parameters", async () => {
it("should return monitors with basic query parameters", async function() {
const mockMonitors = [
{ _id: "1", type: "http", toObject: () => ({ _id: "1", type: "http" }) },
{ _id: "2", type: "ping", toObject: () => ({ _id: "2", type: "ping" }) },
@@ -1345,7 +1367,7 @@ describe("monitorModule", () => {
expect(result).to.have.property("monitorCount", 2);
});
it("should handle type filter with array input", async () => {
it("should handle type filter with array input", async function() {
const req = {
params: { teamId: "team123" },
query: {
@@ -1370,7 +1392,7 @@ describe("monitorModule", () => {
});
});
it("should handle text search filter", async () => {
it("should handle text search filter", async function() {
const req = {
params: { teamId: "team123" },
query: {
@@ -1398,7 +1420,7 @@ describe("monitorModule", () => {
});
});
it("should handle pagination parameters", async () => {
it("should handle pagination parameters", async function() {
const req = {
params: { teamId: "team123" },
query: {
@@ -1423,7 +1445,7 @@ describe("monitorModule", () => {
});
});
it("should handle sorting parameters", async () => {
it("should handle sorting parameters", async function() {
const req = {
params: { teamId: "team123" },
query: {
@@ -1450,7 +1472,7 @@ describe("monitorModule", () => {
});
});
it("should return early when limit is -1", async () => {
it("should return early when limit is -1", async function() {
// Arrange
const req = {
params: { teamId: "team123" },
@@ -1484,7 +1506,7 @@ describe("monitorModule", () => {
});
});
it("should normalize checks when normalize parameter is provided", async () => {
it("should normalize checks when normalize parameter is provided", async function() {
const req = {
params: { teamId: "team123" },
query: { normalize: "true" },
@@ -1508,7 +1530,8 @@ describe("monitorModule", () => {
expect(result.monitorCount).to.equal(2);
expect(result.monitors).to.have.lengthOf(2);
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
const req = {
params: { teamId: "team123" },
query: {},
@@ -1533,8 +1556,9 @@ describe("monitorModule", () => {
}
});
});
describe("createMonitor", () => {
it("should create a monitor without notifications", async () => {
describe("createMonitor", function() {
it("should create a monitor without notifications", async function() {
let monitorSaveStub = sinon.stub(Monitor.prototype, "save").resolves();
const req = {
@@ -1558,7 +1582,8 @@ describe("monitorModule", () => {
expect(result.name).to.equal(expectedMonitor.name);
expect(result.url).to.equal(expectedMonitor.url);
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
const req = {
body: {
name: "Test Monitor",
@@ -1575,8 +1600,8 @@ describe("monitorModule", () => {
});
});
describe("deleteMonitor", () => {
it("should delete a monitor successfully", async () => {
describe("deleteMonitor", function() {
it("should delete a monitor successfully", async function() {
const monitorId = "123456789";
const mockMonitor = {
_id: monitorId,
@@ -1596,7 +1621,7 @@ describe("monitorModule", () => {
sinon.assert.calledWith(monitorFindByIdAndDeleteStub, monitorId);
});
it("should throw error when monitor not found", async () => {
it("should throw error when monitor not found", async function() {
const monitorId = "nonexistent123";
const req = {
params: { monitorId },
@@ -1614,7 +1639,7 @@ describe("monitorModule", () => {
}
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
const monitorId = "123456789";
const req = {
params: { monitorId },
@@ -1634,8 +1659,8 @@ describe("monitorModule", () => {
});
});
describe("deleteAllMonitors", () => {
it("should delete all monitors for a team successfully", async () => {
describe("deleteAllMonitors", function() {
it("should delete all monitors for a team successfully", async function() {
const teamId = "team123";
const mockMonitors = [
{ _id: "1", name: "Monitor 1", teamId },
@@ -1655,7 +1680,7 @@ describe("monitorModule", () => {
sinon.assert.calledWith(monitorDeleteManyStub, { teamId });
});
it("should return empty array when no monitors found", async () => {
it("should return empty array when no monitors found", async function() {
const teamId = "emptyTeam";
monitorFindStub.resolves([]);
@@ -1671,7 +1696,7 @@ describe("monitorModule", () => {
sinon.assert.calledWith(monitorDeleteManyStub, { teamId });
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
const teamId = "team123";
const dbError = new Error("Database connection error");
monitorFindStub.rejects(dbError);
@@ -1685,7 +1710,7 @@ describe("monitorModule", () => {
}
});
it("should handle deleteMany errors", async () => {
it("should handle deleteMany errors", async function() {
const teamId = "team123";
monitorFindStub.resolves([{ _id: "1", name: "Monitor 1" }]);
monitorDeleteManyStub.rejects(new Error("Delete operation failed"));
@@ -1700,14 +1725,14 @@ describe("monitorModule", () => {
});
});
describe("deleteMonitorsByUserId", () => {
beforeEach(() => {});
describe("deleteMonitorsByUserId", function() {
beforeEach(function() {});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should delete all monitors for a user successfully", async () => {
it("should delete all monitors for a user successfully", async function() {
// Arrange
const userId = "user123";
const mockResult = {
@@ -1725,7 +1750,7 @@ describe("monitorModule", () => {
sinon.assert.calledWith(monitorDeleteManyStub, { userId: userId });
});
it("should return zero deletedCount when no monitors found", async () => {
it("should return zero deletedCount when no monitors found", async function() {
// Arrange
const userId = "nonexistentUser";
const mockResult = {
@@ -1743,7 +1768,7 @@ describe("monitorModule", () => {
sinon.assert.calledWith(monitorDeleteManyStub, { userId: userId });
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
// Arrange
const userId = "user123";
const dbError = new Error("Database connection error");
@@ -1761,8 +1786,8 @@ describe("monitorModule", () => {
});
});
describe("editMonitor", () => {
it("should edit a monitor successfully", async () => {
describe("editMonitor", function() {
it("should edit a monitor successfully", async function() {
// Arrange
const candidateId = "monitor123";
const candidateMonitor = {
@@ -1801,7 +1826,7 @@ describe("monitorModule", () => {
);
});
it("should return null when monitor not found", async () => {
it("should return null when monitor not found", async function() {
// Arrange
const candidateId = "nonexistent123";
const candidateMonitor = {
@@ -1823,7 +1848,7 @@ describe("monitorModule", () => {
);
});
it("should remove notifications from update data", async () => {
it("should remove notifications from update data", async function() {
// Arrange
const candidateId = "monitor123";
const candidateMonitor = {
@@ -1855,7 +1880,7 @@ describe("monitorModule", () => {
);
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
// Arrange
const candidateId = "monitor123";
const candidateMonitor = {
@@ -1877,8 +1902,8 @@ describe("monitorModule", () => {
});
});
describe("addDemoMonitors", () => {
it("should add demo monitors successfully", async () => {
describe("addDemoMonitors", function() {
it("should add demo monitors successfully", async function() {
// Arrange
const userId = "user123";
const teamId = "team123";
@@ -1887,7 +1912,7 @@ describe("monitorModule", () => {
expect(result).to.deep.equal([{ _id: "123" }]);
});
it("should handle database errors", async () => {
it("should handle database errors", async function() {
const userId = "user123";
const teamId = "team123";

View File

@@ -6,31 +6,32 @@ import {
deleteNotificationsByMonitorId,
} from "../../db/mongo/modules/notificationModule.js";
describe("notificationModule", () => {
describe("notificationModule", function() {
const mockNotification = {
monitorId: "123",
};
const mockNotifications = [mockNotification];
let notificationSaveStub, notificationFindStub, notificationDeleteManyStub;
beforeEach(() => {
beforeEach(function() {
notificationSaveStub = sinon.stub(Notification.prototype, "save").resolves();
notificationFindStub = sinon.stub(Notification, "find").resolves();
notificationDeleteManyStub = sinon.stub(Notification, "deleteMany").resolves();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createNotification", () => {
it("should create a new notification", async () => {
describe("createNotification", function() {
it("should create a new notification", async function() {
const notificationData = { _id: "123", name: "test" };
notificationSaveStub.resolves(notificationData);
const res = await createNotification(notificationData);
expect(res).to.deep.equal(notificationData);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
notificationSaveStub.rejects(err);
try {
@@ -41,13 +42,14 @@ describe("notificationModule", () => {
});
});
describe("getNotificationsByMonitorId", () => {
it("should return notifications by monitor ID", async () => {
describe("getNotificationsByMonitorId", function() {
it("should return notifications by monitor ID", async function() {
notificationFindStub.resolves(mockNotifications);
const res = await getNotificationsByMonitorId(mockNotification.monitorId);
expect(res).to.deep.equal(mockNotifications);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
notificationFindStub.rejects(err);
try {
@@ -58,13 +60,14 @@ describe("notificationModule", () => {
});
});
describe("deleteNotificationsByMonitorId", () => {
it("should delete notifications by monitor ID", async () => {
describe("deleteNotificationsByMonitorId", function() {
it("should delete notifications by monitor ID", async function() {
notificationDeleteManyStub.resolves({ deletedCount: mockNotifications.length });
const res = await deleteNotificationsByMonitorId(mockNotification.monitorId);
expect(res).to.deep.equal(mockNotifications.length);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
notificationDeleteManyStub.rejects(err);
try {

View File

@@ -14,25 +14,26 @@ const mockPageSpeedCheck = {
const mockDeletedResult = { deletedCount: 1 };
describe("pageSpeedCheckModule", () => {
describe("pageSpeedCheckModule", function() {
let pageSpeedCheckSaveStub, pageSpeedCheckDeleteManyStub;
beforeEach(() => {
beforeEach(function() {
pageSpeedCheckSaveStub = sinon.stub(PageSpeedCheck.prototype, "save");
pageSpeedCheckDeleteManyStub = sinon.stub(PageSpeedCheck, "deleteMany");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createPageSpeedCheck", () => {
it("should return a page speed check", async () => {
describe("createPageSpeedCheck", function() {
it("should return a page speed check", async function() {
pageSpeedCheckSaveStub.resolves(mockPageSpeedCheck);
const pageSpeedCheck = await createPageSpeedCheck(mockPageSpeedCheck);
expect(pageSpeedCheck).to.deep.equal(mockPageSpeedCheck);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
pageSpeedCheckSaveStub.rejects(err);
try {
@@ -44,14 +45,14 @@ describe("pageSpeedCheckModule", () => {
});
});
describe("deletePageSpeedChecksByMonitorId", () => {
it("should return the number of deleted checks", async () => {
describe("deletePageSpeedChecksByMonitorId", function() {
it("should return the number of deleted checks", async function() {
pageSpeedCheckDeleteManyStub.resolves(mockDeletedResult);
const result = await deletePageSpeedChecksByMonitorId("monitorId");
expect(result).to.deep.equal(mockDeletedResult.deletedCount);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
pageSpeedCheckDeleteManyStub.rejects(err);
try {

View File

@@ -43,7 +43,7 @@ const createQueryChain = (finalResult, comparePasswordResult = false) => ({
save: sinon.stub().resolves(),
});
describe("recoveryModule", () => {
describe("recoveryModule", function() {
let deleteManyStub,
saveStub,
findOneStub,
@@ -51,7 +51,8 @@ describe("recoveryModule", () => {
userSaveStub,
userFindOneStub;
let req, res;
beforeEach(() => {
beforeEach(function() {
req = {
body: { email: "test@test.com" },
};
@@ -63,18 +64,19 @@ describe("recoveryModule", () => {
userFindOneStub = sinon.stub().resolves();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("requestRecoveryToken", () => {
it("should return a recovery token", async () => {
describe("requestRecoveryToken", function() {
it("should return a recovery token", async function() {
deleteManyStub.resolves();
saveStub.resolves(mockRecoveryToken);
const result = await requestRecoveryToken(req, res);
expect(result.email).to.equal(mockRecoveryToken.email);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("Test error");
deleteManyStub.rejects(err);
try {
@@ -85,13 +87,15 @@ describe("recoveryModule", () => {
}
});
});
describe("validateRecoveryToken", () => {
it("should return a recovery token if found", async () => {
describe("validateRecoveryToken", function() {
it("should return a recovery token if found", async function() {
findOneStub.resolves(mockRecoveryToken);
const result = await validateRecoveryToken(req, res);
expect(result).to.deep.equal(mockRecoveryToken);
});
it("should thrown an error if a token is not found", async () => {
it("should thrown an error if a token is not found", async function() {
findOneStub.resolves(null);
try {
await validateRecoveryToken(req, res);
@@ -100,7 +104,8 @@ describe("recoveryModule", () => {
expect(error.message).to.equal(errorMessages.DB_TOKEN_NOT_FOUND);
}
});
it("should handle DB errors", async () => {
it("should handle DB errors", async function() {
const err = new Error("Test error");
findOneStub.rejects(err);
try {
@@ -112,19 +117,19 @@ describe("recoveryModule", () => {
});
});
describe("resetPassword", () => {
beforeEach(() => {
describe("resetPassword", function() {
beforeEach(function() {
req.body = {
password: "test",
newPassword: "test1",
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should thrown an error if a recovery token is not found", async () => {
it("should thrown an error if a recovery token is not found", async function() {
findOneStub.resolves(null);
try {
await resetPassword(req, res);
@@ -133,7 +138,8 @@ describe("recoveryModule", () => {
expect(error.message).to.equal(errorMessages.DB_TOKEN_NOT_FOUND);
}
});
it("should throw an error if a user is not found", async () => {
it("should throw an error if a user is not found", async function() {
findOneStub.resolves(mockRecoveryToken);
userFindOneStub = sinon.stub(User, "findOne").resolves(null);
try {
@@ -143,7 +149,8 @@ describe("recoveryModule", () => {
expect(error.message).to.equal(errorMessages.DB_USER_NOT_FOUND);
}
});
it("should throw an error if the passwords match", async () => {
it("should throw an error if the passwords match", async function() {
findOneStub.resolves(mockRecoveryToken);
saveStub.resolves();
userFindOneStub = sinon
@@ -156,7 +163,8 @@ describe("recoveryModule", () => {
expect(error.message).to.equal(errorMessages.DB_RESET_PASSWORD_BAD_MATCH);
}
});
it("should return a user without password if successful", async () => {
it("should return a user without password if successful", async function() {
findOneStub.resolves(mockRecoveryToken);
saveStub.resolves();
userFindOneStub = sinon

View File

@@ -9,23 +9,26 @@ const mockAppSettings = {
appName: "Test App",
};
describe("SettingsModule", () => {
describe("SettingsModule", function() {
let appSettingsFindOneStub, appSettingsFindOneAndUpdateStub;
beforeEach(() => {
beforeEach(function() {
appSettingsFindOneStub = sinon.stub(AppSettings, "findOne");
appSettingsFindOneAndUpdateStub = sinon.stub(AppSettings, "findOneAndUpdate");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("getAppSettings", () => {
it("should return app settings", async () => {
describe("getAppSettings", function() {
it("should return app settings", async function() {
appSettingsFindOneStub.resolves(mockAppSettings);
const result = await getAppSettings();
expect(result).to.deep.equal(mockAppSettings);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("Test error");
appSettingsFindOneStub.throws(err);
try {
@@ -35,13 +38,15 @@ describe("SettingsModule", () => {
}
});
});
describe("updateAppSettings", () => {
it("should update app settings", async () => {
describe("updateAppSettings", function() {
it("should update app settings", async function() {
appSettingsFindOneAndUpdateStub.resolves(mockAppSettings);
const result = await updateAppSettings(mockAppSettings);
expect(result).to.deep.equal(mockAppSettings);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("Test error");
appSettingsFindOneAndUpdateStub.throws(err);
try {

View File

@@ -6,18 +6,21 @@ import {
import StatusPage from "../../db/models/StatusPage.js";
import { errorMessages } from "../../utils/messages.js";
describe("statusPageModule", () => {
describe("statusPageModule", function() {
let statusPageFindOneStub, statusPageSaveStub, statusPageFindStub;
beforeEach(() => {
beforeEach(function() {
statusPageSaveStub = sinon.stub(StatusPage.prototype, "save");
statusPageFindOneStub = sinon.stub(StatusPage, "findOne");
statusPageFindStub = sinon.stub(StatusPage, "find");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createStatusPage", () => {
it("should throw an error if a non-unique url is provided", async () => {
describe("createStatusPage", function() {
it("should throw an error if a non-unique url is provided", async function() {
statusPageFindOneStub.resolves(true);
try {
await createStatusPage({ url: "test" });
@@ -26,7 +29,8 @@ describe("statusPageModule", () => {
expect(error.message).to.equal(errorMessages.STATUS_PAGE_URL_NOT_UNIQUE);
}
});
it("should handle duplicate URL errors", async () => {
it("should handle duplicate URL errors", async function() {
const err = new Error("test");
err.code = 11000;
statusPageSaveStub.rejects(err);
@@ -36,7 +40,8 @@ describe("statusPageModule", () => {
expect(error).to.deep.equal(err);
}
});
it("should return a status page if a unique url is provided", async () => {
it("should return a status page if a unique url is provided", async function() {
statusPageFindOneStub.resolves(null);
statusPageFindStub.resolves([]);
const mockStatusPage = { url: "test" };
@@ -45,8 +50,9 @@ describe("statusPageModule", () => {
expect(statusPage.url).to.equal(mockStatusPage.url);
});
});
describe("getStatusPageByUrl", () => {
it("should throw an error if a status page is not found", async () => {
describe("getStatusPageByUrl", function() {
it("should throw an error if a status page is not found", async function() {
statusPageFindOneStub.resolves(null);
try {
await getStatusPageByUrl("test");
@@ -56,7 +62,7 @@ describe("statusPageModule", () => {
}
});
it("should return a status page if a status page is found", async () => {
it("should return a status page if a status page is found", async function() {
const mockStatusPage = { url: "test" };
statusPageFindOneStub.resolves(mockStatusPage);
const statusPage = await getStatusPageByUrl(mockStatusPage.url);

View File

@@ -27,7 +27,7 @@ const imageFile = {
image: 1,
};
describe("userModule", () => {
describe("userModule", function() {
let teamSaveStub,
teamFindByIdAndDeleteStub,
userSaveStub,
@@ -39,7 +39,8 @@ describe("userModule", () => {
userUpdateOneStub,
generateAvatarImageStub,
parseBooleanStub;
beforeEach(() => {
beforeEach(function() {
teamSaveStub = sinon.stub(TeamModel.prototype, "save");
teamFindByIdAndDeleteStub = sinon.stub(TeamModel, "findByIdAndDelete");
userSaveStub = sinon.stub(UserModel.prototype, "save");
@@ -53,12 +54,12 @@ describe("userModule", () => {
parseBooleanStub = sinon.stub().returns(true);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("insertUser", () => {
it("should insert a regular user", async () => {
describe("insertUser", function() {
it("should insert a regular user", async function() {
userSaveStub.resolves(mockUser);
userFindOneStub.returns({
select: sinon.stub().returns({
@@ -68,7 +69,8 @@ describe("userModule", () => {
const result = await insertUser(mockUser, imageFile, generateAvatarImageStub);
expect(result).to.deep.equal(mockUser);
});
it("should insert a superadmin user", async () => {
it("should insert a superadmin user", async function() {
userSaveStub.resolves(mockSuperUser);
userFindOneStub.returns({
select: sinon.stub().returns({
@@ -78,7 +80,8 @@ describe("userModule", () => {
const result = await insertUser(mockSuperUser, imageFile, generateAvatarImageStub);
expect(result).to.deep.equal(mockSuperUser);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userSaveStub.rejects(err);
try {
@@ -88,7 +91,8 @@ describe("userModule", () => {
expect(error).to.deep.equal(err);
}
});
it("should handle a duplicate key error", async () => {
it("should handle a duplicate key error", async function() {
const err = new Error("test error");
err.code = 11000;
userSaveStub.rejects(err);
@@ -100,8 +104,9 @@ describe("userModule", () => {
}
});
});
describe("getUserByEmail", () => {
it("should return a user", async () => {
describe("getUserByEmail", function() {
it("should return a user", async function() {
userFindOneStub.returns({
select: sinon.stub().resolves(mockUser),
});
@@ -109,8 +114,9 @@ describe("userModule", () => {
expect(result).to.deep.equal(mockUser);
});
});
describe("getUserByEmail", () => {
it("throw an error if a user is not found", async () => {
describe("getUserByEmail", function() {
it("throw an error if a user is not found", async function() {
userFindOneStub.returns({
select: sinon.stub().resolves(null),
});
@@ -121,9 +127,11 @@ describe("userModule", () => {
}
});
});
describe("updateUser", () => {
describe("updateUser", function() {
let req, res;
beforeEach(() => {
beforeEach(function() {
req = {
params: {
userId: "testId",
@@ -140,8 +148,9 @@ describe("userModule", () => {
res = {};
});
afterEach(() => {});
it("should update a user", async () => {
afterEach(function() {});
it("should update a user", async function() {
parseBooleanStub.returns(false);
userFindByIdAndUpdateStub.returns({
select: sinon.stub().returns({
@@ -156,7 +165,8 @@ describe("userModule", () => {
);
expect(result).to.deep.equal(mockUser);
});
it("should delete a user profile image", async () => {
it("should delete a user profile image", async function() {
req.body.deleteProfileImage = "true";
userFindByIdAndUpdateStub.returns({
select: sinon.stub().returns({
@@ -171,7 +181,8 @@ describe("userModule", () => {
);
expect(result).to.deep.equal(mockUser);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userFindByIdAndUpdateStub.throws(err);
try {
@@ -182,13 +193,15 @@ describe("userModule", () => {
}
});
});
describe("deleteUser", async () => {
it("should return a deleted user", async () => {
describe("deleteUser", function() {
it("should return a deleted user", async function() {
userFindByIdAndDeleteStub.resolves(mockUser);
const result = await deleteUser("testId");
expect(result).to.deep.equal(mockUser);
});
it("should throw an error if a user is not found", async () => {
it("should throw an error if a user is not found", async function() {
try {
await deleteUser("testId");
} catch (error) {
@@ -196,7 +209,8 @@ describe("userModule", () => {
expect(error.message).to.equal(errorMessages.DB_USER_NOT_FOUND);
}
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userFindByIdAndDeleteStub.throws(err);
try {
@@ -208,13 +222,14 @@ describe("userModule", () => {
});
});
describe("deleteTeam", () => {
it("should return true if team deleted", async () => {
describe("deleteTeam", function() {
it("should return true if team deleted", async function() {
teamFindByIdAndDeleteStub.resolves();
const result = await deleteTeam("testId");
expect(result).to.equal(true);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
teamFindByIdAndDeleteStub.throws(err);
try {
@@ -226,13 +241,14 @@ describe("userModule", () => {
});
});
describe("deleteAllOtherUsers", () => {
it("should return true if all other users deleted", async () => {
describe("deleteAllOtherUsers", function() {
it("should return true if all other users deleted", async function() {
userDeleteManyStub.resolves(true);
const result = await deleteAllOtherUsers();
expect(result).to.equal(true);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userDeleteManyStub.throws(err);
try {
@@ -244,8 +260,8 @@ describe("userModule", () => {
});
});
describe("getAllUsers", () => {
it("should return all users", async () => {
describe("getAllUsers", function() {
it("should return all users", async function() {
userFindStub.returns({
select: sinon.stub().returns({
select: sinon.stub().resolves([mockUser]),
@@ -254,7 +270,8 @@ describe("userModule", () => {
const result = await getAllUsers();
expect(result).to.deep.equal([mockUser]);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userFindStub.throws(err);
try {
@@ -266,13 +283,14 @@ describe("userModule", () => {
});
});
describe("logoutUser", async () => {
it("should return true if user logged out", async () => {
describe("logoutUser", function() {
it("should return true if user logged out", async function() {
userUpdateOneStub.resolves(true);
const result = await logoutUser("testId");
expect(result).to.equal(true);
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const err = new Error("test error");
userUpdateOneStub.throws(err);
try {

View File

@@ -1,7 +1,7 @@
import sinon from "sinon";
import EmailService from "../../service/emailService.js";
describe("EmailService - Constructor", () => {
describe("EmailService - Constructor", function() {
let settingsServiceMock;
let fsMock;
let pathMock;
@@ -10,7 +10,7 @@ describe("EmailService - Constructor", () => {
let nodemailerMock;
let loggerMock;
beforeEach(() => {
beforeEach(function() {
settingsServiceMock = {
getSettings: sinon.stub().returns({
systemEmailHost: "smtp.example.com",
@@ -43,11 +43,11 @@ describe("EmailService - Constructor", () => {
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should initialize template loaders and email transporter", () => {
it("should initialize template loaders and email transporter", function() {
const emailService = new EmailService(
settingsServiceMock,
fsMock,
@@ -79,7 +79,7 @@ describe("EmailService - Constructor", () => {
});
});
it("should have undefined templates if FS fails", () => {
it("should have undefined templates if FS fails", function() {
fsMock = {
readFileSync: sinon.stub().throws(new Error("File read error")),
};
@@ -97,7 +97,7 @@ describe("EmailService - Constructor", () => {
});
});
describe("EmailService - buildAndSendEmail", () => {
describe("EmailService - buildAndSendEmail", function() {
let settingsServiceMock;
let fsMock;
let pathMock;
@@ -106,7 +106,8 @@ describe("EmailService - buildAndSendEmail", () => {
let nodemailerMock;
let loggerMock;
let emailService;
beforeEach(() => {
beforeEach(function() {
settingsServiceMock = {
getSettings: sinon.stub().returns({
systemEmailHost: "smtp.example.com",
@@ -149,11 +150,11 @@ describe("EmailService - buildAndSendEmail", () => {
);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should build and send email successfully", async () => {
it("should build and send email successfully", async function() {
const messageId = await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
{},
@@ -165,7 +166,7 @@ describe("EmailService - buildAndSendEmail", () => {
expect(nodemailerMock.createTransport().sendMail.calledOnce).to.be.true;
});
it("should log error if building HTML fails", async () => {
it("should log error if building HTML fails", async function() {
mjml2htmlMock.throws(new Error("MJML error"));
const messageId = await emailService.buildAndSendEmail(
@@ -178,7 +179,7 @@ describe("EmailService - buildAndSendEmail", () => {
expect(loggerMock.error.getCall(0).args[0].message).to.equal("MJML error");
});
it("should log error if sending email fails", async () => {
it("should log error if sending email fails", async function() {
nodemailerMock.createTransport().sendMail.rejects(new Error("SMTP error"));
await emailService.buildAndSendEmail(
"welcomeEmailTemplate",
@@ -190,7 +191,7 @@ describe("EmailService - buildAndSendEmail", () => {
expect(loggerMock.error.getCall(0).args[0].message).to.equal("SMTP error");
});
it("should log error if both building HTML and sending email fail", async () => {
it("should log error if both building HTML and sending email fail", async function() {
mjml2htmlMock.throws(new Error("MJML error"));
nodemailerMock.createTransport().sendMail.rejects(new Error("SMTP error"));
@@ -207,5 +208,5 @@ describe("EmailService - buildAndSendEmail", () => {
expect(loggerMock.error.getCall(1).args[0].message).to.equal("SMTP error");
});
it("should log an error if buildHtml fails", async () => {});
it("should log an error if buildHtml fails", async function() {});
});

View File

@@ -51,7 +51,7 @@ class WorkerStub {
}
}
describe("JobQueue", () => {
describe("JobQueue", function() {
let settingsService,
logger,
db,
@@ -60,7 +60,7 @@ describe("JobQueue", () => {
notificationService,
jobQueue;
beforeEach(async () => {
beforeEach(async function() {
settingsService = { getSettings: sinon.stub() };
statusService = { updateStatus: sinon.stub() };
notificationService = { handleNotifications: sinon.stub() };
@@ -83,12 +83,12 @@ describe("JobQueue", () => {
);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("createJobQueue", () => {
it("should create a new JobQueue and add jobs for active monitors", async () => {
describe("createJobQueue", function() {
it("should create a new JobQueue and add jobs for active monitors", async function() {
db.getAllMonitors.returns([
{ id: 1, isActive: true },
{ id: 2, isActive: true },
@@ -108,7 +108,7 @@ describe("JobQueue", () => {
expect(jobQueue.queue.jobs.length).to.equal(4);
});
it("should reject with an error if an error occurs", async () => {
it("should reject with an error if an error occurs", async function() {
db.getAllMonitors.throws("Error");
try {
const jobQueue = await JobQueue.createJobQueue(
@@ -127,7 +127,7 @@ describe("JobQueue", () => {
}
});
it("should reject with an error if an error occurs, should not overwrite error data", async () => {
it("should reject with an error if an error occurs, should not overwrite error data", async function() {
const error = new Error("Error");
error.service = "otherService";
error.method = "otherMethod";
@@ -151,14 +151,15 @@ describe("JobQueue", () => {
});
});
describe("Constructor", () => {
it("should construct a new JobQueue with default port and host if not provided", async () => {
describe("Constructor", function() {
it("should construct a new JobQueue with default port and host if not provided", async function() {
settingsService.getSettings.returns({});
expect(jobQueue.connection.host).to.equal("127.0.0.1");
expect(jobQueue.connection.port).to.equal(6379);
});
it("should construct a new JobQueue with provided port and host", async () => {
it("should construct a new JobQueue with provided port and host", async function() {
settingsService.getSettings.returns({ redisHost: "localhost", redisPort: 1234 });
const jobQueue = await JobQueue.createJobQueue(
db,
@@ -175,8 +176,8 @@ describe("JobQueue", () => {
});
});
describe("isMaintenanceWindow", () => {
it("should throw an error if error occurs", async () => {
describe("isMaintenanceWindow", function() {
it("should throw an error if error occurs", async function() {
db.getMaintenanceWindowsByMonitorId.throws("Error");
const jobQueue = await JobQueue.createJobQueue(
db,
@@ -196,7 +197,7 @@ describe("JobQueue", () => {
}
});
it("should return true if in maintenance window with no repeat", async () => {
it("should return true if in maintenance window with no repeat", async function() {
db.getMaintenanceWindowsByMonitorId.returns([
{
active: true,
@@ -219,7 +220,7 @@ describe("JobQueue", () => {
expect(inWindow).to.be.true;
});
it("should return true if in maintenance window with repeat", async () => {
it("should return true if in maintenance window with repeat", async function() {
db.getMaintenanceWindowsByMonitorId.returns([
{
active: true,
@@ -242,7 +243,7 @@ describe("JobQueue", () => {
expect(inWindow).to.be.true;
});
it("should return false if in end < start", async () => {
it("should return false if in end < start", async function() {
db.getMaintenanceWindowsByMonitorId.returns([
{
active: true,
@@ -264,7 +265,8 @@ describe("JobQueue", () => {
const inWindow = await jobQueue.isInMaintenanceWindow(1);
expect(inWindow).to.be.false;
});
it("should return false if not in maintenance window", async () => {
it("should return false if not in maintenance window", async function() {
db.getMaintenanceWindowsByMonitorId.returns([
{
active: false,
@@ -288,8 +290,8 @@ describe("JobQueue", () => {
});
});
describe("createJobHandler", () => {
it("resolve to an error if an error is thrown within", async () => {
describe("createJobHandler", function() {
it("resolve to an error if an error is thrown within", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -310,7 +312,7 @@ describe("JobQueue", () => {
}
});
it("should log info if job is in maintenance window", async () => {
it("should log info if job is in maintenance window", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -330,7 +332,7 @@ describe("JobQueue", () => {
);
});
it("should return if status has not changed", async () => {
it("should return if status has not changed", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -348,7 +350,7 @@ describe("JobQueue", () => {
expect(jobQueue.notificationService.handleNotifications.notCalled).to.be.true;
});
it("should return if status has changed, but prevStatus was undefined (monitor paused)", async () => {
it("should return if status has changed, but prevStatus was undefined (monitor paused)", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -367,7 +369,8 @@ describe("JobQueue", () => {
await handler({ data: { _id: 1 } });
expect(jobQueue.notificationService.handleNotifications.notCalled).to.be.true;
});
it("should call notification service if status changed and monitor was not paused", async () => {
it("should call notification service if status changed and monitor was not paused", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -388,8 +391,8 @@ describe("JobQueue", () => {
});
});
describe("getWorkerStats", () => {
it("should throw an error if getRepeatable Jobs fails", async () => {
describe("getWorkerStats", function() {
it("should throw an error if getRepeatable Jobs fails", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -410,7 +413,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("getWorkerStats");
}
});
it("should throw an error if getRepeatable Jobs fails but respect existing error data", async () => {
it("should throw an error if getRepeatable Jobs fails but respect existing error data", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -436,8 +440,8 @@ describe("JobQueue", () => {
});
});
describe("scaleWorkers", () => {
it("should scale workers to 5 if no workers", async () => {
describe("scaleWorkers", function() {
it("should scale workers to 5 if no workers", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -450,7 +454,8 @@ describe("JobQueue", () => {
);
expect(jobQueue.workers.length).to.equal(5);
});
it("should scale workers up", async () => {
it("should scale workers up", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -467,7 +472,8 @@ describe("JobQueue", () => {
});
expect(jobQueue.workers.length).to.equal(20);
});
it("should scale workers down, even with error of worker.close fails", async () => {
it("should scale workers down, even with error of worker.close fails", async function() {
WorkerStub.prototype.close = async () => {
throw new Error("Error");
};
@@ -492,7 +498,8 @@ describe("JobQueue", () => {
});
expect(jobQueue.workers.length).to.equal(5);
});
it("should scale workers down", async () => {
it("should scale workers down", async function() {
WorkerStub.prototype.close = async () => {
return true;
};
@@ -517,7 +524,8 @@ describe("JobQueue", () => {
});
expect(jobQueue.workers.length).to.equal(5);
});
it("should return false if scaling doesn't happen", async () => {
it("should return false if scaling doesn't happen", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -534,8 +542,8 @@ describe("JobQueue", () => {
});
});
describe("getJobs", () => {
it("should return jobs", async () => {
describe("getJobs", function() {
it("should return jobs", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -549,7 +557,8 @@ describe("JobQueue", () => {
const jobs = await jobQueue.getJobs();
expect(jobs.length).to.equal(0);
});
it("should throw an error if getRepeatableJobs fails", async () => {
it("should throw an error if getRepeatableJobs fails", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -571,7 +580,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("getJobs");
}
});
it("should throw an error if getRepeatableJobs fails but respect existing error data", async () => {
it("should throw an error if getRepeatableJobs fails but respect existing error data", async function() {
const jobQueue = await JobQueue.createJobQueue(
db,
networkService,
@@ -598,12 +608,13 @@ describe("JobQueue", () => {
});
});
describe("getJobStats", () => {
it("should return job stats for no jobs", async () => {
describe("getJobStats", function() {
it("should return job stats for no jobs", async function() {
const jobStats = await jobQueue.getJobStats();
expect(jobStats).to.deep.equal({ jobs: [], workers: 5 });
});
it("should return job stats for jobs", async () => {
it("should return job stats for jobs", async function() {
jobQueue.queue.getJobs = async () => {
return [{ data: { url: "test" }, getState: async () => "completed" }];
};
@@ -613,7 +624,8 @@ describe("JobQueue", () => {
workers: 5,
});
});
it("should reject with an error if mapping jobs fails", async () => {
it("should reject with an error if mapping jobs fails", async function() {
jobQueue.queue.getJobs = async () => {
return [
{
@@ -632,7 +644,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("getJobStats");
}
});
it("should reject with an error if mapping jobs fails but respect existing error data", async () => {
it("should reject with an error if mapping jobs fails but respect existing error data", async function() {
jobQueue.queue.getJobs = async () => {
return [
{
@@ -656,12 +669,13 @@ describe("JobQueue", () => {
});
});
describe("addJob", () => {
it("should add a job to the queue", async () => {
describe("addJob", function() {
it("should add a job to the queue", async function() {
jobQueue.addJob("test", { url: "test" });
expect(jobQueue.queue.jobs.length).to.equal(1);
});
it("should reject with an error if adding fails", async () => {
it("should reject with an error if adding fails", async function() {
jobQueue.queue.add = async () => {
throw new Error("Error adding job");
};
@@ -673,7 +687,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("addJob");
}
});
it("should reject with an error if adding fails but respect existing error data", async () => {
it("should reject with an error if adding fails but respect existing error data", async function() {
jobQueue.queue.add = async () => {
const error = new Error("Error adding job");
error.service = "otherService";
@@ -689,8 +704,9 @@ describe("JobQueue", () => {
}
});
});
describe("deleteJob", () => {
it("should delete a job from the queue", async () => {
describe("deleteJob", function() {
it("should delete a job from the queue", async function() {
jobQueue.getWorkerStats = sinon.stub().returns({ load: 1, jobs: [{}] });
jobQueue.scaleWorkers = sinon.stub();
const monitor = { _id: 1 };
@@ -702,7 +718,8 @@ describe("JobQueue", () => {
// expect(jobQueue.getWorkerStats.calledOnce).to.be.true;
// expect(jobQueue.scaleWorkers.calledOnce).to.be.true;
});
it("should log an error if job is not found", async () => {
it("should log an error if job is not found", async function() {
jobQueue.getWorkerStats = sinon.stub().returns({ load: 1, jobs: [{}] });
jobQueue.scaleWorkers = sinon.stub();
const monitor = { _id: 1 };
@@ -711,7 +728,8 @@ describe("JobQueue", () => {
await jobQueue.deleteJob({ id_: 2 });
expect(logger.error.calledOnce).to.be.true;
});
it("should reject with an error if removeRepeatable fails", async () => {
it("should reject with an error if removeRepeatable fails", async function() {
jobQueue.queue.removeRepeatable = async () => {
const error = new Error("removeRepeatable error");
throw error;
@@ -725,7 +743,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("deleteJob");
}
});
it("should reject with an error if removeRepeatable fails but respect existing error data", async () => {
it("should reject with an error if removeRepeatable fails but respect existing error data", async function() {
jobQueue.queue.removeRepeatable = async () => {
const error = new Error("removeRepeatable error");
error.service = "otherService";
@@ -742,8 +761,9 @@ describe("JobQueue", () => {
}
});
});
describe("getMetrics", () => {
it("should return metrics for the job queue", async () => {
describe("getMetrics", function() {
it("should return metrics for the job queue", async function() {
jobQueue.queue.getWaitingCount = async () => 1;
jobQueue.queue.getActiveCount = async () => 2;
jobQueue.queue.getCompletedCount = async () => 3;
@@ -760,7 +780,8 @@ describe("JobQueue", () => {
repeatableJobs: 3,
});
});
it("should log an error if metrics operations fail", async () => {
it("should log an error if metrics operations fail", async function() {
jobQueue.queue.getWaitingCount = async () => {
throw new Error("Error");
};
@@ -770,8 +791,8 @@ describe("JobQueue", () => {
});
});
describe("obliterate", () => {
it("should return true if obliteration is successful", async () => {
describe("obliterate", function() {
it("should return true if obliteration is successful", async function() {
jobQueue.queue.pause = async () => true;
jobQueue.getJobs = async () => [{ key: 1, id: 1 }];
jobQueue.queue.removeRepeatableByKey = async () => true;
@@ -780,7 +801,8 @@ describe("JobQueue", () => {
const obliteration = await jobQueue.obliterate();
expect(obliteration).to.be.true;
});
it("should throw an error if obliteration fails", async () => {
it("should throw an error if obliteration fails", async function() {
jobQueue.getMetrics = async () => {
throw new Error("Error");
};
@@ -792,7 +814,8 @@ describe("JobQueue", () => {
expect(error.method).to.equal("obliterate");
}
});
it("should throw an error if obliteration fails but respect existing error data", async () => {
it("should throw an error if obliteration fails but respect existing error data", async function() {
jobQueue.getMetrics = async () => {
const error = new Error("Error");
error.service = "otherService";

View File

@@ -3,10 +3,10 @@ import NetworkService from "../../service/networkService.js";
import { expect } from "chai";
import http from "http";
import { errorMessages } from "../../utils/messages.js";
describe("Network Service", () => {
describe("Network Service", function() {
let axios, ping, Docker, logger, networkService;
beforeEach(() => {
beforeEach(function() {
axios = {
get: sinon.stub().resolves({
data: { foo: "bar" },
@@ -34,21 +34,23 @@ describe("Network Service", () => {
logger = { error: sinon.stub() };
networkService = new NetworkService(axios, ping, logger, http, Docker);
});
describe("constructor", () => {
it("should create a new NetworkService instance", () => {
describe("constructor", function() {
it("should create a new NetworkService instance", function() {
const networkService = new NetworkService();
expect(networkService).to.be.an.instanceOf(NetworkService);
});
});
describe("timeRequest", () => {
it("should time an asynchronous operation", async () => {
describe("timeRequest", function() {
it("should time an asynchronous operation", async function() {
const operation = sinon.stub().resolves("success");
const { response, responseTime } = await networkService.timeRequest(operation);
expect(response).to.equal("success");
expect(responseTime).to.be.a("number");
});
it("should handle errors if operation throws error", async () => {
it("should handle errors if operation throws error", async function() {
const error = new Error("Test error");
const operation = sinon.stub().throws(error);
const { response, responseTime } = await networkService.timeRequest(operation);
@@ -58,8 +60,8 @@ describe("Network Service", () => {
});
});
describe("requestPing", () => {
it("should return a response object if ping successful", async () => {
describe("requestPing", function() {
it("should return a response object if ping successful", async function() {
const pingResult = await networkService.requestPing({
data: { url: "http://test.com", _id: "123" },
});
@@ -68,7 +70,8 @@ describe("Network Service", () => {
expect(pingResult.responseTime).to.be.a("number");
expect(pingResult.status).to.be.true;
});
it("should return a response object if ping unsuccessful", async () => {
it("should return a response object if ping unsuccessful", async function() {
const error = new Error("Test error");
networkService.timeRequest = sinon
.stub()
@@ -82,7 +85,8 @@ describe("Network Service", () => {
expect(pingResult.status).to.be.false;
expect(pingResult.code).to.equal(networkService.PING_ERROR);
});
it("should throw an error if ping cannot resolve", async () => {
it("should throw an error if ping cannot resolve", async function() {
const error = new Error("test error");
networkService.timeRequest = sinon.stub().throws(error);
try {
@@ -95,8 +99,9 @@ describe("Network Service", () => {
}
});
});
describe("requestHttp", () => {
it("should return a response object if http successful", async () => {
describe("requestHttp", function() {
it("should return a response object if http successful", async function() {
const job = { data: { url: "http://test.com", _id: "123", type: "http" } };
const httpResult = await networkService.requestHttp(job);
expect(httpResult.monitorId).to.equal("123");
@@ -104,7 +109,8 @@ describe("Network Service", () => {
expect(httpResult.responseTime).to.be.a("number");
expect(httpResult.status).to.be.true;
});
it("should return a response object if http unsuccessful", async () => {
it("should return a response object if http unsuccessful", async function() {
const error = new Error("Test error");
error.response = { status: 404 };
networkService.timeRequest = sinon
@@ -118,7 +124,8 @@ describe("Network Service", () => {
expect(httpResult.status).to.be.false;
expect(httpResult.code).to.equal(404);
});
it("should return a response object if http unsuccessful with unknown code", async () => {
it("should return a response object if http unsuccessful with unknown code", async function() {
const error = new Error("Test error");
error.response = {};
networkService.timeRequest = sinon
@@ -132,7 +139,8 @@ describe("Network Service", () => {
expect(httpResult.status).to.be.false;
expect(httpResult.code).to.equal(networkService.NETWORK_ERROR);
});
it("should throw an error if an error occurs", async () => {
it("should throw an error if an error occurs", async function() {
const error = new Error("test error");
networkService.timeRequest = sinon.stub().throws(error);
try {
@@ -146,8 +154,8 @@ describe("Network Service", () => {
});
});
describe("requestPagespeed", () => {
it("should return a response object if pagespeed successful", async () => {
describe("requestPagespeed", function() {
it("should return a response object if pagespeed successful", async function() {
const job = { data: { url: "http://test.com", _id: "123", type: "pagespeed" } };
const pagespeedResult = await networkService.requestPagespeed(job);
expect(pagespeedResult.monitorId).to.equal("123");
@@ -155,7 +163,8 @@ describe("Network Service", () => {
expect(pagespeedResult.responseTime).to.be.a("number");
expect(pagespeedResult.status).to.be.true;
});
it("should return a response object if pagespeed unsuccessful", async () => {
it("should return a response object if pagespeed unsuccessful", async function() {
const error = new Error("Test error");
error.response = { status: 404 };
networkService.timeRequest = sinon
@@ -169,7 +178,8 @@ describe("Network Service", () => {
expect(pagespeedResult.status).to.be.false;
expect(pagespeedResult.code).to.equal(404);
});
it("should return a response object if pagespeed unsuccessful with an unknown code", async () => {
it("should return a response object if pagespeed unsuccessful with an unknown code", async function() {
const error = new Error("Test error");
error.response = {};
networkService.timeRequest = sinon
@@ -183,7 +193,8 @@ describe("Network Service", () => {
expect(pagespeedResult.status).to.be.false;
expect(pagespeedResult.code).to.equal(networkService.NETWORK_ERROR);
});
it("should throw an error if pagespeed cannot resolve", async () => {
it("should throw an error if pagespeed cannot resolve", async function() {
const error = new Error("test error");
networkService.timeRequest = sinon.stub().throws(error);
try {
@@ -197,8 +208,8 @@ describe("Network Service", () => {
});
});
describe("requestHardware", () => {
it("should return a response object if hardware successful", async () => {
describe("requestHardware", function() {
it("should return a response object if hardware successful", async function() {
const job = { data: { url: "http://test.com", _id: "123", type: "hardware" } };
const httpResult = await networkService.requestHardware(job);
expect(httpResult.monitorId).to.equal("123");
@@ -206,7 +217,8 @@ describe("Network Service", () => {
expect(httpResult.responseTime).to.be.a("number");
expect(httpResult.status).to.be.true;
});
it("should return a response object if hardware successful and job has a secret", async () => {
it("should return a response object if hardware successful and job has a secret", async function() {
const job = {
data: {
url: "http://test.com",
@@ -221,7 +233,8 @@ describe("Network Service", () => {
expect(httpResult.responseTime).to.be.a("number");
expect(httpResult.status).to.be.true;
});
it("should return a response object if hardware unsuccessful", async () => {
it("should return a response object if hardware unsuccessful", async function() {
const error = new Error("Test error");
error.response = { status: 404 };
networkService.timeRequest = sinon
@@ -235,7 +248,8 @@ describe("Network Service", () => {
expect(httpResult.status).to.be.false;
expect(httpResult.code).to.equal(404);
});
it("should return a response object if hardware unsuccessful with unknown code", async () => {
it("should return a response object if hardware unsuccessful with unknown code", async function() {
const error = new Error("Test error");
error.response = {};
networkService.timeRequest = sinon
@@ -249,7 +263,8 @@ describe("Network Service", () => {
expect(httpResult.status).to.be.false;
expect(httpResult.code).to.equal(networkService.NETWORK_ERROR);
});
it("should throw an error if hardware cannot resolve", async () => {
it("should throw an error if hardware cannot resolve", async function() {
const error = new Error("test error");
networkService.timeRequest = sinon.stub().throws(error);
try {
@@ -263,8 +278,8 @@ describe("Network Service", () => {
});
});
describe("requestDocker", () => {
it("should return a response object if docker successful", async () => {
describe("requestDocker", function() {
it("should return a response object if docker successful", async function() {
const job = { data: { url: "http://test.com", _id: "123", type: "docker" } };
const dockerResult = await networkService.requestDocker(job);
expect(dockerResult.monitorId).to.equal("123");
@@ -273,7 +288,7 @@ describe("Network Service", () => {
expect(dockerResult.status).to.be.true;
});
it("should return a response object with status false if container not running", async () => {
it("should return a response object with status false if container not running", async function() {
Docker = class {
listContainers = sinon.stub().resolves([
{
@@ -292,7 +307,7 @@ describe("Network Service", () => {
expect(dockerResult.code).to.equal(200);
});
it("should handle an error when fetching the container", async () => {
it("should handle an error when fetching the container", async function() {
Docker = class {
listContainers = sinon.stub().resolves([
{
@@ -311,7 +326,7 @@ describe("Network Service", () => {
expect(dockerResult.code).to.equal(networkService.NETWORK_ERROR);
});
it("should throw an error if operations fail", async () => {
it("should throw an error if operations fail", async function() {
Docker = class {
listContainers = sinon.stub().resolves([
{
@@ -329,7 +344,8 @@ describe("Network Service", () => {
expect(error.message).to.equal("test error");
}
});
it("should throw an error if no matching images found", async () => {
it("should throw an error if no matching images found", async function() {
Docker = class {
listContainers = sinon.stub().resolves([]);
getContainer = sinon.stub().throws(new Error("test error"));
@@ -344,8 +360,8 @@ describe("Network Service", () => {
});
});
describe("getStatus", () => {
beforeEach(() => {
describe("getStatus", function() {
beforeEach(function() {
networkService.requestPing = sinon.stub();
networkService.requestHttp = sinon.stub();
networkService.requestPagespeed = sinon.stub();
@@ -353,45 +369,51 @@ describe("Network Service", () => {
networkService.requestDocker = sinon.stub();
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should call requestPing if type is ping", async () => {
it("should call requestPing if type is ping", async function() {
await networkService.getStatus({ data: { type: "ping" } });
expect(networkService.requestPing.calledOnce).to.be.true;
expect(networkService.requestDocker.notCalled).to.be.true;
expect(networkService.requestHttp.notCalled).to.be.true;
expect(networkService.requestPagespeed.notCalled).to.be.true;
});
it("should call requestHttp if type is http", async () => {
it("should call requestHttp if type is http", async function() {
await networkService.getStatus({ data: { type: "http" } });
expect(networkService.requestPing.notCalled).to.be.true;
expect(networkService.requestDocker.notCalled).to.be.true;
expect(networkService.requestHttp.calledOnce).to.be.true;
expect(networkService.requestPagespeed.notCalled).to.be.true;
});
it("should call requestPagespeed if type is pagespeed", async () => {
it("should call requestPagespeed if type is pagespeed", async function() {
await networkService.getStatus({ data: { type: "pagespeed" } });
expect(networkService.requestPing.notCalled).to.be.true;
expect(networkService.requestDocker.notCalled).to.be.true;
expect(networkService.requestHttp.notCalled).to.be.true;
expect(networkService.requestPagespeed.calledOnce).to.be.true;
});
it("should call requestHardware if type is hardware", async () => {
it("should call requestHardware if type is hardware", async function() {
await networkService.getStatus({ data: { type: "hardware" } });
expect(networkService.requestHardware.calledOnce).to.be.true;
expect(networkService.requestDocker.notCalled).to.be.true;
expect(networkService.requestPing.notCalled).to.be.true;
expect(networkService.requestPagespeed.notCalled).to.be.true;
});
it("should call requestDocker if type is Docker", async () => {
it("should call requestDocker if type is Docker", async function() {
await networkService.getStatus({ data: { type: "docker" } });
expect(networkService.requestDocker.calledOnce).to.be.true;
expect(networkService.requestHardware.notCalled).to.be.true;
expect(networkService.requestPing.notCalled).to.be.true;
expect(networkService.requestPagespeed.notCalled).to.be.true;
});
it("should throw an error if an unknown type is provided", async () => {
it("should throw an error if an unknown type is provided", async function() {
try {
await networkService.getStatus({ data: { type: "unknown" } });
} catch (error) {
@@ -400,7 +422,8 @@ describe("Network Service", () => {
expect(error.message).to.equal("Unsupported type: unknown");
}
});
it("should throw an error if job type is undefined", async () => {
it("should throw an error if job type is undefined", async function() {
try {
await networkService.getStatus({ data: { type: undefined } });
} catch (error) {
@@ -409,7 +432,8 @@ describe("Network Service", () => {
expect(error.message).to.equal("Unsupported type: unknown");
}
});
it("should throw an error if job is empty", async () => {
it("should throw an error if job is empty", async function() {
try {
await networkService.getStatus({});
} catch (error) {
@@ -417,7 +441,8 @@ describe("Network Service", () => {
expect(error.message).to.equal("Unsupported type: unknown");
}
});
it("should throw an error if job is null", async () => {
it("should throw an error if job is null", async function() {
try {
await networkService.getStatus(null);
} catch (error) {

View File

@@ -2,9 +2,10 @@ import sinon from "sinon";
import NotificationService from "../../service/notificationService.js";
import { expect } from "chai";
describe("NotificationService", () => {
describe("NotificationService", function() {
let emailService, db, logger, notificationService;
beforeEach(() => {
beforeEach(function() {
db = {
getNotificationsByMonitorId: sinon.stub(),
};
@@ -17,18 +18,19 @@ describe("NotificationService", () => {
notificationService = new NotificationService(emailService, db, logger);
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("constructor", () => {
it("should create a new instance of NotificationService", () => {
describe("constructor", function() {
it("should create a new instance of NotificationService", function() {
expect(notificationService).to.be.an.instanceOf(NotificationService);
});
});
describe("sendEmail", async () => {
it("should send an email notification with Up Template", async () => {
describe("sendEmail", function() {
it("should send an email notification with Up Template", async function() {
const networkResponse = {
monitor: {
name: "Test Monitor",
@@ -47,7 +49,8 @@ describe("NotificationService", () => {
)
);
});
it("should send an email notification with Down Template", async () => {
it("should send an email notification with Down Template", async function() {
const networkResponse = {
monitor: {
name: "Test Monitor",
@@ -60,7 +63,8 @@ describe("NotificationService", () => {
await notificationService.sendEmail(networkResponse, address);
expect(notificationService.emailService.buildAndSendEmail.calledOnce).to.be.true;
});
it("should send an email notification with Up Template", async () => {
it("should send an email notification with Up Template", async function() {
const networkResponse = {
monitor: {
name: "Test Monitor",
@@ -75,8 +79,8 @@ describe("NotificationService", () => {
});
});
describe("handleNotifications", async () => {
it("should handle notifications based on the network response", async () => {
describe("handleNotifications", function() {
it("should handle notifications based on the network response", async function() {
notificationService.sendEmail = sinon.stub();
const res = await notificationService.handleNotifications({
monitor: {
@@ -86,7 +90,8 @@ describe("NotificationService", () => {
});
expect(res).to.be.true;
});
it("should handle hardware notifications", async () => {
it("should handle hardware notifications", async function() {
notificationService.sendEmail = sinon.stub();
const res = await notificationService.handleNotifications({
monitor: {
@@ -97,7 +102,7 @@ describe("NotificationService", () => {
expect(res).to.be.true;
});
it("should handle an error when getting notifications", async () => {
it("should handle an error when getting notifications", async function() {
const testError = new Error("Test Error");
notificationService.db.getNotificationsByMonitorId.rejects(testError);
await notificationService.handleNotifications({ monitorId: "123" });
@@ -105,9 +110,10 @@ describe("NotificationService", () => {
});
});
describe("sendHardwareEmail", async () => {
describe("sendHardwareEmail", function() {
let networkResponse, address, alerts;
beforeEach(() => {
beforeEach(function() {
networkResponse = {
monitor: {
name: "Test Monitor",
@@ -120,10 +126,11 @@ describe("NotificationService", () => {
alerts = ["test"];
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should send an email notification with Hardware Template", async () => {
it("should send an email notification with Hardware Template", async function() {
emailService.buildAndSendEmail.resolves(true);
const res = await notificationService.sendHardwareEmail(
networkResponse,
@@ -132,7 +139,8 @@ describe("NotificationService", () => {
);
expect(res).to.be.true;
});
it("should return false if no alerts are provided", async () => {
it("should return false if no alerts are provided", async function() {
alerts = [];
emailService.buildAndSendEmail.resolves(true);
const res = await notificationService.sendHardwareEmail(
@@ -143,9 +151,11 @@ describe("NotificationService", () => {
expect(res).to.be.false;
});
});
describe("handleStatusNotifications", async () => {
describe("handleStatusNotifications", function() {
let networkResponse;
beforeEach(() => {
beforeEach(function() {
networkResponse = {
monitor: {
name: "Test Monitor",
@@ -157,28 +167,31 @@ describe("NotificationService", () => {
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
it("should handle status notifications", async () => {
it("should handle status notifications", async function() {
db.getNotificationsByMonitorId.resolves([
{ type: "email", address: "test@test.com" },
]);
const res = await notificationService.handleStatusNotifications(networkResponse);
expect(res).to.be.true;
});
it("should return false if status hasn't changed", async () => {
it("should return false if status hasn't changed", async function() {
networkResponse.statusChanged = false;
const res = await notificationService.handleStatusNotifications(networkResponse);
expect(res).to.be.false;
});
it("should return false if prevStatus is undefined", async () => {
it("should return false if prevStatus is undefined", async function() {
networkResponse.prevStatus = undefined;
const res = await notificationService.handleStatusNotifications(networkResponse);
expect(res).to.be.false;
});
it("should handle an error", async () => {
it("should handle an error", async function() {
const testError = new Error("Test Error");
db.getNotificationsByMonitorId.rejects(testError);
try {
@@ -190,9 +203,10 @@ describe("NotificationService", () => {
});
});
describe("handleHardwareNotifications", async () => {
describe("handleHardwareNotifications", function() {
let networkResponse;
beforeEach(() => {
beforeEach(function() {
networkResponse = {
monitor: {
name: "Test Monitor",
@@ -225,26 +239,27 @@ describe("NotificationService", () => {
},
};
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("it should return false if no thresholds are set", () => {
it("should return false if no thresholds are set", async () => {
describe("it should return false if no thresholds are set", function() {
it("should return false if no thresholds are set", async function() {
networkResponse.monitor.thresholds = undefined;
const res =
await notificationService.handleHardwareNotifications(networkResponse);
expect(res).to.be.false;
});
it("should return false if metrics are null", async () => {
it("should return false if metrics are null", async function() {
networkResponse.payload.data = null;
const res =
await notificationService.handleHardwareNotifications(networkResponse);
expect(res).to.be.false;
});
it("should return true if request is well formed and thresholds > 0", async () => {
it("should return true if request is well formed and thresholds > 0", async function() {
db.getNotificationsByMonitorId.resolves([
{
type: "email",
@@ -261,7 +276,7 @@ describe("NotificationService", () => {
expect(res).to.be.true;
});
it("should return true if thresholds are exceeded", async () => {
it("should return true if thresholds are exceeded", async function() {
db.getNotificationsByMonitorId.resolves([
{
type: "email",

View File

@@ -4,8 +4,9 @@ import { expect } from "chai";
import NetworkService from "../../service/networkService.js";
const SERVICE_NAME = "SettingsService";
describe("SettingsService", () => {
describe("SettingsService", function() {
let sandbox, mockAppSettings;
beforeEach(function () {
sandbox = sinon.createSandbox();
sandbox.stub(process.env, "CLIENT_HOST").value("http://localhost");
@@ -35,14 +36,16 @@ describe("SettingsService", () => {
sandbox.restore();
sinon.restore();
});
describe("constructor", () => {
it("should construct a new SettingsService", () => {
describe("constructor", function() {
it("should construct a new SettingsService", function() {
const settingsService = new SettingsService(mockAppSettings);
expect(settingsService.appSettings).to.equal(mockAppSettings);
});
});
describe("loadSettings", () => {
it("should load settings from DB when environment variables are not set", async () => {
describe("loadSettings", function() {
it("should load settings from DB when environment variables are not set", async function() {
const dbSettings = { logLevel: "debug", apiBaseUrl: "http://localhost" };
const appSettings = { findOne: sinon.stub().returns(dbSettings) };
const settingsService = new SettingsService(appSettings);
@@ -50,6 +53,7 @@ describe("SettingsService", () => {
const result = await settingsService.loadSettings();
expect(result).to.deep.equal(dbSettings);
});
it("should throw an error if settings are not found", async function () {
const appSettings = { findOne: sinon.stub().returns(null) };
const settingsService = new SettingsService(appSettings);
@@ -64,7 +68,7 @@ describe("SettingsService", () => {
}
});
it("should add its method and service name to error if not present", async () => {
it("should add its method and service name to error if not present", async function() {
const appSettings = { findOne: sinon.stub().throws(new Error("Test error")) };
const settingsService = new SettingsService(appSettings);
try {
@@ -75,7 +79,8 @@ describe("SettingsService", () => {
expect(error.method).to.equal("loadSettings");
}
});
it("should not add its method and service name to error if present", async () => {
it("should not add its method and service name to error if present", async function() {
const error = new Error("Test error");
error.method = "otherMethod";
error.service = "OTHER_SERVICE";
@@ -89,6 +94,7 @@ describe("SettingsService", () => {
expect(error.method).to.equal("otherMethod");
}
});
it("should merge DB settings with environment variables", async function () {
const dbSettings = { logLevel: "debug", apiBaseUrl: "http://localhost" };
const appSettings = { findOne: sinon.stub().returns(dbSettings) };
@@ -99,8 +105,9 @@ describe("SettingsService", () => {
expect(settingsService.settings.apiBaseUrl).to.equal("http://localhost");
});
});
describe("reloadSettings", () => {
it("should call loadSettings", async () => {
describe("reloadSettings", function() {
it("should call loadSettings", async function() {
const dbSettings = { logLevel: "debug", apiBaseUrl: "http://localhost" };
const appSettings = { findOne: sinon.stub().returns(dbSettings) };
const settingsService = new SettingsService(appSettings);
@@ -109,8 +116,9 @@ describe("SettingsService", () => {
expect(result).to.deep.equal(dbSettings);
});
});
describe("getSettings", () => {
it("should return the current settings", () => {
describe("getSettings", function() {
it("should return the current settings", function() {
const dbSettings = { logLevel: "debug", apiBaseUrl: "http://localhost" };
const appSettings = { findOne: sinon.stub().returns(dbSettings) };
const settingsService = new SettingsService(appSettings);
@@ -118,7 +126,8 @@ describe("SettingsService", () => {
const result = settingsService.getSettings();
expect(result).to.deep.equal(dbSettings);
});
it("should throw an error if settings have not been loaded", () => {
it("should throw an error if settings have not been loaded", function() {
const appSettings = { findOne: sinon.stub().returns(null) };
const settingsService = new SettingsService(appSettings);
settingsService.settings = null;

View File

@@ -4,7 +4,8 @@ import { afterEach, describe } from "node:test";
describe("StatusService", () => {
let db, logger, statusService;
beforeEach(() => {
beforeEach(function() {
db = {
getMonitorById: sinon.stub(),
createCheck: sinon.stub(),
@@ -22,31 +23,35 @@ describe("StatusService", () => {
});
describe("constructor", () => {
it("should create an instance of StatusService", () => {
it("should create an instance of StatusService", function() {
expect(statusService).to.be.an.instanceOf(StatusService);
});
});
describe("getStatusString", () => {
it("should return 'up' if status is true", () => {
it("should return 'up' if status is true", function() {
expect(statusService.getStatusString(true)).to.equal("up");
});
it("should return 'down' if status is false", () => {
it("should return 'down' if status is false", function() {
expect(statusService.getStatusString(false)).to.equal("down");
});
it("should return 'unknown' if status is undefined or null", () => {
it("should return 'unknown' if status is undefined or null", function() {
expect(statusService.getStatusString(undefined)).to.equal("unknown");
});
});
describe("updateStatus", async () => {
beforeEach(() => {
describe("updateStatus", () => {
beforeEach(function() {
// statusService.insertCheck = sinon.stub().resolves;
});
afterEach(() => {
sinon.restore();
});
it("should throw an error if an error occurs", async () => {
it("should throw an error if an error occurs", async function() {
const error = new Error("Test error");
statusService.db.getMonitorById = sinon.stub().throws(error);
try {
@@ -56,7 +61,8 @@ describe("StatusService", () => {
}
// expect(statusService.insertCheck.calledOnce).to.be.true;
});
it("should return {statusChanged: false} if status hasn't changed", async () => {
it("should return {statusChanged: false} if status hasn't changed", async function() {
statusService.db.getMonitorById = sinon.stub().returns({ status: true });
const result = await statusService.updateStatus({
monitorId: "test",
@@ -65,7 +71,8 @@ describe("StatusService", () => {
expect(result).to.deep.equal({ statusChanged: false });
// expect(statusService.insertCheck.calledOnce).to.be.true;
});
it("should return {statusChanged: true} if status has changed from down to up", async () => {
it("should return {statusChanged: true} if status has changed from down to up", async function() {
statusService.db.getMonitorById = sinon
.stub()
.returns({ status: false, save: sinon.stub() });
@@ -78,7 +85,8 @@ describe("StatusService", () => {
expect(result.prevStatus).to.be.false;
// expect(statusService.insertCheck.calledOnce).to.be.true;
});
it("should return {statusChanged: true} if status has changed from up to down", async () => {
it("should return {statusChanged: true} if status has changed from up to down", async function() {
statusService.db.getMonitorById = sinon
.stub()
.returns({ status: true, save: sinon.stub() });
@@ -94,7 +102,7 @@ describe("StatusService", () => {
});
describe("buildCheck", () => {
it("should build a check object", () => {
it("should build a check object", function() {
const check = statusService.buildCheck({
monitorId: "test",
type: "test",
@@ -111,7 +119,7 @@ describe("StatusService", () => {
expect(check.message).to.equal("Test message");
});
it("should build a check object for pagespeed type", () => {
it("should build a check object for pagespeed type", function() {
const check = statusService.buildCheck({
monitorId: "test",
type: "pagespeed",
@@ -154,7 +162,8 @@ describe("StatusService", () => {
tbt: { score: 1 },
});
});
it("should build a check object for pagespeed type with missing data", () => {
it("should build a check object for pagespeed type with missing data", function() {
const check = statusService.buildCheck({
monitorId: "test",
type: "pagespeed",
@@ -186,7 +195,8 @@ describe("StatusService", () => {
tbt: 0,
});
});
it("should build a check for hardware type", () => {
it("should build a check for hardware type", function() {
const check = statusService.buildCheck({
monitorId: "test",
type: "hardware",
@@ -206,7 +216,8 @@ describe("StatusService", () => {
expect(check.disk).to.equal("disk");
expect(check.host).to.equal("host");
});
it("should build a check for hardware type with missing data", () => {
it("should build a check for hardware type with missing data", function() {
const check = statusService.buildCheck({
monitorId: "test",
type: "hardware",
@@ -227,8 +238,9 @@ describe("StatusService", () => {
expect(check.host).to.deep.equal({});
});
});
describe("insertCheck", () => {
it("should log an error if one is thrown", async () => {
it("should log an error if one is thrown", async function() {
const testError = new Error("Test error");
statusService.db.createCheck = sinon.stub().throws(testError);
try {
@@ -238,7 +250,8 @@ describe("StatusService", () => {
}
expect(statusService.logger.error.calledOnce).to.be.true;
});
it("should insert a check into the database", async () => {
it("should insert a check into the database", async function() {
await statusService.insertCheck({ monitorId: "test", type: "http" });
expect(statusService.db.createCheck.calledOnce).to.be.true;
});

View File

@@ -1,8 +1,8 @@
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", () => {
describe("NormalizeData", function() {
it("should normalize response times when checks length is greater than 1", function() {
const checks = [
{ responseTime: 20, _doc: { id: 1 } },
{ responseTime: 40, _doc: { id: 2 } },
@@ -21,7 +21,7 @@ describe("NormalizeData", () => {
});
});
it("should return checks with original response times when checks length is 1", () => {
it("should return checks with original response times when checks length is 1", function() {
const checks = [{ responseTime: 20, _doc: { id: 1 } }];
const rangeMin = 1;
const rangeMax = 100;
@@ -32,7 +32,7 @@ describe("NormalizeData", () => {
expect(result[0]).to.have.property("originalResponseTime", 20);
});
it("should handle edge cases with extreme response times", () => {
it("should handle edge cases with extreme response times", function() {
const checks = [
{ responseTime: 5, _doc: { id: 1 } },
{ responseTime: 95, _doc: { id: 2 } },
@@ -49,8 +49,8 @@ describe("NormalizeData", () => {
});
});
describe("calculatePercentile", () => {
it("should return the lower value when upper is greater than or equal to the length of the sorted array", () => {
describe("calculatePercentile", function() {
it("should return the lower value when upper is greater than or equal to the length of the sorted array", function() {
const checks = [
{ responseTime: 10 },
{ responseTime: 20 },

View File

@@ -3,8 +3,8 @@ 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 () => {
describe("imageProcessing - GenerateAvatarImage", function() {
it("should resize the image to 64x64 and return a base64 string", async function() {
const file = {
buffer: Buffer.from("test image buffer"),
};
@@ -30,7 +30,7 @@ describe("imageProcessing - GenerateAvatarImage", () => {
sharpStub.restore();
});
it("should throw an error if resizing fails", async () => {
it("should throw an error if resizing fails", async function() {
const file = {
buffer: Buffer.from("test image buffer"),
};

View File

@@ -3,20 +3,20 @@ import logger from "../../utils/logger.js";
import { Logger } from "../../utils/logger.js";
import winston from "winston";
describe("Logger", () => {
describe("Logger", function() {
let infoStub, warnStub, errorStub;
beforeEach(() => {
beforeEach(function() {
infoStub = sinon.stub(logger.logger, "info");
warnStub = sinon.stub(logger.logger, "warn");
errorStub = sinon.stub(logger.logger, "error");
});
afterEach(() => {
afterEach(function() {
sinon.restore();
});
describe("constructor", () => {
describe("constructor", function() {
let createLoggerStub;
beforeEach(function () {
@@ -46,6 +46,7 @@ describe("Logger", () => {
const logger = new Logger();
logger.logger.info(logMessage);
});
it("should convert details to JSON string if it is an object", function () {
const logDetails = { key: "value" };
const expectedDetails = JSON.stringify(logDetails, null, 2); // Removed .s
@@ -68,8 +69,8 @@ describe("Logger", () => {
});
});
describe("info", () => {
it("should log an informational message", () => {
describe("info", function() {
it("should log an informational message", function() {
const config = {
message: "Info message",
service: "TestService",
@@ -90,8 +91,8 @@ describe("Logger", () => {
});
});
describe("warn", () => {
it("should log a warning message", () => {
describe("warn", function() {
it("should log a warning message", function() {
const config = {
message: "Warning message",
service: "TestService",
@@ -112,8 +113,8 @@ describe("Logger", () => {
});
});
describe("error", () => {
it("should log an error message", () => {
describe("error", function() {
it("should log an error message", function() {
const config = {
message: "Error message",
service: "TestService",

View File

@@ -1,14 +1,14 @@
import { errorMessages, successMessages } from "../../utils/messages.js";
describe("Messages", () => {
describe("messages - errorMessages", () => {
it("should have a DB_FIND_MONITOR_BY_ID function", () => {
describe("Messages", function() {
describe("messages - errorMessages", function() {
it("should have a DB_FIND_MONITOR_BY_ID function", 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", () => {
it("should have a DB_DELETE_CHECKS function", function() {
const monitorId = "12345";
expect(errorMessages.DB_DELETE_CHECKS(monitorId)).to.equal(
`No checks found for monitor with id ${monitorId}`
@@ -16,8 +16,8 @@ describe("Messages", () => {
});
});
describe("messages - successMessages", () => {
it("should have a MONITOR_GET_BY_USER_ID function", () => {
describe("messages - successMessages", function() {
it("should have a MONITOR_GET_BY_USER_ID function", function() {
const userId = "12345";
expect(successMessages.MONITOR_GET_BY_USER_ID(userId)).to.equal(
`Got monitor for ${userId} successfully"`

View File

@@ -1,49 +1,49 @@
import { ParseBoolean, getTokenFromHeaders } from "../../utils/utils.js";
describe("utils - ParseBoolean", () => {
it("should return true", () => {
describe("utils - ParseBoolean", function() {
it("should return true", function() {
const result = ParseBoolean("true");
expect(result).to.be.true;
});
it("should return false", () => {
it("should return false", function() {
const result = ParseBoolean("false");
expect(result).to.be.false;
});
it("should return false", () => {
it("should return false", function() {
const result = ParseBoolean(null);
expect(result).to.be.false;
});
it("should return false", () => {
it("should return false", function() {
const result = ParseBoolean(undefined);
expect(result).to.be.false;
});
});
describe("utils - getTokenFromHeaders", () => {
it("should throw an error if authorization header is missing", () => {
describe("utils - getTokenFromHeaders", function() {
it("should throw an error if authorization header is missing", function() {
const headers = {};
expect(() => getTokenFromHeaders(headers)).to.throw("No auth headers");
});
it("should throw an error if authorization header does not start with Bearer", () => {
it("should throw an error if authorization header does not start with Bearer", function() {
const headers = { authorization: "Basic abcdef" };
expect(() => getTokenFromHeaders(headers)).to.throw("Invalid auth headers");
});
it("should return the token if authorization header is correctly formatted", () => {
it("should return the token if authorization header is correctly formatted", function() {
const headers = { authorization: "Bearer abcdef" };
expect(getTokenFromHeaders(headers)).to.equal("abcdef");
});
it("should throw an error if authorization header has more than two parts", () => {
it("should throw an error if authorization header has more than two parts", function() {
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", () => {
it("should throw an error if authorization header has less than two parts", function() {
const headers = { authorization: "Bearer" };
expect(() => getTokenFromHeaders(headers)).to.throw("Invalid auth headers");
});

83
grant_funding.md Normal file
View File

@@ -0,0 +1,83 @@
<h1>Announcing USD 5K Grant Prize for Distributed Uptime Management Development</h1>
### January 9, 2025, [Checkmate](https://github.com/bluewave-labs/checkmate) & [UpRock](https://uprock.com/)
**Checkmate** and **UpRock** are excited to announce a USD 5,000 grant prize funding opportunity to support the development of the next-generation distributed uptime manager. UpRock, a DePIN platform with over 2 million devices worldwide, provides the foundation for Checkmate to monitor server uptime from across the globe effectively.
This grant funding aims to empower developers to contribute innovative solutions to enhance Checkmate's functionality and usability for distributed uptime management, powered by **UpRock**.
## Program details
* **Submission start date:** January 9, 2025
* **Submission deadline:** January 20, 2025
* **Announcement of prewinners:** January 25, 2025
* **Total prize pool:** USD 5,000 (subject to change depending on the quality or number submissions)
* **Completion timeline:** A maximum of 30 days after pre-selection
## What were looking for
* Participants are encouraged to submit ideas and features that:
* Enhance Checkmate & UpRock's distributed uptime monitoring capabilities.
* Simplify deployment for businesses and scale effectively.
* Deliver innovative value-adds to Checkmate and UpRock platform.
* Improve UI/UX consistency, performance, and monitoring reliability.
Here are some of the sample ideas you can select from, or come up with your own.
* **Project 1 (DePIN sourced intelligence):** Build a global internet speed survey using 3M devices. This dashboard will implement the underlying Checkmate & UpRock infrastructure and build maps and tables for: 1. Upload speed, 2. Download speed, 3. Ping numbers.
* **Project 2:** Build a notification system that will cover Discord, Slack, Telegram and webhooks.
* **Project 3:** Implement a i18n library for Checkmate. The translation framework will include modifying the source code and using an open source translation manager online so other translators can also contribute. This will help reach out to more developers to build DePIN features on top of Checkmate.
* **Project 4:** A plugin system and implementation for Checkmate to help add more UpRock platform functionality. This plugin system will also be used to add more plugins/features on top of Checkmate easily.
* **Project 5 (Checkmate CLI):** When installed via brew or curl, this CLI will help admins manage the monitoring setup directly from the command line. Admin will be able to list, check, trigger the monitors from the command line easily or change password of the users, or create/invite a new user.
* **Project 6:** Ability to tag or group monitors. Each monitor will have its own tagging, and the admin will be able to filter monitors in the table.
* **Project 7:** Deploy Checkmate and write a blog post about it on dev.to or Hackernoon. Bonus points if you market it on social media.
## How to participate
1. **Submit your ideas:** Fill out our online form to propose enhancements and features for Checkmate powered by UpRock, until January 20, 2025. You can submit a project based on the ideas above, or you can also come up with your own enhancement projects.
2. S**election criteria:** Prewinners will be selected based on functionality, design and impact.
3. **Implementation phase:** Prewinners will have 21 days to develop and submit their code contributions starting from January 25, 2025.
4. **Quality requirements:** Submitted code must:
- Be high quality and free from bugs.
- Pass extensive QA testing
- Adhere to Checkmates UI design and development standards.
5. **Grant disbursement:** Upon code acceptance via pull, winners will receive USD 1,000 each, sent to their bank account or Paypal.
## Timeline
- **January 10, 2025:** Grant announcement and form open for submissions.
- **January 20, 2025:** Submission deadline
- **January 25, 2025:** Winners announced.
- **21 days post-selection:** Code development and submission period.
- **Grant payment:** Issued in 14 days upon PR acceptance.
## Rules
- **Cap enforcement:** All projects submitted to the Checkmate & UpRock grant program will be subject to a strict funding cap of $1000 per project. This rule ensures that funding is distributed fairly among contributors, encouraging a diverse range of submissions. Applicants are encouraged to scope their projects accordingly to stay within this limit. Proposals exceeding this amount may either be revised or considered for partial funding.
- **Multiple submissions:** Contributors are welcome to submit multiple projects, provided each submission adheres to the specified funding cap and size criteria. This approach allows developers to showcase various ideas, features, and improvements without being constrained to a single proposal. Each project will be evaluated independently, ensuring fair consideration regardless of other submissions by the same contributor.
- **Partial funding:** In cases where a proposal exceeds the budget limit or includes additional features that extend beyond the core requirements, partial funding may be offered. Contributors will receive feedback and recommendations to adjust their project scope to align with the funding guidelines. This flexibility ensures that high-value features and enhancements can still be supported, even if full funding is not feasible.
- **Feedback process:** To support continuous improvement, contributors will receive constructive feedback on their submissions, whether accepted or not. Feedback will focus on areas such as code quality, design patterns, documentation and usability. Developers can use this input to refine their proposals, submit follow-ups, or enhance their future contributions.
- **Final review and recognition:** A portion of the total funding, $500 (10%), will be reserved for recognizing outstanding contributions across all categories. This award, labeled the "Best Overall Contribution" prize, will be given to a project that demonstrates exceptional innovation, technical quality, and impact. The selection process will be based on the same evaluation criteria as other submissions, with additional emphasis on originality and long-term value to the Checkmate & UpRock ecosystem.
## Funding tiers
- **4-5 small size projects**
- Examples: Usability fixes, UI enhancements, updating test cases, writing command line interfaces or documentation updates.
- Reward: $100$300
- **4-5 medium size projects**
- Examples: New monitoring modules/additions, API enhancements, performance improvements or feature additions.
- Reward: $300$600
- **1-2 large projects**
- Examples: Integrations with 3rd party / external tools, major scalability enhancements, advanced analytics features, complex monitoring capabilities, better graphics/charts.
- Reward: $600$1000
## Evaluation criteria
- **Innovation (30%):** Uniqueness and creativity of the solution.
- **Contribution value (30%):** Impact on usability, performance, or scalability.
- **Code quality & design (40%):** Clean, documented and tested code with working examples showing screenshots and/or videos.
## Ready to innovate for distributed uptime?
Dont miss this opportunity to shape the future of distributed uptime monitoring with Checkmate and UpRock! Submit your ideas today and join us in building cutting-edge solutions for global server management.
Visit Link to submit your entry.