Skip to content

Commit 42beba9

Browse files
authored
Testing Infastructure (#93)
* Database Factory Constructor A factory constructor for the database is used to allow for unit testing. * Added Testing Infastructure * Update package.json
1 parent f7b4963 commit 42beba9

22 files changed

+11178
-2899
lines changed

@types/index.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
11
export type user_token = { username: string, admin: string }
2+
export type env_file = {
3+
PORT: number,
4+
URI?: string,
5+
DB?: string,
6+
TOKEN_KEY: string,
7+
SECRET_KEY: string,
8+
ENCRYPT_KEY: string,
9+
IV_KEY: string,
10+
DOMAIN: string,
11+
PROD: boolean
12+
}

__tests__/survey.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Express } from "express"
2+
import { Server } from "http";
3+
import supertest = require("supertest");
4+
import { create_app } from "../app";
5+
import { start_server } from "../server";
6+
const request = require('supertest');
7+
8+
let app: Express
9+
let server: Server
10+
11+
beforeAll(async() => {
12+
app = await create_app()
13+
})
14+
15+
16+
test("should return OK response generating survey", (done) => {
17+
const survey_url = "https://raw.githubusercontent.com/Watts-Lab/surveyor/main/surveys/CRT.csv"
18+
19+
request(app)
20+
.get(`/s/?url=${survey_url}`)
21+
.expect(200)
22+
.end((err, res) => {
23+
if (err) return done(err);
24+
return done();
25+
})
26+
27+
})
28+

app.ts

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
1-
/** @format */
21
require("dotenv").config();
3-
import { startServer } from "./server";
2+
import express = require("express");
3+
import cors = require("cors");
4+
import { json, urlencoded } from "body-parser";
5+
import session = require("express-session");
6+
import { env_config } from "./config";
7+
import { Express } from "express"
8+
var cookieParser = require("cookie-parser")
9+
// Router Imports
10+
const links_router = require("./routes/links")
11+
const survey_router = require("./routes/survey")
12+
const auth_router = require("./routes/auth")
13+
const encrypt_router = require("./routes/encrypt")
14+
const validate_router = require("./routes/validation")
415

5-
async function main(): Promise<void> {
6-
// should be updated to Load CSV from URL (we can hard code that URL for now, and can deal with dynamic coding later)
7-
startServer();
8-
}
916

10-
main();
17+
export async function create_app():Promise<Express> {
18+
const app = express()
19+
app.use(cors())
20+
app.use(
21+
session({
22+
secret: env_config.TOKEN_KEY, // just a long random string
23+
resave: false,
24+
saveUninitialized: true,
25+
})
26+
);
27+
28+
app.set("view engine", "pug");
29+
app.use(express.static("public")); // More info on this: http://expressjs.com/en/starter/static-files.html
30+
app.use(json()); // for parsing application/json
31+
app.use(urlencoded({ extended: true })); // for parsing url
32+
app.use(cookieParser())
33+
34+
/** ROUTES */
35+
app.use("/", survey_router)
36+
app.use("/", links_router)
37+
app.use("/", auth_router)
38+
app.use("/", encrypt_router)
39+
app.use("/validate", validate_router)
40+
41+
return app
42+
}

config.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
import { Database_Wrapper } from "./interfaces";
2-
import Mongo from "./databases/prod_db";
3-
2+
import Mongo from "./databases/db";
3+
import { env_file } from "./@types";
4+
import { MongoMemoryServer } from 'mongodb-memory-server';
45

