From 933948ef2f73d5417ffa2c23e084233153787775 Mon Sep 17 00:00:00 2001 From: Satyajit Dey Date: Fri, 29 May 2020 23:57:04 +0600 Subject: [PATCH] BE #7 Prettify --- .prettierrc | 6 + app.js | 69 ++-- controllers/auth.controller.js | 37 ++- controllers/binaries.controller.js | 164 +++++----- controllers/users.controller.js | 91 +++--- jest.config.js | 8 +- middlewares/auth.permission.middleware.js | 54 ++- middlewares/auth.validation.middleware.js | 106 +++--- middlewares/field.validation.middleware.js | 22 +- middlewares/user.validation.middleware.js | 90 ++--- models/article.js | 42 +-- models/images.model.js | 42 +-- models/users.model.js | 129 ++++---- package-lock.json | 6 + package.json | 4 +- routes/article.js | 363 +++++++++++---------- routes/auth.route.js | 26 +- routes/binaries.route.js | 51 +-- routes/index.js | 17 +- routes/users.route.js | 99 ++++-- services/db.service.js | 49 +-- test/app.test.js | 22 +- test/routes/article.test.js | 57 ++-- 23 files changed, 817 insertions(+), 737 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b785842 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true +} diff --git a/app.js b/app.js index b74f59d..ed7e605 100644 --- a/app.js +++ b/app.js @@ -1,46 +1,49 @@ -var debug = require('debug')('cms-backend-api:*'); -var express = require('express'); -var logger = require('morgan'); +var debug = require('debug')('cms-backend-api:*') +var express = require('express') +var logger = require('morgan') -const bodyParser = require('body-parser'); +const bodyParser = require('body-parser') const indexRouter = require('./routes/index') -const authRouter = require('./routes/auth.route'); -const usersRouter = require('./routes/users.route'); -const binaryRouter=require('./routes/binaries.route'); -const articleRouter = require('./routes/article'); +const authRouter = require('./routes/auth.route') +const usersRouter = require('./routes/users.route') +const binaryRouter = require('./routes/binaries.route') +const articleRouter = require('./routes/article') -const app = express(); +const app = express() //middleware -app.use(logger('dev')); -app.use(express.json()); -app.use(express.urlencoded({ extended: false })); +app.use(logger('dev')) +app.use(express.json()) +app.use(express.urlencoded({ extended: false })) app.use(function (req, res, next) { - res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Credentials', 'true'); - res.header('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE'); - res.header('Access-Control-Expose-Headers', 'Content-Length'); - res.header('Access-Control-Allow-Headers', 'Accept, Authorization, Content-Type, X-Requested-With, Range'); - if (req.method === 'OPTIONS') { - return res.send(200); - } else { - return next(); - } -}); - -app.use(bodyParser.json()); + res.header('Access-Control-Allow-Origin', '*') + res.header('Access-Control-Allow-Credentials', 'true') + res.header('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE') + res.header('Access-Control-Expose-Headers', 'Content-Length') + res.header( + 'Access-Control-Allow-Headers', + 'Accept, Authorization, Content-Type, X-Requested-With, Range' + ) + if (req.method === 'OPTIONS') { + return res.send(200) + } else { + return next() + } +}) + +app.use(bodyParser.json()) //List all the routes -app.use('/', indexRouter); -app.use('/auth', authRouter); -app.use(`${process.env.API_ENPOINT_BASE}/users`, usersRouter); -app.use(`${process.env.API_ENPOINT_BASE}/binaries`, binaryRouter); -app.use(`${process.env.API_ENPOINT_BASE}/article`, articleRouter); +app.use('/', indexRouter) +app.use('/auth', authRouter) +app.use(`${process.env.API_ENPOINT_BASE}/users`, usersRouter) +app.use(`${process.env.API_ENPOINT_BASE}/binaries`, binaryRouter) +app.use(`${process.env.API_ENPOINT_BASE}/article`, articleRouter) app.get(process.env.API_ENPOINT_BASE, (req, res) => { - res.send(`CMS API v1.`) -}); + res.send(`CMS API v1.`) +}) -module.exports = app; +module.exports = app diff --git a/controllers/auth.controller.js b/controllers/auth.controller.js index 92a383c..1b531b9 100644 --- a/controllers/auth.controller.js +++ b/controllers/auth.controller.js @@ -1,21 +1,24 @@ -const jwt = require('jsonwebtoken'); -const crypto = require('crypto'); +const jwt = require('jsonwebtoken') +const crypto = require('crypto') exports.login = (req, res) => { - try { - let refreshId = req.body.userId + process.env.AUTH_SECRET; - let salt = crypto.randomBytes(16).toString('base64'); - let hash = crypto.createHmac('sha512', salt).update(refreshId).digest("base64"); - req.body.refreshKey = salt; - let token = jwt.sign(req.body, process.env.AUTH_SECRET); - let b = new Buffer(hash); - let refresh_token = b.toString('base64'); - res.status(201).send({accessToken: token, refreshToken: refresh_token}); - } catch (err) { - res.status(500).send({errors: err}); - } -}; + try { + let refreshId = req.body.userId + process.env.AUTH_SECRET + let salt = crypto.randomBytes(16).toString('base64') + let hash = crypto + .createHmac('sha512', salt) + .update(refreshId) + .digest('base64') + req.body.refreshKey = salt + let token = jwt.sign(req.body, process.env.AUTH_SECRET) + let b = new Buffer(hash) + let refresh_token = b.toString('base64') + res.status(201).send({ accessToken: token, refreshToken: refresh_token }) + } catch (err) { + res.status(500).send({ errors: err }) + } +} exports.logout = (req, res) => { - res.status(204).send({accessToken: null, refreshToken: null}); -}; + res.status(204).send({ accessToken: null, refreshToken: null }) +} diff --git a/controllers/binaries.controller.js b/controllers/binaries.controller.js index 946c78c..bcbd8c2 100644 --- a/controllers/binaries.controller.js +++ b/controllers/binaries.controller.js @@ -1,95 +1,93 @@ -const fs = require('fs'); -const AWS = require('aws-sdk'); -const mime = require('mime-types'); -const {v4: uuidv4} = require('uuid'); +const fs = require('fs') +const AWS = require('aws-sdk') +const mime = require('mime-types') +const { v4: uuidv4 } = require('uuid') -const ImageModel = require('../models/images.model'); +const ImageModel = require('../models/images.model') AWS.config.update({ - accessKeyId: process.env.IAM_ACCESS_KEY, - secretAccessKey: process.env.IAM_SECRET_KEY, - //region: process.env.AWS_REGION, -}); + accessKeyId: process.env.IAM_ACCESS_KEY, + secretAccessKey: process.env.IAM_SECRET_KEY, + //region: process.env.AWS_REGION, +}) -const s3 = new AWS.S3(); +const s3 = new AWS.S3() exports.uploadImage = (req, res) => { - let fileInfo = { - source: req.file.path, - key: `${uuidv4()}---${req.file.filename}`, - caption: req.body.caption, - contentType: mime.lookup(req.file.path), - author: req.jwt.name, - authorEmail: req.jwt.email - }; - uploadFile(fileInfo, res); -}; + let fileInfo = { + source: req.file.path, + key: `${uuidv4()}---${req.file.filename}`, + caption: req.body.caption, + contentType: mime.lookup(req.file.path), + author: req.jwt.name, + authorEmail: req.jwt.email, + } + uploadFile(fileInfo, res) +} exports.retrieveImage = (req, res) => { - let key = `${req.params.id}---${req.params.filename}`; - retrieveFile(key, res); -}; + let key = `${req.params.id}---${req.params.filename}` + retrieveFile(key, res) +} let uploadFile = (fileInfo, res) => { - console.log(fileInfo) - - fs.readFile(fileInfo.source, (err, fileData) => { - if (err) { - return res.status(500).send({error: err}); - } - - const params = { - Bucket: process.env.AWS_S3_BUCKET_BINARIES, - Key: fileInfo.key, - Body: fileData, - ContentType: fileInfo.contentType, - Metadata: { - 'Author': fileInfo.author, - 'Email': fileInfo.authorEmail - } - }; - - //Upload image to S3 bucket - s3.upload(params, (err, data) => { - if (err) { - return res.status(500).send({error: err}); - } - - let keys = fileInfo.key.split('---'); - const imageData = { - _id: keys[0], - fileName: keys[1], - caption: fileInfo.caption, - author: fileInfo.author - }; - - //After successful upload save the image info to Image Mongo model - ImageModel.saveImage(imageData); - - //After successful upload delete the local image - fs.unlink(fileInfo.source, (err) => { - if (err) throw err; - console.log(`${fileInfo.source} deleted.`) - }); - - return res.send(data); - }); - }); -}; + console.log(fileInfo) + + fs.readFile(fileInfo.source, (err, fileData) => { + if (err) { + return res.status(500).send({ error: err }) + } + + const params = { + Bucket: process.env.AWS_S3_BUCKET_BINARIES, + Key: fileInfo.key, + Body: fileData, + ContentType: fileInfo.contentType, + Metadata: { + Author: fileInfo.author, + Email: fileInfo.authorEmail, + }, + } + + //Upload image to S3 bucket + s3.upload(params, (err, data) => { + if (err) { + return res.status(500).send({ error: err }) + } + + let keys = fileInfo.key.split('---') + const imageData = { + _id: keys[0], + fileName: keys[1], + caption: fileInfo.caption, + author: fileInfo.author, + } + + //After successful upload save the image info to Image Mongo model + ImageModel.saveImage(imageData) + + //After successful upload delete the local image + fs.unlink(fileInfo.source, (err) => { + if (err) throw err + console.log(`${fileInfo.source} deleted.`) + }) + + return res.send(data) + }) + }) +} let retrieveFile = (key, res) => { - const getParams = { - Bucket: process.env.AWS_S3_BUCKET_BINARIES, - Key: key - }; - - s3.getObject(getParams, function (err, data) { - if (err) { - return res.status(400).send({success: false, err: err}); - } else { - return res.send(data); - } - }); -}; - - + const getParams = { + Bucket: process.env.AWS_S3_BUCKET_BINARIES, + Key: key, + } + + s3.getObject(getParams, function (err, data) { + if (err) { + return res.status(400).send({ success: false, err: err }) + } else { + return res.send(data) + } + }) +} diff --git a/controllers/users.controller.js b/controllers/users.controller.js index 8ae3f3b..5b3431d 100644 --- a/controllers/users.controller.js +++ b/controllers/users.controller.js @@ -1,56 +1,59 @@ -const UserModel = require('../models/users.model'); -const crypto = require('crypto'); +const UserModel = require('../models/users.model') +const crypto = require('crypto') exports.insert = (req, res) => { - let salt = crypto.randomBytes(16).toString('base64'); - let hash = crypto.createHmac('sha512', salt).update(req.body.password).digest("base64"); - req.body.password = salt + "$" + hash; - UserModel.createUser(req.body) - .then((result) => { - res.status(201).send({id: result._id}); - }); -}; + let salt = crypto.randomBytes(16).toString('base64') + let hash = crypto + .createHmac('sha512', salt) + .update(req.body.password) + .digest('base64') + req.body.password = salt + '$' + hash + UserModel.createUser(req.body).then((result) => { + res.status(201).send({ id: result._id }) + }) +} exports.list = (req, res) => { - let limit = req.query.limit && req.query.limit <= 100 ? parseInt(req.query.limit) : 10; - let page = 0; - if (req.query) { - if (req.query.page) { - req.query.page = parseInt(req.query.page); - page = Number.isInteger(req.query.page) ? req.query.page : 0; - } + let limit = + req.query.limit && req.query.limit <= 100 ? parseInt(req.query.limit) : 10 + let page = 0 + if (req.query) { + if (req.query.page) { + req.query.page = parseInt(req.query.page) + page = Number.isInteger(req.query.page) ? req.query.page : 0 } + } - UserModel.list(limit, page) - .then((result) => { - res.status(200).send(result); - }) -}; + UserModel.list(limit, page).then((result) => { + res.status(200).send(result) + }) +} exports.getById = (req, res) => { - UserModel.findById(req.params.userId) - .then((result) => { - res.status(200).send(result); - }).catch(err => res.status(400).send({'message': err.message})); -}; + UserModel.findById(req.params.userId) + .then((result) => { + res.status(200).send(result) + }) + .catch((err) => res.status(400).send({ message: err.message })) +} exports.patchById = (req, res) => { - if (req.body.password) { - let salt = crypto.randomBytes(16).toString('base64'); - let hash = crypto.createHmac('sha512', salt).update(req.body.password).digest("base64"); - req.body.password = salt + "$" + hash; - } - - UserModel.patchUser(req.params.userId, req.body) - .then((result) => { - res.status(204).send({}); - }); - -}; + if (req.body.password) { + let salt = crypto.randomBytes(16).toString('base64') + let hash = crypto + .createHmac('sha512', salt) + .update(req.body.password) + .digest('base64') + req.body.password = salt + '$' + hash + } + + UserModel.patchUser(req.params.userId, req.body).then((result) => { + res.status(204).send({}) + }) +} exports.removeById = (req, res) => { - UserModel.removeById(req.params.userId) - .then((result) => { - res.status(204).send({}); - }); -}; \ No newline at end of file + UserModel.removeById(req.params.userId).then((result) => { + res.status(204).send({}) + }) +} diff --git a/jest.config.js b/jest.config.js index a3fb370..e94c6de 100644 --- a/jest.config.js +++ b/jest.config.js @@ -21,7 +21,7 @@ module.exports = { // collectCoverageFrom: undefined, // The directory where Jest should output its coverage files - coverageDirectory: "coverage", + coverageDirectory: 'coverage', // An array of regexp pattern strings used to skip coverage collection // coveragePathIgnorePatterns: [ @@ -120,7 +120,7 @@ module.exports = { // runner: "jest-runner", // The paths to modules that run some code to configure or set up the testing environment before each test - setupFiles: ["dotenv/config"], + setupFiles: ['dotenv/config'], // A list of paths to modules that run some code to configure or set up the testing framework before each test // setupFilesAfterEnv: [], @@ -129,7 +129,7 @@ module.exports = { // snapshotSerializers: [], // The test environment that will be used for testing - testEnvironment: "node", + testEnvironment: 'node', // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, @@ -182,4 +182,4 @@ module.exports = { // Whether to use watchman for file crawling // watchman: true, -}; +} diff --git a/middlewares/auth.permission.middleware.js b/middlewares/auth.permission.middleware.js index 0b3fb19..ccce4a0 100644 --- a/middlewares/auth.permission.middleware.js +++ b/middlewares/auth.permission.middleware.js @@ -1,36 +1,34 @@ exports.minimumPermissionLevelRequired = (required_permission_level) => { - return (req, res, next) => { - let user_permission_level = parseInt(req.jwt.permissionLevel); - if (user_permission_level & required_permission_level) { - return next(); - } else { - return res.status(403).send(); - } - }; -}; + return (req, res, next) => { + let user_permission_level = parseInt(req.jwt.permissionLevel) + if (user_permission_level & required_permission_level) { + return next() + } else { + return res.status(403).send() + } + } +} exports.onlySameUserOrAdminCanDoThisAction = (req, res, next) => { - - let user_permission_level = parseInt(req.jwt.permissionLevel); - let userId = req.jwt.userId; - if (req.params && req.params.userId && userId === req.params.userId) { - return next(); + let user_permission_level = parseInt(req.jwt.permissionLevel) + let userId = req.jwt.userId + if (req.params && req.params.userId && userId === req.params.userId) { + return next() + } else { + if (user_permission_level & process.env.AUTH_PERMISSION_ADMIN) { + return next() } else { - if (user_permission_level & process.env.AUTH_PERMISSION_ADMIN) { - return next(); - } else { - return res.status(403).send(); - } + return res.status(403).send() } - -}; + } +} exports.sameUserCantDoThisAction = (req, res, next) => { - let userId = req.jwt.userId; + let userId = req.jwt.userId - if (req.params.userId !== userId) { - return next(); - } else { - return res.status(400).send(); - } -}; + if (req.params.userId !== userId) { + return next() + } else { + return res.status(400).send() + } +} diff --git a/middlewares/auth.validation.middleware.js b/middlewares/auth.validation.middleware.js index efe02cd..0e1bd98 100644 --- a/middlewares/auth.validation.middleware.js +++ b/middlewares/auth.validation.middleware.js @@ -1,59 +1,63 @@ -const {check} = require('express-validator'); -const crypto = require('crypto'); -const jwt = require('jsonwebtoken'); -const UserModel = require('../models/users.model'); +const { check } = require('express-validator') +const crypto = require('crypto') +const jwt = require('jsonwebtoken') +const UserModel = require('../models/users.model') exports.authFieldValidationRules = () => { - return [ - // email should not be empty - check('email', 'email empty').notEmpty(), - // email must be valid - check('email', 'email is not valid').isEmail().normalizeEmail(), - // password should not be empty - check('password', 'password empty').notEmpty() - ] -}; + return [ + // email should not be empty + check('email', 'email empty').notEmpty(), + // email must be valid + check('email', 'email is not valid').isEmail().normalizeEmail(), + // password should not be empty + check('password', 'password empty').notEmpty(), + ] +} exports.matchEmailAndPassword = (req, res, next) => { - const {email, password} = req.body; - UserModel.findByEmail(email).then(user => { - if (!user) { - return res.status(404).send({errors: `User with email:<${email}> doesn't exist`}); - } else { - let passwordFields = user.password.split('$'); - let salt = passwordFields[0]; - let hash = crypto.createHmac('sha512', salt).update(password).digest("base64"); - if (hash === passwordFields[1]) { - req.body = { - userId: user._id, - email: user.email, - permissionLevel: user.permissionLevel, - provider: 'email', - name: `${user.firstName} ${user.lastName}`, - }; - return next(); - } else { - return res.status(400).send({errors: 'Invalid e-mail or password'}); - } + const { email, password } = req.body + UserModel.findByEmail(email).then((user) => { + if (!user) { + return res + .status(404) + .send({ errors: `User with email:<${email}> doesn't exist` }) + } else { + let passwordFields = user.password.split('$') + let salt = passwordFields[0] + let hash = crypto + .createHmac('sha512', salt) + .update(password) + .digest('base64') + if (hash === passwordFields[1]) { + req.body = { + userId: user._id, + email: user.email, + permissionLevel: user.permissionLevel, + provider: 'email', + name: `${user.firstName} ${user.lastName}`, } - }); -}; + return next() + } else { + return res.status(400).send({ errors: 'Invalid e-mail or password' }) + } + } + }) +} exports.verifyJwtToken = (req, res, next) => { - if (req.headers['authorization']) { - try { - let authorization = req.headers['authorization'].split(' '); - if (authorization[0] !== 'Bearer') { - return res.status(401).send(); - } else { - req.jwt = jwt.verify(authorization[1], process.env.AUTH_SECRET); - return next(); - } - - } catch (err) { - return res.status(403).send(); - } - } else { - return res.status(401).send(); + if (req.headers['authorization']) { + try { + let authorization = req.headers['authorization'].split(' ') + if (authorization[0] !== 'Bearer') { + return res.status(401).send() + } else { + req.jwt = jwt.verify(authorization[1], process.env.AUTH_SECRET) + return next() + } + } catch (err) { + return res.status(403).send() } -}; \ No newline at end of file + } else { + return res.status(401).send() + } +} diff --git a/middlewares/field.validation.middleware.js b/middlewares/field.validation.middleware.js index d159d93..650a2fc 100644 --- a/middlewares/field.validation.middleware.js +++ b/middlewares/field.validation.middleware.js @@ -1,15 +1,15 @@ -const {validationResult} = require('express-validator'); +const { validationResult } = require('express-validator') exports.validateRules = (req, res, next) => { - const errors = validationResult(req); - if (errors.isEmpty()) { - return next(); - } + const errors = validationResult(req) + if (errors.isEmpty()) { + return next() + } - const extractedErrors = []; - errors.array().map(err => extractedErrors.push({[err.param]: err.msg})); + const extractedErrors = [] + errors.array().map((err) => extractedErrors.push({ [err.param]: err.msg })) - return res.status(400).json({ - errors: extractedErrors, - }); -}; \ No newline at end of file + return res.status(400).json({ + errors: extractedErrors, + }) +} diff --git a/middlewares/user.validation.middleware.js b/middlewares/user.validation.middleware.js index ffc8b8b..a4c7a30 100644 --- a/middlewares/user.validation.middleware.js +++ b/middlewares/user.validation.middleware.js @@ -1,53 +1,57 @@ -const mongoose = require('../services/db.service').mongoose; -const UserModel = require('../models/users.model'); +const mongoose = require('../services/db.service').mongoose +const UserModel = require('../models/users.model') -const {check} = require('express-validator'); +const { check } = require('express-validator') exports.registrationFieldValidationRules = () => { - return [ - // firstName should not be empty - check('firstName', 'firstName empty').notEmpty(), - // lastName should not be empty - check('lastName', 'lastName empty').notEmpty(), - // email should not be empty - check('email', 'email empty').notEmpty(), - // email must be valid - check('email', 'email is not valid').isEmail().normalizeEmail(), - // password should not be empty - check('password', 'password empty').notEmpty(), - // password must be at least 8 chars long - check('password', 'password must be at least 8 chars long').isLength({min: 8}) - ] -}; + return [ + // firstName should not be empty + check('firstName', 'firstName empty').notEmpty(), + // lastName should not be empty + check('lastName', 'lastName empty').notEmpty(), + // email should not be empty + check('email', 'email empty').notEmpty(), + // email must be valid + check('email', 'email is not valid').isEmail().normalizeEmail(), + // password should not be empty + check('password', 'password empty').notEmpty(), + // password must be at least 8 chars long + check('password', 'password must be at least 8 chars long').isLength({ + min: 8, + }), + ] +} exports.isEmailAlreadyExists = (req, res, next) => { - UserModel.findByEmail(req.body.email) - .then((result) => { - if (result) { - return res.status(409).json({message: 'Email already in use.'}); - } else { - return next(); - } - }).catch(err => res.status(500).json({errors: err})); -}; + UserModel.findByEmail(req.body.email) + .then((result) => { + if (result) { + return res.status(409).json({ message: 'Email already in use.' }) + } else { + return next() + } + }) + .catch((err) => res.status(500).json({ errors: err })) +} exports.verifyUserId = (req, res, next) => { - if (req.params.userId && mongoose.Types.ObjectId.isValid(req.params.userId)) { - return next(); - } + if (req.params.userId && mongoose.Types.ObjectId.isValid(req.params.userId)) { + return next() + } - return res.sendStatus(404); -}; + return res.sendStatus(404) +} exports.updatePasswordValidationRules = () => { - return [ - check('email', 'email empty').notEmpty(), - // email must be valid - check('email', 'email is not valid').isEmail().normalizeEmail(), - // password should not be empty - check('password', 'password empty').notEmpty(), - // password must be at least 8 chars long - check('password', 'password must be at least 8 chars long').isLength({min: 8}) - ] -}; - + return [ + check('email', 'email empty').notEmpty(), + // email must be valid + check('email', 'email is not valid').isEmail().normalizeEmail(), + // password should not be empty + check('password', 'password empty').notEmpty(), + // password must be at least 8 chars long + check('password', 'password must be at least 8 chars long').isLength({ + min: 8, + }), + ] +} diff --git a/models/article.js b/models/article.js index 5efedbb..650888e 100644 --- a/models/article.js +++ b/models/article.js @@ -1,25 +1,27 @@ -var mongoose=require('mongoose'); -var Schema=mongoose.Schema; +var mongoose = require('mongoose') +var Schema = mongoose.Schema - -var articleSchema = new Schema({ - title:{ - type:String, - require:true +var articleSchema = new Schema( + { + title: { + type: String, + require: true, }, - url:{ - type:String, - require:true + url: { + type: String, + require: true, }, - body:[String], + body: [String], author: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: true, - } -}, { - timestamps: true -}); + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: true, + }, + }, + { + timestamps: true, + } +) -var Article=mongoose.model('Article',articleSchema); -module.exports=Article; \ No newline at end of file +var Article = mongoose.model('Article', articleSchema) +module.exports = Article diff --git a/models/images.model.js b/models/images.model.js index a9bcb53..ad64384 100644 --- a/models/images.model.js +++ b/models/images.model.js @@ -1,30 +1,30 @@ -const mongoose = require('../services/db.service').mongoose; +const mongoose = require('../services/db.service').mongoose const imageSchema = new mongoose.Schema({ - _id: {type: String}, - fileName: {type: String, required: true, trim: true}, - caption: {type: String}, - author: {type: String, trim: true}, - credits: [String], - imageType: {type: String}, - copyright: {type: String, trim: true}, - createdAt: {type: Date, default: Date.now}, - status: {type: String, default: 'published'} -}); + _id: { type: String }, + fileName: { type: String, required: true, trim: true }, + caption: { type: String }, + author: { type: String, trim: true }, + credits: [String], + imageType: { type: String }, + copyright: { type: String, trim: true }, + createdAt: { type: Date, default: Date.now }, + status: { type: String, default: 'published' }, +}) -const Images = mongoose.model('Image', imageSchema); +const Images = mongoose.model('Image', imageSchema) exports.saveImage = (imageData) => { - const image = new Images(imageData); - return image.save(); -}; + const image = new Images(imageData) + return image.save() +} exports.findById = (id) => { - Images.findById(id).then(result => { - return result; - }); -}; + Images.findById(id).then((result) => { + return result + }) +} exports.findByAuthor = (email) => { - return Images.find({author: email}); -}; \ No newline at end of file + return Images.find({ author: email }) +} diff --git a/models/users.model.js b/models/users.model.js index 515b7f2..a84a350 100644 --- a/models/users.model.js +++ b/models/users.model.js @@ -1,93 +1,90 @@ -const mongoose = require('../services/db.service').mongoose; +const mongoose = require('../services/db.service').mongoose const userSchema = new mongoose.Schema({ - firstName: {type: String, required: true, trim: true}, - lastName: {type: String, required: true, trim: true}, - email: {type: String, unique: true, required: true, trim: true}, - password: {type: String, required: true}, - permissionLevel: {type: Number, default: 1}, - createdAt: {type: Date, default: Date.now}, - lastModified: {type: Date, default: Date.now} -}); + firstName: { type: String, required: true, trim: true }, + lastName: { type: String, required: true, trim: true }, + email: { type: String, unique: true, required: true, trim: true }, + password: { type: String, required: true }, + permissionLevel: { type: Number, default: 1 }, + createdAt: { type: Date, default: Date.now }, + lastModified: { type: Date, default: Date.now }, +}) -const Users = mongoose.model('User', userSchema); +const Users = mongoose.model('User', userSchema) // Rather than exposing Document's _id expose virtual id fields that is derived from _id // Remember you can not query by virtual fields in Mongoose // Details - https://mongoosejs.com/docs/tutorials/virtuals.html userSchema.virtual('id').get(function () { - return this._id.toHexString(); -}); + return this._id.toHexString() +}) // Serialize virtual fields userSchema.set('toJSON', { - virtuals: true -}); + virtuals: true, +}) userSchema.findById = function (cb) { - return this.model('User').find({id: this.id}, cb); -}; - + return this.model('User').find({ id: this.id }, cb) +} exports.findByEmail = (email) => { - return Users.findOne({email: email}); -}; + return Users.findOne({ email: email }) +} exports.findById = (id) => { - return Users.findById(id) - .then((result) => { - result = result.toJSON(); - delete result._id; - delete result.__v; - return result; - }); -}; + return Users.findById(id).then((result) => { + result = result.toJSON() + delete result._id + delete result.__v + return result + }) +} exports.createUser = (userData) => { - const user = new Users(userData); + const user = new Users(userData) - return user.save(); -}; + return user.save() +} exports.list = (perPage, page) => { - return new Promise((resolve, reject) => { - Users.find() - .limit(perPage) - .skip(perPage * page) - .exec(function (err, users) { - if (err) { - reject(err); - } else { - resolve(users); - } - }) - }); -}; + return new Promise((resolve, reject) => { + Users.find() + .limit(perPage) + .skip(perPage * page) + .exec(function (err, users) { + if (err) { + reject(err) + } else { + resolve(users) + } + }) + }) +} exports.patchUser = (id, userData) => { - return new Promise((resolve, reject) => { - Users.findById(id, function (err, user) { - if (err) reject(err); - for (let i in userData) { - user[i] = userData[i]; - } - user.save(function (err, updatedUser) { - if (err) return reject(err); - resolve(updatedUser); - }); - }); + return new Promise((resolve, reject) => { + Users.findById(id, function (err, user) { + if (err) reject(err) + for (let i in userData) { + user[i] = userData[i] + } + user.save(function (err, updatedUser) { + if (err) return reject(err) + resolve(updatedUser) + }) }) - -}; + }) +} exports.removeById = (userId) => { - return new Promise((resolve, reject) => { - Users.remove({_id: userId}, (err) => { - if (err) { - reject(err); - } else { - resolve(err); - } - }); - }); -}; + return new Promise((resolve, reject) => { + Users.remove({ _id: userId }, (err) => { + if (err) { + reject(err) + } else { + resolve(err) + } + }) + }) +} diff --git a/package-lock.json b/package-lock.json index e1857c1..3c8bb1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5440,6 +5440,12 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, "pretty-format": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", diff --git a/package.json b/package.json index 792cd94..b947644 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "Simple CMS backend", "scripts": { "start": "node ./bin/www", - "test": "jest --detectOpenHandles --forceExit" + "pretty": "prettier --write \"./**/*.{js,json}\"" }, "author": "Satyajit Dey", "contributors": [ @@ -47,7 +47,7 @@ "eslint": "6.8.0", "mocha": "7.1.2", "nodemon": "2.0.3", - "jest": "26.0.1", + "prettier": "2.0.5", "supertest": "4.0.2" }, "repository": { diff --git a/routes/article.js b/routes/article.js index 6e1c719..7489562 100644 --- a/routes/article.js +++ b/routes/article.js @@ -1,187 +1,204 @@ var debug = require('debug') -var express = require('express'); -var mongoose = require('mongoose'); -var bodyParser = require('body-parser'); +var express = require('express') +var mongoose = require('mongoose') +var bodyParser = require('body-parser') var slugify = require('slugify') -var auth = require('../middlewares/auth.validation.middleware'); +var auth = require('../middlewares/auth.validation.middleware') -var Article = require('../models/article'); +var Article = require('../models/article') -var router = express.Router(); -router.use(bodyParser.json()); +var router = express.Router() +router.use(bodyParser.json()) var createUniqueUrl = (title, callBack, counter = 0) => { - var url = slugify(title, { - lower: true, // convert to lower case - strict: true, // strip special characters except replacement - }); - - if (counter > 0) { - url += '-' + counter; + var url = slugify(title, { + lower: true, // convert to lower case + strict: true, // strip special characters except replacement + }) + + if (counter > 0) { + url += '-' + counter + } + + Article.findOne({ url: url }).then((art) => { + if (null === art) { + callBack(url) + } else { + createUniqueUrl(title, callBack, counter + 1) } - - Article.findOne({ url: url }) - .then((art) => { - if (null === art) { - callBack(url); - } - else { - createUniqueUrl(title, callBack, counter + 1); - } - }) + }) } - -router.route('/') - .get((req, res, next) => { - Article.find({}) - .sort({ 'updatedAt': -1 }) - .limit(5) - .populate('author') - .exec(function (err, articles) { - if (err) { - res.statusCode = 500; - res.setHeader('Content-Type', 'application/json'); - res.json(err); - } - else { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(articles); - } - }); - }) - .post(auth.verifyJwtToken, (req, res, next) => { - createUniqueUrl(req.body.title, (url) => { - var article = new Article({ title: req.body.title }); - article.url = url; - article.body = req.body.body; - article.author = req.jwt.userId; - - article.save((err, art) => { - if (err) { - res.statusCode = 500; - res.setHeader('Content-Type', 'application/json'); - res.json(err); - } - else { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(art); - } - }) - }); - }) - .put((req, res, next) => { - res.statusCode = 403; - res.end('PUT operation not supported on /article'); - }) - .delete((req, res, next) => { - res.statusCode = 403; - res.end('DELETE operation not supported on /article'); - }); - - -/* with id */ -router.route('/:articleId') - .get((req, res, next) => { - Article.findById(req.params.articleId) - .populate('author') - .then((article) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(article); - }, (err) => next(err)) - .catch((err) => next(err)); - }) - .post((req, res, next) => { - res.statusCode = 403; - res.end('POST operation not supported on /article/' + req.params.articleId); - }) - .put(auth.verifyJwtToken, (req, res, next) => { - - if (mongoose.Types.ObjectId.isValid(req.params.articleId)) { - - Article.findById(req.params.articleId) - //.populate('author') - .then((article) => { - - if (null === article) { - var err = new Error('Article ' + req.params.articleId + ' not found'); - err.status = 404; - return next(err); - } - else { - //update url as title is changed - if (article.title !== req.body.title) { - createUniqueUrl(req.body.title, (url) => { - Article.findByIdAndUpdate(req.params.articleId, { - $set: { "title": req.body.title, "url": url, "body": req.body.body } - }, { new: true }) - .then((upudatedArt) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(upudatedArt); - }, (err) => next(err)) - .catch((err) => next(err)); - }); - } - else { - Article.findByIdAndUpdate(req.params.articleId, { - $set: req.body - }, { new: true }) - .then((upudatedArt) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(upudatedArt); - }, (err) => next(err)) - .catch((err) => next(err)); - } - } - }, (err) => next(err)) - .catch((err) => next(err)); +router + .route('/') + .get((req, res, next) => { + Article.find({}) + .sort({ updatedAt: -1 }) + .limit(5) + .populate('author') + .exec(function (err, articles) { + if (err) { + res.statusCode = 500 + res.setHeader('Content-Type', 'application/json') + res.json(err) + } else { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(articles) } - else { - var err = new Error('Article ' + req.params.articleId + ' not found'); - err.status = 404; - return next(err); + }) + }) + .post(auth.verifyJwtToken, (req, res, next) => { + createUniqueUrl(req.body.title, (url) => { + var article = new Article({ title: req.body.title }) + article.url = url + article.body = req.body.body + article.author = req.jwt.userId + + article.save((err, art) => { + if (err) { + res.statusCode = 500 + res.setHeader('Content-Type', 'application/json') + res.json(err) + } else { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(art) } + }) }) - .delete(auth.verifyJwtToken, (req, res, next) => { - if (mongoose.Types.ObjectId.isValid(req.params.articleId)) { - Article.findById(req.params.articleId) - .then((art) => { - if (null === art) { - var err = new Error('Article ' + req.params.articleId + ' not found'); - err.status = 404; - return next(err); - } - else { - //only creator can delete his article - if (art.author.id == req.jwt.userId) { - Article.findByIdAndRemove(req.params.articleId) - .then(rem => { - res.statusCode = 200; - res.setHeader('Content-Type', 'application/json'); - res.json(art); - }); - } - else { - var err = new Error('You do not have permission to delete this article!'); - err.status = 403; - return next(err); - } + }) + .put((req, res, next) => { + res.statusCode = 403 + res.end('PUT operation not supported on /article') + }) + .delete((req, res, next) => { + res.statusCode = 403 + res.end('DELETE operation not supported on /article') + }) - } - - }, (err) => next(err)) - .catch((err) => next(err)); - } - else { - var err = new Error('Article ' + req.params.articleId + ' not found'); - err.status = 404; - return next(err); - } - }); +/* with id */ +router + .route('/:articleId') + .get((req, res, next) => { + Article.findById(req.params.articleId) + .populate('author') + .then( + (article) => { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(article) + }, + (err) => next(err) + ) + .catch((err) => next(err)) + }) + .post((req, res, next) => { + res.statusCode = 403 + res.end('POST operation not supported on /article/' + req.params.articleId) + }) + .put(auth.verifyJwtToken, (req, res, next) => { + if (mongoose.Types.ObjectId.isValid(req.params.articleId)) { + Article.findById(req.params.articleId) + //.populate('author') + .then( + (article) => { + if (null === article) { + var err = new Error( + 'Article ' + req.params.articleId + ' not found' + ) + err.status = 404 + return next(err) + } else { + //update url as title is changed + if (article.title !== req.body.title) { + createUniqueUrl(req.body.title, (url) => { + Article.findByIdAndUpdate( + req.params.articleId, + { + $set: { + title: req.body.title, + url: url, + body: req.body.body, + }, + }, + { new: true } + ) + .then( + (upudatedArt) => { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(upudatedArt) + }, + (err) => next(err) + ) + .catch((err) => next(err)) + }) + } else { + Article.findByIdAndUpdate( + req.params.articleId, + { + $set: req.body, + }, + { new: true } + ) + .then( + (upudatedArt) => { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(upudatedArt) + }, + (err) => next(err) + ) + .catch((err) => next(err)) + } + } + }, + (err) => next(err) + ) + .catch((err) => next(err)) + } else { + var err = new Error('Article ' + req.params.articleId + ' not found') + err.status = 404 + return next(err) + } + }) + .delete(auth.verifyJwtToken, (req, res, next) => { + if (mongoose.Types.ObjectId.isValid(req.params.articleId)) { + Article.findById(req.params.articleId) + .then( + (art) => { + if (null === art) { + var err = new Error( + 'Article ' + req.params.articleId + ' not found' + ) + err.status = 404 + return next(err) + } else { + //only creator can delete his article + if (art.author.id == req.jwt.userId) { + Article.findByIdAndRemove(req.params.articleId).then((rem) => { + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.json(art) + }) + } else { + var err = new Error( + 'You do not have permission to delete this article!' + ) + err.status = 403 + return next(err) + } + } + }, + (err) => next(err) + ) + .catch((err) => next(err)) + } else { + var err = new Error('Article ' + req.params.articleId + ' not found') + err.status = 404 + return next(err) + } + }) -module.exports = router; \ No newline at end of file +module.exports = router diff --git a/routes/auth.route.js b/routes/auth.route.js index 425767f..1a0059f 100644 --- a/routes/auth.route.js +++ b/routes/auth.route.js @@ -1,17 +1,19 @@ -const express = require('express'); -const router = express.Router(); +const express = require('express') +const router = express.Router() -const AuthorizationController = require('../controllers/auth.controller'); -const FieldValidateMiddleware = require("../middlewares/field.validation.middleware"); -const AuthValidationMiddleware = require("../middlewares/auth.validation.middleware"); +const AuthorizationController = require('../controllers/auth.controller') +const FieldValidateMiddleware = require('../middlewares/field.validation.middleware') +const AuthValidationMiddleware = require('../middlewares/auth.validation.middleware') router.post('/token', [ - AuthValidationMiddleware.authFieldValidationRules(), [ - FieldValidateMiddleware.validateRules, - AuthValidationMiddleware.matchEmailAndPassword - ], AuthorizationController.login -]); + AuthValidationMiddleware.authFieldValidationRules(), + [ + FieldValidateMiddleware.validateRules, + AuthValidationMiddleware.matchEmailAndPassword, + ], + AuthorizationController.login, +]) -router.get('/logout', AuthorizationController.logout); +router.get('/logout', AuthorizationController.logout) -module.exports = router; \ No newline at end of file +module.exports = router diff --git a/routes/binaries.route.js b/routes/binaries.route.js index de62d00..609ed40 100644 --- a/routes/binaries.route.js +++ b/routes/binaries.route.js @@ -1,29 +1,38 @@ -const express = require('express'); -const router = express.Router(); -const multer = require('multer'); +const express = require('express') +const router = express.Router() +const multer = require('multer') -const AuthValidationMiddleware = require("../middlewares/auth.validation.middleware"); -const AuthPermissionMiddleware = require("../middlewares/auth.permission.middleware"); -const BinariesController = require('../controllers/binaries.controller'); +const AuthValidationMiddleware = require('../middlewares/auth.validation.middleware') +const AuthPermissionMiddleware = require('../middlewares/auth.permission.middleware') +const BinariesController = require('../controllers/binaries.controller') // configure DiscStorage engine const storage = multer.diskStorage({ - destination: process.env.FS_UPLOAD_IMAGE, - filename: function (req, file, cb) { - cb(null, file.originalname); - } -}); + destination: process.env.FS_UPLOAD_IMAGE, + filename: function (req, file, cb) { + cb(null, file.originalname) + }, +}) -const upload = multer({storage: storage}); +const upload = multer({ storage: storage }) -router.get('/images/:id/:filename', - AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_VIEWER), - BinariesController.retrieveImage); +router.get( + '/images/:id/:filename', + AuthValidationMiddleware.verifyJwtToken, + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_VIEWER + ), + BinariesController.retrieveImage +) -router.post('/images/upload', upload.single('image'), - AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_EDITOR), - BinariesController.uploadImage); +router.post( + '/images/upload', + upload.single('image'), + AuthValidationMiddleware.verifyJwtToken, + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_EDITOR + ), + BinariesController.uploadImage +) -module.exports = router; \ No newline at end of file +module.exports = router diff --git a/routes/index.js b/routes/index.js index d41e5fa..e3201ac 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,12 +1,11 @@ - -var express = require('express'); -var router = express.Router(); +var express = require('express') +var router = express.Router() /* GET home page. */ -router.get('/', function(req, res, next) { - res.statusCode=200; - res.setHeader('Content-Type', 'text/html'); - res.end('Hello CMS'); -}); +router.get('/', function (req, res, next) { + res.statusCode = 200 + res.setHeader('Content-Type', 'text/html') + res.end('Hello CMS') +}) -module.exports = router; \ No newline at end of file +module.exports = router diff --git a/routes/users.route.js b/routes/users.route.js index 30059e8..bdf68e1 100644 --- a/routes/users.route.js +++ b/routes/users.route.js @@ -1,48 +1,75 @@ -const express = require('express'); -const router = express.Router(); +const express = require('express') +const router = express.Router() -const UsersController = require('../controllers/users.controller'); -const UserValidationMiddleware = require('../middlewares/user.validation.middleware'); -const FieldValidateMiddleware = require('../middlewares/field.validation.middleware'); -const AuthValidationMiddleware = require("../middlewares/auth.validation.middleware"); -const AuthPermissionMiddleware = require("../middlewares/auth.permission.middleware"); +const UsersController = require('../controllers/users.controller') +const UserValidationMiddleware = require('../middlewares/user.validation.middleware') +const FieldValidateMiddleware = require('../middlewares/field.validation.middleware') +const AuthValidationMiddleware = require('../middlewares/auth.validation.middleware') +const AuthPermissionMiddleware = require('../middlewares/auth.permission.middleware') -router.post('/', - //Pass validation rules - UserValidationMiddleware.registrationFieldValidationRules(), [ - //Validate the rule(s) - FieldValidateMiddleware.validateRules, - UserValidationMiddleware.isEmailAlreadyExists - ], - //Pass the actual operation middleware - UsersController.insert); +router.post( + '/', + //Pass validation rules + UserValidationMiddleware.registrationFieldValidationRules(), + [ + //Validate the rule(s) + FieldValidateMiddleware.validateRules, + UserValidationMiddleware.isEmailAlreadyExists, + ], + //Pass the actual operation middleware + UsersController.insert +) -router.get('/', [ +router.get( + '/', + [ AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_ADMIN) -], UsersController.list); + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_ADMIN + ), + ], + UsersController.list +) -router.get('/:userId', [ +router.get( + '/:userId', + [ UserValidationMiddleware.verifyUserId, AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_VIEWER), - AuthPermissionMiddleware.onlySameUserOrAdminCanDoThisAction -], UsersController.getById); + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_VIEWER + ), + AuthPermissionMiddleware.onlySameUserOrAdminCanDoThisAction, + ], + UsersController.getById +) -router.patch('/:userId', - UserValidationMiddleware.updatePasswordValidationRules(), [ - FieldValidateMiddleware.validateRules, - UserValidationMiddleware.verifyUserId, - AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_VIEWER), - AuthPermissionMiddleware.onlySameUserOrAdminCanDoThisAction - ], UsersController.patchById); +router.patch( + '/:userId', + UserValidationMiddleware.updatePasswordValidationRules(), + [ + FieldValidateMiddleware.validateRules, + UserValidationMiddleware.verifyUserId, + AuthValidationMiddleware.verifyJwtToken, + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_VIEWER + ), + AuthPermissionMiddleware.onlySameUserOrAdminCanDoThisAction, + ], + UsersController.patchById +) -router.delete('/:userId', [ +router.delete( + '/:userId', + [ UserValidationMiddleware.verifyUserId, AuthValidationMiddleware.verifyJwtToken, - AuthPermissionMiddleware.minimumPermissionLevelRequired(process.env.AUTH_PERMISSION_ADMIN), - AuthPermissionMiddleware.sameUserCantDoThisAction -], UsersController.removeById); + AuthPermissionMiddleware.minimumPermissionLevelRequired( + process.env.AUTH_PERMISSION_ADMIN + ), + AuthPermissionMiddleware.sameUserCantDoThisAction, + ], + UsersController.removeById +) -module.exports = router; \ No newline at end of file +module.exports = router diff --git a/services/db.service.js b/services/db.service.js index fbe05be..6507765 100644 --- a/services/db.service.js +++ b/services/db.service.js @@ -1,29 +1,34 @@ -const debug = require('debug')('cms-backend-api:*'); -const mongoose = require('mongoose'); +const debug = require('debug')('cms-backend-api:*') +const mongoose = require('mongoose') -let count = 0; +let count = 0 const options = { - autoIndex: false, // Don't build indexes - poolSize: 10, // Maintain up to 10 socket connections - // If not connected, return errors immediately rather than waiting for reconnect - bufferMaxEntries: 0, - //get rid off the depreciation errors - useNewUrlParser: true, - useUnifiedTopology: true, - useFindAndModify: false - -}; + autoIndex: false, // Don't build indexes + poolSize: 10, // Maintain up to 10 socket connections + // If not connected, return errors immediately rather than waiting for reconnect + bufferMaxEntries: 0, + //get rid off the depreciation errors + useNewUrlParser: true, + useUnifiedTopology: true, + useFindAndModify: false, +} const connectWithRetry = () => { - //console.log('MongoDB connection with retry') - mongoose.connect(process.env.DB_URL, options).then(() => { - debug('MongoDB is connected') - }).catch(err => { - console.log('MongoDB connection unsuccessful, retry after 5 seconds. ', ++count); - setTimeout(connectWithRetry, 5000) + //console.log('MongoDB connection with retry') + mongoose + .connect(process.env.DB_URL, options) + .then(() => { + debug('MongoDB is connected') + }) + .catch((err) => { + console.log( + 'MongoDB connection unsuccessful, retry after 5 seconds. ', + ++count + ) + setTimeout(connectWithRetry, 5000) }) -}; +} -connectWithRetry(); +connectWithRetry() -exports.mongoose = mongoose; +exports.mongoose = mongoose diff --git a/test/app.test.js b/test/app.test.js index 4c55a40..3789170 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -1,13 +1,13 @@ -const request = require("supertest"); -const app = require("../app"); +const request = require('supertest') +const app = require('../app') -describe("Test the root path", () => { - test("It should response the GET method", done => { +describe('Test the root path', () => { + test('It should response the GET method', (done) => { request(app) - .get("/") - .then(response => { - expect(response.statusCode).toBe(200); - done(); - }); - }); -}); \ No newline at end of file + .get('/') + .then((response) => { + expect(response.statusCode).toBe(200) + done() + }) + }) +}) diff --git a/test/routes/article.test.js b/test/routes/article.test.js index 77bc698..d5ce6ab 100644 --- a/test/routes/article.test.js +++ b/test/routes/article.test.js @@ -1,43 +1,40 @@ -const request = require("supertest"); -const app = require("../../app"); +const request = require('supertest') +const app = require('../../app') -describe("Test GET /article", () => { - test("It should response 200 on GET method", done => { +describe('Test GET /article', () => { + test('It should response 200 on GET method', (done) => { request(app) .get(`${process.env.API_ENPOINT_BASE}/article`) - .then(response => { - expect(response.statusCode).toBe(200); - done(); - }); - }); -}); - + .then((response) => { + expect(response.statusCode).toBe(200) + done() + }) + }) +}) const article = { - title: "Test: how to test express API POST request?", - body: ["

Article body sub heading

", "

Article body paragraph

"] -}; - + title: 'Test: how to test express API POST request?', + body: ['

Article body sub heading

', '

Article body paragraph

'], +} /* GET /article/:artId */ -describe("Test POST /article/:articleId", () => { - test("It should response 200 on GET method", done => { +describe('Test POST /article/:articleId', () => { + test('It should response 200 on GET method', (done) => { request(app) .get(`${process.env.API_ENPOINT_BASE}/article`) - .then(response => { - expect(response.statusCode).toBe(200); - const articles = JSON.parse(response.text); + .then((response) => { + expect(response.statusCode).toBe(200) + const articles = JSON.parse(response.text) if (articles && articles.length) { request(app) .get(`${process.env.API_ENPOINT_BASE}/article/${articles[0]._id}`) - .then(response => { - expect(response.statusCode).toBe(200); - done(); - }); - } - else { - done(); + .then((response) => { + expect(response.statusCode).toBe(200) + done() + }) + } else { + done() } - }); - }); -}); + }) + }) +})