Skip to content

Commit

Permalink
Add test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanWEdwards committed Dec 3, 2022
1 parent 15352ea commit 360689b
Show file tree
Hide file tree
Showing 28 changed files with 9,742 additions and 1,798 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
15 changes: 15 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
"root": true,
"extends": [
"eslint:recommended",
"plugin:@next/next/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {}
};
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ npm run dev

## required environmental variables

can be stored in a file called `.env.local`
can be stored in a file called `.env.local`.

```
TWILIO_ACCOUNT_SID=Your-Account-SID
Expand Down
182 changes: 182 additions & 0 deletions __mocks__/mongoose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { Mutex } from "async-mutex";

interface IIndexSignature {
[key: string]: any;
}

type SchemaConfiguration = {
collection?: string;
timestamps?: boolean;
} | undefined;

class Schema<Type> {
protected schema = {};
protected configs: SchemaConfiguration;

constructor(schema: Object, configs: SchemaConfiguration) {
for (const [key, value] of Object.entries(schema)) {
let propertyValue: any;
if (Object.hasOwn(value, 'default')) {
propertyValue = value.default;
} else {
propertyValue = undefined;
}
Object.defineProperty(this.schema, key, {
value: propertyValue,
enumerable: true,
writable: true
})
}
this.configs = configs;
}

document(params: IIndexSignature) {
let document = {};
for (const [key, fieldValue] of Object.entries(this.schema)) {
let propertyValue: any;
let paramsValue: any = params[key];

if (paramsValue !== undefined) {
propertyValue = paramsValue;
} else {
propertyValue = fieldValue;
}

Object.defineProperty(document, key, {
value: propertyValue,
enumerable: true,
writable: true
})
}
if (this.configs !== undefined && this.configs.timestamps === true) {
const currentTime = new Date(Date.now());
Object.defineProperty(document, 'createdAt', {
value: currentTime,
writable: true
})
Object.defineProperty(document, 'updatedAt', {
value: currentTime,
writable: true
})
}

return document;
}
}

class Model<Type> {
protected data: Array<any> = [];
protected mutex: Mutex = new Mutex();
protected schema: Schema<Type>;

constructor(schema: Schema<Type>) {
this.schema = schema;
}

//eslint-disable-next-line @typescript-eslint/ban-types
async create(params: Object) {
await this.mutex.acquire();
try {
const document = this.schema.document(params);
this.data.push(document);
} finally {
this.mutex.release();
}
}

//eslint-disable-next-line @typescript-eslint/ban-types
countDocuments(params: typeof this.schema) {
return {
exec: async () => {
const documents = await this._getDocuments(params);
const count = documents.length;
return count;
}
};
}

//eslint-disable-next-line @typescript-eslint/ban-types
find(params: Object) {
return { exec: async () => { return this._getDocuments(params) } };
}

findOne() {
return {
exec: async () => {
await this.mutex.acquire();
let document: any;
try {
if (this.data.length == 0) {
document = undefined;
} else {
document = this.data[0];
}
} finally {
this.mutex.release();
}
return document;
}
};
}

//eslint-disable-next-line @typescript-eslint/ban-types
async _getDocuments(params: Object, condition?: string) {
await this.mutex.acquire();
let documents: Array<any>;
try {
let matchCondition = true;
if (condition === 'filter') {
matchCondition = false;
}
if (params !== undefined) {
documents = this.data.filter((document) => {
for (const [key, value] of Object.entries(params)) {
const documentValue = document[key as keyof typeof document];
if (Object.hasOwn(value, '$in') && value['$in'].includes(documentValue)) {
return matchCondition;
} else if (documentValue == value) {
return matchCondition;
} else {
return !matchCondition;
}
}
});
} else {
documents = this.data;
}
} finally {
this.mutex.release();
}
return documents;
}

//eslint-disable-next-line @typescript-eslint/ban-types
remove(params: Object) {
return {
exec: async () => {
const documents = await this._getDocuments(params, 'filter');
await this.mutex.acquire();
try {
this.data = documents;
} finally {
this.mutex.release();
}
}
};
}
}

const mongoose = {
createConnection: jest.fn().mockImplementation(function (_args: any) {
return {
model: jest.fn().mockImplementation(function (_: any, schema: any) {
return new Model(schema);
}),
};
}),
Connection: jest.fn(),
Schema,
Model,
};

module.exports = mongoose;
Empty file added __mocks__/winston-mongodb.ts
Empty file.
21 changes: 21 additions & 0 deletions __mocks__/winston.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const winston = {
createLogger: jest.fn().mockImplementation(function(args) {
return {
debug: jest.fn(),
error: jest.fn(),
info: jest.fn(),
warn: jest.fn()
}
}),
format: {
combine: jest.fn(),
printf: jest.fn(),
timestamp: jest.fn()
},
transports: {
Console: jest.fn(),
MongoDB: jest.fn()
}
}

module.exports = winston;
1 change: 0 additions & 1 deletion dao/mongoose.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import mongoose, { Connection, Model } from 'mongoose';
import { Log, Notification, Reminder } from '../types';

let conn:Connection;
let NotificationDao:Model<Notification>;
let ReminderDao:Model<Reminder>;
Expand Down
3 changes: 3 additions & 0 deletions dotenv-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require('dotenv').config({
path: '.env.local'
})
7 changes: 3 additions & 4 deletions instances/vt/models/case.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import moment from 'moment-timezone';
import _ from 'lodash';

import { Case, IInstanceMethods } from '../../../types';
import { initialize, Event, EventDao } from '../dao/mongoose';

const TIMEZONE = 'America/New_York';

function toCase(o:Event, startDate?:Date, endDate?:Date):Case {
let c:Case = {
const c:Case = {
uid: o._id,
number: o.docket_number,
date: o.date,
Expand Down Expand Up @@ -54,7 +53,7 @@ export default class VtInstanceMethods implements IInstanceMethods {
async findAll(obj: { number?: string, startDate?: Date, endDate?: Date }) {
await initialize();

let params:EventParams = {};
const params:EventParams = {};

if (obj.number) {
params.docket_number = new RegExp(`${obj.number}`, 'i');
Expand All @@ -72,7 +71,7 @@ export default class VtInstanceMethods implements IInstanceMethods {
const allCases = await EventDao.find(params).lean().exec();

const uniqueCases:Event[] = [];
const uniqueDocketNumbers:String[] = [];
const uniqueDocketNumbers:string[] = [];
allCases.forEach(o => {
if (uniqueDocketNumbers.indexOf(o.docket_number) === -1) {
uniqueCases.push(o);
Expand Down
22 changes: 22 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const nextJest = require('next/jest')

const createJestConfig = nextJest({
dir: './',
})

/** @type {import('jest').Config} */
const customJestConfig = {
setupFiles: [
"<rootDir>/dotenv-config.js"
],
setupFilesAfterEnv:[
"<rootDir>/jest.helpers.ts"
],
testEnvironment: 'node',
testMatch: [
"<rootDir>/**"
],
verbose: true
}

module.exports = createJestConfig(customJestConfig)
10 changes: 10 additions & 0 deletions jest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
declare namespace Jest {
interface Test {
repeat: (
times: number,
name: string,
fn?: ProviderCallback,
timeout?: number
) => void;
}
}
14 changes: 14 additions & 0 deletions jest.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test.repeat = async (
times: number,
name: string,
fn?: jest.ProvidesCallback,
timeout?: number
) => {
await Promise.all(
Array(times)
.fill(undefined)
.map((_, _index) => {
return test(name.valueOf(), fn, timeout);
})
)
}
Loading

0 comments on commit 360689b

Please sign in to comment.