2016-05-03 23:18:18 +00:00
|
|
|
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
|
|
|
// Node module: loopback-component-storage
|
|
|
|
// This file is licensed under the Artistic License 2.0.
|
|
|
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
var request = require('supertest');
|
|
|
|
var loopback = require('loopback');
|
|
|
|
var assert = require('assert');
|
|
|
|
|
|
|
|
var app = loopback();
|
|
|
|
var path = require('path');
|
|
|
|
|
|
|
|
// expose a rest api
|
|
|
|
app.use(loopback.rest());
|
|
|
|
|
2015-01-29 14:32:51 +00:00
|
|
|
var dsImage = loopback.createDataSource({
|
|
|
|
connector: require('../lib/storage-connector'),
|
|
|
|
provider: 'filesystem',
|
|
|
|
root: path.join(__dirname, 'images'),
|
|
|
|
|
|
|
|
getFilename: function(fileInfo) {
|
|
|
|
return 'image-' + fileInfo.name;
|
2015-02-10 13:45:30 +00:00
|
|
|
},
|
|
|
|
acl: 'public-read',
|
|
|
|
allowedContentTypes: ['image/png', 'image/jpeg'],
|
|
|
|
maxFileSize: 5 * 1024 * 1024
|
2015-01-29 14:32:51 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
var ImageContainer = dsImage.createModel('imageContainer');
|
|
|
|
app.model(ImageContainer);
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
var ds = loopback.createDataSource({
|
|
|
|
connector: require('../lib/storage-connector'),
|
|
|
|
provider: 'filesystem',
|
|
|
|
root: path.join(__dirname, 'images')
|
|
|
|
});
|
|
|
|
|
2015-09-30 03:46:17 +00:00
|
|
|
var Container = ds.createModel('container', {}, {base: 'Model'});
|
2014-01-14 18:26:09 +00:00
|
|
|
app.model(Container);
|
|
|
|
|
2014-03-31 16:49:42 +00:00
|
|
|
/*!
|
|
|
|
* Verify that the JSON response has the correct metadata properties.
|
|
|
|
* Please note the metadata vary by storage providers. This test assumes
|
|
|
|
* the 'filesystem' provider.
|
|
|
|
*
|
|
|
|
* @param {String} containerOrFile The container/file object
|
|
|
|
* @param {String} [name] The name to be checked if not undefined
|
|
|
|
*/
|
|
|
|
function verifyMetadata(containerOrFile, name) {
|
|
|
|
assert(containerOrFile);
|
|
|
|
|
|
|
|
// Name
|
|
|
|
if (name) {
|
|
|
|
assert.equal(containerOrFile.name, name);
|
|
|
|
}
|
|
|
|
// No sensitive information
|
|
|
|
assert(containerOrFile.uid === undefined);
|
|
|
|
assert(containerOrFile.gid === undefined);
|
|
|
|
|
|
|
|
// Timestamps
|
|
|
|
assert(containerOrFile.atime);
|
|
|
|
assert(containerOrFile.ctime);
|
|
|
|
assert(containerOrFile.mtime);
|
|
|
|
|
|
|
|
// Size
|
|
|
|
assert.equal(typeof containerOrFile.size, 'number');
|
|
|
|
}
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
describe('storage service', function () {
|
|
|
|
var server = null;
|
|
|
|
before(function (done) {
|
2016-08-10 17:34:00 +00:00
|
|
|
server = app.listen(0, function () {
|
2014-01-14 18:26:09 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
after(function () {
|
|
|
|
server.close();
|
|
|
|
});
|
|
|
|
|
2014-02-03 18:58:37 +00:00
|
|
|
it('should create a container', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.post('/containers')
|
|
|
|
.send({name: 'test-container'})
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.set('Content-Type', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
2014-03-31 16:49:42 +00:00
|
|
|
verifyMetadata(res.body, 'test-container');
|
2014-02-03 18:58:37 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should get a container', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.get('/containers/test-container')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
2014-03-31 16:49:42 +00:00
|
|
|
verifyMetadata(res.body, 'test-container');
|
2014-02-03 18:58:37 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should list containers', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.get('/containers')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert(Array.isArray(res.body));
|
|
|
|
assert.equal(res.body.length, 2);
|
2014-03-31 16:49:42 +00:00
|
|
|
res.body.forEach(function(c) {
|
|
|
|
verifyMetadata(c);
|
|
|
|
});
|
2014-02-03 18:58:37 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should delete a container', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.del('/containers/test-container')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should list containers after delete', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.get('/containers')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert(Array.isArray(res.body));
|
|
|
|
assert.equal(res.body.length, 1);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should list files', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.get('/containers/album1/files')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert(Array.isArray(res.body));
|
2014-03-31 16:49:42 +00:00
|
|
|
res.body.forEach(function(f) {
|
|
|
|
verifyMetadata(f);
|
|
|
|
});
|
2014-02-03 18:58:37 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
it('uploads files', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-01-14 18:26:09 +00:00
|
|
|
.post('/containers/album1/upload')
|
2016-02-03 01:01:37 +00:00
|
|
|
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
2014-01-14 18:26:09 +00:00
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert.deepEqual(res.body, {"result": {"files": {"image": [
|
2015-04-21 20:02:47 +00:00
|
|
|
{"container": "album1", "name": "test.jpg", "type": "image/jpeg",
|
|
|
|
"size": 60475}
|
2014-01-14 18:26:09 +00:00
|
|
|
]}, "fields": {}}});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2015-01-29 14:32:51 +00:00
|
|
|
it('uploads files with renamer', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2015-01-29 14:32:51 +00:00
|
|
|
.post('/imageContainers/album1/upload')
|
2016-02-03 01:01:37 +00:00
|
|
|
.attach('image', path.join(__dirname, './fixtures/test.jpg'))
|
2015-01-29 14:32:51 +00:00
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert.deepEqual(res.body, {"result": {"files": {"image": [
|
2015-12-05 20:52:01 +00:00
|
|
|
{"container": "album1", "name": "image-test.jpg", "originalFilename":"test.jpg", "type": "image/jpeg", "acl":"public-read", "size": 60475}
|
2015-01-29 14:32:51 +00:00
|
|
|
]}, "fields": {}}});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-09-29 19:20:29 +00:00
|
|
|
it('uploads file wrong content type', function(done) {
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2015-02-10 13:45:30 +00:00
|
|
|
.post('/imageContainers/album1/upload')
|
2016-02-03 01:01:37 +00:00
|
|
|
.attach('image', path.join(__dirname, './fixtures/app.js'))
|
2015-02-10 13:45:30 +00:00
|
|
|
.set('Accept', 'application/json')
|
2016-09-29 19:20:29 +00:00
|
|
|
.set('Connection', 'keep-alive')
|
2015-02-10 13:45:30 +00:00
|
|
|
.expect('Content-Type', /json/)
|
2016-09-29 19:20:29 +00:00
|
|
|
.expect(500, function(err, res) {
|
2015-02-10 13:45:30 +00:00
|
|
|
assert(res.body.error.message.indexOf('is not allowed') !== -1);
|
2016-09-29 19:20:29 +00:00
|
|
|
done(err);
|
2015-02-10 13:45:30 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('uploads file too large', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2015-02-10 13:45:30 +00:00
|
|
|
.post('/imageContainers/album1/upload')
|
2016-02-03 01:01:37 +00:00
|
|
|
.attach('image', path.join(__dirname, './fixtures/largeImage.jpg'))
|
2015-02-10 13:45:30 +00:00
|
|
|
.set('Accept', 'application/json')
|
2016-08-03 20:56:20 +00:00
|
|
|
.set('Connection', 'keep-alive')
|
2015-02-10 13:45:30 +00:00
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
assert(err);
|
|
|
|
assert(res.body.error.message.indexOf('maxFileSize exceeded') !== -1);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-02-03 18:58:37 +00:00
|
|
|
it('should get file by name', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.get('/containers/album1/files/test.jpg')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
2014-03-31 16:49:42 +00:00
|
|
|
verifyMetadata(res.body, 'test.jpg');
|
2014-02-03 18:58:37 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2015-01-29 14:32:51 +00:00
|
|
|
it('should get file by renamed file name', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2015-01-29 14:32:51 +00:00
|
|
|
.get('/imageContainers/album1/files/image-test.jpg')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
verifyMetadata(res.body, 'image-test.jpg');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
it('downloads files', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-01-14 18:26:09 +00:00
|
|
|
.get('/containers/album1/download/test.jpg')
|
2014-01-30 06:39:01 +00:00
|
|
|
.expect('Content-Type', 'image/jpeg')
|
2014-01-14 18:26:09 +00:00
|
|
|
.expect(200, function (err, res) {
|
2016-08-16 20:07:48 +00:00
|
|
|
if (err) done(err);
|
2014-01-14 18:26:09 +00:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-08-16 20:00:05 +00:00
|
|
|
it('should run a function before a download is started by a client', function(done) {
|
|
|
|
var hookCalled = false;
|
|
|
|
|
|
|
|
var Container = app.models.Container;
|
|
|
|
|
|
|
|
Container.beforeRemote('download', function(ctx, unused, cb) {
|
|
|
|
hookCalled = true;
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
|
|
|
|
request('http://localhost:' + app.get('port'))
|
|
|
|
.get('/containers/album1/download/test.jpg')
|
|
|
|
.expect('Content-Type', 'image/jpeg')
|
|
|
|
.expect(200, function(err, res) {
|
2016-08-16 20:07:48 +00:00
|
|
|
if (err) done(err);
|
2016-08-16 20:00:05 +00:00
|
|
|
assert(hookCalled, 'beforeRemote hook was not called');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-08-16 20:07:48 +00:00
|
|
|
it('should run a function after a download is started by a client', function(done) {
|
|
|
|
var hookCalled = false;
|
|
|
|
|
|
|
|
var Container = app.models.Container;
|
|
|
|
|
|
|
|
Container.afterRemote('download', function(ctx, unused, cb) {
|
|
|
|
hookCalled = true;
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
|
|
|
|
request('http://localhost:' + app.get('port'))
|
|
|
|
.get('/containers/album1/download/test.jpg')
|
|
|
|
.expect('Content-Type', 'image/jpeg')
|
|
|
|
.expect(200, function(err, res) {
|
|
|
|
if (err) done(err);
|
|
|
|
assert(hookCalled, 'afterRemote hook was not called');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-02-03 18:58:37 +00:00
|
|
|
it('should delete a file', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-02-03 18:58:37 +00:00
|
|
|
.del('/containers/album1/files/test.jpg')
|
|
|
|
.set('Accept', 'application/json')
|
|
|
|
.expect('Content-Type', /json/)
|
|
|
|
.expect(200, function (err, res) {
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-01-14 18:26:09 +00:00
|
|
|
it('reports errors if it fails to find the file to download', function (done) {
|
|
|
|
|
2016-08-10 17:34:00 +00:00
|
|
|
request('http://localhost:' + app.get('port'))
|
2014-01-14 18:26:09 +00:00
|
|
|
.get('/containers/album1/download/test_not_exist.jpg')
|
2014-01-30 06:39:01 +00:00
|
|
|
.expect('Content-Type', /json/)
|
2014-01-14 18:26:09 +00:00
|
|
|
.expect(500, function (err, res) {
|
|
|
|
assert(res.body.error);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|