From ef5853da4f1b7425c6e2ad40443461fc95eca5e4 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 18:25:52 -0800 Subject: [PATCH 1/9] basic setup and server.js file --- lab-megan/.eslintrc | 21 ++++++ lab-megan/.gitignore | 147 +++++++++++++++++++++++++++++++++++++++++ lab-megan/gulpfile.js | 24 +++++++ lab-megan/package.json | 30 +++++++++ lab-megan/server.js | 15 +++++ 5 files changed, 237 insertions(+) create mode 100644 lab-megan/.eslintrc create mode 100644 lab-megan/.gitignore create mode 100644 lab-megan/gulpfile.js create mode 100644 lab-megan/package.json create mode 100644 lab-megan/server.js diff --git a/lab-megan/.eslintrc b/lab-megan/.eslintrc new file mode 100644 index 0000000..8dc6807 --- /dev/null +++ b/lab-megan/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/lab-megan/.gitignore b/lab-megan/.gitignore new file mode 100644 index 0000000..04d4cc4 --- /dev/null +++ b/lab-megan/.gitignore @@ -0,0 +1,147 @@ +Skip to content +This repository +Search +Pull requests +Issues +Gist + @meganreardon + Watch 5 + Star 1 + Fork 3 codefellows/seattle-javascript-401d12 + Code Issues 0 Pull requests 0 Projects 0 Wiki Pulse Graphs +Branch: master Find file Copy pathseattle-javascript-401d12/02-build_automation_and_dependency_management/lecture/demo/hello-world-gulp/.gitignore +b2d8bee 41 minutes ago +@bnates bnates added lecture 2 material +1 contributor +RawBlameHistory +128 lines (94 sloc) 1.85 KB +# Created by https://www.gitignore.io/api/node,vim,macos,linux,windows + +node_modules/ + +### Node ### +# Logs +logs +*.log +npm-debug.log* +data + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + + +### Vim ### +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + + +### macOS ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk +Contact GitHub API Training Shop Blog About +© 2016 GitHub, Inc. Terms Privacy Security Status Help diff --git a/lab-megan/gulpfile.js b/lab-megan/gulpfile.js new file mode 100644 index 0000000..93ef0cd --- /dev/null +++ b/lab-megan/gulpfile.js @@ -0,0 +1,24 @@ + +'use strict'; + +const gulp = require('gulp'); +const eslint = require('gulp-eslint'); +const mocha = require('gulp-mocha'); + +gulp.task('test', function() { + gulp.src('./test/*-test.js', { read: false }) + .pipe(mocha({ reporter: 'spec'})); +}); + +gulp.task('lint', function(){ + return gulp.src(['**/*.js', '!node_modules/**']) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); + +gulp.task('dev', function() { + gulp.watch(['**/*.js', '!node_modules/**'], ['lint', 'test']); +}); + +gulp.task('default', ['dev']); diff --git a/lab-megan/package.json b/lab-megan/package.json new file mode 100644 index 0000000..b9a9aef --- /dev/null +++ b/lab-megan/package.json @@ -0,0 +1,30 @@ +{ + "name": "lab-megan", + "version": "1.0.0", + "description": "", + "main": "gulpfile.js", + "directories": { + "test": "test" + }, + "scripts": { + "start": "DEBUG='note*' node server.js", + "test": "DEBUG='note*' mocha" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "bluebird": "^3.4.6", + "body-parser": "^1.15.2", + "debug": "^2.4.5", + "express": "^4.14.0", + "http-errors": "^1.5.1", + "morgan": "^1.7.0", + "node-uuid": "^1.4.7" + }, + "devDependencies": { + "chai": "^3.5.0", + "mocha": "^3.2.0", + "superagent": "^3.3.1" + } +} diff --git a/lab-megan/server.js b/lab-megan/server.js new file mode 100644 index 0000000..e769120 --- /dev/null +++ b/lab-megan/server.js @@ -0,0 +1,15 @@ +'use strict'; + +const morgan = require('morgan'); +const express = require('express'); +const createError = require('http-errors'); +const debug = require('debug')('note:server'); + +const PORT = process.env.PORT || 3000; +const app = express(); + +app.use(morgan('dev')); + +app.listen(PORT, () => { + console.log(`server up at: ${PORT}`); +}); From 11847c96c76adc6d8c30a755c959d58748820508 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 19:46:18 -0800 Subject: [PATCH 2/9] created the model and storage files --- lab-megan/lib/storage.js | 58 ++++++++++++++++++++++++++++++++++++++++ lab-megan/model/hat.js | 57 +++++++++++++++++++++++++++++++++++++++ lab-megan/package.json | 4 +-- lab-megan/server.js | 2 +- 4 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 lab-megan/lib/storage.js create mode 100644 lab-megan/model/hat.js diff --git a/lab-megan/lib/storage.js b/lab-megan/lib/storage.js new file mode 100644 index 0000000..83c183a --- /dev/null +++ b/lab-megan/lib/storage.js @@ -0,0 +1,58 @@ +'use strict'; + +const Promise = require('bluebird'); +const fs = Promise.promisifyAll(require('fs'), {suffix: 'Prom'}); +const createError = require('http-errors'); +const debug = require('debug')('hat:storage'); + +module.exports = exports = {}; + +exports.createItem = function(schemaName, item){ + debug('createItem'); + + if (!schemaName) return Promise.reject(createError(400, 'expected schema name')); + if (!item) return Promise.reject(createError(400, 'expected item')); + + let json = JSON.stringify(item); + return fs.writeFileProm(`${__dirname}/../data/${schemaName}/${item.id}.json`, json) + .then( () => item) + .catch( err => Promise.reject(createError(500, err.message))); +}; + +exports.fetchItem = function(schemaName, id){ + debug('fetchItem'); + + if (!schemaName) return Promise.reject(createError(400, 'expected schema name')); + if (!id) return Promise.reject(createError(400, 'expected id')); + + return fs.readFileProm(`${__dirname}/../data/${schemaName}/${id}.json`) + .then(data => { + try { + let item = JSON.parse(data.toString()); + return item; + } catch (err) { + return Promise.reject(createError(500, err.message)); + } + }) + .catch(err => Promise.reject(createError(404, err.message))); +}; + +exports.deleteItem = function(schemaName, id) { + debug('deleteItem'); + + if (!schemaName) return Promise.reject(createError(400, 'expected schema name')); + if (!id) return Promise.reject(createError(400, 'expected id')); + + return fs.unlinkProm(`${__dirname}/../data/${schemaName}/${id}.json`) + .catch( err => Promise.reject(createError(404, err.message))); +}; + +exports.availIDs = function(schemaName) { + debug('availIDs'); // NOTE: I added this line + + if (!schemaName) return Promise.reject(createError(400, 'expected schema name')); // NOTE: I added this line + + return fs.readdirProm(`${__dirname}/../data/${schemaName}`) + .then ( files => files.map(name => name.split('.json')[0])) + .catch( err => Promise.reject(createError(404, err.message))); +}; diff --git a/lab-megan/model/hat.js b/lab-megan/model/hat.js new file mode 100644 index 0000000..ed040d8 --- /dev/null +++ b/lab-megan/model/hat.js @@ -0,0 +1,57 @@ +'use strict'; + +const uuid = require('node-uuid'); +const createError = require('http-errors'); +const debug = require('debug')('hat:hat'); +const storage = require('../lib/storage.js'); + +const Hat = module.exports = function(color, style) { + debug('hat constructor'); + + if (!color) throw createError(400, 'expected color'); + if (!style) throw createError(400, 'expected style'); + + this.id = uuid.v1(); + this.color = color; + this.style = style; +}; + +Hat.createHat = function(_hat) { + debug('createHat'); + + try { + let hat = new Hat(_hat.name, _hat.style); + return storage.createItem('hat', hat); + } catch (err) { + return Promise.reject(createError(400, 'err.message')); + } +}; + +Hat.fetchHat = function(id) { + debug('fetchHat'); + return storage.fetchItem('hat', id); +}; + +Hat.updateHat = function(id, _hat) { + debug('updateHat'); + + return storage.fetchItm('hat', id) + .catch( err => Promise.reject(createError(404, err.message))) + .then( note => { + for (var prop in note) { + if (prop === 'id') continue; + if (_hat[prop]) hat[prop] = _hat[prop]; + } + return storage.createItem('hat', hat); + }); +}; + +Hat.deleteHat = function(id) { + debug('deleteHat'); + return storage.deleteItem('hat', id); +}; + +Hat.fetchIDs = function() { + debug('fetchIDs'); + return storage.availIDs('hat'); +}; diff --git a/lab-megan/package.json b/lab-megan/package.json index b9a9aef..7285805 100644 --- a/lab-megan/package.json +++ b/lab-megan/package.json @@ -7,8 +7,8 @@ "test": "test" }, "scripts": { - "start": "DEBUG='note*' node server.js", - "test": "DEBUG='note*' mocha" + "start": "DEBUG='hat*' node server.js", + "test": "DEBUG='hat*' mocha" }, "keywords": [], "author": "", diff --git a/lab-megan/server.js b/lab-megan/server.js index e769120..cdf4b2e 100644 --- a/lab-megan/server.js +++ b/lab-megan/server.js @@ -3,7 +3,7 @@ const morgan = require('morgan'); const express = require('express'); const createError = require('http-errors'); -const debug = require('debug')('note:server'); +const debug = require('debug')('hat:server'); const PORT = process.env.PORT || 3000; const app = express(); From 8b640db58e22e6037f4bc58d58a94b0bc7306c74 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 19:59:43 -0800 Subject: [PATCH 3/9] added cors and error middleware --- lab-megan/lib/cors-middleware.js | 7 +++++++ lab-megan/lib/error-middleware.js | 21 +++++++++++++++++++++ lab-megan/server.js | 4 ++++ 3 files changed, 32 insertions(+) create mode 100644 lab-megan/lib/cors-middleware.js create mode 100644 lab-megan/lib/error-middleware.js diff --git a/lab-megan/lib/cors-middleware.js b/lab-megan/lib/cors-middleware.js new file mode 100644 index 0000000..6661797 --- /dev/null +++ b/lab-megan/lib/cors-middleware.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function(req, res, next) { + res.append('Access-Control-Allow-Origin', '*'); + res.append('Access-Control-Allow-Headers', '*'); + next(); +}; diff --git a/lab-megan/lib/error-middleware.js b/lab-megan/lib/error-middleware.js new file mode 100644 index 0000000..2247d3b --- /dev/null +++ b/lab-megan/lib/error-middleware.js @@ -0,0 +1,21 @@ +'use strict'; + +const createError = require('http-errors'); +const debug = require('debug')('note:error-middleware'); + +module.exports = function(err, req, res, next) { + console.error(err.message); + + if (err.status) { + debug('user error'); + + res.status(err.status).send(err.name); + next(); + return; + } + + debug('server error'); + err = createError(500, err.message); + res.status(err.status).send(err.name); + next(); +}; diff --git a/lab-megan/server.js b/lab-megan/server.js index cdf4b2e..0d36018 100644 --- a/lab-megan/server.js +++ b/lab-megan/server.js @@ -3,12 +3,16 @@ const morgan = require('morgan'); const express = require('express'); const createError = require('http-errors'); +const cors = require('./lib/cors-middleware.js'); +const errors = require('./lib/error-middleware.js'); const debug = require('debug')('hat:server'); const PORT = process.env.PORT || 3000; const app = express(); app.use(morgan('dev')); +app.use(cors); +app.use(errors); app.listen(PORT, () => { console.log(`server up at: ${PORT}`); From 0af22c0daada05ff3489bf87ec8e32058f19debc Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 20:28:30 -0800 Subject: [PATCH 4/9] created router and required into files where needed --- lab-megan/lib/error-middleware.js | 2 +- lab-megan/model/hat.js | 4 +-- lab-megan/route/hat-router.js | 41 +++++++++++++++++++++++++++++++ lab-megan/server.js | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 lab-megan/route/hat-router.js diff --git a/lab-megan/lib/error-middleware.js b/lab-megan/lib/error-middleware.js index 2247d3b..7efa009 100644 --- a/lab-megan/lib/error-middleware.js +++ b/lab-megan/lib/error-middleware.js @@ -1,7 +1,7 @@ 'use strict'; const createError = require('http-errors'); -const debug = require('debug')('note:error-middleware'); +const debug = require('debug')('hat:error-middleware'); module.exports = function(err, req, res, next) { console.error(err.message); diff --git a/lab-megan/model/hat.js b/lab-megan/model/hat.js index ed040d8..9f5acf0 100644 --- a/lab-megan/model/hat.js +++ b/lab-megan/model/hat.js @@ -37,8 +37,8 @@ Hat.updateHat = function(id, _hat) { return storage.fetchItm('hat', id) .catch( err => Promise.reject(createError(404, err.message))) - .then( note => { - for (var prop in note) { + .then( hat => { + for (var prop in hat) { if (prop === 'id') continue; if (_hat[prop]) hat[prop] = _hat[prop]; } diff --git a/lab-megan/route/hat-router.js b/lab-megan/route/hat-router.js new file mode 100644 index 0000000..ab3ad92 --- /dev/null +++ b/lab-megan/route/hat-router.js @@ -0,0 +1,41 @@ +'use strict'; + +const Router = require('express').Router; +const jsonParser = require('body-parser').json(); +const debug = require('debug')('hat:hat-router'); +const Hat = require('../model/hat.js'); +const hatRouter = new Router(); + +hatRouter.post('/api/hat', jsonParser, function(req, res, next) { + debug('POST: /api/hat'); + + Hat.createHat(req.body) + .then( hat => res.json(hat)) + .catch( err => next(err)); +}); + +hatRouter.get('/api/hat/:id', function(req, res, next) { + debug('GET: /api/hat/:id'); + + Hat.fetchHat(req.params.id) + .then( hat => res.json(hat)) + .catch( err => next(err)); +}); + +hatRouter.get('/api/hat', function(req, res, next) { + debug('GET: /api/hat'); + + Hat.fetchIDs() + .then( ids => res.json(ids)) + .catch(next); +}); + +hatRouter.put('/api/hat', jsonParser, function(req, res, next) { + debug('PUT: /api/hat'); + + Hat.updateHat(req.query.id, req.body) + .then( hat => res.json(hat)) + .catch(next); +}); + +module.exports = hatRouter; diff --git a/lab-megan/server.js b/lab-megan/server.js index 0d36018..e8ab634 100644 --- a/lab-megan/server.js +++ b/lab-megan/server.js @@ -6,12 +6,14 @@ const createError = require('http-errors'); const cors = require('./lib/cors-middleware.js'); const errors = require('./lib/error-middleware.js'); const debug = require('debug')('hat:server'); +const hatRouter = require('./route/hat-router.js'); const PORT = process.env.PORT || 3000; const app = express(); app.use(morgan('dev')); app.use(cors); +app.use(hatRouter); app.use(errors); app.listen(PORT, () => { From 5cf67b7fa049c3a85a10b74bd4fb10a589bfeb7a Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 20:35:48 -0800 Subject: [PATCH 5/9] added tests --- lab-megan/test/hat-route-test.js | 118 +++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 lab-megan/test/hat-route-test.js diff --git a/lab-megan/test/hat-route-test.js b/lab-megan/test/hat-route-test.js new file mode 100644 index 0000000..375b00a --- /dev/null +++ b/lab-megan/test/hat-route-test.js @@ -0,0 +1,118 @@ +'use strict'; + +const expect = require('chai').expect; +const request = require('superagent'); +const Hat = require('../model/hat.js'); +const url = 'http://localhost:8000'; + +require('../server.js'); + +const exampleHat = { + name: 'example name', + content: 'example content' +}; + +describe('Hat Routes', function() { + + describe('GET: /api/hat', function() { + describe('with a valid id', function() { + before( done => { + Hat.createHat(exampleHat) + .then(hat => { + this.tempHat = hat; + done(); + }) + .catch( err => done(err)); + }); + + after( done => { + Hat.deleteHat(this.tempHat.id) + .then( ()=> done()) + .catch( err => done(err)); + }); + + it('should return a hat', done => { + request.get(`${url}/api/hat/${this.tempHat.id}`) + .end((err, res) => { + if (err) return done(err); + expect(res.status).to.equal(200); + expect(res.body.id).to.equal(this.tempHat.id); + expect(res.body.name).to.equal(this.tempHat.name); + expect(res.body.content).to.equal(this.tempHat.content); + done(); + }); + }); + + describe('with an invalid id', function() { + it('should respond with a 404 status code', done => { + request.get(`${url}/api/hat/123456789`) + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + }); + }); + }); + + describe('POST: /api/hat', function() { + describe('with a valid body', function() { + after( done => { + if (this.tempHat) { + Hat.deleteHat(this.tempHat.id) + .then( ()=> done()) + .catch( err => done(err)); + } + }); + + it('should return a hat', done => { + request.post(`${url}/api/hat`) + .send(exampleHat) + .end((err, res) => { + if (err) return done(err); + expect(res.status).to.equal(200); + expect(res.body.name).to.equal(exampleHat.name); + expect(res.body.content).to.equal(exampleHat.content); + this.tempHat = res.body; + done(); + }); + }); + }); + }); + + describe('PUT: /api/hat', function() { + describe('with a valid id and body', function() { + before( done => { + Hat.createHat(exampleHat) + .then( hat => { + this.tempHat = hat; + done(); + }) + .catch( err => done(err)); + }); + + after( done => { + if (this.tempHat) { + Hat.deleteHat(this.tempHat.id) + .then( ()=> done()) + .catch(done); + } + }); + + it('should return a hat', done => { + let updateHat = { name: 'new name', content: 'new content' }; + request.put(`${url}/api/hat?id=${this.tempHat.id}`) + .send(updateHat) + .end((err, res) => { + if (err) return done(err); + expect(res.status).to.equal(200); + expect(res.body.id).to.equal(this.tempHat.id); + for (var prop in updateHat) { + expect(res.body[prop]).to.equal(updateHat[prop]); + } + done(); + }); + }); + }); + }); +}); From e8726e1ab1f3cdc7285261555da87471babe4ac9 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 21:15:07 -0800 Subject: [PATCH 6/9] created tests all passing --- lab-megan/lib/storage.js | 2 +- lab-megan/model/hat.js | 4 ++-- lab-megan/test/hat-route-test.js | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lab-megan/lib/storage.js b/lab-megan/lib/storage.js index 83c183a..a29eaa5 100644 --- a/lab-megan/lib/storage.js +++ b/lab-megan/lib/storage.js @@ -53,6 +53,6 @@ exports.availIDs = function(schemaName) { if (!schemaName) return Promise.reject(createError(400, 'expected schema name')); // NOTE: I added this line return fs.readdirProm(`${__dirname}/../data/${schemaName}`) - .then ( files => files.map(name => name.split('.json')[0])) + .then ( files => files.map(color => color.split('.json')[0])) .catch( err => Promise.reject(createError(404, err.message))); }; diff --git a/lab-megan/model/hat.js b/lab-megan/model/hat.js index 9f5acf0..50d5f0a 100644 --- a/lab-megan/model/hat.js +++ b/lab-megan/model/hat.js @@ -20,7 +20,7 @@ Hat.createHat = function(_hat) { debug('createHat'); try { - let hat = new Hat(_hat.name, _hat.style); + let hat = new Hat(_hat.color, _hat.style); return storage.createItem('hat', hat); } catch (err) { return Promise.reject(createError(400, 'err.message')); @@ -35,7 +35,7 @@ Hat.fetchHat = function(id) { Hat.updateHat = function(id, _hat) { debug('updateHat'); - return storage.fetchItm('hat', id) + return storage.fetchItem('hat', id) .catch( err => Promise.reject(createError(404, err.message))) .then( hat => { for (var prop in hat) { diff --git a/lab-megan/test/hat-route-test.js b/lab-megan/test/hat-route-test.js index 375b00a..49962fb 100644 --- a/lab-megan/test/hat-route-test.js +++ b/lab-megan/test/hat-route-test.js @@ -3,13 +3,13 @@ const expect = require('chai').expect; const request = require('superagent'); const Hat = require('../model/hat.js'); -const url = 'http://localhost:8000'; +const url = 'http://localhost:3000'; require('../server.js'); const exampleHat = { - name: 'example name', - content: 'example content' + color: 'example color', + style: 'example style' }; describe('Hat Routes', function() { @@ -37,8 +37,8 @@ describe('Hat Routes', function() { if (err) return done(err); expect(res.status).to.equal(200); expect(res.body.id).to.equal(this.tempHat.id); - expect(res.body.name).to.equal(this.tempHat.name); - expect(res.body.content).to.equal(this.tempHat.content); + expect(res.body.color).to.equal(this.tempHat.color); + expect(res.body.style).to.equal(this.tempHat.style); done(); }); }); @@ -71,8 +71,8 @@ describe('Hat Routes', function() { .end((err, res) => { if (err) return done(err); expect(res.status).to.equal(200); - expect(res.body.name).to.equal(exampleHat.name); - expect(res.body.content).to.equal(exampleHat.content); + expect(res.body.color).to.equal(exampleHat.color); + expect(res.body.style).to.equal(exampleHat.style); this.tempHat = res.body; done(); }); @@ -100,7 +100,7 @@ describe('Hat Routes', function() { }); it('should return a hat', done => { - let updateHat = { name: 'new name', content: 'new content' }; + let updateHat = { color: 'new color', style: 'new style' }; request.put(`${url}/api/hat?id=${this.tempHat.id}`) .send(updateHat) .end((err, res) => { From e182eb06feeb5ef7a70d0ae29602edf1bbb09c1f Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 21:47:35 -0800 Subject: [PATCH 7/9] adding readme file --- lab-megan/README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lab-megan/README.md diff --git a/lab-megan/README.md b/lab-megan/README.md new file mode 100644 index 0000000..ae879ba --- /dev/null +++ b/lab-megan/README.md @@ -0,0 +1,44 @@ +### ABOUT THIS PROJECT + +This is a simple Express router built as part of the Code Fellows 401 JavaScript class. It uses Express to handle middleware and routing, in this case I'm keeping track of hats with a color and style. + +### HOW TO GET THE API RUNNING + +Clone this repository. +```JavaScript +cd lab-megan + +npm i +``` +To get needed Node dependencies. + +In one terminal window: +```JavaScript +nmp run start +``` + +### HOW TO USE THE API + +With this API you can create, view and delete the records of various hat. To do so get the server running in a terminal window and open a second terminal window and do the following + +To create a hat +`http POST localhost:3000/api/hat color='' style=''` +This will return your color, style and a unique id. + +Note: If your server shows it is running on a different port please use that one instead. + + +To view the record of a hat +`http localhost:3000/api/hat?id=` +This will return the color and style of the requested id. + +To delete the record of a hat +`http DELETE localchost:3000/api/hat?id=` +This will return a 204 message to confirm any record of the had has been deleted. + +### HOW TO INCLUDE IN YOUR PROJECT + +```JavaScript +npm i -D chai mocha superagent +npm run test +``` From e76b7763674e67f1a8209a23a936985b3de57f02 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Tue, 20 Dec 2016 21:51:12 -0800 Subject: [PATCH 8/9] updated readme --- lab-megan/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lab-megan/README.md b/lab-megan/README.md index ae879ba..cd20c68 100644 --- a/lab-megan/README.md +++ b/lab-megan/README.md @@ -21,18 +21,18 @@ nmp run start With this API you can create, view and delete the records of various hat. To do so get the server running in a terminal window and open a second terminal window and do the following -To create a hat +- To create a hat `http POST localhost:3000/api/hat color='' style=''` This will return your color, style and a unique id. Note: If your server shows it is running on a different port please use that one instead. -To view the record of a hat +- To view the record of a hat `http localhost:3000/api/hat?id=` This will return the color and style of the requested id. -To delete the record of a hat +- To delete the record of a hat `http DELETE localchost:3000/api/hat?id=` This will return a 204 message to confirm any record of the had has been deleted. From 9b8c7bb497de88f00fee343f52b9348e6f1ea1b5 Mon Sep 17 00:00:00 2001 From: Megan Reardon Date: Wed, 21 Dec 2016 11:18:55 -0800 Subject: [PATCH 9/9] added more tests --- lab-megan/test/hat-route-test.js | 71 ++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/lab-megan/test/hat-route-test.js b/lab-megan/test/hat-route-test.js index 49962fb..b61412a 100644 --- a/lab-megan/test/hat-route-test.js +++ b/lab-megan/test/hat-route-test.js @@ -14,6 +14,10 @@ const exampleHat = { describe('Hat Routes', function() { +// --------- +// GET tests +// --------- + describe('GET: /api/hat', function() { describe('with a valid id', function() { before( done => { @@ -52,9 +56,24 @@ describe('Hat Routes', function() { }); }); }); + + describe('with an invalid path', function() { + it('should respond with a 404 status code', done => { + request.get(`${url}/api/boots/123456789`) + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + }); + }); }); +// ---------- +// POST tests +// ---------- + describe('POST: /api/hat', function() { describe('with a valid body', function() { after( done => { @@ -77,9 +96,36 @@ describe('Hat Routes', function() { done(); }); }); + + describe('with no content', function() { + it('should respond with a 400 status code', done => { + request.post(`${url}/api/hat`) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.text).to.include('BadRequestError'); + done(); + }); + }); + }); + + describe('with an invalid path', function() { + it('should respond with 404 error code', done => { + request.post(`${url}/api/boots`) + .send(exampleHat) + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + }); + }); }); +// --------- +// PUT tests +// --------- + describe('PUT: /api/hat', function() { describe('with a valid id and body', function() { before( done => { @@ -113,6 +159,31 @@ describe('Hat Routes', function() { done(); }); }); + + describe('with an invalid id', function() { + it('should respond with a 404 status code', done => { + let updateHat = { color: 'new color', style: 'new style' }; + request.put(`${url}/api/hat?id=123456789`) + .send(updateHat) + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + }); + + describe('with an invalid path', function() { + it('should respond with 404 error code', done => { + let updateHat = { color: 'new color', style: 'new style' }; + request.put(`${url}/api/boots`) + .send(updateHat) + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + }); + }); }); });