Add tests for fetchCertificates
This commit is contained in:
1 parent
81d3b8dcb5
commit
c356843799
5 files changed
+205
-134
No files matched your search
+6
-6
@@ -1,8 +1,8 @@
|
||||
module.exports = {
|
||||
require: ["esm", "chai/register-expect.js"], // Include Chai's "expect" interface globally
|
||||
spec: "tests/**/*.test.js", // Specify test files
|
||||
timeout: 5000, // Set test-case timeout in milliseconds
|
||||
recursive: true, // Include subdirectories
|
||||
reporter: "spec", // Use the "spec" reporter
|
||||
exit: true, // Force Mocha to quit after tests complete
|
||||
require: ["esm", "chai/register-expect.js"], // Include Chai's "expect" interface globally
|
||||
spec: "tests/**/*.test.js", // Specify test files
|
||||
timeout: 5000, // Set test-case timeout in milliseconds
|
||||
recursive: true, // Include subdirectories
|
||||
reporter: "spec", // Use the "spec" reporter
|
||||
exit: true, // Force Mocha to quit after tests complete
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
module.exports = {
|
||||
require: ["chai/register-expect.js"], // Include Chai's "expect" interface globally
|
||||
spec: "tests/**/*.test.js", // Specify test files
|
||||
timeout: 5000, // Set test-case timeout in milliseconds
|
||||
recursive: true, // Include subdirectories
|
||||
reporter: "spec", // Use the "spec" reporter
|
||||
exit: true, // Force Mocha to quit after tests complete
|
||||
};
|
||||
@@ -1,6 +1,3 @@
|
||||
import sslChecker from "ssl-checker";
|
||||
import * as tls from "tls";
|
||||
|
||||
const handleValidationError = (error, serviceName) => {
|
||||
error.status = 422;
|
||||
error.service = serviceName;
|
||||
@@ -15,11 +12,11 @@ const handleError = (error, serviceName, method, status = 500) => {
|
||||
return error;
|
||||
};
|
||||
|
||||
const fetchMonitorCertificate = async (monitor) => {
|
||||
const fetchMonitorCertificate = async (tls, monitor) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const monitorUrl = new URL(monitor.url);
|
||||
const hostname = monitorUrl.hostname;
|
||||
try {
|
||||
const monitorUrl = new URL(monitor.url);
|
||||
const hostname = monitorUrl.hostname;
|
||||
let socket = tls.connect(
|
||||
{
|
||||
port: 443,
|
||||
@@ -37,34 +34,10 @@ const fetchMonitorCertificate = async (monitor) => {
|
||||
}
|
||||
}
|
||||
);
|
||||
socket.on("error", (error) => {
|
||||
console.log(error);
|
||||
reject(
|
||||
new Error(
|
||||
`TLS connection error while fetching certificate from ${error.hostname}`
|
||||
)
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const test = async () => {
|
||||
let host = "httpbin.org";
|
||||
console.log(cert.validTo);
|
||||
let socket = tls.connect(
|
||||
{
|
||||
port: 443,
|
||||
host,
|
||||
servername: host, // this is required in case the server enabled SNI
|
||||
},
|
||||
() => {
|
||||
let x509Certificate = socket.getPeerX509Certificate();
|
||||
console.log(x509Certificate.validTo);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export { handleValidationError, handleError, fetchMonitorCertificate, test };
|
||||
export { handleValidationError, handleError, fetchMonitorCertificate };
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
getMonitorStatsByIdQueryValidation,
|
||||
getCertificateParamValidation,
|
||||
} from "../validation/joi.js";
|
||||
import * as tls from "tls";
|
||||
|
||||
const SERVICE_NAME = "monitorController";
|
||||
import { errorMessages, successMessages } from "../utils/messages.js";
|
||||
@@ -86,7 +87,7 @@ const getMonitorCertificate = async (req, res, next) => {
|
||||
try {
|
||||
const { monitorId } = req.params;
|
||||
const monitor = await req.db.getMonitorById(monitorId);
|
||||
const certificate = await fetchMonitorCertificate(monitor);
|
||||
const certificate = await fetchMonitorCertificate(tls, monitor);
|
||||
if (certificate && certificate.validTo) {
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -1,105 +1,210 @@
|
||||
import sinon from "sinon";
|
||||
|
||||
import {
|
||||
handleValidationError,
|
||||
handleError,
|
||||
handleValidationError,
|
||||
handleError,
|
||||
fetchMonitorCertificate,
|
||||
} from "../../controllers/controllerUtils.js";
|
||||
import { expect } from "chai";
|
||||
|
||||
describe("controllerUtils - handleValidationError", () => {
|
||||
it("should set status to 422", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.status).to.equal(422);
|
||||
});
|
||||
it("should set status to 422", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.status).to.equal(422);
|
||||
});
|
||||
|
||||
it("should set service to the provided serviceName", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.service).to.equal(serviceName);
|
||||
});
|
||||
it("should set service to the provided serviceName", () => {
|
||||
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", () => {
|
||||
const error = {
|
||||
details: [{ message: "Detail message" }],
|
||||
};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Detail message");
|
||||
});
|
||||
it("should set message to error.details[0].message if present", () => {
|
||||
const error = {
|
||||
details: [{ message: "Detail message" }],
|
||||
};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Detail message");
|
||||
});
|
||||
|
||||
it("should set message to error.message if error.details is not present", () => {
|
||||
const error = {
|
||||
message: "Error message",
|
||||
};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Error message");
|
||||
});
|
||||
it("should set message to error.message if error.details is not present", () => {
|
||||
const error = {
|
||||
message: "Error message",
|
||||
};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Error message");
|
||||
});
|
||||
|
||||
it('should set message to "Validation Error" if neither error.details nor error.message is present', () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Validation Error");
|
||||
});
|
||||
it('should set message to "Validation Error" if neither error.details nor error.message is present', () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const result = handleValidationError(error, serviceName);
|
||||
expect(result.message).to.equal("Validation Error");
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleError", () => {
|
||||
it("should set stats to the provided status if error.code is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const status = 400;
|
||||
const result = handleError(error, serviceName, method, status);
|
||||
expect(result.status).to.equal(status);
|
||||
});
|
||||
describe("controllerUtils - handleError", () => {
|
||||
it("should set stats to the provided status if error.code is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const status = 400;
|
||||
const result = handleError(error, serviceName, method, status);
|
||||
expect(result.status).to.equal(status);
|
||||
});
|
||||
|
||||
it("should not overwrite error.code if it is already defined", () => {
|
||||
const error = { status: 404 };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const status = 400;
|
||||
const result = handleError(error, serviceName, method, status);
|
||||
expect(result.status).to.equal(404);
|
||||
});
|
||||
it("should not overwrite error.code if it is already defined", () => {
|
||||
const error = { status: 404 };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const status = 400;
|
||||
const result = handleError(error, serviceName, method, status);
|
||||
expect(result.status).to.equal(404);
|
||||
});
|
||||
|
||||
it("should set service to the provided serviceName if error.service is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.service).to.equal(serviceName);
|
||||
});
|
||||
it("should set service to the provided serviceName if error.service is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.service).to.equal(serviceName);
|
||||
});
|
||||
|
||||
it("should not overwrite error.service if it is already defined", () => {
|
||||
const error = { service: "ExistingService" };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.service).to.equal("ExistingService");
|
||||
});
|
||||
it("should not overwrite error.service if it is already defined", () => {
|
||||
const error = { service: "ExistingService" };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.service).to.equal("ExistingService");
|
||||
});
|
||||
|
||||
it("should set method to the provided method if error.method is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.method).to.equal(method);
|
||||
});
|
||||
it("should set method to the provided method if error.method is undefined", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.method).to.equal(method);
|
||||
});
|
||||
|
||||
it("should not overwrite error.method if it is already defined", () => {
|
||||
const error = { method: "existingMethod" };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.method).to.equal("existingMethod");
|
||||
});
|
||||
it("should not overwrite error.method if it is already defined", () => {
|
||||
const error = { method: "existingMethod" };
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.method).to.equal("existingMethod");
|
||||
});
|
||||
|
||||
it("should set code to 500 if error.code is undefined and no code is provided", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.status).to.equal(500);
|
||||
});
|
||||
it("should set code to 500 if error.code is undefined and no code is provided", () => {
|
||||
const error = {};
|
||||
const serviceName = "TestService";
|
||||
const method = "testMethod";
|
||||
const result = handleError(error, serviceName, method);
|
||||
expect(result.status).to.equal(500);
|
||||
});
|
||||
});
|
||||
|
||||
describe("controllerUtils - fetchMonitorCertificate", () => {
|
||||
const originalTls = {
|
||||
connect: sinon.stub().callsFake((options, callback) => {
|
||||
// Create socket stub with sinon stubs for all methods
|
||||
socket = {
|
||||
getPeerX509Certificate: sinon.stub().returns({
|
||||
subject: "CN=fake-cert",
|
||||
validTo: "Dec 31 23:59:59 2023 GMT",
|
||||
}),
|
||||
end: sinon.stub(),
|
||||
on: sinon.stub(),
|
||||
};
|
||||
|
||||
// Use process.nextTick to ensure async behavior
|
||||
process.nextTick(() => {
|
||||
callback.call(socket); // Ensure correct 'this' binding
|
||||
});
|
||||
|
||||
return socket;
|
||||
}),
|
||||
};
|
||||
|
||||
let tls, monitor, socket;
|
||||
beforeEach(() => {
|
||||
monitor = { url: "https://www.google.com" };
|
||||
tls = {
|
||||
connect: sinon.stub().callsFake((options, callback) => {
|
||||
// Create socket stub with sinon stubs for all methods
|
||||
socket = {
|
||||
getPeerX509Certificate: sinon.stub().returns({
|
||||
subject: "CN=fake-cert",
|
||||
validTo: "Dec 31 23:59:59 2023 GMT",
|
||||
}),
|
||||
end: sinon.stub(),
|
||||
on: sinon.stub(),
|
||||
};
|
||||
|
||||
// Use process.nextTick to ensure async behavior
|
||||
process.nextTick(() => {
|
||||
callback.call(socket); // Ensure correct 'this' binding
|
||||
});
|
||||
|
||||
return socket;
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
tls = { ...originalTls };
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it("should resolve with the certificate when the connection is successful", async () => {
|
||||
const certificate = await fetchMonitorCertificate(tls, monitor);
|
||||
expect(certificate.validTo).to.equal("Dec 31 23:59:59 2023 GMT");
|
||||
expect(socket.end.calledOnce).to.be.true;
|
||||
});
|
||||
|
||||
it("should reject with an error when the connection fails", async () => {
|
||||
tls.connect = sinon.stub().throws(new Error("Connection error"));
|
||||
try {
|
||||
await fetchMonitorCertificate(tls, monitor);
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal("Connection error");
|
||||
}
|
||||
});
|
||||
|
||||
it("should reject with an error if monitorURL is invalid", async () => {
|
||||
monitor.url = "invalid-url";
|
||||
try {
|
||||
await fetchMonitorCertificate(tls, monitor);
|
||||
} catch (error) {
|
||||
expect(error.message).to.equal("Invalid URL");
|
||||
}
|
||||
});
|
||||
it("should do a thing", async () => {
|
||||
tls = {
|
||||
connect: sinon.stub().callsFake((options, callback) => {
|
||||
// Create socket stub with sinon stubs for all methods
|
||||
socket = {
|
||||
getPeerX509Certificate: sinon.stub().throws(new Error("Certificate error")),
|
||||
end: sinon.stub(),
|
||||
on: sinon.stub(),
|
||||
};
|
||||
|
||||
// Use process.nextTick to ensure async behavior
|
||||
process.nextTick(() => {
|
||||
callback.call(socket); // Ensure correct 'this' binding
|
||||
});
|
||||
|
||||
return socket;
|
||||
}),
|
||||
};
|
||||
try {
|
||||
await fetchMonitorCertificate(tls, monitor);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user