From 54881f26400770c0ae7f9c78299b436ffebd1b5e Mon Sep 17 00:00:00 2001 From: Farhan-Haseeb Date: Wed, 15 Dec 2021 13:27:24 +0500 Subject: [PATCH 1/5] * Added prettier config file for the project --- .prettierrc.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .prettierrc.js diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..f1284c6 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + trailingComma: 'es5', + tabWidth: 2, + semi: true, + singleQuote: true, +}; From 8848e4de67c82899c1e7fa8ad2b4468be2c8cb2f Mon Sep 17 00:00:00 2001 From: Farhan-Haseeb Date: Wed, 15 Dec 2021 13:28:13 +0500 Subject: [PATCH 2/5] * Removed auth0 file --- config/environments/development.json | 10 --- config/index.js | 91 +++++++++------------------- 2 files changed, 28 insertions(+), 73 deletions(-) diff --git a/config/environments/development.json b/config/environments/development.json index dad31ec..b549dee 100644 --- a/config/environments/development.json +++ b/config/environments/development.json @@ -5,15 +5,5 @@ "password": null, "name": "productbox", "host": "127.0.0.1" - }, - "auth0_primary": { - "clientId": "", - "clientSecret": "", - "domain": "", - "connection": "" - }, - "auth0_secondary": { - "clientId": "", - "clientSecret": "" } } diff --git a/config/index.js b/config/index.js index 9c6492f..30b6594 100644 --- a/config/index.js +++ b/config/index.js @@ -1,97 +1,62 @@ -const convict = require("convict"); +const convict = require('convict'); // Define a schema var config = convict({ env: { - doc: "The application environment.", - format: ["production", "development", "test"], - default: "development", - env: "NODE_ENV", + doc: 'The application environment.', + format: ['production', 'development', 'test'], + default: 'development', + env: 'NODE_ENV', }, ip: { - doc: "The IP address to bind.", - format: "ipaddress", - default: "127.0.0.1", - env: "IP_ADDRESS", + doc: 'The IP address to bind.', + format: 'ipaddress', + default: '127.0.0.1', + env: 'IP_ADDRESS', }, port: { - doc: "The port to bind.", - format: "port", + doc: 'The port to bind.', + format: 'port', default: 8080, - env: "PORT", - arg: "port", + env: 'PORT', + arg: 'port', }, db: { host: { - doc: "Database host name/IP", + doc: 'Database host name/IP', format: String, - default: "127.0.0.1", + default: '127.0.0.1', }, name: { - doc: "Database name", + doc: 'Database name', format: String, - default: "database_development", + default: 'database_development', }, username: { - doc: "db user", + doc: 'db user', format: String, - default: "root", + default: 'root', }, password: { - doc: "db password", - format: "*", + doc: 'db password', + format: '*', default: null, }, - }, - auth0_primary: { - clientId: { - doc: "Auth0 primary application clientID", - format: String, - default: null, - env: "AUTH0_CLIENT_ID", - }, - clientSecret: { - doc: "Auth0 primary application Secret", - format: String, - default: null, - env: "AUTH0_CLIENT_SECRET", - }, - domain: { - doc: "Auth0 application Domain name", - format: String, - default: null, - env: "AUTH0_DOMAIN", - }, - connection: { - doc: "Auth0 connection/realm identifier", - format: String, - default: null, - env: "AUTH0_CONNECTION", - }, - }, - auth0_secondary: { - clientId: { - doc: "Auth0 secondary application clientID", - format: String, - default: null, - env: "AUTH0_CLIENT_ID_SECONDARY", - }, - clientSecret: { - doc: "Auth0 secondary application Secret", - format: String, - default: null, - env: "AUTH0_CLIENT_SECRET_SECONDARY", + port: { + doc: 'db port', + format: Number, + default: 3306, }, }, }); // Load environment dependent configuration -let env = config.get("env"); +let env = config.get('env'); if (env) { - config.loadFile(__dirname + "/environments/" + env + ".json"); + config.loadFile(__dirname + '/environments/' + env + '.json'); } // Perform validation -config.validate({ allowed: "strict" }); +config.validate({ allowed: 'strict' }); module.exports = config; From e074c3f91ee1df91f63e10797ad6aef1eb365204 Mon Sep 17 00:00:00 2001 From: Farhan-Haseeb Date: Wed, 15 Dec 2021 13:29:20 +0500 Subject: [PATCH 3/5] * Modified test JSON --- config/environments/test.json | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/config/environments/test.json b/config/environments/test.json index c2acad1..35d224a 100644 --- a/config/environments/test.json +++ b/config/environments/test.json @@ -4,16 +4,7 @@ "username": "root", "password": null, "name": "productbox_test", - "host": "127.0.0.1" - }, - "auth0_primary": { - "clientId": "", - "clientSecret": "", - "domain": "", - "connection": "" - }, - "auth0_secondary": { - "clientId": "", - "clientSecret": "" + "host": "127.0.0.1", + "port": 3306 } } From 223509120ef51451d7842f1e9ecb2a923a9b58c2 Mon Sep 17 00:00:00 2001 From: Farhan-Haseeb Date: Wed, 15 Dec 2021 15:13:53 +0500 Subject: [PATCH 4/5] * Fixed app structure & respawning the server --- config/environments/test.json | 2 +- package-lock.json | 71 +++++++++++++--------------------- package.json | 4 +- test/setup/hook.js | 14 +++---- test/setup/migration-runner.js | 45 +++++++++++++++++---- test/setup/mockApp.js | 57 +++++++++++++++++++++++++++ test/setup/testHelper.js | 12 ++++++ 7 files changed, 144 insertions(+), 61 deletions(-) create mode 100644 test/setup/mockApp.js create mode 100644 test/setup/testHelper.js diff --git a/config/environments/test.json b/config/environments/test.json index 35d224a..043bf3e 100644 --- a/config/environments/test.json +++ b/config/environments/test.json @@ -2,7 +2,7 @@ "port": 4000, "db": { "username": "root", - "password": null, + "password": "", "name": "productbox_test", "host": "127.0.0.1", "port": 3306 diff --git a/package-lock.json b/package-lock.json index 0d0b520..8343241 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1136,11 +1136,6 @@ "color-convert": "^2.0.1" } }, - "ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" - }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -1553,15 +1548,6 @@ "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", "dev": true }, - "cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", @@ -2303,9 +2289,9 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "denque": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", - "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" }, "depd": { "version": "1.1.2", @@ -4969,28 +4955,40 @@ } }, "mysql2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.1.0.tgz", - "integrity": "sha512-9kGVyi930rG2KaHrz3sHwtc6K+GY9d8wWk1XRSYxQiunvGcn4DwuZxOwmK11ftuhhwrYDwGx9Ta4VBwznJn36A==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", "requires": { - "cardinal": "^2.1.1", - "denque": "^1.4.1", + "denque": "^2.0.1", "generate-function": "^2.3.1", - "iconv-lite": "^0.5.0", + "iconv-lite": "^0.6.3", "long": "^4.0.0", - "lru-cache": "^5.1.1", + "lru-cache": "^6.0.0", "named-placeholders": "^1.1.2", "seq-queue": "^0.0.5", - "sqlstring": "^2.3.1" + "sqlstring": "^2.3.2" }, "dependencies": { "iconv-lite": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz", - "integrity": "sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "yallist": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -6128,21 +6126,6 @@ "picomatch": "^2.0.7" } }, - "redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", - "requires": { - "esprima": "~4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - } - } - }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", diff --git a/package.json b/package.json index 4a37ba9..7a6190a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start-test": "./node_modules/pm2/bin/pm2 start server.js --no-daemon --watch --no-autorestart --env test", "stop-server": "./node_modules/pm2/bin/pm2 stop server.js", "logs": "./node_modules/pm2/bin/pm2 logs", - "test": "NODE_ENV=test mocha test", + "test": "mocha test", "test-coverage": "nyc npm run test", "lint": "npx eslint .", "prettier": "npx prettier -c .", @@ -29,7 +29,7 @@ "express-jwt": "^6.0.0", "express-jwt-authz": "^2.4.1", "lodash": "^4.17.20", - "mysql2": "^2.1.0", + "mysql2": "^2.3.3", "pm2": "^4.4.0", "sequelize": "^5.21.7" }, diff --git a/test/setup/hook.js b/test/setup/hook.js index 3a5201c..5b1a943 100644 --- a/test/setup/hook.js +++ b/test/setup/hook.js @@ -1,19 +1,19 @@ -const chai = require("chai"); -const chaiHttp = require("chai-http"); - -const { migrate, revert } = require("./migration-runner"); - +process.env.NODE_ENV = 'test'; +global.config = require('../../config'); +const chai = require('chai'); +const chaiHttp = require('chai-http'); +const { migrate, revert } = require('./migration-runner'); chai.use(chaiHttp); exports.mochaHooks = { beforeAll: async function () { // do something before all test once - console.log("running migrations..."); + console.log('running migrations...'); await migrate(); }, afterAll: async function () { // do something after all test once - console.log("reverting migrations..."); + console.log('reverting migrations...'); await revert(); }, }; diff --git a/test/setup/migration-runner.js b/test/setup/migration-runner.js index 085a729..293f1ec 100644 --- a/test/setup/migration-runner.js +++ b/test/setup/migration-runner.js @@ -1,21 +1,52 @@ -const Umzug = require("umzug"); -const path = require("path"); -const Sequelize = require("sequelize"); -const { sequelize } = require(path.join(process.cwd(), "models/")); +const Umzug = require('umzug'); +const path = require('path'); +const mysql = require('mysql2/promise'); +const Sequelize = require('sequelize'); +const { sequelize } = require(path.join(process.cwd(), 'models/')); const umzug = new Umzug({ migrations: { - path: path.join(process.cwd(), "database", "migrations/"), + path: path.join(process.cwd(), 'database', 'migrations/'), params: [sequelize.getQueryInterface(), Sequelize], }, - storage: "sequelize", + storage: 'sequelize', storageOptions: { sequelize, }, }); +async function _createDatabase() { + // create db if it doesn't already exist + const { host, port, username, password, name } = global.config.get('db'); + const connection = await mysql.createConnection({ + host, + port, + user: username, + password, + }); + await connection.query(`CREATE DATABASE IF NOT EXISTS \`${name}\`;`); + + // connect to db + const establishedSequelize = new Sequelize(name, username, password, { + dialect: 'mysql', + }); + + // sync all models with database + await establishedSequelize.sync(); + console.log('use database:', global.config.get('db').name); + await connection.query('USE ' + global.config.get('db').name); +} + +async function setup() { + console.log('create database:', global.config.get('db').name); + await _createDatabase(); + console.time('MIGRATIONS RUNNING TIME'); + console.log('run all migrations'); + await umzug.up(); + console.timeEnd('MIGRATIONS RUNNING TIME'); +} function migrate() { - return umzug.up(); + return setup(); } function revert() { diff --git a/test/setup/mockApp.js b/test/setup/mockApp.js new file mode 100644 index 0000000..8141c75 --- /dev/null +++ b/test/setup/mockApp.js @@ -0,0 +1,57 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const expressLogger = require('express-bunyan-logger'); +const cors = require('cors'); +const router = require('../../routes'); + +require('../../models'); + +process.on('uncaughtException', (e) => { + console.log(e); +}); + +const app = express(); + +app.use(bodyParser.json({ limit: '10mb' })); +app.use( + bodyParser.urlencoded({ + limit: '10mb', + extended: true, + parameterLimit: 50000, + }) +); +app.use( + expressLogger({ + excludes: [ + 'headers', + 'req', + 'user-agent', + 'short-body', + 'http-version', + 'req-headers', + 'res-headers', + 'body', + 'res', + ], // remove extra details from log + }) +); +// app.use(expressLogger.errorLogger()); +app.use(cors()); // will configure later + +// routes +app.use('/api', router); + +// catch 404 later +// app.use((req, res, next) => next("Not Found")); + +// error handling +app.use((err, req, res, next) => { + // for now log the error and return 500; need to handle it differently in future + if (res.headersSent) { + return next(err); + } + req.log.error(err); + return res.status(500).send(err.message); +}); + +module.exports = app; diff --git a/test/setup/testHelper.js b/test/setup/testHelper.js new file mode 100644 index 0000000..4f4f995 --- /dev/null +++ b/test/setup/testHelper.js @@ -0,0 +1,12 @@ +process.env.NODE_ENV = 'test'; +const config = require('../../config'); +const app = require('./mockApp'); +const port = config.get('port'); + +app.listen(port, () => { + console.log(`server running on port: ${port}`); +}); + +module.exports = { + app: app, +}; From 14a2cad7f29d161914e55a6932979aa0216f10c7 Mon Sep 17 00:00:00 2001 From: Muhammad Uzair <34101864+uzair004@users.noreply.github.com> Date: Wed, 15 Dec 2021 17:29:26 +0500 Subject: [PATCH 5/5] Updated test setup: close server when tests finished --- .mocharc.js | 15 +++++++-------- config/environments/development.json | 2 +- test/setup/hook.js | 4 ++++ test/setup/testHelper.js | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.mocharc.js b/.mocharc.js index 8bca552..50c7766 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -1,17 +1,16 @@ -"use strict"; +'use strict'; -const path = require("path"); -const pathToHooks = path.join(process.cwd(), "test", "setup", "hook.js"); +const path = require('path'); +const pathToHooks = path.join(process.cwd(), 'test', 'setup', 'hook.js'); module.exports = { - // spec: "test/**/*.test.js", require: pathToHooks, - // file: [pathToHooks], recursive: true, - reporter: "spec", + reporter: 'spec', parallel: false, - ignore: ["/path/to/some/ignored/file"], - extension: ["js", "cjs", "mjs"], + ignore: ['/path/to/some/ignored/file'], + extension: ['js', 'cjs', 'mjs'], color: true, diff: true, + exit: true, }; diff --git a/config/environments/development.json b/config/environments/development.json index b549dee..fc50ee6 100644 --- a/config/environments/development.json +++ b/config/environments/development.json @@ -2,7 +2,7 @@ "port": 4000, "db": { "username": "root", - "password": null, + "password": "", "name": "productbox", "host": "127.0.0.1" } diff --git a/test/setup/hook.js b/test/setup/hook.js index 5b1a943..35b3151 100644 --- a/test/setup/hook.js +++ b/test/setup/hook.js @@ -3,6 +3,7 @@ global.config = require('../../config'); const chai = require('chai'); const chaiHttp = require('chai-http'); const { migrate, revert } = require('./migration-runner'); +const { server } = require('../setup/testHelper'); chai.use(chaiHttp); exports.mochaHooks = { @@ -13,6 +14,9 @@ exports.mochaHooks = { }, afterAll: async function () { // do something after all test once + console.log('closing server'); + server.close(); + console.log('reverting migrations...'); await revert(); }, diff --git a/test/setup/testHelper.js b/test/setup/testHelper.js index 4f4f995..452b1d4 100644 --- a/test/setup/testHelper.js +++ b/test/setup/testHelper.js @@ -3,10 +3,11 @@ const config = require('../../config'); const app = require('./mockApp'); const port = config.get('port'); -app.listen(port, () => { +const server = app.listen(port, () => { console.log(`server running on port: ${port}`); }); module.exports = { app: app, + server: server, };