From 5cf7138ef1b9fb0d7883122de863467c8b669189 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Mon, 16 Dec 2019 11:20:22 +0000 Subject: [PATCH] decaffeinate: Convert AWSSDKPersistorManagerTests.coffee and 12 other files to JS --- .../coffee/AWSSDKPersistorManagerTests.js | 541 ++++++++------ .../test/unit/coffee/BucketControllerTests.js | 147 ++-- .../unit/coffee/FSPersistorManagerTests.js | 555 ++++++++------ .../test/unit/coffee/FileControllerTests.js | 419 ++++++----- .../test/unit/coffee/FileConverterTests.js | 167 +++-- .../test/unit/coffee/FileHandlerTests.js | 461 +++++++----- .../test/unit/coffee/ImageOptimiserTests.js | 124 ++-- .../test/unit/coffee/KeybuilderTests.js | 84 ++- .../test/unit/coffee/LocalFileWriterTests.js | 174 +++-- .../test/unit/coffee/PersistorManagerTests.js | 200 ++--- .../unit/coffee/S3PersistorManagerTests.js | 696 ++++++++++-------- .../test/unit/coffee/SafeExecTests.js | 109 +-- .../test/unit/coffee/SettingsTests.js | 44 +- 13 files changed, 2167 insertions(+), 1554 deletions(-) diff --git a/services/filestore/test/unit/coffee/AWSSDKPersistorManagerTests.js b/services/filestore/test/unit/coffee/AWSSDKPersistorManagerTests.js index 92fb968914..cad0f4b805 100644 --- a/services/filestore/test/unit/coffee/AWSSDKPersistorManagerTests.js +++ b/services/filestore/test/unit/coffee/AWSSDKPersistorManagerTests.js @@ -1,272 +1,353 @@ -sinon = require 'sinon' -chai = require 'chai' +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require('sinon'); +const chai = require('chai'); -should = chai.should() -expect = chai.expect +const should = chai.should(); +const { + expect +} = chai; -modulePath = "../../../app/js/AWSSDKPersistorManager.js" -SandboxedModule = require 'sandboxed-module' +const modulePath = "../../../app/js/AWSSDKPersistorManager.js"; +const SandboxedModule = require('sandboxed-module'); -describe "AWSSDKPersistorManager", -> - beforeEach -> - @settings = - filestore: +describe("AWSSDKPersistorManager", function() { + beforeEach(function() { + this.settings = { + filestore: { backend: "aws-sdk" - @s3 = - upload: sinon.stub() - getObject: sinon.stub() - copyObject: sinon.stub() - deleteObject: sinon.stub() - listObjects: sinon.stub() - deleteObjects: sinon.stub() + } + }; + this.s3 = { + upload: sinon.stub(), + getObject: sinon.stub(), + copyObject: sinon.stub(), + deleteObject: sinon.stub(), + listObjects: sinon.stub(), + deleteObjects: sinon.stub(), headObject: sinon.stub() - @awssdk = - S3: sinon.stub().returns @s3 + }; + this.awssdk = + {S3: sinon.stub().returns(this.s3)}; - @requires = - "aws-sdk": @awssdk - "settings-sharelatex": @settings - "logger-sharelatex": - log:-> - err:-> - "fs": @fs = - createReadStream: sinon.stub() - "./Errors": @Errors = - NotFoundError: sinon.stub() - @key = "my/key" - @bucketName = "my-bucket" - @error = "my error" - @AWSSDKPersistorManager = SandboxedModule.require modulePath, requires: @requires + this.requires = { + "aws-sdk": this.awssdk, + "settings-sharelatex": this.settings, + "logger-sharelatex": { + log() {}, + err() {} + }, + "fs": (this.fs = + {createReadStream: sinon.stub()}), + "./Errors": (this.Errors = + {NotFoundError: sinon.stub()}) + }; + this.key = "my/key"; + this.bucketName = "my-bucket"; + this.error = "my error"; + return this.AWSSDKPersistorManager = SandboxedModule.require(modulePath, {requires: this.requires}); + }); - describe "sendFile", -> - beforeEach -> - @stream = {} - @fsPath = "/usr/local/some/file" - @fs.createReadStream.returns @stream + describe("sendFile", function() { + beforeEach(function() { + this.stream = {}; + this.fsPath = "/usr/local/some/file"; + return this.fs.createReadStream.returns(this.stream); + }); - it "should put the file with s3.upload", (done) -> - @s3.upload.callsArgWith 1 - @AWSSDKPersistorManager.sendFile @bucketName, @key, @fsPath, (err) => - expect(err).to.not.be.ok - expect(@s3.upload.calledOnce, "called only once").to.be.true - expect((@s3.upload.calledWith Bucket: @bucketName, Key: @key, Body: @stream) - , "called with correct arguments").to.be.true - done() + it("should put the file with s3.upload", function(done) { + this.s3.upload.callsArgWith(1); + return this.AWSSDKPersistorManager.sendFile(this.bucketName, this.key, this.fsPath, err => { + expect(err).to.not.be.ok; + expect(this.s3.upload.calledOnce, "called only once").to.be.true; + expect((this.s3.upload.calledWith({Bucket: this.bucketName, Key: this.key, Body: this.stream})) + , "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.upload", (done) -> - @s3.upload.callsArgWith 1, @error - @AWSSDKPersistorManager.sendFile @bucketName, @key, @fsPath, (err) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.upload", function(done) { + this.s3.upload.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.sendFile(this.bucketName, this.key, this.fsPath, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); - describe "sendStream", -> - beforeEach -> - @stream = {} + describe("sendStream", function() { + beforeEach(function() { + return this.stream = {};}); - it "should put the file with s3.upload", (done) -> - @s3.upload.callsArgWith 1 - @AWSSDKPersistorManager.sendStream @bucketName, @key, @stream, (err) => - expect(err).to.not.be.ok - expect(@s3.upload.calledOnce, "called only once").to.be.true - expect((@s3.upload.calledWith Bucket: @bucketName, Key: @key, Body: @stream), - "called with correct arguments").to.be.true - done() + it("should put the file with s3.upload", function(done) { + this.s3.upload.callsArgWith(1); + return this.AWSSDKPersistorManager.sendStream(this.bucketName, this.key, this.stream, err => { + expect(err).to.not.be.ok; + expect(this.s3.upload.calledOnce, "called only once").to.be.true; + expect((this.s3.upload.calledWith({Bucket: this.bucketName, Key: this.key, Body: this.stream})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.upload", (done) -> - @s3.upload.callsArgWith 1, @error - @AWSSDKPersistorManager.sendStream @bucketName, @key, @stream, (err) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.upload", function(done) { + this.s3.upload.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.sendStream(this.bucketName, this.key, this.stream, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); - describe "getFileStream", -> - beforeEach -> - @opts = {} - @stream = {} - @read_stream = - on: @read_stream_on = sinon.stub() - @object = - createReadStream: sinon.stub().returns @read_stream - @s3.getObject.returns @object + describe("getFileStream", function() { + beforeEach(function() { + this.opts = {}; + this.stream = {}; + this.read_stream = + {on: (this.read_stream_on = sinon.stub())}; + this.object = + {createReadStream: sinon.stub().returns(this.read_stream)}; + return this.s3.getObject.returns(this.object); + }); - it "should return a stream from s3.getObject", (done) -> - @read_stream_on.withArgs('readable').callsArgWith 1 + it("should return a stream from s3.getObject", function(done) { + this.read_stream_on.withArgs('readable').callsArgWith(1); - @AWSSDKPersistorManager.getFileStream @bucketName, @key, @opts, (err, stream) => - expect(@read_stream_on.calledTwice) - expect(err).to.not.be.ok - expect(stream, "returned the stream").to.equal @read_stream - expect((@s3.getObject.calledWith Bucket: @bucketName, Key: @key), - "called with correct arguments").to.be.true - done() + return this.AWSSDKPersistorManager.getFileStream(this.bucketName, this.key, this.opts, (err, stream) => { + expect(this.read_stream_on.calledTwice); + expect(err).to.not.be.ok; + expect(stream, "returned the stream").to.equal(this.read_stream); + expect((this.s3.getObject.calledWith({Bucket: this.bucketName, Key: this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - describe "with start and end options", -> - beforeEach -> - @opts = - start: 0 + describe("with start and end options", function() { + beforeEach(function() { + return this.opts = { + start: 0, end: 8 - it "should pass headers to the s3.GetObject", (done) -> - @read_stream_on.withArgs('readable').callsArgWith 1 - @AWSSDKPersistorManager.getFileStream @bucketName, @key, @opts, (err, stream) => - expect((@s3.getObject.calledWith Bucket: @bucketName, Key: @key, Range: 'bytes=0-8'), - "called with correct arguments").to.be.true - done() + }; + }); + return it("should pass headers to the s3.GetObject", function(done) { + this.read_stream_on.withArgs('readable').callsArgWith(1); + this.AWSSDKPersistorManager.getFileStream(this.bucketName, this.key, this.opts, (err, stream) => { + return expect((this.s3.getObject.calledWith({Bucket: this.bucketName, Key: this.key, Range: 'bytes=0-8'})), + "called with correct arguments").to.be.true; + }); + return done(); + }); + }); - describe "error conditions", -> - describe "when the file doesn't exist", -> - beforeEach -> - @error = new Error() - @error.code = 'NoSuchKey' - it "should produce a NotFoundError", (done) -> - @read_stream_on.withArgs('error').callsArgWith 1, @error - @AWSSDKPersistorManager.getFileStream @bucketName, @key, @opts, (err, stream) => - expect(stream).to.not.be.ok - expect(err).to.be.ok - expect(err instanceof @Errors.NotFoundError, "error is a correct instance").to.equal true - done() + return describe("error conditions", function() { + describe("when the file doesn't exist", function() { + beforeEach(function() { + this.error = new Error(); + return this.error.code = 'NoSuchKey'; + }); + return it("should produce a NotFoundError", function(done) { + this.read_stream_on.withArgs('error').callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.getFileStream(this.bucketName, this.key, this.opts, (err, stream) => { + expect(stream).to.not.be.ok; + expect(err).to.be.ok; + expect(err instanceof this.Errors.NotFoundError, "error is a correct instance").to.equal(true); + return done(); + }); + }); + }); - describe "when there is some other error", -> - beforeEach -> - @error = new Error() - it "should dispatch the error from s3 object stream", (done) -> - @read_stream_on.withArgs('error').callsArgWith 1, @error - @AWSSDKPersistorManager.getFileStream @bucketName, @key, @opts, (err, stream) => - expect(stream).to.not.be.ok - expect(err).to.be.ok - expect(err).to.equal @error - done() + return describe("when there is some other error", function() { + beforeEach(function() { + return this.error = new Error(); + }); + return it("should dispatch the error from s3 object stream", function(done) { + this.read_stream_on.withArgs('error').callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.getFileStream(this.bucketName, this.key, this.opts, (err, stream) => { + expect(stream).to.not.be.ok; + expect(err).to.be.ok; + expect(err).to.equal(this.error); + return done(); + }); + }); + }); + }); + }); - describe "copyFile", -> - beforeEach -> - @destKey = "some/key" - @stream = {} + describe("copyFile", function() { + beforeEach(function() { + this.destKey = "some/key"; + return this.stream = {};}); - it "should copy the file with s3.copyObject", (done) -> - @s3.copyObject.callsArgWith 1 - @AWSSDKPersistorManager.copyFile @bucketName, @key, @destKey, (err) => - expect(err).to.not.be.ok - expect(@s3.copyObject.calledOnce, "called only once").to.be.true - expect((@s3.copyObject.calledWith Bucket: @bucketName, Key: @destKey, CopySource: @bucketName + '/' + @key), - "called with correct arguments").to.be.true - done() + it("should copy the file with s3.copyObject", function(done) { + this.s3.copyObject.callsArgWith(1); + return this.AWSSDKPersistorManager.copyFile(this.bucketName, this.key, this.destKey, err => { + expect(err).to.not.be.ok; + expect(this.s3.copyObject.calledOnce, "called only once").to.be.true; + expect((this.s3.copyObject.calledWith({Bucket: this.bucketName, Key: this.destKey, CopySource: this.bucketName + '/' + this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.copyObject", (done) -> - @s3.copyObject.callsArgWith 1, @error - @AWSSDKPersistorManager.copyFile @bucketName, @key, @destKey, (err) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.copyObject", function(done) { + this.s3.copyObject.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.copyFile(this.bucketName, this.key, this.destKey, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); - describe "deleteFile", -> - it "should delete the file with s3.deleteObject", (done) -> - @s3.deleteObject.callsArgWith 1 - @AWSSDKPersistorManager.deleteFile @bucketName, @key, (err) => - expect(err).to.not.be.ok - expect(@s3.deleteObject.calledOnce, "called only once").to.be.true - expect((@s3.deleteObject.calledWith Bucket: @bucketName, Key: @key), - "called with correct arguments").to.be.true - done() + describe("deleteFile", function() { + it("should delete the file with s3.deleteObject", function(done) { + this.s3.deleteObject.callsArgWith(1); + return this.AWSSDKPersistorManager.deleteFile(this.bucketName, this.key, err => { + expect(err).to.not.be.ok; + expect(this.s3.deleteObject.calledOnce, "called only once").to.be.true; + expect((this.s3.deleteObject.calledWith({Bucket: this.bucketName, Key: this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.deleteObject", (done) -> - @s3.deleteObject.callsArgWith 1, @error - @AWSSDKPersistorManager.deleteFile @bucketName, @key, (err) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.deleteObject", function(done) { + this.s3.deleteObject.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.deleteFile(this.bucketName, this.key, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); - describe "deleteDirectory", -> + describe("deleteDirectory", function() { - it "should list the directory content using s3.listObjects", (done) -> - @s3.listObjects.callsArgWith 1, null, Contents: [] - @AWSSDKPersistorManager.deleteDirectory @bucketName, @key, (err) => - expect(err).to.not.be.ok - expect(@s3.listObjects.calledOnce, "called only once").to.be.true - expect((@s3.listObjects.calledWith Bucket: @bucketName, Prefix: @key), - "called with correct arguments").to.be.true - done() + it("should list the directory content using s3.listObjects", function(done) { + this.s3.listObjects.callsArgWith(1, null, {Contents: []}); + return this.AWSSDKPersistorManager.deleteDirectory(this.bucketName, this.key, err => { + expect(err).to.not.be.ok; + expect(this.s3.listObjects.calledOnce, "called only once").to.be.true; + expect((this.s3.listObjects.calledWith({Bucket: this.bucketName, Prefix: this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.listObjects", (done) -> - @s3.listObjects.callsArgWith 1, @error - @AWSSDKPersistorManager.deleteDirectory @bucketName, @key, (err) => - expect(err).to.equal @error - done() + it("should dispatch the error from s3.listObjects", function(done) { + this.s3.listObjects.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.deleteDirectory(this.bucketName, this.key, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); - describe "with directory content", -> - beforeEach -> - @fileList = [ - Key: 'foo' - , Key: 'bar' + return describe("with directory content", function() { + beforeEach(function() { + return this.fileList = [ + {Key: 'foo'} + , { Key: 'bar' , Key: 'baz' - ] + } + ];}); - it "should forward the file keys to s3.deleteObjects", (done) -> - @s3.listObjects.callsArgWith 1, null, Contents: @fileList - @s3.deleteObjects.callsArgWith 1 - @AWSSDKPersistorManager.deleteDirectory @bucketName, @key, (err) => - expect(err).to.not.be.ok - expect(@s3.deleteObjects.calledOnce, "called only once").to.be.true - expect((@s3.deleteObjects.calledWith - Bucket: @bucketName - Delete: - Quiet: true - Objects: @fileList), - "called with correct arguments").to.be.true - done() + it("should forward the file keys to s3.deleteObjects", function(done) { + this.s3.listObjects.callsArgWith(1, null, {Contents: this.fileList}); + this.s3.deleteObjects.callsArgWith(1); + return this.AWSSDKPersistorManager.deleteDirectory(this.bucketName, this.key, err => { + expect(err).to.not.be.ok; + expect(this.s3.deleteObjects.calledOnce, "called only once").to.be.true; + expect((this.s3.deleteObjects.calledWith({ + Bucket: this.bucketName, + Delete: { + Quiet: true, + Objects: this.fileList + }})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.deleteObjects", (done) -> - @s3.listObjects.callsArgWith 1, null, Contents: @fileList - @s3.deleteObjects.callsArgWith 1, @error - @AWSSDKPersistorManager.deleteDirectory @bucketName, @key, (err) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.deleteObjects", function(done) { + this.s3.listObjects.callsArgWith(1, null, {Contents: this.fileList}); + this.s3.deleteObjects.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.deleteDirectory(this.bucketName, this.key, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); + }); - describe "checkIfFileExists", -> + describe("checkIfFileExists", function() { - it "should check for the file with s3.headObject", (done) -> - @s3.headObject.callsArgWith 1, null, {} - @AWSSDKPersistorManager.checkIfFileExists @bucketName, @key, (err, exists) => - expect(err).to.not.be.ok - expect(@s3.headObject.calledOnce, "called only once").to.be.true - expect((@s3.headObject.calledWith Bucket: @bucketName, Key: @key), - "called with correct arguments").to.be.true - done() + it("should check for the file with s3.headObject", function(done) { + this.s3.headObject.callsArgWith(1, null, {}); + return this.AWSSDKPersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists) => { + expect(err).to.not.be.ok; + expect(this.s3.headObject.calledOnce, "called only once").to.be.true; + expect((this.s3.headObject.calledWith({Bucket: this.bucketName, Key: this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should return false on an inexistant file", (done) -> - @s3.headObject.callsArgWith 1, null, {} - @AWSSDKPersistorManager.checkIfFileExists @bucketName, @key, (err, exists) => - expect(exists).to.be.false - done() + it("should return false on an inexistant file", function(done) { + this.s3.headObject.callsArgWith(1, null, {}); + return this.AWSSDKPersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists) => { + expect(exists).to.be.false; + return done(); + }); + }); - it "should return true on an existing file", (done) -> - @s3.headObject.callsArgWith 1, null, ETag: "etag" - @AWSSDKPersistorManager.checkIfFileExists @bucketName, @key, (err, exists) => - expect(exists).to.be.true - done() + it("should return true on an existing file", function(done) { + this.s3.headObject.callsArgWith(1, null, {ETag: "etag"}); + return this.AWSSDKPersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists) => { + expect(exists).to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.headObject", (done) -> - @s3.headObject.callsArgWith 1, @error - @AWSSDKPersistorManager.checkIfFileExists @bucketName, @key, (err, exists) => - expect(err).to.equal @error - done() + return it("should dispatch the error from s3.headObject", function(done) { + this.s3.headObject.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists) => { + expect(err).to.equal(this.error); + return done(); + }); + }); + }); - describe "directorySize", -> + return describe("directorySize", function() { - it "should list the directory content using s3.listObjects", (done) -> - @s3.listObjects.callsArgWith 1, null, Contents: [] - @AWSSDKPersistorManager.directorySize @bucketName, @key, (err) => - expect(err).to.not.be.ok - expect(@s3.listObjects.calledOnce, "called only once").to.be.true - expect((@s3.listObjects.calledWith Bucket: @bucketName, Prefix: @key), - "called with correct arguments").to.be.true - done() + it("should list the directory content using s3.listObjects", function(done) { + this.s3.listObjects.callsArgWith(1, null, {Contents: []}); + return this.AWSSDKPersistorManager.directorySize(this.bucketName, this.key, err => { + expect(err).to.not.be.ok; + expect(this.s3.listObjects.calledOnce, "called only once").to.be.true; + expect((this.s3.listObjects.calledWith({Bucket: this.bucketName, Prefix: this.key})), + "called with correct arguments").to.be.true; + return done(); + }); + }); - it "should dispatch the error from s3.listObjects", (done) -> - @s3.listObjects.callsArgWith 1, @error - @AWSSDKPersistorManager.directorySize @bucketName, @key, (err) => - expect(err).to.equal @error - done() + it("should dispatch the error from s3.listObjects", function(done) { + this.s3.listObjects.callsArgWith(1, this.error); + return this.AWSSDKPersistorManager.directorySize(this.bucketName, this.key, err => { + expect(err).to.equal(this.error); + return done(); + }); + }); - it "should sum directory files sizes", (done) -> - @s3.listObjects.callsArgWith 1, null, Contents: [ { Size: 1024 }, { Size: 2048 }] - @AWSSDKPersistorManager.directorySize @bucketName, @key, (err, size) => - expect(size).to.equal 3072 - done() + return it("should sum directory files sizes", function(done) { + this.s3.listObjects.callsArgWith(1, null, {Contents: [ { Size: 1024 }, { Size: 2048 }]}); + return this.AWSSDKPersistorManager.directorySize(this.bucketName, this.key, (err, size) => { + expect(size).to.equal(3072); + return done(); + }); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/BucketControllerTests.js b/services/filestore/test/unit/coffee/BucketControllerTests.js index c6bbabc89e..db0e6a5aa3 100644 --- a/services/filestore/test/unit/coffee/BucketControllerTests.js +++ b/services/filestore/test/unit/coffee/BucketControllerTests.js @@ -1,71 +1,100 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/BucketController.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/BucketController.js"; +const SandboxedModule = require('sandboxed-module'); -describe "BucketController", -> +describe("BucketController", function() { - beforeEach -> - @PersistorManager = - sendStream: sinon.stub() - copyFile: sinon.stub() + beforeEach(function() { + this.PersistorManager = { + sendStream: sinon.stub(), + copyFile: sinon.stub(), deleteFile:sinon.stub() + }; - @settings = - s3: - buckets: + this.settings = { + s3: { + buckets: { user_files:"user_files" - filestore: - backend: "s3" - s3: - secret: "secret" + } + }, + filestore: { + backend: "s3", + s3: { + secret: "secret", key: "this_key" + } + } + }; - @FileHandler = - getFile: sinon.stub() - deleteFile: sinon.stub() - insertFile: sinon.stub() + this.FileHandler = { + getFile: sinon.stub(), + deleteFile: sinon.stub(), + insertFile: sinon.stub(), getDirectorySize: sinon.stub() - @LocalFileWriter = {} - @controller = SandboxedModule.require modulePath, requires: - "./LocalFileWriter":@LocalFileWriter - "./FileHandler": @FileHandler - "./PersistorManager":@PersistorManager - "settings-sharelatex": @settings - "metrics-sharelatex": - inc:-> - "logger-sharelatex": - log:-> - err:-> - @project_id = "project_id" - @file_id = "file_id" - @bucket = "user_files" - @key = "#{@project_id}/#{@file_id}" - @req = - query:{} - params: - bucket: @bucket - 0: @key + }; + this.LocalFileWriter = {}; + this.controller = SandboxedModule.require(modulePath, { requires: { + "./LocalFileWriter":this.LocalFileWriter, + "./FileHandler": this.FileHandler, + "./PersistorManager":this.PersistorManager, + "settings-sharelatex": this.settings, + "metrics-sharelatex": { + inc() {} + }, + "logger-sharelatex": { + log() {}, + err() {} + } + } + } + ); + this.project_id = "project_id"; + this.file_id = "file_id"; + this.bucket = "user_files"; + this.key = `${this.project_id}/${this.file_id}`; + this.req = { + query:{}, + params: { + bucket: this.bucket, + 0: this.key + }, headers: {} - @res = - setHeader: -> - @fileStream = {} + }; + this.res = + {setHeader() {}}; + return this.fileStream = {};}); - describe "getFile", -> + return describe("getFile", function() { - it "should pipe the stream", (done)-> - @FileHandler.getFile.callsArgWith(3, null, @fileStream) - @fileStream.pipe = (res)=> - res.should.equal @res - done() - @controller.getFile @req, @res + it("should pipe the stream", function(done){ + this.FileHandler.getFile.callsArgWith(3, null, this.fileStream); + this.fileStream.pipe = res=> { + res.should.equal(this.res); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); - it "should send a 500 if there is a problem", (done)-> - @FileHandler.getFile.callsArgWith(3, "error") - @res.send = (code)=> - code.should.equal 500 - done() - @controller.getFile @req, @res + return it("should send a 500 if there is a problem", function(done){ + this.FileHandler.getFile.callsArgWith(3, "error"); + this.res.send = code=> { + code.should.equal(500); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/FSPersistorManagerTests.js b/services/filestore/test/unit/coffee/FSPersistorManagerTests.js index 6980ce3e30..cd73f41ac0 100644 --- a/services/filestore/test/unit/coffee/FSPersistorManagerTests.js +++ b/services/filestore/test/unit/coffee/FSPersistorManagerTests.js @@ -1,281 +1,372 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should -expect = chai.expect -modulePath = "../../../app/js/FSPersistorManager.js" -SandboxedModule = require('sandboxed-module') -fs = require("fs") -response = require("response") +/* + * 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", -> +describe("FSPersistorManagerTests", function() { - beforeEach -> - @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() + 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() - @Rimraf = sinon.stub() - @LocalFileWriter = - writeStream: sinon.stub() + }; + this.Rimraf = sinon.stub(); + this.LocalFileWriter = { + writeStream: sinon.stub(), deleteFile: sinon.stub() - @requires = - "./LocalFileWriter":@LocalFileWriter - "fs":@Fs - "logger-sharelatex": - log:-> - err:-> - "response":response - "rimraf":@Rimraf - "./Errors": @Errors = - NotFoundError: sinon.stub() - @location = "/tmp" - @name1 = "530f2407e7ef165704000007/530f838b46d9a9e859000008" - @name1Filtered ="530f2407e7ef165704000007_530f838b46d9a9e859000008" - @name2 = "second_file" - @error = "error_message" - @FSPersistorManager = SandboxedModule.require modulePath, requires: @requires + }; + 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", -> - beforeEach -> - @Fs.createReadStream = sinon.stub().returns({ - on: -> - pipe: -> - }) + describe("sendFile", function() { + beforeEach(function() { + return this.Fs.createReadStream = sinon.stub().returns({ + on() {}, + pipe() {} + }); + }); - it "should copy the file", (done) -> - @Fs.createWriteStream =sinon.stub().returns({ - on: (event, handler) -> - process.nextTick(handler) if event is 'finish' - }) - @FSPersistorManager.sendFile @location, @name1, @name2, (err)=> - @Fs.createReadStream.calledWith(@name2).should.equal true - @Fs.createWriteStream.calledWith("#{@location}/#{@name1Filtered}" ).should.equal true - done() + 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(); + }); + }); - it "should return an error if the file cannot be stored", (done) -> - @Fs.createWriteStream =sinon.stub().returns({ - on: (event, handler) => - if event is 'error' - process.nextTick () => - handler(@error) - }) - @FSPersistorManager.sendFile @location, @name1, @name2, (err)=> - @Fs.createReadStream.calledWith(@name2).should.equal true - @Fs.createWriteStream.calledWith("#{@location}/#{@name1Filtered}" ).should.equal true - err.should.equal @error - 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", -> - beforeEach -> - @FSPersistorManager.sendFile = sinon.stub().callsArgWith(3) - @LocalFileWriter.writeStream.callsArgWith(2, null, @name1) - @LocalFileWriter.deleteFile.callsArg(1) - @SourceStream = - on:-> + 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", (done)-> - @FSPersistorManager.sendStream @location, @name1, @SourceStream, => - @LocalFileWriter.writeStream.calledWith(@SourceStream).should.equal true - done() + 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", (done)-> - @LocalFileWriter.writeStream.callsArgWith(2, @error) - @FSPersistorManager.sendStream @location, @name1, @SourceStream, (err)=> - err.should.equal @error - 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(); + }); + }); - it "should send the file to the filestore", (done)-> - @LocalFileWriter.writeStream.callsArgWith(2) - @FSPersistorManager.sendStream @location, @name1, @SourceStream, (err)=> - @FSPersistorManager.sendFile.called.should.equal true - 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", -> - beforeEach -> - @opts = {} + describe("getFileStream", function() { + beforeEach(function() { + return this.opts = {};}); - it "should use correct file location", (done) -> - @FSPersistorManager.getFileStream @location, @name1, @opts, (err,res) => - @Fs.open.calledWith("#{@location}/#{@name1Filtered}").should.equal true - done() + 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", -> + describe("with start and end options", function() { - beforeEach -> - @fd = 2019 - @opts_in = {start: 0, end: 8} - @opts = {start: 0, end: 8, fd: @fd} - @Fs.open.callsArgWith(2, null, @fd) + 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); + }); - it 'should pass the options to createReadStream', (done) -> - @FSPersistorManager.getFileStream @location, @name1, @opts_in, (err,res)=> - @Fs.createReadStream.calledWith(null, @opts).should.equal true - done() + 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(); + }); + }); - describe "error conditions", -> + return describe("error conditions", function() { - describe "when the file does not exist", -> + describe("when the file does not exist", function() { - beforeEach -> - @fakeCode = 'ENOENT' - err = new Error() - err.code = @fakeCode - @Fs.open.callsArgWith(2, err, null) + beforeEach(function() { + this.fakeCode = 'ENOENT'; + const err = new Error(); + err.code = this.fakeCode; + return this.Fs.open.callsArgWith(2, err, null); + }); - it "should give a NotFoundError", (done) -> - @FSPersistorManager.getFileStream @location, @name1, @opts, (err,res)=> - expect(res).to.equal null - expect(err).to.not.equal null - expect(err instanceof @Errors.NotFoundError).to.equal true - done() + 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(); + }); + }); + }); - describe "when some other error happens", -> + return describe("when some other error happens", function() { - beforeEach -> - @fakeCode = 'SOMETHINGHORRIBLE' - err = new Error() - err.code = @fakeCode - @Fs.open.callsArgWith(2, err, null) + beforeEach(function() { + this.fakeCode = 'SOMETHINGHORRIBLE'; + const err = new Error(); + err.code = this.fakeCode; + return this.Fs.open.callsArgWith(2, err, null); + }); - it "should give an Error", (done) -> - @FSPersistorManager.getFileStream @location, @name1, @opts, (err,res)=> - expect(res).to.equal null - expect(err).to.not.equal null - expect(err instanceof Error).to.equal true - done() + 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", -> - it "should return the file size", (done) -> - expectedFileSize = 75382 - @Fs.stat.yields(new Error("fs.stat got unexpected arguments")) - @Fs.stat.withArgs("#{@location}/#{@name1Filtered}") - .yields(null, { size: expectedFileSize }) + 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 }); - @FSPersistorManager.getFileSize @location, @name1, (err, fileSize) => - if err? - return done(err) - expect(fileSize).to.equal(expectedFileSize) - done() + 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", (done) -> - error = new Error() - error.code = "ENOENT" - @Fs.stat.yields(error) + 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); - @FSPersistorManager.getFileSize @location, @name1, (err, fileSize) => - expect(err).to.be.instanceof(@Errors.NotFoundError) - done() + return this.FSPersistorManager.getFileSize(this.location, this.name1, (err, fileSize) => { + expect(err).to.be.instanceof(this.Errors.NotFoundError); + return done(); + }); + }); - it "should rethrow any other error", (done) -> - error = new Error() - @Fs.stat.yields(error) + return it("should rethrow any other error", function(done) { + const error = new Error(); + this.Fs.stat.yields(error); - @FSPersistorManager.getFileSize @location, @name1, (err, fileSize) => - expect(err).to.equal(error) - done() + return this.FSPersistorManager.getFileSize(this.location, this.name1, (err, fileSize) => { + expect(err).to.equal(error); + return done(); + }); + }); + }); - describe "copyFile", -> - beforeEach -> - @ReadStream= - on:-> + describe("copyFile", function() { + beforeEach(function() { + this.ReadStream= { + on() {}, pipe:sinon.stub() - @WriteStream= - on:-> - @Fs.createReadStream.returns(@ReadStream) - @Fs.createWriteStream.returns(@WriteStream) + }; + this.WriteStream= + {on() {}}; + this.Fs.createReadStream.returns(this.ReadStream); + return this.Fs.createWriteStream.returns(this.WriteStream); + }); - it "Should open the source for reading", (done) -> - @FSPersistorManager.copyFile @location, @name1, @name2, -> - @Fs.createReadStream.calledWith("#{@location}/#{@name1Filtered}").should.equal true - done() + 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", (done) -> - @FSPersistorManager.copyFile @location, @name1, @name2, -> - @Fs.createWriteStream.calledWith("#{@location}/#{@name2}").should.equal true - 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(); + }); - it "Should pipe the source to the target", (done) -> - @FSPersistorManager.copyFile @location, @name1, @name2, -> - @ReadStream.pipe.calledWith(@WriteStream).should.equal true - 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", -> - beforeEach -> - @Fs.unlink.callsArgWith(1,@error) + describe("deleteFile", function() { + beforeEach(function() { + return this.Fs.unlink.callsArgWith(1,this.error); + }); - it "Should call unlink with correct options", (done) -> - @FSPersistorManager.deleteFile @location, @name1, (err) => - @Fs.unlink.calledWith("#{@location}/#{@name1Filtered}").should.equal true - done() + 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(); + }); + }); - it "Should propogate the error", (done) -> - @FSPersistorManager.deleteFile @location, @name1, (err) => - err.should.equal @error - 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", -> - beforeEach -> - @Rimraf.callsArgWith(1,@error) + describe("deleteDirectory", function() { + beforeEach(function() { + return this.Rimraf.callsArgWith(1,this.error); + }); - it "Should call rmdir(rimraf) with correct options", (done) -> - @FSPersistorManager.deleteDirectory @location, @name1, (err) => - @Rimraf.calledWith("#{@location}/#{@name1Filtered}").should.equal true - done() + 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(); + }); + }); - it "Should propogate the error", (done) -> - @FSPersistorManager.deleteDirectory @location, @name1, (err) => - err.should.equal @error - 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", -> - beforeEach -> - @Fs.exists.callsArgWith(1,true) + describe("checkIfFileExists", function() { + beforeEach(function() { + return this.Fs.exists.callsArgWith(1,true); + }); - it "Should call exists with correct options", (done) -> - @FSPersistorManager.checkIfFileExists @location, @name1, (exists) => - @Fs.exists.calledWith("#{@location}/#{@name1Filtered}").should.equal true - done() + 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", (done) -> - @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) => - expect(err).to.be.null - 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", (done) -> - @Fs.exists.callsArgWith(1,true) - @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) => - exists.should.be.true - 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(); + }); + }); - it "Should return false for non-existing files", (done) -> - @Fs.exists.callsArgWith(1,false) - @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) => - exists.should.be.false - 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(); + }); + }); + }); - describe "directorySize", -> + return describe("directorySize", function() { - it "should propogate the error", (done) -> - @Fs.readdir.callsArgWith(1, @error) - @FSPersistorManager.directorySize @location, @name1, (err, totalsize) => - err.should.equal @error - done() + 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(); + }); + }); - it "should sum directory files size", (done) -> - @Fs.readdir.callsArgWith(1, null, [ {'file1'}, {'file2'} ]) - @Fs.fstatSync.returns({size : 1024}) - @FSPersistorManager.directorySize @location, @name1, (err, totalsize) => - expect(totalsize).to.equal 2048 - 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(); + }); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/FileControllerTests.js b/services/filestore/test/unit/coffee/FileControllerTests.js index 821aadb68d..ea3b0e32b8 100644 --- a/services/filestore/test/unit/coffee/FileControllerTests.js +++ b/services/filestore/test/unit/coffee/FileControllerTests.js @@ -1,216 +1,283 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/FileController.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/FileController.js"; +const SandboxedModule = require('sandboxed-module'); -describe "FileController", -> +describe("FileController", function() { - beforeEach -> - @PersistorManager = - sendStream: sinon.stub() - copyFile: sinon.stub() + beforeEach(function() { + this.PersistorManager = { + sendStream: sinon.stub(), + copyFile: sinon.stub(), deleteFile:sinon.stub() + }; - @settings = - s3: - buckets: + this.settings = { + s3: { + buckets: { user_files:"user_files" - @FileHandler = - getFile: sinon.stub() - getFileSize: sinon.stub() - deleteFile: sinon.stub() - insertFile: sinon.stub() + } + } + }; + this.FileHandler = { + getFile: sinon.stub(), + getFileSize: sinon.stub(), + deleteFile: sinon.stub(), + insertFile: sinon.stub(), getDirectorySize: sinon.stub() - @LocalFileWriter = {} - @controller = SandboxedModule.require modulePath, requires: - "./LocalFileWriter":@LocalFileWriter - "./FileHandler": @FileHandler - "./PersistorManager":@PersistorManager - "./Errors": @Errors = - NotFoundError: sinon.stub() - "settings-sharelatex": @settings - "metrics-sharelatex": - inc:-> - "logger-sharelatex": - log:-> - err:-> - @project_id = "project_id" - @file_id = "file_id" - @bucket = "user_files" - @key = "#{@project_id}/#{@file_id}" - @req = - key:@key - bucket:@bucket - query:{} - params: - project_id:@project_id - file_id:@file_id + }; + this.LocalFileWriter = {}; + this.controller = SandboxedModule.require(modulePath, { requires: { + "./LocalFileWriter":this.LocalFileWriter, + "./FileHandler": this.FileHandler, + "./PersistorManager":this.PersistorManager, + "./Errors": (this.Errors = + {NotFoundError: sinon.stub()}), + "settings-sharelatex": this.settings, + "metrics-sharelatex": { + inc() {} + }, + "logger-sharelatex": { + log() {}, + err() {} + } + } + } + ); + this.project_id = "project_id"; + this.file_id = "file_id"; + this.bucket = "user_files"; + this.key = `${this.project_id}/${this.file_id}`; + this.req = { + key:this.key, + bucket:this.bucket, + query:{}, + params: { + project_id:this.project_id, + file_id:this.file_id + }, headers: {} - @res = - set: sinon.stub().returnsThis() + }; + this.res = { + set: sinon.stub().returnsThis(), status: sinon.stub().returnsThis() - @fileStream = {} + }; + return this.fileStream = {};}); - describe "getFile", -> + describe("getFile", function() { - it "should pipe the stream", (done)-> - @FileHandler.getFile.callsArgWith(3, null, @fileStream) - @fileStream.pipe = (res)=> - res.should.equal @res - done() - @controller.getFile @req, @res + it("should pipe the stream", function(done){ + this.FileHandler.getFile.callsArgWith(3, null, this.fileStream); + this.fileStream.pipe = res=> { + res.should.equal(this.res); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); - it "should send a 200 if the cacheWarm param is true", (done)-> - @req.query.cacheWarm = true - @FileHandler.getFile.callsArgWith(3, null, @fileStream) - @res.send = (statusCode)=> - statusCode.should.equal 200 - done() - @controller.getFile @req, @res + it("should send a 200 if the cacheWarm param is true", function(done){ + this.req.query.cacheWarm = true; + this.FileHandler.getFile.callsArgWith(3, null, this.fileStream); + this.res.send = statusCode=> { + statusCode.should.equal(200); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); - it "should send a 500 if there is a problem", (done)-> - @FileHandler.getFile.callsArgWith(3, "error") - @res.send = (code)=> - code.should.equal 500 - done() - @controller.getFile @req, @res + it("should send a 500 if there is a problem", function(done){ + this.FileHandler.getFile.callsArgWith(3, "error"); + this.res.send = code=> { + code.should.equal(500); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); - describe "with a 'Range' header set", -> + return describe("with a 'Range' header set", function() { - beforeEach -> - @req.headers.range = 'bytes=0-8' + beforeEach(function() { + return this.req.headers.range = 'bytes=0-8'; + }); - it "should pass 'start' and 'end' options to FileHandler", (done) -> - @FileHandler.getFile.callsArgWith(3, null, @fileStream) - @fileStream.pipe = (res)=> - expect(@FileHandler.getFile.lastCall.args[2].start).to.equal 0 - expect(@FileHandler.getFile.lastCall.args[2].end).to.equal 8 - done() - @controller.getFile @req, @res + return it("should pass 'start' and 'end' options to FileHandler", function(done) { + this.FileHandler.getFile.callsArgWith(3, null, this.fileStream); + this.fileStream.pipe = res=> { + expect(this.FileHandler.getFile.lastCall.args[2].start).to.equal(0); + expect(this.FileHandler.getFile.lastCall.args[2].end).to.equal(8); + return done(); + }; + return this.controller.getFile(this.req, this.res); + }); + }); + }); - describe "getFileHead", -> - it "should return the file size in a Content-Length header", (done) -> - expectedFileSize = 84921 - @FileHandler.getFileSize.yields( + describe("getFileHead", function() { + it("should return the file size in a Content-Length header", function(done) { + const expectedFileSize = 84921; + this.FileHandler.getFileSize.yields( new Error("FileHandler.getFileSize: unexpected arguments") - ) - @FileHandler.getFileSize.withArgs(@bucket, @key).yields(null, expectedFileSize) + ); + this.FileHandler.getFileSize.withArgs(this.bucket, this.key).yields(null, expectedFileSize); - @res.end = () => - expect(@res.status.lastCall.args[0]).to.equal(200) - expect(@res.set.calledWith("Content-Length", expectedFileSize)).to.equal(true) - done() + this.res.end = () => { + expect(this.res.status.lastCall.args[0]).to.equal(200); + expect(this.res.set.calledWith("Content-Length", expectedFileSize)).to.equal(true); + return done(); + }; - @controller.getFileHead(@req, @res) + return this.controller.getFileHead(this.req, this.res); + }); - it "should return a 404 is the file is not found", (done) -> - @FileHandler.getFileSize.yields(new @Errors.NotFoundError()) + it("should return a 404 is the file is not found", function(done) { + this.FileHandler.getFileSize.yields(new this.Errors.NotFoundError()); - @res.end = () => - expect(@res.status.lastCall.args[0]).to.equal(404) - done() + this.res.end = () => { + expect(this.res.status.lastCall.args[0]).to.equal(404); + return done(); + }; - @controller.getFileHead(@req, @res) + return this.controller.getFileHead(this.req, this.res); + }); - it "should return a 500 on internal errors", (done) -> - @FileHandler.getFileSize.yields(new Error()) + return it("should return a 500 on internal errors", function(done) { + this.FileHandler.getFileSize.yields(new Error()); - @res.end = () => - expect(@res.status.lastCall.args[0]).to.equal(500) - done() + this.res.end = () => { + expect(this.res.status.lastCall.args[0]).to.equal(500); + return done(); + }; - @controller.getFileHead(@req, @res) + return this.controller.getFileHead(this.req, this.res); + }); + }); - describe "insertFile", -> + describe("insertFile", () => it("should send bucket name key and res to PersistorManager", function(done){ + this.FileHandler.insertFile.callsArgWith(3); + this.res.send = () => { + this.FileHandler.insertFile.calledWith(this.bucket, this.key, this.req).should.equal(true); + return done(); + }; + return this.controller.insertFile(this.req, this.res); + })); - it "should send bucket name key and res to PersistorManager", (done)-> - @FileHandler.insertFile.callsArgWith(3) - @res.send = => - @FileHandler.insertFile.calledWith(@bucket, @key, @req).should.equal true - done() - @controller.insertFile @req, @res + describe("copyFile", function() { + beforeEach(function() { + this.oldFile_id = "old_file_id"; + this.oldProject_id = "old_project_id"; + return this.req.body = { + source: { + project_id: this.oldProject_id, + file_id: this.oldFile_id + } + }; + }); - describe "copyFile", -> - beforeEach -> - @oldFile_id = "old_file_id" - @oldProject_id = "old_project_id" - @req.body = - source: - project_id: @oldProject_id - file_id: @oldFile_id + it("should send bucket name and both keys to PersistorManager", function(done){ + this.PersistorManager.copyFile.callsArgWith(3); + this.res.send = code=> { + code.should.equal(200); + this.PersistorManager.copyFile.calledWith(this.bucket, `${this.oldProject_id}/${this.oldFile_id}`, this.key).should.equal(true); + return done(); + }; + return this.controller.copyFile(this.req, this.res); + }); - it "should send bucket name and both keys to PersistorManager", (done)-> - @PersistorManager.copyFile.callsArgWith(3) - @res.send = (code)=> - code.should.equal 200 - @PersistorManager.copyFile.calledWith(@bucket, "#{@oldProject_id}/#{@oldFile_id}", @key).should.equal true - done() - @controller.copyFile @req, @res + it("should send a 404 if the original file was not found", function(done) { + this.PersistorManager.copyFile.callsArgWith(3, new this.Errors.NotFoundError()); + this.res.send = code=> { + code.should.equal(404); + return done(); + }; + return this.controller.copyFile(this.req, this.res); + }); - it "should send a 404 if the original file was not found", (done) -> - @PersistorManager.copyFile.callsArgWith(3, new @Errors.NotFoundError()) - @res.send = (code)=> - code.should.equal 404 - done() - @controller.copyFile @req, @res + return it("should send a 500 if there was an error", function(done){ + this.PersistorManager.copyFile.callsArgWith(3, "error"); + this.res.send = code=> { + code.should.equal(500); + return done(); + }; + return this.controller.copyFile(this.req, this.res); + }); + }); - it "should send a 500 if there was an error", (done)-> - @PersistorManager.copyFile.callsArgWith(3, "error") - @res.send = (code)=> - code.should.equal 500 - done() - @controller.copyFile @req, @res + describe("delete file", function() { - describe "delete file", -> + it("should tell the file handler", function(done){ + this.FileHandler.deleteFile.callsArgWith(2); + this.res.send = code=> { + code.should.equal(204); + this.FileHandler.deleteFile.calledWith(this.bucket, this.key).should.equal(true); + return done(); + }; + return this.controller.deleteFile(this.req, this.res); + }); - it "should tell the file handler", (done)-> - @FileHandler.deleteFile.callsArgWith(2) - @res.send = (code)=> - code.should.equal 204 - @FileHandler.deleteFile.calledWith(@bucket, @key).should.equal true - done() - @controller.deleteFile @req, @res + return it("should send a 500 if there was an error", function(done){ + this.FileHandler.deleteFile.callsArgWith(2, "error"); + this.res.send = function(code){ + code.should.equal(500); + return done(); + }; + return this.controller.deleteFile(this.req, this.res); + }); + }); - it "should send a 500 if there was an error", (done)-> - @FileHandler.deleteFile.callsArgWith(2, "error") - @res.send = (code)-> - code.should.equal 500 - done() - @controller.deleteFile @req, @res + describe("_get_range", function() { - describe "_get_range", -> + it("should parse a valid Range header", function(done) { + const result = this.controller._get_range('bytes=0-200'); + expect(result).to.not.equal(null); + expect(result.start).to.equal(0); + expect(result.end).to.equal(200); + return done(); + }); - it "should parse a valid Range header", (done) -> - result = @controller._get_range('bytes=0-200') - expect(result).to.not.equal null - expect(result.start).to.equal 0 - expect(result.end).to.equal 200 - done() + it("should return null for an invalid Range header", function(done) { + const result = this.controller._get_range('wat'); + expect(result).to.equal(null); + return done(); + }); - it "should return null for an invalid Range header", (done) -> - result = @controller._get_range('wat') - expect(result).to.equal null - done() + return it("should return null for any type other than 'bytes'", function(done) { + const result = this.controller._get_range('carrots=0-200'); + expect(result).to.equal(null); + return done(); + }); + }); - it "should return null for any type other than 'bytes'", (done) -> - result = @controller._get_range('carrots=0-200') - expect(result).to.equal null - done() + return describe("directorySize", function() { - describe "directorySize", -> + it("should return total directory size bytes", function(done) { + this.FileHandler.getDirectorySize.callsArgWith(2, null, 1024); + return this.controller.directorySize(this.req, { json:result=> { + expect(result['total bytes']).to.equal(1024); + return done(); + } + } + ); + }); - it "should return total directory size bytes", (done) -> - @FileHandler.getDirectorySize.callsArgWith(2, null, 1024) - @controller.directorySize @req, json:(result)=> - expect(result['total bytes']).to.equal 1024 - done() - - it "should send a 500 if there was an error", (done)-> - @FileHandler.getDirectorySize.callsArgWith(2, "error") - @res.send = (code)-> - code.should.equal 500 - done() - @controller.directorySize @req, @res + return it("should send a 500 if there was an error", function(done){ + this.FileHandler.getDirectorySize.callsArgWith(2, "error"); + this.res.send = function(code){ + code.should.equal(500); + return done(); + }; + return this.controller.directorySize(this.req, this.res); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/FileConverterTests.js b/services/filestore/test/unit/coffee/FileConverterTests.js index ed59d56376..c546b61a15 100644 --- a/services/filestore/test/unit/coffee/FileConverterTests.js +++ b/services/filestore/test/unit/coffee/FileConverterTests.js @@ -1,81 +1,112 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/FileConverter.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/FileConverter.js"; +const SandboxedModule = require('sandboxed-module'); -describe "FileConverter", -> +describe("FileConverter", function() { - beforeEach -> + beforeEach(function() { - @safe_exec = sinon.stub() - @converter = SandboxedModule.require modulePath, requires: - "./SafeExec": @safe_exec - "logger-sharelatex": - log:-> - err:-> - "metrics-sharelatex": - inc:-> - Timer:-> - done:-> - "settings-sharelatex": @Settings = - commands: + this.safe_exec = sinon.stub(); + this.converter = SandboxedModule.require(modulePath, { requires: { + "./SafeExec": this.safe_exec, + "logger-sharelatex": { + log() {}, + err() {} + }, + "metrics-sharelatex": { + inc() {}, + Timer() { + return {done() {}}; + } + }, + "settings-sharelatex": (this.Settings = { + commands: { convertCommandPrefix: [] + } + }) + } + }); - @sourcePath = "/this/path/here.eps" - @format = "png" - @error = "Error" + this.sourcePath = "/this/path/here.eps"; + this.format = "png"; + return this.error = "Error"; + }); - describe "convert", -> + describe("convert", function() { - it "should convert the source to the requested format", (done)-> - @safe_exec.callsArgWith(2) - @converter.convert @sourcePath, @format, (err)=> - args = @safe_exec.args[0][0] - args.indexOf("#{@sourcePath}[0]").should.not.equal -1 - args.indexOf("#{@sourcePath}.#{@format}").should.not.equal -1 - done() + it("should convert the source to the requested format", function(done){ + this.safe_exec.callsArgWith(2); + return this.converter.convert(this.sourcePath, this.format, err=> { + const args = this.safe_exec.args[0][0]; + args.indexOf(`${this.sourcePath}[0]`).should.not.equal(-1); + args.indexOf(`${this.sourcePath}.${this.format}`).should.not.equal(-1); + return done(); + }); + }); - it "should return the dest path", (done)-> - @safe_exec.callsArgWith(2) - @converter.convert @sourcePath, @format, (err, destPath)=> - destPath.should.equal "#{@sourcePath}.#{@format}" - done() + it("should return the dest path", function(done){ + this.safe_exec.callsArgWith(2); + return this.converter.convert(this.sourcePath, this.format, (err, destPath)=> { + destPath.should.equal(`${this.sourcePath}.${this.format}`); + return done(); + }); + }); - it "should return the error from convert", (done)-> - @safe_exec.callsArgWith(2, @error) - @converter.convert @sourcePath, @format, (err)=> - err.should.equal @error - done() + it("should return the error from convert", function(done){ + this.safe_exec.callsArgWith(2, this.error); + return this.converter.convert(this.sourcePath, this.format, err=> { + err.should.equal(this.error); + return done(); + }); + }); - it "should not accapt an non aproved format", (done)-> - @safe_exec.callsArgWith(2) - @converter.convert @sourcePath, "ahhhhh", (err)=> - expect(err).to.exist - done() + it("should not accapt an non aproved format", function(done){ + this.safe_exec.callsArgWith(2); + return this.converter.convert(this.sourcePath, "ahhhhh", err=> { + expect(err).to.exist; + return done(); + }); + }); - it "should prefix the command with Settings.commands.convertCommandPrefix", (done) -> - @safe_exec.callsArgWith(2) - @Settings.commands.convertCommandPrefix = ["nice"] - @converter.convert @sourcePath, @format, (err)=> - command = @safe_exec.args[0][0] - command[0].should.equal "nice" - done() + return it("should prefix the command with Settings.commands.convertCommandPrefix", function(done) { + this.safe_exec.callsArgWith(2); + this.Settings.commands.convertCommandPrefix = ["nice"]; + return this.converter.convert(this.sourcePath, this.format, err=> { + const command = this.safe_exec.args[0][0]; + command[0].should.equal("nice"); + return done(); + }); + }); + }); - describe "thumbnail", -> - it "should call converter resize with args", (done)-> - @safe_exec.callsArgWith(2) - @converter.thumbnail @sourcePath, (err)=> - args = @safe_exec.args[0][0] - args.indexOf("#{@sourcePath}[0]").should.not.equal -1 - done() + describe("thumbnail", () => it("should call converter resize with args", function(done){ + this.safe_exec.callsArgWith(2); + return this.converter.thumbnail(this.sourcePath, err=> { + const args = this.safe_exec.args[0][0]; + args.indexOf(`${this.sourcePath}[0]`).should.not.equal(-1); + return done(); + }); + })); - describe "preview", -> - it "should call converter resize with args", (done)-> - @safe_exec.callsArgWith(2) - @converter.preview @sourcePath, (err)=> - args = @safe_exec.args[0][0] - args.indexOf("#{@sourcePath}[0]").should.not.equal -1 - done() + return describe("preview", () => it("should call converter resize with args", function(done){ + this.safe_exec.callsArgWith(2); + return this.converter.preview(this.sourcePath, err=> { + const args = this.safe_exec.args[0][0]; + args.indexOf(`${this.sourcePath}[0]`).should.not.equal(-1); + return done(); + }); + })); +}); diff --git a/services/filestore/test/unit/coffee/FileHandlerTests.js b/services/filestore/test/unit/coffee/FileHandlerTests.js index 754366195e..f83561166f 100644 --- a/services/filestore/test/unit/coffee/FileHandlerTests.js +++ b/services/filestore/test/unit/coffee/FileHandlerTests.js @@ -1,208 +1,275 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/FileHandler.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/FileHandler.js"; +const SandboxedModule = require('sandboxed-module'); -describe "FileHandler", -> +describe("FileHandler", function() { - beforeEach -> - @settings = - s3: - buckets: + beforeEach(function() { + this.settings = { + s3: { + buckets: { user_files:"user_files" - @PersistorManager = - getFileStream: sinon.stub() - checkIfFileExists: sinon.stub() - deleteFile: sinon.stub() - deleteDirectory: sinon.stub() - sendStream: sinon.stub() - insertFile: sinon.stub() - directorySize: sinon.stub() - @LocalFileWriter = - writeStream: sinon.stub() - getStream: sinon.stub() - deleteFile: sinon.stub() - @FileConverter = - convert: sinon.stub() - thumbnail: sinon.stub() - preview: sinon.stub() - @keyBuilder = - addCachingToKey: sinon.stub() - getConvertedFolderKey: sinon.stub() - @ImageOptimiser = - compressPng: sinon.stub() - @handler = SandboxedModule.require modulePath, requires: - "settings-sharelatex": @settings - "./PersistorManager":@PersistorManager - "./LocalFileWriter":@LocalFileWriter - "./FileConverter":@FileConverter - "./KeyBuilder": @keyBuilder - "./ImageOptimiser":@ImageOptimiser - "logger-sharelatex": - log:-> - err:-> - @bucket = "my_bucket" - @key = "key/here" - @stubbedPath = "/var/somewhere/path" - @format = "png" - @formattedStubbedPath = "#{@stubbedPath}.#{@format}" - - describe "insertFile", -> - beforeEach -> - @stream = {} - @PersistorManager.deleteDirectory.callsArgWith(2) - @PersistorManager.sendStream.callsArgWith(3) - - it "should send file to the filestore", (done)-> - @handler.insertFile @bucket, @key, @stream, => - @PersistorManager.sendStream.calledWith(@bucket, @key, @stream).should.equal true - done() - - it "should delete the convetedKey folder", (done)-> - @keyBuilder.getConvertedFolderKey.returns(@stubbedConvetedKey) - @handler.insertFile @bucket, @key, @stream, => - @PersistorManager.deleteDirectory.calledWith(@bucket, @stubbedConvetedKey).should.equal true - done() - - describe "deleteFile", -> - beforeEach -> - @keyBuilder.getConvertedFolderKey.returns(@stubbedConvetedKey) - @PersistorManager.deleteFile.callsArgWith(2) - @PersistorManager.deleteDirectory.callsArgWith(2) - - it "should tell the filestore manager to delete the file", (done)-> - @handler.deleteFile @bucket, @key, => - @PersistorManager.deleteFile.calledWith(@bucket, @key).should.equal true - done() - - it "should tell the filestore manager to delete the cached foler", (done)-> - @handler.deleteFile @bucket, @key, => - @PersistorManager.deleteDirectory.calledWith(@bucket, @stubbedConvetedKey).should.equal true - done() - - describe "getFile", -> - beforeEach -> - @handler._getStandardFile = sinon.stub().callsArgWith(3) - @handler._getConvertedFile = sinon.stub().callsArgWith(3) - - it "should call _getStandardFile if no format or style are defined", (done)-> - - @handler.getFile @bucket, @key, null, => - @handler._getStandardFile.called.should.equal true - @handler._getConvertedFile.called.should.equal false - done() - - it "should pass options to _getStandardFile", (done) -> - options = {start: 0, end: 8} - @handler.getFile @bucket, @key, options, => - expect(@handler._getStandardFile.lastCall.args[2].start).to.equal 0 - expect(@handler._getStandardFile.lastCall.args[2].end).to.equal 8 - done() - - it "should call _getConvertedFile if a format is defined", (done)-> - @handler.getFile @bucket, @key, format:"png", => - @handler._getStandardFile.called.should.equal false - @handler._getConvertedFile.called.should.equal true - done() - - describe "_getStandardFile", -> - - beforeEach -> - @fileStream = {on:->} - @PersistorManager.getFileStream.callsArgWith(3, "err", @fileStream) - - it "should get the stream", (done)-> - @handler.getFile @bucket, @key, null, => - @PersistorManager.getFileStream.calledWith(@bucket, @key).should.equal true - done() - - it "should return the stream and error", (done)-> - @handler.getFile @bucket, @key, null, (err, stream)=> - err.should.equal "err" - stream.should.equal @fileStream - done() - - it "should pass options to PersistorManager", (done) -> - @handler.getFile @bucket, @key, {start: 0, end: 8}, => - expect(@PersistorManager.getFileStream.lastCall.args[2].start).to.equal 0 - expect(@PersistorManager.getFileStream.lastCall.args[2].end).to.equal 8 - done() - - - describe "_getConvertedFile", -> - - it "should getFileStream if it does exists", (done)-> - @PersistorManager.checkIfFileExists.callsArgWith(2, null, true) - @PersistorManager.getFileStream.callsArgWith(3) - @handler._getConvertedFile @bucket, @key, {}, => - @PersistorManager.getFileStream.calledWith(@bucket).should.equal true - done() - - it "should call _getConvertedFileAndCache if it does exists", (done)-> - @PersistorManager.checkIfFileExists.callsArgWith(2, null, false) - @handler._getConvertedFileAndCache = sinon.stub().callsArgWith(4) - @handler._getConvertedFile @bucket, @key, {}, => - @handler._getConvertedFileAndCache.calledWith(@bucket, @key).should.equal true - done() - - describe "_getConvertedFileAndCache", -> - - it "should _convertFile ", (done)-> - @stubbedStream = {"something":"here"} - @localStream = { - on: -> + } } - @PersistorManager.sendFile = sinon.stub().callsArgWith(3) - @LocalFileWriter.getStream = sinon.stub().callsArgWith(1, null, @localStream) - @convetedKey = @key+"converted" - @handler._convertFile = sinon.stub().callsArgWith(3, null, @stubbedPath) - @ImageOptimiser.compressPng = sinon.stub().callsArgWith(1) - @handler._getConvertedFileAndCache @bucket, @key, @convetedKey, {}, (err, fsStream)=> - @handler._convertFile.called.should.equal true - @PersistorManager.sendFile.calledWith(@bucket, @convetedKey, @stubbedPath).should.equal true - @ImageOptimiser.compressPng.calledWith(@stubbedPath).should.equal true - @LocalFileWriter.getStream.calledWith(@stubbedPath).should.equal true - fsStream.should.equal @localStream - done() + }; + this.PersistorManager = { + getFileStream: sinon.stub(), + checkIfFileExists: sinon.stub(), + deleteFile: sinon.stub(), + deleteDirectory: sinon.stub(), + sendStream: sinon.stub(), + insertFile: sinon.stub(), + directorySize: sinon.stub() + }; + this.LocalFileWriter = { + writeStream: sinon.stub(), + getStream: sinon.stub(), + deleteFile: sinon.stub() + }; + this.FileConverter = { + convert: sinon.stub(), + thumbnail: sinon.stub(), + preview: sinon.stub() + }; + this.keyBuilder = { + addCachingToKey: sinon.stub(), + getConvertedFolderKey: sinon.stub() + }; + this.ImageOptimiser = + {compressPng: sinon.stub()}; + this.handler = SandboxedModule.require(modulePath, { requires: { + "settings-sharelatex": this.settings, + "./PersistorManager":this.PersistorManager, + "./LocalFileWriter":this.LocalFileWriter, + "./FileConverter":this.FileConverter, + "./KeyBuilder": this.keyBuilder, + "./ImageOptimiser":this.ImageOptimiser, + "logger-sharelatex": { + log() {}, + err() {} + } + } + } + ); + this.bucket = "my_bucket"; + this.key = "key/here"; + this.stubbedPath = "/var/somewhere/path"; + this.format = "png"; + return this.formattedStubbedPath = `${this.stubbedPath}.${this.format}`; + }); - describe "_convertFile", -> - beforeEach -> - @FileConverter.convert.callsArgWith(2, null, @formattedStubbedPath) - @FileConverter.thumbnail.callsArgWith(1, null, @formattedStubbedPath) - @FileConverter.preview.callsArgWith(1, null, @formattedStubbedPath) - @handler._writeS3FileToDisk = sinon.stub().callsArgWith(3, null, @stubbedPath) - @LocalFileWriter.deleteFile.callsArgWith(1) + describe("insertFile", function() { + beforeEach(function() { + this.stream = {}; + this.PersistorManager.deleteDirectory.callsArgWith(2); + return this.PersistorManager.sendStream.callsArgWith(3); + }); - it "should call thumbnail on the writer path if style was thumbnail was specified", (done)-> - @handler._convertFile @bucket, @key, style:"thumbnail", (err, path)=> - path.should.equal @formattedStubbedPath - @FileConverter.thumbnail.calledWith(@stubbedPath).should.equal true - @LocalFileWriter.deleteFile.calledWith(@stubbedPath).should.equal true - done() + it("should send file to the filestore", function(done){ + return this.handler.insertFile(this.bucket, this.key, this.stream, () => { + this.PersistorManager.sendStream.calledWith(this.bucket, this.key, this.stream).should.equal(true); + return done(); + }); + }); - it "should call preview on the writer path if style was preview was specified", (done)-> - @handler._convertFile @bucket, @key, style:"preview", (err, path)=> - path.should.equal @formattedStubbedPath - @FileConverter.preview.calledWith(@stubbedPath).should.equal true - @LocalFileWriter.deleteFile.calledWith(@stubbedPath).should.equal true - done() + return it("should delete the convetedKey folder", function(done){ + this.keyBuilder.getConvertedFolderKey.returns(this.stubbedConvetedKey); + return this.handler.insertFile(this.bucket, this.key, this.stream, () => { + this.PersistorManager.deleteDirectory.calledWith(this.bucket, this.stubbedConvetedKey).should.equal(true); + return done(); + }); + }); + }); - it "should call convert on the writer path if a format was specified", (done)-> - @handler._convertFile @bucket, @key, format:@format, (err, path)=> - path.should.equal @formattedStubbedPath - @FileConverter.convert.calledWith(@stubbedPath, @format).should.equal true - @LocalFileWriter.deleteFile.calledWith(@stubbedPath).should.equal true - done() + describe("deleteFile", function() { + beforeEach(function() { + this.keyBuilder.getConvertedFolderKey.returns(this.stubbedConvetedKey); + this.PersistorManager.deleteFile.callsArgWith(2); + return this.PersistorManager.deleteDirectory.callsArgWith(2); + }); - describe "getDirectorySize", -> + it("should tell the filestore manager to delete the file", function(done){ + return this.handler.deleteFile(this.bucket, this.key, () => { + this.PersistorManager.deleteFile.calledWith(this.bucket, this.key).should.equal(true); + return done(); + }); + }); - beforeEach -> - @PersistorManager.directorySize.callsArgWith(2) + return it("should tell the filestore manager to delete the cached foler", function(done){ + return this.handler.deleteFile(this.bucket, this.key, () => { + this.PersistorManager.deleteDirectory.calledWith(this.bucket, this.stubbedConvetedKey).should.equal(true); + return done(); + }); + }); + }); - it "should call the filestore manager to get directory size", (done)-> - @handler.getDirectorySize @bucket, @key, => - @PersistorManager.directorySize.calledWith(@bucket, @key).should.equal true - done() + describe("getFile", function() { + beforeEach(function() { + this.handler._getStandardFile = sinon.stub().callsArgWith(3); + return this.handler._getConvertedFile = sinon.stub().callsArgWith(3); + }); + + it("should call _getStandardFile if no format or style are defined", function(done){ + + return this.handler.getFile(this.bucket, this.key, null, () => { + this.handler._getStandardFile.called.should.equal(true); + this.handler._getConvertedFile.called.should.equal(false); + return done(); + }); + }); + + it("should pass options to _getStandardFile", function(done) { + const options = {start: 0, end: 8}; + return this.handler.getFile(this.bucket, this.key, options, () => { + expect(this.handler._getStandardFile.lastCall.args[2].start).to.equal(0); + expect(this.handler._getStandardFile.lastCall.args[2].end).to.equal(8); + return done(); + }); + }); + + return it("should call _getConvertedFile if a format is defined", function(done){ + return this.handler.getFile(this.bucket, this.key, {format:"png"}, () => { + this.handler._getStandardFile.called.should.equal(false); + this.handler._getConvertedFile.called.should.equal(true); + return done(); + }); + }); + }); + + describe("_getStandardFile", function() { + + beforeEach(function() { + this.fileStream = {on() {}}; + return this.PersistorManager.getFileStream.callsArgWith(3, "err", this.fileStream); + }); + + it("should get the stream", function(done){ + return this.handler.getFile(this.bucket, this.key, null, () => { + this.PersistorManager.getFileStream.calledWith(this.bucket, this.key).should.equal(true); + return done(); + }); + }); + + it("should return the stream and error", function(done){ + return this.handler.getFile(this.bucket, this.key, null, (err, stream)=> { + err.should.equal("err"); + stream.should.equal(this.fileStream); + return done(); + }); + }); + + return it("should pass options to PersistorManager", function(done) { + return this.handler.getFile(this.bucket, this.key, {start: 0, end: 8}, () => { + expect(this.PersistorManager.getFileStream.lastCall.args[2].start).to.equal(0); + expect(this.PersistorManager.getFileStream.lastCall.args[2].end).to.equal(8); + return done(); + }); + }); + }); + + + describe("_getConvertedFile", function() { + + it("should getFileStream if it does exists", function(done){ + this.PersistorManager.checkIfFileExists.callsArgWith(2, null, true); + this.PersistorManager.getFileStream.callsArgWith(3); + return this.handler._getConvertedFile(this.bucket, this.key, {}, () => { + this.PersistorManager.getFileStream.calledWith(this.bucket).should.equal(true); + return done(); + }); + }); + + return it("should call _getConvertedFileAndCache if it does exists", function(done){ + this.PersistorManager.checkIfFileExists.callsArgWith(2, null, false); + this.handler._getConvertedFileAndCache = sinon.stub().callsArgWith(4); + return this.handler._getConvertedFile(this.bucket, this.key, {}, () => { + this.handler._getConvertedFileAndCache.calledWith(this.bucket, this.key).should.equal(true); + return done(); + }); + }); + }); + + describe("_getConvertedFileAndCache", () => it("should _convertFile ", function(done){ + this.stubbedStream = {"something":"here"}; + this.localStream = { + on() {} + }; + this.PersistorManager.sendFile = sinon.stub().callsArgWith(3); + this.LocalFileWriter.getStream = sinon.stub().callsArgWith(1, null, this.localStream); + this.convetedKey = this.key+"converted"; + this.handler._convertFile = sinon.stub().callsArgWith(3, null, this.stubbedPath); + this.ImageOptimiser.compressPng = sinon.stub().callsArgWith(1); + return this.handler._getConvertedFileAndCache(this.bucket, this.key, this.convetedKey, {}, (err, fsStream)=> { + this.handler._convertFile.called.should.equal(true); + this.PersistorManager.sendFile.calledWith(this.bucket, this.convetedKey, this.stubbedPath).should.equal(true); + this.ImageOptimiser.compressPng.calledWith(this.stubbedPath).should.equal(true); + this.LocalFileWriter.getStream.calledWith(this.stubbedPath).should.equal(true); + fsStream.should.equal(this.localStream); + return done(); + }); + })); + + describe("_convertFile", function() { + beforeEach(function() { + this.FileConverter.convert.callsArgWith(2, null, this.formattedStubbedPath); + this.FileConverter.thumbnail.callsArgWith(1, null, this.formattedStubbedPath); + this.FileConverter.preview.callsArgWith(1, null, this.formattedStubbedPath); + this.handler._writeS3FileToDisk = sinon.stub().callsArgWith(3, null, this.stubbedPath); + return this.LocalFileWriter.deleteFile.callsArgWith(1); + }); + + it("should call thumbnail on the writer path if style was thumbnail was specified", function(done){ + return this.handler._convertFile(this.bucket, this.key, {style:"thumbnail"}, (err, path)=> { + path.should.equal(this.formattedStubbedPath); + this.FileConverter.thumbnail.calledWith(this.stubbedPath).should.equal(true); + this.LocalFileWriter.deleteFile.calledWith(this.stubbedPath).should.equal(true); + return done(); + }); + }); + + it("should call preview on the writer path if style was preview was specified", function(done){ + return this.handler._convertFile(this.bucket, this.key, {style:"preview"}, (err, path)=> { + path.should.equal(this.formattedStubbedPath); + this.FileConverter.preview.calledWith(this.stubbedPath).should.equal(true); + this.LocalFileWriter.deleteFile.calledWith(this.stubbedPath).should.equal(true); + return done(); + }); + }); + + return it("should call convert on the writer path if a format was specified", function(done){ + return this.handler._convertFile(this.bucket, this.key, {format:this.format}, (err, path)=> { + path.should.equal(this.formattedStubbedPath); + this.FileConverter.convert.calledWith(this.stubbedPath, this.format).should.equal(true); + this.LocalFileWriter.deleteFile.calledWith(this.stubbedPath).should.equal(true); + return done(); + }); + }); + }); + + return describe("getDirectorySize", function() { + + beforeEach(function() { + return this.PersistorManager.directorySize.callsArgWith(2); + }); + + return it("should call the filestore manager to get directory size", function(done){ + return this.handler.getDirectorySize(this.bucket, this.key, () => { + this.PersistorManager.directorySize.calledWith(this.bucket, this.key).should.equal(true); + return done(); + }); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/ImageOptimiserTests.js b/services/filestore/test/unit/coffee/ImageOptimiserTests.js index 398eacf70f..6074120a56 100644 --- a/services/filestore/test/unit/coffee/ImageOptimiserTests.js +++ b/services/filestore/test/unit/coffee/ImageOptimiserTests.js @@ -1,64 +1,84 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/ImageOptimiser.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/ImageOptimiser.js"; +const SandboxedModule = require('sandboxed-module'); -describe "ImageOptimiser", -> +describe("ImageOptimiser", function() { - beforeEach -> - @child_process = - exec : sinon.stub() - @settings = - enableConversions:true - @optimiser = SandboxedModule.require modulePath, requires: - 'child_process': @child_process - "logger-sharelatex": - log:-> - err:-> - warn:-> - "settings-sharelatex": @settings + beforeEach(function() { + this.child_process = + {exec : sinon.stub()}; + this.settings = + {enableConversions:true}; + this.optimiser = SandboxedModule.require(modulePath, { requires: { + 'child_process': this.child_process, + "logger-sharelatex": { + log() {}, + err() {}, + warn() {} + }, + "settings-sharelatex": this.settings + } + } + ); - @sourcePath = "/this/path/here.eps" - @error = "Error" + this.sourcePath = "/this/path/here.eps"; + return this.error = "Error"; + }); - describe "compressPng", -> + describe("compressPng", function() { - it "convert the file", (done)-> - @child_process.exec.callsArgWith(2) - @optimiser.compressPng @sourcePath, (err)=> - args = @child_process.exec.args[0][0] - args.should.equal "optipng #{@sourcePath}" - done() + it("convert the file", function(done){ + this.child_process.exec.callsArgWith(2); + return this.optimiser.compressPng(this.sourcePath, err=> { + const args = this.child_process.exec.args[0][0]; + args.should.equal(`optipng ${this.sourcePath}`); + return done(); + }); + }); - it "should return the error", (done)-> - @child_process.exec.callsArgWith(2, @error) - @optimiser.compressPng @sourcePath, (err)=> - err.should.equal @error - done() + return it("should return the error", function(done){ + this.child_process.exec.callsArgWith(2, this.error); + return this.optimiser.compressPng(this.sourcePath, err=> { + err.should.equal(this.error); + return done(); + }); + }); + }); - describe 'when enableConversions is disabled', -> - - it 'should produce an error', (done) -> - @settings.enableConversions = false - @child_process.exec.callsArgWith(2) - @optimiser.compressPng @sourcePath, (err)=> - @child_process.exec.called.should.equal false - expect(err).to.exist - done() + describe('when enableConversions is disabled', () => it('should produce an error', function(done) { + this.settings.enableConversions = false; + this.child_process.exec.callsArgWith(2); + return this.optimiser.compressPng(this.sourcePath, err=> { + this.child_process.exec.called.should.equal(false); + expect(err).to.exist; + return done(); + }); + })); - describe 'when optimiser is sigkilled', -> - - it 'should not produce an error', (done) -> - @error = new Error('woops') - @error.signal = 'SIGKILL' - @child_process.exec.callsArgWith(2, @error) - @optimiser.compressPng @sourcePath, (err)=> - expect(err).to.equal(null) - done() + return describe('when optimiser is sigkilled', () => it('should not produce an error', function(done) { + this.error = new Error('woops'); + this.error.signal = 'SIGKILL'; + this.child_process.exec.callsArgWith(2, this.error); + return this.optimiser.compressPng(this.sourcePath, err=> { + expect(err).to.equal(null); + return done(); + }); + })); +}); diff --git a/services/filestore/test/unit/coffee/KeybuilderTests.js b/services/filestore/test/unit/coffee/KeybuilderTests.js index 3ab2dd037a..063a278f23 100644 --- a/services/filestore/test/unit/coffee/KeybuilderTests.js +++ b/services/filestore/test/unit/coffee/KeybuilderTests.js @@ -1,39 +1,59 @@ +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/KeyBuilder.js" -SandboxedModule = require('sandboxed-module') +const { + assert +} = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +const should = chai.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/KeyBuilder.js"; +const SandboxedModule = require('sandboxed-module'); -describe "LocalFileWriter", -> +describe("LocalFileWriter", function() { - beforeEach -> + beforeEach(function() { - @keyBuilder = SandboxedModule.require modulePath, requires: - "logger-sharelatex": - log:-> - err:-> - @key = "123/456" + this.keyBuilder = SandboxedModule.require(modulePath, { requires: { + "logger-sharelatex": { + log() {}, + err() {} + } + } + } + ); + return this.key = "123/456"; + }); - describe "cachedKey", -> + return describe("cachedKey", function() { - it "should add the fomat on", -> - opts = + it("should add the fomat on", function() { + const opts = + {format: "png"}; + const newKey = this.keyBuilder.addCachingToKey(this.key, opts); + return newKey.should.equal(`${this.key}-converted-cache/format-png`); + }); + + it("should add the style on", function() { + const opts = + {style: "thumbnail"}; + const newKey = this.keyBuilder.addCachingToKey(this.key, opts); + return newKey.should.equal(`${this.key}-converted-cache/style-thumbnail`); + }); + + return it("should add format on first", function() { + const opts = { + style: "thumbnail", format: "png" - newKey = @keyBuilder.addCachingToKey @key, opts - newKey.should.equal "#{@key}-converted-cache/format-png" - - it "should add the style on", -> - opts = - style: "thumbnail" - newKey = @keyBuilder.addCachingToKey @key, opts - newKey.should.equal "#{@key}-converted-cache/style-thumbnail" - - it "should add format on first", -> - opts = - style: "thumbnail" - format: "png" - newKey = @keyBuilder.addCachingToKey @key, opts - newKey.should.equal "#{@key}-converted-cache/format-png-style-thumbnail" + }; + const newKey = this.keyBuilder.addCachingToKey(this.key, opts); + return newKey.should.equal(`${this.key}-converted-cache/format-png-style-thumbnail`); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/LocalFileWriterTests.js b/services/filestore/test/unit/coffee/LocalFileWriterTests.js index 55cf1f551f..ed3eb2dfa3 100644 --- a/services/filestore/test/unit/coffee/LocalFileWriterTests.js +++ b/services/filestore/test/unit/coffee/LocalFileWriterTests.js @@ -1,83 +1,121 @@ +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/LocalFileWriter.js" -SandboxedModule = require('sandboxed-module') +const { + assert +} = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +const should = chai.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/LocalFileWriter.js"; +const SandboxedModule = require('sandboxed-module'); -describe "LocalFileWriter", -> +describe("LocalFileWriter", function() { - beforeEach -> + beforeEach(function() { - @writeStream = - on: (type, cb)-> - if type == "finish" - cb() - @readStream = - on: -> - @fs = - createWriteStream : sinon.stub().returns(@writeStream) - createReadStream: sinon.stub().returns(@readStream) + this.writeStream = { + on(type, cb){ + if (type === "finish") { + return cb(); + } + } + }; + this.readStream = + {on() {}}; + this.fs = { + createWriteStream : sinon.stub().returns(this.writeStream), + createReadStream: sinon.stub().returns(this.readStream), unlink: sinon.stub() - @settings = - path: + }; + this.settings = { + path: { uploadFolder:"somewhere" - @writer = SandboxedModule.require modulePath, requires: - "fs": @fs - "logger-sharelatex": - log:-> - err:-> - "settings-sharelatex":@settings - "metrics-sharelatex": - inc:-> - Timer:-> - done:-> + } + }; + this.writer = SandboxedModule.require(modulePath, { requires: { + "fs": this.fs, + "logger-sharelatex": { + log() {}, + err() {} + }, + "settings-sharelatex":this.settings, + "metrics-sharelatex": { + inc() {}, + Timer() { + return {done() {}}; + } + } + } + } + ); - @stubbedFsPath = "something/uploads/eio2k1j3" + return this.stubbedFsPath = "something/uploads/eio2k1j3"; + }); - describe "writeStrem", -> - beforeEach -> - @writer._getPath = sinon.stub().returns(@stubbedFsPath) + describe("writeStrem", function() { + beforeEach(function() { + return this.writer._getPath = sinon.stub().returns(this.stubbedFsPath); + }); - it "write the stream to ./uploads", (done)-> - stream = - pipe: (dest)=> - dest.should.equal @writeStream - done() - on: -> - @writer.writeStream stream, null, ()=> + it("write the stream to ./uploads", function(done){ + const stream = { + pipe: dest=> { + dest.should.equal(this.writeStream); + return done(); + }, + on() {} + }; + return this.writer.writeStream(stream, null, ()=> {}); + }); - it "should send the path in the callback", (done)-> - stream = - pipe: (dest)=> - on: (type, cb)-> - if type == "end" - cb() - @writer.writeStream stream, null, (err, fsPath)=> - fsPath.should.equal @stubbedFsPath - done() + return it("should send the path in the callback", function(done){ + const stream = { + pipe: dest=> {}, + on(type, cb){ + if (type === "end") { + return cb(); + } + } + }; + return this.writer.writeStream(stream, null, (err, fsPath)=> { + fsPath.should.equal(this.stubbedFsPath); + return done(); + }); + }); + }); - describe "getStream", -> + describe("getStream", function() { - it "should read the stream from the file ", (done)-> - @writer.getStream @stubbedFsPath, (err, stream)=> - @fs.createReadStream.calledWith(@stubbedFsPath).should.equal true - done() + it("should read the stream from the file ", function(done){ + return this.writer.getStream(this.stubbedFsPath, (err, stream)=> { + this.fs.createReadStream.calledWith(this.stubbedFsPath).should.equal(true); + return done(); + }); + }); - it "should send the stream in the callback", (done)-> - @writer.getStream @stubbedFsPath, (err, readStream)=> - readStream.should.equal @readStream - done() + return it("should send the stream in the callback", function(done){ + return this.writer.getStream(this.stubbedFsPath, (err, readStream)=> { + readStream.should.equal(this.readStream); + return done(); + }); + }); + }); - describe "delete file", -> - - it "should unlink the file", (done)-> - error = "my error" - @fs.unlink.callsArgWith(1, error) - @writer.deleteFile @stubbedFsPath, (err)=> - @fs.unlink.calledWith(@stubbedFsPath).should.equal true - err.should.equal error - done() + return describe("delete file", () => it("should unlink the file", function(done){ + const error = "my error"; + this.fs.unlink.callsArgWith(1, error); + return this.writer.deleteFile(this.stubbedFsPath, err=> { + this.fs.unlink.calledWith(this.stubbedFsPath).should.equal(true); + err.should.equal(error); + return done(); + }); + })); +}); diff --git a/services/filestore/test/unit/coffee/PersistorManagerTests.js b/services/filestore/test/unit/coffee/PersistorManagerTests.js index 3c4ca329e1..d5b859448a 100644 --- a/services/filestore/test/unit/coffee/PersistorManagerTests.js +++ b/services/filestore/test/unit/coffee/PersistorManagerTests.js @@ -1,101 +1,131 @@ -logger = require("logger-sharelatex") -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/PersistorManager.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const logger = require("logger-sharelatex"); +const { + assert +} = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +const should = chai.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/PersistorManager.js"; +const SandboxedModule = require('sandboxed-module'); -describe "PersistorManagerTests", -> +describe("PersistorManagerTests", function() { - beforeEach -> - @S3PersistorManager = - getFileStream: sinon.stub() - checkIfFileExists: sinon.stub() - deleteFile: sinon.stub() - deleteDirectory: sinon.stub() - sendStream: sinon.stub() + beforeEach(function() { + return this.S3PersistorManager = { + getFileStream: sinon.stub(), + checkIfFileExists: sinon.stub(), + deleteFile: sinon.stub(), + deleteDirectory: sinon.stub(), + sendStream: sinon.stub(), insertFile: sinon.stub() + }; + }); - describe "test s3 mixin", -> - beforeEach -> - @settings = - filestore: + describe("test s3 mixin", function() { + beforeEach(function() { + this.settings = { + filestore: { backend: "s3" - @requires = - "./S3PersistorManager": @S3PersistorManager - "settings-sharelatex": @settings - "logger-sharelatex": - log:-> - err:-> - @PersistorManager = SandboxedModule.require modulePath, requires: @requires + } + }; + this.requires = { + "./S3PersistorManager": this.S3PersistorManager, + "settings-sharelatex": this.settings, + "logger-sharelatex": { + log() {}, + err() {} + } + }; + return this.PersistorManager = SandboxedModule.require(modulePath, {requires: this.requires}); + }); - it "should load getFileStream", (done) -> - @PersistorManager.should.respondTo("getFileStream") - @PersistorManager.getFileStream() - @S3PersistorManager.getFileStream.calledOnce.should.equal true - done() + it("should load getFileStream", function(done) { + this.PersistorManager.should.respondTo("getFileStream"); + this.PersistorManager.getFileStream(); + this.S3PersistorManager.getFileStream.calledOnce.should.equal(true); + return done(); + }); - it "should load checkIfFileExists", (done) -> - @PersistorManager.checkIfFileExists() - @S3PersistorManager.checkIfFileExists.calledOnce.should.equal true - done() + it("should load checkIfFileExists", function(done) { + this.PersistorManager.checkIfFileExists(); + this.S3PersistorManager.checkIfFileExists.calledOnce.should.equal(true); + return done(); + }); - it "should load deleteFile", (done) -> - @PersistorManager.deleteFile() - @S3PersistorManager.deleteFile.calledOnce.should.equal true - done() + it("should load deleteFile", function(done) { + this.PersistorManager.deleteFile(); + this.S3PersistorManager.deleteFile.calledOnce.should.equal(true); + return done(); + }); - it "should load deleteDirectory", (done) -> - @PersistorManager.deleteDirectory() - @S3PersistorManager.deleteDirectory.calledOnce.should.equal true - done() + it("should load deleteDirectory", function(done) { + this.PersistorManager.deleteDirectory(); + this.S3PersistorManager.deleteDirectory.calledOnce.should.equal(true); + return done(); + }); - it "should load sendStream", (done) -> - @PersistorManager.sendStream() - @S3PersistorManager.sendStream.calledOnce.should.equal true - done() + it("should load sendStream", function(done) { + this.PersistorManager.sendStream(); + this.S3PersistorManager.sendStream.calledOnce.should.equal(true); + return done(); + }); - it "should load insertFile", (done) -> - @PersistorManager.insertFile() - @S3PersistorManager.insertFile.calledOnce.should.equal true - done() + return it("should load insertFile", function(done) { + this.PersistorManager.insertFile(); + this.S3PersistorManager.insertFile.calledOnce.should.equal(true); + return done(); + }); + }); - describe "test unspecified mixins", -> + describe("test unspecified mixins", () => it("should load s3 when no wrapper specified", function(done) { + this.settings = {filestore:{}}; + this.requires = { + "./S3PersistorManager": this.S3PersistorManager, + "settings-sharelatex": this.settings, + "logger-sharelatex": { + log() {}, + err() {} + } + }; + this.PersistorManager = SandboxedModule.require(modulePath, {requires: this.requires}); + this.PersistorManager.should.respondTo("getFileStream"); + this.PersistorManager.getFileStream(); + this.S3PersistorManager.getFileStream.calledOnce.should.equal(true); + return done(); + })); - it "should load s3 when no wrapper specified", (done) -> - @settings = {filestore:{}} - @requires = - "./S3PersistorManager": @S3PersistorManager - "settings-sharelatex": @settings - "logger-sharelatex": - log:-> - err:-> - @PersistorManager = SandboxedModule.require modulePath, requires: @requires - @PersistorManager.should.respondTo("getFileStream") - @PersistorManager.getFileStream() - @S3PersistorManager.getFileStream.calledOnce.should.equal true - done() - - describe "test invalid mixins", -> - it "should not load an invalid wrapper", (done) -> - @settings = - filestore: - backend:"magic" - @requires = - "./S3PersistorManager": @S3PersistorManager - "settings-sharelatex": @settings - "logger-sharelatex": - log:-> - err:-> - @fsWrapper=null - try - @PersistorManager=SandboxedModule.require modulePath, requires: @requires - catch error - assert.equal("Unknown filestore backend: magic",error.message) - assert.isNull(@fsWrapper) - done() + return describe("test invalid mixins", () => it("should not load an invalid wrapper", function(done) { + this.settings = { + filestore: { + backend:"magic" + } + }; + this.requires = { + "./S3PersistorManager": this.S3PersistorManager, + "settings-sharelatex": this.settings, + "logger-sharelatex": { + log() {}, + err() {} + } + }; + this.fsWrapper=null; + try { + this.PersistorManager=SandboxedModule.require(modulePath, {requires: this.requires}); + } catch (error) { + assert.equal("Unknown filestore backend: magic",error.message); + } + assert.isNull(this.fsWrapper); + return done(); + })); +}); diff --git a/services/filestore/test/unit/coffee/S3PersistorManagerTests.js b/services/filestore/test/unit/coffee/S3PersistorManagerTests.js index a5ab5c2932..4396ce9606 100644 --- a/services/filestore/test/unit/coffee/S3PersistorManagerTests.js +++ b/services/filestore/test/unit/coffee/S3PersistorManagerTests.js @@ -1,343 +1,447 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/S3PersistorManager.js" -SandboxedModule = require('sandboxed-module') +/* + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/S3PersistorManager.js"; +const SandboxedModule = require('sandboxed-module'); -describe "S3PersistorManagerTests", -> +describe("S3PersistorManagerTests", function() { - beforeEach -> - @settings = - filestore: - backend: "s3" - s3: - secret: "secret" + beforeEach(function() { + this.settings = { + filestore: { + backend: "s3", + s3: { + secret: "secret", key: "this_key" - stores: + }, + stores: { user_files:"sl_user_files" - @knoxClient = - putFile:sinon.stub() - copyFile:sinon.stub() - list: sinon.stub() - deleteMultiple: sinon.stub() - get: sinon.stub() - @knox = - createClient: sinon.stub().returns(@knoxClient) - @s3EventHandlers = {} - @s3Request = - on: sinon.stub().callsFake (event, callback) => - @s3EventHandlers[event] = callback - send: sinon.stub() - @s3Response = - httpResponse: - createUnbufferedStream: sinon.stub() - @s3Client = - copyObject: sinon.stub() - headObject: sinon.stub() - getObject: sinon.stub().returns(@s3Request) - @awsS3 = sinon.stub().returns(@s3Client) - @LocalFileWriter = - writeStream: sinon.stub() - deleteFile: sinon.stub() - @request = sinon.stub() - @requires = - "knox": @knox - "aws-sdk/clients/s3": @awsS3 - "settings-sharelatex": @settings - "./LocalFileWriter":@LocalFileWriter - "logger-sharelatex": - log:-> - err:-> - "request": @request - "./Errors": @Errors = - NotFoundError: sinon.stub() - @key = "my/key" - @bucketName = "my-bucket" - @error = "my errror" - @S3PersistorManager = SandboxedModule.require modulePath, requires: @requires - - describe "getFileStream", -> - describe "success", -> - beforeEach () -> - @expectedStream = { expectedStream: true } - @expectedStream.on = sinon.stub() - @s3Request.send.callsFake () => - @s3EventHandlers.httpHeaders(200, {}, @s3Response, "OK") - @s3Response.httpResponse.createUnbufferedStream.returns(@expectedStream) - - it "returns a stream", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - if err? - return done(err) - expect(stream).to.equal(@expectedStream) - done() - - it "sets the AWS client up with credentials from settings", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - if err? - return done(err) - expect(@awsS3.lastCall.args).to.deep.equal([{ - credentials: - accessKeyId: @settings.filestore.s3.key - secretAccessKey: @settings.filestore.s3.secret - }]) - done() - - it "fetches the right key from the right bucket", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - if err? - return done(err) - expect(@s3Client.getObject.lastCall.args).to.deep.equal([{ - Bucket: @bucketName, - Key: @key - }]) - done() - - it "accepts alternative credentials", (done) -> - accessKeyId = "that_key" - secret = "that_secret" - opts = { - credentials: - auth_key: accessKeyId - auth_secret: secret } - @S3PersistorManager.getFileStream @bucketName, @key, opts, (err, stream) => - if err? - return done(err) - expect(@awsS3.lastCall.args).to.deep.equal([{ - credentials: - accessKeyId: accessKeyId + } + }; + this.knoxClient = { + putFile:sinon.stub(), + copyFile:sinon.stub(), + list: sinon.stub(), + deleteMultiple: sinon.stub(), + get: sinon.stub() + }; + this.knox = + {createClient: sinon.stub().returns(this.knoxClient)}; + this.s3EventHandlers = {}; + this.s3Request = { + on: sinon.stub().callsFake((event, callback) => { + return this.s3EventHandlers[event] = callback; + }), + send: sinon.stub() + }; + this.s3Response = { + httpResponse: { + createUnbufferedStream: sinon.stub() + } + }; + this.s3Client = { + copyObject: sinon.stub(), + headObject: sinon.stub(), + getObject: sinon.stub().returns(this.s3Request) + }; + this.awsS3 = sinon.stub().returns(this.s3Client); + this.LocalFileWriter = { + writeStream: sinon.stub(), + deleteFile: sinon.stub() + }; + this.request = sinon.stub(); + this.requires = { + "knox": this.knox, + "aws-sdk/clients/s3": this.awsS3, + "settings-sharelatex": this.settings, + "./LocalFileWriter":this.LocalFileWriter, + "logger-sharelatex": { + log() {}, + err() {} + }, + "request": this.request, + "./Errors": (this.Errors = + {NotFoundError: sinon.stub()}) + }; + this.key = "my/key"; + this.bucketName = "my-bucket"; + this.error = "my errror"; + return this.S3PersistorManager = SandboxedModule.require(modulePath, {requires: this.requires}); + }); + + describe("getFileStream", function() { + describe("success", function() { + beforeEach(function() { + this.expectedStream = { expectedStream: true }; + this.expectedStream.on = sinon.stub(); + this.s3Request.send.callsFake(() => { + return this.s3EventHandlers.httpHeaders(200, {}, this.s3Response, "OK"); + }); + return this.s3Response.httpResponse.createUnbufferedStream.returns(this.expectedStream); + }); + + it("returns a stream", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + if (err != null) { + return done(err); + } + expect(stream).to.equal(this.expectedStream); + return done(); + }); + }); + + it("sets the AWS client up with credentials from settings", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + if (err != null) { + return done(err); + } + expect(this.awsS3.lastCall.args).to.deep.equal([{ + credentials: { + accessKeyId: this.settings.filestore.s3.key, + secretAccessKey: this.settings.filestore.s3.secret + } + }]); + return done(); + }); + }); + + it("fetches the right key from the right bucket", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + if (err != null) { + return done(err); + } + expect(this.s3Client.getObject.lastCall.args).to.deep.equal([{ + Bucket: this.bucketName, + Key: this.key + }]); + return done(); + }); + }); + + it("accepts alternative credentials", function(done) { + const accessKeyId = "that_key"; + const secret = "that_secret"; + const opts = { + credentials: { + auth_key: accessKeyId, + auth_secret: secret + } + }; + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, opts, (err, stream) => { + if (err != null) { + return done(err); + } + expect(this.awsS3.lastCall.args).to.deep.equal([{ + credentials: { + accessKeyId, secretAccessKey: secret - }]) - expect(stream).to.equal(@expectedStream) - done() + } + }]); + expect(stream).to.equal(this.expectedStream); + return done(); + }); + }); - it "accepts byte range", (done) -> - start = 0 - end = 8 - opts = { start: start, end: end } - @S3PersistorManager.getFileStream @bucketName, @key, opts, (err, stream) => - if err? - return done(err) - expect(@s3Client.getObject.lastCall.args).to.deep.equal([{ - Bucket: @bucketName - Key: @key - Range: "bytes=#{start}-#{end}" - }]) - expect(stream).to.equal(@expectedStream) - done() + return it("accepts byte range", function(done) { + const start = 0; + const end = 8; + const opts = { start, end }; + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, opts, (err, stream) => { + if (err != null) { + return done(err); + } + expect(this.s3Client.getObject.lastCall.args).to.deep.equal([{ + Bucket: this.bucketName, + Key: this.key, + Range: `bytes=${start}-${end}` + }]); + expect(stream).to.equal(this.expectedStream); + return done(); + }); + }); + }); - describe "errors", -> - describe "when the file doesn't exist", -> - beforeEach -> - @s3Request.send.callsFake () => - @s3EventHandlers.httpHeaders(404, {}, @s3Response, "Not found") + return describe("errors", function() { + describe("when the file doesn't exist", function() { + beforeEach(function() { + return this.s3Request.send.callsFake(() => { + return this.s3EventHandlers.httpHeaders(404, {}, this.s3Response, "Not found"); + }); + }); - it "returns a NotFoundError that indicates the bucket and key", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - expect(err).to.be.instanceof(@Errors.NotFoundError) - errMsg = @Errors.NotFoundError.lastCall.args[0] - expect(errMsg).to.match(new RegExp(".*#{@bucketName}.*")) - expect(errMsg).to.match(new RegExp(".*#{@key}.*")) - done() + return it("returns a NotFoundError that indicates the bucket and key", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + expect(err).to.be.instanceof(this.Errors.NotFoundError); + const errMsg = this.Errors.NotFoundError.lastCall.args[0]; + expect(errMsg).to.match(new RegExp(`.*${this.bucketName}.*`)); + expect(errMsg).to.match(new RegExp(`.*${this.key}.*`)); + return done(); + }); + }); + }); - describe "when S3 encounters an unkown error", -> - beforeEach -> - @s3Request.send.callsFake () => - @s3EventHandlers.httpHeaders(500, {}, @s3Response, "Internal server error") + describe("when S3 encounters an unkown error", function() { + beforeEach(function() { + return this.s3Request.send.callsFake(() => { + return this.s3EventHandlers.httpHeaders(500, {}, this.s3Response, "Internal server error"); + }); + }); - it "returns an error", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - expect(err).to.be.instanceof(Error) - done() + return it("returns an error", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + expect(err).to.be.instanceof(Error); + return done(); + }); + }); + }); - describe "when the S3 request errors out before receiving HTTP headers", -> - beforeEach -> - @s3Request.send.callsFake () => - @s3EventHandlers.error(new Error("connection failed")) + return describe("when the S3 request errors out before receiving HTTP headers", function() { + beforeEach(function() { + return this.s3Request.send.callsFake(() => { + return this.s3EventHandlers.error(new Error("connection failed")); + }); + }); - it "returns an error", (done) -> - @S3PersistorManager.getFileStream @bucketName, @key, {}, (err, stream) => - expect(err).to.be.instanceof(Error) - done() + return it("returns an error", function(done) { + return this.S3PersistorManager.getFileStream(this.bucketName, this.key, {}, (err, stream) => { + expect(err).to.be.instanceof(Error); + return done(); + }); + }); + }); + }); + }); - describe "getFileSize", -> - it "should obtain the file size from S3", (done) -> - expectedFileSize = 123 - @s3Client.headObject.yields(new Error( + describe("getFileSize", function() { + it("should obtain the file size from S3", function(done) { + const expectedFileSize = 123; + this.s3Client.headObject.yields(new Error( "s3Client.headObject got unexpected arguments" - )) - @s3Client.headObject.withArgs({ - Bucket: @bucketName - Key: @key - }).yields(null, { ContentLength: expectedFileSize }) + )); + this.s3Client.headObject.withArgs({ + Bucket: this.bucketName, + Key: this.key + }).yields(null, { ContentLength: expectedFileSize }); - @S3PersistorManager.getFileSize @bucketName, @key, (err, fileSize) => - if err? - return done(err) - expect(fileSize).to.equal(expectedFileSize) - done() + return this.S3PersistorManager.getFileSize(this.bucketName, this.key, (err, fileSize) => { + if (err != null) { + return done(err); + } + expect(fileSize).to.equal(expectedFileSize); + return done(); + }); + }); - [403, 404].forEach (statusCode) -> - it "should throw NotFoundError when S3 responds with #{statusCode}", (done) -> - error = new Error() - error.statusCode = statusCode - @s3Client.headObject.yields(error) + [403, 404].forEach(statusCode => it(`should throw NotFoundError when S3 responds with ${statusCode}`, function(done) { + const error = new Error(); + error.statusCode = statusCode; + this.s3Client.headObject.yields(error); - @S3PersistorManager.getFileSize @bucketName, @key, (err, fileSize) => - expect(err).to.be.an.instanceof(@Errors.NotFoundError) - done() + return this.S3PersistorManager.getFileSize(this.bucketName, this.key, (err, fileSize) => { + expect(err).to.be.an.instanceof(this.Errors.NotFoundError); + return done(); + }); + })); - it "should rethrow any other error", (done) -> - error = new Error() - @s3Client.headObject.yields(error) - @s3Client.headObject.yields(error) + return it("should rethrow any other error", function(done) { + const error = new Error(); + this.s3Client.headObject.yields(error); + this.s3Client.headObject.yields(error); - @S3PersistorManager.getFileSize @bucketName, @key, (err, fileSize) => - expect(err).to.equal(error) - done() + return this.S3PersistorManager.getFileSize(this.bucketName, this.key, (err, fileSize) => { + expect(err).to.equal(error); + return done(); + }); + }); + }); - describe "sendFile", -> + describe("sendFile", function() { - beforeEach -> - @knoxClient.putFile.returns on:-> + beforeEach(function() { + return this.knoxClient.putFile.returns({on() {}}); + }); - it "should put file with knox", (done)-> - @LocalFileWriter.deleteFile.callsArgWith(1) - @knoxClient.putFile.callsArgWith(2, @error) - @S3PersistorManager.sendFile @bucketName, @key, @fsPath, (err)=> - @knoxClient.putFile.calledWith(@fsPath, @key).should.equal true - err.should.equal @error - done() + it("should put file with knox", function(done){ + this.LocalFileWriter.deleteFile.callsArgWith(1); + this.knoxClient.putFile.callsArgWith(2, this.error); + return this.S3PersistorManager.sendFile(this.bucketName, this.key, this.fsPath, err=> { + this.knoxClient.putFile.calledWith(this.fsPath, this.key).should.equal(true); + err.should.equal(this.error); + return done(); + }); + }); - it "should delete the file and pass the error with it", (done)-> - @LocalFileWriter.deleteFile.callsArgWith(1) - @knoxClient.putFile.callsArgWith(2, @error) - @S3PersistorManager.sendFile @bucketName, @key, @fsPath, (err)=> - @knoxClient.putFile.calledWith(@fsPath, @key).should.equal true - err.should.equal @error - done() + return it("should delete the file and pass the error with it", function(done){ + this.LocalFileWriter.deleteFile.callsArgWith(1); + this.knoxClient.putFile.callsArgWith(2, this.error); + return this.S3PersistorManager.sendFile(this.bucketName, this.key, this.fsPath, err=> { + this.knoxClient.putFile.calledWith(this.fsPath, this.key).should.equal(true); + err.should.equal(this.error); + return done(); + }); + }); + }); - describe "sendStream", -> - beforeEach -> - @fsPath = "to/some/where" - @origin = - on:-> - @S3PersistorManager.sendFile = sinon.stub().callsArgWith(3) + describe("sendStream", function() { + beforeEach(function() { + this.fsPath = "to/some/where"; + this.origin = + {on() {}}; + return this.S3PersistorManager.sendFile = sinon.stub().callsArgWith(3); + }); - it "should send stream to LocalFileWriter", (done)-> - @LocalFileWriter.deleteFile.callsArgWith(1) - @LocalFileWriter.writeStream.callsArgWith(2, null, @fsPath) - @S3PersistorManager.sendStream @bucketName, @key, @origin, => - @LocalFileWriter.writeStream.calledWith(@origin).should.equal true - done() + it("should send stream to LocalFileWriter", function(done){ + this.LocalFileWriter.deleteFile.callsArgWith(1); + this.LocalFileWriter.writeStream.callsArgWith(2, null, this.fsPath); + return this.S3PersistorManager.sendStream(this.bucketName, this.key, this.origin, () => { + this.LocalFileWriter.writeStream.calledWith(this.origin).should.equal(true); + return done(); + }); + }); - it "should return the error from LocalFileWriter", (done)-> - @LocalFileWriter.deleteFile.callsArgWith(1) - @LocalFileWriter.writeStream.callsArgWith(2, @error) - @S3PersistorManager.sendStream @bucketName, @key, @origin, (err)=> - err.should.equal @error - done() + it("should return the error from LocalFileWriter", function(done){ + this.LocalFileWriter.deleteFile.callsArgWith(1); + this.LocalFileWriter.writeStream.callsArgWith(2, this.error); + return this.S3PersistorManager.sendStream(this.bucketName, this.key, this.origin, err=> { + err.should.equal(this.error); + return done(); + }); + }); - it "should send the file to the filestore", (done)-> - @LocalFileWriter.deleteFile.callsArgWith(1) - @LocalFileWriter.writeStream.callsArgWith(2) - @S3PersistorManager.sendStream @bucketName, @key, @origin, (err)=> - @S3PersistorManager.sendFile.called.should.equal true - done() + return it("should send the file to the filestore", function(done){ + this.LocalFileWriter.deleteFile.callsArgWith(1); + this.LocalFileWriter.writeStream.callsArgWith(2); + return this.S3PersistorManager.sendStream(this.bucketName, this.key, this.origin, err=> { + this.S3PersistorManager.sendFile.called.should.equal(true); + return done(); + }); + }); + }); - describe "copyFile", -> - beforeEach -> - @sourceKey = "my/key" - @destKey = "my/dest/key" + describe("copyFile", function() { + beforeEach(function() { + this.sourceKey = "my/key"; + return this.destKey = "my/dest/key"; + }); - it "should use AWS SDK to copy file", (done)-> - @s3Client.copyObject.callsArgWith(1, @error) - @S3PersistorManager.copyFile @bucketName, @sourceKey, @destKey, (err)=> - err.should.equal @error - @s3Client.copyObject.calledWith({Bucket: @bucketName, Key: @destKey, CopySource: @bucketName + '/' + @key}).should.equal true - done() + it("should use AWS SDK to copy file", function(done){ + this.s3Client.copyObject.callsArgWith(1, this.error); + return this.S3PersistorManager.copyFile(this.bucketName, this.sourceKey, this.destKey, err=> { + err.should.equal(this.error); + this.s3Client.copyObject.calledWith({Bucket: this.bucketName, Key: this.destKey, CopySource: this.bucketName + '/' + this.key}).should.equal(true); + return done(); + }); + }); - it "should return a NotFoundError object if the original file does not exist", (done)-> - NoSuchKeyError = {code: "NoSuchKey"} - @s3Client.copyObject.callsArgWith(1, NoSuchKeyError) - @S3PersistorManager.copyFile @bucketName, @sourceKey, @destKey, (err)=> - expect(err instanceof @Errors.NotFoundError).to.equal true - done() + return it("should return a NotFoundError object if the original file does not exist", function(done){ + const NoSuchKeyError = {code: "NoSuchKey"}; + this.s3Client.copyObject.callsArgWith(1, NoSuchKeyError); + return this.S3PersistorManager.copyFile(this.bucketName, this.sourceKey, this.destKey, err=> { + expect(err instanceof this.Errors.NotFoundError).to.equal(true); + return done(); + }); + }); + }); - describe "deleteDirectory", -> + describe("deleteDirectory", () => it("should list the contents passing them onto multi delete", function(done){ + const data = + {Contents: [{Key:"1234"}, {Key: "456"}]}; + this.knoxClient.list.callsArgWith(1, null, data); + this.knoxClient.deleteMultiple.callsArgWith(1); + return this.S3PersistorManager.deleteDirectory(this.bucketName, this.key, err=> { + this.knoxClient.deleteMultiple.calledWith(["1234","456"]).should.equal(true); + return done(); + }); + })); - it "should list the contents passing them onto multi delete", (done)-> - data = - Contents: [{Key:"1234"}, {Key: "456"}] - @knoxClient.list.callsArgWith(1, null, data) - @knoxClient.deleteMultiple.callsArgWith(1) - @S3PersistorManager.deleteDirectory @bucketName, @key, (err)=> - @knoxClient.deleteMultiple.calledWith(["1234","456"]).should.equal true - done() + describe("deleteFile", function() { - describe "deleteFile", -> + it("should use correct options", function(done){ + this.request.callsArgWith(1); - it "should use correct options", (done)-> - @request.callsArgWith(1) + return this.S3PersistorManager.deleteFile(this.bucketName, this.key, err=> { + const opts = this.request.args[0][0]; + assert.deepEqual(opts.aws, {key:this.settings.filestore.s3.key, secret:this.settings.filestore.s3.secret, bucket:this.bucketName}); + opts.method.should.equal("delete"); + opts.timeout.should.equal((30*1000)); + opts.uri.should.equal(`https://${this.bucketName}.s3.amazonaws.com/${this.key}`); + return done(); + }); + }); - @S3PersistorManager.deleteFile @bucketName, @key, (err)=> - opts = @request.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@bucketName}) - opts.method.should.equal "delete" - opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@bucketName}.s3.amazonaws.com/#{@key}" - done() + return it("should return the error", function(done){ + this.request.callsArgWith(1, this.error); - it "should return the error", (done)-> - @request.callsArgWith(1, @error) + return this.S3PersistorManager.deleteFile(this.bucketName, this.key, err=> { + err.should.equal(this.error); + return done(); + }); + }); + }); - @S3PersistorManager.deleteFile @bucketName, @key, (err)=> - err.should.equal @error - done() + describe("checkIfFileExists", function() { - describe "checkIfFileExists", -> + it("should use correct options", function(done){ + this.request.callsArgWith(1, null, {statusCode:200}); - it "should use correct options", (done)-> - @request.callsArgWith(1, null, statusCode:200) + return this.S3PersistorManager.checkIfFileExists(this.bucketName, this.key, err=> { + const opts = this.request.args[0][0]; + assert.deepEqual(opts.aws, {key:this.settings.filestore.s3.key, secret:this.settings.filestore.s3.secret, bucket:this.bucketName}); + opts.method.should.equal("head"); + opts.timeout.should.equal((30*1000)); + opts.uri.should.equal(`https://${this.bucketName}.s3.amazonaws.com/${this.key}`); + return done(); + }); + }); - @S3PersistorManager.checkIfFileExists @bucketName, @key, (err)=> - opts = @request.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@bucketName}) - opts.method.should.equal "head" - opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@bucketName}.s3.amazonaws.com/#{@key}" - done() + it("should return true for a 200", function(done){ + this.request.callsArgWith(1, null, {statusCode:200}); - it "should return true for a 200", (done)-> - @request.callsArgWith(1, null, statusCode:200) + return this.S3PersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists)=> { + exists.should.equal(true); + return done(); + }); + }); - @S3PersistorManager.checkIfFileExists @bucketName, @key, (err, exists)=> - exists.should.equal true - done() + it("should return false for a non 200", function(done){ + this.request.callsArgWith(1, null, {statusCode:404}); - it "should return false for a non 200", (done)-> - @request.callsArgWith(1, null, statusCode:404) + return this.S3PersistorManager.checkIfFileExists(this.bucketName, this.key, (err, exists)=> { + exists.should.equal(false); + return done(); + }); + }); - @S3PersistorManager.checkIfFileExists @bucketName, @key, (err, exists)=> - exists.should.equal false - done() + return it("should return the error", function(done){ + this.request.callsArgWith(1, this.error, {}); - it "should return the error", (done)-> - @request.callsArgWith(1, @error, {}) + return this.S3PersistorManager.checkIfFileExists(this.bucketName, this.key, err=> { + err.should.equal(this.error); + return done(); + }); + }); + }); - @S3PersistorManager.checkIfFileExists @bucketName, @key, (err)=> - err.should.equal @error - done() - - describe "directorySize", -> - - it "should sum directory files size", (done) -> - data = - Contents: [ {Size: 1024}, {Size: 2048} ] - @knoxClient.list.callsArgWith(1, null, data) - @S3PersistorManager.directorySize @bucketName, @key, (err, totalSize)=> - totalSize.should.equal 3072 - done() + return describe("directorySize", () => it("should sum directory files size", function(done) { + const data = + {Contents: [ {Size: 1024}, {Size: 2048} ]}; + this.knoxClient.list.callsArgWith(1, null, data); + return this.S3PersistorManager.directorySize(this.bucketName, this.key, (err, totalSize)=> { + totalSize.should.equal(3072); + return done(); + }); + })); +}); diff --git a/services/filestore/test/unit/coffee/SafeExecTests.js b/services/filestore/test/unit/coffee/SafeExecTests.js index 1be22f3993..4c462f887d 100644 --- a/services/filestore/test/unit/coffee/SafeExecTests.js +++ b/services/filestore/test/unit/coffee/SafeExecTests.js @@ -1,50 +1,75 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/SafeExec.js" -SandboxedModule = require('sandboxed-module') +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/SafeExec.js"; +const SandboxedModule = require('sandboxed-module'); -describe "SafeExec", -> +describe("SafeExec", function() { - beforeEach -> - @settings = - enableConversions:true - @safe_exec = SandboxedModule.require modulePath, requires: - "logger-sharelatex": - log:-> - err:-> - "settings-sharelatex": @settings - @options = {timeout: 10*1000, killSignal: "SIGTERM" } + beforeEach(function() { + this.settings = + {enableConversions:true}; + this.safe_exec = SandboxedModule.require(modulePath, { requires: { + "logger-sharelatex": { + log() {}, + err() {} + }, + "settings-sharelatex": this.settings + } + } + ); + return this.options = {timeout: 10*1000, killSignal: "SIGTERM" };}); - describe "safe_exec", -> + return describe("safe_exec", function() { - it "should execute a valid command", (done) -> - @safe_exec ["/bin/echo", "hello"], @options, (err, stdout, stderr) => - stdout.should.equal "hello\n" - should.not.exist(err) - done() + it("should execute a valid command", function(done) { + return this.safe_exec(["/bin/echo", "hello"], this.options, (err, stdout, stderr) => { + stdout.should.equal("hello\n"); + should.not.exist(err); + return done(); + }); + }); - it "should error when conversions are disabled", (done) -> - @settings.enableConversions = false - @safe_exec ["/bin/echo", "hello"], @options, (err, stdout, stderr) => - expect(err).to.exist - done() + it("should error when conversions are disabled", function(done) { + this.settings.enableConversions = false; + return this.safe_exec(["/bin/echo", "hello"], this.options, (err, stdout, stderr) => { + expect(err).to.exist; + return done(); + }); + }); - it "should execute a command with non-zero exit status", (done) -> - @safe_exec ["/usr/bin/env", "false"], @options, (err, stdout, stderr) => - stdout.should.equal "" - stderr.should.equal "" - err.message.should.equal "exit status 1" - done() + it("should execute a command with non-zero exit status", function(done) { + return this.safe_exec(["/usr/bin/env", "false"], this.options, (err, stdout, stderr) => { + stdout.should.equal(""); + stderr.should.equal(""); + err.message.should.equal("exit status 1"); + return done(); + }); + }); - it "should handle an invalid command", (done) -> - @safe_exec ["/bin/foobar"], @options, (err, stdout, stderr) => - err.code.should.equal "ENOENT" - done() + it("should handle an invalid command", function(done) { + return this.safe_exec(["/bin/foobar"], this.options, (err, stdout, stderr) => { + err.code.should.equal("ENOENT"); + return done(); + }); + }); - it "should handle a command that runs too long", (done) -> - @safe_exec ["/bin/sleep", "10"], {timeout: 500, killSignal: "SIGTERM"}, (err, stdout, stderr) => - err.should.equal "SIGTERM" - done() + return it("should handle a command that runs too long", function(done) { + return this.safe_exec(["/bin/sleep", "10"], {timeout: 500, killSignal: "SIGTERM"}, (err, stdout, stderr) => { + err.should.equal("SIGTERM"); + return done(); + }); + }); + }); +}); diff --git a/services/filestore/test/unit/coffee/SettingsTests.js b/services/filestore/test/unit/coffee/SettingsTests.js index efb690511e..5c1b79d70c 100644 --- a/services/filestore/test/unit/coffee/SettingsTests.js +++ b/services/filestore/test/unit/coffee/SettingsTests.js @@ -1,19 +1,29 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/BucketController.js" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * 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.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/BucketController.js"; -describe "Settings", -> - describe "s3", -> - it "should use JSONified env var if present", (done)-> - s3_settings = - bucket1: - auth_key: 'bucket1_key' - auth_secret: 'bucket1_secret' - process.env['S3_BUCKET_CREDENTIALS'] = JSON.stringify s3_settings +describe("Settings", () => describe("s3", () => it("should use JSONified env var if present", function(done){ + const s3_settings = { + bucket1: { + auth_key: 'bucket1_key', + auth_secret: 'bucket1_secret' + } + }; + process.env['S3_BUCKET_CREDENTIALS'] = JSON.stringify(s3_settings); - settings = require("settings-sharelatex") - expect(settings.filestore.s3BucketCreds).to.deep.equal s3_settings - done() + const settings = require("settings-sharelatex"); + expect(settings.filestore.s3BucketCreds).to.deep.equal(s3_settings); + return done(); +})));