added server tests
This commit is contained in:
parent
6181ea6463
commit
cdf45de8e2
76
package-lock.json
generated
76
package-lock.json
generated
@ -191,6 +191,11 @@
|
||||
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "6.7.7",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
|
||||
@ -556,11 +561,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
||||
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk="
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
|
||||
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q="
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -694,6 +709,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"cookiejar": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz",
|
||||
"integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
@ -846,6 +866,11 @@
|
||||
"integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
|
||||
"dev": true
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
|
||||
@ -1210,6 +1235,11 @@
|
||||
"resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz",
|
||||
"integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||
},
|
||||
"external-editor": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
|
||||
@ -1306,12 +1336,22 @@
|
||||
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
|
||||
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.2.0.tgz",
|
||||
"integrity": "sha1-ml47kpX5gLJiPPZPojixTOvKcHs="
|
||||
},
|
||||
"formatio": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz",
|
||||
"integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=",
|
||||
"dev": true
|
||||
},
|
||||
"formidable": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz",
|
||||
"integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak="
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
|
||||
@ -3381,8 +3421,7 @@
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"dev": true
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"progress": {
|
||||
"version": "2.0.0",
|
||||
@ -3775,8 +3814,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
@ -4213,6 +4251,33 @@
|
||||
"integrity": "sha1-rDQjdWMyfG/4l7ZHQr9q7BkK054=",
|
||||
"dev": true
|
||||
},
|
||||
"superagent": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/superagent/-/superagent-3.5.2.tgz",
|
||||
"integrity": "sha1-M2GjlxVnUEw1EGOr6q4PqiPb8/g=",
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"supertest": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supertest/-/supertest-3.0.0.tgz",
|
||||
"integrity": "sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
@ -4417,8 +4482,7 @@
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.0",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"raven": "^2.1.0",
|
||||
"raven-js": "^3.16.0",
|
||||
"redis": "^2.7.1",
|
||||
"supertest": "^3.0.0",
|
||||
"uglify-es": "3.0.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -50,7 +51,7 @@
|
||||
"lint:css": "stylelint 'public/*.css'",
|
||||
"lint:js": "eslint .",
|
||||
"start": "node server/portal_server",
|
||||
"test": "mocha",
|
||||
"test": "mocha test/unit && mocha test/server",
|
||||
"version": "node scripts/version"
|
||||
}
|
||||
}
|
||||
|
@ -153,9 +153,19 @@ app.post('/delete/:id', (req, res) => {
|
||||
|
||||
app.post('/upload', (req, res, next) => {
|
||||
const newId = crypto.randomBytes(5).toString('hex');
|
||||
const meta = JSON.parse(req.header('X-File-Metadata'));
|
||||
let meta;
|
||||
|
||||
try {
|
||||
meta = JSON.parse(req.header('X-File-Metadata'));
|
||||
} catch(err) {
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validateIV(meta.id)) {
|
||||
if (!validateIV(meta.id) ||
|
||||
!meta.hasOwnProperty('aad') ||
|
||||
!meta.hasOwnProperty('id') ||
|
||||
!meta.hasOwnProperty('filename')) {
|
||||
res.sendStatus(404);
|
||||
return;
|
||||
}
|
||||
@ -191,7 +201,7 @@ app.get('/__version__', (req, res) => {
|
||||
res.sendFile(path.join(STATIC_PATH, 'version.json'));
|
||||
});
|
||||
|
||||
app.listen(conf.listen_port, () => {
|
||||
const server = app.listen(conf.listen_port, () => {
|
||||
log.info('startServer:', `Portal app listening on port ${conf.listen_port}!`);
|
||||
});
|
||||
|
||||
@ -201,4 +211,9 @@ const validateID = route_id => {
|
||||
|
||||
const validateIV = route_id => {
|
||||
return route_id.match(/^[0-9a-fA-F]{24}$/) !== null;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
server: server,
|
||||
storage: storage
|
||||
}
|
@ -31,6 +31,8 @@ if (conf.s3_bucket) {
|
||||
delete: awsDelete,
|
||||
forceDelete: awsForceDelete,
|
||||
ping: awsPing,
|
||||
flushall: flushall,
|
||||
quit: quit,
|
||||
metadata
|
||||
};
|
||||
} else {
|
||||
@ -45,10 +47,20 @@ if (conf.s3_bucket) {
|
||||
delete: localDelete,
|
||||
forceDelete: localForceDelete,
|
||||
ping: localPing,
|
||||
flushall: flushall,
|
||||
quit: quit,
|
||||
metadata
|
||||
};
|
||||
}
|
||||
|
||||
function flushall() {
|
||||
redis_client.flushdb();
|
||||
}
|
||||
|
||||
function quit() {
|
||||
redis_client.quit();
|
||||
}
|
||||
|
||||
function metadata(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
redis_client.hgetall(id, (err, reply) => {
|
||||
|
170
test/server/server.test.js
Normal file
170
test/server/server.test.js
Normal file
@ -0,0 +1,170 @@
|
||||
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 fildId;
|
||||
|
||||
before(function() {
|
||||
const app = proxyquire('../../server/portal_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({
|
||||
aad: '11111',
|
||||
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))
|
||||
})
|
||||
});
|
1
test/test_upload.txt
Normal file
1
test/test_upload.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test.
|
@ -43,7 +43,7 @@ const awsStub = {
|
||||
}
|
||||
};
|
||||
|
||||
const storage = proxyquire('../server/storage', {
|
||||
const storage = proxyquire('../../server/storage', {
|
||||
redis: redisStub,
|
||||
fs: fsStub,
|
||||
'./log.js': function() {
|
@ -32,7 +32,7 @@ const logStub = {};
|
||||
logStub.info = sinon.stub();
|
||||
logStub.error = sinon.stub();
|
||||
|
||||
const storage = proxyquire('../server/storage', {
|
||||
const storage = proxyquire('../../server/storage', {
|
||||
redis: redisStub,
|
||||
fs: fsStub,
|
||||
'./log.js': function() {
|
Loading…
Reference in New Issue
Block a user