2019-05-29 05:21:06 -04:00
|
|
|
const sinon = require('sinon')
|
2020-04-16 08:01:40 -04:00
|
|
|
const { expect } = require('chai')
|
|
|
|
const timekeeper = require('timekeeper')
|
2019-05-29 05:21:06 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
const MODULE_PATH =
|
|
|
|
'../../../../app/src/Features/Uploads/ProjectUploadManager.js'
|
2019-06-24 09:18:14 -04:00
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
describe('ProjectUploadManager', function() {
|
|
|
|
beforeEach(function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.now = Date.now()
|
|
|
|
timekeeper.freeze(this.now)
|
2019-05-29 05:21:06 -04:00
|
|
|
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.source = '/path/to/zip/file-name.zip'
|
2020-04-16 08:01:40 -04:00
|
|
|
this.destination = `/path/to/zip/file-name-${this.now}`
|
2019-05-29 05:21:06 -04:00
|
|
|
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 }]
|
|
|
|
}
|
2020-04-16 08:01:40 -04:00
|
|
|
this.topLevelDestination = '/path/to/zip/file-extracted/nested'
|
|
|
|
|
|
|
|
this.fs = {
|
|
|
|
remove: sinon.stub().resolves()
|
|
|
|
}
|
|
|
|
this.ArchiveManager = {
|
|
|
|
promises: {
|
|
|
|
extractZipArchive: sinon.stub().resolves(),
|
|
|
|
findTopLevelDirectory: sinon.stub().resolves(this.topLevelDestination)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.FileSystemImportManager = {
|
|
|
|
promises: {
|
|
|
|
addFolderContents: sinon.stub().resolves()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.ProjectCreationHandler = {
|
|
|
|
promises: {
|
|
|
|
createBlankProject: sinon.stub().resolves(this.project)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.ProjectRootDocManager = {
|
|
|
|
promises: {
|
|
|
|
setRootDocAutomatically: sinon.stub().resolves(),
|
|
|
|
findRootDocFileFromDirectory: sinon
|
|
|
|
.stub()
|
|
|
|
.resolves({ path: 'main.tex', content: this.othername }),
|
|
|
|
setRootDocFromName: sinon.stub().resolves()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.ProjectDetailsHandler = {
|
|
|
|
fixProjectName: sinon.stub().returnsArg(0),
|
|
|
|
promises: {
|
|
|
|
generateUniqueName: sinon.stub().resolves(this.othername)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.ProjectDeleter = {
|
|
|
|
promises: {
|
|
|
|
deleteProject: sinon.stub().resolves()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.DocumentHelper = {
|
|
|
|
getTitleFromTexContent: sinon.stub().returns(this.othername)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.ProjectUploadManager = SandboxedModule.require(MODULE_PATH, {
|
2019-07-15 06:33:47 -04:00
|
|
|
globals: {
|
|
|
|
console: console
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
requires: {
|
2020-04-16 08:01:40 -04:00
|
|
|
'fs-extra': this.fs,
|
|
|
|
'./FileSystemImportManager': this.FileSystemImportManager,
|
|
|
|
'./ArchiveManager': this.ArchiveManager,
|
|
|
|
'../Project/ProjectCreationHandler': this.ProjectCreationHandler,
|
|
|
|
'../Project/ProjectRootDocManager': this.ProjectRootDocManager,
|
|
|
|
'../Project/ProjectDetailsHandler': this.ProjectDetailsHandler,
|
|
|
|
'../Project/ProjectDeleter': this.ProjectDeleter,
|
|
|
|
'../Documents/DocumentHelper': this.DocumentHelper
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
})
|
2020-04-16 08:01:40 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
afterEach(function() {
|
|
|
|
timekeeper.reset()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('createProjectFromZipArchive', function() {
|
|
|
|
describe('when the title can be read from the root document', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
beforeEach(async function() {
|
|
|
|
await this.ProjectUploadManager.promises.createProjectFromZipArchive(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
2020-04-16 08:01:40 -04:00
|
|
|
this.source
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should extract the archive', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ArchiveManager.promises.extractZipArchive.should.have.been.calledWith(
|
|
|
|
this.source,
|
|
|
|
this.destination
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should find the top level directory', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ArchiveManager.promises.findTopLevelDirectory.should.have.been.calledWith(
|
|
|
|
this.destination
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should insert the extracted archive into the folder', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.FileSystemImportManager.promises.addFolderContents.should.have.been.calledWith(
|
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.folder_id,
|
|
|
|
this.topLevelDestination,
|
|
|
|
false
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project owned by the owner_id', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject.should.have.been.calledWith(
|
|
|
|
this.owner_id
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project with the correct name', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject.should.have.been.calledWith(
|
|
|
|
sinon.match.any,
|
|
|
|
this.othername
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should read the title from the tex contents', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.DocumentHelper.getTitleFromTexContent.should.have.been.called
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should set the root document', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocFromName.should.have.been.calledWith(
|
|
|
|
this.project_id,
|
|
|
|
'main.tex'
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should ensure the name is valid', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectDetailsHandler.fixProjectName.should.have.been.called
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when the root document can't be determined", function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
beforeEach(async function() {
|
|
|
|
this.ProjectRootDocManager.promises.findRootDocFileFromDirectory.resolves(
|
|
|
|
{}
|
|
|
|
)
|
|
|
|
await this.ProjectUploadManager.promises.createProjectFromZipArchive(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
2020-04-16 08:01:40 -04:00
|
|
|
this.source
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should not try to set the root doc', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocFromName.should.not.have
|
|
|
|
.been.called
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('createProjectFromZipArchiveWithName', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
beforeEach(async function() {
|
|
|
|
await this.ProjectUploadManager.promises.createProjectFromZipArchiveWithName(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
2020-04-16 08:01:40 -04:00
|
|
|
this.source
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project owned by the owner_id', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject.should.have.been.calledWith(
|
|
|
|
this.owner_id
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should create a project with the correct name', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectCreationHandler.promises.createBlankProject.should.have.been.calledWith(
|
|
|
|
sinon.match.any,
|
|
|
|
this.othername
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should automatically set the root doc', function() {
|
2020-04-16 08:01:40 -04:00
|
|
|
this.ProjectRootDocManager.promises.setRootDocAutomatically.should.have.been.calledWith(
|
|
|
|
this.project_id
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
2019-06-27 06:10:46 -04:00
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should extract the archive', function() {
|
|
|
|
this.ArchiveManager.promises.extractZipArchive.should.have.been.calledWith(
|
|
|
|
this.source,
|
|
|
|
this.destination
|
|
|
|
)
|
2019-06-27 06:10:46 -04:00
|
|
|
})
|
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should find the top level directory', function() {
|
|
|
|
this.ArchiveManager.promises.findTopLevelDirectory.should.have.been.calledWith(
|
|
|
|
this.destination
|
|
|
|
)
|
2019-06-27 06:10:46 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should insert the extracted archive into the folder', function() {
|
|
|
|
this.FileSystemImportManager.promises.addFolderContents.should.have.been.calledWith(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner_id,
|
|
|
|
this.project_id,
|
|
|
|
this.folder_id,
|
2020-04-16 08:01:40 -04:00
|
|
|
this.topLevelDestination,
|
|
|
|
false
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should remove the destination directory afterwards', function() {
|
|
|
|
this.fs.remove.should.have.been.calledWith(this.destination)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
describe('when inserting the zip file contents into the root folder fails', function() {
|
|
|
|
beforeEach(async function() {
|
|
|
|
this.FileSystemImportManager.promises.addFolderContents.rejects()
|
|
|
|
await expect(
|
|
|
|
this.ProjectUploadManager.promises.createProjectFromZipArchiveWithName(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source
|
|
|
|
)
|
|
|
|
).to.be.rejected
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should cleanup the blank project created', async function() {
|
|
|
|
this.ProjectDeleter.promises.deleteProject.should.have.been.calledWith(
|
|
|
|
this.project_id
|
2019-05-29 05:21:06 -04:00
|
|
|
)
|
2020-04-16 08:01:40 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
describe('when setting automatically the root doc fails', function() {
|
|
|
|
beforeEach(async function() {
|
|
|
|
this.ProjectRootDocManager.promises.setRootDocAutomatically.rejects()
|
|
|
|
await expect(
|
|
|
|
this.ProjectUploadManager.promises.createProjectFromZipArchiveWithName(
|
|
|
|
this.owner_id,
|
|
|
|
this.name,
|
|
|
|
this.source
|
|
|
|
)
|
|
|
|
).to.be.rejected
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-04-16 08:01:40 -04:00
|
|
|
it('should cleanup the blank project created', function() {
|
|
|
|
this.ProjectDeleter.promises.deleteProject.should.have.been.calledWith(
|
|
|
|
this.project_id
|
|
|
|
)
|
|
|
|
})
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|