mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #104 from sharelatex/hof-version-entity-creation
Version entity creation in SL -> OL history
This commit is contained in:
commit
1ddd199b7d
32 changed files with 774 additions and 251 deletions
|
@ -204,11 +204,11 @@ module.exports = DocumentUpdaterHandler =
|
|||
logger.error {project_id, doc_id, thread_id}, "doc updater returned a non-success status code: #{res.statusCode}"
|
||||
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
||||
|
||||
updateProjectStructure : (project_id, userId, oldDocs, newDocs, oldFiles, newFiles, callback = (error) ->)->
|
||||
updateProjectStructure : (project_id, userId, changes, callback = (error) ->)->
|
||||
return callback() if !settings.apis.project_history?.enabled
|
||||
|
||||
docUpdates = DocumentUpdaterHandler._getRenameUpdates('doc', oldDocs, newDocs)
|
||||
fileUpdates = DocumentUpdaterHandler._getRenameUpdates('file', oldFiles, newFiles)
|
||||
docUpdates = DocumentUpdaterHandler._getRenameUpdates('doc', changes.oldDocs, changes.newDocs)
|
||||
fileUpdates = DocumentUpdaterHandler._getRenameUpdates('file', changes.oldFiles, changes.newFiles)
|
||||
|
||||
timer = new metrics.Timer("set-document")
|
||||
url = "#{settings.apis.documentupdater.url}/project/#{project_id}"
|
||||
|
@ -231,14 +231,25 @@ module.exports = DocumentUpdaterHandler =
|
|||
callback new Error("doc updater returned a non-success status code: #{res.statusCode}")
|
||||
|
||||
_getRenameUpdates: (entityType, oldEntities, newEntities) ->
|
||||
oldEntities ||= []
|
||||
newEntities ||= []
|
||||
updates = []
|
||||
|
||||
for oldEntity in oldEntities
|
||||
id = oldEntity[entityType]._id
|
||||
newEntity = _.find newEntities, (newEntity) ->
|
||||
newEntity[entityType]._id.toString() == id.toString()
|
||||
oldEntitiesHash = _.indexBy oldEntities, (entity) -> entity[entityType]._id.toString()
|
||||
newEntitiesHash = _.indexBy newEntities, (entity) -> entity[entityType]._id.toString()
|
||||
|
||||
if newEntity.path != oldEntity.path
|
||||
for id, newEntity of newEntitiesHash
|
||||
oldEntity = oldEntitiesHash[id]
|
||||
|
||||
if !oldEntity?
|
||||
# entity added
|
||||
updates.push
|
||||
id: id
|
||||
pathname: newEntity.path
|
||||
docLines: newEntity.docLines
|
||||
url: newEntity.url
|
||||
else if newEntity.path != oldEntity.path
|
||||
# entity renamed
|
||||
updates.push
|
||||
id: id
|
||||
pathname: oldEntity.path
|
||||
|
|
|
@ -19,48 +19,48 @@ module.exports = EditorController =
|
|||
DocumentUpdaterHandler.flushDocToMongo project_id, doc_id, callback
|
||||
|
||||
|
||||
addDoc: (project_id, folder_id, docName, docLines, source, callback = (error, doc)->)->
|
||||
addDoc: (project_id, folder_id, docName, docLines, source, user_id, callback = (error, doc)->)->
|
||||
LockManager.getLock project_id, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, source:source, "could not get lock to addDoc"
|
||||
return callback(err)
|
||||
EditorController.addDocWithoutLock project_id, folder_id, docName, docLines, source, (error, doc)->
|
||||
EditorController.addDocWithoutLock project_id, folder_id, docName, docLines, source, user_id, (error, doc)->
|
||||
LockManager.releaseLock project_id, ->
|
||||
callback(error, doc)
|
||||
|
||||
addDocWithoutLock: (project_id, folder_id, docName, docLines, source, callback = (error, doc)->)->
|
||||
addDocWithoutLock: (project_id, folder_id, docName, docLines, source, user_id, callback = (error, doc)->)->
|
||||
docName = docName.trim()
|
||||
logger.log {project_id, folder_id, docName, source}, "sending new doc to project"
|
||||
Metrics.inc "editor.add-doc"
|
||||
ProjectEntityHandler.addDoc project_id, folder_id, docName, docLines, (err, doc, folder_id)=>
|
||||
ProjectEntityHandler.addDoc project_id, folder_id, docName, docLines, user_id, (err, doc, folder_id)=>
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, docName:docName, "error adding doc without lock"
|
||||
return callback(err)
|
||||
EditorRealTimeController.emitToRoom(project_id, 'reciveNewDoc', folder_id, doc, source)
|
||||
callback(err, doc)
|
||||
|
||||
addFile: (project_id, folder_id, fileName, path, source, callback = (error, file)->)->
|
||||
addFile: (project_id, folder_id, fileName, path, source, user_id, callback = (error, file)->)->
|
||||
LockManager.getLock project_id, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, source:source, "could not get lock to addFile"
|
||||
return callback(err)
|
||||
EditorController.addFileWithoutLock project_id, folder_id, fileName, path, source, (error, file)->
|
||||
EditorController.addFileWithoutLock project_id, folder_id, fileName, path, source, user_id, (error, file)->
|
||||
LockManager.releaseLock project_id, ->
|
||||
callback(error, file)
|
||||
|
||||
addFileWithoutLock: (project_id, folder_id, fileName, path, source, callback = (error, file)->)->
|
||||
addFileWithoutLock: (project_id, folder_id, fileName, path, source, user_id, callback = (error, file)->)->
|
||||
fileName = fileName.trim()
|
||||
logger.log {project_id, folder_id, fileName, path}, "sending new file to project"
|
||||
Metrics.inc "editor.add-file"
|
||||
ProjectEntityHandler.addFile project_id, folder_id, fileName, path, (err, fileRef, folder_id)=>
|
||||
ProjectEntityHandler.addFile project_id, folder_id, fileName, path, user_id, (err, fileRef, folder_id)=>
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, folder_id:folder_id, fileName:fileName, "error adding file without lock"
|
||||
return callback(err)
|
||||
EditorRealTimeController.emitToRoom(project_id, 'reciveNewFile', folder_id, fileRef, source)
|
||||
callback(err, fileRef)
|
||||
|
||||
replaceFile: (project_id, file_id, fsPath, source, callback = (error) ->)->
|
||||
ProjectEntityHandler.replaceFile project_id, file_id, fsPath, callback
|
||||
replaceFile: (project_id, file_id, fsPath, source, user_id, callback = (error) ->)->
|
||||
ProjectEntityHandler.replaceFile project_id, file_id, fsPath, user_id, callback
|
||||
|
||||
addFolder : (project_id, folder_id, folderName, source, callback = (error, folder)->)->
|
||||
LockManager.getLock project_id, (err)->
|
||||
|
|
|
@ -81,10 +81,11 @@ module.exports = EditorHttpController =
|
|||
project_id = req.params.Project_id
|
||||
name = req.body.name
|
||||
parent_folder_id = req.body.parent_folder_id
|
||||
user_id = AuthenticationController.getLoggedInUserId(req)
|
||||
logger.log project_id:project_id, name:name, parent_folder_id:parent_folder_id, "getting request to add doc to project"
|
||||
if !EditorHttpController._nameIsAcceptableLength(name)
|
||||
return res.sendStatus 400
|
||||
EditorController.addDoc project_id, parent_folder_id, name, [], "editor", (error, doc) ->
|
||||
EditorController.addDoc project_id, parent_folder_id, name, [], "editor", user_id, (error, doc) ->
|
||||
if error == "project_has_to_many_files"
|
||||
res.status(400).json(req.i18n.translate("project_has_to_many_files"))
|
||||
else if error?
|
||||
|
@ -113,9 +114,9 @@ module.exports = EditorHttpController =
|
|||
entity_id = req.params.entity_id
|
||||
entity_type = req.params.entity_type
|
||||
name = req.body.name
|
||||
user_id = AuthenticationController.getLoggedInUserId(req)
|
||||
if !EditorHttpController._nameIsAcceptableLength(name)
|
||||
return res.sendStatus 400
|
||||
user_id = AuthenticationController.getLoggedInUserId(req)
|
||||
EditorController.renameEntity project_id, entity_id, entity_type, name, user_id, (error) ->
|
||||
return next(error) if error?
|
||||
res.sendStatus 204
|
||||
|
|
|
@ -21,9 +21,9 @@ module.exports = FileStoreHandler =
|
|||
return callback(new Error("can not upload symlink"))
|
||||
|
||||
_cb = callback
|
||||
callback = (err) ->
|
||||
callback = (err, url) ->
|
||||
callback = -> # avoid double callbacks
|
||||
_cb(err)
|
||||
_cb(err, url)
|
||||
|
||||
logger.log project_id:project_id, file_id:file_id, fsPath:fsPath, "uploading file from disk"
|
||||
readStream = fs.createReadStream(fsPath)
|
||||
|
@ -31,9 +31,10 @@ module.exports = FileStoreHandler =
|
|||
logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "something went wrong on the read stream of uploadFileFromDisk"
|
||||
callback err
|
||||
readStream.on "open", () ->
|
||||
url = FileStoreHandler._buildUrl(project_id, file_id)
|
||||
opts =
|
||||
method: "post"
|
||||
uri: FileStoreHandler._buildUrl(project_id, file_id)
|
||||
uri: url
|
||||
timeout:fiveMinsInMs
|
||||
writeStream = request(opts)
|
||||
writeStream.on "error", (err)->
|
||||
|
@ -45,7 +46,7 @@ module.exports = FileStoreHandler =
|
|||
logger.err {err, statusCode: response.statusCode}, "error uploading to filestore"
|
||||
callback(err)
|
||||
else
|
||||
callback(null)
|
||||
callback(null, url)
|
||||
readStream.pipe writeStream
|
||||
|
||||
getFileStream: (project_id, file_id, query, callback)->
|
||||
|
@ -91,7 +92,7 @@ module.exports = FileStoreHandler =
|
|||
request opts, (err)->
|
||||
if err?
|
||||
logger.err err:err, oldProject_id:oldProject_id, oldFile_id:oldFile_id, newProject_id:newProject_id, newFile_id:newFile_id, "something went wrong telling filestore api to copy file"
|
||||
callback(err)
|
||||
callback(err, opts.uri)
|
||||
|
||||
_buildUrl: (project_id, file_id)->
|
||||
return "#{settings.apis.filestore.url}/project/#{project_id}/file/#{file_id}"
|
||||
|
|
|
@ -52,7 +52,7 @@ module.exports = ProjectCreationHandler =
|
|||
return callback(error) if error?
|
||||
self._buildTemplate "mainbasic.tex", owner_id, projectName, (error, docLines)->
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "main.tex", docLines, (error, doc)->
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "main.tex", docLines, owner_id, (error, doc)->
|
||||
if error?
|
||||
logger.err err:error, "error adding doc when creating basic project"
|
||||
return callback(error)
|
||||
|
@ -67,17 +67,17 @@ module.exports = ProjectCreationHandler =
|
|||
(callback) ->
|
||||
self._buildTemplate "main.tex", owner_id, projectName, (error, docLines)->
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "main.tex", docLines, (error, doc)->
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "main.tex", docLines, owner_id, (error, doc)->
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.setRootDoc project._id, doc._id, callback
|
||||
(callback) ->
|
||||
self._buildTemplate "references.bib", owner_id, projectName, (error, docLines)->
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "references.bib", docLines, (error, doc)->
|
||||
ProjectEntityHandler.addDoc project._id, project.rootFolder[0]._id, "references.bib", docLines, owner_id, (error, doc)->
|
||||
callback(error)
|
||||
(callback) ->
|
||||
universePath = Path.resolve(__dirname + "/../../../templates/project_files/universe.jpg")
|
||||
ProjectEntityHandler.addFile project._id, project.rootFolder[0]._id, "universe.jpg", universePath, callback
|
||||
ProjectEntityHandler.addFile project._id, project.rootFolder[0]._id, "universe.jpg", universePath, owner_id, callback
|
||||
], (error) ->
|
||||
callback(error, project)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ logger = require("logger-sharelatex")
|
|||
|
||||
module.exports = ProjectDuplicator =
|
||||
|
||||
_copyDocs: (newProject, originalRootDoc, originalFolder, desFolder, docContents, callback)->
|
||||
_copyDocs: (owner_id, newProject, originalRootDoc, originalFolder, desFolder, docContents, callback)->
|
||||
setRootDoc = _.once (doc_id)->
|
||||
projectEntityHandler.setRootDoc newProject._id, doc_id
|
||||
docs = originalFolder.docs or []
|
||||
|
@ -21,7 +21,7 @@ module.exports = ProjectDuplicator =
|
|||
if !doc?._id?
|
||||
return callback()
|
||||
content = docContents[doc._id.toString()]
|
||||
projectEntityHandler.addDocWithProject newProject, desFolder._id, doc.name, content.lines, (err, newDoc)->
|
||||
projectEntityHandler.addDocWithProject newProject, desFolder._id, doc.name, content.lines, owner_id, (err, newDoc)->
|
||||
if err?
|
||||
logger.err err:err, "error copying doc"
|
||||
return callback(err)
|
||||
|
@ -31,15 +31,15 @@ module.exports = ProjectDuplicator =
|
|||
|
||||
async.series jobs, callback
|
||||
|
||||
_copyFiles: (newProject, originalProject_id, originalFolder, desFolder, callback)->
|
||||
_copyFiles: (owner_id, newProject, originalProject_id, originalFolder, desFolder, callback)->
|
||||
fileRefs = originalFolder.fileRefs or []
|
||||
jobs = fileRefs.map (file)->
|
||||
return (cb)->
|
||||
projectEntityHandler.copyFileFromExistingProjectWithProject newProject, desFolder._id, originalProject_id, file, cb
|
||||
projectEntityHandler.copyFileFromExistingProjectWithProject newProject, desFolder._id, originalProject_id, file, owner_id, cb
|
||||
async.parallelLimit jobs, 5, callback
|
||||
|
||||
|
||||
_copyFolderRecursivly: (newProject_id, originalProject_id, originalRootDoc, originalFolder, desFolder, docContents, callback)->
|
||||
_copyFolderRecursivly: (owner_id, newProject_id, originalProject_id, originalRootDoc, originalFolder, desFolder, docContents, callback)->
|
||||
ProjectGetter.getProject newProject_id, {rootFolder:true, name:true}, (err, newProject)->
|
||||
if err?
|
||||
logger.err project_id:newProject_id, "could not get project"
|
||||
|
@ -53,12 +53,12 @@ module.exports = ProjectDuplicator =
|
|||
return cb()
|
||||
projectEntityHandler.addFolderWithProject newProject, desFolder?._id, childFolder.name, (err, newFolder)->
|
||||
return cb(err) if err?
|
||||
ProjectDuplicator._copyFolderRecursivly newProject_id, originalProject_id, originalRootDoc, childFolder, newFolder, docContents, cb
|
||||
ProjectDuplicator._copyFolderRecursivly owner_id, newProject_id, originalProject_id, originalRootDoc, childFolder, newFolder, docContents, cb
|
||||
|
||||
jobs.push (cb)->
|
||||
ProjectDuplicator._copyFiles newProject, originalProject_id, originalFolder, desFolder, cb
|
||||
ProjectDuplicator._copyFiles owner_id, newProject, originalProject_id, originalFolder, desFolder, cb
|
||||
jobs.push (cb)->
|
||||
ProjectDuplicator._copyDocs newProject, originalRootDoc, originalFolder, desFolder, docContents, cb
|
||||
ProjectDuplicator._copyDocs owner_id, newProject, originalRootDoc, originalFolder, desFolder, docContents, cb
|
||||
|
||||
async.series jobs, callback
|
||||
|
||||
|
@ -90,7 +90,7 @@ module.exports = ProjectDuplicator =
|
|||
|
||||
projectOptionsHandler.setCompiler newProject._id, originalProject.compiler, ->
|
||||
|
||||
ProjectDuplicator._copyFolderRecursivly newProject._id, originalProject_id, originalRootDoc, originalProject.rootFolder[0], newProject.rootFolder[0], docContents, ->
|
||||
ProjectDuplicator._copyFolderRecursivly owner._id, newProject._id, originalProject_id, originalRootDoc, originalProject.rootFolder[0], newProject.rootFolder[0], docContents, ->
|
||||
if err?
|
||||
logger.err err:err, originalProject_id:originalProject_id, newProjectName:newProjectName, "error cloning project"
|
||||
callback(err, newProject)
|
||||
|
|
|
@ -16,7 +16,7 @@ projectUpdateHandler = require('./ProjectUpdateHandler')
|
|||
DocstoreManager = require "../Docstore/DocstoreManager"
|
||||
ProjectGetter = require "./ProjectGetter"
|
||||
CooldownManager = require '../Cooldown/CooldownManager'
|
||||
|
||||
DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
|
||||
|
||||
module.exports = ProjectEntityHandler =
|
||||
getAllFolders: (project_id, callback) ->
|
||||
|
@ -106,8 +106,7 @@ module.exports = ProjectEntityHandler =
|
|||
flushProjectToThirdPartyDataStore: (project_id, callback) ->
|
||||
self = @
|
||||
logger.log project_id:project_id, "flushing project to tpds"
|
||||
documentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
|
||||
documentUpdaterHandler.flushProjectToMongo project_id, (error) ->
|
||||
DocumentUpdaterHandler.flushProjectToMongo project_id, (error) ->
|
||||
return callback(error) if error?
|
||||
ProjectGetter.getProject project_id, {name:true}, (error, project) ->
|
||||
return callback(error) if error?
|
||||
|
@ -150,14 +149,14 @@ module.exports = ProjectEntityHandler =
|
|||
else
|
||||
DocstoreManager.getDoc project_id, doc_id, options, callback
|
||||
|
||||
addDoc: (project_id, folder_id, docName, docLines, callback = (error, doc, folder_id) ->)=>
|
||||
addDoc: (project_id, folder_id, docName, docLines, userId, callback = (error, doc, folder_id) ->)=>
|
||||
ProjectGetter.getProjectWithOnlyFolders project_id, (err, project) ->
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for add doc"
|
||||
return callback(err)
|
||||
ProjectEntityHandler.addDocWithProject project, folder_id, docName, docLines, callback
|
||||
ProjectEntityHandler.addDocWithProject project, folder_id, docName, docLines, userId, callback
|
||||
|
||||
addDocWithProject: (project, folder_id, docName, docLines, callback = (error, doc, folder_id) ->)=>
|
||||
addDocWithProject: (project, folder_id, docName, docLines, userId, callback = (error, doc, folder_id) ->)=>
|
||||
project_id = project._id
|
||||
logger.log project_id: project_id, folder_id: folder_id, doc_name: docName, "adding doc to project with project"
|
||||
confirmFolder project, folder_id, (folder_id)=>
|
||||
|
@ -177,7 +176,14 @@ module.exports = ProjectEntityHandler =
|
|||
rev: 0
|
||||
}, (err) ->
|
||||
return callback(err) if err?
|
||||
callback(null, doc, folder_id)
|
||||
newDocs = [
|
||||
doc: doc
|
||||
path: result?.path?.fileSystem
|
||||
docLines: docLines.join('\n')
|
||||
]
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newDocs}, (error) ->
|
||||
return callback(error) if error?
|
||||
callback null, doc, folder_id
|
||||
|
||||
restoreDoc: (project_id, doc_id, name, callback = (error, doc, folder_id) ->) ->
|
||||
# getDoc will return the deleted doc's lines, but we don't actually remove
|
||||
|
@ -186,20 +192,20 @@ module.exports = ProjectEntityHandler =
|
|||
return callback(error) if error?
|
||||
ProjectEntityHandler.addDoc project_id, null, name, lines, callback
|
||||
|
||||
addFile: (project_id, folder_id, fileName, path, callback = (error, fileRef, folder_id) ->)->
|
||||
addFile: (project_id, folder_id, fileName, path, userId, callback = (error, fileRef, folder_id) ->)->
|
||||
ProjectGetter.getProjectWithOnlyFolders project_id, (err, project) ->
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for add file"
|
||||
return callback(err)
|
||||
ProjectEntityHandler.addFileWithProject project, folder_id, fileName, path, callback
|
||||
ProjectEntityHandler.addFileWithProject project, folder_id, fileName, path, userId, callback
|
||||
|
||||
addFileWithProject: (project, folder_id, fileName, path, callback = (error, fileRef, folder_id) ->)->
|
||||
addFileWithProject: (project, folder_id, fileName, path, userId, callback = (error, fileRef, folder_id) ->)->
|
||||
project_id = project._id
|
||||
logger.log project_id: project._id, folder_id: folder_id, file_name: fileName, path:path, "adding file"
|
||||
return callback(err) if err?
|
||||
confirmFolder project, folder_id, (folder_id)->
|
||||
fileRef = new File name : fileName
|
||||
FileStoreHandler.uploadFileFromDisk project._id, fileRef._id, path, (err)->
|
||||
FileStoreHandler.uploadFileFromDisk project._id, fileRef._id, path, (err, fileStoreUrl)->
|
||||
if err?
|
||||
logger.err err:err, project_id: project._id, folder_id: folder_id, file_name: fileName, fileRef:fileRef, "error uploading image to s3"
|
||||
return callback(err)
|
||||
|
@ -209,27 +215,31 @@ module.exports = ProjectEntityHandler =
|
|||
return callback(err)
|
||||
tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:result?.path?.fileSystem, project_name:project.name, rev:fileRef.rev}, (err) ->
|
||||
return callback(err) if err?
|
||||
callback(null, fileRef, folder_id)
|
||||
newFiles = [
|
||||
file: fileRef
|
||||
path: result?.path?.fileSystem
|
||||
url: fileStoreUrl
|
||||
]
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newFiles}, (error) ->
|
||||
return callback(error) if error?
|
||||
callback null, fileRef, folder_id
|
||||
|
||||
replaceFile: (project_id, file_id, fsPath, callback)->
|
||||
ProjectGetter.getProject project_id, {name:true}, (err, project) ->
|
||||
replaceFile: (project_id, file_id, fsPath, userId, callback)->
|
||||
self = ProjectEntityHandler
|
||||
FileStoreHandler.uploadFileFromDisk project_id, file_id, fsPath, (err, fileStoreUrl)->
|
||||
return callback(err) if err?
|
||||
findOpts =
|
||||
project_id:project._id
|
||||
element_id:file_id
|
||||
type:"file"
|
||||
FileStoreHandler.uploadFileFromDisk project._id, file_id, fsPath, (err)->
|
||||
ProjectGetter.getProject project_id, {rootFolder: true, name:true}, (err, project) ->
|
||||
return callback(err) if err?
|
||||
# Note there is a potential race condition here (and elsewhere)
|
||||
# If the file tree changes between findElement and the Project.update
|
||||
# then the path to the file element will be out of date. In practice
|
||||
# this is not a problem so long as we do not do anything longer running
|
||||
# between them (like waiting for the file to upload.)
|
||||
projectLocator.findElement findOpts, (err, fileRef, path)=>
|
||||
projectLocator.findElement {project:project, element_id: file_id, type: 'file'}, (err, fileRef, path)=>
|
||||
return callback(err) if err?
|
||||
tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:path.fileSystem, rev:fileRef.rev+1, project_name:project.name}, (error) ->
|
||||
tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:path.fileSystem, rev:fileRef.rev+1, project_name:project.name}, (err) ->
|
||||
return callback(err) if err?
|
||||
conditons = _id:project._id
|
||||
conditions = _id:project._id
|
||||
inc = {}
|
||||
inc["#{path.mongo}.rev"] = 1
|
||||
set = {}
|
||||
|
@ -237,39 +247,43 @@ module.exports = ProjectEntityHandler =
|
|||
update =
|
||||
"$inc": inc
|
||||
"$set": set
|
||||
Project.update conditons, update, {}, (err, second)->
|
||||
callback()
|
||||
Project.findOneAndUpdate conditions, update, { "new": true}, (err) ->
|
||||
return callback(err) if err?
|
||||
newFiles = [
|
||||
file: fileRef
|
||||
path: path.fileSystem
|
||||
url: fileStoreUrl
|
||||
]
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newFiles}, callback
|
||||
|
||||
copyFileFromExistingProject: (project_id, folder_id, originalProject_id, origonalFileRef, callback = (error, fileRef, folder_id) ->)->
|
||||
logger.log project_id:project_id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "copying file in s3"
|
||||
ProjectGetter.getProject project_id, {name:true}, (err, project) ->
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for copy file from existing project"
|
||||
return callback(err)
|
||||
ProjectEntityHandler.copyFileFromExistingProjectWithProject project, folder_id, originalProject_id, origonalFileRef, callback
|
||||
|
||||
|
||||
copyFileFromExistingProjectWithProject: (project, folder_id, originalProject_id, origonalFileRef, callback = (error, fileRef, folder_id) ->)->
|
||||
copyFileFromExistingProjectWithProject: (project, folder_id, originalProject_id, origonalFileRef, userId, callback = (error, fileRef, folder_id) ->)->
|
||||
project_id = project._id
|
||||
logger.log project_id:project_id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "copying file in s3 with project"
|
||||
logger.log { project_id, folder_id, originalProject_id, origonalFileRef }, "copying file in s3 with project"
|
||||
return callback(err) if err?
|
||||
confirmFolder project, folder_id, (folder_id)=>
|
||||
if !origonalFileRef?
|
||||
logger.err project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "file trying to copy is null"
|
||||
logger.err { project_id, folder_id, originalProject_id, origonalFileRef }, "file trying to copy is null"
|
||||
return callback()
|
||||
fileRef = new File name : origonalFileRef.name
|
||||
FileStoreHandler.copyFile originalProject_id, origonalFileRef._id, project._id, fileRef._id, (err)->
|
||||
FileStoreHandler.copyFile originalProject_id, origonalFileRef._id, project._id, fileRef._id, (err, fileStoreUrl)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "error coping file in s3"
|
||||
logger.err { err, project_id, folder_id, originalProject_id, origonalFileRef }, "error coping file in s3"
|
||||
return callback(err)
|
||||
ProjectEntityHandler._putElement project, folder_id, fileRef, "file", (err, result)=>
|
||||
if err?
|
||||
logger.err err:err, project_id:project._id, folder_id:folder_id, "error putting element as part of copy"
|
||||
logger.err { err, project_id, folder_id }, "error putting element as part of copy"
|
||||
return callback(err)
|
||||
tpdsUpdateSender.addFile {project_id:project._id, file_id:fileRef._id, path:result?.path?.fileSystem, rev:fileRef.rev, project_name:project.name}, (err) ->
|
||||
tpdsUpdateSender.addFile { project_id, file_id:fileRef._id, path:result?.path?.fileSystem, rev:fileRef.rev, project_name:project.name}, (err) ->
|
||||
if err?
|
||||
logger.err err:err, project_id:project._id, folder_id:folder_id, originalProject_id:originalProject_id, origonalFileRef:origonalFileRef, "error sending file to tpds worker"
|
||||
callback(null, fileRef, folder_id)
|
||||
logger.err { err, project_id, folder_id, originalProject_id, origonalFileRef }, "error sending file to tpds worker"
|
||||
newFiles = [
|
||||
file: fileRef
|
||||
path: result?.path?.fileSystem
|
||||
url: fileStoreUrl
|
||||
]
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newFiles}, (error) ->
|
||||
return callback(error) if error?
|
||||
callback null, fileRef, folder_id
|
||||
|
||||
mkdirp: (project_id, path, callback = (err, newlyCreatedFolders, lastFolderInPath)->)->
|
||||
self = @
|
||||
|
@ -381,11 +395,9 @@ module.exports = ProjectEntityHandler =
|
|||
endPath: result.path.fileSystem,
|
||||
rev: entity.rev
|
||||
tpdsUpdateSender.moveEntity opts
|
||||
self.getAllEntitiesFromProject newProject, (error, newDocs, newFiles
|
||||
) =>
|
||||
self.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
|
||||
return callback(error) if error?
|
||||
documentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
|
||||
documentUpdaterHandler.updateProjectStructure project_id, userId, oldDocs, newDocs, oldFiles, newFiles, callback
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldDocs, newDocs, oldFiles, newFiles}, callback
|
||||
|
||||
_checkValidMove: (project, entityType, entityPath, destFolderId, callback = (error) ->) ->
|
||||
return callback() if !entityType.match(/folder/)
|
||||
|
@ -442,8 +454,7 @@ module.exports = ProjectEntityHandler =
|
|||
return callback(error) if error?
|
||||
ProjectEntityHandler.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
|
||||
return callback(error) if error?
|
||||
documentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
|
||||
documentUpdaterHandler.updateProjectStructure project_id, userId, oldDocs, newDocs, oldFiles, newFiles, callback
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldDocs, newDocs, oldFiles, newFiles}, callback
|
||||
|
||||
_cleanUpEntity: (project, entity, entityType, callback = (error) ->) ->
|
||||
if(entityType.indexOf("file") != -1)
|
||||
|
@ -466,7 +477,7 @@ module.exports = ProjectEntityHandler =
|
|||
|
||||
unsetRootDocIfRequired (error) ->
|
||||
return callback(error) if error?
|
||||
require('../../Features/DocumentUpdater/DocumentUpdaterHandler').deleteDoc project_id, doc_id, (error) ->
|
||||
DocumentUpdaterHandler.deleteDoc project_id, doc_id, (error) ->
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler._insertDeletedDocReference project._id, doc, (error) ->
|
||||
return callback(error) if error?
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports =
|
|||
FileTypeManager.isBinary path, fsPath, (err, isFile)->
|
||||
return callback(err) if err?
|
||||
if isFile
|
||||
self.p.processFile project_id, elementId, fsPath, path, source, callback
|
||||
self.p.processFile project_id, elementId, fsPath, path, source, user_id, callback
|
||||
else
|
||||
self.p.processDoc project_id, elementId, user_id, fsPath, path, source, callback
|
||||
|
||||
|
@ -57,9 +57,9 @@ module.exports =
|
|||
if err?
|
||||
logger.err err:err, project_id:project_id, doc_id:doc_id, path:path, "error processing file"
|
||||
return callback(err)
|
||||
editorController.addDoc project_id, folder._id, fileName, docLines, source, callback
|
||||
editorController.addDoc project_id, folder._id, fileName, docLines, source, user_id, callback
|
||||
|
||||
processFile: (project_id, file_id, fsPath, path, source, callback)->
|
||||
processFile: (project_id, file_id, fsPath, path, source, user_id, callback)->
|
||||
finish = (err)->
|
||||
logger.log project_id:project_id, file_id:file_id, path:path, "completed processing file update from tpds"
|
||||
callback(err)
|
||||
|
@ -69,9 +69,9 @@ module.exports =
|
|||
logger.err err:err, project_id:project_id, file_id:file_id, path:path, "error processing file"
|
||||
return callback(err)
|
||||
else if file_id?
|
||||
editorController.replaceFile project_id, file_id, fsPath, source, finish
|
||||
editorController.replaceFile project_id, file_id, fsPath, source, user_id, finish
|
||||
else
|
||||
editorController.addFile project_id, folder?._id, fileName, fsPath, source, finish
|
||||
editorController.addFile project_id, folder?._id, fileName, fsPath, source, user_id, finish
|
||||
|
||||
writeStreamToDisk: (project_id, file_id, stream, callback = (err, fsPath)->)->
|
||||
if !file_id?
|
||||
|
|
|
@ -28,9 +28,9 @@ module.exports = FileSystemImportManager =
|
|||
if existingDoc?
|
||||
EditorController.setDoc project_id, existingDoc._id, user_id, lines, "upload", callback
|
||||
else
|
||||
EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", callback
|
||||
EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", user_id, callback
|
||||
else
|
||||
EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", callback
|
||||
EditorController.addDocWithoutLock project_id, folder_id, name, lines, "upload", user_id, callback
|
||||
|
||||
addFile: (user_id, project_id, folder_id, name, path, replace, callback = (error, file)-> )->
|
||||
FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
|
||||
|
@ -39,7 +39,7 @@ module.exports = FileSystemImportManager =
|
|||
return callback("path is symlink")
|
||||
|
||||
if !replace
|
||||
EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", callback
|
||||
EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", user_id, callback
|
||||
else
|
||||
ProjectLocator.findElement project_id: project_id, element_id: folder_id, type: "folder", (error, folder) ->
|
||||
return callback(error) if error?
|
||||
|
@ -50,9 +50,9 @@ module.exports = FileSystemImportManager =
|
|||
existingFile = fileRef
|
||||
break
|
||||
if existingFile?
|
||||
EditorController.replaceFile project_id, existingFile._id, path, "upload", callback
|
||||
EditorController.replaceFile project_id, existingFile._id, path, "upload", user_id, callback
|
||||
else
|
||||
EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", callback
|
||||
EditorController.addFileWithoutLock project_id, folder_id, name, path, "upload", user_id, callback
|
||||
|
||||
addFolder: (user_id, project_id, folder_id, name, path, replace, callback = (error)-> ) ->
|
||||
FileSystemImportManager._isSafeOnFileSystem path, (err, isSafe)->
|
||||
|
|
|
@ -111,7 +111,7 @@ module.exports = settings =
|
|||
trackchanges:
|
||||
url : "http://localhost:3015"
|
||||
project_history:
|
||||
enabled: false
|
||||
enabled: process.env.PROJECT_HISTORY_ENABLED == 'true' or false
|
||||
url : "http://localhost:3054"
|
||||
docstore:
|
||||
url : "http://#{process.env['DOCSTORE_HOST'] or 'localhost'}:3016"
|
||||
|
|
|
@ -24,6 +24,7 @@ services:
|
|||
REDIS_HOST: redis
|
||||
MONGO_URL: "mongodb://mongo/sharelatex"
|
||||
SHARELATEX_ALLOW_PUBLIC_ACCESS: 'true'
|
||||
PROJECT_HISTORY_ENABLED: 'true'
|
||||
depends_on:
|
||||
- redis
|
||||
- mongo
|
||||
|
|
|
@ -25,6 +25,7 @@ services:
|
|||
- ./config:/app/config
|
||||
- ./test/unit/coffee:/app/test/unit/coffee:ro
|
||||
- ./test/acceptance/coffee:/app/test/acceptance/coffee:ro
|
||||
- ./test/acceptance/files:/app/test/acceptance/files:ro
|
||||
- ./test/smoke/coffee:/app/test/smoke/coffee:ro
|
||||
MODULE_VOLUMES
|
||||
working_dir: /app
|
||||
working_dir: /app
|
||||
|
|
307
services/web/test/acceptance/coffee/ProjectStructureTests.coffee
Normal file
307
services/web/test/acceptance/coffee/ProjectStructureTests.coffee
Normal file
|
@ -0,0 +1,307 @@
|
|||
async = require "async"
|
||||
expect = require("chai").expect
|
||||
mkdirp = require "mkdirp"
|
||||
ObjectId = require("mongojs").ObjectId
|
||||
Path = require "path"
|
||||
fs = require "fs"
|
||||
Settings = require "settings-sharelatex"
|
||||
_ = require "underscore"
|
||||
|
||||
ProjectGetter = require "../../../app/js/Features/Project/ProjectGetter.js"
|
||||
|
||||
MockDocUpdaterApi = require './helpers/MockDocUpdaterApi'
|
||||
MockFileStoreApi = require './helpers/MockFileStoreApi'
|
||||
MockProjectHistoryApi = require './helpers/MockProjectHistoryApi'
|
||||
request = require "./helpers/request"
|
||||
User = require "./helpers/User"
|
||||
|
||||
describe "ProjectStructureChanges", ->
|
||||
before (done) ->
|
||||
@owner = new User()
|
||||
@owner.login done
|
||||
|
||||
describe "creating a project from the example template", ->
|
||||
before (done) ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
@owner.createProject "example-project", {template: "example"}, (error, project_id) =>
|
||||
throw error if error?
|
||||
@example_project_id = project_id
|
||||
done()
|
||||
|
||||
it "should version creating a doc", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@example_project_id).docUpdates
|
||||
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
|
||||
|
||||
it "should version creating a file", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@example_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
describe "duplicating a project", ->
|
||||
before (done) ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
@owner.request.post {
|
||||
uri: "/Project/#{@example_project_id}/clone",
|
||||
json:
|
||||
projectName: 'new.tex'
|
||||
}, (error, res, body) =>
|
||||
throw error if error?
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to add doc #{res.statusCode}")
|
||||
@dup_project_id = body.project_id
|
||||
done()
|
||||
|
||||
it "should version the dosc created", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id).docUpdates
|
||||
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)
|
||||
|
||||
it "should version the files created", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@dup_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
describe "adding a doc", ->
|
||||
before (done) ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
|
||||
ProjectGetter.getProject @example_project_id, (error, projects) =>
|
||||
throw error if error?
|
||||
@owner.request.post {
|
||||
uri: "project/#{@example_project_id}/doc",
|
||||
json:
|
||||
name: 'new.tex'
|
||||
parent_folder_id: projects[0].rootFolder[0]._id
|
||||
}, (error, res, body) =>
|
||||
throw error if error?
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to add doc #{res.statusCode}")
|
||||
done()
|
||||
|
||||
it "should version the doc added", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@example_project_id).docUpdates
|
||||
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');
|
||||
|
||||
describe "uploading a project", ->
|
||||
before (done) ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
|
||||
zip_file = fs.createReadStream(Path.resolve(__dirname + '/../files/test_project.zip'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "project/new/upload",
|
||||
formData:
|
||||
qqfile: zip_file
|
||||
}, (error, res, body) =>
|
||||
throw error if error?
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload project #{res.statusCode}")
|
||||
@uploaded_project_id = JSON.parse(body).project_id
|
||||
done()
|
||||
|
||||
it "should version the dosc created", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id).docUpdates
|
||||
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")
|
||||
|
||||
it "should version the files created", ->
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@uploaded_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
describe "uploading a file", ->
|
||||
before (done) ->
|
||||
ProjectGetter.getProject @example_project_id, (error, projects) =>
|
||||
throw error if error?
|
||||
@root_folder_id = projects[0].rootFolder[0]._id.toString()
|
||||
done()
|
||||
|
||||
beforeEach () ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
|
||||
it "should version a newly uploaded file", (done) ->
|
||||
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/1pixel.png'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "project/#{@example_project_id}/upload",
|
||||
qs:
|
||||
folder_id: @root_folder_id
|
||||
formData:
|
||||
qqfile:
|
||||
value: image_file
|
||||
options:
|
||||
filename: '1pixel.png',
|
||||
contentType: 'image/png'
|
||||
}, (error, res, body) =>
|
||||
throw error if error?
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload file #{res.statusCode}")
|
||||
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@example_project_id).fileUpdates
|
||||
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
|
||||
|
||||
done()
|
||||
|
||||
it "should version a replacement file", (done) ->
|
||||
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/2pixel.png'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "project/#{@example_project_id}/upload",
|
||||
qs:
|
||||
folder_id: @root_folder_id
|
||||
formData:
|
||||
qqfile:
|
||||
value: image_file
|
||||
options:
|
||||
filename: '1pixel.png',
|
||||
contentType: 'image/png'
|
||||
}, (error, res, body) =>
|
||||
throw error if error?
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload file #{res.statusCode}")
|
||||
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@example_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
done()
|
||||
|
||||
describe "tpds", ->
|
||||
before (done) ->
|
||||
@tpds_project_name = "tpds-project-#{new ObjectId().toString()}"
|
||||
@owner.createProject @tpds_project_name, (error, project_id) =>
|
||||
throw error if error?
|
||||
@tpds_project_id = project_id
|
||||
mkdirp Settings.path.dumpFolder, done
|
||||
|
||||
beforeEach () ->
|
||||
MockDocUpdaterApi.clearProjectStructureUpdates()
|
||||
|
||||
it "should version adding a doc", (done) ->
|
||||
tex_file = fs.createReadStream(Path.resolve(__dirname + '/../files/test.tex'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "/user/#{@owner._id}/update/#{@tpds_project_name}/test.tex",
|
||||
auth:
|
||||
user: _.keys(Settings.httpAuthUsers)[0]
|
||||
pass: _.values(Settings.httpAuthUsers)[0]
|
||||
sendImmediately: true
|
||||
}
|
||||
|
||||
tex_file.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "response", (res) =>
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload file #{res.statusCode}")
|
||||
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).docUpdates
|
||||
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")
|
||||
|
||||
done()
|
||||
|
||||
tex_file.pipe(req)
|
||||
|
||||
it "should version adding a new file", (done) ->
|
||||
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/1pixel.png'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "/user/#{@owner._id}/update/#{@tpds_project_name}/1pixel.png",
|
||||
auth:
|
||||
user: _.keys(Settings.httpAuthUsers)[0]
|
||||
pass: _.values(Settings.httpAuthUsers)[0]
|
||||
sendImmediately: true
|
||||
}
|
||||
|
||||
image_file.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "response", (res) =>
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload file #{res.statusCode}")
|
||||
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
done()
|
||||
|
||||
image_file.pipe(req)
|
||||
|
||||
it "should version replacing a file", (done) ->
|
||||
image_file = fs.createReadStream(Path.resolve(__dirname + '/../files/2pixel.png'))
|
||||
|
||||
req = @owner.request.post {
|
||||
uri: "/user/#{@owner._id}/update/#{@tpds_project_name}/1pixel.png",
|
||||
auth:
|
||||
user: _.keys(Settings.httpAuthUsers)[0]
|
||||
pass: _.values(Settings.httpAuthUsers)[0]
|
||||
sendImmediately: true
|
||||
}
|
||||
|
||||
image_file.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "error", (err) ->
|
||||
throw err
|
||||
|
||||
req.on "response", (res) =>
|
||||
if res.statusCode < 200 || res.statusCode >= 300
|
||||
throw new Error("failed to upload file #{res.statusCode}")
|
||||
|
||||
updates = MockDocUpdaterApi.getProjectStructureUpdates(@tpds_project_id).fileUpdates
|
||||
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');
|
||||
|
||||
done()
|
||||
|
||||
image_file.pipe(req)
|
|
@ -1,11 +1,38 @@
|
|||
express = require("express")
|
||||
app = express()
|
||||
bodyParser = require "body-parser"
|
||||
jsonParser = bodyParser.json()
|
||||
|
||||
module.exports = MockDocUpdaterApi =
|
||||
updates: {}
|
||||
|
||||
clearProjectStructureUpdates: () ->
|
||||
@updates = {}
|
||||
|
||||
getProjectStructureUpdates: (project_id) ->
|
||||
@updates[project_id] || { docUpdates: [], fileUpdates: [] }
|
||||
|
||||
addProjectStructureUpdates: (project_id, userId, docUpdates, fileUpdates) ->
|
||||
@updates[project_id] ||= { docUpdates: [], fileUpdates: [] }
|
||||
|
||||
for update in docUpdates
|
||||
update.userId = userId
|
||||
@updates[project_id].docUpdates.push(update)
|
||||
|
||||
for update in fileUpdates
|
||||
update.userId = userId
|
||||
@updates[project_id].fileUpdates.push(update)
|
||||
|
||||
run: () ->
|
||||
app.post "/project/:project_id/flush", (req, res, next) =>
|
||||
res.sendStatus 200
|
||||
|
||||
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)
|
||||
res.sendStatus 200
|
||||
|
||||
app.listen 3003, (error) ->
|
||||
throw error if error?
|
||||
.on "error", (error) ->
|
||||
|
|
|
@ -13,6 +13,7 @@ module.exports = MockDocStoreApi =
|
|||
@docs[project_id][doc_id] = {lines, version, ranges}
|
||||
@docs[project_id][doc_id].rev ?= 0
|
||||
@docs[project_id][doc_id].rev += 1
|
||||
@docs[project_id][doc_id]._id = doc_id
|
||||
res.json {
|
||||
modified: true
|
||||
rev: @docs[project_id][doc_id].rev
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
express = require("express")
|
||||
app = express()
|
||||
|
||||
module.exports = MockFileStoreApi =
|
||||
files: {}
|
||||
|
||||
run: () ->
|
||||
app.post "/project/:project_id/file/:file_id", (req, res, next) =>
|
||||
req.on 'data', ->
|
||||
|
||||
req.on 'end', ->
|
||||
res.send 200
|
||||
|
||||
app.listen 3009, (error) ->
|
||||
throw error if error?
|
||||
.on "error", (error) ->
|
||||
console.error "error starting MockFileStoreApi:", error.message
|
||||
process.exit(1)
|
||||
|
||||
MockFileStoreApi.run()
|
|
@ -0,0 +1,18 @@
|
|||
express = require("express")
|
||||
app = express()
|
||||
|
||||
module.exports = MockProjectHistoryApi =
|
||||
docs: {}
|
||||
|
||||
run: () ->
|
||||
app.post "/project", (req, res, next) =>
|
||||
res.json project: id: 1
|
||||
|
||||
app.listen 3054, (error) ->
|
||||
throw error if error?
|
||||
.on "error", (error) ->
|
||||
console.error "error starting MockProjectHistoryApi:", error.message
|
||||
process.exit(1)
|
||||
|
||||
|
||||
MockProjectHistoryApi.run()
|
|
@ -99,11 +99,14 @@ class User
|
|||
getProject: (project_id, callback = (error, project)->) ->
|
||||
db.projects.findOne {_id: ObjectId(project_id.toString())}, callback
|
||||
|
||||
createProject: (name, callback = (error, project_id) ->) ->
|
||||
createProject: (name, options, callback = (error, oroject_id) ->) ->
|
||||
if typeof options == "function"
|
||||
callback = options
|
||||
options = {}
|
||||
|
||||
@request.post {
|
||||
url: "/project/new",
|
||||
json:
|
||||
projectName: name
|
||||
json: Object.assign({projectName: name}, options)
|
||||
}, (error, response, body) ->
|
||||
return callback(error) if error?
|
||||
if !body?.project_id?
|
||||
|
|
BIN
services/web/test/acceptance/files/1pixel.png
Normal file
BIN
services/web/test/acceptance/files/1pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
services/web/test/acceptance/files/2pixel.png
Normal file
BIN
services/web/test/acceptance/files/2pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
1
services/web/test/acceptance/files/test.tex
Normal file
1
services/web/test/acceptance/files/test.tex
Normal file
|
@ -0,0 +1 @@
|
|||
Test
|
BIN
services/web/test/acceptance/files/test_project.zip
Normal file
BIN
services/web/test/acceptance/files/test_project.zip
Normal file
Binary file not shown.
|
@ -3,7 +3,7 @@
|
|||
# If you're running on OS X, you probably need to rebuild
|
||||
# some dependencies in the docker container, before it will start.
|
||||
#
|
||||
# npm rebuild --update-binary
|
||||
#npm rebuild --update-binary
|
||||
|
||||
echo ">> Starting server..."
|
||||
|
||||
|
|
|
@ -390,26 +390,13 @@ describe 'DocumentUpdaterHandler', ->
|
|||
describe "updateProjectStructure ", ->
|
||||
beforeEach ->
|
||||
@user_id = 1234
|
||||
@docIdA = new ObjectId()
|
||||
@docIdB = new ObjectId()
|
||||
@oldDocs = [
|
||||
{ path: '/old_a', doc: _id: @docIdA }
|
||||
{ path: '/old_b', doc: _id: @docIdB }
|
||||
]
|
||||
# create new instances of the same ObjectIds so that == doens't pass
|
||||
@newDocs = [
|
||||
{ path: '/old_a', doc: _id: new ObjectId(@docIdA.toString()) }
|
||||
{ path: '/new_b', doc: _id: new ObjectId(@docIdB.toString()) }
|
||||
]
|
||||
@oldFiles = []
|
||||
@newFiles = []
|
||||
|
||||
describe "with project history disabled", ->
|
||||
beforeEach ->
|
||||
@settings.apis.project_history.enabled = false
|
||||
@request.post = sinon.stub()
|
||||
|
||||
@handler.updateProjectStructure @project_id, @user_id, @oldDocs, @newDocs, @oldFiles, @newFiles, @callback
|
||||
@handler.updateProjectStructure @project_id, @user_id, {}, @callback
|
||||
|
||||
it 'does not make a web request', ->
|
||||
@request.post.called.should.equal false
|
||||
|
@ -420,20 +407,85 @@ describe 'DocumentUpdaterHandler', ->
|
|||
describe "with project history enabled", ->
|
||||
beforeEach ->
|
||||
@settings.apis.project_history.enabled = true
|
||||
@url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}"
|
||||
@request.post = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "")
|
||||
@handler.updateProjectStructure @project_id, @user_id, @oldDocs, @newDocs, @oldFiles, @newFiles, @callback
|
||||
|
||||
it 'should send the structure update to the document updater', ->
|
||||
docUpdates = [
|
||||
id: @docIdB,
|
||||
pathname: "/old_b"
|
||||
newPathname: "/new_b"
|
||||
]
|
||||
describe "when an entity has changed name", ->
|
||||
it 'should send the structure update to the document updater', (done) ->
|
||||
@docIdA = new ObjectId()
|
||||
@docIdB = new ObjectId()
|
||||
@changes = {
|
||||
oldDocs: [
|
||||
{ path: '/old_a', doc: _id: @docIdA }
|
||||
{ path: '/old_b', doc: _id: @docIdB }
|
||||
]
|
||||
# create new instances of the same ObjectIds so that == doesn't pass
|
||||
newDocs: [
|
||||
{ path: '/old_a', doc: _id: new ObjectId(@docIdA.toString()) }
|
||||
{ path: '/new_b', doc: _id: new ObjectId(@docIdB.toString()) }
|
||||
]
|
||||
}
|
||||
|
||||
url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}"
|
||||
@request.post
|
||||
.calledWith(url: url, json: {docUpdates, fileUpdates: [], userId: @user_id})
|
||||
.should.equal true
|
||||
docUpdates = [
|
||||
id: @docIdB.toString(),
|
||||
pathname: "/old_b"
|
||||
newPathname: "/new_b"
|
||||
]
|
||||
|
||||
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
|
||||
@request.post
|
||||
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id})
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
describe "when a doc has been added", ->
|
||||
it 'should send the structure update to the document updater', (done) ->
|
||||
@docId = new ObjectId()
|
||||
@changes = newDocs: [
|
||||
{ path: '/foo', docLines: 'a\nb', doc: _id: @docId }
|
||||
]
|
||||
|
||||
docUpdates = [
|
||||
id: @docId.toString(),
|
||||
pathname: "/foo"
|
||||
docLines: 'a\nb'
|
||||
url: undefined
|
||||
]
|
||||
|
||||
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
|
||||
@request.post
|
||||
.calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id})
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
describe "when a file has been added", ->
|
||||
it 'should send the structure update to the document updater', (done) ->
|
||||
@fileId = new ObjectId()
|
||||
@changes = newFiles: [
|
||||
{ path: '/bar', url: 'filestore.example.com/file', file: _id: @fileId }
|
||||
]
|
||||
|
||||
fileUpdates = [
|
||||
id: @fileId.toString(),
|
||||
pathname: "/bar"
|
||||
url: 'filestore.example.com/file'
|
||||
docLines: undefined
|
||||
]
|
||||
|
||||
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
|
||||
@request.post
|
||||
.calledWith(url: @url, json: {docUpdates: [], fileUpdates, userId: @user_id})
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
describe "when a doc has been deleted", ->
|
||||
it 'should do nothing', (done) ->
|
||||
@docId = new ObjectId()
|
||||
@changes = oldDocs: [
|
||||
{ path: '/foo', docLines: 'a\nb', doc: _id: @docId }
|
||||
]
|
||||
|
||||
@handler.updateProjectStructure @project_id, @user_id, @changes, () =>
|
||||
@request.post.called.should.equal false
|
||||
done()
|
||||
|
||||
it "should call the callback with no error", ->
|
||||
@callback.calledWith(null).should.equal true
|
||||
|
|
|
@ -131,24 +131,24 @@ describe "EditorController", ->
|
|||
@docLines = ["1234","dskl"]
|
||||
|
||||
it 'should add the doc using the project entity handler', (done)->
|
||||
mock = sinon.mock(@ProjectEntityHandler).expects("addDoc").withArgs(@project_id, @folder_id, @docName, @docLines).callsArg(4)
|
||||
mock = sinon.mock(@ProjectEntityHandler).expects("addDoc").withArgs(@project_id, @folder_id, @docName, @docLines).callsArg(5)
|
||||
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, ->
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, @user_id, ->
|
||||
mock.verify()
|
||||
done()
|
||||
|
||||
it 'should send the update out to the users in the project', (done)->
|
||||
@ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(4, null, @doc, @folder_id)
|
||||
@ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(5, null, @doc, @folder_id)
|
||||
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, =>
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, @user_id, =>
|
||||
@EditorRealTimeController.emitToRoom
|
||||
.calledWith(@project_id, "reciveNewDoc", @folder_id, @doc, @source)
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
it 'should return the doc to the callback', (done) ->
|
||||
@ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(4, null, @doc, @folder_id)
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, (error, doc) =>
|
||||
@ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(5, null, @doc, @folder_id)
|
||||
@EditorController.addDocWithoutLock @project_id, @folder_id, @docName, @docLines, @source, @user_id, (error, doc) =>
|
||||
doc.should.equal @doc
|
||||
done()
|
||||
|
||||
|
@ -157,32 +157,29 @@ describe "EditorController", ->
|
|||
beforeEach ->
|
||||
@LockManager.getLock.callsArgWith(1)
|
||||
@LockManager.releaseLock.callsArgWith(1)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArgWith(5)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArgWith(6)
|
||||
|
||||
it "should call addDocWithoutLock", (done)->
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, =>
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @docName, @docLines, @source).should.equal true
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, @user_id, =>
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @docName, @docLines, @source, @user_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should take the lock", (done)->
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, =>
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, @user_id, =>
|
||||
@LockManager.getLock.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should release the lock", (done)->
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, =>
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, @user_id, =>
|
||||
@LockManager.releaseLock.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should error if it can't cat the lock", (done)->
|
||||
@LockManager.getLock = sinon.stub().callsArgWith(1, "timed out")
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, (err)=>
|
||||
@EditorController.addDoc @project_id, @folder_id, @docName, @docLines, @source, @user_id, (err)=>
|
||||
expect(err).to.exist
|
||||
err.should.equal "timed out"
|
||||
done()
|
||||
|
||||
|
||||
|
||||
done()
|
||||
|
||||
describe 'addFileWithoutLock:', ->
|
||||
beforeEach ->
|
||||
|
@ -196,23 +193,23 @@ describe "EditorController", ->
|
|||
@stream = new ArrayBuffer()
|
||||
|
||||
it 'should add the folder using the project entity handler', (done)->
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(4)
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, =>
|
||||
@ProjectEntityHandler.addFile.calledWith(@project_id, @folder_id).should.equal true
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(5)
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, @user_id, =>
|
||||
@ProjectEntityHandler.addFile.calledWith(@project_id, @folder_id, @fileName, @stream, @user_id).should.equal true
|
||||
done()
|
||||
|
||||
it 'should send the update of a new folder out to the users in the project', (done)->
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(4, null, @file, @folder_id)
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(5, null, @file, @folder_id)
|
||||
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, =>
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, @user_id, =>
|
||||
@EditorRealTimeController.emitToRoom
|
||||
.calledWith(@project_id, "reciveNewFile", @folder_id, @file, @source)
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
it "should return the file in the callback", (done) ->
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(4, null, @file, @folder_id)
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, (error, file) =>
|
||||
@ProjectEntityHandler.addFile = sinon.stub().callsArgWith(5, null, @file, @folder_id)
|
||||
@EditorController.addFileWithoutLock @project_id, @folder_id, @fileName, @stream, @source, @user_id, (error, file) =>
|
||||
file.should.equal @file
|
||||
done()
|
||||
|
||||
|
@ -222,28 +219,28 @@ describe "EditorController", ->
|
|||
beforeEach ->
|
||||
@LockManager.getLock.callsArgWith(1)
|
||||
@LockManager.releaseLock.callsArgWith(1)
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArgWith(5)
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArgWith(6)
|
||||
|
||||
it "should call addFileWithoutLock", (done)->
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, (error, file) =>
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @fileName, @stream, @source).should.equal true
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, @user_id, (error, file) =>
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @fileName, @stream, @source, @user_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should take the lock", (done)->
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, (error, file) =>
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, @user_id, (error, file) =>
|
||||
@LockManager.getLock.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should release the lock", (done)->
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, (error, file) =>
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, @user_id, (error, file) =>
|
||||
@LockManager.releaseLock.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should error if it can't cat the lock", (done)->
|
||||
@LockManager.getLock = sinon.stub().callsArgWith(1, "timed out")
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, (err, file) =>
|
||||
expect(err).to.exist
|
||||
err.should.equal "timed out"
|
||||
@EditorController.addFile @project_id, @folder_id, @fileName, @stream, @source, @user_id, (error, file) =>
|
||||
expect(error).to.exist
|
||||
error.should.equal "timed out"
|
||||
done()
|
||||
|
||||
|
||||
|
@ -256,9 +253,9 @@ describe "EditorController", ->
|
|||
@fsPath = "/folder/file.png"
|
||||
|
||||
it 'should send the replace file message to the editor controller', (done)->
|
||||
@ProjectEntityHandler.replaceFile = sinon.stub().callsArgWith(3)
|
||||
@EditorController.replaceFile @project_id, @file_id, @fsPath, @source, =>
|
||||
@ProjectEntityHandler.replaceFile.calledWith(@project_id, @file_id, @fsPath).should.equal true
|
||||
@ProjectEntityHandler.replaceFile = sinon.stub().callsArgWith(4)
|
||||
@EditorController.replaceFile @project_id, @file_id, @fsPath, @source, @user_id, =>
|
||||
@ProjectEntityHandler.replaceFile.calledWith(@project_id, @file_id, @fsPath, @user_id).should.equal true
|
||||
done()
|
||||
|
||||
describe 'addFolderWithoutLock :', ->
|
||||
|
|
|
@ -201,7 +201,7 @@ describe "EditorHttpController", ->
|
|||
@req.body =
|
||||
name: @name = "doc-name"
|
||||
parent_folder_id: @parent_folder_id
|
||||
@EditorController.addDoc = sinon.stub().callsArgWith(5, null, @doc)
|
||||
@EditorController.addDoc = sinon.stub().callsArgWith(6, null, @doc)
|
||||
|
||||
describe "successfully", ->
|
||||
beforeEach ->
|
||||
|
@ -209,7 +209,7 @@ describe "EditorHttpController", ->
|
|||
|
||||
it "should call EditorController.addDoc", ->
|
||||
@EditorController.addDoc
|
||||
.calledWith(@project_id, @parent_folder_id, @name, [], "editor")
|
||||
.calledWith(@project_id, @parent_folder_id, @name, [], "editor", @userId)
|
||||
.should.equal true
|
||||
|
||||
it "should send the doc back as JSON", ->
|
||||
|
|
|
@ -16,7 +16,7 @@ describe "FileStoreHandler", ->
|
|||
})
|
||||
@writeStream =
|
||||
my:"writeStream"
|
||||
on: (type, cb)->
|
||||
on: (type, cb)->
|
||||
if type == "response"
|
||||
cb({statusCode: 200})
|
||||
@readStream = {my:"readStream", on: sinon.stub()}
|
||||
|
@ -38,7 +38,7 @@ describe "FileStoreHandler", ->
|
|||
@isSafeOnFileSystem = true
|
||||
|
||||
it "should create read stream", (done)->
|
||||
@fs.createReadStream.returns
|
||||
@fs.createReadStream.returns
|
||||
pipe:->
|
||||
on: (type, cb)->
|
||||
if type == "open"
|
||||
|
@ -49,8 +49,8 @@ describe "FileStoreHandler", ->
|
|||
|
||||
it "should pipe the read stream to request", (done)->
|
||||
@request.returns(@writeStream)
|
||||
@fs.createReadStream.returns
|
||||
on: (type, cb)->
|
||||
@fs.createReadStream.returns
|
||||
on: (type, cb)->
|
||||
if type == "open"
|
||||
cb()
|
||||
pipe:(o)=>
|
||||
|
@ -59,9 +59,9 @@ describe "FileStoreHandler", ->
|
|||
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
||||
|
||||
it "should pass the correct options to request", (done)->
|
||||
@fs.createReadStream.returns
|
||||
@fs.createReadStream.returns
|
||||
pipe:->
|
||||
on: (type, cb)->
|
||||
on: (type, cb)->
|
||||
if type == "open"
|
||||
cb()
|
||||
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
||||
|
@ -70,23 +70,24 @@ describe "FileStoreHandler", ->
|
|||
done()
|
||||
|
||||
it "builds the correct url", (done)->
|
||||
@fs.createReadStream.returns
|
||||
@fs.createReadStream.returns
|
||||
pipe:->
|
||||
on: (type, cb)->
|
||||
on: (type, cb)->
|
||||
if type == "open"
|
||||
cb()
|
||||
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
||||
@handler._buildUrl.calledWith(@project_id, @file_id).should.equal true
|
||||
done()
|
||||
|
||||
it 'should callback with null', (done) ->
|
||||
it 'should callback with the url', (done) ->
|
||||
@fs.createReadStream.returns
|
||||
pipe:->
|
||||
on: (type, cb)->
|
||||
if type == "open"
|
||||
cb()
|
||||
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, (err) =>
|
||||
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, (err, url) =>
|
||||
expect(err).to.not.exist
|
||||
expect(url).to.equal(@handler._buildUrl())
|
||||
done()
|
||||
|
||||
describe "symlink", ->
|
||||
|
@ -218,6 +219,11 @@ describe "FileStoreHandler", ->
|
|||
@handler._buildUrl.calledWith(@newProject_id, @newFile_id).should.equal true
|
||||
done()
|
||||
|
||||
it "returns the url", (done)->
|
||||
@request.callsArgWith(1, null)
|
||||
@handler.copyFile @project_id, @file_id, @newProject_id, @newFile_id, (err, url) =>
|
||||
url.should.equal "http://filestore.stubbedBuilder.com"
|
||||
done()
|
||||
|
||||
it "should return the err", (done)->
|
||||
error = "errrror"
|
||||
|
|
|
@ -33,8 +33,8 @@ describe 'ProjectCreationHandler', ->
|
|||
constructor:(options)->
|
||||
{@name} = options
|
||||
@ProjectEntityHandler =
|
||||
addDoc: sinon.stub().callsArgWith(4, null, {_id: docId})
|
||||
addFile: sinon.stub().callsArg(4)
|
||||
addDoc: sinon.stub().callsArgWith(5, null, {_id: docId})
|
||||
addFile: sinon.stub().callsArg(5)
|
||||
setRootDoc: sinon.stub().callsArg(2)
|
||||
@ProjectDetailsHandler =
|
||||
validateProjectName: sinon.stub().yields()
|
||||
|
@ -149,7 +149,7 @@ describe 'ProjectCreationHandler', ->
|
|||
.should.equal true
|
||||
|
||||
it 'should insert main.tex', ->
|
||||
@ProjectEntityHandler.addDoc.calledWith(project_id, rootFolderId, "main.tex", ["mainbasic.tex", "lines"])
|
||||
@ProjectEntityHandler.addDoc.calledWith(project_id, rootFolderId, "main.tex", ["mainbasic.tex", "lines"], ownerId)
|
||||
.should.equal true
|
||||
|
||||
it 'should set the main doc id', ->
|
||||
|
@ -180,19 +180,20 @@ describe 'ProjectCreationHandler', ->
|
|||
|
||||
it 'should insert main.tex', ->
|
||||
@ProjectEntityHandler.addDoc
|
||||
.calledWith(project_id, rootFolderId, "main.tex", ["main.tex", "lines"])
|
||||
.calledWith(project_id, rootFolderId, "main.tex", ["main.tex", "lines"], ownerId)
|
||||
.should.equal true
|
||||
|
||||
it 'should insert references.bib', ->
|
||||
@ProjectEntityHandler.addDoc
|
||||
.calledWith(project_id, rootFolderId, "references.bib", ["references.bib", "lines"])
|
||||
.calledWith(project_id, rootFolderId, "references.bib", ["references.bib", "lines"], ownerId)
|
||||
.should.equal true
|
||||
|
||||
it 'should insert universe.jpg', ->
|
||||
@ProjectEntityHandler.addFile
|
||||
.calledWith(
|
||||
project_id, rootFolderId, "universe.jpg",
|
||||
Path.resolve(__dirname + "/../../../../app/templates/project_files/universe.jpg")
|
||||
Path.resolve(__dirname + "/../../../../app/templates/project_files/universe.jpg"),
|
||||
ownerId
|
||||
)
|
||||
.should.equal true
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ describe 'ProjectDuplicator', ->
|
|||
@projectOptionsHandler =
|
||||
setCompiler : sinon.stub()
|
||||
@entityHandler =
|
||||
addDocWithProject: sinon.stub().callsArgWith(4, null, {name:"somDoc"})
|
||||
copyFileFromExistingProjectWithProject: sinon.stub().callsArgWith(4)
|
||||
addDocWithProject: sinon.stub().callsArgWith(5, null, {name:"somDoc"})
|
||||
copyFileFromExistingProjectWithProject: sinon.stub().callsArgWith(5)
|
||||
setRootDoc: sinon.stub()
|
||||
addFolderWithProject: sinon.stub().callsArgWith(3, null, @newFolder)
|
||||
|
||||
|
@ -112,13 +112,13 @@ describe 'ProjectDuplicator', ->
|
|||
done()
|
||||
|
||||
it 'should use the same compiler', (done)->
|
||||
@entityHandler.addDocWithProject.callsArgWith(4, null, @rootFolder.docs[0])
|
||||
@entityHandler.addDocWithProject.callsArgWith(5, null, @rootFolder.docs[0], @owner._id)
|
||||
@duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
|
||||
@projectOptionsHandler.setCompiler.calledWith(@stubbedNewProject._id, @project.compiler).should.equal true
|
||||
done()
|
||||
|
||||
it 'should use the same root doc', (done)->
|
||||
@entityHandler.addDocWithProject.callsArgWith(4, null, @rootFolder.docs[0])
|
||||
@entityHandler.addDocWithProject.callsArgWith(5, null, @rootFolder.docs[0], @owner._id)
|
||||
@duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
|
||||
@entityHandler.setRootDoc.calledWith(@stubbedNewProject._id, @rootFolder.docs[0]._id).should.equal true
|
||||
done()
|
||||
|
@ -139,14 +139,26 @@ describe 'ProjectDuplicator', ->
|
|||
it 'should copy all the docs', (done)->
|
||||
@duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
|
||||
@DocstoreManager.getAllDocs.calledWith(@old_project_id).should.equal true
|
||||
@entityHandler.addDocWithProject.calledWith(@stubbedNewProject, @stubbedNewProject.rootFolder[0]._id, @doc0.name, @doc0_lines).should.equal true
|
||||
@entityHandler.addDocWithProject.calledWith(@stubbedNewProject, @newFolder._id, @doc1.name, @doc1_lines).should.equal true
|
||||
@entityHandler.addDocWithProject.calledWith(@stubbedNewProject, @newFolder._id, @doc2.name, @doc2_lines).should.equal true
|
||||
@entityHandler.addDocWithProject
|
||||
.calledWith(@stubbedNewProject, @stubbedNewProject.rootFolder[0]._id, @doc0.name, @doc0_lines, @owner._id)
|
||||
.should.equal true
|
||||
@entityHandler.addDocWithProject
|
||||
.calledWith(@stubbedNewProject, @newFolder._id, @doc1.name, @doc1_lines, @owner._id)
|
||||
.should.equal true
|
||||
@entityHandler.addDocWithProject
|
||||
.calledWith(@stubbedNewProject, @newFolder._id, @doc2.name, @doc2_lines, @owner._id)
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
it 'should copy all the files', (done)->
|
||||
@duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
|
||||
@entityHandler.copyFileFromExistingProjectWithProject.calledWith(@stubbedNewProject, @stubbedNewProject.rootFolder[0]._id, @project._id, @rootFolder.fileRefs[0]).should.equal true
|
||||
@entityHandler.copyFileFromExistingProjectWithProject.calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level1folder.fileRefs[0]).should.equal true
|
||||
@entityHandler.copyFileFromExistingProjectWithProject.calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level2folder.fileRefs[0]).should.equal true
|
||||
@entityHandler.copyFileFromExistingProjectWithProject
|
||||
.calledWith(@stubbedNewProject, @stubbedNewProject.rootFolder[0]._id, @project._id, @rootFolder.fileRefs[0], @owner._id)
|
||||
.should.equal true
|
||||
@entityHandler.copyFileFromExistingProjectWithProject
|
||||
.calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level1folder.fileRefs[0], @owner._id)
|
||||
.should.equal true
|
||||
@entityHandler.copyFileFromExistingProjectWithProject
|
||||
.calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level2folder.fileRefs[0], @owner._id)
|
||||
.should.equal true
|
||||
done()
|
||||
|
|
|
@ -17,9 +17,10 @@ describe 'ProjectEntityHandler', ->
|
|||
userId = 1234
|
||||
|
||||
beforeEach ->
|
||||
@fileUrl = 'filestore.example.com/file'
|
||||
@FileStoreHandler =
|
||||
uploadFileFromDisk:(project_id, fileRef, localImagePath, callback)->callback()
|
||||
copyFile: sinon.stub().callsArgWith(4, null)
|
||||
uploadFileFromDisk: sinon.stub().callsArgWith(3, null, @fileUrl)
|
||||
copyFile: sinon.stub().callsArgWith(4, null, @fileUrl)
|
||||
@tpdsUpdateSender =
|
||||
addDoc:sinon.stub().callsArg(1)
|
||||
addFile:sinon.stub().callsArg(1)
|
||||
|
@ -67,6 +68,9 @@ describe 'ProjectEntityHandler', ->
|
|||
findElement : sinon.stub()
|
||||
@settings =
|
||||
maxEntitiesPerProject:200
|
||||
@documentUpdaterHandler =
|
||||
updateProjectStructure: sinon.stub().yields()
|
||||
deleteDoc: sinon.stub().callsArg(2)
|
||||
@ProjectEntityHandler = SandboxedModule.require modulePath, requires:
|
||||
'../../models/Project': Project:@ProjectModel
|
||||
'../../models/Doc': Doc:@DocModel
|
||||
|
@ -75,7 +79,7 @@ describe 'ProjectEntityHandler', ->
|
|||
'../FileStore/FileStoreHandler':@FileStoreHandler
|
||||
'../ThirdPartyDataStore/TpdsUpdateSender':@tpdsUpdateSender
|
||||
'./ProjectLocator': @projectLocator
|
||||
'../../Features/DocumentUpdater/DocumentUpdaterHandler':@documentUpdaterHandler = {}
|
||||
'../../Features/DocumentUpdater/DocumentUpdaterHandler':@documentUpdaterHandler
|
||||
'../Docstore/DocstoreManager': @DocstoreManager = {}
|
||||
'logger-sharelatex': @logger = {log:sinon.stub(), error: sinon.stub(), err:->}
|
||||
'./ProjectUpdateHandler': @projectUpdater
|
||||
|
@ -184,7 +188,6 @@ describe 'ProjectEntityHandler', ->
|
|||
describe "_cleanUpEntity", ->
|
||||
beforeEach ->
|
||||
@entity_id = "4eecaffcbffa66588e000009"
|
||||
@documentUpdaterHandler.deleteDoc = sinon.stub().callsArg(2)
|
||||
@FileStoreHandler.deleteFile = sinon.stub().callsArg(2)
|
||||
@ProjectEntityHandler.unsetRootDoc = sinon.stub().callsArg(1)
|
||||
|
||||
|
@ -240,7 +243,6 @@ describe 'ProjectEntityHandler', ->
|
|||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, path: @pathAfterMove)
|
||||
@ProjectGetter.getProject.callsArgWith(2, null, @project)
|
||||
@tpdsUpdateSender.moveEntity = sinon.stub()
|
||||
@documentUpdaterHandler.updateProjectStructure = sinon.stub().callsArg(6)
|
||||
@ProjectEntityHandler.getAllEntitiesFromProject = sinon.stub()
|
||||
@ProjectEntityHandler.getAllEntitiesFromProject
|
||||
.onFirstCall()
|
||||
|
@ -272,7 +274,7 @@ describe 'ProjectEntityHandler', ->
|
|||
|
||||
it "should should send the update to the doc updater", ->
|
||||
@documentUpdaterHandler.updateProjectStructure
|
||||
.calledWith(project_id, userId, @oldDocs, @newDocs, @oldFiles, @newFiles)
|
||||
.calledWith(project_id, userId, {@oldDocs, @newDocs, @oldFiles, @newFiles})
|
||||
.should.equal true
|
||||
|
||||
it 'should remove the element from its current position', ->
|
||||
|
@ -324,7 +326,7 @@ describe 'ProjectEntityHandler', ->
|
|||
|
||||
it "should should send the update to the doc updater", ->
|
||||
@documentUpdaterHandler.updateProjectStructure
|
||||
.calledWith(project_id, userId, @oldDocs, @newDocs, @oldFiles, @newFiles)
|
||||
.calledWith(project_id, userId, {@oldDocs, @newDocs, @oldFiles, @newFiles})
|
||||
.should.equal true
|
||||
|
||||
it 'should remove the element from its current position', ->
|
||||
|
@ -455,7 +457,7 @@ describe 'ProjectEntityHandler', ->
|
|||
@tpdsUpdateSender.addDoc = sinon.stub().callsArg(1)
|
||||
@DocstoreManager.updateDoc = sinon.stub().yields(null, true, 0)
|
||||
|
||||
@ProjectEntityHandler.addDoc project_id, folder_id, @name, @lines, @callback
|
||||
@ProjectEntityHandler.addDoc project_id, folder_id, @name, @lines, userId, @callback
|
||||
|
||||
# Created doc
|
||||
@doc = @ProjectEntityHandler._putElement.args[0][2]
|
||||
|
@ -484,6 +486,16 @@ describe 'ProjectEntityHandler', ->
|
|||
.calledWith(project_id, @doc._id.toString(), @lines)
|
||||
.should.equal true
|
||||
|
||||
it "should should send the change in project structure to the doc updater", () ->
|
||||
newDocs = [
|
||||
doc: @doc
|
||||
path: @path
|
||||
docLines: @lines.join('\n')
|
||||
]
|
||||
@documentUpdaterHandler.updateProjectStructure
|
||||
.calledWith(project_id, userId, {newDocs})
|
||||
.should.equal true
|
||||
|
||||
describe "restoreDoc", ->
|
||||
beforeEach ->
|
||||
@name = "doc-name"
|
||||
|
@ -512,7 +524,10 @@ describe 'ProjectEntityHandler', ->
|
|||
describe 'addFile', ->
|
||||
fileName = "something.jpg"
|
||||
beforeEach ->
|
||||
@fileSystemPath = "somehintg"
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem: @fileSystemPath}})
|
||||
@filePath = "somewhere"
|
||||
|
||||
it 'should upload it via the FileStoreHandler', (done)->
|
||||
@FileStoreHandler.uploadFileFromDisk = (passedProject_id, file_id, filePath, callback)=>
|
||||
file_id.should.equal "file_id"
|
||||
|
@ -520,7 +535,7 @@ describe 'ProjectEntityHandler', ->
|
|||
filePath.should.equal @filePath
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, @filePath, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, @filePath, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
it 'should put file into folder by calling put element', (done)->
|
||||
@ProjectEntityHandler._putElement = (passedProject, passedFolder_id, passedFileRef, passedType, callback)->
|
||||
|
@ -530,11 +545,10 @@ describe 'ProjectEntityHandler', ->
|
|||
passedType.should.equal 'file'
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
it 'should return doc and parent folder', (done)->
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem:"somehintg"}})
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, userId, (err, fileRef, parentFolder)->
|
||||
parentFolder.should.equal folder_id
|
||||
fileRef.name.should.equal fileName
|
||||
done()
|
||||
|
@ -554,33 +568,45 @@ describe 'ProjectEntityHandler', ->
|
|||
options.rev.should.equal 0
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
describe 'replacing a file', ->
|
||||
it "should should send the change in project structure to the doc updater", (done) ->
|
||||
@documentUpdaterHandler.updateProjectStructure = (passed_project_id, passed_user_id, changes) =>
|
||||
passed_project_id.should.equal project_id
|
||||
passed_user_id.should.equal userId
|
||||
{ newFiles } = changes
|
||||
newFiles.length.should.equal 1
|
||||
newFile = newFiles[0]
|
||||
newFile.file.name.should.equal fileName
|
||||
newFile.path.should.equal @fileSystemPath
|
||||
newFile.url.should.equal @fileUrl
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.addFile project_id, folder_id, fileName, {}, userId, () ->
|
||||
|
||||
describe 'replaceFile', ->
|
||||
beforeEach ->
|
||||
@projectLocator
|
||||
@file_id = "file_id_here"
|
||||
@fsPath = "fs_path_here.png"
|
||||
@fileRef = {rev:3, _id:@file_id}
|
||||
@filePaths = {fileSystem:"/folder1/file.png", mongo:"folder.1.files.somewhere"}
|
||||
@fileRef = {rev:3, _id: @file_id, name: @fileName = "fileName"}
|
||||
@filePaths = {fileSystem: @fileSystemPath="/folder1/file.png", mongo:"folder.1.files.somewhere"}
|
||||
@projectLocator.findElement = sinon.stub().callsArgWith(1, null, @fileRef, @filePaths)
|
||||
@ProjectModel.update = (_, __, ___, cb)-> cb()
|
||||
@ProjectModel.findOneAndUpdate = sinon.stub().callsArgWith(3)
|
||||
@ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, @project)
|
||||
|
||||
it 'should find the file', (done)->
|
||||
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, =>
|
||||
@projectLocator.findElement.calledWith({element_id:@file_id, type:"file", project_id:project_id}).should.equal true
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
@projectLocator.findElement
|
||||
.calledWith({element_id:@file_id, type:"file", project: @project})
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
it 'should tell the file store handler to upload the file from disk', (done)->
|
||||
@FileStoreHandler.uploadFileFromDisk = sinon.stub().callsArgWith(3)
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, =>
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
@FileStoreHandler.uploadFileFromDisk.calledWith(project_id, @file_id, @fsPath).should.equal true
|
||||
done()
|
||||
|
||||
|
||||
it 'should send the file to the tpds with an incremented rev', (done)->
|
||||
@tpdsUpdateSender.addFile = (options)=>
|
||||
options.project_id.should.equal project_id
|
||||
|
@ -590,26 +616,39 @@ describe 'ProjectEntityHandler', ->
|
|||
options.rev.should.equal @fileRef.rev + 1
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, =>
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
|
||||
it 'should inc the rev id', (done)->
|
||||
@ProjectModel.update = (conditions, update, options, callback)=>
|
||||
@ProjectModel.findOneAndUpdate = (conditions, update, options, callback)=>
|
||||
conditions._id.should.equal project_id
|
||||
update.$inc["#{@filePaths.mongo}.rev"].should.equal 1
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, =>
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
|
||||
it 'should update the created at date', (done)->
|
||||
d = new Date()
|
||||
@ProjectModel.update = (conditions, update, options, callback)=>
|
||||
@ProjectModel.findOneAndUpdate = (conditions, update, options, callback)=>
|
||||
conditions._id.should.equal project_id
|
||||
differenceInMs = update.$set["#{@filePaths.mongo}.created"].getTime() - d.getTime()
|
||||
differenceInMs.should.be.below(20)
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, =>
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
|
||||
it "should should send the old and new project structure to the doc updater", (done) ->
|
||||
@documentUpdaterHandler.updateProjectStructure = (passed_project_id, passed_user_id, changes) =>
|
||||
passed_project_id.should.equal project_id
|
||||
passed_user_id.should.equal userId
|
||||
{ newFiles } = changes
|
||||
newFiles.length.should.equal 1
|
||||
newFile = newFiles[0]
|
||||
newFile.file.name.should.equal @fileName
|
||||
newFile.path.should.equal @fileSystemPath
|
||||
newFile.url.should.equal @fileUrl
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.replaceFile project_id, @file_id, @fsPath, userId, =>
|
||||
|
||||
describe 'addFolder', ->
|
||||
folderName = "folder1234"
|
||||
|
@ -943,19 +982,19 @@ describe 'ProjectEntityHandler', ->
|
|||
@ProjectModel.update.calledWith({_id : @project_id}, {$unset : {rootDoc_id: true}})
|
||||
.should.equal true
|
||||
|
||||
describe 'copyFileFromExistingProject', ->
|
||||
describe 'copyFileFromExistingProjectWithProject', ->
|
||||
fileName = "something.jpg"
|
||||
filePath = "dumpFolder/somewhere/image.jpeg"
|
||||
oldProject_id = "123kljadas"
|
||||
oldFileRef = {name:fileName, _id:"oldFileRef"}
|
||||
beforeEach ->
|
||||
@ProjectGetter.getProject = (project_id, fields, callback)=> callback(null, {name:@project.name, _id:@project._id})
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem:"somehintg"}})
|
||||
|
||||
beforeEach ->
|
||||
@fileSystemPath = "somehintg"
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem: @fileSystemPath}})
|
||||
|
||||
it 'should copy the file in FileStoreHandler', (done)->
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem:"somehintg"}})
|
||||
@ProjectEntityHandler.copyFileFromExistingProject project_id, folder_id, oldProject_id, oldFileRef, (err, fileRef, parentFolder)=>
|
||||
@ProjectEntityHandler.copyFileFromExistingProjectWithProject @project, folder_id, oldProject_id, oldFileRef, userId, (err, fileRef, parentFolder)=>
|
||||
@FileStoreHandler.copyFile.calledWith(oldProject_id, oldFileRef._id, project_id, fileRef._id).should.equal true
|
||||
done()
|
||||
|
||||
|
@ -967,10 +1006,10 @@ describe 'ProjectEntityHandler', ->
|
|||
passedType.should.equal 'file'
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.copyFileFromExistingProject project_id, folder_id, oldProject_id, oldFileRef, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.copyFileFromExistingProjectWithProject @project, folder_id, oldProject_id, oldFileRef, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
it 'should return doc and parent folder', (done)->
|
||||
@ProjectEntityHandler.copyFileFromExistingProject project_id, folder_id, oldProject_id, oldFileRef, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.copyFileFromExistingProjectWithProject @project, folder_id, oldProject_id, oldFileRef, userId, (err, fileRef, parentFolder)->
|
||||
parentFolder.should.equal folder_id
|
||||
fileRef.name.should.equal fileName
|
||||
done()
|
||||
|
@ -990,8 +1029,21 @@ describe 'ProjectEntityHandler', ->
|
|||
options.rev.should.equal 0
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.copyFileFromExistingProject project_id, folder_id, oldProject_id, oldFileRef, (err, fileRef, parentFolder)->
|
||||
@ProjectEntityHandler.copyFileFromExistingProjectWithProject @project, folder_id, oldProject_id, oldFileRef, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
it "should should send the change in project structure to the doc updater", (done) ->
|
||||
@documentUpdaterHandler.updateProjectStructure = (passed_project_id, passed_user_id, changes) =>
|
||||
passed_project_id.should.equal project_id
|
||||
passed_user_id.should.equal userId
|
||||
{ newFiles } = changes
|
||||
newFiles.length.should.equal 1
|
||||
newFile = newFiles[0]
|
||||
newFile.file.name.should.equal fileName
|
||||
newFile.path.should.equal @fileSystemPath
|
||||
newFile.url.should.equal @fileUrl
|
||||
done()
|
||||
|
||||
@ProjectEntityHandler.copyFileFromExistingProjectWithProject @project, folder_id, oldProject_id, oldFileRef, userId, (err, fileRef, parentFolder)->
|
||||
|
||||
describe "renameEntity", ->
|
||||
beforeEach ->
|
||||
|
@ -1012,12 +1064,12 @@ describe 'ProjectEntityHandler', ->
|
|||
@projectLocator.findElement = sinon.stub().callsArgWith(1, null, @entity = { _id: @entity_id, name:"old.tex", rev:4 }, @path)
|
||||
@tpdsUpdateSender.moveEntity = sinon.stub()
|
||||
@ProjectModel.findOneAndUpdate = sinon.stub().callsArgWith(3, null, @project)
|
||||
@documentUpdaterHandler.updateProjectStructure = sinon.stub().callsArg(6)
|
||||
@documentUpdaterHandler.updateProjectStructure = sinon.stub().yields()
|
||||
|
||||
it "should should send the old and new project structure to the doc updater", (done) ->
|
||||
@ProjectEntityHandler.renameEntity project_id, @entity_id, @entityType, @newName, userId, =>
|
||||
@documentUpdaterHandler.updateProjectStructure
|
||||
.calledWith(project_id, userId, @oldDocs, @newDocs, @oldFiles, @newFiles)
|
||||
.calledWith(project_id, userId, {@oldDocs, @newDocs, @oldFiles, @newFiles})
|
||||
.should.equal true
|
||||
done()
|
||||
|
||||
|
|
|
@ -63,11 +63,11 @@ describe 'UpdateMerger :', ->
|
|||
file_id = "1231"
|
||||
@projectLocator.findElementByPath = (_, __, cb)->cb(null, {_id:file_id})
|
||||
@FileTypeManager.isBinary.callsArgWith(2, null, true)
|
||||
@updateMerger.p.processFile = sinon.stub().callsArgWith(5)
|
||||
@updateMerger.p.processFile = sinon.stub().callsArgWith(6)
|
||||
filePath = "/folder/file1.png"
|
||||
|
||||
@updateMerger.mergeUpdate @user_id, @project_id, filePath, @update, @source, =>
|
||||
@updateMerger.p.processFile.calledWith(@project_id, file_id, @fsPath, filePath, @source).should.equal true
|
||||
@updateMerger.p.processFile.calledWith(@project_id, file_id, @fsPath, filePath, @source, @user_id).should.equal true
|
||||
@FileTypeManager.isBinary.calledWith(filePath, @fsPath).should.equal true
|
||||
@fs.unlink.calledWith(@fsPath).should.equal true
|
||||
done()
|
||||
|
@ -97,7 +97,7 @@ describe 'UpdateMerger :', ->
|
|||
path = "folder1/folder2/#{docName}"
|
||||
@editorController.mkdirp = sinon.stub().withArgs(@project_id).callsArgWith(2, null, [folder], folder)
|
||||
@editorController.addDoc = ->
|
||||
mock = sinon.mock(@editorController).expects("addDoc").withArgs(@project_id, folder._id, docName, @splitDocLines, @source).callsArg(5)
|
||||
mock = sinon.mock(@editorController).expects("addDoc").withArgs(@project_id, folder._id, docName, @splitDocLines, @source, @user_id).callsArg(6)
|
||||
|
||||
@update.write(@docLines)
|
||||
@update.end()
|
||||
|
@ -114,22 +114,22 @@ describe 'UpdateMerger :', ->
|
|||
@folder = _id: @folder_id
|
||||
@fileName = "file.png"
|
||||
@fsPath = "fs/path.tex"
|
||||
@editorController.addFile = sinon.stub().callsArg(5)
|
||||
@editorController.replaceFile = sinon.stub().callsArg(4)
|
||||
@editorController.addFile = sinon.stub().callsArg(6)
|
||||
@editorController.replaceFile = sinon.stub().callsArg(5)
|
||||
@editorController.deleteEntity = sinon.stub()
|
||||
@editorController.mkdirp = sinon.stub().withArgs(@project_id).callsArgWith(2, null, [@folder], @folder)
|
||||
@updateMerger.p.writeStreamToDisk = sinon.stub().withArgs(@project_id, @file_id, @update).callsArgWith(3, null, @fsPath)
|
||||
|
||||
it 'should replace file if the file already exists', (done)->
|
||||
@updateMerger.p.processFile @project_id, @file_id, @fsPath, @path, @source, =>
|
||||
@updateMerger.p.processFile @project_id, @file_id, @fsPath, @path, @source, @user_id, =>
|
||||
@editorController.addFile.called.should.equal false
|
||||
@editorController.replaceFile.calledWith(@project_id, @file_id, @fsPath, @source).should.equal true
|
||||
@editorController.replaceFile.calledWith(@project_id, @file_id, @fsPath, @source, @user_id).should.equal true
|
||||
done()
|
||||
|
||||
it 'should call add file if the file does not exist', (done)->
|
||||
@updateMerger.p.processFile @project_id, undefined, @fsPath, @path, @source, =>
|
||||
@updateMerger.p.processFile @project_id, undefined, @fsPath, @path, @source, @user_id, =>
|
||||
@editorController.mkdirp.calledWith(@project_id, "folder/").should.equal true
|
||||
@editorController.addFile.calledWith(@project_id, @folder_id, @fileName, @fsPath, @source).should.equal true
|
||||
@editorController.addFile.calledWith(@project_id, @folder_id, @fileName, @fsPath, @source, @user_id).should.equal true
|
||||
@editorController.replaceFile.called.should.equal false
|
||||
done()
|
||||
|
||||
|
|
|
@ -44,14 +44,14 @@ describe "FileSystemImportManager", ->
|
|||
|
||||
describe "with replace set to false", ->
|
||||
beforeEach ->
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(5)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(6)
|
||||
@FileSystemImportManager.addDoc @user_id, @project_id, @folder_id, @name, @path_on_disk, false, @callback
|
||||
|
||||
it "should read the file from disk", ->
|
||||
@fs.readFile.calledWith(@path_on_disk, "utf8").should.equal true
|
||||
|
||||
it "should insert the doc", ->
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload")
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "with windows line ending", ->
|
||||
|
@ -59,11 +59,11 @@ describe "FileSystemImportManager", ->
|
|||
@docContent = "one\r\ntwo\r\nthree"
|
||||
@docLines = ["one", "two", "three"]
|
||||
@fs.readFile = sinon.stub().callsArgWith(2, null, @docContent)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(5)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(6)
|
||||
@FileSystemImportManager.addDoc @user_id, @project_id, @folder_id, @name, @path_on_disk, false, @callback
|
||||
|
||||
it "should strip the \\r characters before adding", ->
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload")
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "with replace set to true", ->
|
||||
|
@ -76,7 +76,7 @@ describe "FileSystemImportManager", ->
|
|||
}]
|
||||
}
|
||||
@ProjectLocator.findElement = sinon.stub().callsArgWith(1, null, @folder)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(5)
|
||||
@EditorController.addDocWithoutLock = sinon.stub().callsArg(6)
|
||||
@FileSystemImportManager.addDoc @user_id, @project_id, @folder_id, @name, @path_on_disk, true, @callback
|
||||
|
||||
it "should look up the folder", ->
|
||||
|
@ -85,7 +85,7 @@ describe "FileSystemImportManager", ->
|
|||
.should.equal true
|
||||
|
||||
it "should insert the doc", ->
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload")
|
||||
@EditorController.addDocWithoutLock.calledWith(@project_id, @folder_id, @name, @docLines, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "when the doc does exist", ->
|
||||
|
@ -114,12 +114,12 @@ describe "FileSystemImportManager", ->
|
|||
|
||||
describe "addFile with replace set to false", ->
|
||||
beforeEach ->
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArg(5)
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArg(6)
|
||||
@FileSystemImportManager._isSafeOnFileSystem = sinon.stub().callsArgWith(1, null, true)
|
||||
@FileSystemImportManager.addFile @user_id, @project_id, @folder_id, @name, @path_on_disk, false, @callback
|
||||
|
||||
it "should add the file", ->
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @name, @path_on_disk, "upload")
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @name, @path_on_disk, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "addFile with symlink", ->
|
||||
|
@ -144,7 +144,7 @@ describe "FileSystemImportManager", ->
|
|||
}
|
||||
@FileSystemImportManager._isSafeOnFileSystem = sinon.stub().callsArgWith(1, null, true)
|
||||
@ProjectLocator.findElement = sinon.stub().callsArgWith(1, null, @folder)
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArg(5)
|
||||
@EditorController.addFileWithoutLock = sinon.stub().callsArg(6)
|
||||
@FileSystemImportManager.addFile @user_id, @project_id, @folder_id, @name, @path_on_disk, true, @callback
|
||||
|
||||
it "should look up the folder", ->
|
||||
|
@ -153,7 +153,7 @@ describe "FileSystemImportManager", ->
|
|||
.should.equal true
|
||||
|
||||
it "should add the file", ->
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @name, @path_on_disk, "upload")
|
||||
@EditorController.addFileWithoutLock.calledWith(@project_id, @folder_id, @name, @path_on_disk, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "when the file does exist", ->
|
||||
|
@ -169,7 +169,7 @@ describe "FileSystemImportManager", ->
|
|||
}
|
||||
@FileSystemImportManager._isSafeOnFileSystem = sinon.stub().callsArgWith(1, null, true)
|
||||
@ProjectLocator.findElement = sinon.stub().callsArgWith(1, null, @folder)
|
||||
@EditorController.replaceFile = sinon.stub().callsArg(4)
|
||||
@EditorController.replaceFile = sinon.stub().callsArg(5)
|
||||
@FileSystemImportManager.addFile @user_id, @project_id, @folder_id, @name, @path_on_disk, true, @callback
|
||||
|
||||
it "should look up the folder", ->
|
||||
|
@ -178,7 +178,7 @@ describe "FileSystemImportManager", ->
|
|||
.should.equal true
|
||||
|
||||
it "should replace the file", ->
|
||||
@EditorController.replaceFile.calledWith(@project_id, @file_id, @path_on_disk, "upload")
|
||||
@EditorController.replaceFile.calledWith(@project_id, @file_id, @path_on_disk, "upload", @user_id)
|
||||
.should.equal true
|
||||
|
||||
describe "addFolder", ->
|
||||
|
|
Loading…
Reference in a new issue