overleaf/services/web/test/unit/src/ThirdPartyDataStore/UpdateMergerTests.js

368 lines
11 KiB
JavaScript
Raw Normal View History

const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
const modulePath = require('path').join(
__dirname,
'../../../../app/src/Features/ThirdPartyDataStore/UpdateMerger.js'
)
const BufferedStream = require('bufferedstream')
describe('UpdateMerger :', function () {
beforeEach(function () {
this.updateMerger = SandboxedModule.require(modulePath, {
requires: {
fs: (this.fs = { unlink: sinon.stub().callsArgWith(1) }),
'../Editor/EditorController': (this.EditorController = {}),
'../Uploads/FileTypeManager': (this.FileTypeManager = {}),
'../../infrastructure/FileWriter': (this.FileWriter = {}),
'../Project/ProjectEntityHandler': (this.ProjectEntityHandler = {}),
'settings-sharelatex': { path: { dumpPath: 'dump_here' } },
},
})
this.project_id = 'project_id_here'
this.user_id = 'mock-user-id'
this.docPath = this.newDocPath = '/folder/doc.tex'
this.filePath = this.newFilePath = '/folder/file.png'
this.existingDocPath = '/folder/other.tex'
this.existingFilePath = '/folder/fig1.pdf'
this.linkedFileData = { provider: 'url' }
this.existingDocs = [{ path: '/main.tex' }, { path: '/folder/other.tex' }]
this.existingFiles = [{ path: '/figure.pdf' }, { path: '/folder/fig1.pdf' }]
this.ProjectEntityHandler.getAllEntities = sinon
.stub()
.callsArgWith(1, null, this.existingDocs, this.existingFiles)
this.fsPath = '/tmp/file/path'
this.source = 'dropbox'
this.updateRequest = new BufferedStream()
this.FileWriter.writeStreamToDisk = sinon.stub().yields(null, this.fsPath)
this.callback = sinon.stub()
})
describe('mergeUpdate', function () {
describe('doc updates for a new doc', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon
.stub()
.yields(null, { binary: false, encoding: 'utf-8' })
this.updateMerger.p.processDoc = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.docPath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should process update as doc', function () {
this.updateMerger.p.processDoc
.calledWith(
this.project_id,
this.user_id,
this.fsPath,
this.docPath,
this.source
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
describe('file updates for a new file ', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon
.stub()
.yields(null, { binary: true })
this.updateMerger.p.processFile = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.filePath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should process update as file', function () {
this.updateMerger.p.processFile
.calledWith(
this.project_id,
this.fsPath,
this.filePath,
this.source,
this.user_id
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
describe('doc updates for an existing doc', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon
.stub()
.yields(null, { binary: false, encoding: 'utf-8' })
this.updateMerger.p.processDoc = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.existingDocPath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should process update as doc', function () {
this.updateMerger.p.processDoc
.calledWith(
this.project_id,
this.user_id,
this.fsPath,
this.existingDocPath,
this.source
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
describe('file updates for an existing file', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon
.stub()
.yields(null, { binary: true })
this.updateMerger.p.processFile = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.existingFilePath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should process update as file', function () {
this.updateMerger.p.processFile
.calledWith(
this.project_id,
this.fsPath,
this.existingFilePath,
this.source,
this.user_id
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
})
describe('file updates for an existing doc', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon.stub().yields(null, { binary: true })
this.updateMerger.deleteUpdate = sinon.stub().yields()
this.updateMerger.p.processFile = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.existingDocPath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should delete the existing doc', function () {
this.updateMerger.deleteUpdate
.calledWith(
this.user_id,
this.project_id,
this.existingDocPath,
this.source
)
.should.equal(true)
})
it('should process update as file', function () {
this.updateMerger.p.processFile
.calledWith(
this.project_id,
this.fsPath,
this.existingDocPath,
this.source,
this.user_id
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
describe('doc updates for an existing file', function () {
beforeEach(function () {
this.FileTypeManager.getType = sinon.stub().yields(null, { binary: true })
this.updateMerger.deleteUpdate = sinon.stub().yields()
this.updateMerger.p.processFile = sinon.stub().yields()
this.updateMerger.mergeUpdate(
this.user_id,
this.project_id,
this.existingFilePath,
this.updateRequest,
this.source,
this.callback
)
})
it('should look at the file contents', function () {
this.FileTypeManager.getType.called.should.equal(true)
})
it('should not delete the existing file', function () {
this.updateMerger.deleteUpdate.called.should.equal(false)
})
it('should process update as file', function () {
this.updateMerger.p.processFile
.calledWith(
this.project_id,
this.fsPath,
this.existingFilePath,
this.source,
this.user_id
)
.should.equal(true)
})
it('removes the temp file from disk', function () {
this.fs.unlink.calledWith(this.fsPath).should.equal(true)
})
})
describe('deleteUpdate', function () {
beforeEach(function () {
this.EditorController.deleteEntityWithPath = sinon.stub().yields()
this.updateMerger.deleteUpdate(
this.user_id,
this.project_id,
this.docPath,
this.source,
this.callback
)
})
it('should delete the entity in the editor controller', function () {
this.EditorController.deleteEntityWithPath
.calledWith(this.project_id, this.docPath, this.source, this.user_id)
.should.equal(true)
})
})
describe('private methods', function () {
describe('processDoc', function () {
beforeEach(function () {
this.docLines =
'\\documentclass{article}\n\\usepackage[utf8]{inputenc}\n\n\\title{42}\n\\author{Jane Doe}\n\\date{June 2011}'
this.updateMerger.p.readFileIntoTextArray = sinon
.stub()
.yields(null, this.docLines)
this.EditorController.upsertDocWithPath = sinon.stub().yields()
this.updateMerger.p.processDoc(
this.project_id,
this.user_id,
this.fsPath,
this.docPath,
this.source,
this.callback
)
})
it('reads the temp file from disk', function () {
this.updateMerger.p.readFileIntoTextArray
.calledWith(this.fsPath)
.should.equal(true)
})
it('should upsert the doc in the editor controller', function () {
this.EditorController.upsertDocWithPath
.calledWith(
this.project_id,
this.docPath,
this.docLines,
this.source,
this.user_id
)
.should.equal(true)
})
})
describe('processFile', function () {
beforeEach(function () {
this.EditorController.upsertFileWithPath = sinon.stub().yields()
this.updateMerger.p.processFile(
this.project_id,
this.fsPath,
this.filePath,
this.source,
this.user_id,
this.callback
)
})
it('should upsert the file in the editor controller', function () {
this.EditorController.upsertFileWithPath
.calledWith(
this.project_id,
this.filePath,
this.fsPath,
null,
this.source,
this.user_id
)
.should.equal(true)
})
})
})
})