clear rootDoc_id when deleting doc, reset on compiles if invalid

GitOrigin-RevId: 539982adbf55014400f4aff94195e7f567cda676
This commit is contained in:
Ersun Warncke 2020-01-22 12:24:57 -04:00 committed by Copybot
parent 0d67c9382c
commit 74ecb4bebe
5 changed files with 83 additions and 21 deletions

View file

@ -62,7 +62,7 @@ module.exports = CompileManager = {
return callback(null, 'autocompile-backoff', [])
}
return ProjectRootDocManager.ensureRootDocumentIsSet(
return ProjectRootDocManager.ensureRootDocumentIsValid(
project_id,
function(error) {
if (error != null) {

View file

@ -314,8 +314,9 @@ async function moveEntity(projectId, entityId, destFolderId, entityType) {
async function deleteEntity(projectId, entityId, entityType, callback) {
const project = await ProjectGetter.promises.getProjectWithoutLock(
projectId,
{ name: true, rootFolder: true, overleaf: true }
{ name: true, rootFolder: true, overleaf: true, rootDoc_id: true }
)
const deleteRootDoc = project.rootDoc_id && entityId && project.rootDoc_id.toString() === entityId.toString()
const { element: entity, path } = await ProjectLocator.promises.findElement({
project,
element_id: entityId,
@ -325,7 +326,8 @@ async function deleteEntity(projectId, entityId, entityType, callback) {
Project,
projectId,
path.mongo,
entityId
entityId,
deleteRootDoc
)
return { entity, path, projectBeforeDeletion: project, newProject }
}
@ -414,19 +416,18 @@ async function _insertDeletedFileReference(projectId, fileRef) {
).exec()
}
async function _removeElementFromMongoArray(model, modelId, path, elementId) {
async function _removeElementFromMongoArray(model, modelId, path, elementId, deleteRootDoc=false) {
const nonArrayPath = path.slice(0, path.lastIndexOf('.'))
const newDoc = model
.findOneAndUpdate(
{ _id: modelId },
{
$pull: { [nonArrayPath]: { _id: elementId } },
$inc: { version: 1 }
},
{ new: true }
)
.exec()
return newDoc
const options = { new: true }
const query = { _id: modelId }
const update = {
$pull: { [nonArrayPath]: { _id: elementId } },
$inc: { version: 1 }
}
if (deleteRootDoc) {
update.$unset = { rootDoc_id: 1 }
}
return model.findOneAndUpdate(query, update, options).exec()
}
function _countElements(project) {

View file

@ -6,6 +6,7 @@ const fs = require('fs')
const Settings = require('settings-sharelatex')
const _ = require('underscore')
const { Project } = require('../../../app/src/models/Project')
const ProjectGetter = require('../../../app/src/Features/Project/ProjectGetter.js')
const MockDocUpdaterApi = require('./helpers/MockDocUpdaterApi')
@ -1098,6 +1099,68 @@ describe('ProjectStructureChanges', function() {
})
})
describe('deleting docs', function() {
beforeEach(function(done) {
createExampleProject(this, () => {
createExampleFolder(this, () => {
createExampleDoc(this, () => {
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject(
this.exampleProjectId,
(error, project) => {
if (error) {
throw error
}
this.project0 = project
done()
})
})
})
})
})
describe('when rootDoc_id matches doc being deleted', () => {
beforeEach(function(done) {
Project.update({_id: this.exampleProjectId}, {$set: {rootDoc_id: this.exampleDocId}}, done)
})
it('should clear rootDoc_id', function(done) {
deleteItem(this, 'doc', this.exampleDocId, () => {
ProjectGetter.getProject(
this.exampleProjectId,
(error, project) => {
if (error) {
throw error
}
expect(project.rootDoc_id).to.be.undefined
done()
})
})
})
})
describe('when rootDoc_id does not match doc being deleted', () => {
beforeEach(function(done) {
this.exampleRootDocId = new ObjectId()
Project.update({_id: this.exampleProjectId}, {$set: {rootDoc_id: this.exampleRootDocId}}, done)
})
it('should not clear rootDoc_id', function(done) {
deleteItem(this, 'doc', this.exampleDocId, () => {
ProjectGetter.getProject(
this.exampleProjectId,
(error, project) => {
if (error) {
throw error
}
expect(project.rootDoc_id.toString()).to.equal(this.exampleRootDocId.toString())
done()
})
})
})
})
})
describe('tpds', function() {
let projectName, exampleProjectId, oldVersion, rootFolderId

View file

@ -120,14 +120,12 @@ describe('CompileController', function() {
})
it('should set the content-type of the response to application/json', function() {
return this.res.contentType
.calledWith('application/json')
.should.equal(true)
this.res.type.should.equal('application/json')
})
it('should send a successful response reporting the status and files', function() {
this.res.statusCode.should.equal(200)
return this.res.body.should.equal(
this.res.body.should.equal(
JSON.stringify({
status: this.status,
outputFiles: this.outputFiles

View file

@ -76,7 +76,7 @@ describe('CompileManager', function() {
this.CompileManager._checkIfRecentlyCompiled = sinon
.stub()
.callsArgWith(2, null, false)
this.ProjectRootDocManager.ensureRootDocumentIsSet = sinon
this.ProjectRootDocManager.ensureRootDocumentIsValid = sinon
.stub()
.callsArgWith(1, null)
this.CompileManager.getProjectCompileLimits = sinon
@ -115,7 +115,7 @@ describe('CompileManager', function() {
})
it('should ensure that the root document is set', function() {
return this.ProjectRootDocManager.ensureRootDocumentIsSet
return this.ProjectRootDocManager.ensureRootDocumentIsValid
.calledWith(this.project_id)
.should.equal(true)
})