mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-25 02:00:10 +02:00
Merge pull request #286 from sharelatex/bg-prevent-duplicate-filenames
prevent duplicate filenames
This commit is contained in:
@@ -105,7 +105,7 @@ module.exports = EditorHttpController =
|
||||
else if error?.message == 'invalid element name'
|
||||
res.status(400).json(req.i18n.translate('invalid_file_name'))
|
||||
else if error?
|
||||
res.status(500).json(req.i18n.translate('generic_something_went_wrong'))
|
||||
next(error)
|
||||
else
|
||||
res.json doc
|
||||
|
||||
|
||||
@@ -170,7 +170,8 @@ module.exports = ProjectEntityHandler =
|
||||
if project_or_id._id? # project
|
||||
return cb(null, project_or_id)
|
||||
else # id
|
||||
return ProjectGetter.getProjectWithOnlyFolders project_or_id, cb
|
||||
# need to retrieve full project structure to check for duplicates
|
||||
return ProjectGetter.getProject project_or_id, {rootFolder:true, name:true}, cb
|
||||
getProject (error, project) ->
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for add doc"
|
||||
@@ -207,7 +208,7 @@ module.exports = ProjectEntityHandler =
|
||||
ProjectEntityHandler.addDoc project_id, null, name, lines, callback
|
||||
|
||||
addFileWithoutUpdatingHistory: (project_id, folder_id, fileName, path, userId, callback = (error, fileRef, folder_id, path, fileStoreUrl) ->)->
|
||||
ProjectGetter.getProjectWithOnlyFolders project_id, (err, project) ->
|
||||
ProjectGetter.getProject project_id, {rootFolder:true, name:true}, (err, project) ->
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for add file"
|
||||
return callback(err)
|
||||
@@ -229,6 +230,7 @@ module.exports = ProjectEntityHandler =
|
||||
|
||||
addFile: (project_id, folder_id, fileName, fsPath, userId, callback = (error, fileRef, folder_id) ->)->
|
||||
ProjectEntityHandler.addFileWithoutUpdatingHistory project_id, folder_id, fileName, fsPath, userId, (error, fileRef, folder_id, path, fileStoreUrl) ->
|
||||
return callback(error) if error?
|
||||
newFiles = [
|
||||
file: fileRef
|
||||
path: path
|
||||
@@ -340,7 +342,7 @@ module.exports = ProjectEntityHandler =
|
||||
callback(null, folders, lastFolder)
|
||||
|
||||
addFolder: (project_id, parentFolder_id, folderName, callback) ->
|
||||
ProjectGetter.getProjectWithOnlyFolders project_id, (err, project)=>
|
||||
ProjectGetter.getProject project_id, {rootFolder:true, name:true}, (err, project)=>
|
||||
if err?
|
||||
logger.err project_id:project_id, err:err, "error getting project for add folder"
|
||||
return callback(err)
|
||||
@@ -394,7 +396,7 @@ module.exports = ProjectEntityHandler =
|
||||
return callback(err) if err?
|
||||
projectLocator.findElement {project, element_id: entity_id, type: entityType}, (err, entity, entityPath)->
|
||||
return callback(err) if err?
|
||||
self._checkValidMove project, entityType, entityPath, destFolderId, (error) ->
|
||||
self._checkValidMove project, entityType, entity, entityPath, destFolderId, (error) ->
|
||||
return callback(error) if error?
|
||||
self.getAllEntitiesFromProject project, (error, oldDocs, oldFiles) =>
|
||||
return callback(error) if error?
|
||||
@@ -413,19 +415,20 @@ module.exports = ProjectEntityHandler =
|
||||
return callback(error) if error?
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldDocs, newDocs, oldFiles, newFiles}, callback
|
||||
|
||||
_checkValidMove: (project, entityType, entityPath, destFolderId, callback = (error) ->) ->
|
||||
return callback() if !entityType.match(/folder/)
|
||||
|
||||
_checkValidMove: (project, entityType, entity, entityPath, destFolderId, callback = (error) ->) ->
|
||||
projectLocator.findElement { project, element_id: destFolderId, type:"folder"}, (err, destEntity, destFolderPath) ->
|
||||
return callback(err) if err?
|
||||
logger.log destFolderPath: destFolderPath.fileSystem, folderPath: entityPath.fileSystem, "checking folder is not moving into child folder"
|
||||
isNestedFolder = destFolderPath.fileSystem.slice(0, entityPath.fileSystem.length) == entityPath.fileSystem
|
||||
if isNestedFolder
|
||||
callback(new Error("destination folder is a child folder of me"))
|
||||
else
|
||||
# check if there is already a doc/file/folder with the same name
|
||||
# in the destination folder
|
||||
ProjectEntityHandler.checkValidElementName destEntity, entity.name, (err)->
|
||||
return callback(err) if err?
|
||||
if entityType.match(/folder/)
|
||||
logger.log destFolderPath: destFolderPath.fileSystem, folderPath: entityPath.fileSystem, "checking folder is not moving into child folder"
|
||||
isNestedFolder = destFolderPath.fileSystem.slice(0, entityPath.fileSystem.length) == entityPath.fileSystem
|
||||
if isNestedFolder
|
||||
return callback(new Errors.InvalidNameError("destination folder is a child folder of me"))
|
||||
callback()
|
||||
|
||||
|
||||
deleteEntity: (project_id, entity_id, entityType, userId, callback = (error) ->)->
|
||||
self = @
|
||||
logger.log entity_id:entity_id, entityType:entityType, project_id:project_id, "deleting project entity"
|
||||
@@ -456,19 +459,22 @@ module.exports = ProjectEntityHandler =
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.getAllEntitiesFromProject project, (error, oldDocs, oldFiles) =>
|
||||
return callback(error) if error?
|
||||
projectLocator.findElement {project:project, element_id:entity_id, type:entityType}, (error, entity, entPath)=>
|
||||
projectLocator.findElement {project:project, element_id:entity_id, type:entityType}, (error, entity, entPath, parentFolder)=>
|
||||
return callback(error) if error?
|
||||
endPath = path.join(path.dirname(entPath.fileSystem), newName)
|
||||
conditions = {_id:project_id}
|
||||
update = "$set":{}
|
||||
namePath = entPath.mongo+".name"
|
||||
update["$set"][namePath] = newName
|
||||
tpdsUpdateSender.moveEntity({project_id:project_id, startPath:entPath.fileSystem, endPath:endPath, project_name:project.name, rev:entity.rev})
|
||||
Project.findOneAndUpdate conditions, update, { "new": true}, (error, newProject) ->
|
||||
# check if the new name already exists in the current folder
|
||||
ProjectEntityHandler.checkValidElementName parentFolder, newName, (error) =>
|
||||
return callback(error) if error?
|
||||
ProjectEntityHandler.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
|
||||
endPath = path.join(path.dirname(entPath.fileSystem), newName)
|
||||
conditions = {_id:project_id}
|
||||
update = "$set":{}
|
||||
namePath = entPath.mongo+".name"
|
||||
update["$set"][namePath] = newName
|
||||
tpdsUpdateSender.moveEntity({project_id:project_id, startPath:entPath.fileSystem, endPath:endPath, project_name:project.name, rev:entity.rev})
|
||||
Project.findOneAndUpdate conditions, update, { "new": true}, (error, newProject) ->
|
||||
return callback(error) if error?
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldDocs, newDocs, oldFiles, newFiles}, callback
|
||||
ProjectEntityHandler.getAllEntitiesFromProject newProject, (error, newDocs, newFiles) =>
|
||||
return callback(error) if error?
|
||||
DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldDocs, newDocs, oldFiles, newFiles}, callback
|
||||
|
||||
_cleanUpEntity: (project, entity, entityType, path, userId, callback = (error) ->) ->
|
||||
if(entityType.indexOf("file") != -1)
|
||||
@@ -606,19 +612,32 @@ module.exports = ProjectEntityHandler =
|
||||
newPath =
|
||||
fileSystem: "#{path.fileSystem}/#{element.name}"
|
||||
mongo: path.mongo
|
||||
id = element._id+''
|
||||
element._id = require('mongoose').Types.ObjectId(id)
|
||||
conditions = _id:project._id
|
||||
mongopath = "#{path.mongo}.#{type}"
|
||||
update = "$push":{}
|
||||
update["$push"][mongopath] = element
|
||||
logger.log project_id: project._id, element_id: element._id, fileType: type, folder_id: folder_id, mongopath:mongopath, "adding element to project"
|
||||
Project.findOneAndUpdate conditions, update, {"new": true}, (err, project)->
|
||||
if err?
|
||||
logger.err err: err, project_id: project._id, 'error saving in putElement project'
|
||||
return callback(err)
|
||||
callback(err, {path:newPath}, project)
|
||||
ProjectEntityHandler.checkValidElementName folder, element.name, (err) =>
|
||||
return callback(err) if err?
|
||||
id = element._id+''
|
||||
element._id = require('mongoose').Types.ObjectId(id)
|
||||
conditions = _id:project._id
|
||||
mongopath = "#{path.mongo}.#{type}"
|
||||
update = "$push":{}
|
||||
update["$push"][mongopath] = element
|
||||
logger.log project_id: project._id, element_id: element._id, fileType: type, folder_id: folder_id, mongopath:mongopath, "adding element to project"
|
||||
Project.findOneAndUpdate conditions, update, {"new": true}, (err, project)->
|
||||
if err?
|
||||
logger.err err: err, project_id: project._id, 'error saving in putElement project'
|
||||
return callback(err)
|
||||
callback(err, {path:newPath}, project)
|
||||
|
||||
checkValidElementName: (folder, name, callback = (err) ->) ->
|
||||
# check if the name is already taken by a doc, file or
|
||||
# folder. If so, return an error "file already exists".
|
||||
err = new Errors.InvalidNameError("file already exists")
|
||||
for doc in folder?.docs or []
|
||||
return callback(err) if doc.name is name
|
||||
for file in folder?.fileRefs or []
|
||||
return callback(err) if file.name is name
|
||||
for folder in folder?.folders or []
|
||||
return callback(err) if folder.name is name
|
||||
callback()
|
||||
|
||||
confirmFolder = (project, folder_id, callback)->
|
||||
logger.log folder_id:folder_id, project_id:project._id, "confirming folder in project"
|
||||
|
||||
@@ -110,7 +110,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||
i.fa.fa-fw(ng-if="entity.type != 'folder'", ng-class="'fa-' + iconTypeFromName(entity.name)")
|
||||
span(
|
||||
ng-hide="entity.renaming"
|
||||
) {{ entity.name }}
|
||||
) {{ entity.renamingToName || entity.name }}
|
||||
span.rename-input
|
||||
input(
|
||||
ng-if="permissions.write",
|
||||
@@ -198,7 +198,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||
|
||||
span(
|
||||
ng-hide="entity.renaming"
|
||||
) {{ entity.name }}
|
||||
) {{ entity.renamingToName || entity.name }}
|
||||
span.rename-input
|
||||
input(
|
||||
ng-if="permissions.write",
|
||||
|
||||
@@ -321,7 +321,20 @@ define [
|
||||
|
||||
return null
|
||||
|
||||
existsInThisFolder: (folder, name) ->
|
||||
for entity in folder?.children or []
|
||||
return true if entity.name is name
|
||||
return false
|
||||
|
||||
nameExistsError: (message = "already exists") ->
|
||||
nameExists = @ide.$q.defer()
|
||||
nameExists.reject({data: message})
|
||||
return nameExists.promise
|
||||
|
||||
createDoc: (name, parent_folder = @getCurrentFolder()) ->
|
||||
# check if a doc/file/folder already exists with this name
|
||||
if @existsInThisFolder parent_folder, name
|
||||
return @nameExistsError()
|
||||
# We'll wait for the socket.io notification to actually
|
||||
# add the doc for us.
|
||||
@ide.$http.post "/project/#{@ide.project_id}/doc", {
|
||||
@@ -331,6 +344,9 @@ define [
|
||||
}
|
||||
|
||||
createFolder: (name, parent_folder = @getCurrentFolder()) ->
|
||||
# check if a doc/file/folder already exists with this name
|
||||
if @existsInThisFolder parent_folder, name
|
||||
return @nameExistsError()
|
||||
# We'll wait for the socket.io notification to actually
|
||||
# add the folder for us.
|
||||
return @ide.$http.post "/project/#{@ide.project_id}/folder", {
|
||||
@@ -341,12 +357,20 @@ define [
|
||||
|
||||
renameEntity: (entity, name, callback = (error) ->) ->
|
||||
return if entity.name == name
|
||||
if name.length < 150
|
||||
entity.name = name
|
||||
return @ide.$http.post "/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/rename", {
|
||||
name: entity.name,
|
||||
return if name.length >= 150
|
||||
# check if a doc/file/folder already exists with this name
|
||||
parent_folder = @getCurrentFolder()
|
||||
if @existsInThisFolder parent_folder, name
|
||||
return @nameExistsError()
|
||||
entity.renamingToName = name
|
||||
@ide.$http.post("/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/rename", {
|
||||
name: name,
|
||||
_csrf: window.csrfToken
|
||||
}
|
||||
})
|
||||
.then () ->
|
||||
entity.name = name
|
||||
.finally () ->
|
||||
entity.renamingToName = null
|
||||
|
||||
deleteEntity: (entity, callback = (error) ->) ->
|
||||
# We'll wait for the socket.io notification to
|
||||
@@ -362,11 +386,15 @@ define [
|
||||
# Abort move if the folder being moved (entity) has the parent_folder as child
|
||||
# since that would break the tree structure.
|
||||
return if @_isChildFolder(entity, parent_folder)
|
||||
@_moveEntityInScope(entity, parent_folder)
|
||||
return @ide.queuedHttp.post "/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/move", {
|
||||
# check if a doc/file/folder already exists with this name
|
||||
if @existsInThisFolder parent_folder, entity.name
|
||||
return @nameExistsError()
|
||||
# Wait for the http response before doing the move
|
||||
@ide.queuedHttp.post("/project/#{@ide.project_id}/#{entity.type}/#{entity.id}/move", {
|
||||
folder_id: parent_folder.id
|
||||
_csrf: window.csrfToken
|
||||
}
|
||||
}).then () =>
|
||||
@_moveEntityInScope(entity, parent_folder)
|
||||
|
||||
_isChildFolder: (parent_folder, child_folder) ->
|
||||
parent_path = @getEntityPath(parent_folder) or "" # null if root folder
|
||||
|
||||
@@ -69,6 +69,7 @@ define [
|
||||
.catch (response)->
|
||||
{ data } = response
|
||||
$scope.error = data
|
||||
$scope.state.inflight = false
|
||||
|
||||
$scope.cancel = () ->
|
||||
$modalInstance.dismiss('cancel')
|
||||
|
||||
@@ -28,6 +28,9 @@ define [
|
||||
|
||||
invalidModalShowing = false
|
||||
$scope.finishRenaming = () ->
|
||||
# avoid double events when blur and on-enter fire together
|
||||
return if !$scope.entity.renaming
|
||||
|
||||
name = $scope.inputs.name
|
||||
|
||||
if !name.match(new RegExp(ide.validFileRegex))
|
||||
|
||||
@@ -3,10 +3,11 @@ define [
|
||||
], (App) ->
|
||||
# We create and provide this as service so that we can access the global ide
|
||||
# from within other parts of the angular app.
|
||||
App.factory "ide", ["$http", "queuedHttp", "$modal", ($http, queuedHttp, $modal) ->
|
||||
App.factory "ide", ["$http", "queuedHttp", "$modal", "$q", ($http, queuedHttp, $modal, $q) ->
|
||||
ide = {}
|
||||
ide.$http = $http
|
||||
ide.queuedHttp = queuedHttp
|
||||
ide.$q = $q
|
||||
|
||||
@recentEvents = []
|
||||
ide.pushEvent = (type, meta = {}) =>
|
||||
|
||||
@@ -0,0 +1,448 @@
|
||||
async = require "async"
|
||||
expect = require("chai").expect
|
||||
sinon = require "sinon"
|
||||
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"
|
||||
|
||||
MockDocStoreApi = require './helpers/MockDocstoreApi'
|
||||
MockFileStoreApi = require './helpers/MockFileStoreApi'
|
||||
request = require "./helpers/request"
|
||||
User = require "./helpers/User"
|
||||
|
||||
describe "ProjectDuplicateNames", ->
|
||||
before (done) ->
|
||||
@owner = new User()
|
||||
@owner.login done
|
||||
@project = {}
|
||||
@callback = sinon.stub()
|
||||
|
||||
describe "creating a project from the example template", ->
|
||||
before (done) ->
|
||||
@owner.createProject "example-project", {template: "example"}, (error, project_id) =>
|
||||
throw error if error?
|
||||
@example_project_id = project_id
|
||||
@owner.getProject project_id, (error, project) =>
|
||||
@project = project
|
||||
@mainTexDoc = _.find(project.rootFolder[0].docs, (doc) -> doc.name is 'main.tex')
|
||||
@refBibDoc = _.find(project.rootFolder[0].docs, (doc) -> doc.name is 'references.bib')
|
||||
@imageFile = _.find(project.rootFolder[0].fileRefs, (file) -> file.name is 'universe.jpg')
|
||||
@rootFolderId = project.rootFolder[0]._id.toString()
|
||||
# create a folder called 'testfolder'
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "testfolder"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@testFolderId = body._id
|
||||
done()
|
||||
|
||||
it "should create a project", ->
|
||||
expect(@project.rootFolder[0].docs.length).to.equal(2)
|
||||
expect(@project.rootFolder[0].fileRefs.length).to.equal(1)
|
||||
|
||||
it "should create two docs in the docstore", ->
|
||||
docs = MockDocStoreApi.docs[@example_project_id]
|
||||
expect(Object.keys(docs).length).to.equal(2)
|
||||
|
||||
it "should create one file in the filestore", ->
|
||||
files = MockFileStoreApi.files[@example_project_id]
|
||||
expect(Object.keys(files).length).to.equal(1)
|
||||
|
||||
describe "for an existing doc", ->
|
||||
describe "trying to add a doc with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc"
|
||||
json:
|
||||
name: "main.tex"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to add a folder with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "main.tex"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to upload a file with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post
|
||||
uri: "/project/#{@example_project_id}/upload"
|
||||
json: true
|
||||
qs:
|
||||
folder_id: @rootFolderId
|
||||
qqfilename: "main.tex"
|
||||
formData:
|
||||
qqfile:
|
||||
value: fs.createReadStream Path.resolve(__dirname + '/../files/1pixel.png')
|
||||
options:
|
||||
filename: 'main.tex',
|
||||
contentType: 'image/png'
|
||||
, (err, res, body) =>
|
||||
@body = body
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@body.success).to.equal false
|
||||
|
||||
describe "trying to add a folder with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "main.tex"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to upload a file with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post
|
||||
uri: "/project/#{@example_project_id}/upload"
|
||||
json: true
|
||||
qs:
|
||||
folder_id: @rootFolderId
|
||||
qqfilename: "main.tex"
|
||||
formData:
|
||||
qqfile:
|
||||
value: fs.createReadStream Path.resolve(__dirname + '/../files/1pixel.png')
|
||||
options:
|
||||
filename: 'main.tex',
|
||||
contentType: 'image/png'
|
||||
, (err, res, body) =>
|
||||
@body = body
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@body.success).to.equal false
|
||||
|
||||
|
||||
describe "for an existing file", ->
|
||||
describe "trying to add a doc with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to add a folder with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to upload a file with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post
|
||||
uri: "/project/#{@example_project_id}/upload"
|
||||
json: true
|
||||
qs:
|
||||
folder_id: @rootFolderId
|
||||
qqfilename: "universe.jpg"
|
||||
formData:
|
||||
qqfile:
|
||||
value: fs.createReadStream Path.resolve(__dirname + '/../files/1pixel.png')
|
||||
options:
|
||||
filename: 'universe.jpg',
|
||||
contentType: 'image/jpeg'
|
||||
, (err, res, body) =>
|
||||
@body = body
|
||||
done()
|
||||
|
||||
it "should succeed (overwriting the file)", ->
|
||||
expect(@body.success).to.equal true
|
||||
|
||||
describe "for an existing folder", ->
|
||||
describe "trying to add a doc with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc"
|
||||
json:
|
||||
name: "testfolder"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to add a folder with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "testfolder"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to upload a file with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post
|
||||
uri: "/project/#{@example_project_id}/upload"
|
||||
json: true
|
||||
qs:
|
||||
folder_id: @rootFolderId
|
||||
qqfilename: "universe.jpg"
|
||||
formData:
|
||||
qqfile:
|
||||
value: fs.createReadStream Path.resolve(__dirname + '/../files/1pixel.png')
|
||||
options:
|
||||
filename: 'testfolder',
|
||||
contentType: 'image/jpeg'
|
||||
, (err, res, body) =>
|
||||
@body = body
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@body.success).to.equal false
|
||||
|
||||
|
||||
describe "for an existing doc", ->
|
||||
describe "trying to rename a doc to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc/#{@refBibDoc._id}/rename"
|
||||
json:
|
||||
name: "main.tex"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a folder to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder/#{@testFolderId}/rename"
|
||||
json:
|
||||
name: "main.tex"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a file to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/file/#{@imageFile._id}/rename"
|
||||
json:
|
||||
name: "main.tex"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
|
||||
describe "for an existing file", ->
|
||||
describe "trying to rename a doc to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc/#{@refBibDoc._id}/rename"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a folder to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder/#{@testFolderId}/rename"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a file to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/file/#{@imageFile._id}/rename"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
|
||||
describe "for an existing folder", ->
|
||||
describe "trying to rename a doc to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc/#{@refBibDoc._id}/rename"
|
||||
json:
|
||||
name: "testfolder"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a folder to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder/#{@testFolderId}/rename"
|
||||
json:
|
||||
name: "testfolder"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to rename a file to the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/file/#{@imageFile._id}/rename"
|
||||
json:
|
||||
name: "testfolder"
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with failure status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
|
||||
describe "for an existing folder with a file with the same name", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc"
|
||||
json:
|
||||
name: "main.tex"
|
||||
parent_folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc"
|
||||
json:
|
||||
name: "universe.jpg"
|
||||
parent_folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "otherFolder"
|
||||
parent_folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@subFolderId = body._id
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder"
|
||||
json:
|
||||
name: "otherFolder"
|
||||
parent_folder_id: @rootFolderId
|
||||
}, (err, res, body) =>
|
||||
@otherFolderId = body._id
|
||||
done()
|
||||
|
||||
describe "trying to move a doc into the folder", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/doc/#{@mainTexDoc._id}/move"
|
||||
json:
|
||||
folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to move a file into the folder", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/file/#{@imageFile._id}/move"
|
||||
json:
|
||||
folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to move a folder into the folder", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder/#{@otherFolderId}/move"
|
||||
json:
|
||||
folder_id: @testFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
|
||||
describe "trying to move a folder into a subfolder of itself", ->
|
||||
before (done) ->
|
||||
@owner.request.post {
|
||||
uri: "/project/#{@example_project_id}/folder/#{@testFolderId}/move"
|
||||
json:
|
||||
folder_id: @subFolderId
|
||||
}, (err, res, body) =>
|
||||
@res = res
|
||||
done()
|
||||
|
||||
it "should respond with 400 error status", ->
|
||||
expect(@res.statusCode).to.equal 400
|
||||
@@ -8,8 +8,11 @@ module.exports = MockFileStoreApi =
|
||||
app.post "/project/:project_id/file/:file_id", (req, res, next) =>
|
||||
req.on 'data', ->
|
||||
|
||||
req.on 'end', ->
|
||||
res.send 200
|
||||
req.on 'end', =>
|
||||
{project_id, file_id} = req.params
|
||||
@files[project_id] ?= {}
|
||||
@files[project_id][file_id] = { content : "test-file-content" }
|
||||
res.sendStatus 200
|
||||
|
||||
app.listen 3009, (error) ->
|
||||
throw error if error?
|
||||
|
||||
@@ -62,7 +62,7 @@ describe 'ProjectEntityHandler', ->
|
||||
@ProjectGetter =
|
||||
getProjectWithOnlyFolders : (project_id, callback)=> callback(null, @project)
|
||||
getProjectWithoutDocLines : (project_id, callback)=> callback(null, @project)
|
||||
getProject:sinon.stub()
|
||||
getProject: sinon.stub().callsArgWith(2, null, @project)
|
||||
@projectUpdater = markAsUpdated:sinon.stub()
|
||||
@projectLocator =
|
||||
findElement : sinon.stub()
|
||||
@@ -287,6 +287,8 @@ describe 'ProjectEntityHandler', ->
|
||||
@projectLocator.findElement = sinon.stub()
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: @docId, type: 'docs'})
|
||||
.callsArgWith(1, null, @doc, @path)
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: folder_id, type:"folder"},)
|
||||
.callsArgWith(1, null, @destFolder, @destFolderPath)
|
||||
@ProjectEntityHandler.moveEntity project_id, @docId, folder_id, "docs", userId, done
|
||||
|
||||
it 'should find the doc to move', ->
|
||||
@@ -315,6 +317,46 @@ describe 'ProjectEntityHandler', ->
|
||||
})
|
||||
.should.equal true
|
||||
|
||||
describe "moving a doc when another with the same name already exists", ->
|
||||
beforeEach () ->
|
||||
@docId = "4eecaffcbffa66588e000009"
|
||||
@doc = { name: "another-doc.tex", lines:["1234","312343d"], rev: "1234"}
|
||||
@path = {
|
||||
mongo:"folders[0]"
|
||||
fileSystem:"/old_folder/somewhere.txt"
|
||||
}
|
||||
@destFolder = { name: "folder", docs: [ {name:"another-doc.tex"} ] }
|
||||
@destFolderPath = {
|
||||
mongo: "folders[0]"
|
||||
fileSystem: "/dest_folder"
|
||||
}
|
||||
@projectLocator.findElement = sinon.stub()
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: @docId, type: 'docs'})
|
||||
.callsArgWith(1, null, @doc, @path)
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: folder_id, type:"folder"},)
|
||||
.callsArgWith(1, null, @destFolder, @destFolderPath)
|
||||
@callback = sinon.stub()
|
||||
@ProjectEntityHandler.moveEntity project_id, @docId, folder_id, "docs", userId, @callback
|
||||
|
||||
it 'should return an error', ->
|
||||
@callback.calledWith(new Errors.InvalidNameError("file already exists")).should.equal true
|
||||
|
||||
it "should should not send the update to the doc updater", ->
|
||||
@documentUpdaterHandler.updateProjectStructure
|
||||
.called.should.equal false
|
||||
|
||||
it 'should not remove the element from its current position', ->
|
||||
@ProjectEntityHandler._removeElementFromMongoArray
|
||||
.called.should.equal false
|
||||
|
||||
it "should not put the element back in the new folder", ->
|
||||
@ProjectEntityHandler._putElement.called.should.equal false
|
||||
|
||||
it 'should not tell the third party data store', ->
|
||||
@tpdsUpdateSender.moveEntity
|
||||
.called.should.equal false
|
||||
|
||||
|
||||
describe "moving a folder", ->
|
||||
beforeEach ->
|
||||
@folder_id = "folder-to-move"
|
||||
@@ -379,10 +421,37 @@ describe 'ProjectEntityHandler', ->
|
||||
})
|
||||
.should.equal true
|
||||
|
||||
describe "when the destination folder contains a file with the same name", ->
|
||||
beforeEach ->
|
||||
@path.fileSystem = "/one/src_dir"
|
||||
@pathToMoveTo.fileSystem = "/two/dest_dir"
|
||||
@folder_to_move_to = { name: "folder to move to", fileRefs: [ {name: "folder"}] }
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: @move_to_folder_id, type: 'folder'})
|
||||
.callsArgWith(1, null, @folder_to_move_to, @pathToMoveTo)
|
||||
@callback = sinon.stub()
|
||||
@ProjectEntityHandler.moveEntity project_id, @folder_id, @move_to_folder_id, "folder", userId, @callback
|
||||
|
||||
it 'should find the folder we are moving to element', ->
|
||||
@projectLocator.findElement
|
||||
.calledWith({
|
||||
element_id: @move_to_folder_id,
|
||||
type: "folder",
|
||||
project: @project
|
||||
})
|
||||
.should.equal true
|
||||
|
||||
it "should return an error", ->
|
||||
@callback
|
||||
.calledWith(new Errors.InvalidNameError("file already exists"))
|
||||
.should.equal true
|
||||
|
||||
describe "when the destination folder is inside the moving folder", ->
|
||||
beforeEach ->
|
||||
@path.fileSystem = "/one/two"
|
||||
@pathToMoveTo.fileSystem = "/one/two/three"
|
||||
|
||||
@projectLocator.findElement.withArgs({project: @project, element_id: @move_to_folder_id, type: 'folder'})
|
||||
.callsArgWith(1, null, @folder_to_move_to, @pathToMoveTo)
|
||||
@callback = sinon.stub()
|
||||
@ProjectEntityHandler.moveEntity project_id, @folder_id, @move_to_folder_id, "folder", userId, @callback
|
||||
|
||||
@@ -472,6 +541,7 @@ describe 'ProjectEntityHandler', ->
|
||||
@lines = ['1234','abc']
|
||||
@path = "/path/to/doc"
|
||||
|
||||
@ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, @project)
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem:@path}})
|
||||
@callback = sinon.stub()
|
||||
@tpdsUpdateSender.addDoc = sinon.stub().callsArg(1)
|
||||
@@ -522,6 +592,7 @@ describe 'ProjectEntityHandler', ->
|
||||
@lines = ['1234','abc']
|
||||
@path = "/path/to/doc"
|
||||
|
||||
@ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, @project)
|
||||
@ProjectEntityHandler._putElement = sinon.stub().callsArgWith(4, null, {path:{fileSystem:@path}})
|
||||
@callback = sinon.stub()
|
||||
@tpdsUpdateSender.addDoc = sinon.stub().callsArg(1)
|
||||
@@ -1123,6 +1194,20 @@ describe 'ProjectEntityHandler', ->
|
||||
@newName = "new.tex"
|
||||
@path = mongo: "mongo.path", fileSystem: "/oldnamepath/oldname"
|
||||
|
||||
@project_id = project_id
|
||||
@project =
|
||||
_id: ObjectId(project_id)
|
||||
rootFolder: [_id:ObjectId()]
|
||||
@folder =
|
||||
_id: ObjectId()
|
||||
name: "someFolder"
|
||||
docs: [ {name: "another-doc.tex"} ]
|
||||
fileRefs: [ {name: "another-file.tex"} ]
|
||||
folders: [ {name: "another-folder"} ]
|
||||
@doc =
|
||||
_id: ObjectId()
|
||||
name: "new.tex"
|
||||
|
||||
@ProjectGetter.getProject.callsArgWith(2, null, @project)
|
||||
@ProjectEntityHandler.getAllEntitiesFromProject = sinon.stub()
|
||||
@ProjectEntityHandler.getAllEntitiesFromProject
|
||||
@@ -1132,7 +1217,7 @@ describe 'ProjectEntityHandler', ->
|
||||
.onSecondCall()
|
||||
.callsArgWith(1, null, @newDocs = ['new-doc'], @newFiles = ['new-file'])
|
||||
|
||||
@projectLocator.findElement = sinon.stub().callsArgWith(1, null, @entity = { _id: @entity_id, name:"oldname", rev:4 }, @path)
|
||||
@projectLocator.findElement = sinon.stub().callsArgWith(1, null, @entity = { _id: @entity_id, name:"oldname", rev:4 }, @path, @folder)
|
||||
@tpdsUpdateSender.moveEntity = sinon.stub()
|
||||
@ProjectModel.findOneAndUpdate = sinon.stub().callsArgWith(3, null, @project)
|
||||
@documentUpdaterHandler.updateProjectStructure = sinon.stub().yields()
|
||||
@@ -1154,6 +1239,27 @@ describe 'ProjectEntityHandler', ->
|
||||
@tpdsUpdateSender.moveEntity.calledWith({project_id:project_id, startPath:@path.fileSystem, endPath:"/oldnamepath/new.tex", project_name:@project.name, rev:4}).should.equal true
|
||||
done()
|
||||
|
||||
describe "when a document already exists with the same name", ->
|
||||
beforeEach ->
|
||||
@project =
|
||||
_id: ObjectId(project_id)
|
||||
rootFolder: [_id:ObjectId()]
|
||||
@folder =
|
||||
_id: ObjectId()
|
||||
name: "someFolder"
|
||||
docs: [ {name: "another-doc.tex"} ]
|
||||
fileRefs: [ {name: "another-file.tex"} ]
|
||||
folders: [ {name: "another-folder"} ]
|
||||
@doc =
|
||||
_id: ObjectId()
|
||||
name: "new.tex"
|
||||
@newName = "another-doc.tex"
|
||||
|
||||
it "should return an error", (done)->
|
||||
@ProjectEntityHandler.renameEntity project_id, @entity_id, @entityType, @newName, userId, (err)=>
|
||||
err.should.deep.equal new Errors.InvalidNameError("file already exists")
|
||||
done()
|
||||
|
||||
describe "_insertDeletedDocReference", ->
|
||||
beforeEach ->
|
||||
@doc =
|
||||
@@ -1248,6 +1354,9 @@ describe 'ProjectEntityHandler', ->
|
||||
@folder =
|
||||
_id: ObjectId()
|
||||
name: "someFolder"
|
||||
docs: [ {name: "another-doc.tex"} ]
|
||||
fileRefs: [ {name: "another-file.tex"} ]
|
||||
folders: [ {name: "another-folder"} ]
|
||||
@doc =
|
||||
_id: ObjectId()
|
||||
name: "new.tex"
|
||||
@@ -1290,6 +1399,33 @@ describe 'ProjectEntityHandler', ->
|
||||
@ProjectModel.findOneAndUpdate.called.should.equal false
|
||||
done()
|
||||
|
||||
it "should error if a document already exists with the same name", (done)->
|
||||
doc =
|
||||
_id: ObjectId()
|
||||
name: "another-doc.tex"
|
||||
@ProjectEntityHandler._putElement @project, @folder, doc, "doc", (err)=>
|
||||
@ProjectModel.findOneAndUpdate.called.should.equal false
|
||||
err.should.deep.equal new Errors.InvalidNameError("file already exists")
|
||||
done()
|
||||
|
||||
it "should error if a file already exists with the same name", (done)->
|
||||
doc =
|
||||
_id: ObjectId()
|
||||
name: "another-file.tex"
|
||||
@ProjectEntityHandler._putElement @project, @folder, doc, "doc", (err)=>
|
||||
@ProjectModel.findOneAndUpdate.called.should.equal false
|
||||
err.should.deep.equal new Errors.InvalidNameError("file already exists")
|
||||
done()
|
||||
|
||||
it "should error if a folder already exists with the same name", (done)->
|
||||
doc =
|
||||
_id: ObjectId()
|
||||
name: "another-folder"
|
||||
@ProjectEntityHandler._putElement @project, @folder, doc, "doc", (err)=>
|
||||
@ProjectModel.findOneAndUpdate.called.should.equal false
|
||||
err.should.deep.equal new Errors.InvalidNameError("file already exists")
|
||||
done()
|
||||
|
||||
describe "_countElements", ->
|
||||
|
||||
beforeEach ->
|
||||
|
||||
Reference in New Issue
Block a user