| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- const sinon = require('sinon')
- const { expect } = require('chai')
- const SandboxedModule = require('sandboxed-module')
- const { ObjectId } = require('mongodb')
- const MODULE_PATH =
- '../../../../app/src/Features/Uploads/FileSystemImportManager.js'
- describe('FileSystemImportManager', function() {
- beforeEach(function() {
- this.projectId = new ObjectId()
- this.folderId = new ObjectId()
- this.newFolderId = new ObjectId()
- this.userId = new ObjectId()
- this.folderPath = '/path/to/folder'
- this.docName = 'test-doc.tex'
- this.docPath = `/path/to/folder/${this.docName}`
- this.docContent = 'one\ntwo\nthree'
- this.docLines = this.docContent.split('\n')
- this.fileName = 'test-file.jpg'
- this.filePath = `/path/to/folder/${this.fileName}`
- this.symlinkName = 'symlink'
- this.symlinkPath = `/path/to/${this.symlinkName}`
- this.ignoredName = '.DS_Store'
- this.ignoredPath = `/path/to/folder/${this.ignoredName}`
- this.folderEntries = [this.ignoredName, this.docName, this.fileName]
- this.encoding = 'latin1'
- this.fileStat = {
- isFile: sinon.stub().returns(true),
- isDirectory: sinon.stub().returns(false)
- }
- this.dirStat = {
- isFile: sinon.stub().returns(false),
- isDirectory: sinon.stub().returns(true)
- }
- this.symlinkStat = {
- isFile: sinon.stub().returns(false),
- isDirectory: sinon.stub().returns(false)
- }
- this.fs = {
- promises: {
- lstat: sinon.stub(),
- readFile: sinon.stub(),
- readdir: sinon.stub()
- }
- }
- this.fs.promises.lstat.withArgs(this.filePath).resolves(this.fileStat)
- this.fs.promises.lstat.withArgs(this.docPath).resolves(this.fileStat)
- this.fs.promises.lstat.withArgs(this.symlinkPath).resolves(this.symlinkStat)
- this.fs.promises.lstat.withArgs(this.folderPath).resolves(this.dirStat)
- this.fs.promises.readFile
- .withArgs(this.docPath, this.encoding)
- .resolves(this.docContent)
- this.fs.promises.readdir
- .withArgs(this.folderPath)
- .resolves(this.folderEntries)
- this.EditorController = {
- promises: {
- addDoc: sinon.stub().resolves(),
- addFile: sinon.stub().resolves(),
- upsertDoc: sinon.stub().resolves(),
- upsertFile: sinon.stub().resolves(),
- addFolder: sinon.stub().resolves({ _id: this.newFolderId })
- }
- }
- this.FileTypeManager = {
- promises: {
- isDirectory: sinon.stub().resolves(false),
- getType: sinon.stub(),
- shouldIgnore: sinon.stub().resolves(false)
- }
- }
- this.FileTypeManager.promises.getType
- .withArgs(this.fileName, this.filePath)
- .resolves({ binary: true })
- this.FileTypeManager.promises.getType
- .withArgs(this.docName, this.docPath)
- .resolves({ binary: false, encoding: this.encoding })
- this.FileTypeManager.promises.isDirectory
- .withArgs(this.folderPath)
- .resolves(true)
- this.FileTypeManager.promises.shouldIgnore
- .withArgs(this.ignoredName)
- .resolves(true)
- this.logger = {
- log() {},
- err() {}
- }
- this.FileSystemImportManager = SandboxedModule.require(MODULE_PATH, {
- globals: {
- console: console
- },
- requires: {
- fs: this.fs,
- '../Editor/EditorController': this.EditorController,
- './FileTypeManager': this.FileTypeManager,
- 'logger-sharelatex': this.logger
- }
- })
- })
- describe('addFolderContents', function() {
- describe('successfully', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addFolderContents(
- this.userId,
- this.projectId,
- this.folderId,
- this.folderPath,
- false
- )
- })
- it('should add each file in the folder which is not ignored', function() {
- this.EditorController.promises.addDoc.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- this.EditorController.promises.addFile.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.fileName,
- this.filePath,
- null,
- 'upload',
- this.userId
- )
- })
- })
- describe('with symlink', function() {
- it('should stop with an error', async function() {
- await expect(
- this.FileSystemImportManager.promises.addFolderContents(
- this.userId,
- this.projectId,
- this.folderId,
- this.symlinkPath,
- false
- )
- ).to.be.rejectedWith('path is symlink')
- this.EditorController.promises.addFolder.should.not.have.been.called
- this.EditorController.promises.addDoc.should.not.have.been.called
- this.EditorController.promises.addFile.should.not.have.been.called
- })
- })
- })
- describe('addEntity', function() {
- describe('with directory', function() {
- describe('successfully', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.folderName,
- this.folderPath,
- false
- )
- })
- it('should add a folder to the project', function() {
- this.EditorController.promises.addFolder.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.folderName,
- 'upload'
- )
- })
- it("should add the folder's contents", function() {
- this.EditorController.promises.addDoc.should.have.been.calledWith(
- this.projectId,
- this.newFolderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- this.EditorController.promises.addFile.should.have.been.calledWith(
- this.projectId,
- this.newFolderId,
- this.fileName,
- this.filePath,
- null,
- 'upload',
- this.userId
- )
- })
- })
- })
- describe('with binary file', function() {
- describe('with replace set to false', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.fileName,
- this.filePath,
- false
- )
- })
- it('should add the file', function() {
- this.EditorController.promises.addFile.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.fileName,
- this.filePath,
- null,
- 'upload',
- this.userId
- )
- })
- })
- describe('with replace set to true', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.fileName,
- this.filePath,
- true
- )
- })
- it('should add the file', function() {
- this.EditorController.promises.upsertFile.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.fileName,
- this.filePath,
- null,
- 'upload',
- this.userId
- )
- })
- })
- describe('with text file', function() {
- describe('with replace set to false', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.docName,
- this.docPath,
- false
- )
- })
- it('should insert the doc', function() {
- this.EditorController.promises.addDoc.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- })
- })
- describe('with windows line ending', function() {
- beforeEach(async function() {
- this.docContent = 'one\r\ntwo\r\nthree'
- this.docLines = ['one', 'two', 'three']
- this.fs.promises.readFile
- .withArgs(this.docPath, this.encoding)
- .resolves(this.docContent)
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.docName,
- this.docPath,
- false
- )
- })
- it('should strip the \\r characters before adding', function() {
- this.EditorController.promises.addDoc.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- })
- })
- describe('with \r line endings', function() {
- beforeEach(async function() {
- this.docContent = 'one\rtwo\rthree'
- this.docLines = ['one', 'two', 'three']
- this.fs.promises.readFile
- .withArgs(this.docPath, this.encoding)
- .resolves(this.docContent)
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.docName,
- this.docPath,
- false
- )
- })
- it('should treat the \\r characters as newlines', function() {
- this.EditorController.promises.addDoc.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- })
- })
- describe('with replace set to true', function() {
- beforeEach(async function() {
- await this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.docName,
- this.docPath,
- true
- )
- })
- it('should upsert the doc', function() {
- this.EditorController.promises.upsertDoc.should.have.been.calledWith(
- this.projectId,
- this.folderId,
- this.docName,
- this.docLines,
- 'upload',
- this.userId
- )
- })
- })
- })
- })
- describe('with symlink', function() {
- it('should stop with an error', async function() {
- await expect(
- this.FileSystemImportManager.promises.addEntity(
- this.userId,
- this.projectId,
- this.folderId,
- this.symlinkName,
- this.symlinkPath,
- false
- )
- ).to.be.rejectedWith('path is symlink')
- this.EditorController.promises.addFolder.should.not.have.been.called
- this.EditorController.promises.addDoc.should.not.have.been.called
- this.EditorController.promises.addFile.should.not.have.been.called
- })
- })
- })
- })
|