From 03e1a1e1403d36e6b4702738a69222f831231760 Mon Sep 17 00:00:00 2001 From: Surabhi Sharma Date: Thu, 27 Jul 2017 23:20:19 +0530 Subject: [PATCH] Add travis-script --- .travis.yml | 29 ++-- dist/.gitignore | 51 ++++++ dist/config/config.js | 51 ++++++ dist/config/config.js.map | 1 + dist/config/express.js | 145 ++++++++++++++++++ dist/config/express.js.map | 1 + dist/config/param-validation.js | 42 +++++ dist/config/param-validation.js.map | 1 + dist/config/winston.js | 22 +++ dist/config/winston.js.map | 1 + dist/index.js | 59 +++++++ dist/index.js.map | 1 + dist/package.json | 109 +++++++++++++ dist/server/controllers/auth.controller.js | 71 +++++++++ .../server/controllers/auth.controller.js.map | 1 + dist/server/controllers/user.controller.js | 105 +++++++++++++ .../server/controllers/user.controller.js.map | 1 + dist/server/helpers/APIError.js | 71 +++++++++ dist/server/helpers/APIError.js.map | 1 + dist/server/models/user.model.js | 98 ++++++++++++ dist/server/models/user.model.js.map | 1 + dist/server/routes/auth.route.js | 44 ++++++ dist/server/routes/auth.route.js.map | 1 + dist/server/routes/index.route.js | 36 +++++ dist/server/routes/index.route.js.map | 1 + dist/server/routes/user.route.js | 49 ++++++ dist/server/routes/user.route.js.map | 1 + dist/server/tests/auth.test.js | 88 +++++++++++ dist/server/tests/auth.test.js.map | 1 + dist/server/tests/misc.test.js | 60 ++++++++ dist/server/tests/misc.test.js.map | 1 + dist/server/tests/user.test.js | 109 +++++++++++++ dist/server/tests/user.test.js.map | 1 + package.json | 3 +- travis.sh | 22 +-- 35 files changed, 1257 insertions(+), 22 deletions(-) create mode 100644 dist/.gitignore create mode 100644 dist/config/config.js create mode 100644 dist/config/config.js.map create mode 100644 dist/config/express.js create mode 100644 dist/config/express.js.map create mode 100644 dist/config/param-validation.js create mode 100644 dist/config/param-validation.js.map create mode 100644 dist/config/winston.js create mode 100644 dist/config/winston.js.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/package.json create mode 100644 dist/server/controllers/auth.controller.js create mode 100644 dist/server/controllers/auth.controller.js.map create mode 100644 dist/server/controllers/user.controller.js create mode 100644 dist/server/controllers/user.controller.js.map create mode 100644 dist/server/helpers/APIError.js create mode 100644 dist/server/helpers/APIError.js.map create mode 100644 dist/server/models/user.model.js create mode 100644 dist/server/models/user.model.js.map create mode 100644 dist/server/routes/auth.route.js create mode 100644 dist/server/routes/auth.route.js.map create mode 100644 dist/server/routes/index.route.js create mode 100644 dist/server/routes/index.route.js.map create mode 100644 dist/server/routes/user.route.js create mode 100644 dist/server/routes/user.route.js.map create mode 100644 dist/server/tests/auth.test.js create mode 100644 dist/server/tests/auth.test.js.map create mode 100644 dist/server/tests/misc.test.js create mode 100644 dist/server/tests/misc.test.js.map create mode 100644 dist/server/tests/user.test.js create mode 100644 dist/server/tests/user.test.js.map diff --git a/.travis.yml b/.travis.yml index 153febe6..076e73a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,32 @@ language: node_js node_js: -- '7.6' + - '7.6' services: -- mongodb + - mongodb cache: directories: - node_modules git: depth: 3 -script: npm run build && cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec - --colors --compilers js:babel-core/register server/tests --recursive +script: npm run travis-script after_script: -- npm report-coverage + - npm report-coverage before_script: -- npm install -g gulp-cli -- bash travis.sh + - npm install -g gulp-cli deploy: app: test-ci provider: heroku api_key: secure: auBdU0dKRsULQaMsTFnt0Gal/YSJSQFgSz1bONqYkm+TFnSlC2W3w1BNUFAqyrUceWT90aieBRau4G9yFNUE6/MGFaxH7a2B1CYraXE2sHXQQ5+vts2mIyeMNnAWiQTiqpMjBvIVKkfLzgOdYgTgNwIZ4b6bSRqd9upCAZAbhoipFNpChSdPtKS6iAr3V7PXlHl1GOyPqURVmhi5r3snHAWk70tp5RZMEX/jSvXnQDFK+YlNyKS4LwpyS1B9UB1C+wLx5MCuijFi6l02ETD21LN3JQG800MKukG3/6Zhec2JbCzlRMMphHJk0fX2bshIpLAEuZzEd0dvOYVTJ5maMuCUijq07PTTIuTOLKCcoZFuKm+sypF9jv4lEVfQUp+dEchrfQyixJNgbuEP6qbbo00i4xzMxPMrj/l0cPI0LSSgupLS4CrrmwiVvqTx30Cr0MXY+sU2uGMNOABHVce6S7QoNv0jst9RlDd2Ab+Q+akD7/ZABGFpOE8AIADP4y9gZcoj92nn8uOpRnISgYGjdBYM9iqksTxiWqwgGWKKWXhr5Gjvc1Ql6y4LBHvtKNDHliMwGs7N9f5PLpWitY50q7NMzwuMH8mO95+WXQ1MFxFORp04p+rscTx7jr8Q+uF/SWZ20BmmmAYIyqMIvREEHKMK/s5xlT7QvrQV/ZENMKU= -# after_success: -# - bash travis.sh -# env: -# global: -# secure: GaWCIjifcrDR1/bzRo5X5tcZXKfiulC8LcxXmzAD9nL83VNmuXZ5XE9j5Pt5uNtT9J6xDHF9OMnvknJlAKKp6ZmWGU8wQmO4nc/GZFOhZP4jv8v/v0kFFhvDN9YzuBGIl+daafCZ2Ve3wANnxb92qsHC5TsIBRcf/1QGme25tfHqaAGxL165EoecRmbFyFC2biYCj9EyYNxx3gXNB2EPL8M0aLDtXabDHWs3i38G5jZakgYoC0DqGXRubbzl6uJCylawJYoAkk09U8obs6Zv+Z/HkgbR0AjeLVuXd3cwbZkh3uXBw2llFRb/J3T30rfBPgtXDEiI/Qu+uhQSSjf9C4jWu2sVrSizk/6d2wZGlFMIW/549Bi3tSgyhb8PCllTscPGgVaSNAeoBRd3QPj6BVS5u8+DN+hpjGp3sb2IOaWL5NSDd+o8QKQrhSxe5PQDQtmIXZ9vd1Mi9WXCLJiUWSs4R3U4qzEn4b/TiIWKLUqfJg1o++xwZRuUr6GCO3VDcdGcSQOfpr4NCwsZ1QpLY1cbuQGGDzmeviMXy+l0r6wW7knqWmnQBXLcQCqTh0niFok9x4M7Nk3M9Z7vIqa3/bZc7cWUJAk4RFZ3AiO0B1Xw0wpn9cD3tLRasm4SR3HRo5sD4gMvnJY+Fsw3te3jwx7fG/C2hS28jqB9lZJzdl8= +after_success: + - git config --global user.name "Surabhi Sharma" + - git config --global user.email surabhisharma.226005@gmail.com + - if [ "$TRAVIS_BRANCH" == "develop" ] ; then + - git add dist/ + - git checkout -b release + - git commit -m "Dist" + - git push heroku release:master + - fi + + +#- if [ "$TRAVIS_BRANCH" == "master" ] ; then npm run deploy ; else echo "Skipping after_success" ; fi \ No newline at end of file diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 00000000..d5bc83e9 --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1,51 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# IDE +.idea + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +ehthumbs.db +Icon? +Thumbs.db + +# Babel ES6 compiles files +# dist + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# .env +.env diff --git a/dist/config/config.js b/dist/config/config.js new file mode 100644 index 00000000..3bc82424 --- /dev/null +++ b/dist/config/config.js @@ -0,0 +1,51 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _joi = require('joi'); + +var _joi2 = _interopRequireDefault(_joi); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// require and configure dotenv, will load vars in .env in PROCESS.ENV +require('dotenv').config(); + +// define validation for all the env vars +var envVarsSchema = _joi2.default.object({ + NODE_ENV: _joi2.default.string().allow(['development', 'production', 'test', 'provision']).default('development'), + PORT: _joi2.default.number().default(4040), + MONGOOSE_DEBUG: _joi2.default.boolean().when('NODE_ENV', { + is: _joi2.default.string().equal('development'), + then: _joi2.default.boolean().default(true), + otherwise: _joi2.default.boolean().default(false) + }), + JWT_SECRET: _joi2.default.string().required().description('JWT Secret required to sign'), + MONGO_HOST: _joi2.default.string().required().description('Mongo DB host url'), + MONGO_PORT: _joi2.default.number().default(27017) +}).unknown().required(); + +var _Joi$validate = _joi2.default.validate(process.env, envVarsSchema), + error = _Joi$validate.error, + envVars = _Joi$validate.value; + +if (error) { + throw new Error('Config validation error: ' + error.message); +} + +var config = { + env: envVars.NODE_ENV, + port: envVars.PORT, + mongooseDebug: envVars.MONGOOSE_DEBUG, + jwtSecret: envVars.JWT_SECRET, + mongo: { + host: envVars.MONGO_HOST, + port: envVars.MONGO_PORT + } +}; + +exports.default = config; +module.exports = exports['default']; +//# sourceMappingURL=config.js.map diff --git a/dist/config/config.js.map b/dist/config/config.js.map new file mode 100644 index 00000000..c48b0019 --- /dev/null +++ b/dist/config/config.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["config/config.js"],"names":["require","config","envVarsSchema","object","NODE_ENV","string","allow","default","PORT","number","MONGOOSE_DEBUG","boolean","when","is","equal","then","otherwise","JWT_SECRET","required","description","MONGO_HOST","MONGO_PORT","unknown","validate","process","env","error","envVars","value","Error","message","port","mongooseDebug","jwtSecret","mongo","host"],"mappings":";;;;;;AAAA;;;;;;AAEA;AACAA,QAAQ,QAAR,EAAkBC,MAAlB;;AAEA;AACA,IAAMC,gBAAgB,cAAIC,MAAJ,CAAW;AAC/BC,YAAU,cAAIC,MAAJ,GACPC,KADO,CACD,CAAC,aAAD,EAAgB,YAAhB,EAA8B,MAA9B,EAAsC,WAAtC,CADC,EAEPC,OAFO,CAEC,aAFD,CADqB;AAI/BC,QAAM,cAAIC,MAAJ,GACHF,OADG,CACK,IADL,CAJyB;AAM/BG,kBAAgB,cAAIC,OAAJ,GACbC,IADa,CACR,UADQ,EACI;AAChBC,QAAI,cAAIR,MAAJ,GAAaS,KAAb,CAAmB,aAAnB,CADY;AAEhBC,UAAM,cAAIJ,OAAJ,GAAcJ,OAAd,CAAsB,IAAtB,CAFU;AAGhBS,eAAW,cAAIL,OAAJ,GAAcJ,OAAd,CAAsB,KAAtB;AAHK,GADJ,CANe;AAY/BU,cAAY,cAAIZ,MAAJ,GAAaa,QAAb,GACTC,WADS,CACG,6BADH,CAZmB;AAc/BC,cAAY,cAAIf,MAAJ,GAAaa,QAAb,GACTC,WADS,CACG,mBADH,CAdmB;AAgB/BE,cAAY,cAAIZ,MAAJ,GACTF,OADS,CACD,KADC;AAhBmB,CAAX,EAkBnBe,OAlBmB,GAmBnBJ,QAnBmB,EAAtB;;oBAqBkC,cAAIK,QAAJ,CAAaC,QAAQC,GAArB,EAA0BvB,aAA1B,C;IAA1BwB,K,iBAAAA,K;IAAcC,O,iBAAPC,K;;AACf,IAAIF,KAAJ,EAAW;AACT,QAAM,IAAIG,KAAJ,+BAAsCH,MAAMI,OAA5C,CAAN;AACD;;AAED,IAAM7B,SAAS;AACbwB,OAAKE,QAAQvB,QADA;AAEb2B,QAAMJ,QAAQnB,IAFD;AAGbwB,iBAAeL,QAAQjB,cAHV;AAIbuB,aAAWN,QAAQV,UAJN;AAKbiB,SAAO;AACLC,UAAMR,QAAQP,UADT;AAELW,UAAMJ,QAAQN;AAFT;AALM,CAAf;;kBAWepB,M","file":"config.js","sourceRoot":"../../.."} \ No newline at end of file diff --git a/dist/config/express.js b/dist/config/express.js new file mode 100644 index 00000000..43100a99 --- /dev/null +++ b/dist/config/express.js @@ -0,0 +1,145 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _express = require('express'); + +var _express2 = _interopRequireDefault(_express); + +var _morgan = require('morgan'); + +var _morgan2 = _interopRequireDefault(_morgan); + +var _bodyParser = require('body-parser'); + +var _bodyParser2 = _interopRequireDefault(_bodyParser); + +var _cookieParser = require('cookie-parser'); + +var _cookieParser2 = _interopRequireDefault(_cookieParser); + +var _compression = require('compression'); + +var _compression2 = _interopRequireDefault(_compression); + +var _methodOverride = require('method-override'); + +var _methodOverride2 = _interopRequireDefault(_methodOverride); + +var _cors = require('cors'); + +var _cors2 = _interopRequireDefault(_cors); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _expressWinston = require('express-winston'); + +var _expressWinston2 = _interopRequireDefault(_expressWinston); + +var _expressValidation = require('express-validation'); + +var _expressValidation2 = _interopRequireDefault(_expressValidation); + +var _helmet = require('helmet'); + +var _helmet2 = _interopRequireDefault(_helmet); + +var _winston = require('./winston'); + +var _winston2 = _interopRequireDefault(_winston); + +var _index = require('../server/routes/index.route'); + +var _index2 = _interopRequireDefault(_index); + +var _config = require('./config'); + +var _config2 = _interopRequireDefault(_config); + +var _APIError = require('../server/helpers/APIError'); + +var _APIError2 = _interopRequireDefault(_APIError); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var app = (0, _express2.default)(); + +if (_config2.default.env === 'development') { + app.use((0, _morgan2.default)('dev')); +} + +// parse body params and attache them to req.body +app.use(_bodyParser2.default.json()); +app.use(_bodyParser2.default.urlencoded({ extended: true })); + +app.use((0, _cookieParser2.default)()); +app.use((0, _compression2.default)()); +app.use((0, _methodOverride2.default)()); + +// secure apps by setting various HTTP headers +app.use((0, _helmet2.default)()); + +// enable CORS - Cross Origin Resource Sharing +app.use((0, _cors2.default)()); + +// enable detailed API logging in dev env +if (_config2.default.env === 'development') { + _expressWinston2.default.requestWhitelist.push('body'); + _expressWinston2.default.responseWhitelist.push('body'); + app.use(_expressWinston2.default.logger({ + winstonInstance: _winston2.default, + meta: true, // optional: log meta data about request (defaults to true) + msg: 'HTTP {{req.method}} {{req.url}} {{res.statusCode}} {{res.responseTime}}ms', + colorStatus: true // Color the status code (default green, 3XX cyan, 4XX yellow, 5XX red). + })); +} + +// mount all routes on /api path +app.use('/api', _index2.default); + +// if error is not an instanceOf APIError, convert it. +app.use(function (err, req, res, next) { + if (err instanceof _expressValidation2.default.ValidationError) { + // validation error contains errors which is an array of error each containing message[] + var unifiedErrorMessage = err.errors.map(function (error) { + return error.messages.join('. '); + }).join(' and '); + var error = new _APIError2.default(unifiedErrorMessage, err.status, true); + return next(error); + } else if (!(err instanceof _APIError2.default)) { + var apiError = new _APIError2.default(err.message, err.status, err.isPublic); + return next(apiError); + } + return next(err); +}); + +// catch 404 and forward to error handler +app.use(function (req, res, next) { + var err = new _APIError2.default('API not found', _httpStatus2.default.NOT_FOUND); + return next(err); +}); + +// log error in winston transports except when executing test suite +if (_config2.default.env !== 'test') { + app.use(_expressWinston2.default.errorLogger({ + winstonInstance: _winston2.default + })); +} + +// error handler, send stacktrace only during development +app.use(function (err, req, res, next) { + return (// eslint-disable-line no-unused-vars + res.status(err.status).json({ + message: err.isPublic ? err.message : _httpStatus2.default[err.status], + stack: _config2.default.env === 'development' ? err.stack : {} + }) + ); +}); + +exports.default = app; +module.exports = exports['default']; +//# sourceMappingURL=express.js.map diff --git a/dist/config/express.js.map b/dist/config/express.js.map new file mode 100644 index 00000000..c314012c --- /dev/null +++ b/dist/config/express.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["config/express.js"],"names":["app","env","use","json","urlencoded","extended","requestWhitelist","push","responseWhitelist","logger","winstonInstance","meta","msg","colorStatus","err","req","res","next","ValidationError","unifiedErrorMessage","errors","map","error","messages","join","status","apiError","message","isPublic","NOT_FOUND","errorLogger","stack"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAMA,MAAM,wBAAZ;;AAEA,IAAI,iBAAOC,GAAP,KAAe,aAAnB,EAAkC;AAChCD,MAAIE,GAAJ,CAAQ,sBAAO,KAAP,CAAR;AACD;;AAED;AACAF,IAAIE,GAAJ,CAAQ,qBAAWC,IAAX,EAAR;AACAH,IAAIE,GAAJ,CAAQ,qBAAWE,UAAX,CAAsB,EAAEC,UAAU,IAAZ,EAAtB,CAAR;;AAEAL,IAAIE,GAAJ,CAAQ,6BAAR;AACAF,IAAIE,GAAJ,CAAQ,4BAAR;AACAF,IAAIE,GAAJ,CAAQ,+BAAR;;AAEA;AACAF,IAAIE,GAAJ,CAAQ,uBAAR;;AAEA;AACAF,IAAIE,GAAJ,CAAQ,qBAAR;;AAEA;AACA,IAAI,iBAAOD,GAAP,KAAe,aAAnB,EAAkC;AAChC,2BAAeK,gBAAf,CAAgCC,IAAhC,CAAqC,MAArC;AACA,2BAAeC,iBAAf,CAAiCD,IAAjC,CAAsC,MAAtC;AACAP,MAAIE,GAAJ,CAAQ,yBAAeO,MAAf,CAAsB;AAC5BC,sCAD4B;AAE5BC,UAAM,IAFsB,EAEhB;AACZC,SAAK,2EAHuB;AAI5BC,iBAAa,IAJe,CAIV;AAJU,GAAtB,CAAR;AAMD;;AAED;AACAb,IAAIE,GAAJ,CAAQ,MAAR;;AAEA;AACAF,IAAIE,GAAJ,CAAQ,UAACY,GAAD,EAAMC,GAAN,EAAWC,GAAX,EAAgBC,IAAhB,EAAyB;AAC/B,MAAIH,eAAe,4BAAkBI,eAArC,EAAsD;AACpD;AACA,QAAMC,sBAAsBL,IAAIM,MAAJ,CAAWC,GAAX,CAAe;AAAA,aAASC,MAAMC,QAAN,CAAeC,IAAf,CAAoB,IAApB,CAAT;AAAA,KAAf,EAAmDA,IAAnD,CAAwD,OAAxD,CAA5B;AACA,QAAMF,QAAQ,uBAAaH,mBAAb,EAAkCL,IAAIW,MAAtC,EAA8C,IAA9C,CAAd;AACA,WAAOR,KAAKK,KAAL,CAAP;AACD,GALD,MAKO,IAAI,EAAER,iCAAF,CAAJ,EAAgC;AACrC,QAAMY,WAAW,uBAAaZ,IAAIa,OAAjB,EAA0Bb,IAAIW,MAA9B,EAAsCX,IAAIc,QAA1C,CAAjB;AACA,WAAOX,KAAKS,QAAL,CAAP;AACD;AACD,SAAOT,KAAKH,GAAL,CAAP;AACD,CAXD;;AAaA;AACAd,IAAIE,GAAJ,CAAQ,UAACa,GAAD,EAAMC,GAAN,EAAWC,IAAX,EAAoB;AAC1B,MAAMH,MAAM,uBAAa,eAAb,EAA8B,qBAAWe,SAAzC,CAAZ;AACA,SAAOZ,KAAKH,GAAL,CAAP;AACD,CAHD;;AAKA;AACA,IAAI,iBAAOb,GAAP,KAAe,MAAnB,EAA2B;AACzBD,MAAIE,GAAJ,CAAQ,yBAAe4B,WAAf,CAA2B;AACjCpB;AADiC,GAA3B,CAAR;AAGD;;AAED;AACAV,IAAIE,GAAJ,CAAQ,UAACY,GAAD,EAAMC,GAAN,EAAWC,GAAX,EAAgBC,IAAhB;AAAA,SAAyB;AAC/BD,QAAIS,MAAJ,CAAWX,IAAIW,MAAf,EAAuBtB,IAAvB,CAA4B;AAC1BwB,eAASb,IAAIc,QAAJ,GAAed,IAAIa,OAAnB,GAA6B,qBAAWb,IAAIW,MAAf,CADZ;AAE1BM,aAAO,iBAAO9B,GAAP,KAAe,aAAf,GAA+Ba,IAAIiB,KAAnC,GAA2C;AAFxB,KAA5B;AADM;AAAA,CAAR;;kBAOe/B,G","file":"express.js","sourceRoot":"../../.."} \ No newline at end of file diff --git a/dist/config/param-validation.js b/dist/config/param-validation.js new file mode 100644 index 00000000..d1065fef --- /dev/null +++ b/dist/config/param-validation.js @@ -0,0 +1,42 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _joi = require('joi'); + +var _joi2 = _interopRequireDefault(_joi); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + // POST /api/users + createUser: { + body: { + username: _joi2.default.string().required(), + mobileNumber: _joi2.default.string().regex(/^[1-9][0-9]{9}$/).required() + } + }, + + // UPDATE /api/users/:userId + updateUser: { + body: { + username: _joi2.default.string().required(), + mobileNumber: _joi2.default.string().regex(/^[1-9][0-9]{9}$/).required() + }, + params: { + userId: _joi2.default.string().hex().required() + } + }, + + // POST /api/auth/login + login: { + body: { + username: _joi2.default.string().required(), + password: _joi2.default.string().required() + } + } +}; +module.exports = exports['default']; +//# sourceMappingURL=param-validation.js.map diff --git a/dist/config/param-validation.js.map b/dist/config/param-validation.js.map new file mode 100644 index 00000000..ca3aa39b --- /dev/null +++ b/dist/config/param-validation.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["config/param-validation.js"],"names":["createUser","body","username","string","required","mobileNumber","regex","updateUser","params","userId","hex","login","password"],"mappings":";;;;;;AAAA;;;;;;kBAEe;AACb;AACAA,cAAY;AACVC,UAAM;AACJC,gBAAU,cAAIC,MAAJ,GAAaC,QAAb,EADN;AAEJC,oBAAc,cAAIF,MAAJ,GAAaG,KAAb,CAAmB,iBAAnB,EAAsCF,QAAtC;AAFV;AADI,GAFC;;AASb;AACAG,cAAY;AACVN,UAAM;AACJC,gBAAU,cAAIC,MAAJ,GAAaC,QAAb,EADN;AAEJC,oBAAc,cAAIF,MAAJ,GAAaG,KAAb,CAAmB,iBAAnB,EAAsCF,QAAtC;AAFV,KADI;AAKVI,YAAQ;AACNC,cAAQ,cAAIN,MAAJ,GAAaO,GAAb,GAAmBN,QAAnB;AADF;AALE,GAVC;;AAoBb;AACAO,SAAO;AACLV,UAAM;AACJC,gBAAU,cAAIC,MAAJ,GAAaC,QAAb,EADN;AAEJQ,gBAAU,cAAIT,MAAJ,GAAaC,QAAb;AAFN;AADD;AArBM,C","file":"param-validation.js","sourceRoot":"../../.."} \ No newline at end of file diff --git a/dist/config/winston.js b/dist/config/winston.js new file mode 100644 index 00000000..2bbc564e --- /dev/null +++ b/dist/config/winston.js @@ -0,0 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _winston = require('winston'); + +var _winston2 = _interopRequireDefault(_winston); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var logger = new _winston2.default.Logger({ + transports: [new _winston2.default.transports.Console({ + json: true, + colorize: true + })] +}); + +exports.default = logger; +module.exports = exports['default']; +//# sourceMappingURL=winston.js.map diff --git a/dist/config/winston.js.map b/dist/config/winston.js.map new file mode 100644 index 00000000..c1c998fc --- /dev/null +++ b/dist/config/winston.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["config/winston.js"],"names":["logger","Logger","transports","Console","json","colorize"],"mappings":";;;;;;AAAA;;;;;;AAEA,IAAMA,SAAS,IAAK,kBAAQC,MAAb,CAAqB;AAClCC,cAAY,CACV,IAAK,kBAAQA,UAAR,CAAmBC,OAAxB,CAAiC;AAC/BC,UAAM,IADyB;AAE/BC,cAAU;AAFqB,GAAjC,CADU;AADsB,CAArB,CAAf;;kBASeL,M","file":"winston.js","sourceRoot":"../../.."} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..faabecd2 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,59 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _mongoose = require('mongoose'); + +var _mongoose2 = _interopRequireDefault(_mongoose); + +var _util = require('util'); + +var _util2 = _interopRequireDefault(_util); + +var _config = require('./config/config'); + +var _config2 = _interopRequireDefault(_config); + +var _express = require('./config/express'); + +var _express2 = _interopRequireDefault(_express); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// config should be imported before importing any other file +var debug = require('debug')('express-mongoose-es6-rest-api:index'); + +// make bluebird default Promise +Promise = require('bluebird'); // eslint-disable-line no-global-assign + +// plugin bluebird promise in mongoose +_mongoose2.default.Promise = Promise; + +// connect to mongo db +var mongoUri = _config2.default.mongo.host; +_mongoose2.default.connect(mongoUri, { server: { socketOptions: { keepAlive: 1 } } }); +_mongoose2.default.connection.on('error', function () { + throw new Error('unable to connect to database: ' + mongoUri); +}); + +// print mongoose logs in dev env +if (_config2.default.MONGOOSE_DEBUG) { + _mongoose2.default.set('debug', function (collectionName, method, query, doc) { + debug(collectionName + '.' + method, _util2.default.inspect(query, false, 20), doc); + }); +} + +// module.parent check is required to support mocha watch +// src: https://github.com/mochajs/mocha/issues/1912 +if (!module.parent) { + // listen on port config.port + _express2.default.listen(_config2.default.port, function () { + console.info('server started on port ' + _config2.default.port + ' (' + _config2.default.env + ')'); // eslint-disable-line no-console + }); +} + +exports.default = _express2.default; +module.exports = exports['default']; +//# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 00000000..0077e8c2 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["index.js"],"names":["debug","require","Promise","mongoUri","mongo","host","connect","server","socketOptions","keepAlive","connection","on","Error","MONGOOSE_DEBUG","set","collectionName","method","query","doc","inspect","module","parent","listen","port","console","info","env"],"mappings":";;;;;;AAAA;;;;AACA;;;;AAGA;;;;AACA;;;;;;AAFA;AAIA,IAAMA,QAAQC,QAAQ,OAAR,EAAiB,qCAAjB,CAAd;;AAEA;AACAC,UAAUD,QAAQ,UAAR,CAAV,C,CAA+B;;AAE/B;AACA,mBAASC,OAAT,GAAmBA,OAAnB;;AAEA;AACA,IAAMC,WAAW,iBAAOC,KAAP,CAAaC,IAA9B;AACA,mBAASC,OAAT,CAAiBH,QAAjB,EAA2B,EAAEI,QAAQ,EAAEC,eAAe,EAAEC,WAAW,CAAb,EAAjB,EAAV,EAA3B;AACA,mBAASC,UAAT,CAAoBC,EAApB,CAAuB,OAAvB,EAAgC,YAAM;AACpC,QAAM,IAAIC,KAAJ,qCAA4CT,QAA5C,CAAN;AACD,CAFD;;AAIA;AACA,IAAI,iBAAOU,cAAX,EAA2B;AACzB,qBAASC,GAAT,CAAa,OAAb,EAAsB,UAACC,cAAD,EAAiBC,MAAjB,EAAyBC,KAAzB,EAAgCC,GAAhC,EAAwC;AAC5DlB,UAASe,cAAT,SAA2BC,MAA3B,EAAqC,eAAKG,OAAL,CAAaF,KAAb,EAAoB,KAApB,EAA2B,EAA3B,CAArC,EAAqEC,GAArE;AACD,GAFD;AAGD;;AAED;AACA;AACA,IAAI,CAACE,OAAOC,MAAZ,EAAoB;AAClB;AACA,oBAAIC,MAAJ,CAAW,iBAAOC,IAAlB,EAAwB,YAAM;AAC5BC,YAAQC,IAAR,6BAAuC,iBAAOF,IAA9C,UAAuD,iBAAOG,GAA9D,QAD4B,CAC2C;AACxE,GAFD;AAGD","file":"index.js","sourceRoot":".."} \ No newline at end of file diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 00000000..5a30115f --- /dev/null +++ b/dist/package.json @@ -0,0 +1,109 @@ +{ + "name": "express-mongoose-es6-rest-api", + "version": "2.0.0", + "description": "A Boilerplate application for building REST APIs using express, mongoose in ES6 with code coverage", + "author": "Kunal Kapadia ", + "main": "index.js", + "private": false, + "engines": { + "node": ">=4.8.0", + "npm": ">=2.15.11" + }, + "scripts": { + "start": "gulp serve", + "start:debug": "cross-env DEBUG=express-mongoose-es6-rest-api:* npm start", + "build": "gulp", + "lint": "esw *.js server config --color", + "lint:watch": "npm lint -- --watch", + "test": "cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec --colors --compilers js:babel-core/register server/tests --recursive", + "test:watch": "npm test -- --watch", + "test:coverage": "cross-env NODE_ENV=test ./node_modules/.bin/istanbul cover _mocha -- --ui bdd --reporter spec --colors --compilers js:babel-core/register server/tests --recursive", + "test:check-coverage": "npm test:coverage && istanbul check-coverage", + "report-coverage": "coveralls < ./coverage/lcov.info", + "travis-script": "npm run lint && npm test && npm run build" + }, + "repository": { + "type": "git", + "url": "git@github.com:KunalKapadia/express-mongoose-es6-rest-api.git" + }, + "keywords": [ + "express", + "node", + "node.js", + "mongodb", + "mongoose", + "es6", + "mocha", + "istanbul", + "REST", + "API", + "boilerplate" + ], + "dependencies": { + "bluebird": "3.4.6", + "body-parser": "1.15.2", + "compression": "1.6.2", + "cookie-parser": "1.4.3", + "cors": "2.8.1", + "debug": "^2.4.5", + "dotenv": "^4.0.0", + "express": "4.14.0", + "express-jwt": "5.1.0", + "express-validation": "1.0.1", + "express-winston": "2.1.2", + "helmet": "3.1.0", + "http-status": "^0.2.0", + "joi": "10.0.6", + "jsonwebtoken": "7.1.9", + "method-override": "^2.3.5", + "mongoose": "4.7.4", + "morgan": "1.7.0", + "winston": "2.3.0" + }, + "devDependencies": { + "babel-cli": "6.18.0", + "babel-core": "6.18.0", + "babel-plugin-add-module-exports": "0.2.1", + "babel-preset-es2015": "6.16.0", + "babel-preset-stage-2": "6.18.0", + "chai": "^3.4.1", + "commitizen": "^2.9.2", + "coveralls": "^2.11.6", + "cross-env": "3.1.3", + "cz-conventional-changelog": "1.2.0", + "del": "^2.2.0", + "eslint": "3.16.1", + "eslint-config-airbnb-base": "7.1.0", + "eslint-plugin-import": "1.16.0", + "eslint-watch": "2.1.14", + "gulp": "3.9.1", + "gulp-babel": "6.1.2", + "gulp-load-plugins": "^1.2.0", + "gulp-newer": "^1.1.0", + "gulp-nodemon": "^2.0.6", + "gulp-sourcemaps": "^1.6.0", + "gulp-util": "^3.0.7", + "husky": "^0.13.1", + "istanbul": "1.1.0-alpha.1", + "mocha": "3.2.0", + "run-sequence": "^1.1.5", + "supertest": "2.0.1", + "supertest-as-promised": "4.0.2", + "validate-commit-msg": "^2.6.1" + }, + "license": "MIT", + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "babel": { + "presets": [ + "es2015", + "stage-2" + ], + "plugins": [ + "add-module-exports" + ] + } +} diff --git a/dist/server/controllers/auth.controller.js b/dist/server/controllers/auth.controller.js new file mode 100644 index 00000000..16232349 --- /dev/null +++ b/dist/server/controllers/auth.controller.js @@ -0,0 +1,71 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jsonwebtoken = require('jsonwebtoken'); + +var _jsonwebtoken2 = _interopRequireDefault(_jsonwebtoken); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _APIError = require('../helpers/APIError'); + +var _APIError2 = _interopRequireDefault(_APIError); + +var _config = require('../../config/config'); + +var _config2 = _interopRequireDefault(_config); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// sample user, used for authentication +var user = { + username: 'react', + password: 'express' +}; + +/** + * Returns jwt token if valid username and password is provided + * @param req + * @param res + * @param next + * @returns {*} + */ +function login(req, res, next) { + // Ideally you'll fetch this from the db + // Idea here was to show how jwt works with simplicity + if (req.body.username === user.username && req.body.password === user.password) { + var token = _jsonwebtoken2.default.sign({ + username: user.username + }, _config2.default.jwtSecret); + return res.json({ + token: token, + username: user.username + }); + } + + var err = new _APIError2.default('Authentication error', _httpStatus2.default.UNAUTHORIZED, true); + return next(err); +} + +/** + * This is a protected route. Will return random number only if jwt token is provided in header. + * @param req + * @param res + * @returns {*} + */ +function getRandomNumber(req, res) { + // req.user is assigned by jwt middleware if valid token is provided + return res.json({ + user: req.user, + num: Math.random() * 100 + }); +} + +exports.default = { login: login, getRandomNumber: getRandomNumber }; +module.exports = exports['default']; +//# sourceMappingURL=auth.controller.js.map diff --git a/dist/server/controllers/auth.controller.js.map b/dist/server/controllers/auth.controller.js.map new file mode 100644 index 00000000..68794348 --- /dev/null +++ b/dist/server/controllers/auth.controller.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/controllers/auth.controller.js"],"names":["user","username","password","login","req","res","next","body","token","sign","jwtSecret","json","err","UNAUTHORIZED","getRandomNumber","num","Math","random"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA;AACA,IAAMA,OAAO;AACXC,YAAU,OADC;AAEXC,YAAU;AAFC,CAAb;;AAKA;;;;;;;AAOA,SAASC,KAAT,CAAeC,GAAf,EAAoBC,GAApB,EAAyBC,IAAzB,EAA+B;AAC7B;AACA;AACA,MAAIF,IAAIG,IAAJ,CAASN,QAAT,KAAsBD,KAAKC,QAA3B,IAAuCG,IAAIG,IAAJ,CAASL,QAAT,KAAsBF,KAAKE,QAAtE,EAAgF;AAC9E,QAAMM,QAAQ,uBAAIC,IAAJ,CAAS;AACrBR,gBAAUD,KAAKC;AADM,KAAT,EAEX,iBAAOS,SAFI,CAAd;AAGA,WAAOL,IAAIM,IAAJ,CAAS;AACdH,kBADc;AAEdP,gBAAUD,KAAKC;AAFD,KAAT,CAAP;AAID;;AAED,MAAMW,MAAM,uBAAa,sBAAb,EAAqC,qBAAWC,YAAhD,EAA8D,IAA9D,CAAZ;AACA,SAAOP,KAAKM,GAAL,CAAP;AACD;;AAED;;;;;;AAMA,SAASE,eAAT,CAAyBV,GAAzB,EAA8BC,GAA9B,EAAmC;AACjC;AACA,SAAOA,IAAIM,IAAJ,CAAS;AACdX,UAAMI,IAAIJ,IADI;AAEde,SAAKC,KAAKC,MAAL,KAAgB;AAFP,GAAT,CAAP;AAID;;kBAEc,EAAEd,YAAF,EAASW,gCAAT,E","file":"auth.controller.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/controllers/user.controller.js b/dist/server/controllers/user.controller.js new file mode 100644 index 00000000..b4a815c4 --- /dev/null +++ b/dist/server/controllers/user.controller.js @@ -0,0 +1,105 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _user = require('../models/user.model'); + +var _user2 = _interopRequireDefault(_user); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Load user and append to req. + */ +function load(req, res, next, id) { + _user2.default.get(id).then(function (user) { + req.user = user; // eslint-disable-line no-param-reassign + return next(); + }).catch(function (e) { + return next(e); + }); +} + +/** + * Get user + * @returns {User} + */ +function get(req, res) { + return res.json(req.user); +} + +/** + * Create new user + * @property {string} req.body.username - The username of user. + * @property {string} req.body.mobileNumber - The mobileNumber of user. + * @returns {User} + */ +function create(req, res, next) { + var user = new _user2.default({ + username: req.body.username, + mobileNumber: req.body.mobileNumber + }); + + user.save().then(function (savedUser) { + return res.json(savedUser); + }).catch(function (e) { + return next(e); + }); +} + +/** + * Update existing user + * @property {string} req.body.username - The username of user. + * @property {string} req.body.mobileNumber - The mobileNumber of user. + * @returns {User} + */ +function update(req, res, next) { + var user = req.user; + user.username = req.body.username; + user.mobileNumber = req.body.mobileNumber; + + user.save().then(function (savedUser) { + return res.json(savedUser); + }).catch(function (e) { + return next(e); + }); +} + +/** + * Get user list. + * @property {number} req.query.skip - Number of users to be skipped. + * @property {number} req.query.limit - Limit number of users to be returned. + * @returns {User[]} + */ +function list(req, res, next) { + var _req$query = req.query, + _req$query$limit = _req$query.limit, + limit = _req$query$limit === undefined ? 50 : _req$query$limit, + _req$query$skip = _req$query.skip, + skip = _req$query$skip === undefined ? 0 : _req$query$skip; + + _user2.default.list({ limit: limit, skip: skip }).then(function (users) { + return res.json(users); + }).catch(function (e) { + return next(e); + }); +} + +/** + * Delete user. + * @returns {User} + */ +function remove(req, res, next) { + var user = req.user; + user.remove().then(function (deletedUser) { + return res.json(deletedUser); + }).catch(function (e) { + return next(e); + }); +} + +exports.default = { load: load, get: get, create: create, update: update, list: list, remove: remove }; +module.exports = exports['default']; +//# sourceMappingURL=user.controller.js.map diff --git a/dist/server/controllers/user.controller.js.map b/dist/server/controllers/user.controller.js.map new file mode 100644 index 00000000..d811ba8e --- /dev/null +++ b/dist/server/controllers/user.controller.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/controllers/user.controller.js"],"names":["load","req","res","next","id","get","then","user","catch","e","json","create","username","body","mobileNumber","save","savedUser","update","list","query","limit","skip","users","remove","deletedUser"],"mappings":";;;;;;AAAA;;;;;;AAEA;;;AAGA,SAASA,IAAT,CAAcC,GAAd,EAAmBC,GAAnB,EAAwBC,IAAxB,EAA8BC,EAA9B,EAAkC;AAChC,iBAAKC,GAAL,CAASD,EAAT,EACGE,IADH,CACQ,UAACC,IAAD,EAAU;AACdN,QAAIM,IAAJ,GAAWA,IAAX,CADc,CACG;AACjB,WAAOJ,MAAP;AACD,GAJH,EAKGK,KALH,CAKS;AAAA,WAAKL,KAAKM,CAAL,CAAL;AAAA,GALT;AAMD;;AAED;;;;AAIA,SAASJ,GAAT,CAAaJ,GAAb,EAAkBC,GAAlB,EAAuB;AACrB,SAAOA,IAAIQ,IAAJ,CAAST,IAAIM,IAAb,CAAP;AACD;;AAED;;;;;;AAMA,SAASI,MAAT,CAAgBV,GAAhB,EAAqBC,GAArB,EAA0BC,IAA1B,EAAgC;AAC9B,MAAMI,OAAO,mBAAS;AACpBK,cAAUX,IAAIY,IAAJ,CAASD,QADC;AAEpBE,kBAAcb,IAAIY,IAAJ,CAASC;AAFH,GAAT,CAAb;;AAKAP,OAAKQ,IAAL,GACGT,IADH,CACQ;AAAA,WAAaJ,IAAIQ,IAAJ,CAASM,SAAT,CAAb;AAAA,GADR,EAEGR,KAFH,CAES;AAAA,WAAKL,KAAKM,CAAL,CAAL;AAAA,GAFT;AAGD;;AAED;;;;;;AAMA,SAASQ,MAAT,CAAgBhB,GAAhB,EAAqBC,GAArB,EAA0BC,IAA1B,EAAgC;AAC9B,MAAMI,OAAON,IAAIM,IAAjB;AACAA,OAAKK,QAAL,GAAgBX,IAAIY,IAAJ,CAASD,QAAzB;AACAL,OAAKO,YAAL,GAAoBb,IAAIY,IAAJ,CAASC,YAA7B;;AAEAP,OAAKQ,IAAL,GACGT,IADH,CACQ;AAAA,WAAaJ,IAAIQ,IAAJ,CAASM,SAAT,CAAb;AAAA,GADR,EAEGR,KAFH,CAES;AAAA,WAAKL,KAAKM,CAAL,CAAL;AAAA,GAFT;AAGD;;AAED;;;;;;AAMA,SAASS,IAAT,CAAcjB,GAAd,EAAmBC,GAAnB,EAAwBC,IAAxB,EAA8B;AAAA,mBACKF,IAAIkB,KADT;AAAA,oCACpBC,KADoB;AAAA,MACpBA,KADoB,oCACZ,EADY;AAAA,mCACRC,IADQ;AAAA,MACRA,IADQ,mCACD,CADC;;AAE5B,iBAAKH,IAAL,CAAU,EAAEE,YAAF,EAASC,UAAT,EAAV,EACGf,IADH,CACQ;AAAA,WAASJ,IAAIQ,IAAJ,CAASY,KAAT,CAAT;AAAA,GADR,EAEGd,KAFH,CAES;AAAA,WAAKL,KAAKM,CAAL,CAAL;AAAA,GAFT;AAGD;;AAED;;;;AAIA,SAASc,MAAT,CAAgBtB,GAAhB,EAAqBC,GAArB,EAA0BC,IAA1B,EAAgC;AAC9B,MAAMI,OAAON,IAAIM,IAAjB;AACAA,OAAKgB,MAAL,GACGjB,IADH,CACQ;AAAA,WAAeJ,IAAIQ,IAAJ,CAASc,WAAT,CAAf;AAAA,GADR,EAEGhB,KAFH,CAES;AAAA,WAAKL,KAAKM,CAAL,CAAL;AAAA,GAFT;AAGD;;kBAEc,EAAET,UAAF,EAAQK,QAAR,EAAaM,cAAb,EAAqBM,cAArB,EAA6BC,UAA7B,EAAmCK,cAAnC,E","file":"user.controller.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/helpers/APIError.js b/dist/server/helpers/APIError.js new file mode 100644 index 00000000..4fb70440 --- /dev/null +++ b/dist/server/helpers/APIError.js @@ -0,0 +1,71 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * @extends Error + */ +var ExtendableError = function (_Error) { + _inherits(ExtendableError, _Error); + + function ExtendableError(message, status, isPublic) { + _classCallCheck(this, ExtendableError); + + var _this = _possibleConstructorReturn(this, (ExtendableError.__proto__ || Object.getPrototypeOf(ExtendableError)).call(this, message)); + + _this.name = _this.constructor.name; + _this.message = message; + _this.status = status; + _this.isPublic = isPublic; + _this.isOperational = true; // This is required since bluebird 4 doesn't append it anymore. + Error.captureStackTrace(_this, _this.constructor.name); + return _this; + } + + return ExtendableError; +}(Error); + +/** + * Class representing an API error. + * @extends ExtendableError + */ + + +var APIError = function (_ExtendableError) { + _inherits(APIError, _ExtendableError); + + /** + * Creates an API error. + * @param {string} message - Error message. + * @param {number} status - HTTP status code of error. + * @param {boolean} isPublic - Whether the message should be visible to user or not. + */ + function APIError(message) { + var status = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _httpStatus2.default.INTERNAL_SERVER_ERROR; + var isPublic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + _classCallCheck(this, APIError); + + return _possibleConstructorReturn(this, (APIError.__proto__ || Object.getPrototypeOf(APIError)).call(this, message, status, isPublic)); + } + + return APIError; +}(ExtendableError); + +exports.default = APIError; +module.exports = exports['default']; +//# sourceMappingURL=APIError.js.map diff --git a/dist/server/helpers/APIError.js.map b/dist/server/helpers/APIError.js.map new file mode 100644 index 00000000..e7b7f1a2 --- /dev/null +++ b/dist/server/helpers/APIError.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/helpers/APIError.js"],"names":["ExtendableError","message","status","isPublic","name","constructor","isOperational","Error","captureStackTrace","APIError","INTERNAL_SERVER_ERROR"],"mappings":";;;;;;AAAA;;;;;;;;;;;;AAEA;;;IAGMA,e;;;AACJ,2BAAYC,OAAZ,EAAqBC,MAArB,EAA6BC,QAA7B,EAAuC;AAAA;;AAAA,kIAC/BF,OAD+B;;AAErC,UAAKG,IAAL,GAAY,MAAKC,WAAL,CAAiBD,IAA7B;AACA,UAAKH,OAAL,GAAeA,OAAf;AACA,UAAKC,MAAL,GAAcA,MAAd;AACA,UAAKC,QAAL,GAAgBA,QAAhB;AACA,UAAKG,aAAL,GAAqB,IAArB,CANqC,CAMV;AAC3BC,UAAMC,iBAAN,QAA8B,MAAKH,WAAL,CAAiBD,IAA/C;AAPqC;AAQtC;;;EAT2BG,K;;AAY9B;;;;;;IAIME,Q;;;AACJ;;;;;;AAMA,oBAAYR,OAAZ,EAAkF;AAAA,QAA7DC,MAA6D,uEAApD,qBAAWQ,qBAAyC;AAAA,QAAlBP,QAAkB,uEAAP,KAAO;;AAAA;;AAAA,+GAC1EF,OAD0E,EACjEC,MADiE,EACzDC,QADyD;AAEjF;;;EAToBH,e;;kBAYRS,Q","file":"APIError.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/models/user.model.js b/dist/server/models/user.model.js new file mode 100644 index 00000000..e784d537 --- /dev/null +++ b/dist/server/models/user.model.js @@ -0,0 +1,98 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _bluebird = require('bluebird'); + +var _bluebird2 = _interopRequireDefault(_bluebird); + +var _mongoose = require('mongoose'); + +var _mongoose2 = _interopRequireDefault(_mongoose); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _APIError = require('../helpers/APIError'); + +var _APIError2 = _interopRequireDefault(_APIError); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * User Schema + */ +var UserSchema = new _mongoose2.default.Schema({ + username: { + type: String, + required: true + }, + mobileNumber: { + type: String, + required: true, + match: [/^[1-9][0-9]{9}$/, 'The value of path {PATH} ({VALUE}) is not a valid mobile number.'] + }, + createdAt: { + type: Date, + default: Date.now + } +}); + +/** + * Add your + * - pre-save hooks + * - validations + * - virtuals + */ + +/** + * Methods + */ +UserSchema.method({}); + +/** + * Statics + */ +UserSchema.statics = { + /** + * Get user + * @param {ObjectId} id - The objectId of user. + * @returns {Promise} + */ + get: function get(id) { + return this.findById(id).exec().then(function (user) { + if (user) { + return user; + } + var err = new _APIError2.default('No such user exists!', _httpStatus2.default.NOT_FOUND); + return _bluebird2.default.reject(err); + }); + }, + + + /** + * List users in descending order of 'createdAt' timestamp. + * @param {number} skip - Number of users to be skipped. + * @param {number} limit - Limit number of users to be returned. + * @returns {Promise} + */ + list: function list() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref$skip = _ref.skip, + skip = _ref$skip === undefined ? 0 : _ref$skip, + _ref$limit = _ref.limit, + limit = _ref$limit === undefined ? 50 : _ref$limit; + + return this.find().sort({ createdAt: -1 }).skip(+skip).limit(+limit).exec(); + } +}; + +/** + * @typedef User + */ +exports.default = _mongoose2.default.model('User', UserSchema); +module.exports = exports['default']; +//# sourceMappingURL=user.model.js.map diff --git a/dist/server/models/user.model.js.map b/dist/server/models/user.model.js.map new file mode 100644 index 00000000..5861971d --- /dev/null +++ b/dist/server/models/user.model.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/models/user.model.js"],"names":["UserSchema","Schema","username","type","String","required","mobileNumber","match","createdAt","Date","default","now","method","statics","get","id","findById","exec","then","user","err","NOT_FOUND","reject","list","skip","limit","find","sort","model"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA;;;AAGA,IAAMA,aAAa,IAAI,mBAASC,MAAb,CAAoB;AACrCC,YAAU;AACRC,UAAMC,MADE;AAERC,cAAU;AAFF,GAD2B;AAKrCC,gBAAc;AACZH,UAAMC,MADM;AAEZC,cAAU,IAFE;AAGZE,WAAO,CAAC,iBAAD,EAAoB,kEAApB;AAHK,GALuB;AAUrCC,aAAW;AACTL,UAAMM,IADG;AAETC,aAASD,KAAKE;AAFL;AAV0B,CAApB,CAAnB;;AAgBA;;;;;;;AAOA;;;AAGAX,WAAWY,MAAX,CAAkB,EAAlB;;AAGA;;;AAGAZ,WAAWa,OAAX,GAAqB;AACnB;;;;;AAKAC,KANmB,eAMfC,EANe,EAMX;AACN,WAAO,KAAKC,QAAL,CAAcD,EAAd,EACJE,IADI,GAEJC,IAFI,CAEC,UAACC,IAAD,EAAU;AACd,UAAIA,IAAJ,EAAU;AACR,eAAOA,IAAP;AACD;AACD,UAAMC,MAAM,uBAAa,sBAAb,EAAqC,qBAAWC,SAAhD,CAAZ;AACA,aAAO,mBAAQC,MAAR,CAAeF,GAAf,CAAP;AACD,KARI,CAAP;AASD,GAhBkB;;;AAkBnB;;;;;;AAMAG,MAxBmB,kBAwBiB;AAAA,mFAAJ,EAAI;AAAA,yBAA7BC,IAA6B;AAAA,QAA7BA,IAA6B,6BAAtB,CAAsB;AAAA,0BAAnBC,KAAmB;AAAA,QAAnBA,KAAmB,8BAAX,EAAW;;AAClC,WAAO,KAAKC,IAAL,GACJC,IADI,CACC,EAAEnB,WAAW,CAAC,CAAd,EADD,EAEJgB,IAFI,CAEC,CAACA,IAFF,EAGJC,KAHI,CAGE,CAACA,KAHH,EAIJR,IAJI,EAAP;AAKD;AA9BkB,CAArB;;AAiCA;;;kBAGe,mBAASW,KAAT,CAAe,MAAf,EAAuB5B,UAAvB,C","file":"user.model.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/routes/auth.route.js b/dist/server/routes/auth.route.js new file mode 100644 index 00000000..7b943710 --- /dev/null +++ b/dist/server/routes/auth.route.js @@ -0,0 +1,44 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _express = require('express'); + +var _express2 = _interopRequireDefault(_express); + +var _expressValidation = require('express-validation'); + +var _expressValidation2 = _interopRequireDefault(_expressValidation); + +var _expressJwt = require('express-jwt'); + +var _expressJwt2 = _interopRequireDefault(_expressJwt); + +var _paramValidation = require('../../config/param-validation'); + +var _paramValidation2 = _interopRequireDefault(_paramValidation); + +var _auth = require('../controllers/auth.controller'); + +var _auth2 = _interopRequireDefault(_auth); + +var _config = require('../../config/config'); + +var _config2 = _interopRequireDefault(_config); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var router = _express2.default.Router(); // eslint-disable-line new-cap + +/** POST /api/auth/login - Returns token if correct username and password is provided */ +router.route('/login').post((0, _expressValidation2.default)(_paramValidation2.default.login), _auth2.default.login); + +/** GET /api/auth/random-number - Protected route, + * needs token returned by the above as header. Authorization: Bearer {token} */ +router.route('/random-number').get((0, _expressJwt2.default)({ secret: _config2.default.jwtSecret }), _auth2.default.getRandomNumber); + +exports.default = router; +module.exports = exports['default']; +//# sourceMappingURL=auth.route.js.map diff --git a/dist/server/routes/auth.route.js.map b/dist/server/routes/auth.route.js.map new file mode 100644 index 00000000..7495516a --- /dev/null +++ b/dist/server/routes/auth.route.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/routes/auth.route.js"],"names":["router","Router","route","post","login","get","secret","jwtSecret","getRandomNumber"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAMA,SAAS,kBAAQC,MAAR,EAAf,C,CAAiC;;AAEjC;AACAD,OAAOE,KAAP,CAAa,QAAb,EACGC,IADH,CACQ,iCAAS,0BAAgBC,KAAzB,CADR,EACyC,eAASA,KADlD;;AAGA;;AAEAJ,OAAOE,KAAP,CAAa,gBAAb,EACGG,GADH,CACO,0BAAW,EAAEC,QAAQ,iBAAOC,SAAjB,EAAX,CADP,EACiD,eAASC,eAD1D;;kBAGeR,M","file":"auth.route.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/routes/index.route.js b/dist/server/routes/index.route.js new file mode 100644 index 00000000..e1eb254b --- /dev/null +++ b/dist/server/routes/index.route.js @@ -0,0 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _express = require('express'); + +var _express2 = _interopRequireDefault(_express); + +var _user = require('./user.route'); + +var _user2 = _interopRequireDefault(_user); + +var _auth = require('./auth.route'); + +var _auth2 = _interopRequireDefault(_auth); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var router = _express2.default.Router(); // eslint-disable-line new-cap + +/** GET /health-check - Check service health */ +router.get('/health-check', function (req, res) { + return res.send('OK'); +}); + +// mount user routes at /users +router.use('/users', _user2.default); + +// mount auth routes at /auth +router.use('/auth', _auth2.default); + +exports.default = router; +module.exports = exports['default']; +//# sourceMappingURL=index.route.js.map diff --git a/dist/server/routes/index.route.js.map b/dist/server/routes/index.route.js.map new file mode 100644 index 00000000..db77c779 --- /dev/null +++ b/dist/server/routes/index.route.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/routes/index.route.js"],"names":["router","Router","get","req","res","send","use"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;;;AAEA,IAAMA,SAAS,kBAAQC,MAAR,EAAf,C,CAAiC;;AAEjC;AACAD,OAAOE,GAAP,CAAW,eAAX,EAA4B,UAACC,GAAD,EAAMC,GAAN;AAAA,SAC1BA,IAAIC,IAAJ,CAAS,IAAT,CAD0B;AAAA,CAA5B;;AAIA;AACAL,OAAOM,GAAP,CAAW,QAAX;;AAEA;AACAN,OAAOM,GAAP,CAAW,OAAX;;kBAEeN,M","file":"index.route.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/routes/user.route.js b/dist/server/routes/user.route.js new file mode 100644 index 00000000..532afb24 --- /dev/null +++ b/dist/server/routes/user.route.js @@ -0,0 +1,49 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _express = require('express'); + +var _express2 = _interopRequireDefault(_express); + +var _expressValidation = require('express-validation'); + +var _expressValidation2 = _interopRequireDefault(_expressValidation); + +var _paramValidation = require('../../config/param-validation'); + +var _paramValidation2 = _interopRequireDefault(_paramValidation); + +var _user = require('../controllers/user.controller'); + +var _user2 = _interopRequireDefault(_user); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var router = _express2.default.Router(); // eslint-disable-line new-cap + +router.route('/') +/** GET /api/users - Get list of users */ +.get(_user2.default.list) + +/** POST /api/users - Create new user */ +.post((0, _expressValidation2.default)(_paramValidation2.default.createUser), _user2.default.create); + +router.route('/:userId') +/** GET /api/users/:userId - Get user */ +.get(_user2.default.get) + +/** PUT /api/users/:userId - Update user */ +.put((0, _expressValidation2.default)(_paramValidation2.default.updateUser), _user2.default.update) + +/** DELETE /api/users/:userId - Delete user */ +.delete(_user2.default.remove); + +/** Load user when API with userId route parameter is hit */ +router.param('userId', _user2.default.load); + +exports.default = router; +module.exports = exports['default']; +//# sourceMappingURL=user.route.js.map diff --git a/dist/server/routes/user.route.js.map b/dist/server/routes/user.route.js.map new file mode 100644 index 00000000..6b8b3e19 --- /dev/null +++ b/dist/server/routes/user.route.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/routes/user.route.js"],"names":["router","Router","route","get","list","post","createUser","create","put","updateUser","update","delete","remove","param","load"],"mappings":";;;;;;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,IAAMA,SAAS,kBAAQC,MAAR,EAAf,C,CAAiC;;AAEjCD,OAAOE,KAAP,CAAa,GAAb;AACE;AADF,CAEGC,GAFH,CAEO,eAASC,IAFhB;;AAIE;AAJF,CAKGC,IALH,CAKQ,iCAAS,0BAAgBC,UAAzB,CALR,EAK8C,eAASC,MALvD;;AAOAP,OAAOE,KAAP,CAAa,UAAb;AACE;AADF,CAEGC,GAFH,CAEO,eAASA,GAFhB;;AAIE;AAJF,CAKGK,GALH,CAKO,iCAAS,0BAAgBC,UAAzB,CALP,EAK6C,eAASC,MALtD;;AAOE;AAPF,CAQGC,MARH,CAQU,eAASC,MARnB;;AAUA;AACAZ,OAAOa,KAAP,CAAa,QAAb,EAAuB,eAASC,IAAhC;;kBAEed,M","file":"user.route.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/tests/auth.test.js b/dist/server/tests/auth.test.js new file mode 100644 index 00000000..37f0a41b --- /dev/null +++ b/dist/server/tests/auth.test.js @@ -0,0 +1,88 @@ +'use strict'; + +var _supertestAsPromised = require('supertest-as-promised'); + +var _supertestAsPromised2 = _interopRequireDefault(_supertestAsPromised); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _jsonwebtoken = require('jsonwebtoken'); + +var _jsonwebtoken2 = _interopRequireDefault(_jsonwebtoken); + +var _chai = require('chai'); + +var _chai2 = _interopRequireDefault(_chai); + +var _index = require('../../index'); + +var _index2 = _interopRequireDefault(_index); + +var _config = require('../../config/config'); + +var _config2 = _interopRequireDefault(_config); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_chai2.default.config.includeStack = true; + +describe('## Auth APIs', function () { + var validUserCredentials = { + username: 'react', + password: 'express' + }; + + var invalidUserCredentials = { + username: 'react', + password: 'IDontKnow' + }; + + var jwtToken = void 0; + + describe('# POST /api/auth/login', function () { + it('should return Authentication error', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).post('/api/auth/login').send(invalidUserCredentials).expect(_httpStatus2.default.UNAUTHORIZED).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Authentication error'); + done(); + }).catch(done); + }); + + it('should get valid JWT token', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).post('/api/auth/login').send(validUserCredentials).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body).to.have.property('token'); + _jsonwebtoken2.default.verify(res.body.token, _config2.default.jwtSecret, function (err, decoded) { + (0, _chai.expect)(err).to.not.be.ok; // eslint-disable-line no-unused-expressions + (0, _chai.expect)(decoded.username).to.equal(validUserCredentials.username); + jwtToken = 'Bearer ' + res.body.token; + done(); + }); + }).catch(done); + }); + }); + + describe('# GET /api/auth/random-number', function () { + it('should fail to get random number because of missing Authorization', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/auth/random-number').expect(_httpStatus2.default.UNAUTHORIZED).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Unauthorized'); + done(); + }).catch(done); + }); + + it('should fail to get random number because of wrong token', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/auth/random-number').set('Authorization', 'Bearer inValidToken').expect(_httpStatus2.default.UNAUTHORIZED).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Unauthorized'); + done(); + }).catch(done); + }); + + it('should get a random number', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/auth/random-number').set('Authorization', jwtToken).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body.num).to.be.a('number'); + done(); + }).catch(done); + }); + }); +}); +//# sourceMappingURL=auth.test.js.map diff --git a/dist/server/tests/auth.test.js.map b/dist/server/tests/auth.test.js.map new file mode 100644 index 00000000..ab7b5a06 --- /dev/null +++ b/dist/server/tests/auth.test.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/tests/auth.test.js"],"names":["config","includeStack","describe","validUserCredentials","username","password","invalidUserCredentials","jwtToken","it","done","post","send","expect","UNAUTHORIZED","then","res","body","message","to","equal","catch","OK","have","property","verify","token","jwtSecret","err","decoded","not","be","ok","get","set","num","a"],"mappings":"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","file":"auth.test.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/tests/misc.test.js b/dist/server/tests/misc.test.js new file mode 100644 index 00000000..2917e932 --- /dev/null +++ b/dist/server/tests/misc.test.js @@ -0,0 +1,60 @@ +'use strict'; + +var _supertestAsPromised = require('supertest-as-promised'); + +var _supertestAsPromised2 = _interopRequireDefault(_supertestAsPromised); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _chai = require('chai'); + +var _chai2 = _interopRequireDefault(_chai); + +var _index = require('../../index'); + +var _index2 = _interopRequireDefault(_index); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_chai2.default.config.includeStack = true; + +describe('## Misc', function () { + describe('# GET /api/health-check', function () { + it('should return OK', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/health-check').expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.text).to.equal('OK'); + done(); + }).catch(done); + }); + }); + + describe('# GET /api/404', function () { + it('should return 404 status', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/404').expect(_httpStatus2.default.NOT_FOUND).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Not Found'); + done(); + }).catch(done); + }); + }); + + describe('# Error Handling', function () { + it('should handle mongoose CastError - Cast to ObjectId failed', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/users/56z787zzz67fc').expect(_httpStatus2.default.INTERNAL_SERVER_ERROR).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Internal Server Error'); + done(); + }).catch(done); + }); + + it('should handle express validation error - username is required', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).post('/api/users').send({ + mobileNumber: '1234567890' + }).expect(_httpStatus2.default.BAD_REQUEST).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('"username" is required'); + done(); + }).catch(done); + }); + }); +}); +//# sourceMappingURL=misc.test.js.map diff --git a/dist/server/tests/misc.test.js.map b/dist/server/tests/misc.test.js.map new file mode 100644 index 00000000..fe04c02a --- /dev/null +++ b/dist/server/tests/misc.test.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/tests/misc.test.js"],"names":["config","includeStack","describe","it","done","get","expect","OK","then","res","text","to","equal","catch","NOT_FOUND","body","message","INTERNAL_SERVER_ERROR","post","send","mobileNumber","BAD_REQUEST"],"mappings":";;AAAA;;;;AACA;;;;AACA;;;;AACA;;;;;;AAEA,eAAKA,MAAL,CAAYC,YAAZ,GAA2B,IAA3B;;AAEAC,SAAS,SAAT,EAAoB,YAAM;AACxBA,WAAS,yBAAT,EAAoC,YAAM;AACxCC,OAAG,kBAAH,EAAuB,UAACC,IAAD,EAAU;AAC/B,0DACGC,GADH,CACO,mBADP,EAEGC,MAFH,CAEU,qBAAWC,EAFrB,EAGGC,IAHH,CAGQ,UAACC,GAAD,EAAS;AACb,0BAAOA,IAAIC,IAAX,EAAiBC,EAAjB,CAAoBC,KAApB,CAA0B,IAA1B;AACAR;AACD,OANH,EAOGS,KAPH,CAOST,IAPT;AAQD,KATD;AAUD,GAXD;;AAaAF,WAAS,gBAAT,EAA2B,YAAM;AAC/BC,OAAG,0BAAH,EAA+B,UAACC,IAAD,EAAU;AACvC,0DACGC,GADH,CACO,UADP,EAEGC,MAFH,CAEU,qBAAWQ,SAFrB,EAGGN,IAHH,CAGQ,UAACC,GAAD,EAAS;AACb,0BAAOA,IAAIM,IAAJ,CAASC,OAAhB,EAAyBL,EAAzB,CAA4BC,KAA5B,CAAkC,WAAlC;AACAR;AACD,OANH,EAOGS,KAPH,CAOST,IAPT;AAQD,KATD;AAUD,GAXD;;AAaAF,WAAS,kBAAT,EAA6B,YAAM;AACjCC,OAAG,4DAAH,EAAiE,UAACC,IAAD,EAAU;AACzE,0DACGC,GADH,CACO,0BADP,EAEGC,MAFH,CAEU,qBAAWW,qBAFrB,EAGGT,IAHH,CAGQ,UAACC,GAAD,EAAS;AACb,0BAAOA,IAAIM,IAAJ,CAASC,OAAhB,EAAyBL,EAAzB,CAA4BC,KAA5B,CAAkC,uBAAlC;AACAR;AACD,OANH,EAOGS,KAPH,CAOST,IAPT;AAQD,KATD;;AAWAD,OAAG,+DAAH,EAAoE,UAACC,IAAD,EAAU;AAC5E,0DACGc,IADH,CACQ,YADR,EAEGC,IAFH,CAEQ;AACJC,sBAAc;AADV,OAFR,EAKGd,MALH,CAKU,qBAAWe,WALrB,EAMGb,IANH,CAMQ,UAACC,GAAD,EAAS;AACb,0BAAOA,IAAIM,IAAJ,CAASC,OAAhB,EAAyBL,EAAzB,CAA4BC,KAA5B,CAAkC,wBAAlC;AACAR;AACD,OATH,EAUGS,KAVH,CAUST,IAVT;AAWD,KAZD;AAaD,GAzBD;AA0BD,CArDD","file":"misc.test.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/dist/server/tests/user.test.js b/dist/server/tests/user.test.js new file mode 100644 index 00000000..8c7eac1f --- /dev/null +++ b/dist/server/tests/user.test.js @@ -0,0 +1,109 @@ +'use strict'; + +var _mongoose = require('mongoose'); + +var _mongoose2 = _interopRequireDefault(_mongoose); + +var _supertestAsPromised = require('supertest-as-promised'); + +var _supertestAsPromised2 = _interopRequireDefault(_supertestAsPromised); + +var _httpStatus = require('http-status'); + +var _httpStatus2 = _interopRequireDefault(_httpStatus); + +var _chai = require('chai'); + +var _chai2 = _interopRequireDefault(_chai); + +var _index = require('../../index'); + +var _index2 = _interopRequireDefault(_index); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +_chai2.default.config.includeStack = true; + +/** + * root level hooks + */ +after(function (done) { + // required because https://github.com/Automattic/mongoose/issues/1251#issuecomment-65793092 + _mongoose2.default.models = {}; + _mongoose2.default.modelSchemas = {}; + _mongoose2.default.connection.close(); + done(); +}); + +describe('## User APIs', function () { + var user = { + username: 'KK123', + mobileNumber: '1234567890' + }; + + describe('# POST /api/users', function () { + it('should create a new user', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).post('/api/users').send(user).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body.username).to.equal(user.username); + (0, _chai.expect)(res.body.mobileNumber).to.equal(user.mobileNumber); + user = res.body; + done(); + }).catch(done); + }); + }); + + describe('# GET /api/users/:userId', function () { + it('should get user details', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/users/' + user._id).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body.username).to.equal(user.username); + (0, _chai.expect)(res.body.mobileNumber).to.equal(user.mobileNumber); + done(); + }).catch(done); + }); + + it('should report error with message - Not found, when user does not exists', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/users/56c787ccc67fc16ccc1a5e92').expect(_httpStatus2.default.NOT_FOUND).then(function (res) { + (0, _chai.expect)(res.body.message).to.equal('Not Found'); + done(); + }).catch(done); + }); + }); + + describe('# PUT /api/users/:userId', function () { + it('should update user details', function (done) { + user.username = 'KK'; + (0, _supertestAsPromised2.default)(_index2.default).put('/api/users/' + user._id).send(user).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body.username).to.equal('KK'); + (0, _chai.expect)(res.body.mobileNumber).to.equal(user.mobileNumber); + done(); + }).catch(done); + }); + }); + + describe('# GET /api/users/', function () { + it('should get all users', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/users').expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body).to.be.an('array'); + done(); + }).catch(done); + }); + + it('should get all users (with limit and skip)', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).get('/api/users').query({ limit: 10, skip: 1 }).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body).to.be.an('array'); + done(); + }).catch(done); + }); + }); + + describe('# DELETE /api/users/', function () { + it('should delete user', function (done) { + (0, _supertestAsPromised2.default)(_index2.default).delete('/api/users/' + user._id).expect(_httpStatus2.default.OK).then(function (res) { + (0, _chai.expect)(res.body.username).to.equal('KK'); + (0, _chai.expect)(res.body.mobileNumber).to.equal(user.mobileNumber); + done(); + }).catch(done); + }); + }); +}); +//# sourceMappingURL=user.test.js.map diff --git a/dist/server/tests/user.test.js.map b/dist/server/tests/user.test.js.map new file mode 100644 index 00000000..89438cf6 --- /dev/null +++ b/dist/server/tests/user.test.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["server/tests/user.test.js"],"names":["config","includeStack","after","done","models","modelSchemas","connection","close","describe","user","username","mobileNumber","it","post","send","expect","OK","then","res","body","to","equal","catch","get","_id","NOT_FOUND","message","put","be","an","query","limit","skip","delete"],"mappings":"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","file":"user.test.js","sourceRoot":"../../../../.."} \ No newline at end of file diff --git a/package.json b/package.json index 6b62af49..5a30115f 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "test:watch": "npm test -- --watch", "test:coverage": "cross-env NODE_ENV=test ./node_modules/.bin/istanbul cover _mocha -- --ui bdd --reporter spec --colors --compilers js:babel-core/register server/tests --recursive", "test:check-coverage": "npm test:coverage && istanbul check-coverage", - "report-coverage": "coveralls < ./coverage/lcov.info" + "report-coverage": "coveralls < ./coverage/lcov.info", + "travis-script": "npm run lint && npm test && npm run build" }, "repository": { "type": "git", diff --git a/travis.sh b/travis.sh index e31e75f9..dd85215a 100644 --- a/travis.sh +++ b/travis.sh @@ -1,9 +1,13 @@ -#git remote add upstream "https://$GH_TOKEN@github.com/rust-lang/rust-by-example.git" -# git remote add upstream "https://github.com/surabhi226005/express-mongoose-es6-rest-api.git" -# echo "Remote branch added" -# git fetch -# echo "Remote fetched" -# git branch --track develop origin/develop -# git branch -git checkout develop -git pull +#!/bin/bash +if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then + cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec --colors --compilers js:babel-core/register server/tests --recursive + npm run build + git add dist/ + git checkout -b release + git commit -m "Dist" + git push heroku release:master +fi +if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then + cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec --colors --compilers js:babel-core/register server/tests --recursive + npm run build +fi