const assert = require('assert'); const sinon = require('sinon'); const proxyquire = require('proxyquire'); const request = require('supertest'); const fs = require('fs'); const logStub = {}; logStub.info = sinon.stub(); logStub.error = sinon.stub(); const storage = proxyquire('../../server/storage', { './log.js': function() { return logStub; } }); storage.flushall(); describe('Server integration tests', function() { let server; let storage; let uuid; let fileId; before(function() { const app = proxyquire('../../server/server', { './log.js': function() { return logStub; } }); server = app.server; storage = app.storage; }); after(function() { storage.flushall(); storage.quit(); server.close(); }); function upload() { return request(server) .post('/upload') .field('fname', 'test_upload.txt') .set( 'X-File-Metadata', JSON.stringify({ id: '111111111111111111111111', filename: 'test_upload.txt' }) ) .attach('file', './test/test_upload.txt'); } it('Responds with a 200 when the service is up', function() { return request(server) .get('/') .expect(200); }); it('Rejects with a 404 when a file id is not valid', function() { return request(server) .post('/upload/123') .field('fname', 'test_upload.txt') .set( 'X-File-Metadata', JSON.stringify({ silly: 'text' }) ) .attach('file', './test/test_upload.txt') .expect(404); }); it('Accepts a file and stores it when properly uploaded', function(done) { upload().then(res => { assert(res.body.hasOwnProperty('delete')); uuid = res.body.delete; assert(res.body.hasOwnProperty('url')); assert(res.body.hasOwnProperty('id')); fileId = res.body.id; fs.access('./static/' + fileId, fs.constants.F_OK, err => { if (err) { done(new Error('The file does not exist')); } else { done(); } }); }); }); it('Responds with a 200 if a file exists', function() { return request(server) .get('/exists/' + fileId) .expect(200); }); it('Exists in the redis server', function() { return storage .exists(fileId) .then(() => assert(1)) .catch(err => assert.fail()); }); it('Fails delete if the delete token does not match', function() { return request(server) .post('/delete/' + fileId) .send({ delete_token: 11 }) .expect(404); }); it('Fails delete if the id is invalid', function() { return request(server) .post('/delete/1') .expect(404); }); it('Successfully deletes if the id is valid and the delete token matches', function(done) { request(server) .post('/delete/' + fileId) .send({ delete_token: uuid }) .expect(200) .then(() => { fs.access('./static/' + fileId, fs.constants.F_OK, err => { if (err) { done(); } else { done(new Error('The file does not exist')); } }); }); }); it('Responds with a 404 if a file does not exist', function() { return request(server) .get('/exists/notfound') .expect(404); }); it('Uploads properly after a delete', function(done) { upload().then(res => { assert(res.body.hasOwnProperty('delete')); uuid = res.body.delete; assert(res.body.hasOwnProperty('url')); assert(res.body.hasOwnProperty('id')); fileId = res.body.id; fs.access('./static/' + fileId, fs.constants.F_OK, err => { if (err) { done(new Error('The file does not exist')); } else { done(); } }); }); }); it('Responds with a 200 for the download page', function() { return request(server) .get('/download/' + fileId) .expect(200); }); it('Downloads a file properly', function() { return request(server) .get('/assets/download/' + fileId) .then(res => { assert(res.header.hasOwnProperty('content-disposition')); assert(res.header.hasOwnProperty('content-type')); assert(res.header.hasOwnProperty('content-length')); assert(res.header.hasOwnProperty('x-file-metadata')); assert.equal( res.header['content-disposition'], 'attachment; filename=test_upload.txt' ); assert.equal(res.header['content-type'], 'application/octet-stream'); }); }); it('The file is deleted after one download', function() { assert(!fs.existsSync('./static/' + fileId)); }); it('No longer exists in the redis server', function() { return storage .exists(fileId) .then(() => assert.fail()) .catch(err => assert(1)); }); });