/* eslint-disable handle-callback-err, no-return-assign, no-unused-vars, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const { assert } = require("chai"); const sinon = require('sinon'); const chai = require('chai'); const { should } = chai; const { expect } = chai; const modulePath = "../../../app/js/FSPersistorManager.js"; const SandboxedModule = require('sandboxed-module'); const fs = require("fs"); const response = require("response"); describe("FSPersistorManagerTests", function() { beforeEach(function() { this.Fs = { rename:sinon.stub(), createReadStream:sinon.stub(), createWriteStream:sinon.stub(), unlink:sinon.stub(), rmdir:sinon.stub(), exists:sinon.stub(), readdir:sinon.stub(), open:sinon.stub(), openSync:sinon.stub(), fstatSync:sinon.stub(), closeSync:sinon.stub(), stat:sinon.stub() }; this.Rimraf = sinon.stub(); this.LocalFileWriter = { writeStream: sinon.stub(), deleteFile: sinon.stub() }; this.requires = { "./LocalFileWriter":this.LocalFileWriter, "fs":this.Fs, "logger-sharelatex": { log() {}, err() {} }, "response":response, "rimraf":this.Rimraf, "./Errors": (this.Errors = {NotFoundError: sinon.stub()}) }; this.location = "/tmp"; this.name1 = "530f2407e7ef165704000007/530f838b46d9a9e859000008"; this.name1Filtered ="530f2407e7ef165704000007_530f838b46d9a9e859000008"; this.name2 = "second_file"; this.error = "error_message"; return this.FSPersistorManager = SandboxedModule.require(modulePath, {requires: this.requires}); }); describe("sendFile", function() { beforeEach(function() { return this.Fs.createReadStream = sinon.stub().returns({ on() {}, pipe() {} }); }); it("should copy the file", function(done) { this.Fs.createWriteStream =sinon.stub().returns({ on(event, handler) { if (event === 'finish') { return process.nextTick(handler); } } }); return this.FSPersistorManager.sendFile(this.location, this.name1, this.name2, err=> { this.Fs.createReadStream.calledWith(this.name2).should.equal(true); this.Fs.createWriteStream.calledWith(`${this.location}/${this.name1Filtered}` ).should.equal(true); return done(); }); }); return it("should return an error if the file cannot be stored", function(done) { this.Fs.createWriteStream =sinon.stub().returns({ on: (event, handler) => { if (event === 'error') { return process.nextTick(() => { return handler(this.error); }); } } }); return this.FSPersistorManager.sendFile(this.location, this.name1, this.name2, err=> { this.Fs.createReadStream.calledWith(this.name2).should.equal(true); this.Fs.createWriteStream.calledWith(`${this.location}/${this.name1Filtered}` ).should.equal(true); err.should.equal(this.error); return done(); }); }); }); describe("sendStream", function() { beforeEach(function() { this.FSPersistorManager.sendFile = sinon.stub().callsArgWith(3); this.LocalFileWriter.writeStream.callsArgWith(2, null, this.name1); this.LocalFileWriter.deleteFile.callsArg(1); return this.SourceStream = {on() {}}; }); it("should sent stream to LocalFileWriter", function(done){ return this.FSPersistorManager.sendStream(this.location, this.name1, this.SourceStream, () => { this.LocalFileWriter.writeStream.calledWith(this.SourceStream).should.equal(true); return done(); }); }); it("should return the error from LocalFileWriter", function(done){ this.LocalFileWriter.writeStream.callsArgWith(2, this.error); return this.FSPersistorManager.sendStream(this.location, this.name1, this.SourceStream, err=> { err.should.equal(this.error); return done(); }); }); return it("should send the file to the filestore", function(done){ this.LocalFileWriter.writeStream.callsArgWith(2); return this.FSPersistorManager.sendStream(this.location, this.name1, this.SourceStream, err=> { this.FSPersistorManager.sendFile.called.should.equal(true); return done(); }); }); }); describe("getFileStream", function() { beforeEach(function() { return this.opts = {};}); it("should use correct file location", function(done) { this.FSPersistorManager.getFileStream(this.location, this.name1, this.opts, (err,res) => {}); this.Fs.open.calledWith(`${this.location}/${this.name1Filtered}`).should.equal(true); return done(); }); describe("with start and end options", function() { beforeEach(function() { this.fd = 2019; this.opts_in = {start: 0, end: 8}; this.opts = {start: 0, end: 8, fd: this.fd}; return this.Fs.open.callsArgWith(2, null, this.fd); }); return it('should pass the options to createReadStream', function(done) { this.FSPersistorManager.getFileStream(this.location, this.name1, this.opts_in, (err,res)=> {}); this.Fs.createReadStream.calledWith(null, this.opts).should.equal(true); return done(); }); }); return describe("error conditions", function() { describe("when the file does not exist", function() { beforeEach(function() { this.fakeCode = 'ENOENT'; const err = new Error(); err.code = this.fakeCode; return this.Fs.open.callsArgWith(2, err, null); }); return it("should give a NotFoundError", function(done) { return this.FSPersistorManager.getFileStream(this.location, this.name1, this.opts, (err,res)=> { expect(res).to.equal(null); expect(err).to.not.equal(null); expect(err instanceof this.Errors.NotFoundError).to.equal(true); return done(); }); }); }); return describe("when some other error happens", function() { beforeEach(function() { this.fakeCode = 'SOMETHINGHORRIBLE'; const err = new Error(); err.code = this.fakeCode; return this.Fs.open.callsArgWith(2, err, null); }); return it("should give an Error", function(done) { return this.FSPersistorManager.getFileStream(this.location, this.name1, this.opts, (err,res)=> { expect(res).to.equal(null); expect(err).to.not.equal(null); expect(err instanceof Error).to.equal(true); return done(); }); }); }); }); }); describe("getFileSize", function() { it("should return the file size", function(done) { const expectedFileSize = 75382; this.Fs.stat.yields(new Error("fs.stat got unexpected arguments")); this.Fs.stat.withArgs(`${this.location}/${this.name1Filtered}`) .yields(null, { size: expectedFileSize }); return this.FSPersistorManager.getFileSize(this.location, this.name1, (err, fileSize) => { if (err != null) { return done(err); } expect(fileSize).to.equal(expectedFileSize); return done(); }); }); it("should throw a NotFoundError if the file does not exist", function(done) { const error = new Error(); error.code = "ENOENT"; this.Fs.stat.yields(error); return this.FSPersistorManager.getFileSize(this.location, this.name1, (err, fileSize) => { expect(err).to.be.instanceof(this.Errors.NotFoundError); return done(); }); }); return it("should rethrow any other error", function(done) { const error = new Error(); this.Fs.stat.yields(error); return this.FSPersistorManager.getFileSize(this.location, this.name1, (err, fileSize) => { expect(err).to.equal(error); return done(); }); }); }); describe("copyFile", function() { beforeEach(function() { this.ReadStream= { on() {}, pipe:sinon.stub() }; this.WriteStream= {on() {}}; this.Fs.createReadStream.returns(this.ReadStream); return this.Fs.createWriteStream.returns(this.WriteStream); }); it("Should open the source for reading", function(done) { this.FSPersistorManager.copyFile(this.location, this.name1, this.name2, function() {}); this.Fs.createReadStream.calledWith(`${this.location}/${this.name1Filtered}`).should.equal(true); return done(); }); it("Should open the target for writing", function(done) { this.FSPersistorManager.copyFile(this.location, this.name1, this.name2, function() {}); this.Fs.createWriteStream.calledWith(`${this.location}/${this.name2}`).should.equal(true); return done(); }); return it("Should pipe the source to the target", function(done) { this.FSPersistorManager.copyFile(this.location, this.name1, this.name2, function() {}); this.ReadStream.pipe.calledWith(this.WriteStream).should.equal(true); return done(); }); }); describe("deleteFile", function() { beforeEach(function() { return this.Fs.unlink.callsArgWith(1,this.error); }); it("Should call unlink with correct options", function(done) { return this.FSPersistorManager.deleteFile(this.location, this.name1, err => { this.Fs.unlink.calledWith(`${this.location}/${this.name1Filtered}`).should.equal(true); return done(); }); }); return it("Should propogate the error", function(done) { return this.FSPersistorManager.deleteFile(this.location, this.name1, err => { err.should.equal(this.error); return done(); }); }); }); describe("deleteDirectory", function() { beforeEach(function() { return this.Rimraf.callsArgWith(1,this.error); }); it("Should call rmdir(rimraf) with correct options", function(done) { return this.FSPersistorManager.deleteDirectory(this.location, this.name1, err => { this.Rimraf.calledWith(`${this.location}/${this.name1Filtered}`).should.equal(true); return done(); }); }); return it("Should propogate the error", function(done) { return this.FSPersistorManager.deleteDirectory(this.location, this.name1, err => { err.should.equal(this.error); return done(); }); }); }); describe("checkIfFileExists", function() { beforeEach(function() { return this.Fs.exists.callsArgWith(1,true); }); it("Should call exists with correct options", function(done) { return this.FSPersistorManager.checkIfFileExists(this.location, this.name1, exists => { this.Fs.exists.calledWith(`${this.location}/${this.name1Filtered}`).should.equal(true); return done(); }); }); // fs.exists simply returns false on any error, so... it("should not return an error", function(done) { return this.FSPersistorManager.checkIfFileExists(this.location, this.name1, (err,exists) => { expect(err).to.be.null; return done(); }); }); it("Should return true for existing files", function(done) { this.Fs.exists.callsArgWith(1,true); return this.FSPersistorManager.checkIfFileExists(this.location, this.name1, (err,exists) => { exists.should.be.true; return done(); }); }); return it("Should return false for non-existing files", function(done) { this.Fs.exists.callsArgWith(1,false); return this.FSPersistorManager.checkIfFileExists(this.location, this.name1, (err,exists) => { exists.should.be.false; return done(); }); }); }); return describe("directorySize", function() { it("should propogate the error", function(done) { this.Fs.readdir.callsArgWith(1, this.error); return this.FSPersistorManager.directorySize(this.location, this.name1, (err, totalsize) => { err.should.equal(this.error); return done(); }); }); return it("should sum directory files size", function(done) { this.Fs.readdir.callsArgWith(1, null, [ {'file1': 'file1'}, {'file2': 'file2'} ]); this.Fs.fstatSync.returns({size : 1024}); return this.FSPersistorManager.directorySize(this.location, this.name1, (err, totalsize) => { expect(totalsize).to.equal(2048); return done(); }); }); }); });