From 31e7f67d542d84aee77ba5b7ed1f447b681ad1f2 Mon Sep 17 00:00:00 2001 From: andyfiveeleven Date: Thu, 27 Jul 2017 13:11:25 -0700 Subject: [PATCH 1/2] gitignore, scafoold --- .gitignore | 1 + README.md | 57 ++++++++++++++++++-------- lib/parse-json.js | 31 ++++++++++++++ lib/parse-url.js | 10 +++++ lib/response.js | 0 lib/router.js | 62 ++++++++++++++++++++++++++++ lib/storage.js | 48 ++++++++++++++++++++++ model/hike.js | 16 ++++++++ package.json | 33 +++++++++++++++ route/hike-route.js | 0 server.js | 89 +++++++++++++++++++++++++++++++++++++++++ test/hike-route-test.js | 73 +++++++++++++++++++++++++++++++++ 12 files changed, 404 insertions(+), 16 deletions(-) create mode 100644 .gitignore create mode 100644 lib/parse-json.js create mode 100644 lib/parse-url.js create mode 100644 lib/response.js create mode 100644 lib/router.js create mode 100644 lib/storage.js create mode 100644 model/hike.js create mode 100644 package.json create mode 100644 route/hike-route.js create mode 100644 server.js create mode 100644 test/hike-route-test.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md index 0aaf9f2..994c94e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![cf](https://i.imgur.com/7v5ASc8.png) Lab 09: Vanilla REST API w/ Persistence +![cf](https://i.imgur.com/7v5ASc8.png) Lab 08: Vanilla REST API ====== ## Submission Instructions @@ -10,23 +10,48 @@ * write a question and observation on canvas ## Learning Objectives -* students will learn how to save resource data to the file system for a layer of data persistence -* students will learn how to refactor commonly used coding constructs into custom helper modules +* students will learn to use promise constructs to manage asynchronous code +* students will learn to create a vanilla RESTful API with in-memory persistence ## Requirements - #### Configuration -* `package.json` -* `.eslintrc` -* `.gitignore` -* `README.md` - * your `README.md` should include detailed instructions on how to use your API - * this should include documentation on how to access your API endpoints + * `.gitignore` + * `.eslintrc` + * `package.json` + * `README.md` #### Feature Tasks -* continue working on your vanilla REST API -* refactor your routes to be contained in a separate module (ex: `route/resource-route.js`) -* refactor your `res` messages & status codes to be contained in a separate module (ex: `response.js`) -* refactor the `storage.js` module to use file system persistence - * use the `fs` module to create and read the associated data files - * the name of the file should contain the related resource id +* create the following directories to organize your code: + * `lib` + * `model` + * `test` +* create an HTTP server using the native NodeJS `http` module +* create an object constructor that creates a _simple resource_ with at least 3 properties + * include an `id` property that is set to a unique id (**hint:** you'll need to use `node-uuid`) + * include two additional properties of your choice (ex: name, content, etc.) +* create a custom body parser module that uses promises to parse the JSON body of `POST` and `PUT` requests +* create a custom url parser module that returns a promise and uses the NodeJS `url` and `querystring` modules to parse the request url +* create a router constructor that handles requests to `GET`, `POST`, `PUT`, and `DELETE` requests +* create a storage module that will store resources by their schema type (ex: note) and id + +## Server Endpoints +### `/api/simple-resource-name` +* `POST` request + * pass data as stringifed JSON in the body of a **POST** request to create a new resource +* `GET` request + * pass `?id=` as a query string parameter to retrieve a specific resource (as JSON) +* `DELETE` request + * pass `?id=` in the query string to **DELETE** a specific resource + * this should return a 204 status code with no content in the body + +## Tests +* write a test to ensure that your api returns a status code of 404 for routes that have not been registered +* write tests to ensure the `/api/simple-resource-name` endpoint responds as described for each condition below: + * `GET`: test 404, it should respond with 'not found' for valid requests made with an id that was not found + * `GET`: test 400, it should respond with 'bad request' if no id was provided in the request + * `GET`: test 200, it should contain a response body for a request made with a valid id + * `POST`: test 400, it should respond with 'bad request' if no request body was provided or the body was invalid + * `POST`: test 200, it should respond with the body content for a post request with a valid body + +## Bonus +* **2pts:** a `GET` request to `/api/simple-resource-name` with no **?id=** should return an array of all of the ids for that resource diff --git a/lib/parse-json.js b/lib/parse-json.js new file mode 100644 index 0000000..660f59e --- /dev/null +++ b/lib/parse-json.js @@ -0,0 +1,31 @@ +'use strict'; + +module.exports = function(req){ + return new Promise((resolve, reject) => { + if (req.method === 'POST' || req.method === 'PUT') { + var body = ''; + req.on('data', data => { + body += data.toString(); + }); + + req.on('end', () => { + try { + req.body = JSON.parse(body); + resolve(req); + } catch (err) { + console.error(err); + reject(err); + } + }); + + req.on('error', err => { + console.error(err); + reject(err); + }); + + return; + } + + resolve(); + }); +}; diff --git a/lib/parse-url.js b/lib/parse-url.js new file mode 100644 index 0000000..f9c85e5 --- /dev/null +++ b/lib/parse-url.js @@ -0,0 +1,10 @@ +'use strict'; + +const parseUrl = require('url').parse; +const parseQuery = require('querystring').parse; + +module.exports = function(req){ + req.url = parseUrl(req.url); + req.url.query = parseQuery(req.url.query); + return Promise.resolve(req); +}; diff --git a/lib/response.js b/lib/response.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/router.js b/lib/router.js new file mode 100644 index 0000000..d9610a9 --- /dev/null +++ b/lib/router.js @@ -0,0 +1,62 @@ +'use strict'; + +const parseUrl = require('./parse-url.js'); +const parseJSON = require('./parse-json.js'); + +const Router = module.exports = function(){ + this.routes = { + GET: {}, + POST: {}, + PUT: {}, + DELETE: {} + }; +}; + +Router.prototype.get = function(endpoint, callback){ + this.routes.GET[endpoint] = callback; +}; + +Router.prototype.post = function(endpoint, callback){ + this.routes.POST[endpoint] = callback; +}; + +Router.prototype.put = function(endpoint, callback){ + this.routes.PUT[endpoint] = callback; +}; + +Router.prototype.delete = function (endpoint, callback){ + this.routes.DELETE[endpoint] = callback; +}; + +Router.prototype.route = function(){ + return (req, res) => { + Promise.all([ + parseUrl(req), + parseJSON(req) + ]) + .then(()=> { + if(typeof this.routes[req.method][req.url.pathname] === 'function'){ + this.routes[req.method][req.url.pathname](req,res); + return; + } + console.error('route not found'); + + res.writeHead(404, { + 'Content-Type': 'text/plain' + }); + + res.write('route not found'); + res.end(); + }) + .catch(err => { + console.error(err); + + res.writeHead(400, { + 'Content-Type': 'text/plain' + }); + + res.write('bad result'); + res.end(); + }); + }; +}; diff --git a/lib/storage.js b/lib/storage.js new file mode 100644 index 0000000..0f5e4fb --- /dev/null +++ b/lib/storage.js @@ -0,0 +1,48 @@ +'use strict'; + + +const storage = {} + +module.exports = exports = {}; + +exports.createItem = function(schemaName, item){ + if(!schemaName) return Promise.reject(new Error('expected schemaName')); + if(!item) return Promise.reject(new Error('expected item')); + if(!storage[schemaName]) storage[schemaName] = {}; + + storage[schemaName][item.id]= item; + + return Promise.resolve(item); +}; + + +exports.fetchItem = function(schemaName, id){ + return new Promise((resolve, reject) => { + if(!schemaName) return reject(new Error('expected schema name')); + if(!id) return reject(new Error('expected id')); + + var schema = storage[schemaName]; + if(!schema) return reject(new Error('schema not found')); + + var item = schema[id]; + if(!item) return reject(new Error('item not found')); + + resolve(item); + }); +}; + +exports.deleteItem = function(schemaName, id){ + return new Promise((resolve, reject) => { + if(!schemaName) return reject(new Error('expected schemaName')); + if(!id) return reject(new Error('expected id')); + + var schema = storage[schemaName]; + if(!schema) return reject(new Error('schema not found')); + + var item = schema[id]; + if(!item) return reject(new Error('item not found')); + + delete storage[schemaName][id]; + resolve(); + }); +}; diff --git a/model/hike.js b/model/hike.js new file mode 100644 index 0000000..edf0023 --- /dev/null +++ b/model/hike.js @@ -0,0 +1,16 @@ +'use strict'; + +const uuidv4 = require('uuid/v4'); + +module.exports = function(name, distance, difficulty, description){ + if(!name)throw new Error('expected name'); + if(!distance)throw new Error('expected distance'); + if(!difficulty)throw new Error('expected difficulty'); + if(!description)throw new Error('expected description'); + + this.id = uuidv4(); + this.name = name; + this.distance = distance; + this.difficulty = difficulty; + this.description = description; +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..63a713d --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "08-vanilla_rest_api", + "version": "1.0.0", + "description": "![cf](https://i.imgur.com/7v5ASc8.png) Lab 08: Vanilla REST API ======", + "main": "server.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/codefellows-javascript-401d17/08-vanilla_rest_api.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/codefellows-javascript-401d17/08-vanilla_rest_api/issues" + }, + "homepage": "https://github.com/codefellows-javascript-401d17/08-vanilla_rest_api#readme", + "dependencies": { + "bluebird": "^3.5.0", + "uuid": "^3.1.0" + }, + "devDependencies": { + "chai": "^4.1.0", + "mocha": "^3.4.2", + "superagent": "^3.5.2" + } +} diff --git a/route/hike-route.js b/route/hike-route.js new file mode 100644 index 0000000..e69de29 diff --git a/server.js b/server.js new file mode 100644 index 0000000..e372087 --- /dev/null +++ b/server.js @@ -0,0 +1,89 @@ +'use strict'; + +const http =require('http'); +const Hike = require('./model/hike.js'); +const Router = require('./lib/router.js'); +const storage = require('./lib/storage.js'); +const PORT = process.env.PORT || 3000; +const router = new Router(); + +router.get('/api/hike', function(req, res){ + if(req.url.query.id) { + storage.fetchItem('hike', req.url.query.id) + .then( hike => { + res.writeHead(200, { + 'Content-Type': 'application/json' + }); + + res.write(JSON.stringify(hike)); + res.end(); + }) + .catch(err => { + console.error(err); + res.writeHead(404, { + 'Content-Type': 'plain/text' + }); + res.write('hike not found!'); + res.end(); + }); + + return; + } + + res.writeHead(400, { + 'Content-Type': 'text/plain' + }); + res.write('bad request'); + res.end(); +}); + +router.post('/api/hike', function(req, res){ + try{ + var hike = new Hike(req.body.name, req.body.distance, req.body.difficulty, req.body.description); + storage.createItem('hike', hike); + res.writeHead(200, { + 'Content-Type': 'application/json' + }); + res.write(JSON.stringify(hike)); + res.end(); + } catch(err){ + console.error(err); + res.writeHead(400, { + 'Content-Type': 'text/plain' + }); + res.write('bad request'); + res.end(); + } +}); + +router.delete('/api/hike', function(req, res){ + if(req.url.query.id) { + storage.deleteItem('hike', req.url.query.id) + .then( () => { + res.writeHead(204, { + 'Content-type': 'text/plain' + }); + res.end(); + }) + .catch( err => { + console.error(err); + res.writeHead(404, { + 'Content-type': 'text/plain' + }); + res.write('hike not found'); + res.end(); + }); + return; + } + res.writeHead(400, { + 'Content-type': 'text/plain' + }); + res.write('bad request'); + res.end(); +}); + +const server = http.createServer(router.route()); + +server.listen(PORT, () => { + console.log('listening on PORT:', PORT); +}); diff --git a/test/hike-route-test.js b/test/hike-route-test.js new file mode 100644 index 0000000..aa00166 --- /dev/null +++ b/test/hike-route-test.js @@ -0,0 +1,73 @@ +'use strict'; + +const request = require('superagent'); +const expect = require('chai').expect; + +require('../server.js'); + +describe('Hike Routes', function(){ + var hike = null; + + describe('POST: /api/hike', function(){ + it('should return a hike', function(done){ + request.post('localhost:8000/api/hike') + .send({name:'some cool hike', distance: '3.4 miles', difficulty: 'medium', description:'a cool hike'}) + .end((err, res) => { + if(err) return done(err); + expect(res.status).to.equal(200); + expect(res.body.name).to.equal('some cool hike'); + expect(res.body.distance).to.equal('3.4 miles'); + expect(res.body.difficulty).to.equal('medium'); + expect(res.body.description).to.equal('a cool hike'); + hike = res.body; + done(); + }); + }); + + it('should return bad request', function(done){ + request.post('localhost:8000/api/hike') + .send({name:'some cool hike', blue: '3.4 miles'}) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.text).to.equal('bad request'); + done(); + }); + }); + }); + + //also do a 400, in the server too. + + describe('GET: /api/hike', function(){ + it('should return a hike', function(done){ + request.get(`localhost:8000/api/hike?id=${hike.id}`) + .send({name:'some cool hike', distance: '3.4 miles', difficulty: 'medium', description:'a cool hike'}) + .end((err, res) => { + if(err) return done(err); + expect(res.status).to.equal(200); + expect(res.body.name).to.equal('some cool hike'); + expect(res.body.distance).to.equal('3.4 miles'); + expect(res.body.difficulty).to.equal('medium'); + expect(res.body.description).to.equal('a cool hike'); + console.log('get request hike:', res.body); + done(); + }); + }); + it('should return an error(404)', function(done){ + request.get('localhost:8000/api/hike?id=123456') + .end((err, res) => { + expect(res.status).to.equal(404); + done(); + }); + }); + + it('should return bad request (400)', function(done){ + request.get('localhost:8000/api/hike?=1234567') + .end(function(err,res){ + expect(res.status).to.equal(400); + done(); + }); + }); + }); +}); + +//also 404 and 400 From 83c129e784ca0a1ab76a0b0a988d50499f8fe120 Mon Sep 17 00:00:00 2001 From: andyfiveeleven Date: Fri, 28 Jul 2017 08:58:17 -0700 Subject: [PATCH 2/2] errors fixed, i suck at file paths --- .../09b66e38-156c-41a7-906a-05675fb638c7.json | 1 + .../09c55d68-ec12-4b57-90c1-3735ef74ac92.json | 1 + .../106404cb-9a5c-42cd-87d1-447dcb1198d0.json | 1 + .../78b02d3c-99e5-450a-9a57-97df43d0f88a.json | 1 + .../976954a0-a510-426c-b0f8-e6269bef045e.json | 1 + lib/response.js | 21 +++++ lib/storage.js | 68 ++++++++-------- route/hike-route.js | 33 ++++++++ server.js | 77 +------------------ test/hike-route-test.js | 2 +- 10 files changed, 96 insertions(+), 110 deletions(-) create mode 100644 data/hike/09b66e38-156c-41a7-906a-05675fb638c7.json create mode 100644 data/hike/09c55d68-ec12-4b57-90c1-3735ef74ac92.json create mode 100644 data/hike/106404cb-9a5c-42cd-87d1-447dcb1198d0.json create mode 100644 data/hike/78b02d3c-99e5-450a-9a57-97df43d0f88a.json create mode 100644 data/hike/976954a0-a510-426c-b0f8-e6269bef045e.json diff --git a/data/hike/09b66e38-156c-41a7-906a-05675fb638c7.json b/data/hike/09b66e38-156c-41a7-906a-05675fb638c7.json new file mode 100644 index 0000000..1831f83 --- /dev/null +++ b/data/hike/09b66e38-156c-41a7-906a-05675fb638c7.json @@ -0,0 +1 @@ +{"id":"09b66e38-156c-41a7-906a-05675fb638c7","name":"some cool hike","distance":"3.4 miles","difficulty":"medium","description":"a cool hike"} \ No newline at end of file diff --git a/data/hike/09c55d68-ec12-4b57-90c1-3735ef74ac92.json b/data/hike/09c55d68-ec12-4b57-90c1-3735ef74ac92.json new file mode 100644 index 0000000..ba70b75 --- /dev/null +++ b/data/hike/09c55d68-ec12-4b57-90c1-3735ef74ac92.json @@ -0,0 +1 @@ +{"id":"09c55d68-ec12-4b57-90c1-3735ef74ac92","name":"some cool hike","distance":"3.4 miles","difficulty":"medium","description":"a cool hike"} \ No newline at end of file diff --git a/data/hike/106404cb-9a5c-42cd-87d1-447dcb1198d0.json b/data/hike/106404cb-9a5c-42cd-87d1-447dcb1198d0.json new file mode 100644 index 0000000..9353800 --- /dev/null +++ b/data/hike/106404cb-9a5c-42cd-87d1-447dcb1198d0.json @@ -0,0 +1 @@ +{"id":"106404cb-9a5c-42cd-87d1-447dcb1198d0","name":"some cool hike","distance":"3.4 miles","difficulty":"medium","description":"a cool hike"} \ No newline at end of file diff --git a/data/hike/78b02d3c-99e5-450a-9a57-97df43d0f88a.json b/data/hike/78b02d3c-99e5-450a-9a57-97df43d0f88a.json new file mode 100644 index 0000000..e0b9396 --- /dev/null +++ b/data/hike/78b02d3c-99e5-450a-9a57-97df43d0f88a.json @@ -0,0 +1 @@ +{"id":"78b02d3c-99e5-450a-9a57-97df43d0f88a","name":"some cool hike","distance":"3.4 miles","difficulty":"medium","description":"a cool hike"} \ No newline at end of file diff --git a/data/hike/976954a0-a510-426c-b0f8-e6269bef045e.json b/data/hike/976954a0-a510-426c-b0f8-e6269bef045e.json new file mode 100644 index 0000000..5fd28f7 --- /dev/null +++ b/data/hike/976954a0-a510-426c-b0f8-e6269bef045e.json @@ -0,0 +1 @@ +{"id":"976954a0-a510-426c-b0f8-e6269bef045e","name":"some cool hike","distance":"3.4 miles","difficulty":"medium","description":"a cool hike"} \ No newline at end of file diff --git a/lib/response.js b/lib/response.js index e69de29..e9c9366 100644 --- a/lib/response.js +++ b/lib/response.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports = exports = {}; + +exports.sendJSON = function(res,status,data) { + res.writeHead(status, { + 'Content-Type': 'application/json' + }); + + res.write(JSON.stringify(data)); + res.end(); +}; + +exports.sendText = function (res, status, msg){ + res.writeHead(status, { + 'Content-Type': 'text/plain' + }); + + res.write(msg); + res.end(); +}; diff --git a/lib/storage.js b/lib/storage.js index 0f5e4fb..1206b65 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -1,48 +1,50 @@ 'use strict'; - -const storage = {} +const Promise = require('bluebird'); +const fs = Promise.promisifyAll(require('fs'), { suffix: 'Prom'}); module.exports = exports = {}; exports.createItem = function(schemaName, item){ if(!schemaName) return Promise.reject(new Error('expected schemaName')); if(!item) return Promise.reject(new Error('expected item')); - if(!storage[schemaName]) storage[schemaName] = {}; - - storage[schemaName][item.id]= item; - return Promise.resolve(item); + let json = JSON.stringify(item); + return fs.writeFileProm(`${__dirname}/../data/${schemaName}/${item.id}.json`, json) + .then( () => item) + .catch( err => Promise.reject(err)); }; - exports.fetchItem = function(schemaName, id){ - return new Promise((resolve, reject) => { - if(!schemaName) return reject(new Error('expected schema name')); - if(!id) return reject(new Error('expected id')); - - var schema = storage[schemaName]; - if(!schema) return reject(new Error('schema not found')); - - var item = schema[id]; - if(!item) return reject(new Error('item not found')); - - resolve(item); - }); + if(!schemaName) return Promise.reject(new Error('expected schema name')); + if(!id) return Promise.reject(new Error('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(err); + } + }) + .catch( err => Promise.reject()); }; -exports.deleteItem = function(schemaName, id){ - return new Promise((resolve, reject) => { - if(!schemaName) return reject(new Error('expected schemaName')); - if(!id) return reject(new Error('expected id')); - - var schema = storage[schemaName]; - if(!schema) return reject(new Error('schema not found')); - var item = schema[id]; - if(!item) return reject(new Error('item not found')); - - delete storage[schemaName][id]; - resolve(); - }); -}; +// didn't know if i was supposed to rafactor this, was short on time so didn't, but kept it around just in case... +// exports.deleteItem = function(schemaName, id){ +// return new Promise((resolve, reject) => { +// if(!schemaName) return reject(new Error('expected schemaName')); +// if(!id) return reject(new Error('expected id')); +// +// var schema = storage[schemaName]; +// if(!schema) return reject(new Error('schema not found')); +// +// var item = schema[id]; +// if(!item) return reject(new Error('item not found')); +// +// delete storage[schemaName][id]; +// resolve(); +// }); +// }; diff --git a/route/hike-route.js b/route/hike-route.js index e69de29..a08468e 100644 --- a/route/hike-route.js +++ b/route/hike-route.js @@ -0,0 +1,33 @@ +'use strict'; + +const storage = require('../lib/storage.js'); +const response = require('../lib/response.js'); +const Hike = require('../model/hike.js'); + +module.exports = function(router) { + router.get('/api/hike', function(req,res) { + if (req.url.query.id){ + storage.fetchItem('hike', req.url.query.id) + .then(hike => { + response.sendJSON(res, 200, hike); + }) + .catch( err => { + response.sendText(res, 404, 'not found'); + }); + + return; + } + response.sendText(res, 400, 'bad request'); + }); + + router.post('/api/hike', function(req, res){ + try { + var hike = new Hike(req.body.name, req.body.distance, req.body.difficulty, req.body.description); + storage.createItem('hike', hike); + response.sendJSON(res, 200, hike); + } catch (err) { + console.error(err); + response.sendText(res, 400, 'bad request'); + } + }); +}; diff --git a/server.js b/server.js index e372087..011103b 100644 --- a/server.js +++ b/server.js @@ -1,86 +1,11 @@ 'use strict'; const http =require('http'); -const Hike = require('./model/hike.js'); const Router = require('./lib/router.js'); -const storage = require('./lib/storage.js'); const PORT = process.env.PORT || 3000; const router = new Router(); -router.get('/api/hike', function(req, res){ - if(req.url.query.id) { - storage.fetchItem('hike', req.url.query.id) - .then( hike => { - res.writeHead(200, { - 'Content-Type': 'application/json' - }); - - res.write(JSON.stringify(hike)); - res.end(); - }) - .catch(err => { - console.error(err); - res.writeHead(404, { - 'Content-Type': 'plain/text' - }); - res.write('hike not found!'); - res.end(); - }); - - return; - } - - res.writeHead(400, { - 'Content-Type': 'text/plain' - }); - res.write('bad request'); - res.end(); -}); - -router.post('/api/hike', function(req, res){ - try{ - var hike = new Hike(req.body.name, req.body.distance, req.body.difficulty, req.body.description); - storage.createItem('hike', hike); - res.writeHead(200, { - 'Content-Type': 'application/json' - }); - res.write(JSON.stringify(hike)); - res.end(); - } catch(err){ - console.error(err); - res.writeHead(400, { - 'Content-Type': 'text/plain' - }); - res.write('bad request'); - res.end(); - } -}); - -router.delete('/api/hike', function(req, res){ - if(req.url.query.id) { - storage.deleteItem('hike', req.url.query.id) - .then( () => { - res.writeHead(204, { - 'Content-type': 'text/plain' - }); - res.end(); - }) - .catch( err => { - console.error(err); - res.writeHead(404, { - 'Content-type': 'text/plain' - }); - res.write('hike not found'); - res.end(); - }); - return; - } - res.writeHead(400, { - 'Content-type': 'text/plain' - }); - res.write('bad request'); - res.end(); -}); +require('./route/hike-route.js')(router); const server = http.createServer(router.route()); diff --git a/test/hike-route-test.js b/test/hike-route-test.js index aa00166..c030419 100644 --- a/test/hike-route-test.js +++ b/test/hike-route-test.js @@ -11,7 +11,7 @@ describe('Hike Routes', function(){ describe('POST: /api/hike', function(){ it('should return a hike', function(done){ request.post('localhost:8000/api/hike') - .send({name:'some cool hike', distance: '3.4 miles', difficulty: 'medium', description:'a cool hike'}) + .send({name:'some cool hike', distance:'3.4 miles', difficulty:'medium', description:'a cool hike'}) .end((err, res) => { if(err) return done(err); expect(res.status).to.equal(200);