Merge pull request #1119 from bluewave-labs/feat/be/check-module-tests

Feat/be/check module tests
This commit is contained in:
Alexander Holliday authored and GitHub committed 2024-11-07 18:29:57 -08:00
commit 1592523ae9
2 files changed
+618 -48

No files matched your search

+53 -48
View File
@@ -48,7 +48,6 @@ const createCheck = async (checkData) => {
}
await monitor.save();
return check;
} catch (error) {
error.service = SERVICE_NAME;
@@ -105,7 +104,7 @@ const getChecks = async (req) => {
const { monitorId } = req.params;
let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query;
// Default limit to 0 if not provided
limit = limit === "undefined" ? 0 : limit;
limit = limit === undefined ? 0 : limit;
// Default sort order is newest -> oldest
sortOrder = sortOrder === "asc" ? 1 : -1;
@@ -155,58 +154,64 @@ const getChecks = async (req) => {
};
const getTeamChecks = async (req) => {
const { teamId } = req.params;
let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query;
try {
const { teamId } = req.params;
let { sortOrder, limit, dateRange, filter, page, rowsPerPage } = req.query;
// Get monitorIDs
const userMonitors = await Monitor.find({ teamId: teamId }).select("_id");
// Get monitorIDs
const userMonitors = await Monitor.find({ teamId: teamId }).select("_id");
//Build check query
// Default limit to 0 if not provided
limit = limit === undefined ? 0 : limit;
// Default sort order is newest -> oldest
sortOrder = sortOrder === "asc" ? 1 : -1;
//Build check query
// Default limit to 0 if not provided
limit = limit === undefined ? 0 : limit;
// Default sort order is newest -> oldest
sortOrder = sortOrder === "asc" ? 1 : -1;
const checksQuery = { monitorId: { $in: userMonitors } };
const checksQuery = { monitorId: { $in: userMonitors } };
if (filter !== undefined) {
checksQuery.status = false;
switch (filter) {
case "all":
break;
case "down":
break;
case "resolve":
checksQuery.statusCode = 5000;
break;
default:
logger.warn({
message: "invalid filter",
service: SERVICE_NAME,
method: "getTeamChecks",
});
break;
if (filter !== undefined) {
checksQuery.status = false;
switch (filter) {
case "all":
break;
case "down":
break;
case "resolve":
checksQuery.statusCode = 5000;
break;
default:
logger.warn({
message: "invalid filter",
service: SERVICE_NAME,
method: "getTeamChecks",
});
break;
}
}
if (dateRange !== undefined) {
checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] };
}
// Skip and limit for pagination
let skip = 0;
if (page && rowsPerPage) {
skip = page * rowsPerPage;
}
const checksCount = await Check.countDocuments(checksQuery);
const checks = await Check.find(checksQuery)
.skip(skip)
.limit(rowsPerPage)
.sort({ createdAt: sortOrder })
.select(["monitorId", "status", "responseTime", "statusCode", "message"]);
return { checksCount, checks };
} catch (error) {
error.service = SERVICE_NAME;
error.method = "getTeamChecks";
throw error;
}
if (dateRange !== undefined) {
checksQuery.createdAt = { $gte: dateRangeLookup[dateRange] };
}
// Skip and limit for pagination
let skip = 0;
if (page && rowsPerPage) {
skip = page * rowsPerPage;
}
const checksCount = await Check.countDocuments(checksQuery);
const checks = await Check.find(checksQuery)
.skip(skip)
.limit(rowsPerPage)
.sort({ createdAt: sortOrder })
.select(["monitorId", "status", "responseTime", "statusCode", "message"]);
return { checksCount, checks };
};
/**
+565
View File
@@ -0,0 +1,565 @@
import sinon from "sinon";
import {
createCheck,
getChecksCount,
getChecks,
getTeamChecks,
deleteChecks,
deleteChecksByTeamId,
updateChecksTTL,
} from "../../db/mongo/modules/checkModule.js";
import Check from "../../db/models/Check.js";
import Monitor from "../../db/models/Monitor.js";
import User from "../../db/models/User.js";
import logger from "../../utils/logger.js";
describe("checkModule", () => {
describe("createCheck", () => {
let checkCountDocumentsStub, checkSaveStub, monitorFindByIdStub, monitorSaveStub;
const mockMonitor = {
_id: "123",
uptimePercentage: 0.5,
status: true,
save: () => this,
};
const mockCheck = { active: true };
beforeEach(() => {
checkSaveStub = sinon.stub(Check.prototype, "save");
checkCountDocumentsStub = sinon.stub(Check, "countDocuments");
monitorFindByIdStub = sinon.stub(Monitor, "findById");
monitorSaveStub = sinon.stub(Monitor.prototype, "save");
});
afterEach(() => {
sinon.restore();
});
it("should return undefined early if no monitor is found", async () => {
monitorFindByIdStub.returns(null);
const check = await createCheck({ monitorId: "123" });
expect(check).to.be.undefined;
});
it("should return a check", async () => {
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 () => {
mockMonitor.status = false;
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
monitorSaveStub.returns(mockMonitor);
const check = await createCheck({ monitorId: "123", status: false });
expect(check).to.deep.equal(mockCheck);
});
it("should return a check if uptimePercentage is undefined", async () => {
mockMonitor.uptimePercentage = undefined;
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 uptimePercentage is undefined and status is down", async () => {
mockMonitor.uptimePercentage = undefined;
monitorFindByIdStub.returns(mockMonitor);
checkSaveStub.returns(mockCheck);
monitorSaveStub.returns(mockMonitor);
const check = await createCheck({ monitorId: "123", status: false });
expect(check).to.deep.equal(mockCheck);
});
it("should monitor save error", async () => {
const err = new Error("Save Error");
monitorSaveStub.throws(err);
try {
await createCheck({ monitorId: "123" });
} catch (error) {
expect(error).to.deep.equal(err);
}
});
it("should handle errors", async () => {
const err = new Error("DB Error");
checkCountDocumentsStub.throws(err);
try {
await createCheck({ monitorId: "123" });
} catch (error) {
expect(error).to.deep.equal(err);
}
});
});
describe("getChecksCount", () => {
let checkCountDocumentStub;
beforeEach(() => {
checkCountDocumentStub = sinon.stub(Check, "countDocuments");
});
afterEach(() => {
checkCountDocumentStub.restore();
});
it("should return count with basic monitorId query", async () => {
const req = {
params: { monitorId: "test123" },
query: {},
};
checkCountDocumentStub.resolves(5);
const result = await getChecksCount(req);
expect(result).to.equal(5);
expect(checkCountDocumentStub.calledOnce).to.be.true;
expect(checkCountDocumentStub.firstCall.args[0]).to.deep.equal({
monitorId: "test123",
});
});
it("should include dateRange in query when provided", async () => {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "day" },
};
checkCountDocumentStub.resolves(3);
const result = await getChecksCount(req);
expect(result).to.equal(3);
expect(checkCountDocumentStub.firstCall.args[0]).to.have.property("createdAt");
expect(checkCountDocumentStub.firstCall.args[0].createdAt).to.have.property("$gte");
});
it('should handle "all" filter correctly', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
};
checkCountDocumentStub.resolves(2);
const result = await getChecksCount(req);
expect(result).to.equal(2);
expect(checkCountDocumentStub.firstCall.args[0]).to.deep.equal({
monitorId: "test123",
status: false,
});
});
it('should handle "down" filter correctly', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
};
checkCountDocumentStub.resolves(2);
const result = await getChecksCount(req);
expect(result).to.equal(2);
expect(checkCountDocumentStub.firstCall.args[0]).to.deep.equal({
monitorId: "test123",
status: false,
});
});
it('should handle "resolve" filter correctly', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
};
checkCountDocumentStub.resolves(1);
const result = await getChecksCount(req);
expect(result).to.equal(1);
expect(checkCountDocumentStub.firstCall.args[0]).to.deep.equal({
monitorId: "test123",
status: false,
statusCode: 5000,
});
});
it("should handle unknown filter correctly", async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
};
checkCountDocumentStub.resolves(1);
const result = await getChecksCount(req);
expect(result).to.equal(1);
expect(checkCountDocumentStub.firstCall.args[0]).to.deep.equal({
monitorId: "test123",
status: false,
});
});
it("should combine dateRange and filter in query", async () => {
const req = {
params: { monitorId: "test123" },
query: {
dateRange: "week",
filter: "down",
},
};
checkCountDocumentStub.resolves(4);
const result = await getChecksCount(req);
expect(result).to.equal(4);
expect(checkCountDocumentStub.firstCall.args[0]).to.have.all.keys(
"monitorId",
"createdAt",
"status"
);
});
});
describe("getChecks", () => {
let checkFindStub, monitorFindStub;
beforeEach(() => {
checkFindStub = sinon.stub(Check, "find").returns({
skip: sinon.stub().returns({
limit: sinon.stub().returns({
sort: sinon.stub().returns([{ id: 1 }, { id: 2 }]),
}),
}),
});
});
afterEach(() => {
sinon.restore();
});
it("should return checks with basic monitorId query", async () => {
const req = {
params: { monitorId: "test123" },
query: {},
};
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should return checks with limit query", async () => {
const req = {
params: { monitorId: "test123" },
query: { limit: 10 },
};
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle pagination correctly", async () => {
const req = {
params: { monitorId: "test123" },
query: {
page: 2,
rowsPerPage: 10,
},
};
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle dateRange filter", async () => {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "week" },
};
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "all" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
};
await getChecks(req);
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "down" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
};
await getChecks(req);
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "resolve" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
};
await getChecks(req);
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it('should handle "unknown" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
};
await getChecks(req);
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle ascending sort order", async () => {
const req = {
params: { monitorId: "test123" },
query: { sortOrder: "asc" },
};
await getChecks(req);
const result = await getChecks(req);
expect(result).to.deep.equal([{ id: 1 }, { id: 2 }]);
});
it("should handle error case", async () => {
const req = {
params: { monitorId: "test123" },
query: {},
};
checkFindStub.throws(new Error("Database error"));
try {
await getChecks(req);
} catch (error) {
expect(error.message).to.equal("Database error");
expect(error.service).to.equal("checkModule");
expect(error.method).to.equal("getChecks");
}
});
});
describe("getTeamChecks", () => {
let checkFindStub, checkCountDocumentsStub, monitorFindStub;
const mockMonitors = [{ _id: "123" }];
beforeEach(() => {
monitorFindStub = sinon.stub(Monitor, "find").returns({
select: sinon.stub().returns(mockMonitors),
});
checkCountDocumentsStub = sinon.stub(Check, "countDocuments").returns(2);
checkFindStub = sinon.stub(Check, "find").returns({
skip: sinon.stub().returns({
limit: sinon.stub().returns({
sort: sinon.stub().returns({
select: sinon.stub().returns([{ id: 1 }, { id: 2 }]),
}),
}),
}),
});
});
afterEach(() => {
sinon.restore();
});
it("should return checks with basic monitorId query", async () => {
const req = {
params: { teamId: "test123" },
query: {},
};
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle pagination correctly", async () => {
const req = {
params: { monitorId: "test123" },
query: { limit: 1, page: 2, rowsPerPage: 10 },
};
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle dateRange filter", async () => {
const req = {
params: { monitorId: "test123" },
query: { dateRange: "week" },
};
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "all" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "all" },
};
await getChecks(req);
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "down" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "down" },
};
await getChecks(req);
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "resolve" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "resolve" },
};
await getChecks(req);
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it('should handle "unknown" filter', async () => {
const req = {
params: { monitorId: "test123" },
query: { filter: "unknown" },
};
await getChecks(req);
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle ascending sort order", async () => {
const req = {
params: { monitorId: "test123" },
query: { sortOrder: "asc" },
};
await getChecks(req);
const result = await getTeamChecks(req);
expect(result).to.deep.equal({ checksCount: 2, checks: [{ id: 1 }, { id: 2 }] });
});
it("should handle error case", async () => {
const req = {
params: { monitorId: "test123" },
query: {},
};
checkFindStub.throws(new Error("Database error"));
try {
await getTeamChecks(req);
} catch (error) {
expect(error.message).to.equal("Database error");
expect(error.service).to.equal("checkModule");
expect(error.method).to.equal("getTeamChecks");
}
});
});
describe("deleteChecks", () => {
let checkDeleteManyStub;
beforeEach(() => {
checkDeleteManyStub = sinon.stub(Check, "deleteMany").resolves({ deletedCount: 1 });
});
afterEach(() => {
sinon.restore();
});
it("should return a value if a check is deleted", async () => {
const result = await deleteChecks("123");
expect(result).to.equal(1);
});
it("should handle an error", async () => {
checkDeleteManyStub.throws(new Error("Database error"));
try {
await deleteChecks("123");
} catch (error) {
expect(error.message).to.equal("Database error");
expect(error.method).to.equal("deleteChecks");
}
});
});
describe("deleteChecksByTeamId", () => {
let mockMonitors = [{ _id: 123, save: () => this }];
let monitorFindStub, monitorSaveStub, checkDeleteManyStub;
beforeEach(() => {
monitorSaveStub = sinon.stub(Monitor.prototype, "save");
monitorFindStub = sinon.stub(Monitor, "find").returns(mockMonitors);
checkDeleteManyStub = sinon.stub(Check, "deleteMany").resolves({ deletedCount: 1 });
});
afterEach(() => {
sinon.restore();
});
it("should return a deleted count", async () => {
const result = await deleteChecksByTeamId("123");
expect(result).to.equal(1);
});
it("should handle errors", async () => {
const err = new Error("DB Error");
monitorFindStub.throws(err);
try {
const result = await deleteChecksByTeamId("123");
} catch (error) {
expect(error).to.deep.equal(err);
}
});
});
describe("updateChecksTTL", () => {
let userUpdateManyStub;
let loggerStub;
beforeEach(() => {
loggerStub = sinon.stub(logger, "error");
userUpdateManyStub = sinon.stub(User, "updateMany");
Check.collection = { dropIndex: sinon.stub(), createIndex: sinon.stub() };
});
afterEach(() => {
sinon.restore();
});
it("should return undefined", async () => {
const result = await updateChecksTTL("123", 10);
expect(result).to.be.undefined;
});
it("should log an error if dropIndex throws an error", async () => {
const err = new Error("Drop Index Error");
Check.collection.dropIndex.throws(err);
await updateChecksTTL("123", 10);
expect(loggerStub.calledOnce).to.be.true;
expect(loggerStub.firstCall.args[0].message).to.equal(err.message);
});
it("should throw an error if createIndex throws an error", async () => {
const err = new Error("Create Index Error");
Check.collection.createIndex.throws(err);
try {
await updateChecksTTL("123", 10);
} catch (error) {
expect(error).to.deep.equal(err);
}
});
it("should throw an error if User.updateMany throws an error", async () => {
const err = new Error("Update Many Error");
userUpdateManyStub.throws(err);
try {
await updateChecksTTL("123", 10);
} catch (error) {
expect(error).to.deep.equal(err);
}
});
});
});