mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
image upload controller refactor
issue #635 - upload controller shouldn't assume fs - filesystem module proxies all the fs work - proxies and exposes middleware for serving images - creating a date based path and unique filename is a base object util - unit tests updated
This commit is contained in:
parent
778e626f85
commit
15da975c06
8 changed files with 187 additions and 137 deletions
|
@ -15,6 +15,7 @@ var express = require('express'),
|
||||||
Ghost = require('./ghost'),
|
Ghost = require('./ghost'),
|
||||||
helpers = require('./server/helpers'),
|
helpers = require('./server/helpers'),
|
||||||
middleware = require('./server/middleware'),
|
middleware = require('./server/middleware'),
|
||||||
|
storage = require('./server/storage'),
|
||||||
packageInfo = require('../package.json'),
|
packageInfo = require('../package.json'),
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
|
@ -177,7 +178,9 @@ when(ghost.init()).then(function () {
|
||||||
express['static'].mime.define({'application/font-woff': ['woff']});
|
express['static'].mime.define({'application/font-woff': ['woff']});
|
||||||
// Shared static config
|
// Shared static config
|
||||||
server.use('/shared', express['static'](path.join(__dirname, '/shared')));
|
server.use('/shared', express['static'](path.join(__dirname, '/shared')));
|
||||||
server.use('/content/images', express['static'](path.join(__dirname, '/../content/images')));
|
|
||||||
|
server.use('/content/images', storage.get_storage().serve());
|
||||||
|
|
||||||
// Serve our built scripts; can't use /scripts here because themes already are
|
// Serve our built scripts; can't use /scripts here because themes already are
|
||||||
server.use('/built/scripts', express['static'](path.join(__dirname, '/built/scripts'), {
|
server.use('/built/scripts', express['static'](path.join(__dirname, '/built/scripts'), {
|
||||||
// Put a maxAge of one year on built scripts
|
// Put a maxAge of one year on built scripts
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
var Ghost = require('../../ghost'),
|
var Ghost = require('../../ghost'),
|
||||||
_ = require('underscore'),
|
_ = require('underscore'),
|
||||||
fs = require('fs-extra'),
|
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
api = require('../api'),
|
api = require('../api'),
|
||||||
moment = require('moment'),
|
|
||||||
errors = require('../errorHandling'),
|
errors = require('../errorHandling'),
|
||||||
|
storage = require('../storage'),
|
||||||
|
|
||||||
ghost = new Ghost(),
|
ghost = new Ghost(),
|
||||||
dataProvider = ghost.dataProvider,
|
dataProvider = ghost.dataProvider,
|
||||||
|
@ -44,35 +43,20 @@ function setSelected(list, name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
adminControllers = {
|
adminControllers = {
|
||||||
'get_storage': function () {
|
|
||||||
// TODO this is where the check for storage plugins should go
|
|
||||||
// Local file system is the default
|
|
||||||
var storageChoice = 'localfilesystem.js';
|
|
||||||
return require('./storage/' + storageChoice);
|
|
||||||
},
|
|
||||||
'uploader': function (req, res) {
|
'uploader': function (req, res) {
|
||||||
var type = req.files.uploadimage.type,
|
var type = req.files.uploadimage.type,
|
||||||
ext = path.extname(req.files.uploadimage.name).toLowerCase(),
|
ext = path.extname(req.files.uploadimage.name).toLowerCase(),
|
||||||
storage = adminControllers.get_storage();
|
store = storage.get_storage();
|
||||||
|
|
||||||
if ((type !== 'image/jpeg' && type !== 'image/png' && type !== 'image/gif')
|
if ((type !== 'image/jpeg' && type !== 'image/png' && type !== 'image/gif')
|
||||||
|| (ext !== '.jpg' && ext !== '.jpeg' && ext !== '.png' && ext !== '.gif')) {
|
|| (ext !== '.jpg' && ext !== '.jpeg' && ext !== '.png' && ext !== '.gif')) {
|
||||||
return res.send(415, 'Unsupported Media Type');
|
return res.send(415, 'Unsupported Media Type');
|
||||||
}
|
}
|
||||||
|
|
||||||
storage
|
store
|
||||||
.save(new Date().getTime(), req.files.uploadimage)
|
.save(req.files.uploadimage)
|
||||||
.then(function (url) {
|
.then(function (url) {
|
||||||
|
return res.send(url);
|
||||||
// delete the temporary file
|
|
||||||
// TODO convert to promise using nodefn
|
|
||||||
fs.unlink(req.files.uploadimage.path, function (e) {
|
|
||||||
if (e) {
|
|
||||||
return errors.logError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.send(url);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.otherwise(function (e) {
|
.otherwise(function (e) {
|
||||||
return errors.logError(e);
|
return errors.logError(e);
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
// # Local File System Image Storage module
|
|
||||||
// The (default) module for storing images, using the local file system
|
|
||||||
|
|
||||||
var errors = require('../../errorHandling'),
|
|
||||||
fs = require('fs-extra'),
|
|
||||||
moment = require('moment'),
|
|
||||||
nodefn = require('when/node/function'),
|
|
||||||
path = require('path'),
|
|
||||||
when = require('when');
|
|
||||||
|
|
||||||
var localfilesystem;
|
|
||||||
|
|
||||||
// TODO: this could be a separate module
|
|
||||||
function getUniqueFileName(dir, name, ext, i, done) {
|
|
||||||
var filename,
|
|
||||||
append = '';
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
append = '-' + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = path.join(dir, name + append + ext);
|
|
||||||
fs.exists(filename, function (exists) {
|
|
||||||
if (exists) {
|
|
||||||
setImmediate(function () {
|
|
||||||
i = i + 1;
|
|
||||||
return getUniqueFileName(dir, name, ext, i, done);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return done(filename);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ## Module interface
|
|
||||||
localfilesystem = {
|
|
||||||
|
|
||||||
// ### Save
|
|
||||||
// Saves the image to storage (the file system)
|
|
||||||
// - date is current date in ticks
|
|
||||||
// - image is the express image object
|
|
||||||
// - returns a promise which ultimately returns the full url to the uploaded image
|
|
||||||
'save': function (date, image) {
|
|
||||||
|
|
||||||
// QUESTION is it okay for this module to know about content/images?
|
|
||||||
var saved = when.defer(),
|
|
||||||
m = moment(date),
|
|
||||||
month = m.format('MMM'),
|
|
||||||
year = m.format('YYYY'),
|
|
||||||
target_dir = path.join('content/images', year, month),
|
|
||||||
ext = path.extname(image.name),
|
|
||||||
basename = path.basename(image.name, ext).replace(/[\W]/gi, '_');
|
|
||||||
|
|
||||||
getUniqueFileName(target_dir, basename, ext, null, function (filename) {
|
|
||||||
nodefn.call(fs.mkdirs, target_dir).then(function () {
|
|
||||||
return nodefn.call(fs.copy, image.path, filename);
|
|
||||||
}).then(function () {
|
|
||||||
// The src for the image must be in URI format, not a file system path, which in Windows uses \
|
|
||||||
// For local file system storage can use relative path so add a slash
|
|
||||||
var fullUrl = ('/' + filename).replace(new RegExp('\\' + path.sep, 'g'), '/');
|
|
||||||
return saved.resolve(fullUrl);
|
|
||||||
}).otherwise(function (e) {
|
|
||||||
errors.logError(e);
|
|
||||||
return saved.reject(e);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return saved.promise;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = localfilesystem;
|
|
53
core/server/storage/base.js
Normal file
53
core/server/storage/base.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
var _ = require('underscore'),
|
||||||
|
moment = require('moment'),
|
||||||
|
path = require('path'),
|
||||||
|
when = require('when'),
|
||||||
|
baseStore;
|
||||||
|
|
||||||
|
// TODO: would probably be better to put these on the prototype and have proper constructors etc
|
||||||
|
baseStore = {
|
||||||
|
'getTargetDir': function (baseDir) {
|
||||||
|
var m = moment(new Date().getTime()),
|
||||||
|
month = m.format('MMM'),
|
||||||
|
year = m.format('YYYY');
|
||||||
|
|
||||||
|
if (baseDir) {
|
||||||
|
return path.join(baseDir, year, month);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.join(year, month);
|
||||||
|
},
|
||||||
|
'generateUnique': function (store, dir, name, ext, i, done) {
|
||||||
|
var self = this,
|
||||||
|
filename,
|
||||||
|
append = '';
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
append = '-' + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = path.join(dir, name + append + ext);
|
||||||
|
|
||||||
|
store.exists(filename).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
setImmediate(function () {
|
||||||
|
i = i + 1;
|
||||||
|
self.generateUnique(store, dir, name, ext, i, done);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
done.resolve(filename);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'getUniqueFileName': function (store, image, targetDir) {
|
||||||
|
var done = when.defer(),
|
||||||
|
ext = path.extname(image.name),
|
||||||
|
name = path.basename(image.name, ext).replace(/[\W]/gi, '_');
|
||||||
|
|
||||||
|
this.generateUnique(store, targetDir, name, ext, 0, done);
|
||||||
|
|
||||||
|
return done.promise;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = baseStore;
|
22
core/server/storage/index.js
Normal file
22
core/server/storage/index.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
var errors = require('../errorHandling'),
|
||||||
|
storage;
|
||||||
|
|
||||||
|
function get_storage() {
|
||||||
|
// TODO: this is where the check for storage plugins should go
|
||||||
|
// Local file system is the default
|
||||||
|
var storageChoice = 'localfilesystem';
|
||||||
|
|
||||||
|
if (storage) {
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: determine if storage has all the necessary methods
|
||||||
|
storage = require('./' + storageChoice);
|
||||||
|
} catch (e) {
|
||||||
|
errors.logError(e);
|
||||||
|
}
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.get_storage = get_storage;
|
62
core/server/storage/localfilesystem.js
Normal file
62
core/server/storage/localfilesystem.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// # Local File System Image Storage module
|
||||||
|
// The (default) module for storing images, using the local file system
|
||||||
|
|
||||||
|
var _ = require('underscore'),
|
||||||
|
express = require('express'),
|
||||||
|
fs = require('fs-extra'),
|
||||||
|
nodefn = require('when/node/function'),
|
||||||
|
path = require('path'),
|
||||||
|
when = require('when'),
|
||||||
|
errors = require('../errorHandling'),
|
||||||
|
baseStore = require('./base'),
|
||||||
|
|
||||||
|
localFileStore,
|
||||||
|
localDir = 'content/images';
|
||||||
|
|
||||||
|
localFileStore = _.extend(baseStore, {
|
||||||
|
// ### Save
|
||||||
|
// Saves the image to storage (the file system)
|
||||||
|
// - image is the express image object
|
||||||
|
// - returns a promise which ultimately returns the full url to the uploaded image
|
||||||
|
'save': function (image) {
|
||||||
|
var saved = when.defer(),
|
||||||
|
targetDir = this.getTargetDir(localDir);
|
||||||
|
|
||||||
|
this.getUniqueFileName(this, image, targetDir).then(function (filename) {
|
||||||
|
nodefn.call(fs.mkdirs, targetDir).then(function () {
|
||||||
|
return nodefn.call(fs.copy, image.path, filename);
|
||||||
|
}).then(function () {
|
||||||
|
// we should remove the temporary image
|
||||||
|
return nodefn.call(fs.unlink, image.path).otherwise(errors.logError);
|
||||||
|
}).then(function () {
|
||||||
|
// The src for the image must be in URI format, not a file system path, which in Windows uses \
|
||||||
|
// For local file system storage can use relative path so add a slash
|
||||||
|
var fullUrl = ('/' + filename).replace(new RegExp('\\' + path.sep, 'g'), '/');
|
||||||
|
return saved.resolve(fullUrl);
|
||||||
|
}).otherwise(function (e) {
|
||||||
|
errors.logError(e);
|
||||||
|
return saved.reject(e);
|
||||||
|
});
|
||||||
|
}).otherwise(errors.logError);
|
||||||
|
|
||||||
|
return saved.promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
'exists': function (filename) {
|
||||||
|
// fs.exists does not play nicely with nodefn because the callback doesn't have an error argument
|
||||||
|
var done = when.defer();
|
||||||
|
|
||||||
|
fs.exists(filename, function (exists) {
|
||||||
|
done.resolve(exists);
|
||||||
|
});
|
||||||
|
|
||||||
|
return done.promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
// middleware for serving the files
|
||||||
|
'serve': function () {
|
||||||
|
return express['static'](path.join(__dirname, '/../../../', localDir));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = localFileStore;
|
|
@ -1,8 +1,9 @@
|
||||||
/*globals describe, beforeEach, it*/
|
/*globals describe, beforeEach, it*/
|
||||||
var fs = require('fs-extra'),
|
var fs = require('fs-extra'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
when = require('when'),
|
||||||
|
storage = require('../../server/storage'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
admin = require('../../server/controllers/admin');
|
admin = require('../../server/controllers/admin');
|
||||||
|
@ -10,7 +11,7 @@ var fs = require('fs-extra'),
|
||||||
describe('Admin Controller', function () {
|
describe('Admin Controller', function () {
|
||||||
describe('uploader', function () {
|
describe('uploader', function () {
|
||||||
|
|
||||||
var req, res, storage;
|
var req, res, store;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
req = {
|
req = {
|
||||||
|
@ -26,20 +27,22 @@ describe('Admin Controller', function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storage = sinon.stub();
|
store = sinon.stub();
|
||||||
storage.save = sinon.stub().returns(when('URL'));
|
store.save = sinon.stub().returns(when('URL'));
|
||||||
sinon.stub(admin, 'get_storage').returns(storage);
|
store.exists = sinon.stub().returns(when(true));
|
||||||
|
store.destroy = sinon.stub().returns(when());
|
||||||
|
sinon.stub(storage, 'get_storage').returns(store);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
admin.get_storage.restore();
|
storage.get_storage.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('can not upload invalid file', function () {
|
describe('can not upload invalid file', function () {
|
||||||
it('should return 415 for invalid file type', function () {
|
it('should return 415 for invalid file type', function () {
|
||||||
res.send = sinon.stub();
|
res.send = sinon.stub();
|
||||||
req.files.uploadimage.name = 'INVALID.FILE';
|
req.files.uploadimage.name = 'INVALID.FILE';
|
||||||
req.files.uploadimage.type = 'application/octet-stream'
|
req.files.uploadimage.type = 'application/octet-stream';
|
||||||
admin.uploader(req, res);
|
admin.uploader(req, res);
|
||||||
res.send.calledOnce.should.be.true;
|
res.send.calledOnce.should.be.true;
|
||||||
res.send.args[0][0].should.equal(415);
|
res.send.args[0][0].should.equal(415);
|
||||||
|
@ -112,16 +115,6 @@ describe('Admin Controller', function () {
|
||||||
admin.uploader(req, res);
|
admin.uploader(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not leave temporary file when uploading', function (done) {
|
|
||||||
sinon.stub(res, 'send', function (data) {
|
|
||||||
fs.unlink.calledOnce.should.be.true;
|
|
||||||
fs.unlink.args[0][0].should.equal('/tmp/TMPFILEID');
|
|
||||||
return done();
|
|
||||||
});
|
|
||||||
|
|
||||||
admin.uploader(req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should send correct url', function (done) {
|
it('should send correct url', function (done) {
|
||||||
sinon.stub(res, 'send', function (data) {
|
sinon.stub(res, 'send', function (data) {
|
||||||
data.should.equal('URL');
|
data.should.equal('URL');
|
||||||
|
|
|
@ -4,9 +4,9 @@ var fs = require('fs-extra'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
when = require('when'),
|
||||||
localfilesystem = require('../../server/controllers/storage/localfilesystem');
|
localfilesystem = require('../../server/storage/localfilesystem');
|
||||||
|
|
||||||
describe('Local File System Storage', function() {
|
describe('Local File System Storage', function () {
|
||||||
|
|
||||||
var image;
|
var image;
|
||||||
|
|
||||||
|
@ -14,32 +14,36 @@ describe('Local File System Storage', function() {
|
||||||
sinon.stub(fs, 'mkdirs').yields();
|
sinon.stub(fs, 'mkdirs').yields();
|
||||||
sinon.stub(fs, 'copy').yields();
|
sinon.stub(fs, 'copy').yields();
|
||||||
sinon.stub(fs, 'exists').yields(false);
|
sinon.stub(fs, 'exists').yields(false);
|
||||||
|
sinon.stub(fs, 'unlink').yields();
|
||||||
|
|
||||||
image = {
|
image = {
|
||||||
path: "tmp/123456.jpg",
|
path: "tmp/123456.jpg",
|
||||||
name: "IMAGE.jpg",
|
name: "IMAGE.jpg",
|
||||||
type: "image/jpeg"
|
type: "image/jpeg"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sat Sep 07 2013 21:24
|
||||||
|
this.clock = sinon.useFakeTimers(new Date(2013, 8, 7, 21, 24).getTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
fs.mkdirs.restore();
|
fs.mkdirs.restore();
|
||||||
fs.copy.restore();
|
fs.copy.restore();
|
||||||
fs.exists.restore();
|
fs.exists.restore();
|
||||||
|
fs.unlink.restore();
|
||||||
|
this.clock.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send correct path to image when date is in Sep 2013', function (done) {
|
it('should send correct path to image when date is in Sep 2013', function (done) {
|
||||||
// Sat Sep 07 2013 21:24
|
localfilesystem.save(image).then(function (url) {
|
||||||
var date = new Date(2013, 8, 7, 21, 24).getTime();
|
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
|
||||||
url.should.equal('/content/images/2013/Sep/IMAGE.jpg');
|
url.should.equal('/content/images/2013/Sep/IMAGE.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send correct path to image when original file has spaces', function (done) {
|
it('should send correct path to image when original file has spaces', function (done) {
|
||||||
var date = new Date(2013, 8, 7, 21, 24).getTime();
|
|
||||||
image.name = 'AN IMAGE.jpg';
|
image.name = 'AN IMAGE.jpg';
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
localfilesystem.save(image).then(function (url) {
|
||||||
url.should.equal('/content/images/2013/Sep/AN_IMAGE.jpg');
|
url.should.equal('/content/images/2013/Sep/AN_IMAGE.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
|
@ -47,17 +51,15 @@ describe('Local File System Storage', function() {
|
||||||
|
|
||||||
it('should send correct path to image when date is in Jan 2014', function (done) {
|
it('should send correct path to image when date is in Jan 2014', function (done) {
|
||||||
// Jan 1 2014 12:00
|
// Jan 1 2014 12:00
|
||||||
var date = new Date(2014, 0, 1, 12).getTime();
|
this.clock = sinon.useFakeTimers(new Date(2014, 0, 1, 12).getTime());
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
localfilesystem.save(image).then(function (url) {
|
||||||
url.should.equal('/content/images/2014/Jan/IMAGE.jpg');
|
url.should.equal('/content/images/2014/Jan/IMAGE.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create month and year directory', function (done) {
|
it('should create month and year directory', function (done) {
|
||||||
// Sat Sep 07 2013 21:24
|
localfilesystem.save(image).then(function (url) {
|
||||||
var date = new Date(2013, 8, 7, 21, 24).getTime();
|
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
|
||||||
fs.mkdirs.calledOnce.should.be.true;
|
fs.mkdirs.calledOnce.should.be.true;
|
||||||
fs.mkdirs.args[0][0].should.equal(path.join('content/images/2013/Sep'));
|
fs.mkdirs.args[0][0].should.equal(path.join('content/images/2013/Sep'));
|
||||||
done();
|
done();
|
||||||
|
@ -65,9 +67,7 @@ describe('Local File System Storage', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should copy temp file to new location', function (done) {
|
it('should copy temp file to new location', function (done) {
|
||||||
// Sat Sep 07 2013 21:24
|
localfilesystem.save(image).then(function (url) {
|
||||||
var date = new Date(2013, 8, 7, 21, 24).getTime();
|
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
|
||||||
fs.copy.calledOnce.should.be.true;
|
fs.copy.calledOnce.should.be.true;
|
||||||
fs.copy.args[0][0].should.equal('tmp/123456.jpg');
|
fs.copy.args[0][0].should.equal('tmp/123456.jpg');
|
||||||
fs.copy.args[0][1].should.equal(path.join('content/images/2013/Sep/IMAGE.jpg'));
|
fs.copy.args[0][1].should.equal(path.join('content/images/2013/Sep/IMAGE.jpg'));
|
||||||
|
@ -75,10 +75,17 @@ describe('Local File System Storage', function() {
|
||||||
}).then(null, done);
|
}).then(null, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not leave temporary file when uploading', function (done) {
|
||||||
|
localfilesystem.save(image).then(function (url) {
|
||||||
|
fs.unlink.calledOnce.should.be.true;
|
||||||
|
fs.unlink.args[0][0].should.equal('tmp/123456.jpg');
|
||||||
|
done();
|
||||||
|
}).then(null, done);
|
||||||
|
});
|
||||||
|
|
||||||
it('can upload two different images with the same name without overwriting the first', function (done) {
|
it('can upload two different images with the same name without overwriting the first', function (done) {
|
||||||
// Sun Sep 08 2013 10:57
|
// Sun Sep 08 2013 10:57
|
||||||
var date = new Date(2013, 8, 8, 10, 57).getTime();
|
this.clock = sinon.useFakeTimers(new Date(2013, 8, 8, 10, 57).getTime());
|
||||||
clock = sinon.useFakeTimers(date);
|
|
||||||
fs.exists.withArgs('content/images/2013/Sep/IMAGE.jpg').yields(true);
|
fs.exists.withArgs('content/images/2013/Sep/IMAGE.jpg').yields(true);
|
||||||
fs.exists.withArgs('content/images/2013/Sep/IMAGE-1.jpg').yields(false);
|
fs.exists.withArgs('content/images/2013/Sep/IMAGE-1.jpg').yields(false);
|
||||||
|
|
||||||
|
@ -87,7 +94,7 @@ describe('Local File System Storage', function() {
|
||||||
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE.jpg').yields(true);
|
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE.jpg').yields(true);
|
||||||
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-1.jpg').yields(false);
|
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-1.jpg').yields(false);
|
||||||
|
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
localfilesystem.save(image).then(function (url) {
|
||||||
url.should.equal('/content/images/2013/Sep/IMAGE-1.jpg');
|
url.should.equal('/content/images/2013/Sep/IMAGE-1.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
|
@ -95,8 +102,7 @@ describe('Local File System Storage', function() {
|
||||||
|
|
||||||
it('can upload five different images with the same name without overwriting the first', function (done) {
|
it('can upload five different images with the same name without overwriting the first', function (done) {
|
||||||
// Sun Sep 08 2013 10:57
|
// Sun Sep 08 2013 10:57
|
||||||
var date = new Date(2013, 8, 8, 10, 57).getTime();
|
this.clock = sinon.useFakeTimers(new Date(2013, 8, 8, 10, 57).getTime());
|
||||||
clock = sinon.useFakeTimers(date);
|
|
||||||
fs.exists.withArgs('content/images/2013/Sep/IMAGE.jpg').yields(true);
|
fs.exists.withArgs('content/images/2013/Sep/IMAGE.jpg').yields(true);
|
||||||
fs.exists.withArgs('content/images/2013/Sep/IMAGE-1.jpg').yields(true);
|
fs.exists.withArgs('content/images/2013/Sep/IMAGE-1.jpg').yields(true);
|
||||||
fs.exists.withArgs('content/images/2013/Sep/IMAGE-2.jpg').yields(true);
|
fs.exists.withArgs('content/images/2013/Sep/IMAGE-2.jpg').yields(true);
|
||||||
|
@ -110,7 +116,7 @@ describe('Local File System Storage', function() {
|
||||||
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-3.jpg').yields(true);
|
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-3.jpg').yields(true);
|
||||||
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-4.jpg').yields(false);
|
fs.exists.withArgs('content\\images\\2013\\Sep\\IMAGE-4.jpg').yields(false);
|
||||||
|
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
localfilesystem.save(image).then(function (url) {
|
||||||
url.should.equal('/content/images/2013/Sep/IMAGE-4.jpg');
|
url.should.equal('/content/images/2013/Sep/IMAGE-4.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
|
@ -134,8 +140,7 @@ describe('Local File System Storage', function() {
|
||||||
it('should return url in proper format for windows', function (done) {
|
it('should return url in proper format for windows', function (done) {
|
||||||
path.sep = '\\';
|
path.sep = '\\';
|
||||||
path.join.returns('content\\images\\2013\\Sep\\IMAGE.jpg');
|
path.join.returns('content\\images\\2013\\Sep\\IMAGE.jpg');
|
||||||
var date = new Date(2013, 8, 7, 21, 24).getTime();
|
localfilesystem.save(image).then(function (url) {
|
||||||
localfilesystem.save(date, image).then(function (url) {
|
|
||||||
url.should.equal('/content/images/2013/Sep/IMAGE.jpg');
|
url.should.equal('/content/images/2013/Sep/IMAGE.jpg');
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue