Merge pull request #377 from sharelatex/bg-add-project-structure-version-number

add project structure version number
This commit is contained in:
Brian Gough 2018-03-05 08:41:14 +00:00 committed by GitHub
commit 3bbd49c7eb
7 changed files with 215 additions and 81 deletions

View file

@ -205,29 +205,32 @@ module.exports = DocumentUpdaterHandler =
updateProjectStructure : (project_id, userId, changes, callback = (error) ->)->
return callback() if !settings.apis.project_history?.sendProjectStructureOps
Project.findOne {_id: project_id}, {version:true}, (err, currentProject) ->
return callback(err) if err?
return callback new Error("project not found") if !currentProject?
docUpdates = DocumentUpdaterHandler._getUpdates('doc', changes.oldDocs, changes.newDocs)
fileUpdates = DocumentUpdaterHandler._getUpdates('file', changes.oldFiles, changes.newFiles)
docUpdates = DocumentUpdaterHandler._getUpdates('doc', changes.oldDocs, changes.newDocs)
fileUpdates = DocumentUpdaterHandler._getUpdates('file', changes.oldFiles, changes.newFiles)
timer = new metrics.Timer("set-document")
url = "#{settings.apis.documentupdater.url}/project/#{project_id}"
body =
url: url
json: { docUpdates, fileUpdates, userId }
timer = new metrics.Timer("set-document")
url = "#{settings.apis.documentupdater.url}/project/#{project_id}"
body =
url: url
json: { docUpdates, fileUpdates, userId, version: currentProject.version }
return callback() if (docUpdates.length + fileUpdates.length) < 1
return callback() if (docUpdates.length + fileUpdates.length) < 1
request.post body, (error, res, body)->
timer.done()
if error?
logger.error {error, url, project_id}, "error update project structure in doc updater"
callback(error)
else if res.statusCode >= 200 and res.statusCode < 300
logger.log {project_id}, "updated project structure in doc updater"
callback(null)
else
logger.error {project_id, url}, "doc updater returned a non-success status code: #{res.statusCode}"
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
request.post body, (error, res, body)->
timer.done()
if error?
logger.error {error, url, project_id}, "error update project structure in doc updater"
callback(error)
else if res.statusCode >= 200 and res.statusCode < 300
logger.log {project_id}, "updated project structure in doc updater"
callback(null)
else
logger.error {project_id, url}, "doc updater returned a non-success status code: #{res.statusCode}"
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
_getUpdates: (entityType, oldEntities, newEntities) ->
oldEntities ||= []

View file

@ -56,6 +56,11 @@ module.exports = ProjectEntityMongoUpdateHandler = self =
conditions = _id:project._id
inc = {}
inc["#{path.mongo}.rev"] = 1
# currently we do not need to increment the project version number for changes that are replacements
# but when we make switch to having immutable files the replace operation will add a new file, and
# this will require a version increase. We will start incrementing the project version now as it does
# no harm and will help to test it.
inc['version'] = 1
set = {}
set["#{path.mongo}.created"] = new Date()
update =
@ -144,9 +149,11 @@ module.exports = ProjectEntityMongoUpdateHandler = self =
return callback(error) if error?
endPath = path.join(path.dirname(entPath.fileSystem), newName)
conditions = {_id:project_id}
update = "$set":{}
update = "$set":{}, "$inc":{}
namePath = entPath.mongo+".name"
update["$set"][namePath] = newName
# we need to increment the project version number for any structure change
update["$inc"]["version"] = 1
Project.findOneAndUpdate conditions, update, { "new": true}, (error, newProject) ->
return callback(error) if error?
ProjectEntityHandler.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
@ -174,9 +181,11 @@ module.exports = ProjectEntityMongoUpdateHandler = self =
update = {"$unset":{}}
update["$unset"][path] = 1
model.update conditions, update, {}, (err)->
pullUpdate = {"$pull":{}}
pullUpdate = {"$pull":{}, "$inc":{}}
nonArrayPath = path.slice(0, path.lastIndexOf("."))
pullUpdate["$pull"][nonArrayPath] = null
# we need to increment the project version number for any structure change
pullUpdate["$inc"]["version"] = 1
model.findOneAndUpdate conditions, pullUpdate, {"new": true}, callback
_countElements: (project)->
@ -245,14 +254,16 @@ module.exports = ProjectEntityMongoUpdateHandler = self =
element._id = require('mongoose').Types.ObjectId(id)
conditions = _id:project._id
mongopath = "#{path.mongo}.#{type}"
update = "$push":{}
update = "$push":{}, "$inc":{}
update["$push"][mongopath] = element
# we need to increment the project version number for any structure change
update["$inc"]["version"] = 1 # increment project version number
logger.log project_id: project._id, element_id: element._id, fileType: type, folder_id: folder_id, mongopath:mongopath, "adding element to project"
Project.findOneAndUpdate conditions, update, {"new": true}, (err, project)->
Project.findOneAndUpdate conditions, update, {"new": true}, (err, newProject)->
if err?
logger.err err: err, project_id: project._id, 'error saving in putElement project'
return callback(err)
callback(err, {path:newPath}, project)
callback(err, {path:newPath}, newProject)
_checkValidElementName: (folder, name, callback = (err) ->) ->
# check if the name is already taken by a doc, file or

View file

@ -22,6 +22,7 @@ ProjectSchema = new Schema
readOnly_refs : [ type:ObjectId, ref:'User' ]
rootDoc_id : {type: ObjectId}
rootFolder : [FolderSchema]
version : {type: Number} # incremented for every change in the project structure (folders and filenames)
publicAccesLevel : {type: String, default: 'private'}
compiler : {type:String, default:'pdflatex'}
spellCheckLanguage : {type:String, default:'en'}

View file

@ -35,21 +35,23 @@ describe "ProjectStructureChanges", ->
done()
it "should version creating a doc", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(2)
_.each updates, (update) =>
expect(update.userId).to.equal(@owner._id)
expect(update.docLines).to.be.a('string')
expect(_.where(updates, pathname: "/main.tex").length).to.equal 1
expect(_.where(updates, pathname: "/references.bib").length).to.equal 1
expect(version).to.equal(3)
it "should version creating a file", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/universe.jpg")
expect(update.url).to.be.a('string');
expect(version).to.equal(3)
describe "duplicating a project", ->
before (done) ->
@ -67,21 +69,23 @@ describe "ProjectStructureChanges", ->
done()
it "should version the docs created", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id).docUpdates
{docUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id)
expect(updates.length).to.equal(2)
_.each updates, (update) =>
expect(update.userId).to.equal(@owner._id)
expect(update.docLines).to.be.a('string')
expect(_.where(updates, pathname: "/main.tex").length).to.equal(1)
expect(_.where(updates, pathname: "/references.bib").length).to.equal(1)
expect(version).to.equal(3)
it "should version the files created", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id).fileUpdates
{fileUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/universe.jpg")
expect(update.url).to.be.a('string');
expect(version).to.equal(3)
describe "adding a doc", ->
before (done) ->
@ -89,6 +93,7 @@ describe "ProjectStructureChanges", ->
ProjectGetter.getProject example_project_id, (error, project) =>
throw error if error?
@project_0 = project
@owner.request.post {
uri: "project/#{example_project_id}/doc",
json:
@ -99,15 +104,22 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to add doc #{res.statusCode}")
example_doc_id = body._id
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
done()
it "should version the doc added", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/new.tex")
expect(update.docLines).to.be.a('string');
expect(version).to.equal(@project_0.version + 1)
it "should increment the project structure version number", ->
expect(@project_1.version).to.equal(@project_0.version + 1)
describe "uploading a project", ->
before (done) ->
@ -127,31 +139,32 @@ describe "ProjectStructureChanges", ->
done()
it "should version the dosc created", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id).docUpdates
{docUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/main.tex")
expect(update.docLines).to.equal("Test")
expect(version).to.equal(2)
it "should version the files created", ->
updates = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id).fileUpdates
{fileUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.url).to.be.a('string');
expect(version).to.equal(2)
describe "uploading a file", ->
before (done) ->
beforeEach (done) ->
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject example_project_id, (error, project) =>
throw error if error?
@root_folder_id = project.rootFolder[0]._id.toString()
@project_0 = project
done()
beforeEach () ->
MockDocUpdaterApi.clearProjectStructureUpdates()
it "should version a newly uploaded file", (done) ->
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/1pixel.png'))
@ -172,15 +185,21 @@ describe "ProjectStructureChanges", ->
example_file_id = JSON.parse(body).entity_id
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates: updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.url).to.be.a('string');
@original_file_url = update.url
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# uploading a new file does change the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
it "should version a replacement file", (done) ->
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/2pixel.png'))
@ -200,14 +219,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to upload file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.url).to.be.a('string');
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
describe "moving entities", ->
before (done) ->
@ -220,8 +245,13 @@ describe "ProjectStructureChanges", ->
example_folder_id_1 = JSON.parse(body)._id
done()
beforeEach () ->
beforeEach (done) ->
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject example_project_id, (error, project) =>
throw error if error?
@root_folder_id = project.rootFolder[0]._id.toString()
@project_0 = project
done()
it "should version moving a doc", (done) ->
@owner.request.post {
@ -233,14 +263,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move doc #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/new.tex")
expect(update.newPathname).to.equal("/foo/new.tex")
expect(version).to.equal(@project_0.version + 2)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 2) # 2 because it's a delete and then add
done()
it "should version moving a file", (done) ->
@owner.request.post {
@ -252,14 +288,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.newPathname).to.equal("/foo/1pixel.png")
expect(version).to.equal(@project_0.version + 2)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 2) # 2 because it's a delete and then add
done()
it "should version moving a folder", (done) ->
@owner.request.post {
@ -279,25 +321,37 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move folder #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/foo/new.tex")
expect(update.newPathname).to.equal("/bar/foo/new.tex")
expect(version).to.equal(@project_0.version + 3)
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/foo/1pixel.png")
expect(update.newPathname).to.equal("/bar/foo/1pixel.png")
expect(version).to.equal(@project_0.version + 3)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 3) # because folder and 2 files move
done()
describe "renaming entities", ->
beforeEach () ->
beforeEach (done) ->
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject example_project_id, (error, project) =>
throw error if error?
@root_folder_id = project.rootFolder[0]._id.toString()
@project_0 = project
done()
it "should version renaming a doc", (done) ->
@owner.request.post {
@ -309,14 +363,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move doc #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo/new.tex")
expect(update.newPathname).to.equal("/bar/foo/new_renamed.tex")
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
it "should version renaming a file", (done) ->
@owner.request.post {
@ -328,14 +388,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo/1pixel.png")
expect(update.newPathname).to.equal("/bar/foo/1pixel_renamed.png")
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
it "should version renaming a folder", (done) ->
@owner.request.post {
@ -347,25 +413,38 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to move folder #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo/new_renamed.tex")
expect(update.newPathname).to.equal("/bar/foo_renamed/new_renamed.tex")
expect(version).to.equal(@project_0.version + 1)
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo/1pixel_renamed.png")
expect(update.newPathname).to.equal("/bar/foo_renamed/1pixel_renamed.png")
expect(version).to.equal(@project_0.version + 1)
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
done()
describe "deleting entities", ->
beforeEach () ->
beforeEach (done) ->
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject example_project_id, (error, project) =>
throw error if error?
@root_folder_id = project.rootFolder[0]._id.toString()
@project_0 = project
done()
it "should version deleting a folder", (done) ->
@owner.request.delete {
@ -375,21 +454,28 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to delete folder #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo_renamed/new_renamed.tex")
expect(update.newPathname).to.equal("")
expect(version).to.equal(@project_0.version + 1)
updates = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(example_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/bar/foo_renamed/1pixel_renamed.png")
expect(update.newPathname).to.equal("")
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject example_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
describe "tpds", ->
before (done) ->
@ -399,8 +485,13 @@ describe "ProjectStructureChanges", ->
@tpds_project_id = project_id
mkdirp Settings.path.dumpFolder, done
beforeEach () ->
beforeEach (done) ->
MockDocUpdaterApi.clearProjectStructureUpdates()
ProjectGetter.getProject @tpds_project_id, (error, project) =>
throw error if error?
@root_folder_id = project.rootFolder[0]._id.toString()
@project_0 = project
done()
it "should version adding a doc", (done) ->
tex_file = fs.createReadStream(Path.resolve(__dirname + '/../files/test.tex'))
@ -423,14 +514,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to upload file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/test.tex")
expect(update.docLines).to.equal("Test")
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject @tpds_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
tex_file.pipe(req)
@ -455,14 +552,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to upload file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.url).to.be.a('string');
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject @tpds_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
image_file.pipe(req)
@ -487,14 +590,20 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to upload file #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).fileUpdates
{fileUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/1pixel.png")
expect(update.url).to.be.a('string');
expect(version).to.equal(@project_0.version + 1)
done()
ProjectGetter.getProject @tpds_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()
image_file.pipe(req)
@ -510,12 +619,18 @@ describe "ProjectStructureChanges", ->
if res.statusCode < 200 || res.statusCode >= 300
throw new Error("failed to delete doc #{res.statusCode}")
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).docUpdates
{docUpdates:updates, version} = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id)
expect(updates.length).to.equal(1)
update = updates[0]
expect(update.userId).to.equal(@owner._id)
expect(update.pathname).to.equal("/test.tex")
expect(update.newPathname).to.equal("")
done()
expect(version).to.equal(@project_0.version + 1)
ProjectGetter.getProject @tpds_project_id, (error, newProject) =>
throw error if error?
@project_1 = newProject
# replacing a file should update the project structure
expect(@project_1.version).to.equal(@project_0.version + 1)
done()

View file

@ -12,7 +12,7 @@ module.exports = MockDocUpdaterApi =
getProjectStructureUpdates: (project_id) ->
@updates[project_id] || { docUpdates: [], fileUpdates: [] }
addProjectStructureUpdates: (project_id, userId, docUpdates, fileUpdates) ->
addProjectStructureUpdates: (project_id, userId, docUpdates, fileUpdates, version) ->
@updates[project_id] ||= { docUpdates: [], fileUpdates: [] }
for update in docUpdates
@ -22,6 +22,8 @@ module.exports = MockDocUpdaterApi =
for update in fileUpdates
update.userId = userId
@updates[project_id].fileUpdates.push(update)
@updates[project_id].version = version
run: () ->
app.post "/project/:project_id/flush", (req, res, next) =>
@ -29,8 +31,8 @@ module.exports = MockDocUpdaterApi =
app.post "/project/:project_id", jsonParser, (req, res, next) =>
project_id = req.params.project_id
{userId, docUpdates, fileUpdates} = req.body
@addProjectStructureUpdates(project_id, userId, docUpdates, fileUpdates)
{userId, docUpdates, fileUpdates, version} = req.body
@addProjectStructureUpdates(project_id, userId, docUpdates, fileUpdates, version)
res.sendStatus 200
app.delete "/project/:project_id/doc/:doc_id", (req, res, next) =>

View file

@ -390,6 +390,8 @@ describe 'DocumentUpdaterHandler', ->
describe "updateProjectStructure ", ->
beforeEach ->
@user_id = 1234
@version = 999
@Project.findOne = sinon.stub().callsArgWith(2,null, {_id: @project_id, version:@version})
describe "with project history disabled", ->
beforeEach ->
@ -434,7 +436,7 @@ describe 'DocumentUpdaterHandler', ->
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
@request.post
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id})
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version})
.should.equal true
done()
@ -454,7 +456,7 @@ describe 'DocumentUpdaterHandler', ->
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
@request.post
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id})
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version})
.should.equal true
done()
@ -474,7 +476,7 @@ describe 'DocumentUpdaterHandler', ->
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
@request.post
.calledWith(url: @url, json: {docUpdates: [], fileUpdates, userId: @user_id})
.calledWith(url: @url, json: {docUpdates: [], fileUpdates, userId: @user_id, version:@version})
.should.equal true
done()
@ -493,7 +495,7 @@ describe 'DocumentUpdaterHandler', ->
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
@request.post
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id})
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version})
.should.equal true
done()

View file

@ -117,7 +117,7 @@ describe 'ProjectEntityMongoUpdateHandler', ->
.calledWith(
{ _id: project_id },
{
'$inc': { 'file.png.rev': 1 }
'$inc': { 'file.png.rev': 1, 'version': 1 }
'$set': { 'file.png.created': new Date() }
}
{}
@ -324,7 +324,7 @@ describe 'ProjectEntityMongoUpdateHandler', ->
@ProjectModel.findOneAndUpdate
.calledWith(
{ _id: project_id },
{ $set: { "mongo.path.name": @newName } },
{ $set: { "mongo.path.name": @newName }, $inc: {"version": 1} },
{ new: true }
).should.equal true
@ -384,7 +384,7 @@ describe 'ProjectEntityMongoUpdateHandler', ->
it 'should pull', ->
@ProjectModel.findOneAndUpdate
.calledWith({ _id: @id }, { '$pull': { 'folders[0]': null } }, {'new': true})
.calledWith({ _id: @id }, { '$pull': { 'folders[0]': null }, '$inc': {'version': 1} }, {'new': true})
.should.equal true
it 'should call the callback', ->