aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin J Hoerr <kjhoerr@protonmail.com>2020-04-27 05:23:23 -0400
committerKevin J Hoerr <kjhoerr@protonmail.com>2020-04-27 05:23:23 -0400
commit32db5f6e5e8b6f6d2baffbec44cc34daedd24533 (patch)
tree9c2687baec92e70a28690165729ff871c2d147c3 /src
parent051ff1871a163c62f1c5f5aa5ffb0ac18da49424 (diff)
downloadao-coverage-32db5f6e5e8b6f6d2baffbec44cc34daedd24533.tar.gz
ao-coverage-32db5f6e5e8b6f6d2baffbec44cc34daedd24533.tar.bz2
ao-coverage-32db5f6e5e8b6f6d2baffbec44cc34daedd24533.zip
Add unit tests and correct CHANGELOG
Diffstat (limited to 'src')
-rw-r--r--src/routes.test.ts11
-rw-r--r--src/util/config.test.ts182
-rw-r--r--src/util/config.ts12
3 files changed, 197 insertions, 8 deletions
diff --git a/src/routes.test.ts b/src/routes.test.ts
index 3579011..90084f6 100644
--- a/src/routes.test.ts
+++ b/src/routes.test.ts
@@ -117,6 +117,17 @@ describe("Static files", () => {
.expect(200);
expect(res.text).toEqual(buffer.toString("utf-8"));
});
+
+ it("should return 404.html at unhandled endpoints", async () => {
+ const buffer = await fs.promises.readFile(
+ path.join(staticRoot, "404.html")
+ );
+
+ const res = await request()
+ .get("/thisisnotanendpoint")
+ .expect(404);
+ expect(res.text).toEqual(buffer.toString("utf-8"));
+ });
});
describe("Badges and reports", () => {
diff --git a/src/util/config.test.ts b/src/util/config.test.ts
index 418edb7..b1e7df3 100644
--- a/src/util/config.test.ts
+++ b/src/util/config.test.ts
@@ -2,9 +2,17 @@ const exit = jest
.spyOn(process, "exit")
.mockImplementation(() => undefined as never);
-import { configOrError, handleShutdown } from "./config";
-import { MongoClient } from "mongodb";
+import {
+ configOrError,
+ persistTemplate,
+ handleStartup,
+ handleShutdown
+} from "./config";
+import { MongoClient, MongoError } from "mongodb";
import { Server } from "http";
+import path from "path";
+import fs from "fs";
+import * as templates from "../templates";
const CommonMocks = {
connect: jest.fn(),
@@ -92,6 +100,176 @@ describe("configOrError", () => {
});
});
+describe("persistTemplate", () => {
+ beforeEach(() => {
+ exit.mockClear();
+ });
+
+ it("should generate a template without error", async () => {
+ const template = {
+ inputFile: "/mnt/c/Windows/System32",
+ outputFile: "./helloworld.txt",
+ context: { EXAMPLE: "this" }
+ } as templates.Template;
+ const processTemplate = jest
+ .spyOn(templates, "default")
+ .mockImplementation(
+ (template: templates.Template) => new Promise(res => res(template))
+ );
+ const fsAccess = jest.spyOn(fs.promises, "access").mockResolvedValue();
+
+ await persistTemplate(template);
+
+ expect(processTemplate).toHaveBeenCalledWith(template);
+ expect(fsAccess).not.toHaveBeenCalled();
+ expect(exit).not.toHaveBeenCalled();
+ processTemplate.mockRestore();
+ fsAccess.mockRestore();
+ });
+
+ it("should exit without error if template does not generate but file already exists", async () => {
+ const template = {
+ inputFile: "/mnt/c/Windows/System32",
+ outputFile: "./helloworld.txt",
+ context: { EXAMPLE: "this" }
+ } as templates.Template;
+ const processTemplate = jest
+ .spyOn(templates, "default")
+ .mockRejectedValue("baa");
+ const fsAccess = jest.spyOn(fs.promises, "access").mockResolvedValue();
+
+ await persistTemplate(template);
+
+ expect(processTemplate).toHaveBeenCalledWith(template);
+ expect(fsAccess).toHaveBeenCalledWith(
+ template.outputFile,
+ fs.constants.R_OK
+ );
+ expect(exit).not.toHaveBeenCalled();
+ processTemplate.mockRestore();
+ fsAccess.mockRestore();
+ });
+
+ it("should exit with error if template does not generate and file does not exist", async () => {
+ const template = {
+ inputFile: "/mnt/c/Windows/System32",
+ outputFile: "./helloworld.txt",
+ context: { EXAMPLE: "this" }
+ } as templates.Template;
+ const processTemplate = jest
+ .spyOn(templates, "default")
+ .mockRejectedValue("baz");
+ const fsAccess = jest.spyOn(fs.promises, "access").mockRejectedValue("bar");
+
+ await persistTemplate(template);
+
+ expect(processTemplate).toHaveBeenCalledWith(template);
+ expect(fsAccess).toHaveBeenCalledWith(
+ template.outputFile,
+ fs.constants.R_OK
+ );
+ expect(exit).toHaveBeenCalledWith(1);
+ processTemplate.mockRestore();
+ fsAccess.mockRestore();
+ });
+});
+
+describe("handleStartup", () => {
+ beforeEach(() => {
+ exit.mockClear();
+ });
+
+ it("should pass back MongoClient", async () => {
+ const superClient = {} as MongoClient;
+ const fsAccess = jest.spyOn(fs.promises, "access").mockResolvedValue();
+ const pathAbsolute = jest.spyOn(path, "isAbsolute").mockReturnValue(true);
+ const pathJoin = jest.spyOn(path, "join").mockReturnValue("path");
+ const mongoClient = jest.spyOn(MongoClient, "connect").mockImplementation(
+ () => new Promise<MongoClient>(res => res(superClient))
+ );
+ const processTemplate = jest
+ .spyOn(templates, "default")
+ .mockImplementation(
+ (template: templates.Template) => new Promise(res => res(template))
+ );
+
+ const result = await handleStartup();
+
+ expect(fsAccess).toHaveBeenCalledTimes(1);
+ expect(pathAbsolute).toHaveBeenCalledTimes(1);
+ expect(mongoClient).toHaveBeenCalledTimes(1);
+ expect(processTemplate).toHaveBeenCalledTimes(2);
+ expect(exit).not.toHaveBeenCalled();
+ expect(result).toEqual(superClient);
+ processTemplate.mockRestore();
+ mongoClient.mockRestore();
+ pathAbsolute.mockRestore();
+ pathJoin.mockRestore();
+ fsAccess.mockRestore();
+ });
+
+ it("should exit if HOST_DIR is not read/write accessible", async () => {
+ const fsAccess = jest.spyOn(fs.promises, "access").mockRejectedValue("boo");
+ const pathAbsolute = jest.spyOn(path, "isAbsolute").mockReturnValue(true);
+ const pathJoin = jest.spyOn(path, "join").mockReturnValue("path");
+
+ const result = await handleStartup();
+
+ expect(fsAccess).toHaveBeenCalledTimes(1);
+ expect(exit).toHaveBeenCalledWith(1);
+ expect(pathAbsolute).not.toHaveBeenCalled();
+ expect(result).toBeUndefined();
+ pathAbsolute.mockRestore();
+ pathJoin.mockRestore();
+ fsAccess.mockRestore();
+ });
+
+ it("should exit if HOST_DIR is not absolute path", async () => {
+ const superClient = {} as MongoClient;
+ const fsAccess = jest.spyOn(fs.promises, "access").mockResolvedValue();
+ const pathAbsolute = jest.spyOn(path, "isAbsolute").mockReturnValue(false);
+ const pathJoin = jest.spyOn(path, "join").mockReturnValue("path");
+ const mongoClient = jest.spyOn(MongoClient, "connect").mockImplementation(
+ () => new Promise<MongoClient>(res => res(superClient))
+ );
+
+ await handleStartup();
+
+ expect(pathAbsolute).toHaveBeenCalledTimes(1);
+ expect(exit).toHaveBeenCalledWith(1);
+ mongoClient.mockRestore();
+ pathAbsolute.mockRestore();
+ pathJoin.mockRestore();
+ fsAccess.mockRestore();
+ });
+
+ it("should exit if MongoClient has error", async () => {
+ const fsAccess = jest.spyOn(fs.promises, "access").mockResolvedValue();
+ const pathAbsolute = jest.spyOn(path, "isAbsolute").mockReturnValue(true);
+ const pathJoin = jest.spyOn(path, "join").mockReturnValue("path");
+ const mongoClient = jest
+ .spyOn(MongoClient, "connect")
+ .mockImplementation(
+ () => new Promise((_, rej) => rej({ message: "aaahhh" } as MongoError))
+ );
+ const processTemplate = jest
+ .spyOn(templates, "default")
+ .mockImplementation(
+ (template: templates.Template) => new Promise(res => res(template))
+ );
+
+ await handleStartup();
+
+ expect(mongoClient).toHaveBeenCalledTimes(1);
+ expect(exit).toHaveBeenCalledWith(1);
+ processTemplate.mockRestore();
+ mongoClient.mockRestore();
+ pathAbsolute.mockRestore();
+ pathJoin.mockRestore();
+ fsAccess.mockRestore();
+ });
+});
+
describe("handleShutdown", () => {
beforeEach(() => {
exit.mockClear();
diff --git a/src/util/config.ts b/src/util/config.ts
index d2ad130..195d85b 100644
--- a/src/util/config.ts
+++ b/src/util/config.ts
@@ -57,12 +57,12 @@ export const handleStartup = async (): Promise<MongoClient> => {
process.exit(1);
}
- const mongo = await new MongoClient(MONGO_URI, { useUnifiedTopology: true })
- .connect()
- .catch((err: MongoError) => {
- logger.error(err.message ?? "Unable to connect to database");
- process.exit(1);
- });
+ const mongo = await MongoClient.connect(MONGO_URI, {
+ useUnifiedTopology: true
+ }).catch((err: MongoError) => {
+ logger.error(err.message ?? "Unable to connect to database");
+ process.exit(1);
+ });
await persistTemplate({
inputFile: path.join(