commit
8b32412f98
7 changed files with 606 additions and 67 deletions
@ -0,0 +1,86 @@ |
||||
'use strict'; |
||||
|
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
const Readable = require('stream').Readable; |
||||
|
||||
/** |
||||
* Returns true if argument is function. |
||||
*/ |
||||
const isFunc = func => func && func.constructor && func.call && func.apply ? true: false; |
||||
|
||||
/** |
||||
* Creates a folder for file specified in the path variable |
||||
* @param {Object} fileUploadOptions |
||||
* @param {String} filePath |
||||
*/ |
||||
const checkAndMakeDir = function(fileUploadOptions, filePath){ |
||||
//Check upload options were set.
|
||||
if (!fileUploadOptions) return false; |
||||
if (!fileUploadOptions.createParentPath) return false; |
||||
//Check whether folder for the file exists.
|
||||
if (!filePath) return false; |
||||
const parentPath = path.dirname(filePath); |
||||
//Create folder if it is not exists.
|
||||
if (!fs.existsSync(parentPath)) fs.mkdirSync(parentPath);
|
||||
return true; |
||||
}; |
||||
|
||||
/** |
||||
* Copy file via streams |
||||
* @param {String} src - Path to the source file |
||||
* @param {String} dst - Path to the destination file. |
||||
*/ |
||||
const copyFile = function(src, dst, callback){ |
||||
//cbCalled flag and runCb helps to run cb only once.
|
||||
let cbCalled = false; |
||||
let runCb = (err) => { |
||||
if (cbCalled) return; |
||||
cbCalled = true; |
||||
callback(err); |
||||
}; |
||||
//Create read stream
|
||||
let readable = fs.createReadStream(src); |
||||
readable.on('error', runCb); |
||||
//Create write stream
|
||||
let writable = fs.createWriteStream(dst); |
||||
writable.on('error', (err)=>{ |
||||
readable.destroy(); |
||||
runCb(err); |
||||
}); |
||||
writable.on('close', () => runCb()); |
||||
//Copy file via piping streams.
|
||||
readable.pipe(writable); |
||||
}; |
||||
|
||||
/** |
||||
* Save buffer data to a file. |
||||
* @param {Buffer} buffer - buffer to save to a file. |
||||
* @param {String} filePath - path to a file. |
||||
*/ |
||||
const saveBufferToFile = function(buffer, filePath, callback){ |
||||
if (!Buffer.isBuffer(buffer)){ |
||||
callback(new Error('buffer variable should be a Buffer!')); |
||||
return; |
||||
} |
||||
//Setup readable stream from buffer.
|
||||
let streamData = buffer; |
||||
let readStream = Readable(); |
||||
readStream._read = ()=>{ |
||||
readStream.push(streamData); |
||||
streamData = null; |
||||
}; |
||||
//Setup file system writable stream.
|
||||
let fstream = fs.createWriteStream(filePath); |
||||
fstream.on('error', error => callback(error)); |
||||
fstream.on('close', () => callback()); |
||||
//Copy file via piping streams.
|
||||
readStream.pipe(fstream); |
||||
}; |
||||
|
||||
module.exports = { |
||||
isFunc, |
||||
checkAndMakeDir, |
||||
copyFile, |
||||
saveBufferToFile |
||||
}; |
@ -0,0 +1,156 @@ |
||||
'use strict'; |
||||
|
||||
const assert = require('assert'); |
||||
const path = require('path'); |
||||
const fs = require('fs'); |
||||
const md5 = require('md5'); |
||||
const server = require('./server'); |
||||
const fileDir = server.fileDir; |
||||
const uploadDir = server.uploadDir; |
||||
|
||||
const { |
||||
isFunc, |
||||
checkAndMakeDir, |
||||
copyFile, |
||||
saveBufferToFile |
||||
} = require('../lib/utilities.js'); |
||||
|
||||
|
||||
const mockFile = 'basketball.png'; |
||||
const mockBuffer = fs.readFileSync(path.join(fileDir, mockFile)); |
||||
const mockHash = md5(mockBuffer); |
||||
|
||||
|
||||
describe('Test of the utilities functions', function() { |
||||
beforeEach(function() { |
||||
server.clearUploadsDir(); |
||||
}); |
||||
//isFunc tests
|
||||
describe('Test isFunc function', () => { |
||||
|
||||
it('isFunc returns true if function passed', () => assert.equal(isFunc(()=>{}), true)); |
||||
|
||||
it('isFunc returns false if null passed', function() { |
||||
assert.equal(isFunc(null), false); |
||||
}); |
||||
|
||||
it('isFunc returns false if undefined passed', function() { |
||||
assert.equal(isFunc(undefined), false); |
||||
}); |
||||
|
||||
it('isFunc returns false if object passed', function() { |
||||
assert.equal(isFunc({}), false); |
||||
}); |
||||
|
||||
it('isFunc returns false if array passed', function() { |
||||
assert.equal(isFunc([]), false); |
||||
}); |
||||
}); |
||||
//checkAndMakeDir tests
|
||||
describe('Test checkAndMakeDir function', () => { |
||||
//
|
||||
it('checkAndMakeDir returns false if upload options object was not set', () => { |
||||
assert.equal(checkAndMakeDir(), false); |
||||
}); |
||||
//
|
||||
it('checkAndMakeDir returns false if upload option createParentPath was not set', () => { |
||||
assert.equal(checkAndMakeDir({}), false); |
||||
}); |
||||
//
|
||||
it('checkAndMakeDir returns false if filePath was not set', () => { |
||||
assert.equal(checkAndMakeDir({createParentPath: true}), false); |
||||
}); |
||||
//
|
||||
it('checkAndMakeDir return true if path to the file already exists', ()=>{ |
||||
let dir = path.join(uploadDir, 'testfile'); |
||||
assert.equal(checkAndMakeDir({createParentPath: true}, dir), true); |
||||
}); |
||||
//
|
||||
it('checkAndMakeDir creates a dir if path to the file not exists', ()=>{ |
||||
let dir = path.join(uploadDir, 'testfolder', 'testfile'); |
||||
assert.equal(checkAndMakeDir({createParentPath: true}, dir), true); |
||||
}); |
||||
}); |
||||
//saveBufferToFile tests
|
||||
describe('Test saveBufferToFile function', function(){ |
||||
beforeEach(function() { |
||||
server.clearUploadsDir(); |
||||
}); |
||||
|
||||
it('Save buffer to a file', function(done) { |
||||
let filePath = path.join(uploadDir, mockFile); |
||||
saveBufferToFile(mockBuffer, filePath, function(err){ |
||||
if (err) { |
||||
return done(err); |
||||
} |
||||
fs.stat(filePath, done); |
||||
}); |
||||
}); |
||||
|
||||
it('Failed if not a buffer passed', function(done) { |
||||
let filePath = path.join(uploadDir, mockFile); |
||||
saveBufferToFile(undefined, filePath, function(err){ |
||||
if (err) { |
||||
return done(); |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
it('Failed if wrong path passed', function(done) { |
||||
let filePath = ''; |
||||
saveBufferToFile(mockFile, filePath, function(err){ |
||||
if (err) { |
||||
return done(); |
||||
} |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
describe('Test copyFile function', function(){ |
||||
beforeEach(function() { |
||||
server.clearUploadsDir(); |
||||
}); |
||||
|
||||
it('Copy a file and check a hash', function(done) { |
||||
let srcPath = path.join(fileDir, mockFile); |
||||
let dstPath = path.join(uploadDir, mockFile); |
||||
|
||||
copyFile(srcPath, dstPath, function(err){ |
||||
if (err) { |
||||
return done(err); |
||||
} |
||||
fs.stat(dstPath, (err)=>{ |
||||
if (err){ |
||||
return done(err); |
||||
} |
||||
//Match source and destination files hash.
|
||||
let fileBuffer = fs.readFileSync(dstPath); |
||||
let fileHash = md5(fileBuffer); |
||||
return (fileHash === mockHash) ? done() : done(err); |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
it('Failed if wrong source file path passed', function(done){ |
||||
let srcPath = path.join(fileDir, 'unknown'); |
||||
let dstPath = path.join(uploadDir, mockFile); |
||||
|
||||
copyFile(srcPath, dstPath, function(err){ |
||||
if (err) { |
||||
return done(); |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
it('Failed if wrong destination file path passed', function(done){ |
||||
let srcPath = path.join(fileDir, 'unknown'); |
||||
let dstPath = path.join('unknown', 'unknown'); |
||||
|
||||
copyFile(srcPath, dstPath, function(err){ |
||||
if (err) { |
||||
return done(); |
||||
} |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
Loading…
Reference in new issue