From b331a3403b76882caee6b1e448d15720e68e72ea Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Tue, 24 May 2016 10:50:42 -0700 Subject: [PATCH 01/11] init commit --- dustin/.eslintrc.js | 29 ++++++++++ dustin/.gitignore | 2 + dustin/data/1.json | 6 ++ dustin/data/2.json | 6 ++ dustin/data/3.json | 6 ++ dustin/gulpfile.js | 22 +++++++ dustin/package.json | 29 ++++++++++ dustin/routes/companies.js | 63 ++++++++++++++++++++ dustin/routes/index.js | 10 ++++ dustin/server.js | 20 +++++++ dustin/test/test.js | 114 +++++++++++++++++++++++++++++++++++++ 11 files changed, 307 insertions(+) create mode 100644 dustin/.eslintrc.js create mode 100644 dustin/.gitignore create mode 100644 dustin/data/1.json create mode 100644 dustin/data/2.json create mode 100644 dustin/data/3.json create mode 100644 dustin/gulpfile.js create mode 100644 dustin/package.json create mode 100644 dustin/routes/companies.js create mode 100644 dustin/routes/index.js create mode 100644 dustin/server.js create mode 100644 dustin/test/test.js diff --git a/dustin/.eslintrc.js b/dustin/.eslintrc.js new file mode 100644 index 0000000..ed2ec67 --- /dev/null +++ b/dustin/.eslintrc.js @@ -0,0 +1,29 @@ +module.exports = { + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ] + } +}; diff --git a/dustin/.gitignore b/dustin/.gitignore new file mode 100644 index 0000000..b418f0d --- /dev/null +++ b/dustin/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/data*.json diff --git a/dustin/data/1.json b/dustin/data/1.json new file mode 100644 index 0000000..395e9d9 --- /dev/null +++ b/dustin/data/1.json @@ -0,0 +1,6 @@ +{ + "name": "Scrub Daddy", + "website": "www.scrubdaddy", + "rasied": "500000", + "id": 1 +} \ No newline at end of file diff --git a/dustin/data/2.json b/dustin/data/2.json new file mode 100644 index 0000000..6c02ef4 --- /dev/null +++ b/dustin/data/2.json @@ -0,0 +1,6 @@ +{ + "name": "Scrub Daddy", + "website": "www.scrubdaddy", + "rasied": "500000", + "id": 2 +} \ No newline at end of file diff --git a/dustin/data/3.json b/dustin/data/3.json new file mode 100644 index 0000000..2301e9b --- /dev/null +++ b/dustin/data/3.json @@ -0,0 +1,6 @@ +{ + "name": "Scrub Daddy", + "website": "www.scrubdaddy", + "rasied": "500000", + "id": 3 +} \ No newline at end of file diff --git a/dustin/gulpfile.js b/dustin/gulpfile.js new file mode 100644 index 0000000..fc90c44 --- /dev/null +++ b/dustin/gulpfile.js @@ -0,0 +1,22 @@ +const gulp = require('gulp'); +const mocha = require('gulp-mocha'); +const lint = require('gulp-eslint'); + +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'], ['linter', 'tests']); +}); + +gulp.task('default', ['linter', 'tests', 'watch'], () => { + +}); diff --git a/dustin/package.json b/dustin/package.json new file mode 100644 index 0000000..73e3105 --- /dev/null +++ b/dustin/package.json @@ -0,0 +1,29 @@ +{ + "name": "Shark Tank API", + "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" + }, + "dependencies": { + "body-parser": "^1.15.1", + "express": "^4.13.4", + "json-fs-store": "^1.0.0" + } +} diff --git a/dustin/routes/companies.js b/dustin/routes/companies.js new file mode 100644 index 0000000..b877fa9 --- /dev/null +++ b/dustin/routes/companies.js @@ -0,0 +1,63 @@ +'use strict'; +var express = require('express'); +var router = express.Router(); +var db = require('json-fs-store')('./data'); +var fs = require('fs'); +var nextID = function () { + return fs.readdirSync('./data').length + 1; +}; + +router.post('/', (req, res, next) => { + let company = req.body; + company.id = nextID(); + db.add(company, function (err) { + if (err) throw err; + }); + res.send({ + Message: "POST received" + }); +}); + +router.put('/id', (req, res, next) => { + db.load(req.params.id, function (err, object) { + if (err) { + res.status(404).json({ + Error: 'Not Found' + }); + } + object.test = 100; + }); +}); + +router.get('/', (req, res, next) => { + db.list(function (err, objects) { + if (err) throw err; + res.json(objects); + }); +}); + +router.get('/:id', (req, res, next) => { + db.load(req.params.id, function (err, object) { + if (err) { + res.status(404).json({ + Error: 'Not Found' + }); + } + res.json(object); + }); +}); + +router.delete('/:id', (req, res, next) => { + db.remove(req.params.id, function (err) { + res.send({ + 'Message': 'Entry DELETED' + }); + if (err) { + res.status(404).json({ + Error: 'Not Found' + }); + } + }); +}); + +module.exports = router; diff --git a/dustin/routes/index.js b/dustin/routes/index.js new file mode 100644 index 0000000..b0a2ca3 --- /dev/null +++ b/dustin/routes/index.js @@ -0,0 +1,10 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + //res.render('index', { title: 'Express' }); + res.send("shark tank api") +}); + +module.exports = router; diff --git a/dustin/server.js b/dustin/server.js new file mode 100644 index 0000000..fcd40fb --- /dev/null +++ b/dustin/server.js @@ -0,0 +1,20 @@ +'use strict'; +const express = require('express'); +const bodyParser = require('body-parser'); +const jsonPaser = bodyParser.json(); +//const companyRouter = express.Router(); +var routes = require('./routes/index'); +var companies = require('./routes/companies'); +var app = express(); + +app.use(jsonPaser); + +app.use('/', routes); +app.use('/companies', companies); + + +app.get('/*', (req,res) => { + res.status(404).json({Error:'Not Found'}) +}) + +app.listen(3000, () => console.log('up on 3000')); diff --git a/dustin/test/test.js b/dustin/test/test.js new file mode 100644 index 0000000..d0fe3f7 --- /dev/null +++ b/dustin/test/test.js @@ -0,0 +1,114 @@ +'use strict'; + +const chai = require('chai'); +const expect = require('chai').expect; +const chaiHTTP = require('chai-http'); +var fs = require('fs'); +chai.use(chaiHTTP); +const request = chai.request; +require('../server'); + +var dbEntries = fs.readdirSync('./data').length +var payload = { + company: 'Tanktest', + seek_dollar: '200000', + seek_equity: '.2', + id: (dbEntries + 1) +}; + + describe('Shark tank API should', function () { + it('accept a POST request to /companies', function (done) { + request('localhost:3000') + .post('/companies') + .send(payload) + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.text).to.eql('{"Message":"POST received"}'); + done(); + }); + }); + + + it('list all companies in the "database"', function (done) { + request('localhost:3000') + .get('/companies') + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.length).to.eql(dbEntries + 1) + done(); + }); + }); + + + + it('list a company by id', function (done) { + request('localhost:3000') + .get('/companies/' + (dbEntries + 1)) + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body).to.eql(payload) + done(); + }); + }); + + // it('respond to a PUT request on default route /', function (done) { + // request('localhost:3000') + // .put('/') + // .end(function (err, res) { + // expect(err).to.eql(null); + // expect(res).to.have.status(200); + // expect(res.text).to.eql('{"Message":"PUT request to homepage received"}'); + // done(); + // }); + // }); + + + it('properly DELETE', function (done) { + request('localhost:3000') + .delete('/companies/' + (dbEntries + 1)) + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.text).to.eql('{"Message":"Entry DELETED"}'); + done(); + }); + }); + + // + + // + // it('respond to a PATCH request on default route /', function (done) { + // request('localhost:3000') + // .patch('/') + // .end(function (err, res) { + // expect(err).to.eql(null); + // expect(res).to.have.status(200); + // expect(res.text).to.eql('{"Message":"PATCH request to homepage received"}'); + // done(); + // }); + // }); + // + it('respond with 404 to an invalid route', function (done) { + request('localhost:3000') + .get('/companies/' + (dbEntries + 1)) + .end(function (err, res) { + expect(res).to.have.status(404); + expect(res.text).to.eql('{"Error":"Not Found"}'); + done(); + }); + }); + // + // it('respond with 400 if an invalid request is made', function (done) { + // request('localhost:3000') + // .copy('/') + // .end(function (err, res) { + // expect(res).to.have.status(400); + // expect(res.text).to.eql('{"Error":"Bad Request"}'); + // done(); + // }); + // }); + +}); From 499eb2b1eba601446b2c29de0375e2159ae24f65 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Tue, 24 May 2016 10:52:59 -0700 Subject: [PATCH 02/11] removed data files --- dustin/.gitignore | 2 +- dustin/data/1.json | 6 ------ dustin/data/2.json | 6 ------ dustin/data/3.json | 6 ------ 4 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 dustin/data/1.json delete mode 100644 dustin/data/2.json delete mode 100644 dustin/data/3.json diff --git a/dustin/.gitignore b/dustin/.gitignore index b418f0d..a99e447 100644 --- a/dustin/.gitignore +++ b/dustin/.gitignore @@ -1,2 +1,2 @@ /node_modules -/data*.json +/data/*.json diff --git a/dustin/data/1.json b/dustin/data/1.json deleted file mode 100644 index 395e9d9..0000000 --- a/dustin/data/1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Scrub Daddy", - "website": "www.scrubdaddy", - "rasied": "500000", - "id": 1 -} \ No newline at end of file diff --git a/dustin/data/2.json b/dustin/data/2.json deleted file mode 100644 index 6c02ef4..0000000 --- a/dustin/data/2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Scrub Daddy", - "website": "www.scrubdaddy", - "rasied": "500000", - "id": 2 -} \ No newline at end of file diff --git a/dustin/data/3.json b/dustin/data/3.json deleted file mode 100644 index 2301e9b..0000000 --- a/dustin/data/3.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Scrub Daddy", - "website": "www.scrubdaddy", - "rasied": "500000", - "id": 3 -} \ No newline at end of file From 89a256bba354992de2779111b4871dc6b040a9b7 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Tue, 24 May 2016 10:55:47 -0700 Subject: [PATCH 03/11] fixed linter errors --- dustin/server.js | 4 ++-- dustin/test/test.js | 30 +++++++++++++----------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/dustin/server.js b/dustin/server.js index fcd40fb..e62894d 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -14,7 +14,7 @@ app.use('/companies', companies); app.get('/*', (req,res) => { - res.status(404).json({Error:'Not Found'}) -}) + res.status(404).json({Error:'Not Found'}); +}); app.listen(3000, () => console.log('up on 3000')); diff --git a/dustin/test/test.js b/dustin/test/test.js index d0fe3f7..7baea4c 100644 --- a/dustin/test/test.js +++ b/dustin/test/test.js @@ -8,7 +8,7 @@ chai.use(chaiHTTP); const request = chai.request; require('../server'); -var dbEntries = fs.readdirSync('./data').length +var dbEntries = fs.readdirSync('./data').length; var payload = { company: 'Tanktest', seek_dollar: '200000', @@ -16,7 +16,7 @@ var payload = { id: (dbEntries + 1) }; - describe('Shark tank API should', function () { +describe('Shark tank API should', function () { it('accept a POST request to /companies', function (done) { request('localhost:3000') .post('/companies') @@ -29,19 +29,16 @@ var payload = { }); }); - - it('list all companies in the "database"', function (done) { - request('localhost:3000') - .get('/companies') - .end(function (err, res) { - expect(err).to.eql(null); - expect(res).to.have.status(200); - expect(res.body.length).to.eql(dbEntries + 1) - done(); - }); - }); - - + it('list all companies in the "database"', function (done) { + request('localhost:3000') + .get('/companies') + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.body.length).to.eql(dbEntries + 1); + done(); + }); + }); it('list a company by id', function (done) { request('localhost:3000') @@ -49,7 +46,7 @@ var payload = { .end(function (err, res) { expect(err).to.eql(null); expect(res).to.have.status(200); - expect(res.body).to.eql(payload) + expect(res.body).to.eql(payload); done(); }); }); @@ -65,7 +62,6 @@ var payload = { // }); // }); - it('properly DELETE', function (done) { request('localhost:3000') .delete('/companies/' + (dbEntries + 1)) From aaa2c6a4730212860d941af2216c0e8c5f6cc34a Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Wed, 25 May 2016 16:36:10 -0700 Subject: [PATCH 04/11] minor changes --- dustin/routes/index.js | 5 ++--- dustin/server.js | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dustin/routes/index.js b/dustin/routes/index.js index b0a2ca3..83916a5 100644 --- a/dustin/routes/index.js +++ b/dustin/routes/index.js @@ -1,10 +1,9 @@ var express = require('express'); var router = express.Router(); -/* GET home page. */ + router.get('/', function(req, res, next) { - //res.render('index', { title: 'Express' }); - res.send("shark tank api") + res.send("shark tank api"); }); module.exports = router; diff --git a/dustin/server.js b/dustin/server.js index e62894d..80ff4a0 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -13,6 +13,7 @@ app.use('/', routes); app.use('/companies', companies); + app.get('/*', (req,res) => { res.status(404).json({Error:'Not Found'}); }); From d1bfa42259ee48be326bd399b1a6a4545f8fda10 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Fri, 27 May 2016 10:24:32 -0700 Subject: [PATCH 05/11] added second resource and migrated to mongo --- dustin/.gitignore | 2 +- dustin/lib/errorhandler.js | 5 + dustin/package.json | 8 +- dustin/routes/companies.js | 87 +++++----- dustin/routes/index.js | 4 +- dustin/routes/sharks.js | 50 ++++++ dustin/schema/companies.js | 23 +++ dustin/schema/db_seeds/company_seeds.js | 85 +++++++++ dustin/schema/db_seeds/shark_seeds.js | 60 +++++++ dustin/schema/sharks.js | 8 + dustin/server.js | 30 +++- dustin/test/company_test.js | 152 ++++++++++++++++ dustin/test/db_seeds/shark_seeds.js | 50 ++++++ dustin/test/shark_test.js | 82 +++++++++ dustin/test/test.js | 220 ++++++++++++------------ 15 files changed, 702 insertions(+), 164 deletions(-) create mode 100644 dustin/lib/errorhandler.js create mode 100644 dustin/routes/sharks.js create mode 100644 dustin/schema/companies.js create mode 100644 dustin/schema/db_seeds/company_seeds.js create mode 100644 dustin/schema/db_seeds/shark_seeds.js create mode 100644 dustin/schema/sharks.js create mode 100644 dustin/test/company_test.js create mode 100644 dustin/test/db_seeds/shark_seeds.js create mode 100644 dustin/test/shark_test.js diff --git a/dustin/.gitignore b/dustin/.gitignore index a99e447..4c497d6 100644 --- a/dustin/.gitignore +++ b/dustin/.gitignore @@ -1,2 +1,2 @@ /node_modules -/data/*.json +/db diff --git a/dustin/lib/errorhandler.js b/dustin/lib/errorhandler.js new file mode 100644 index 0000000..5e09b43 --- /dev/null +++ b/dustin/lib/errorhandler.js @@ -0,0 +1,5 @@ +module.exports = function (err, req, res, next) { + res.status(500).json({ + message: err.message + }); +}; diff --git a/dustin/package.json b/dustin/package.json index 73e3105..6990956 100644 --- a/dustin/package.json +++ b/dustin/package.json @@ -1,5 +1,5 @@ { - "name": "Shark Tank API", + "name": "SharkTankAPI", "version": "0.0.1", "description": "", "main": "server.js", @@ -19,11 +19,13 @@ "gulp": "^3.9.1", "gulp-eslint": "^2.0.0", "gulp-mocha": "^2.2.0", - "mocha": "^2.4.5" + "mocha": "^2.4.5", + "morgan": "^1.7.0" }, "dependencies": { "body-parser": "^1.15.1", "express": "^4.13.4", - "json-fs-store": "^1.0.0" + "json-fs-store": "^1.0.0", + "mongoose": "^4.4.19" } } diff --git a/dustin/routes/companies.js b/dustin/routes/companies.js index b877fa9..0e18325 100644 --- a/dustin/routes/companies.js +++ b/dustin/routes/companies.js @@ -1,62 +1,69 @@ 'use strict'; var express = require('express'); var router = express.Router(); -var db = require('json-fs-store')('./data'); -var fs = require('fs'); -var nextID = function () { - return fs.readdirSync('./data').length + 1; -}; +const bodyParser = require('body-parser').json(); +const Company = require('../schema/companies'); -router.post('/', (req, res, next) => { - let company = req.body; - company.id = nextID(); - db.add(company, function (err) { - if (err) throw err; - }); - res.send({ - Message: "POST received" +//index companies +router.get('/', (req, res, next) => { + Company.find({}, (err, companies) => { + if (err) return next(err); + res.json(companies); }); }); -router.put('/id', (req, res, next) => { - db.load(req.params.id, function (err, object) { - if (err) { - res.status(404).json({ - Error: 'Not Found' - }); +router.get('/dealstats', (req, res, next) => { + + //get tvDealValuation amount + Company.find({ + tvDealValuation: { + $ne: true } - object.test = 100; + }, (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 }); }); }); -router.get('/', (req, res, next) => { - db.list(function (err, objects) { - if (err) throw err; - res.json(objects); +//create companies +router.post('/', bodyParser, (req, res, next) => { + let newCompany = new Company(req.body); + newCompany.save((err, company) => { + if (err) return next(err); + res.json(company); }); }); -router.get('/:id', (req, res, next) => { - db.load(req.params.id, function (err, object) { - if (err) { - res.status(404).json({ - Error: 'Not Found' - }); - } - res.json(object); +//put company +router.put('/', bodyParser, (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', (req, res, next) => { - db.remove(req.params.id, function (err) { - res.send({ - 'Message': 'Entry DELETED' + let _id = req.params.id; + Company.findOneAndRemove({ + _id + }, (err) => { + if (err) return next(err); + let message = 'sucessfully deleted'; + res.json({ + message }); - if (err) { - res.status(404).json({ - Error: 'Not Found' - }); - } }); }); diff --git a/dustin/routes/index.js b/dustin/routes/index.js index 83916a5..530f1fa 100644 --- a/dustin/routes/index.js +++ b/dustin/routes/index.js @@ -2,8 +2,8 @@ var express = require('express'); var router = express.Router(); -router.get('/', function(req, res, next) { - res.send("shark tank api"); +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..bb5a0a9 --- /dev/null +++ b/dustin/routes/sharks.js @@ -0,0 +1,50 @@ +'use strict'; +var express = require('express'); +var router = express.Router(); +const bodyParser = require('body-parser').json(); +const Shark = require('../schema/companies'); + +//index companies +router.get('/', (req, res, next) => { + Shark.find({}, (err, companies) => { + if (err) return next(err); + res.json(companies); + }); +}); + +//create companies +router.post('/', bodyParser, (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, (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', (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/schema/companies.js b/dustin/schema/companies.js new file mode 100644 index 0000000..1497e6b --- /dev/null +++ b/dustin/schema/companies.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/schema/db_seeds/company_seeds.js b/dustin/schema/db_seeds/company_seeds.js new file mode 100644 index 0000000..9023817 --- /dev/null +++ b/dustin/schema/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/schema/db_seeds/shark_seeds.js b/dustin/schema/db_seeds/shark_seeds.js new file mode 100644 index 0000000..2cebe76 --- /dev/null +++ b/dustin/schema/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/schema/sharks.js b/dustin/schema/sharks.js new file mode 100644 index 0000000..a32b00a --- /dev/null +++ b/dustin/schema/sharks.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/server.js b/dustin/server.js index 80ff4a0..a6f16b9 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -2,20 +2,34 @@ const express = require('express'); const bodyParser = require('body-parser'); const jsonPaser = bodyParser.json(); -//const companyRouter = express.Router(); -var routes = require('./routes/index'); -var companies = require('./routes/companies'); -var app = express(); +const routes = require('./routes/index'); +const companies = require('./routes/companies'); +const sharks = require('./routes/sharks'); +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.get('/*', (req, res) => { + res.status(404).json({ + Error: 'Not Found' + }); +}); +app.use(errorHandler); -app.get('/*', (req,res) => { - res.status(404).json({Error:'Not Found'}); +app.listen(3000, () => { + if (!(process.env.NODE_ENV === 'TEST')) console.log('up on 3000'); }); - -app.listen(3000, () => 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..3edbe93 --- /dev/null +++ b/dustin/test/company_test.js @@ -0,0 +1,152 @@ +'use strict'; + +const chai = require('chai'); +const chaiHTTP = require('chai-http'); +const Company = require('../schema/companies'); +const mongoose = require('mongoose'); +chai.use(chaiHTTP); +const expect = chai.expect; +const request = chai.request; + +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; + beforeEach((done) => { + 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', () => { + request('localhost:3000') + .get('/companies/') + .end((err, res) => { + expect(err).to.eql(null); + expect(Array.isArray(res.body)).to.eql(true); + }); + }); + + it('POST should accept a post and create a new company', (done) => { + request('localhost:3000') + .post('/companies/') + .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 company', (done) => { + testCompany.name = 'updated'; + request('localhost:3000') + .put('/companies/') + .send(testCompany) + .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) + .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') + .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/shark_test.js b/dustin/test/shark_test.js new file mode 100644 index 0000000..0d1a3b9 --- /dev/null +++ b/dustin/test/shark_test.js @@ -0,0 +1,82 @@ +'use strict'; + +const chai = require('chai'); +const chaiHTTP = require('chai-http'); +const Shark = require('../schema/companies'); +const mongoose = require('mongoose'); +chai.use(chaiHTTP); +const expect = chai.expect; +const request = chai.request; + +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; + beforeEach((done) => { + let newShark = new Shark({ + name: 'test' + }); + newShark.save((err, shark) => { + testShark = shark; + done(); + }); + }); + after((done) => { + process.env.MONGOLAB_URI = dbPort; + mongoose.connection.db.dropDatabase(() => { + done(); + }); + }); + + it('GET should return a list of companies', () => { + request('localhost:3000') + .get('/companies/') + .end((err, res) => { + expect(err).to.eql(null); + expect(Array.isArray(res.body)).to.eql(true); + }); + }); + + it('POST should accept a post and create a new shark', (done) => { + request('localhost:3000') + .post('/companies/') + .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('/companies/') + .send(testShark) + .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('/companies/' + testShark._id) + .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/test.js b/dustin/test/test.js index 7baea4c..7c812aa 100644 --- a/dustin/test/test.js +++ b/dustin/test/test.js @@ -1,110 +1,110 @@ -'use strict'; - -const chai = require('chai'); -const expect = require('chai').expect; -const chaiHTTP = require('chai-http'); -var fs = require('fs'); -chai.use(chaiHTTP); -const request = chai.request; -require('../server'); - -var dbEntries = fs.readdirSync('./data').length; -var payload = { - company: 'Tanktest', - seek_dollar: '200000', - seek_equity: '.2', - id: (dbEntries + 1) -}; - -describe('Shark tank API should', function () { - it('accept a POST request to /companies', function (done) { - request('localhost:3000') - .post('/companies') - .send(payload) - .end(function (err, res) { - expect(err).to.eql(null); - expect(res).to.have.status(200); - expect(res.text).to.eql('{"Message":"POST received"}'); - done(); - }); - }); - - it('list all companies in the "database"', function (done) { - request('localhost:3000') - .get('/companies') - .end(function (err, res) { - expect(err).to.eql(null); - expect(res).to.have.status(200); - expect(res.body.length).to.eql(dbEntries + 1); - done(); - }); - }); - - it('list a company by id', function (done) { - request('localhost:3000') - .get('/companies/' + (dbEntries + 1)) - .end(function (err, res) { - expect(err).to.eql(null); - expect(res).to.have.status(200); - expect(res.body).to.eql(payload); - done(); - }); - }); - - // it('respond to a PUT request on default route /', function (done) { - // request('localhost:3000') - // .put('/') - // .end(function (err, res) { - // expect(err).to.eql(null); - // expect(res).to.have.status(200); - // expect(res.text).to.eql('{"Message":"PUT request to homepage received"}'); - // done(); - // }); - // }); - - it('properly DELETE', function (done) { - request('localhost:3000') - .delete('/companies/' + (dbEntries + 1)) - .end(function (err, res) { - expect(err).to.eql(null); - expect(res).to.have.status(200); - expect(res.text).to.eql('{"Message":"Entry DELETED"}'); - done(); - }); - }); - - // - - // - // it('respond to a PATCH request on default route /', function (done) { - // request('localhost:3000') - // .patch('/') - // .end(function (err, res) { - // expect(err).to.eql(null); - // expect(res).to.have.status(200); - // expect(res.text).to.eql('{"Message":"PATCH request to homepage received"}'); - // done(); - // }); - // }); - // - it('respond with 404 to an invalid route', function (done) { - request('localhost:3000') - .get('/companies/' + (dbEntries + 1)) - .end(function (err, res) { - expect(res).to.have.status(404); - expect(res.text).to.eql('{"Error":"Not Found"}'); - done(); - }); - }); - // - // it('respond with 400 if an invalid request is made', function (done) { - // request('localhost:3000') - // .copy('/') - // .end(function (err, res) { - // expect(res).to.have.status(400); - // expect(res.text).to.eql('{"Error":"Bad Request"}'); - // done(); - // }); - // }); - -}); +// 'use strict'; +// +// const chai = require('chai'); +// const expect = require('chai').expect; +// const chaiHTTP = require('chai-http'); +// var fs = require('fs'); +// chai.use(chaiHTTP); +// const request = chai.request; +// require('../server'); +// +// var dbEntries = fs.readdirSync('./data').length; +// var payload = { +// company: 'Tanktest', +// seek_dollar: '200000', +// seek_equity: '.2', +// id: (dbEntries + 1) +// }; +// +// describe('Shark tank API should', function () { +// it('accept a POST request to /companies', function (done) { +// request('localhost:3000') +// .post('/companies') +// .send(payload) +// .end(function (err, res) { +// expect(err).to.eql(null); +// expect(res).to.have.status(200); +// expect(res.text).to.eql('{"Message":"POST received"}'); +// done(); +// }); +// }); +// +// it('list all companies in the "database"', function (done) { +// request('localhost:3000') +// .get('/companies') +// .end(function (err, res) { +// expect(err).to.eql(null); +// expect(res).to.have.status(200); +// expect(res.body.length).to.eql(dbEntries + 1); +// done(); +// }); +// }); +// +// it('list a company by id', function (done) { +// request('localhost:3000') +// .get('/companies/' + (dbEntries + 1)) +// .end(function (err, res) { +// expect(err).to.eql(null); +// expect(res).to.have.status(200); +// expect(res.body).to.eql(payload); +// done(); +// }); +// }); +// +// // it('respond to a PUT request on default route /', function (done) { +// // request('localhost:3000') +// // .put('/') +// // .end(function (err, res) { +// // expect(err).to.eql(null); +// // expect(res).to.have.status(200); +// // expect(res.text).to.eql('{"Message":"PUT request to homepage received"}'); +// // done(); +// // }); +// // }); +// +// it('properly DELETE', function (done) { +// request('localhost:3000') +// .delete('/companies/' + (dbEntries + 1)) +// .end(function (err, res) { +// expect(err).to.eql(null); +// expect(res).to.have.status(200); +// expect(res.text).to.eql('{"Message":"Entry DELETED"}'); +// done(); +// }); +// }); +// +// // +// +// // +// // it('respond to a PATCH request on default route /', function (done) { +// // request('localhost:3000') +// // .patch('/') +// // .end(function (err, res) { +// // expect(err).to.eql(null); +// // expect(res).to.have.status(200); +// // expect(res.text).to.eql('{"Message":"PATCH request to homepage received"}'); +// // done(); +// // }); +// // }); +// // +// it('respond with 404 to an invalid route', function (done) { +// request('localhost:3000') +// .get('/companies/' + (dbEntries + 1)) +// .end(function (err, res) { +// expect(res).to.have.status(404); +// expect(res.text).to.eql('{"Error":"Not Found"}'); +// done(); +// }); +// }); +// // +// // it('respond with 400 if an invalid request is made', function (done) { +// // request('localhost:3000') +// // .copy('/') +// // .end(function (err, res) { +// // expect(res).to.have.status(400); +// // expect(res.text).to.eql('{"Error":"Bad Request"}'); +// // done(); +// // }); +// // }); +// +// }); From f9956a331d2a86bdc758351a301e954906bc4ea3 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Fri, 27 May 2016 11:15:08 -0700 Subject: [PATCH 06/11] fixed testing error --- dustin/test/shark_test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dustin/test/shark_test.js b/dustin/test/shark_test.js index 0d1a3b9..a296683 100644 --- a/dustin/test/shark_test.js +++ b/dustin/test/shark_test.js @@ -2,7 +2,7 @@ const chai = require('chai'); const chaiHTTP = require('chai-http'); -const Shark = require('../schema/companies'); +const Shark = require('../schema/sharks'); const mongoose = require('mongoose'); chai.use(chaiHTTP); const expect = chai.expect; @@ -32,9 +32,9 @@ describe('The /shark route', () => { }); }); - it('GET should return a list of companies', () => { + it('GET should return a list of sharks', () => { request('localhost:3000') - .get('/companies/') + .get('/sharks/') .end((err, res) => { expect(err).to.eql(null); expect(Array.isArray(res.body)).to.eql(true); @@ -43,7 +43,7 @@ describe('The /shark route', () => { it('POST should accept a post and create a new shark', (done) => { request('localhost:3000') - .post('/companies/') + .post('/sharks/') .send({ name: 'posty' }) @@ -59,7 +59,7 @@ describe('The /shark route', () => { it('PUT should update a shark', (done) => { testShark.name = 'updated'; request('localhost:3000') - .put('/companies/') + .put('/sharks/') .send(testShark) .end((err, res) => { expect(err).to.eql(null); @@ -71,7 +71,7 @@ describe('The /shark route', () => { it('DELETE should remove a shark', (done) => { request('localhost:3000') - .delete('/companies/' + testShark._id) + .delete('/sharks/' + testShark._id) .end((err, res) => { expect(err).to.eql(null); expect(res).to.have.status(200); From d658ebc06ac96088fd6bfb890258ceda77040c79 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Wed, 1 Jun 2016 11:29:52 -0700 Subject: [PATCH 07/11] added basic auth --- dustin/.eslintrc.js | 29 ----- dustin/gulpfile.js | 4 +- dustin/lib/basic_auth.js | 19 +++ dustin/model/company.js | 23 ++++ .../db_seeds/company_seeds.js | 2 +- .../{schema => model}/db_seeds/shark_seeds.js | 2 +- dustin/{schema/sharks.js => model/shark.js} | 0 dustin/model/user.js | 19 +++ dustin/package.json | 4 +- dustin/routes/auth.js | 31 +++++ dustin/routes/companies.js | 4 +- dustin/routes/sharks.js | 2 +- dustin/schema/companies.js | 23 ---- dustin/server.js | 2 + dustin/test/company_test.js | 2 +- dustin/test/db_seeds/user_test.js | 0 dustin/test/shark_test.js | 4 +- dustin/test/test.js | 110 ------------------ dustin/test/user_test.js | 63 ++++++++++ 19 files changed, 170 insertions(+), 173 deletions(-) delete mode 100644 dustin/.eslintrc.js create mode 100644 dustin/lib/basic_auth.js create mode 100644 dustin/model/company.js rename dustin/{schema => model}/db_seeds/company_seeds.js (99%) rename dustin/{schema => model}/db_seeds/shark_seeds.js (99%) rename dustin/{schema/sharks.js => model/shark.js} (100%) create mode 100644 dustin/model/user.js create mode 100644 dustin/routes/auth.js delete mode 100644 dustin/schema/companies.js create mode 100644 dustin/test/db_seeds/user_test.js delete mode 100644 dustin/test/test.js create mode 100644 dustin/test/user_test.js diff --git a/dustin/.eslintrc.js b/dustin/.eslintrc.js deleted file mode 100644 index ed2ec67..0000000 --- a/dustin/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - "env": { - "es6": true, - "node": true, - "mocha": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "sourceType": "module" - }, - "rules": { - "indent": [ - "error", - 2 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - } -}; diff --git a/dustin/gulpfile.js b/dustin/gulpfile.js index fc90c44..0c58bb1 100644 --- a/dustin/gulpfile.js +++ b/dustin/gulpfile.js @@ -2,6 +2,8 @@ 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()) @@ -14,7 +16,7 @@ gulp.task('tests', () => { }); gulp.task('watch', () => { - gulp.watch(['./*.js', './test/*.js', './lib/*.js'], ['linter', 'tests']); + 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..f46c77d --- /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/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/schema/db_seeds/company_seeds.js b/dustin/model/db_seeds/company_seeds.js similarity index 99% rename from dustin/schema/db_seeds/company_seeds.js rename to dustin/model/db_seeds/company_seeds.js index 9023817..940f269 100644 --- a/dustin/schema/db_seeds/company_seeds.js +++ b/dustin/model/db_seeds/company_seeds.js @@ -10,7 +10,7 @@ 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, diff --git a/dustin/schema/db_seeds/shark_seeds.js b/dustin/model/db_seeds/shark_seeds.js similarity index 99% rename from dustin/schema/db_seeds/shark_seeds.js rename to dustin/model/db_seeds/shark_seeds.js index 2cebe76..d9bf205 100644 --- a/dustin/schema/db_seeds/shark_seeds.js +++ b/dustin/model/db_seeds/shark_seeds.js @@ -10,7 +10,7 @@ const Shark = require('../../schema/sharks'); mongoose.connection.collections['sharks'].drop(function () { console.log('collection dropped'); - + new Shark({ name: 'Kevin O\'Leary' }).save((err, data) => { diff --git a/dustin/schema/sharks.js b/dustin/model/shark.js similarity index 100% rename from dustin/schema/sharks.js rename to dustin/model/shark.js diff --git a/dustin/model/user.js b/dustin/model/user.js new file mode 100644 index 0000000..bc90131 --- /dev/null +++ b/dustin/model/user.js @@ -0,0 +1,19 @@ +'use strict'; + +const mongoose = require('mongoose'); +const bcrypt = require('bcrypt'); + +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.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 index 6990956..3c8d078 100644 --- a/dustin/package.json +++ b/dustin/package.json @@ -20,11 +20,13 @@ "gulp-eslint": "^2.0.0", "gulp-mocha": "^2.2.0", "mocha": "^2.4.5", - "morgan": "^1.7.0" + "morgan": "^1.7.0", + "really-need": "^1.9.2" }, "dependencies": { "body-parser": "^1.15.1", "express": "^4.13.4", + "bcrypt": "^0.8.6", "json-fs-store": "^1.0.0", "mongoose": "^4.4.19" } diff --git a/dustin/routes/auth.js b/dustin/routes/auth.js new file mode 100644 index 0000000..c09d9c0 --- /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('could not create user')); + newUser.save((err, user) => { + if (err) return next(new Error('could not create user')); + res.json({token: 'token'}); + }); + }); +}); + +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: 'token'}); + }); + +}); diff --git a/dustin/routes/companies.js b/dustin/routes/companies.js index 0e18325..c3457b0 100644 --- a/dustin/routes/companies.js +++ b/dustin/routes/companies.js @@ -2,7 +2,7 @@ var express = require('express'); var router = express.Router(); const bodyParser = require('body-parser').json(); -const Company = require('../schema/companies'); +const Company = require('../model/company'); //index companies router.get('/', (req, res, next) => { @@ -13,8 +13,6 @@ router.get('/', (req, res, next) => { }); router.get('/dealstats', (req, res, next) => { - - //get tvDealValuation amount Company.find({ tvDealValuation: { $ne: true diff --git a/dustin/routes/sharks.js b/dustin/routes/sharks.js index bb5a0a9..2902cd4 100644 --- a/dustin/routes/sharks.js +++ b/dustin/routes/sharks.js @@ -2,7 +2,7 @@ var express = require('express'); var router = express.Router(); const bodyParser = require('body-parser').json(); -const Shark = require('../schema/companies'); +const Shark = require('../model/shark'); //index companies router.get('/', (req, res, next) => { diff --git a/dustin/schema/companies.js b/dustin/schema/companies.js deleted file mode 100644 index 1497e6b..0000000 --- a/dustin/schema/companies.js +++ /dev/null @@ -1,23 +0,0 @@ -'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/server.js b/dustin/server.js index a6f16b9..c1aa2fd 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -5,6 +5,7 @@ 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'); @@ -21,6 +22,7 @@ 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({ diff --git a/dustin/test/company_test.js b/dustin/test/company_test.js index 3edbe93..289bd44 100644 --- a/dustin/test/company_test.js +++ b/dustin/test/company_test.js @@ -2,7 +2,7 @@ const chai = require('chai'); const chaiHTTP = require('chai-http'); -const Company = require('../schema/companies'); +const Company = require('../model/company'); const mongoose = require('mongoose'); chai.use(chaiHTTP); const expect = chai.expect; 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 index a296683..0f8be2d 100644 --- a/dustin/test/shark_test.js +++ b/dustin/test/shark_test.js @@ -2,7 +2,7 @@ const chai = require('chai'); const chaiHTTP = require('chai-http'); -const Shark = require('../schema/sharks'); +const Shark = require('../model/shark'); const mongoose = require('mongoose'); chai.use(chaiHTTP); const expect = chai.expect; @@ -13,7 +13,7 @@ process.env.NODE_ENV = 'TEST'; process.env.MONGOLAB_URI = 'mongodb://localhost/test_db'; require('../server'); - + describe('The /shark route', () => { let testShark; beforeEach((done) => { diff --git a/dustin/test/test.js b/dustin/test/test.js deleted file mode 100644 index 7c812aa..0000000 --- a/dustin/test/test.js +++ /dev/null @@ -1,110 +0,0 @@ -// 'use strict'; -// -// const chai = require('chai'); -// const expect = require('chai').expect; -// const chaiHTTP = require('chai-http'); -// var fs = require('fs'); -// chai.use(chaiHTTP); -// const request = chai.request; -// require('../server'); -// -// var dbEntries = fs.readdirSync('./data').length; -// var payload = { -// company: 'Tanktest', -// seek_dollar: '200000', -// seek_equity: '.2', -// id: (dbEntries + 1) -// }; -// -// describe('Shark tank API should', function () { -// it('accept a POST request to /companies', function (done) { -// request('localhost:3000') -// .post('/companies') -// .send(payload) -// .end(function (err, res) { -// expect(err).to.eql(null); -// expect(res).to.have.status(200); -// expect(res.text).to.eql('{"Message":"POST received"}'); -// done(); -// }); -// }); -// -// it('list all companies in the "database"', function (done) { -// request('localhost:3000') -// .get('/companies') -// .end(function (err, res) { -// expect(err).to.eql(null); -// expect(res).to.have.status(200); -// expect(res.body.length).to.eql(dbEntries + 1); -// done(); -// }); -// }); -// -// it('list a company by id', function (done) { -// request('localhost:3000') -// .get('/companies/' + (dbEntries + 1)) -// .end(function (err, res) { -// expect(err).to.eql(null); -// expect(res).to.have.status(200); -// expect(res.body).to.eql(payload); -// done(); -// }); -// }); -// -// // it('respond to a PUT request on default route /', function (done) { -// // request('localhost:3000') -// // .put('/') -// // .end(function (err, res) { -// // expect(err).to.eql(null); -// // expect(res).to.have.status(200); -// // expect(res.text).to.eql('{"Message":"PUT request to homepage received"}'); -// // done(); -// // }); -// // }); -// -// it('properly DELETE', function (done) { -// request('localhost:3000') -// .delete('/companies/' + (dbEntries + 1)) -// .end(function (err, res) { -// expect(err).to.eql(null); -// expect(res).to.have.status(200); -// expect(res.text).to.eql('{"Message":"Entry DELETED"}'); -// done(); -// }); -// }); -// -// // -// -// // -// // it('respond to a PATCH request on default route /', function (done) { -// // request('localhost:3000') -// // .patch('/') -// // .end(function (err, res) { -// // expect(err).to.eql(null); -// // expect(res).to.have.status(200); -// // expect(res.text).to.eql('{"Message":"PATCH request to homepage received"}'); -// // done(); -// // }); -// // }); -// // -// it('respond with 404 to an invalid route', function (done) { -// request('localhost:3000') -// .get('/companies/' + (dbEntries + 1)) -// .end(function (err, res) { -// expect(res).to.have.status(404); -// expect(res.text).to.eql('{"Error":"Not Found"}'); -// done(); -// }); -// }); -// // -// // it('respond with 400 if an invalid request is made', function (done) { -// // request('localhost:3000') -// // .copy('/') -// // .end(function (err, res) { -// // expect(res).to.have.status(400); -// // expect(res.text).to.eql('{"Error":"Bad Request"}'); -// // done(); -// // }); -// // }); -// -// }); diff --git a/dustin/test/user_test.js b/dustin/test/user_test.js new file mode 100644 index 0000000..24bc90f --- /dev/null +++ b/dustin/test/user_test.js @@ -0,0 +1,63 @@ +'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 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(); + }); + }); + after((done) => { + process.env.MONGOLAB_URI = dbPort; + mongoose.connection.db.dropDatabase(() => { + done(); + }); + }); + + it('allow a known user to login', (done) => { + request('localhost:3000') + .get('/signin') + .auth('testuser', 'testuser') + .end((err, res) => { + expect(err).to.eql(null); + expect(res.body).to.have.property('token'); + done(); + }); + }); + + it('allow a new user to be created', (done) => { + request('localhost:3000') + .post('/signup') + .set('Content-Type', 'application/json') + .send({ + username: 'user', + password: 'password' + }) + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + //expect(res.body.token).to.have.eql('posty'); + expect(res.body).to.have.property('token'); + done(); + }); + }); + }); From 7c0729af31664c5e8ae87577192561cd36ed289a Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Thu, 2 Jun 2016 10:01:09 -0700 Subject: [PATCH 08/11] added support for tokens --- dustin/lib/jwt_auth.js | 27 +++++++++++++++++++++++++++ dustin/model/user.js | 7 +++++++ dustin/routes/auth.js | 6 +++--- dustin/server.js | 7 +++++++ dustin/test/user_test.js | 27 +++++++++++++++++---------- 5 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 dustin/lib/jwt_auth.js diff --git a/dustin/lib/jwt_auth.js b/dustin/lib/jwt_auth.js new file mode 100644 index 0000000..602e7f3 --- /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(tokenErr) + } + + User.findOne({ + _id: decodedToken._id + }, (err, user) => { + if (!user || err) return next(tokeErr); + req.user = user; + next(); + }) + +} diff --git a/dustin/model/user.js b/dustin/model/user.js index bc90131..d6010a7 100644 --- a/dustin/model/user.js +++ b/dustin/model/user.js @@ -2,6 +2,9 @@ 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}, @@ -12,6 +15,10 @@ 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); }; diff --git a/dustin/routes/auth.js b/dustin/routes/auth.js index c09d9c0..fd455e1 100644 --- a/dustin/routes/auth.js +++ b/dustin/routes/auth.js @@ -12,10 +12,10 @@ router.post('/signup', bodyParser, (req, res, next) => { newUser.password = hashedPassword; req.body.password = null; User.findOne({username: req.body.username}, (err, user) => { - if (err || user) return next(new Error('could not create 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: 'token'}); + res.json({token: user.generateToken()}); }); }); }); @@ -25,7 +25,7 @@ router.get('/signin', basicHTTP, (req, res, next) => { 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: 'token'}); + res.json({token: user.generateToken()}); }); }); diff --git a/dustin/server.js b/dustin/server.js index c1aa2fd..7eafbee 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -10,6 +10,7 @@ const app = express(); const mongoose = require('mongoose'); const morgan = require('morgan'); const errorHandler = require('./lib/errorhandler'); +const jwtAuth = require('./lib/jwt_auth') const dbPort = process.env.MONGOLAB_URI || 'mongodb://localhost/dev_db'; @@ -24,6 +25,12 @@ app.use('/companies', companies); app.use('/sharks', sharks); app.use('/', authRouter) + +app.post('/test', jwtAuth, (req,res) => { + res.json({message:'need a token', user:req.user}); + next(err); +}) + app.get('/*', (req, res) => { res.status(404).json({ Error: 'Not Found' diff --git a/dustin/test/user_test.js b/dustin/test/user_test.js index 24bc90f..ec82489 100644 --- a/dustin/test/user_test.js +++ b/dustin/test/user_test.js @@ -7,7 +7,9 @@ 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'; @@ -33,18 +35,21 @@ describe('User authorization should', () => { }); }); - it('allow a known user to login', (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).to.have.property('token'); + expect(res.body.token).to.eql(jwt.sign({ + _id: testUser._id + }, secret)); done(); }); }); - it('allow a new user to be created', (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') @@ -52,12 +57,14 @@ describe('User authorization should', () => { username: 'user', password: 'password' }) - .end((err, res) => { - expect(err).to.eql(null); - expect(res).to.have.status(200); - //expect(res.body.token).to.have.eql('posty'); - expect(res.body).to.have.property('token'); - done(); + .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)) + //expect(res.body).to.have.property('token'); + done(); + }); }); }); - }); +}); From 730f0c9f0a6603f0800b3c81c128c0dd61987082 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Thu, 2 Jun 2016 10:30:26 -0700 Subject: [PATCH 09/11] test --- dustin/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dustin/package.json b/dustin/package.json index 3c8d078..9613f8a 100644 --- a/dustin/package.json +++ b/dustin/package.json @@ -24,10 +24,11 @@ "really-need": "^1.9.2" }, "dependencies": { + "bcrypt": "^0.8.6", "body-parser": "^1.15.1", "express": "^4.13.4", - "bcrypt": "^0.8.6", "json-fs-store": "^1.0.0", + "jsonwebtoken": "^7.0.0", "mongoose": "^4.4.19" } } From 0a3a6270d6560158147dfb841c6bf32badca39b1 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Thu, 2 Jun 2016 15:46:21 -0700 Subject: [PATCH 10/11] adding travis --- dustin/.travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 dustin/.travis.yml 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 From 7d17df0114e82e36554eb299a896e464d1c4e904 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Fri, 3 Jun 2016 11:27:26 -0700 Subject: [PATCH 11/11] added auth --- dustin/.eslintignore | 5 +++++ dustin/.eslintrc | 41 +++++++++++++++++++++++++++++++++++++ dustin/gulpfile.js | 2 +- dustin/lib/basic_auth.js | 2 +- dustin/lib/errorhandler.js | 1 + dustin/lib/jwt_auth.js | 16 +++++++-------- dustin/routes/companies.js | 14 ++++++++----- dustin/routes/sharks.js | 9 ++++---- dustin/server.js | 13 ++---------- dustin/test/company_test.js | 21 ++++++++++++++++++- dustin/test/shark_test.js | 25 +++++++++++++++++++--- dustin/test/user_test.js | 14 ++++++++----- 12 files changed, 124 insertions(+), 39 deletions(-) create mode 100644 dustin/.eslintignore create mode 100644 dustin/.eslintrc 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/gulpfile.js b/dustin/gulpfile.js index 0c58bb1..713267f 100644 --- a/dustin/gulpfile.js +++ b/dustin/gulpfile.js @@ -2,7 +2,7 @@ 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' ] +//var js = ['./model/**/*.js', './lib/**/*.js', './routes/**/*.js', './test/**/*.js', './*.js' ] gulp.task('linter' , () => { return gulp.src(['./*.js', './test/*.js', './lib/*.js']) diff --git a/dustin/lib/basic_auth.js b/dustin/lib/basic_auth.js index f46c77d..b2bb8f8 100644 --- a/dustin/lib/basic_auth.js +++ b/dustin/lib/basic_auth.js @@ -16,4 +16,4 @@ module.exports = function(req, res, next) { } next(); -} +}; diff --git a/dustin/lib/errorhandler.js b/dustin/lib/errorhandler.js index 5e09b43..9256fc5 100644 --- a/dustin/lib/errorhandler.js +++ b/dustin/lib/errorhandler.js @@ -2,4 +2,5 @@ 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 index 602e7f3..2234fe9 100644 --- a/dustin/lib/jwt_auth.js +++ b/dustin/lib/jwt_auth.js @@ -1,11 +1,11 @@ -'use strict' +'use strict'; var jwt = require('jsonwebtoken'); var User = require('../model/user'); -const secret = process.env.SECRET || 'changeme' +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 token = req.headers.token || req.headers.token; + let tokenErr = new Error('Authorization Failure'); let decodedToken; if (!token) return next(tokenErr); @@ -13,15 +13,15 @@ module.exports = function (req, res, next) { try { decodedToken = jwt.verify(token, secret); } catch (e) { - return next(tokenErr) + return next(e); } User.findOne({ _id: decodedToken._id }, (err, user) => { - if (!user || err) return next(tokeErr); + if (!user || err) return next(err); req.user = user; next(); - }) + }); -} +}; diff --git a/dustin/routes/companies.js b/dustin/routes/companies.js index c3457b0..1c94dd2 100644 --- a/dustin/routes/companies.js +++ b/dustin/routes/companies.js @@ -3,16 +3,20 @@ 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('/', (req, res, next) => { +router.get('/', jwtAuth, (req, res, next) => { Company.find({}, (err, companies) => { if (err) return next(err); res.json(companies); }); }); -router.get('/dealstats', (req, res, next) => { +router.get('/dealstats', jwtAuth, (req, res, next) => { Company.find({ tvDealValuation: { $ne: true @@ -29,7 +33,7 @@ router.get('/dealstats', (req, res, next) => { }); //create companies -router.post('/', bodyParser, (req, res, next) => { +router.post('/', bodyParser, jwtAuth, (req, res, next) => { let newCompany = new Company(req.body); newCompany.save((err, company) => { if (err) return next(err); @@ -38,7 +42,7 @@ router.post('/', bodyParser, (req, res, next) => { }); //put company -router.put('/', bodyParser, (req, res, next) => { +router.put('/', bodyParser, jwtAuth, (req, res, next) => { let _id = req.body._id; Company.findOneAndUpdate({ _id @@ -52,7 +56,7 @@ router.put('/', bodyParser, (req, res, next) => { }); //delete companies -router.delete('/:id', (req, res, next) => { +router.delete('/:id', jwtAuth, (req, res, next) => { let _id = req.params.id; Company.findOneAndRemove({ _id diff --git a/dustin/routes/sharks.js b/dustin/routes/sharks.js index 2902cd4..c380d4c 100644 --- a/dustin/routes/sharks.js +++ b/dustin/routes/sharks.js @@ -3,9 +3,10 @@ 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('/', (req, res, next) => { +router.get('/', jwtAuth, (req, res, next) => { Shark.find({}, (err, companies) => { if (err) return next(err); res.json(companies); @@ -13,7 +14,7 @@ router.get('/', (req, res, next) => { }); //create companies -router.post('/', bodyParser, (req, res, next) => { +router.post('/', bodyParser, jwtAuth, (req, res, next) => { let newShark = new Shark(req.body); newShark.save((err, shark) => { if (err) return next(err); @@ -22,7 +23,7 @@ router.post('/', bodyParser, (req, res, next) => { }); //put shark -router.put('/', bodyParser, (req, res, next) => { +router.put('/', bodyParser, jwtAuth, (req, res, next) => { let _id = req.body._id; Shark.findOneAndUpdate({_id}, req.body, (err) => { if (err) return next(err); @@ -34,7 +35,7 @@ router.put('/', bodyParser, (req, res, next) => { }); //delete companies -router.delete('/:id', (req, res, next) => { +router.delete('/:id', jwtAuth, (req, res, next) => { let _id = req.params.id; Shark.findOneAndRemove({ _id diff --git a/dustin/server.js b/dustin/server.js index 7eafbee..a4f9b0a 100644 --- a/dustin/server.js +++ b/dustin/server.js @@ -5,17 +5,14 @@ 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 authRouter = require('./routes/auth'); const app = express(); const mongoose = require('mongoose'); const morgan = require('morgan'); const errorHandler = require('./lib/errorhandler'); -const jwtAuth = require('./lib/jwt_auth') 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); @@ -23,13 +20,7 @@ app.use(jsonPaser); app.use('/', routes); app.use('/companies', companies); app.use('/sharks', sharks); -app.use('/', authRouter) - - -app.post('/test', jwtAuth, (req,res) => { - res.json({message:'need a token', user:req.user}); - next(err); -}) +app.use('/', authRouter); app.get('/*', (req, res) => { res.status(404).json({ diff --git a/dustin/test/company_test.js b/dustin/test/company_test.js index 289bd44..b7e8463 100644 --- a/dustin/test/company_test.js +++ b/dustin/test/company_test.js @@ -3,10 +3,13 @@ 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'; @@ -16,7 +19,17 @@ 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, @@ -91,12 +104,14 @@ describe('The /company route', () => { }); }); - it('GET should return a list of companies', () => { + 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(); }); }); @@ -106,6 +121,7 @@ describe('The /company route', () => { .send({ name: 'posty' }) + .set('token', token) .end((err, res) => { expect(err).to.eql(null); expect(res).to.have.status(200); @@ -120,6 +136,7 @@ describe('The /company route', () => { request('localhost:3000') .put('/companies/') .send(testCompany) + .set('token', token) .end((err, res) => { expect(err).to.eql(null); expect(res).to.have.status(200); @@ -131,6 +148,7 @@ describe('The /company route', () => { 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); @@ -142,6 +160,7 @@ describe('The /company route', () => { 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); diff --git a/dustin/test/shark_test.js b/dustin/test/shark_test.js index 0f8be2d..a79723a 100644 --- a/dustin/test/shark_test.js +++ b/dustin/test/shark_test.js @@ -7,16 +7,30 @@ 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' }); @@ -25,25 +39,28 @@ describe('The /shark route', () => { done(); }); }); - after((done) => { + afterEach((done) => { process.env.MONGOLAB_URI = dbPort; mongoose.connection.db.dropDatabase(() => { done(); }); }); - it('GET should return a list of sharks', () => { + 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' }) @@ -61,6 +78,7 @@ describe('The /shark route', () => { request('localhost:3000') .put('/sharks/') .send(testShark) + .set('token', token) .end((err, res) => { expect(err).to.eql(null); expect(res).to.have.status(200); @@ -72,6 +90,7 @@ describe('The /shark route', () => { 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); diff --git a/dustin/test/user_test.js b/dustin/test/user_test.js index ec82489..25a1964 100644 --- a/dustin/test/user_test.js +++ b/dustin/test/user_test.js @@ -9,7 +9,7 @@ const expect = chai.expect; const request = chai.request; const jwt = require('jsonwebtoken'); -const secret = process.env.SECRET || 'changeme' +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'; @@ -28,7 +28,7 @@ describe('User authorization should', () => { done(); }); }); - after((done) => { + afterEach((done) => { process.env.MONGOLAB_URI = dbPort; mongoose.connection.db.dropDatabase(() => { done(); @@ -57,12 +57,16 @@ describe('User authorization should', () => { username: 'user', password: 'password' }) - .end((err, res) => {User.find({username: 'user'}, (err, user) => { + .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)) - //expect(res.body).to.have.property('token'); + expect(res.body.token).to.eql(jwt.sign({ + _id: user[0]._id + }, secret)); done(); }); });