diff --git a/dustin/.eslintignore b/dustin/.eslintignore new file mode 100644 index 0000000..5b88cef --- /dev/null +++ b/dustin/.eslintignore @@ -0,0 +1,5 @@ +**/node_modules/* +**/vendor/* +**/*.min.js +/*.md +/package.json diff --git a/dustin/.eslintrc b/dustin/.eslintrc new file mode 100644 index 0000000..6d505ad --- /dev/null +++ b/dustin/.eslintrc @@ -0,0 +1,41 @@ +{ +"rules": { +"no-console": 0, +"indent": [ +2, +2 +], +"quotes": [ +2, +"single" +], +"linebreak-style": [ +2, +"unix" +], +"semi": [ +2, +"always" +] +}, +"env": { +"es6": true, +"node": true, +"browser": true, +"mocha": true +}, +"globals": { +"describe": false, +"it": false, +"beforeEach": false, +"afterEach": false, +"before": false, +"after": false +}, +"ecmaFeatures": { +"modules": true, +"experimentalObjectRestSpread": true, +"impliedStrict": true +}, +"extends": "eslint:recommended" +} diff --git a/dustin/.gitignore b/dustin/.gitignore new file mode 100644 index 0000000..4c497d6 --- /dev/null +++ b/dustin/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/db diff --git a/dustin/.travis.yml b/dustin/.travis.yml new file mode 100644 index 0000000..dc8091e --- /dev/null +++ b/dustin/.travis.yml @@ -0,0 +1,16 @@ +language: node_js +node_js: + - 4 +services: + - mongodb +addons: + apt: + sources: + - mongodb-3.2.4-precise + packages: + - mongodb-org-server +sudo: required +before_script: npm install +script: + - npm run test + - npm run lint diff --git a/dustin/gulpfile.js b/dustin/gulpfile.js new file mode 100644 index 0000000..713267f --- /dev/null +++ b/dustin/gulpfile.js @@ -0,0 +1,24 @@ +const gulp = require('gulp'); +const mocha = require('gulp-mocha'); +const lint = require('gulp-eslint'); + +//var js = ['./model/**/*.js', './lib/**/*.js', './routes/**/*.js', './test/**/*.js', './*.js' ] + +gulp.task('linter' , () => { + return gulp.src(['./*.js', './test/*.js', './lib/*.js']) + .pipe(lint()) + .pipe(lint.format()); +}); + +gulp.task('tests', () => { + return gulp.src(['./*.js', './test/*.js', './lib/*.js'], {read: false}) + .pipe(mocha({reporter: 'nyan'})); +}); + +gulp.task('watch', () => { + gulp.watch(['./*.js', './test/*.js', './lib/*.js', './model/**/*.js'], ['linter', 'tests']); +}); + +gulp.task('default', ['linter', 'tests', 'watch'], () => { + +}); diff --git a/dustin/lib/basic_auth.js b/dustin/lib/basic_auth.js new file mode 100644 index 0000000..b2bb8f8 --- /dev/null +++ b/dustin/lib/basic_auth.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = function(req, res, next) { + + let authBuff = new Buffer(req.headers.authorization.split(' ').pop(), 'base64'); + let authArray = authBuff.toString().split(':'); + authBuff.fill(0); + + req.auth = { + username: authArray[0], + password: authArray[1] + }; + + if(!req.auth.username || !req.auth.password) { + return next(new Error('Username or Password missing')); + } + + next(); +}; diff --git a/dustin/lib/errorhandler.js b/dustin/lib/errorhandler.js new file mode 100644 index 0000000..9256fc5 --- /dev/null +++ b/dustin/lib/errorhandler.js @@ -0,0 +1,6 @@ +module.exports = function (err, req, res, next) { + res.status(500).json({ + message: err.message + }); + next(); +}; diff --git a/dustin/lib/jwt_auth.js b/dustin/lib/jwt_auth.js new file mode 100644 index 0000000..2234fe9 --- /dev/null +++ b/dustin/lib/jwt_auth.js @@ -0,0 +1,27 @@ +'use strict'; +var jwt = require('jsonwebtoken'); +var User = require('../model/user'); +const secret = process.env.SECRET || 'changeme'; + +module.exports = function (req, res, next) { + let token = req.headers.token || req.headers.token; + let tokenErr = new Error('Authorization Failure'); + let decodedToken; + + if (!token) return next(tokenErr); + + try { + decodedToken = jwt.verify(token, secret); + } catch (e) { + return next(e); + } + + User.findOne({ + _id: decodedToken._id + }, (err, user) => { + if (!user || err) return next(err); + req.user = user; + next(); + }); + +}; diff --git a/dustin/model/company.js b/dustin/model/company.js new file mode 100644 index 0000000..b66f2a2 --- /dev/null +++ b/dustin/model/company.js @@ -0,0 +1,23 @@ + 'use strict'; + const mongoose = require('mongoose'); + + const Company = new mongoose.Schema({ + name: String, + tvDealReached: Boolean, + seekAmount: Number, + seekEquity: Number, + seekValuation: Number, + tvDealAmount: Number, + tvDealEquity: Number, + tvDealValuation: Number, + actualDealReached: Boolean, + actualDealAmount: Number, + actualDealEquity: Number, + actualDealValuation: Number, + season: Number, + episode: Number + //sharks: Schema.Types.sharks; + //{type: Number, default: 0} + }); + + module.exports = mongoose.model('companies', Company); diff --git a/dustin/model/db_seeds/company_seeds.js b/dustin/model/db_seeds/company_seeds.js new file mode 100644 index 0000000..940f269 --- /dev/null +++ b/dustin/model/db_seeds/company_seeds.js @@ -0,0 +1,85 @@ +'use strict'; + +const mongoose = require('mongoose'); +const Company = require('../../schema/companies'); + +process.env.NODE_ENV = 'DEV'; +if (process.env.NODE_ENV === 'TEST') mongoose.connect('mongodb://localhost/test_db'); +if (process.env.NODE_ENV === 'DEV') mongoose.connect('mongodb://localhost/dev_db'); + +mongoose.connection.collections['companies'].drop(function () { + console.log('collection dropped'); +}); + +new Company({ + name: 'Scrub Daddy', + tvDealReached: true, + tvDealAmount: 300000, + tvDealEquity: .33, + tvDealValuation: 1000000, + actualDealReached: true, + season: 4, + episode: 7 +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Company ' + data.name + ' created'); +}); + +new Company({ + name: 'Squatty Potty', + tvDealReached: true, + tvDealAmount: 350000, + tvDealEquity: .1, + tvDealValuation: 3500000, + actualDealReached: true, + season: 6, + episode: 9 +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Company ' + data.name + ' created'); +}); + +new Company({ + name: 'Cousins Maine Lobster', + tvDealReached: true, + tvDealAmount: 55000, + tvDealEquity: .15, + tvDealValuation: 366667, + actualDealReached: true, + season: 4, + episode: 6 +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Company ' + data.name + ' created'); +}); + +new Company({ + name: 'Tower Paddle Boards', + tvDealReached: true, + tvDealAmount: 150000, + tvDealEquity: .3, + tvDealValuation: 500000, + actualDealReached: true, + season: 3, + episode: 9 +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Company ' + data.name + ' created'); +}); + +new Company({ + name: 'Bantam Bagels', + tvDealReached: true, + tvDealAmount: 275000, + tvDealEquity: .25, + tvDealValuation: 1100000, + actualDealReached: true, + season: 6, + episode: 13 +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Company ' + data.name + ' created'); + mongoose.connection.close(function (data) { + //if (cb) cb(); + }); +}) diff --git a/dustin/model/db_seeds/shark_seeds.js b/dustin/model/db_seeds/shark_seeds.js new file mode 100644 index 0000000..d9bf205 --- /dev/null +++ b/dustin/model/db_seeds/shark_seeds.js @@ -0,0 +1,60 @@ +'use strict'; + +const mongoose = require('mongoose'); +const Shark = require('../../schema/sharks'); + + + process.env.NODE_ENV='DEV' + if (process.env.NODE_ENV === 'TEST') mongoose.connect('mongodb://localhost/test_db'); + if (process.env.NODE_ENV === 'DEV') mongoose.connect('mongodb://localhost/dev_db'); + + mongoose.connection.collections['sharks'].drop(function () { + console.log('collection dropped'); + + new Shark({ + name: 'Kevin O\'Leary' + }).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); + }); + + new Shark({ + name: 'Barbara Corcoran' + }).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); + }); + + new Shark({ + name: 'Daymond John' + }).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); + }); + + new Shark({ + name: 'Robert Herjavec' + }).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); + }); + + new Shark({ + name: 'Lori Greiner' + }).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); + }); + + new Shark({ + name: 'Mark Cuban' + }).save((err, data) => { + if (err) console.log(err); + if (data) { + console.log('Shark ' + data.name + ' created'); + mongoose.connection.close(function (data) { + //if (cb) cb(); + }); + } + }); + }); diff --git a/dustin/model/shark.js b/dustin/model/shark.js new file mode 100644 index 0000000..a32b00a --- /dev/null +++ b/dustin/model/shark.js @@ -0,0 +1,8 @@ +'use strict'; +const mongoose = require('mongoose'); + +const Shark = new mongoose.Schema({ + name: String, +}); + +module.exports = mongoose.model('sharks', Shark); diff --git a/dustin/model/user.js b/dustin/model/user.js new file mode 100644 index 0000000..d6010a7 --- /dev/null +++ b/dustin/model/user.js @@ -0,0 +1,26 @@ +'use strict'; + +const mongoose = require('mongoose'); +const bcrypt = require('bcrypt'); +const jwt = require('jsonwebtoken'); +const secret = process.env.SECRET || 'changeme' + + +const User = new mongoose.Schema({ + username: {type: String, required: true}, + password: {type: String, required: true} +}); + +User.methods.hashPassword = function() { + return bcrypt.hashSync(this.password, 8); +}; + +User.methods.generateToken = function () { + return jwt.sign({_id: this._id}, secret) +} + +User.methods.comparePassword = function(password) { + return bcrypt.compareSync(password, this.password); +}; + +module.exports = mongoose.model('user', User); diff --git a/dustin/package.json b/dustin/package.json new file mode 100644 index 0000000..9613f8a --- /dev/null +++ b/dustin/package.json @@ -0,0 +1,34 @@ +{ + "name": "SharkTankAPI", + "version": "0.0.1", + "description": "", + "main": "server.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "chai": "^3.5.0", + "chai-http": "^2.0.1", + "gulp": "^3.9.1", + "gulp-eslint": "^2.0.0", + "gulp-mocha": "^2.2.0", + "mocha": "^2.4.5", + "morgan": "^1.7.0", + "really-need": "^1.9.2" + }, + "dependencies": { + "bcrypt": "^0.8.6", + "body-parser": "^1.15.1", + "express": "^4.13.4", + "json-fs-store": "^1.0.0", + "jsonwebtoken": "^7.0.0", + "mongoose": "^4.4.19" + } +} diff --git a/dustin/routes/auth.js b/dustin/routes/auth.js new file mode 100644 index 0000000..fd455e1 --- /dev/null +++ b/dustin/routes/auth.js @@ -0,0 +1,31 @@ +'use strict'; +const express = require('express'); +const bodyParser = require('body-parser').json(); +const User = require('../model/user'); +const basicHTTP = require('../lib/basic_auth'); + +const router = module.exports = exports = express.Router(); + +router.post('/signup', bodyParser, (req, res, next) => { + let newUser = new User(req.body); + let hashedPassword = newUser.hashPassword(); + newUser.password = hashedPassword; + req.body.password = null; + User.findOne({username: req.body.username}, (err, user) => { + if (err || user) return next(new Error('user already exist')); + newUser.save((err, user) => { + if (err) return next(new Error('could not create user')); + res.json({token: user.generateToken()}); + }); + }); +}); + +router.get('/signin', basicHTTP, (req, res, next) => { + User.findOne({username: req.auth.username}, (err, user) => { + if (err || !user) return next(new Error('Could not sign in')); + if (!user.comparePassword(req.auth.password)) return next(new Error('Could not sign in')); + + res.json({token: user.generateToken()}); + }); + +}); diff --git a/dustin/routes/companies.js b/dustin/routes/companies.js new file mode 100644 index 0000000..1c94dd2 --- /dev/null +++ b/dustin/routes/companies.js @@ -0,0 +1,72 @@ +'use strict'; +var express = require('express'); +var router = express.Router(); +const bodyParser = require('body-parser').json(); +const Company = require('../model/company'); +const User = require('../model/user'); +const jwt = require('jsonwebtoken'); +const secret = process.env.SECRET || 'changeme' +const jwtAuth = require('../lib/jwt_auth') + +//index companies +router.get('/', jwtAuth, (req, res, next) => { + Company.find({}, (err, companies) => { + if (err) return next(err); + res.json(companies); + }); +}); + +router.get('/dealstats', jwtAuth, (req, res, next) => { + Company.find({ + tvDealValuation: { + $ne: true + } + }, (err, companies) => { + if (err) return next(err); + let count = 0; + let total = (companies.reduce((a,b)=> { + if (b.tvDealValuation) ++count; + return a + b.tvDealValuation; + },0)); + res.send({averageTvDealValuation: total/count, totalTvDealValuation: total }); + }); +}); + +//create companies +router.post('/', bodyParser, jwtAuth, (req, res, next) => { + let newCompany = new Company(req.body); + newCompany.save((err, company) => { + if (err) return next(err); + res.json(company); + }); +}); + +//put company +router.put('/', bodyParser, jwtAuth, (req, res, next) => { + let _id = req.body._id; + Company.findOneAndUpdate({ + _id + }, req.body, (err) => { + if (err) return next(err); + let message = 'successfully update'; + res.json({ + message + }); + }); +}); + +//delete companies +router.delete('/:id', jwtAuth, (req, res, next) => { + let _id = req.params.id; + Company.findOneAndRemove({ + _id + }, (err) => { + if (err) return next(err); + let message = 'sucessfully deleted'; + res.json({ + message + }); + }); +}); + +module.exports = router; diff --git a/dustin/routes/index.js b/dustin/routes/index.js new file mode 100644 index 0000000..530f1fa --- /dev/null +++ b/dustin/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + + +router.get('/', function(req, res) { + res.send('shark tank api'); +}); + +module.exports = router; diff --git a/dustin/routes/sharks.js b/dustin/routes/sharks.js new file mode 100644 index 0000000..c380d4c --- /dev/null +++ b/dustin/routes/sharks.js @@ -0,0 +1,51 @@ +'use strict'; +var express = require('express'); +var router = express.Router(); +const bodyParser = require('body-parser').json(); +const Shark = require('../model/shark'); +const jwtAuth = require('../lib/jwt_auth') + +//index companies +router.get('/', jwtAuth, (req, res, next) => { + Shark.find({}, (err, companies) => { + if (err) return next(err); + res.json(companies); + }); +}); + +//create companies +router.post('/', bodyParser, jwtAuth, (req, res, next) => { + let newShark = new Shark(req.body); + newShark.save((err, shark) => { + if (err) return next(err); + res.json(shark); + }); +}); + +//put shark +router.put('/', bodyParser, jwtAuth, (req, res, next) => { + let _id = req.body._id; + Shark.findOneAndUpdate({_id}, req.body, (err) => { + if (err) return next(err); + let message = 'successfully update'; + res.json({ + message + }); + }); +}); + +//delete companies +router.delete('/:id', jwtAuth, (req, res, next) => { + let _id = req.params.id; + Shark.findOneAndRemove({ + _id + }, (err) => { + if (err) return next(err); + let message = 'sucessfully deleted'; + res.json({ + message + }); + }); +}); + +module.exports = router; diff --git a/dustin/server.js b/dustin/server.js new file mode 100644 index 0000000..a4f9b0a --- /dev/null +++ b/dustin/server.js @@ -0,0 +1,35 @@ +'use strict'; +const express = require('express'); +const bodyParser = require('body-parser'); +const jsonPaser = bodyParser.json(); +const routes = require('./routes/index'); +const companies = require('./routes/companies'); +const sharks = require('./routes/sharks'); +const authRouter = require('./routes/auth'); +const app = express(); +const mongoose = require('mongoose'); +const morgan = require('morgan'); +const errorHandler = require('./lib/errorhandler'); + +const dbPort = process.env.MONGOLAB_URI || 'mongodb://localhost/dev_db'; +mongoose.connect(dbPort); +if (!(process.env.NODE_ENV === 'TEST')) app.use(morgan('dev')); + +app.use(jsonPaser); + +app.use('/', routes); +app.use('/companies', companies); +app.use('/sharks', sharks); +app.use('/', authRouter); + +app.get('/*', (req, res) => { + res.status(404).json({ + Error: 'Not Found' + }); +}); + +app.use(errorHandler); + +app.listen(3000, () => { + if (!(process.env.NODE_ENV === 'TEST')) console.log('up on 3000'); +}); diff --git a/dustin/test/company_test.js b/dustin/test/company_test.js new file mode 100644 index 0000000..b7e8463 --- /dev/null +++ b/dustin/test/company_test.js @@ -0,0 +1,171 @@ +'use strict'; + +const chai = require('chai'); +const chaiHTTP = require('chai-http'); +const Company = require('../model/company'); +const User = require('../model/user'); +const mongoose = require('mongoose'); +chai.use(chaiHTTP); +const expect = chai.expect; +const request = chai.request; +const jwt = require('jsonwebtoken'); +const secret = process.env.SECRET || 'changeme'; + +const dbPort = process.env.MONGOLAB_URI; +process.env.NODE_ENV = 'TEST'; +process.env.MONGOLAB_URI = 'mongodb://localhost/test_db'; + +require('../server'); + +describe('The /company route', () => { + let testCompany; + let testUser; + let token; + beforeEach((done) => { + let newUser = new User({ + username: 'testuser', + password: '$2a$08$pMewnngJdnSYxMz6dVcl8.H6PSiCqGCEP8Gri5zA6asB/qChSFMHq' + }); + newUser.save((err, user) => { + testUser = user; + token = jwt.sign({_id: testUser._id}, secret); + }); + new Company({ + name: 'Scrub Daddy', + tvDealReached: true, + tvDealAmount: 300000, + tvDealEquity: .33, + tvDealValuation: 1000000, + actualDealReached: true, + season: 4, + episode: 7 + }).save((err, data) => { + if (data) testCompany = data; + if (err) throw err; + }); + + new Company({ + name: 'Squatty Potty', + tvDealReached: true, + tvDealAmount: 350000, + tvDealEquity: .1, + tvDealValuation: 3500000, + actualDealReached: true, + season: 6, + episode: 9 + }).save((err) => { + if (err) throw err; + }); + + new Company({ + name: 'Cousins Maine Lobster', + tvDealReached: true, + tvDealAmount: 55000, + tvDealEquity: .15, + tvDealValuation: 366667, + actualDealReached: true, + season: 4, + episode: 6 + }).save((err) => { + if (err) throw err; + }); + + new Company({ + name: 'Tower Paddle Boards', + tvDealReached: true, + tvDealAmount: 150000, + tvDealEquity: .3, + tvDealValuation: 500000, + actualDealReached: true, + season: 3, + episode: 9 + }).save((err) => { + if (err) throw err; + }); + + new Company({ + name: 'Bantam Bagels', + tvDealReached: true, + tvDealAmount: 275000, + tvDealEquity: .25, + tvDealValuation: 1100000, + actualDealReached: true, + season: 6, + episode: 13 + }).save((err,data) => { + if (err) throw err; + if (data) done(); + }); + }); + afterEach((done) => { + process.env.MONGOLAB_URI = dbPort; + mongoose.connection.db.dropDatabase(() => { + done(); + }); + }); + + it('GET should return a list of companies', (done) => { + request('localhost:3000') + .get('/companies/') + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(Array.isArray(res.body)).to.eql(true); + done(); + }); + }); + + it('POST should accept a post and create a new company', (done) => { + request('localhost:3000') + .post('/companies/') + .send({ + name: 'posty' + }) + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.name).to.have.eql('posty'); + expect(res.body).to.have.property('_id'); + done(); + }); + }); + + it('PUT should update a company', (done) => { + testCompany.name = 'updated'; + request('localhost:3000') + .put('/companies/') + .send(testCompany) + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.message).to.eql('successfully update'); + done(); + }); + }); + + it('DELETE should remove a company', (done) => { + request('localhost:3000') + .delete('/companies/' + testCompany._id) + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.message).to.eql('sucessfully deleted'); + done(); + }); + }); + + it('/dealstats return deal stats', (done) => { + request('localhost:3000') + .get('/companies/dealstats') + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body).to.eql({averageTvDealValuation:1293333.4, totalTvDealValuation:6466667}); + done(); + }); + }); +}); diff --git a/dustin/test/db_seeds/shark_seeds.js b/dustin/test/db_seeds/shark_seeds.js new file mode 100644 index 0000000..1572bbe --- /dev/null +++ b/dustin/test/db_seeds/shark_seeds.js @@ -0,0 +1,50 @@ +'use strict'; + +const mongoose = require('mongoose'); +const Shark = require('../../schema/sharks'); + +process.env.NODE_ENV = 'DEV'; +if (process.env.NODE_ENV === 'TEST') mongoose.connect('mongodb://localhost/test_db'); +if (process.env.NODE_ENV === 'DEV') mongoose.connect('mongodb://localhost/dev_db'); +console.log("ger"); +new Shark({ + name: 'Kevin O\'Leary' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); + +new Shark({ + name: 'Barbara Corcoran' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); + +new Shark({ + name: 'Daymond John' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); + +new Shark({ + name: 'Robert Herjavec' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); + +new Shark({ + name: 'Lori Greiner' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); + +new Shark({ + name: 'Mark Cuban' +}).save((err, data) => { + if (err) console.log(err); + if (data) console.log('Shark ' + data.name + ' created'); +}); diff --git a/dustin/test/db_seeds/user_test.js b/dustin/test/db_seeds/user_test.js new file mode 100644 index 0000000..e69de29 diff --git a/dustin/test/shark_test.js b/dustin/test/shark_test.js new file mode 100644 index 0000000..a79723a --- /dev/null +++ b/dustin/test/shark_test.js @@ -0,0 +1,101 @@ +'use strict'; + +const chai = require('chai'); +const chaiHTTP = require('chai-http'); +const Shark = require('../model/shark'); +const mongoose = require('mongoose'); +chai.use(chaiHTTP); +const expect = chai.expect; +const request = chai.request; +const User = require('../model/user'); +const jwt = require('jsonwebtoken'); +const secret = process.env.SECRET || 'changeme'; + +const dbPort = process.env.MONGOLAB_URI; +process.env.NODE_ENV = 'TEST'; +process.env.MONGOLAB_URI = 'mongodb://localhost/test_db'; + +require('../server'); + +describe('The /shark route', () => { + let testShark; + let testUser; + let token; + + beforeEach((done) => { + let newUser = new User({ + username: 'testuser', + password: '$2a$08$pMewnngJdnSYxMz6dVcl8.H6PSiCqGCEP8Gri5zA6asB/qChSFMHq' + }); + newUser.save((err, user) => { + testUser = user; + token = jwt.sign({_id: testUser._id}, secret); + }); + let newShark = new Shark({ + name: 'test' + }); + newShark.save((err, shark) => { + testShark = shark; + done(); + }); + }); + afterEach((done) => { + process.env.MONGOLAB_URI = dbPort; + mongoose.connection.db.dropDatabase(() => { + done(); + }); + }); + + it('GET should return a list of sharks', (done) => { + request('localhost:3000') + .get('/sharks/') + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(Array.isArray(res.body)).to.eql(true); + done(); + }); + }); + + it('POST should accept a post and create a new shark', (done) => { + request('localhost:3000') + .post('/sharks/') + .set('token', token) + .send({ + name: 'posty' + }) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.name).to.have.eql('posty'); + expect(res.body).to.have.property('_id'); + done(); + }); + }); + + it('PUT should update a shark', (done) => { + testShark.name = 'updated'; + request('localhost:3000') + .put('/sharks/') + .send(testShark) + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.message).to.eql('successfully update'); + done(); + }); + }); + + it('DELETE should remove a shark', (done) => { + request('localhost:3000') + .delete('/sharks/' + testShark._id) + .set('token', token) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.message).to.eql('sucessfully deleted'); + done(); + }); + }); +}); diff --git a/dustin/test/user_test.js b/dustin/test/user_test.js new file mode 100644 index 0000000..25a1964 --- /dev/null +++ b/dustin/test/user_test.js @@ -0,0 +1,74 @@ +'use strict'; + +const chai = require('chai'); +const chaiHTTP = require('chai-http'); +const User = require('../model/user'); +const mongoose = require('mongoose'); +chai.use(chaiHTTP); +const expect = chai.expect; +const request = chai.request; +const jwt = require('jsonwebtoken'); + +const secret = process.env.SECRET || 'changeme'; +const dbPort = process.env.MONGOLAB_URI; +process.env.NODE_ENV = 'TEST'; +process.env.MONGOLAB_URI = 'mongodb://localhost/test_db'; + +require('../server'); + +describe('User authorization should', () => { + let testUser; + beforeEach((done) => { + let newUser = new User({ + username: 'testuser', + password: '$2a$08$pMewnngJdnSYxMz6dVcl8.H6PSiCqGCEP8Gri5zA6asB/qChSFMHq' + }); + newUser.save((err, user) => { + testUser = user; + done(); + }); + }); + afterEach((done) => { + process.env.MONGOLAB_URI = dbPort; + mongoose.connection.db.dropDatabase(() => { + done(); + }); + }); + + it('allow a known user to login and send a correct token', (done) => { + + request('localhost:3000') + .get('/signin') + .auth('testuser', 'testuser') + .end((err, res) => { + expect(err).to.eql(null); + expect(res.body.token).to.eql(jwt.sign({ + _id: testUser._id + }, secret)); + done(); + }); + }); + + it('allow a new user to be created and send a token back', (done) => { + request('localhost:3000') + .post('/signup') + .set('Content-Type', 'application/json') + .send({ + username: 'user', + password: 'password' + }) + .end((err, res) => { + User.find({ + username: 'user' + }, (err, user) => { + if (err) return err; + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.token).to.eql(jwt.sign({ + _id: user[0]._id + }, secret)); + done(); + }); + }); + }); +});