5-
6-
const env_config = {
7-
PORT: parseInt(process.env.PORT),
8-
URI: process.env.URI,
9-
DB: process.env.PROD.toLowerCase() == "true" ? process.env.PROD_DB : process.env.TEST_DB,
10-
RANDOM: process.env.RANDOM,
11-
TOKEN_KEY: process.env.TOKEN_KEY,
12-
SECRET_KEY: process.env.SECRET_KEY,
13-
ENCRYPT_KEY: process.env.ENCRYPT_KEY,
14-
IV_KEY: process.env.IV_KEY,
15-
DOMAIN: process.env.DOMAIN
6+
const env_config: env_file = {
7+
PORT: parseInt(process.env.PORT),
8+
URI: process.env.URI,
9+
DB: process.env.PROD.toLowerCase() == "true" ? process.env.PROD_DB : process.env.TEST_DB,
10+
TOKEN_KEY: process.env.TOKEN_KEY,
11+
SECRET_KEY: process.env.SECRET_KEY,
12+
ENCRYPT_KEY: process.env.ENCRYPT_KEY,
13+
IV_KEY: process.env.IV_KEY,
14+
DOMAIN: process.env.DOMAIN,
15+
PROD: process.env.PROD.toLowerCase() == "true"
1616
}
1717

1818
if (env_config.URI === undefined || env_config.DB === undefined) {
1919
throw new Error("Please set mongo db uri or db")
2020
}
2121

22-
const Db_Wrapper: Database_Wrapper = new Mongo(env_config);
23-
Db_Wrapper.set_db(env_config.DB);
24-
25-
export {Db_Wrapper, env_config}
22+
export {env_config}

databases/prod_db.ts renamed to databases/db.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
let mongodb, { MongoClient, collection, ObjectID } = require("mongodb");
2+
import { MongoMemoryServer } from 'mongodb-memory-server';
3+
import { env_file } from '../@types';
24
import { Database_Wrapper } from '../interfaces'
35

46
export default class Mongo implements Database_Wrapper {
5-
readonly db_uri: string;
7+
db_uri: string;
68
collection: string;
79
client: any
810
db: string
911

10-
constructor(env_config) {
11-
this.db_uri = env_config.URI;
12-
console.log(this.db_uri)
12+
constructor(db_uri: string, db: string) {
13+
this.db_uri = db_uri
14+
this.db = db
1315
this.client = new MongoClient(this.db_uri);
14-
this.test_database()
16+
this.test_database()
17+
}
18+
19+
static async create_mongo_memory_server(db: string) {
20+
const mongod = await MongoMemoryServer.create({
21+
instance: {
22+
dbName: db
23+
}
24+
})
25+
26+
return mongod.getUri()
1527
}
1628

1729
set_db(db: string): void {
@@ -23,7 +35,6 @@ export default class Mongo implements Database_Wrapper {
2335
// Connect the client to the server
2436
await this.client.connect();
2537
await this.client.db("admin").command({ ping: 1 });
26-
console.log("Connected successfully to mongodb server");
2738
} catch {
2839
console.dir
2940
} finally {
@@ -74,3 +85,12 @@ export default class Mongo implements Database_Wrapper {
7485
}
7586
}
7687

88+
export let Db_Wrapper: Database_Wrapper = null
89+
90+
export const start_db_server = async (env_config: env_file) => {
91+
if (!env_config.PROD) {
92+
const uri = await Mongo.create_mongo_memory_server(env_config.DB)
93+
env_config.URI = uri
94+
}
95+
Db_Wrapper = new Mongo(env_config.URI, env_config.DB)
96+
}

databases/test_db.ts

Lines changed: 0 additions & 61 deletions
This file was deleted.

helpers/encrypt_utils.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import crypto = require("crypto")
2-
import {Db_Wrapper, env_config} from "../config"
2+
import { env_config } from "../config"
33

4-
const private_key = crypto.scryptSync(env_config.ENCRYPT_KEY, "salt", 32)
5-
const iv = Buffer.from(env_config.IV_KEY, 'hex')
64
const algorithm = 'aes-256-cbc';
75

86
export const encrypt = (text) => {
7+
const private_key = crypto.scryptSync(env_config.ENCRYPT_KEY, "salt", 32)
8+
const iv = Buffer.from(env_config.IV_KEY, 'hex')
99
const cipher = crypto.createCipheriv(algorithm, private_key, iv)
1010
let crypted = cipher.update(text,'utf8','hex')
1111
crypted += cipher.final('hex')
1212
return crypted
1313
}
1414

1515
export const decrypt = (text) => {
16+
const private_key = crypto.scryptSync(env_config.ENCRYPT_KEY, "salt", 32)
17+
const iv = Buffer.from(env_config.IV_KEY, 'hex')
1618
let decipher = crypto.createDecipheriv(algorithm, private_key, iv)
1719
let dec = decipher.update(text,'hex','utf8')
1820
dec += decipher.final('utf8')

helpers/survey_helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { response } from "express";
22
import { Request, Response } from "express-serve-static-core";
3-
import {Db_Wrapper, env_config} from "../config"
3+
import { Db_Wrapper } from "../databases/db"
44

55
export const setPageNums = (survey) => {
66
var pagefinal = 0

interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { env_file } from "./@types";
2+
13
export interface Database_Wrapper {
24
set_db(db: any): void;
35

jest.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2+
module.exports = {
3+
preset: 'ts-jest',
4+
testEnvironment: 'node',
5+
testPathIgnorePatterns : [
6+
"<rootDir>/built/"
7+
],
8+
globalTeardown: '<rootDir>/teardown.js',
9+
};

markdown.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import marked = require("marked");
44

55
// Gets MD content from a tasks table
66
function get_task_content(tasks_to_extract: any): Promise<any[]> {
7-
const tasks_with_promises = tasks_to_extract
7+
const tasks_with_promises: [] = tasks_to_extract
88
.filter(
99
(task) =>
1010
task["task summary url"].includes(".md") &&

middlewares/auth.middleware.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import {Db_Wrapper, env_config} from "../config"
1+
import { env_config } from "../config"
2+
import { Db_Wrapper } from "../databases/db"
3+
24
const jwt = require('jsonwebtoken');
35

46
export const verify_token = (req, res, next) => {

0 commit comments

Comments
 (0)