From 2a14ccaf1cf0cef9f5e0f2d3e53a2deae800d965 Mon Sep 17 00:00:00 2001 From: Dustin McBride Date: Thu, 19 May 2016 11:54:47 -0700 Subject: [PATCH] init commit --- dustin/.eslintrc | 28 +++++++++++ dustin/gulpfile.js | 25 ++++++++++ dustin/lib/getnextid.js | 15 ++++++ dustin/package.json | 20 ++++++++ dustin/server.js | 80 ++++++++++++++++++++++++++++++++ dustin/test/server_test.js | 95 ++++++++++++++++++++++++++++++++++++++ dustin/view/_footer.html | 1 + dustin/view/_header.html | 1 + 8 files changed, 265 insertions(+) create mode 100644 dustin/.eslintrc create mode 100644 dustin/gulpfile.js create mode 100644 dustin/lib/getnextid.js create mode 100644 dustin/package.json create mode 100644 dustin/server.js create mode 100644 dustin/test/server_test.js create mode 100644 dustin/view/_footer.html create mode 100644 dustin/view/_header.html diff --git a/dustin/.eslintrc b/dustin/.eslintrc new file mode 100644 index 0000000..468db4e --- /dev/null +++ b/dustin/.eslintrc @@ -0,0 +1,28 @@ +{ + "env": { + "es6": true, + "node": 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 new file mode 100644 index 0000000..205ef66 --- /dev/null +++ b/dustin/gulpfile.js @@ -0,0 +1,25 @@ +var gulp = require('gulp'); +var eslint = require('gulp-eslint'); +var mocha = require('gulp-mocha'); + + +gulp.task('watch', function () { + gulp.watch(['*.js', '../test/*.js'], ['lint', 'mocha']); +}); + +gulp.task('default', ['mocha', 'lint', 'watch'], function () {}); + +gulp.task('lint', function () { + gulp.src(['./*.js', './test/*.js', './lib/*.js']) + .pipe(eslint()) //{} pass in rules + .pipe(eslint.format()); +}); + +gulp.task('mocha', function () { + return gulp.src('./test/*.js', { + read: false + }) + .pipe(mocha({ + reporter: 'nyan' + })); +}); diff --git a/dustin/lib/getnextid.js b/dustin/lib/getnextid.js new file mode 100644 index 0000000..3d5d39a --- /dev/null +++ b/dustin/lib/getnextid.js @@ -0,0 +1,15 @@ +module.exports = function (dataPath) { + var fs = require('fs'); + + // fs.readdir(dataPath, function (err, files) { + // return files.map(function (f) { + // return f.split('.')[0]; + // }); + // }); + + var files = fs.readdirSync(dataPath); + var nums = files.map(function (f) { + return f.split('.')[0]; + }); + return Math.max.apply(null,nums) + 1; +}; diff --git a/dustin/package.json b/dustin/package.json new file mode 100644 index 0000000..25f5c1f --- /dev/null +++ b/dustin/package.json @@ -0,0 +1,20 @@ +{ + "name": "basic_http_server", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "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", + "gulp-watch": "^4.3.5", + "mocha": "^2.4.5" + } +} diff --git a/dustin/server.js b/dustin/server.js new file mode 100644 index 0000000..483e85e --- /dev/null +++ b/dustin/server.js @@ -0,0 +1,80 @@ +'use strict'; + +const http = require('http'); +const noteDataPath = (__dirname + '/data'); +var fs = require('fs'); +var getNextId = require('./lib/getnextid'); +var stream = require('stream'); +var header = fs.readFileSync('./view/_header.html'); +var footer = fs.readFileSync('./view/_footer.html'); +var nextNoteId = getNextId(noteDataPath); + +http.createServer(function (req, res) { + + res.processed = false; + var url_array = req.url.split('/'); + + if (req.method === 'GET' && url_array[1] === 'notes') notesIndex(res); + if (req.method === 'GET' && url_array[1] === 'notes' && (url_array[2])) notesShow(res); + if (req.method === 'POST' && url_array[1] === 'notes') notesPost(res, req); + if (res.processed === false) url404(res); + +}).listen(3000); + +var notesIndex = function (res) { + res.processed = true; + fs.readdir(noteDataPath, function (err, files) { + var payload = ''; + files.forEach(function (f) { + payload = payload + f + '
'; + }); + renderLayout(res, payload); + }); +}; + +var notesShow = function (res) { + res.write('works'); + res.end(); +}; + +var notesPost = function (res, req) { + res.processed = true; + var body = ''; + req.on('data', function (data) { + body += data; + }); + req.on('end', function () { + if (req.headers['content-type'] === 'application/json') { + var file = fs.createWriteStream(noteDataPath + '/' + nextNoteId + '.json'); + var bufferStream = new stream.PassThrough(); + var inBuf = new Buffer(JSON.stringify(body)); + bufferStream.end(inBuf); + bufferStream.pipe(file); + res.end(); + } else { + badRequest(res); + } + }); +}; + +var url404 = function (res) { + res.writeHead(404, { + 'Content-Type': 'text/html' + }); + res.write('Not found'); + res.end(); +}; + +var badRequest = function (res) { + res.processed = true; + res.writeHead(400, { + 'Content-Type': 'text/html' + }); + res.write('BAD REQUEST'); + res.end(); +}; + +var renderLayout = function (res, payload) { + res.write(header + payload + footer); + res.end(); +}; diff --git a/dustin/test/server_test.js b/dustin/test/server_test.js new file mode 100644 index 0000000..2eb8bf4 --- /dev/null +++ b/dustin/test/server_test.js @@ -0,0 +1,95 @@ +var chai = require('chai'); +var chaiHTTP = require('chai-http'); +var fs = require('fs'); +var expect = chai.expect; +chai.use(chaiHTTP); +var request = chai.request; + +var getNextId = require('../lib/getnextid'); +var noteDataPath = (__dirname + '/../data'); +var nextNoteId = getNextId(noteDataPath); + +var header = fs.readFileSync('./view/_header.html'); +var footer = fs.readFileSync('./view/_footer.html'); + +require('../server'); + +describe('HTTP server', function () { + it('/notes should respond with a list of all of the json files', function (done) { + files = fs.readdirSync('./data'); + request('localhost:3000') + .get('/notes') + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + var payload = ''; + files.forEach(function (f) { + payload = payload + f + '
'; + }); + expect(res.text).to.eql(header + payload + footer); + done(); + }); + }); + + it('accept a POST request to /notes with proper headers and payload and be saved correctly', function (done) { + var noteJSON = "{'noteBody': 'buy milk'}"; + var filename = noteDataPath + '/' + (nextNoteId - 1) + '.json'; + var fileBirthtime = fs.statSync(filename)['birthtime']; + request('localhost:3000') + .post('/notes') + .set('Content-Type', 'application/json') + .send(noteJSON) + .end(function (err, res) { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(Date.now() - Date.parse(fileBirthtime)).to.be.below(100000); + expect(noteJSON).to.eql(JSON.parse(fs.readFileSync(filename))); + done(); + }); + }); + + it('return a 404 when no route is found', function (done) { + request('localhost:3000') + .get('/nothere') + .end(function (err, res) { + expect(res).to.have.status(404); + done(); + }); + }); + + // it('return an error to a POST request to /notes without proper headers', function (done) { + // request('localhost:3000') + // .post('/greet') + // .set('Content-Type', 'text/html') + // .send({ + // 'name': 'walter sobchak' + // }) + // .end(function (err, res) { + // expect(err).to.eql(null); + // expect(res).to.have.status(200); + // expect(savedJSON).to.eql([{ + // 'name': 'walter sobchak' + // }]); + // done(); + // }); + // }); + + // it('return an error to a POST request to /notes without proper payload', function (done) { + // request('localhost:3000') + // .post('/greet') + // .set('Content-Type', 'application/json') + // .send({ + // 'name': 'walter sobchak' + // }) + // .end(function (err, res) { + // expect(err).to.eql(null); + // expect(res).to.have.status(200); + // expect(savedJSON).to.eql([{ + // 'name': 'walter sobchak' + // }]); + // done(); + // }); + // }); + // + +}); diff --git a/dustin/view/_footer.html b/dustin/view/_footer.html new file mode 100644 index 0000000..44b22a9 --- /dev/null +++ b/dustin/view/_footer.html @@ -0,0 +1 @@ + diff --git a/dustin/view/_header.html b/dustin/view/_header.html new file mode 100644 index 0000000..7cd2c4c --- /dev/null +++ b/dustin/view/_header.html @@ -0,0 +1 @@ +