2019-05-29 05:21:06 -04:00
|
|
|
/* eslint-disable
|
|
|
|
max-len,
|
|
|
|
no-return-assign,
|
|
|
|
no-unused-vars,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
|
|
|
const sinon = require('sinon')
|
|
|
|
const chai = require('chai')
|
|
|
|
const should = chai.should()
|
|
|
|
const modulePath =
|
|
|
|
'../../../../app/src/Features/Uploads/ProjectUploadManager.js'
|
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
|
2019-06-24 09:18:14 -04:00
|
|
|
const promiseStub = val => new Promise(resolve => resolve(val))
|
2019-06-27 06:10:46 -04:00
|
|
|
const failedPromiseStub = err => new Promise((resolve, reject) => reject(err))
|
2019-06-24 09:18:14 -04:00
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
describe('ProjectUploadManager', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.project_id = 'project-id-123'
|
|
|
|
this.folder_id = 'folder-id-123'
|
2019-06-24 09:18:14 -04:00
|
|
|
this.owner_id = 'owner-id-123'
|
2019-05-29 05:21:06 -04:00
|
|
|
this.callback = sinon.stub()
|
|
|
|
this.source = '/path/to/zip/file-name.zip'
|
|
|
|
this.destination = '/path/to/zile/file-extracted'
|
|
|
|
this.root_folder_id = this.folder_id
|
|
|
|
this.owner_id = 'owner-id-123'
|
|
|
|
this.name = 'Project name'
|
|
|
|
this.othername = 'Other name'
|
|
|
|
this.project = {
|
|
|
|
_id: this.project_id,
|
|
|
|
rootFolder: [{ _id: this.root_folder_id }]
|
|
|
|
}
|
|
|
|
this.ProjectUploadManager = SandboxedModule.require(modulePath, {
|
2019-07-15 06:33:47 -04:00
|
|
|
globals: {
|
|
|
|
console: console
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
requires: {
|
|
|
|
'./FileSystemImportManager': (this.FileSystemImportManager = {}),
|
2019-06-24 09:18:14 -04:00
|
|
|
'./ArchiveManager': (this.ArchiveManager = { promises: {} }),
|
|
|
|
'../Project/ProjectCreationHandler': (this.ProjectCreationHandler = {
|
|
|
|
promises: {}
|
|
|
|
}),
|
|
|
|
'../Project/ProjectRootDocManager': (this.ProjectRootDocManager = {
|
|
|
|
promises: {}
|
|
|
|
}),
|
|
|
|
'../Project/ProjectDetailsHandler': (this.ProjectDetailsHandler = {
|
|
|
|
promises: {}
|
|
|
|
}),
|
2019-06-27 06:10:46 -04:00
|
|
|
'../Project/ProjectDeleter': (this.ProjectDeleter = {
|
|
|
|
promises: {}
|
|
|
|
}),
|
2019-05-29 05:21:06 -04:00
|
|
|
'../Documents/DocumentHelper': (this.DocumentHelper = {}),
|
|
|
|
rimraf: (this.rimraf = sinon.stub().callsArg(1))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
this.ArchiveManager.extractZipArchive = sinon.stub().callsArg(2)
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ArchiveManager.promises.extractZipArchive = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(promiseStub())
|
2019-05-29 05:21:06 -04:00
|
|
|
this.ArchiveManager.findTopLevelDirectory = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(
|
|
|
|
1,
|
|
|
|
null,
|
|
|
|
(this.topLevelDestination = '/path/to/zip/file-extracted/nested')
|
|
|
|
)
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub(this.project))
|
|
|
|
this.ProjectRootDocManager.promises.setRootDocAutomatically = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub())
|
2019-05-29 05:21:06 -04:00
|
|
|
this.FileSystemImportManager.addFolderContents = sinon.stub().callsArg(5)
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectRootDocManager.promises.findRootDocFileFromDirectory = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(promiseStub({ path: 'main.tex', content: this.othername }))
|
|
|
|
this.ProjectRootDocManager.promises.setRootDocFromName = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub())
|
2019-05-29 05:21:06 -04:00
|
|
|
this.DocumentHelper.getTitleFromTexContent = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(this.othername)
|
|
|
|
return (this.ProjectDetailsHandler.fixProjectName = sinon
|
|
|
|
.stub()
|
|
|
|
.returnsArg(0))
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('createProjectFromZipArchive', function() {
|
|
|
|
describe('when the title can be read from the root document', function() {
|
|
|
|
beforeEach(function(done) {
|
|
|
|
this.ProjectUploadManager._getDestinationDirectory = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(this.destination)
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectDetailsHandler.promises.generateUniqueName = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub(this.othername))
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ProjectUploadManager.createProjectFromZipArchive(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source,
|
|
|
|
(err, project) => {
|
|
|
|
this.callback(err, project)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should set up the directory to extract the archive to', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectUploadManager._getDestinationDirectory
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.source)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should extract the archive', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ArchiveManager.promises.extractZipArchive
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.source, this.destination)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should find the top level directory', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ArchiveManager.findTopLevelDirectory
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.destination)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should insert the extracted archive into the folder', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.FileSystemImportManager.addFolderContents
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(
|
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.folder_id,
|
|
|
|
this.topLevelDestination,
|
|
|
|
false
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project owned by the owner_id', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.owner_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project with the correct name', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(sinon.match.any, this.othername)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should read the title from the tex contents', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.DocumentHelper.getTitleFromTexContent.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should set the root document', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocFromName
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.project_id, 'main.tex')
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should call the callback', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.callback
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(sinon.match.falsy, this.project)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should ensure the name is valid', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ProjectDetailsHandler.fixProjectName.called.should.equal(
|
|
|
|
true
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when the root document can't be determined", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function(done) {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectRootDocManager.promises.findRootDocFileFromDirectory = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub())
|
2019-05-29 05:21:06 -04:00
|
|
|
this.ProjectUploadManager._getDestinationDirectory = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(this.destination)
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectDetailsHandler.promises.generateUniqueName = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub(this.name))
|
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ProjectUploadManager.createProjectFromZipArchive(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source,
|
|
|
|
(err, project) => {
|
|
|
|
this.callback(err, project)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should not try to set the root doc', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocFromName.called.should.equal(
|
2019-05-29 05:21:06 -04:00
|
|
|
false
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('createProjectFromZipArchiveWithName', function() {
|
|
|
|
beforeEach(function(done) {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectDetailsHandler.promises.generateUniqueName = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub(this.name))
|
|
|
|
this.ProjectCreationHandler.promises.createBlankProject = sinon
|
2019-06-04 07:08:04 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub(this.project))
|
|
|
|
this.ProjectUploadManager.promises.insertZipArchiveIntoFolder = sinon
|
2019-05-29 05:21:06 -04:00
|
|
|
.stub()
|
2019-06-24 09:18:14 -04:00
|
|
|
.returns(promiseStub())
|
2019-06-27 06:10:46 -04:00
|
|
|
this.ProjectUploadManager.createProjectFromZipArchiveWithName(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source,
|
|
|
|
(err, project) => {
|
|
|
|
this.callback(err, project)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project owned by the owner_id', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.owner_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project with the correct name', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(sinon.match.any, this.name)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should insert the zip file contents into the root folder', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectUploadManager.promises.insertZipArchiveIntoFolder
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(
|
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.root_folder_id,
|
|
|
|
this.source
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should automatically set the root doc', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocAutomatically
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.project_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should call the callback', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.callback
|
|
|
|
.calledWith(sinon.match.falsy, this.project)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
2019-06-27 06:10:46 -04:00
|
|
|
describe('when inserting the zip file contents into the root folder fails', function() {
|
|
|
|
beforeEach(function(done) {
|
|
|
|
this.callback = sinon.stub()
|
|
|
|
this.ProjectUploadManager.promises.insertZipArchiveIntoFolder = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(failedPromiseStub('insert-zip-error'))
|
|
|
|
this.ProjectDeleter.promises.deleteProject = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(promiseStub())
|
|
|
|
this.ProjectUploadManager.createProjectFromZipArchiveWithName(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source,
|
|
|
|
(err, project) => {
|
|
|
|
this.callback(err, project)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should pass an error to the callback', function() {
|
|
|
|
return this.callback
|
|
|
|
.calledWith('insert-zip-error', sinon.match.falsy)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should cleanup the blank project created', function() {
|
|
|
|
return this.ProjectDeleter.promises.deleteProject
|
|
|
|
.calledWith(this.project_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('when setting automatically the root doc fails', function() {
|
|
|
|
beforeEach(function(done) {
|
|
|
|
this.callback = sinon.stub()
|
|
|
|
this.ProjectRootDocManager.promises.setRootDocAutomatically = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(failedPromiseStub('set-root-auto-error'))
|
|
|
|
this.ProjectDeleter.promises.deleteProject = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(promiseStub())
|
|
|
|
this.ProjectUploadManager.createProjectFromZipArchiveWithName(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source,
|
|
|
|
(err, project) => {
|
|
|
|
this.callback(err, project)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should pass an error to the callback', function() {
|
|
|
|
return this.callback
|
|
|
|
.calledWith('set-root-auto-error', sinon.match.falsy)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should cleanup the blank project created', function() {
|
|
|
|
return this.ProjectDeleter.promises.deleteProject
|
|
|
|
.calledWith(this.project_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('insertZipArchiveIntoFolder', function() {
|
|
|
|
beforeEach(function(done) {
|
|
|
|
this.ProjectUploadManager._getDestinationDirectory = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(this.destination)
|
|
|
|
return this.ProjectUploadManager.insertZipArchiveIntoFolder(
|
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.folder_id,
|
|
|
|
this.source,
|
|
|
|
err => {
|
|
|
|
this.callback(err)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should set up the directory to extract the archive to', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ProjectUploadManager._getDestinationDirectory
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.source)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should extract the archive', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ArchiveManager.extractZipArchive
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.source, this.destination)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should find the top level directory', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.ArchiveManager.findTopLevelDirectory
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.destination)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should insert the extracted archive into the folder', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.FileSystemImportManager.addFolderContents
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(
|
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.folder_id,
|
|
|
|
this.topLevelDestination,
|
|
|
|
false
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return the callback', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.callback.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should remove the desintation directory afterwards', function() {
|
2019-06-24 09:18:14 -04:00
|
|
|
this.rimraf.calledWith(this.destination).should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-08-07 10:04:04 -04:00
|
|
|
describe('_getDestinationDirectory', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
it('should return the path with the time appended', function() {
|
|
|
|
const date = Date.now()
|
2019-11-18 09:37:05 -05:00
|
|
|
sinon.stub(Date, 'now').returns(date)
|
2019-05-29 05:21:06 -04:00
|
|
|
this.ProjectUploadManager._getDestinationDirectory(
|
|
|
|
'/path/to/zip/file.zip'
|
|
|
|
).should.equal(`/path/to/zip/file-${date}`)
|
2019-06-24 09:18:14 -04:00
|
|
|
Date.now.restore()
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|