diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb3be50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/data diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..ac4cee7 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,65 @@ +'use strict'; + +const gulp = require('gulp'); +const mocha = require('gulp-mocha'); +const lint = require('gulp-eslint'); +const opts = { + 'extends': 'eslint:recommended', + 'ecmaFeatures': { + 'modules': true + }, + 'rules': { + 'no-alert': 0, + 'no-bitwise': 0, + 'camelcase': 1, + 'no-console': 1, + 'curly': 1, + 'eqeqeq': 0, + 'no-eq-null': 0, + 'guard-for-in': 1, + 'no-empty': 1, + 'no-use-before-define': 0, + 'no-obj-calls': 2, + 'no-unused-vars': 0, + 'new-cap': 1, + 'no-shadow': 0, + 'strict': 1, + 'no-invalid-regexp': 2, + 'comma-dangle': 2, + 'no-undef': 1, + 'no-new': 1, + 'no-extra-semi': 1, + 'no-debugger': 2, + 'no-caller': 1, + 'semi': 1, + 'quotes': 0, + 'no-unreachable': 2 + }, + 'globals': { + '$': false + }, + 'env': { + 'node': true, + 'es6': true + } +}; + +gulp.task('linter' , () => { + return gulp.src('./**/*.js') + .pipe(lint(opts)) + .pipe(lint.format()); +}); + +gulp.task('tests', () => { + return gulp.src('./test/server-test.js', {read: false}) + .pipe(mocha({reporter: 'spec'})); +}); + +gulp.task('watch', () => { + gulp.watch('./test/server-test.js', ['linter', 'tests']); + gulp.watch('./**/*.js', ['linter']); +}); + +gulp.task('default', ['watch', 'linter', 'tests'], () => { + console.log('All tasks completed successfully'); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..d46a076 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "stefanie-hansen", + "version": "1.0.0", + "description": "##To Submit this Assignment * fork this repository * write all of your code in a folder containing your name * push to your repository * submit a pull request to this repository * submit a link to your PR in canvas", + "main": "server.js", + "directories": { + "test": "test" + }, + "dependencies": { + }, + "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" + }, + "scripts": { + "test": "mocha", + "start": "node server.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/stefuhnee/simple_http_with_persistence.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/stefuhnee/simple_http_with_persistence/issues" + }, + "homepage": "https://github.com/stefuhnee/simple_http_with_persistence#readme" +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..1a568d1 --- /dev/null +++ b/server.js @@ -0,0 +1,42 @@ +'use strict'; + +const http = require('http'); +const fs = require('fs'); +const fileArr = fs.readdirSync(__dirname + '/data'); + +http.createServer((req, res) => { + if (req.method === 'POST' && req.url === '/notes') { + let dataString = ''; + req.on('data', (data) => { + dataString += data.toString(); + }); + req.on('end', () => { + fileArr.push(dataString); + let fileName = __dirname + '/data/note' + fileArr.length + '.json'; + fs.writeFileSync(fileName, dataString); + res.statusCode = 200; + return res.end('File saved successfully'); + }); + } + + else if (req.method === 'GET' && req.url === '/notes') { + let files = fs.readdir(__dirname + '/data', (err, files) => { + if (err) { + res.statusCode = 400; + return res.end('Error occurred: ', err); + } + files.forEach((file) => { + res.write(file + '\n'); + }); + return res.end(); + }); + } + + else { + res.statusCode = 404; + return res.end('Not found'); + } + +}).listen(3000, () => { + console.log('listening on port 3000'); +}); diff --git a/test/server-test.js b/test/server-test.js new file mode 100644 index 0000000..ce9818f --- /dev/null +++ b/test/server-test.js @@ -0,0 +1,64 @@ +'use strict'; + +const chai = require('chai'); +const expect = require('chai').expect; +const chaiHTTP = require('chai-http'); +chai.use(chaiHTTP); +const request = chai.request; +const fs = require('fs'); +let oldFiles = []; +let newFiles = []; +require('../server.js'); + +describe('HTTP server with persistence tests', () => { + before('read original list of files in data directory', () => { + oldFiles = fs.readdirSync(__dirname + '/../data'); + }); + it('should respond to a GET request to /notes without errors', (done) => { + request('localhost:3000') + .get('/notes') + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + done(); + }); + }); + it('should respond to a POST request to /notes without errors', (done) => { + request('localhost:3000') + .post('/notes') + .end((err, res) => { + expect(err).to.eql(null); + expect(res).to.have.status(200); + expect(res.text).to.eql('File saved successfully'); + done(); + }); + }); + it('should respond to request to any path besides /notes with a 404 status', (done) => { + request('localhost:3000') + .get('/TEST') + .end((err, res) => { + expect(res).to.have.status(404); + expect(res.text).to.eql('Not found'); + done(); + }); + }); + it('should respond to a GET request with a list of files', (done) => { + request('localhost:3000') + .get('/notes') + .end((err, res) => { + let file = res.text.trim().split('\n').pop(); + expect(file.endsWith('.json')).to.eql(true); + done(); + }); + }); + it('should should create a file with a POST request to /notes', (done) => { + request('localhost:3000') + .post('/notes') + .send({"test":"test"}) + .end((err, res) => { + newFiles = fs.readdirSync(__dirname + '/../data'); + expect(oldFiles.length).to.be.below(newFiles.length); + done(); + }); + }); +});