mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
[web] update the projects lastUpdated timestamp when changing file-tree (#24867)
* [misc] freeze time before any other unit test setup steps Freezing it after other work (notably sandboxed-module imports) will result in flaky tests. * [web] update the projects lastUpdated timestamp when changing file-tree GitOrigin-RevId: b82b2ff74dc31886f3c4bd300375117eead6e0cd
This commit is contained in:
@@ -20,6 +20,7 @@ const tk = require('timekeeper')
|
||||
|
||||
describe('ConnectedUsersManager', function () {
|
||||
beforeEach(function () {
|
||||
tk.freeze(new Date())
|
||||
this.settings = {
|
||||
redis: {
|
||||
realtime: {
|
||||
@@ -56,7 +57,6 @@ describe('ConnectedUsersManager', function () {
|
||||
return this.rClient
|
||||
},
|
||||
}
|
||||
tk.freeze(new Date())
|
||||
this.Metrics = {
|
||||
inc: sinon.stub(),
|
||||
histogram: sinon.stub(),
|
||||
|
||||
@@ -307,6 +307,7 @@ const EditorController = {
|
||||
projectId,
|
||||
folderId,
|
||||
folderName,
|
||||
userId,
|
||||
(err, folder, folderId) => {
|
||||
if (err) {
|
||||
OError.tag(err, 'could not add folder', {
|
||||
@@ -333,11 +334,12 @@ const EditorController = {
|
||||
)
|
||||
},
|
||||
|
||||
mkdirp(projectId, path, callback) {
|
||||
mkdirp(projectId, path, userId, callback) {
|
||||
logger.debug({ projectId, path }, "making directories if they don't exist")
|
||||
ProjectEntityUpdateHandler.mkdirp(
|
||||
projectId,
|
||||
path,
|
||||
userId,
|
||||
(err, newFolders, lastFolder) => {
|
||||
if (err) {
|
||||
OError.tag(err, 'could not mkdirp', {
|
||||
|
||||
@@ -33,7 +33,8 @@ const RestoreManager = {
|
||||
}
|
||||
const parentFolderId = await RestoreManager._findOrCreateFolder(
|
||||
projectId,
|
||||
dirname
|
||||
dirname,
|
||||
userId
|
||||
)
|
||||
const addEntityWithName = async name =>
|
||||
await FileSystemImportManager.promises.addEntity(
|
||||
@@ -71,7 +72,8 @@ const RestoreManager = {
|
||||
}
|
||||
const parentFolderId = await RestoreManager._findOrCreateFolder(
|
||||
projectId,
|
||||
dirname
|
||||
dirname,
|
||||
userId
|
||||
)
|
||||
const file = await ProjectLocator.promises
|
||||
.findElementByPath({
|
||||
@@ -264,10 +266,11 @@ const RestoreManager = {
|
||||
}
|
||||
},
|
||||
|
||||
async _findOrCreateFolder(projectId, dirname) {
|
||||
async _findOrCreateFolder(projectId, dirname, userId) {
|
||||
const { lastFolder } = await EditorController.promises.mkdirp(
|
||||
projectId,
|
||||
dirname
|
||||
dirname,
|
||||
userId
|
||||
)
|
||||
return lastFolder?._id
|
||||
},
|
||||
|
||||
@@ -105,7 +105,7 @@ function wrapWithLock(methodWithoutLock) {
|
||||
return methodWithLock
|
||||
}
|
||||
|
||||
async function addDoc(projectId, folderId, doc) {
|
||||
async function addDoc(projectId, folderId, doc, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{
|
||||
@@ -119,12 +119,13 @@ async function addDoc(projectId, folderId, doc) {
|
||||
project,
|
||||
folderId,
|
||||
doc,
|
||||
'doc'
|
||||
'doc',
|
||||
userId
|
||||
)
|
||||
return { result, project: newProject }
|
||||
}
|
||||
|
||||
async function addFile(projectId, folderId, fileRef) {
|
||||
async function addFile(projectId, folderId, fileRef, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -134,23 +135,24 @@ async function addFile(projectId, folderId, fileRef) {
|
||||
project,
|
||||
folderId,
|
||||
fileRef,
|
||||
'file'
|
||||
'file',
|
||||
userId
|
||||
)
|
||||
return { result, project: newProject }
|
||||
}
|
||||
|
||||
async function addFolder(projectId, parentFolderId, folderName) {
|
||||
async function addFolder(projectId, parentFolderId, folderName, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
)
|
||||
parentFolderId = _confirmFolder(project, parentFolderId)
|
||||
const folder = new Folder({ name: folderName })
|
||||
await _putElement(project, parentFolderId, folder, 'folder')
|
||||
await _putElement(project, parentFolderId, folder, 'folder', userId)
|
||||
return { folder, parentFolderId }
|
||||
}
|
||||
|
||||
async function replaceFileWithNew(projectId, fileId, newFileRef) {
|
||||
async function replaceFileWithNew(projectId, fileId, newFileRef, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -169,6 +171,8 @@ async function replaceFileWithNew(projectId, fileId, newFileRef) {
|
||||
[`${path.mongo}.created`]: new Date(),
|
||||
[`${path.mongo}.linkedFileData`]: newFileRef.linkedFileData,
|
||||
[`${path.mongo}.hash`]: newFileRef.hash,
|
||||
lastUpdated: new Date(),
|
||||
lastUpdatedBy: userId,
|
||||
},
|
||||
$inc: {
|
||||
version: 1,
|
||||
@@ -194,7 +198,7 @@ async function replaceFileWithNew(projectId, fileId, newFileRef) {
|
||||
return { oldFileRef: fileRef, project, path, newProject, newFileRef }
|
||||
}
|
||||
|
||||
async function replaceDocWithFile(projectId, docId, fileRef) {
|
||||
async function replaceDocWithFile(projectId, docId, fileRef, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -215,6 +219,7 @@ async function replaceDocWithFile(projectId, docId, fileRef) {
|
||||
[`${folderMongoPath}.fileRefs`]: fileRef,
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
},
|
||||
{ new: true }
|
||||
).exec()
|
||||
@@ -227,7 +232,7 @@ async function replaceDocWithFile(projectId, docId, fileRef) {
|
||||
return newProject
|
||||
}
|
||||
|
||||
async function replaceFileWithDoc(projectId, fileId, newDoc) {
|
||||
async function replaceFileWithDoc(projectId, fileId, newDoc, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -248,6 +253,7 @@ async function replaceFileWithDoc(projectId, fileId, newDoc) {
|
||||
[`${folderMongoPath}.docs`]: newDoc,
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
},
|
||||
{ new: true }
|
||||
).exec()
|
||||
@@ -260,7 +266,7 @@ async function replaceFileWithDoc(projectId, fileId, newDoc) {
|
||||
return newProject
|
||||
}
|
||||
|
||||
async function mkdirp(projectId, path, options = {}) {
|
||||
async function mkdirp(projectId, path, userId, options = {}) {
|
||||
// defaults to case insensitive paths, use options {exactCaseMatch:true}
|
||||
// to make matching case-sensitive
|
||||
const folders = path.split('/').filter(folder => folder.length !== 0)
|
||||
@@ -289,7 +295,7 @@ async function mkdirp(projectId, path, options = {}) {
|
||||
// Folder couldn't be found. Create it.
|
||||
const parentFolderId = lastFolder && lastFolder._id
|
||||
const { folder: newFolder, parentFolderId: newParentFolderId } =
|
||||
await addFolder(projectId, parentFolderId, folderName)
|
||||
await addFolder(projectId, parentFolderId, folderName, userId)
|
||||
newFolder.parentFolder_id = newParentFolderId
|
||||
lastFolder = newFolder
|
||||
newFolders.push(newFolder)
|
||||
@@ -298,7 +304,13 @@ async function mkdirp(projectId, path, options = {}) {
|
||||
return { folder: lastFolder, newFolders }
|
||||
}
|
||||
|
||||
async function moveEntity(projectId, entityId, destFolderId, entityType) {
|
||||
async function moveEntity(
|
||||
projectId,
|
||||
entityId,
|
||||
destFolderId,
|
||||
entityType,
|
||||
userId
|
||||
) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -326,7 +338,8 @@ async function moveEntity(projectId, entityId, destFolderId, entityType) {
|
||||
project,
|
||||
destFolderId,
|
||||
entity,
|
||||
entityType
|
||||
entityType,
|
||||
userId
|
||||
)
|
||||
// Note: putElement always pushes onto the end of an
|
||||
// array so it will never change an existing mongo
|
||||
@@ -337,10 +350,10 @@ async function moveEntity(projectId, entityId, destFolderId, entityType) {
|
||||
// is done by _checkValidMove above) because that
|
||||
// would lead to it being deleted.
|
||||
const newProject = await _removeElementFromMongoArray(
|
||||
Project,
|
||||
projectId,
|
||||
entityPath.mongo,
|
||||
entityId
|
||||
entityId,
|
||||
userId
|
||||
)
|
||||
const { docs: newDocs, files: newFiles } =
|
||||
ProjectEntityHandler.getAllEntitiesFromProject(newProject)
|
||||
@@ -375,7 +388,7 @@ async function moveEntity(projectId, entityId, destFolderId, entityType) {
|
||||
return { project, startPath, endPath, rev: entity.rev, changes }
|
||||
}
|
||||
|
||||
async function deleteEntity(projectId, entityId, entityType) {
|
||||
async function deleteEntity(projectId, entityId, entityType, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ name: true, rootFolder: true, overleaf: true, rootDoc_id: true }
|
||||
@@ -399,22 +412,16 @@ async function deleteEntity(projectId, entityId, entityType) {
|
||||
type: entityType,
|
||||
})
|
||||
const newProject = await _removeElementFromMongoArray(
|
||||
Project,
|
||||
projectId,
|
||||
path.mongo,
|
||||
entityId,
|
||||
userId,
|
||||
deleteRootDoc
|
||||
)
|
||||
return { entity, path, projectBeforeDeletion: project, newProject }
|
||||
}
|
||||
|
||||
async function renameEntity(
|
||||
projectId,
|
||||
entityId,
|
||||
entityType,
|
||||
newName,
|
||||
callback
|
||||
) {
|
||||
async function renameEntity(projectId, entityId, entityType, newName, userId) {
|
||||
const project = await ProjectGetter.promises.getProjectWithoutLock(
|
||||
projectId,
|
||||
{ rootFolder: true, name: true, overleaf: true }
|
||||
@@ -445,7 +452,14 @@ async function renameEntity(
|
||||
// we need to increment the project version number for any structure change
|
||||
const newProject = await Project.findOneAndUpdate(
|
||||
{ _id: projectId, [entPath.mongo]: { $exists: true } },
|
||||
{ $set: { [`${entPath.mongo}.name`]: newName }, $inc: { version: 1 } },
|
||||
{
|
||||
$set: {
|
||||
[`${entPath.mongo}.name`]: newName,
|
||||
lastUpdated: new Date(),
|
||||
lastUpdatedBy: userId,
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
},
|
||||
{ new: true }
|
||||
).exec()
|
||||
if (newProject == null) {
|
||||
@@ -478,10 +492,10 @@ async function _insertDeletedFileReference(projectId, fileRef) {
|
||||
}
|
||||
|
||||
async function _removeElementFromMongoArray(
|
||||
model,
|
||||
modelId,
|
||||
path,
|
||||
elementId,
|
||||
userId,
|
||||
deleteRootDoc = false
|
||||
) {
|
||||
const nonArrayPath = path.slice(0, path.lastIndexOf('.'))
|
||||
@@ -490,11 +504,12 @@ async function _removeElementFromMongoArray(
|
||||
const update = {
|
||||
$pull: { [nonArrayPath]: { _id: elementId } },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
if (deleteRootDoc) {
|
||||
update.$unset = { rootDoc_id: 1 }
|
||||
}
|
||||
return model.findOneAndUpdate(query, update, options).exec()
|
||||
return Project.findOneAndUpdate(query, update, options).exec()
|
||||
}
|
||||
|
||||
function _countElements(project) {
|
||||
@@ -522,7 +537,7 @@ function _countElements(project) {
|
||||
return countFolder(project.rootFolder[0])
|
||||
}
|
||||
|
||||
async function _putElement(project, folderId, element, type) {
|
||||
async function _putElement(project, folderId, element, type, userId) {
|
||||
if (element == null || element._id == null) {
|
||||
logger.warn(
|
||||
{ projectId: project._id, folderId, element, type },
|
||||
@@ -578,7 +593,11 @@ async function _putElement(project, folderId, element, type) {
|
||||
const mongoPath = `${path.mongo}.${pathSegment}`
|
||||
const newProject = await Project.findOneAndUpdate(
|
||||
{ _id: project._id, [path.mongo]: { $exists: true } },
|
||||
{ $push: { [mongoPath]: element }, $inc: { version: 1 } },
|
||||
{
|
||||
$push: { [mongoPath]: element },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
},
|
||||
{ new: true }
|
||||
).exec()
|
||||
if (newProject == null) {
|
||||
@@ -709,7 +728,11 @@ async function createNewFolderStructure(projectId, docEntries, fileEntries) {
|
||||
'rootFolder.0.files.0': { $exists: false },
|
||||
},
|
||||
{
|
||||
$set: { rootFolder: [rootFolder] },
|
||||
$set: {
|
||||
rootFolder: [rootFolder],
|
||||
// NOTE: Do not set lastUpdated/lastUpdatedBy here. They are both set when creating the initial record.
|
||||
// The newly created clsi-cache record uses the lastUpdated timestamp of the initial record. Updating the lastUpdated timestamp here invalidates the cache record.
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
},
|
||||
{
|
||||
|
||||
@@ -296,7 +296,8 @@ const addDocWithRanges = wrapWithLock({
|
||||
await ProjectEntityUpdateHandler._addDocAndSendToTpds(
|
||||
projectId,
|
||||
folderId,
|
||||
doc
|
||||
doc,
|
||||
userId
|
||||
)
|
||||
const docPath = result?.path?.fileSystem
|
||||
const projectHistoryId = project?.overleaf?.history?.id
|
||||
@@ -364,7 +365,8 @@ const addFile = wrapWithLock({
|
||||
await ProjectEntityUpdateHandler._addFileAndSendToTpds(
|
||||
projectId,
|
||||
folderId,
|
||||
fileRef
|
||||
fileRef,
|
||||
userId
|
||||
)
|
||||
const projectHistoryId = project.overleaf?.history?.id
|
||||
const newFiles = [
|
||||
@@ -382,12 +384,6 @@ const addFile = wrapWithLock({
|
||||
{ newFiles, newProject: project },
|
||||
source
|
||||
)
|
||||
|
||||
ProjectUpdateHandler.promises
|
||||
.markAsUpdated(projectId, new Date(), userId)
|
||||
.catch(error => {
|
||||
logger.error({ error }, 'failed to mark project as updated')
|
||||
})
|
||||
return { fileRef, folderId, createdBlob }
|
||||
},
|
||||
})
|
||||
@@ -434,7 +430,8 @@ const upsertDoc = wrapWithLock(
|
||||
await ProjectEntityMongoUpdateHandler.promises.replaceFileWithDoc(
|
||||
projectId,
|
||||
existingFile._id,
|
||||
doc
|
||||
doc,
|
||||
userId
|
||||
)
|
||||
|
||||
await TpdsUpdateSender.promises.addDoc({
|
||||
@@ -616,7 +613,8 @@ const upsertFile = wrapWithLock({
|
||||
await ProjectEntityMongoUpdateHandler.promises.replaceDocWithFile(
|
||||
projectId,
|
||||
existingDoc._id,
|
||||
fileRef
|
||||
fileRef,
|
||||
userId
|
||||
)
|
||||
const projectHistoryId = project.overleaf?.history?.id
|
||||
await TpdsUpdateSender.promises.addFile({
|
||||
@@ -699,7 +697,8 @@ const upsertDocWithPath = wrapWithLock(
|
||||
const { newFolders, folder } =
|
||||
await ProjectEntityUpdateHandler.promises.mkdirp.withoutLock(
|
||||
projectId,
|
||||
folderPath
|
||||
folderPath,
|
||||
userId
|
||||
)
|
||||
const { isNew, doc } =
|
||||
await ProjectEntityUpdateHandler.promises.upsertDoc.withoutLock(
|
||||
@@ -772,7 +771,8 @@ const upsertFileWithPath = wrapWithLock({
|
||||
const { newFolders, folder } =
|
||||
await ProjectEntityUpdateHandler.promises.mkdirp.withoutLock(
|
||||
projectId,
|
||||
folderPath
|
||||
folderPath,
|
||||
userId
|
||||
)
|
||||
// this calls directly into the upsertFile main task (without the beforeLock part)
|
||||
const {
|
||||
@@ -818,7 +818,8 @@ const deleteEntity = wrapWithLock(
|
||||
await ProjectEntityMongoUpdateHandler.promises.deleteEntity(
|
||||
projectId,
|
||||
entityId,
|
||||
entityType
|
||||
entityType,
|
||||
userId
|
||||
)
|
||||
const subtreeListing = await ProjectEntityUpdateHandler._cleanUpEntity(
|
||||
projectBeforeDeletion,
|
||||
@@ -866,7 +867,7 @@ const deleteEntityWithPath = wrapWithLock(
|
||||
}
|
||||
)
|
||||
|
||||
const mkdirp = wrapWithLock(async function (projectId, path) {
|
||||
const mkdirp = wrapWithLock(async function (projectId, path, userId) {
|
||||
for (const folder of path.split('/')) {
|
||||
if (folder.length > 0 && !SafePath.isCleanFilename(folder)) {
|
||||
throw new Errors.InvalidNameError('invalid element name')
|
||||
@@ -875,32 +876,37 @@ const mkdirp = wrapWithLock(async function (projectId, path) {
|
||||
return await ProjectEntityMongoUpdateHandler.promises.mkdirp(
|
||||
projectId,
|
||||
path,
|
||||
userId,
|
||||
{ exactCaseMatch: false }
|
||||
)
|
||||
})
|
||||
|
||||
const mkdirpWithExactCase = wrapWithLock(async function (projectId, path) {
|
||||
for (const folder of path.split('/')) {
|
||||
if (folder.length > 0 && !SafePath.isCleanFilename(folder)) {
|
||||
throw new Errors.InvalidNameError('invalid element name')
|
||||
const mkdirpWithExactCase = wrapWithLock(
|
||||
async function (projectId, path, userId) {
|
||||
for (const folder of path.split('/')) {
|
||||
if (folder.length > 0 && !SafePath.isCleanFilename(folder)) {
|
||||
throw new Errors.InvalidNameError('invalid element name')
|
||||
}
|
||||
}
|
||||
return await ProjectEntityMongoUpdateHandler.promises.mkdirp(
|
||||
projectId,
|
||||
path,
|
||||
userId,
|
||||
{ exactCaseMatch: true }
|
||||
)
|
||||
}
|
||||
return await ProjectEntityMongoUpdateHandler.promises.mkdirp(
|
||||
projectId,
|
||||
path,
|
||||
{ exactCaseMatch: true }
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
const addFolder = wrapWithLock(
|
||||
async function (projectId, parentFolderId, folderName) {
|
||||
async function (projectId, parentFolderId, folderName, userId) {
|
||||
if (!SafePath.isCleanFilename(folderName)) {
|
||||
throw new Errors.InvalidNameError('invalid element name')
|
||||
}
|
||||
return await ProjectEntityMongoUpdateHandler.promises.addFolder(
|
||||
projectId,
|
||||
parentFolderId,
|
||||
folderName
|
||||
folderName,
|
||||
userId
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -929,7 +935,8 @@ const moveEntity = wrapWithLock(
|
||||
projectId,
|
||||
entityId,
|
||||
destFolderId,
|
||||
entityType
|
||||
entityType,
|
||||
userId
|
||||
)
|
||||
|
||||
const projectHistoryId = project.overleaf?.history?.id
|
||||
@@ -988,7 +995,8 @@ const renameEntity = wrapWithLock(
|
||||
projectId,
|
||||
entityId,
|
||||
entityType,
|
||||
newName
|
||||
newName,
|
||||
userId
|
||||
)
|
||||
|
||||
const projectHistoryId = project.overleaf?.history?.id
|
||||
@@ -1115,7 +1123,8 @@ const convertDocToFile = wrapWithLock({
|
||||
await ProjectEntityMongoUpdateHandler.promises.replaceDocWithFile(
|
||||
projectId,
|
||||
doc._id,
|
||||
fileRef
|
||||
fileRef,
|
||||
userId
|
||||
)
|
||||
const projectHistoryId = project.overleaf?.history?.id
|
||||
await DocumentUpdaterHandler.promises.updateProjectStructure(
|
||||
@@ -1276,14 +1285,15 @@ const ProjectEntityUpdateHandler = {
|
||||
appendToDocWithPath: appendToDoc,
|
||||
},
|
||||
|
||||
async _addDocAndSendToTpds(projectId, folderId, doc) {
|
||||
async _addDocAndSendToTpds(projectId, folderId, doc, userId) {
|
||||
let result, project
|
||||
try {
|
||||
;({ result, project } =
|
||||
await ProjectEntityMongoUpdateHandler.promises.addDoc(
|
||||
projectId,
|
||||
folderId,
|
||||
doc
|
||||
doc,
|
||||
userId
|
||||
))
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'error adding file with project', {
|
||||
@@ -1328,14 +1338,15 @@ const ProjectEntityUpdateHandler = {
|
||||
}
|
||||
},
|
||||
|
||||
async _addFileAndSendToTpds(projectId, folderId, fileRef) {
|
||||
async _addFileAndSendToTpds(projectId, folderId, fileRef, userId) {
|
||||
let result, project
|
||||
try {
|
||||
;({ result, project } =
|
||||
await ProjectEntityMongoUpdateHandler.promises.addFile(
|
||||
projectId,
|
||||
folderId,
|
||||
fileRef
|
||||
fileRef,
|
||||
userId
|
||||
))
|
||||
} catch (err) {
|
||||
throw OError.tag(err, 'error adding file with project', {
|
||||
@@ -1382,7 +1393,8 @@ const ProjectEntityUpdateHandler = {
|
||||
} = await ProjectEntityMongoUpdateHandler.promises.replaceFileWithNew(
|
||||
projectId,
|
||||
fileId,
|
||||
newFileRef
|
||||
newFileRef,
|
||||
userId
|
||||
)
|
||||
|
||||
const oldFiles = [
|
||||
@@ -1410,11 +1422,6 @@ const ProjectEntityUpdateHandler = {
|
||||
projectName: project.name,
|
||||
folderId,
|
||||
})
|
||||
ProjectUpdateHandler.promises
|
||||
.markAsUpdated(projectId, new Date(), userId)
|
||||
.catch(error => {
|
||||
logger.error({ error }, 'failed to mark project as updated')
|
||||
})
|
||||
|
||||
await DocumentUpdaterHandler.promises.updateProjectStructure(
|
||||
projectId,
|
||||
@@ -1538,7 +1545,8 @@ const ProjectEntityUpdateHandler = {
|
||||
projectId,
|
||||
entityId,
|
||||
entityType,
|
||||
rename.newName
|
||||
rename.newName,
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
|
||||
// update the renamed entity for the resync
|
||||
|
||||
@@ -180,7 +180,11 @@ async function createFolder(userId, projectId, projectName, path) {
|
||||
return null
|
||||
}
|
||||
|
||||
const folder = await UpdateMerger.promises.createFolder(project._id, path)
|
||||
const folder = await UpdateMerger.promises.createFolder(
|
||||
project._id,
|
||||
path,
|
||||
userId
|
||||
)
|
||||
return {
|
||||
folderId: folder._id,
|
||||
parentFolderId: folder.parentFolder_id,
|
||||
|
||||
@@ -176,10 +176,11 @@ async function _readFileIntoTextArray(path) {
|
||||
return lines
|
||||
}
|
||||
|
||||
async function createFolder(projectId, path) {
|
||||
async function createFolder(projectId, path, userId) {
|
||||
const { lastFolder: folder } = await EditorController.promises.mkdirp(
|
||||
projectId,
|
||||
path
|
||||
path,
|
||||
userId
|
||||
)
|
||||
return folder
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ async function uploadFile(req, res, next) {
|
||||
const name = req.body.name
|
||||
const path = req.file?.path
|
||||
const projectId = req.params.Project_id
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
let { folder_id: folderId } = req.query
|
||||
if (name == null || name.length === 0 || name.length > 150) {
|
||||
return res.status(422).json({
|
||||
@@ -87,13 +88,12 @@ async function uploadFile(req, res, next) {
|
||||
})
|
||||
const { lastFolder } = await EditorController.promises.mkdirp(
|
||||
projectId,
|
||||
Path.dirname(Path.join('/', path.fileSystem, relativePath))
|
||||
Path.dirname(Path.join('/', path.fileSystem, relativePath)),
|
||||
userId
|
||||
)
|
||||
folderId = lastFolder._id
|
||||
}
|
||||
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
|
||||
return FileSystemImportManager.addEntity(
|
||||
userId,
|
||||
projectId,
|
||||
|
||||
@@ -136,7 +136,8 @@ async function createRecoveryFolder(projectId) {
|
||||
const recoveryFolder = `recovered-${Date.now()}`
|
||||
const { folder } = await ProjectEntityMongoUpdateHandler.promises.mkdirp(
|
||||
new ObjectId(projectId),
|
||||
recoveryFolder
|
||||
recoveryFolder,
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
console.log('Created recovery folder:', folder._id.toString())
|
||||
return folder
|
||||
@@ -149,7 +150,8 @@ async function restoreMissingDocs(projectId, folder, missingDocs) {
|
||||
await ProjectEntityMongoUpdateHandler.promises.addDoc(
|
||||
new ObjectId(projectId),
|
||||
folder._id,
|
||||
doc
|
||||
doc,
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
console.log('Restored doc to filetree:', doc._id.toString())
|
||||
} catch (err) {
|
||||
|
||||
@@ -104,7 +104,8 @@ async function deleteDoc(projectId, docId) {
|
||||
await ProjectEntityMongoUpdateHandler.promises.deleteEntity(
|
||||
projectId,
|
||||
docId,
|
||||
'doc'
|
||||
'doc',
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -115,7 +116,8 @@ async function deleteFile(projectId, fileId) {
|
||||
await ProjectEntityMongoUpdateHandler.promises.deleteEntity(
|
||||
projectId,
|
||||
fileId,
|
||||
'file'
|
||||
'file',
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import fs from 'node:fs'
|
||||
import logger from '@overleaf/logger'
|
||||
|
||||
const { ObjectId } = mongodb
|
||||
const lastUpdated = new Date()
|
||||
|
||||
const argv = minimist(process.argv.slice(2), {
|
||||
string: ['logs'],
|
||||
@@ -157,6 +158,8 @@ async function fixRootFolder(projectId) {
|
||||
fileRefs: [],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy: null, // unset lastUpdatedBy
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -185,6 +188,10 @@ async function removeNulls(projectId, _id) {
|
||||
[`${path}.docs`]: null,
|
||||
[`${path}.fileRefs`]: null,
|
||||
},
|
||||
$set: {
|
||||
lastUpdated,
|
||||
lastUpdatedBy: null, // unset lastUpdatedBy
|
||||
},
|
||||
}
|
||||
)
|
||||
return result.modifiedCount
|
||||
@@ -196,7 +203,7 @@ async function removeNulls(projectId, _id) {
|
||||
async function fixArray(projectId, path) {
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [path]: { $not: { $type: 'array' } } },
|
||||
{ $set: { [path]: [] } }
|
||||
{ $set: { [path]: [], lastUpdated, lastUpdatedBy: null } }
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
@@ -207,7 +214,13 @@ async function fixArray(projectId, path) {
|
||||
async function fixFolderId(projectId, path) {
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [path]: { $exists: false } },
|
||||
{ $set: { [path]: new ObjectId() } }
|
||||
{
|
||||
$set: {
|
||||
[path]: new ObjectId(),
|
||||
lastUpdated,
|
||||
lastUpdatedBy: null, // unset lastUpdatedBy
|
||||
},
|
||||
}
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
@@ -218,7 +231,13 @@ async function fixFolderId(projectId, path) {
|
||||
async function removeElementsWithoutIds(projectId, path) {
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [path]: { $type: 'array' } },
|
||||
{ $pull: { [path]: { _id: null } } }
|
||||
{
|
||||
$pull: { [path]: { _id: null } },
|
||||
$set: {
|
||||
lastUpdated,
|
||||
lastUpdatedBy: null, // unset lastUpdatedBy
|
||||
},
|
||||
}
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
@@ -245,7 +264,13 @@ async function fixName(projectId, _id) {
|
||||
const pathToName = `${path}.name`
|
||||
const result = await db.projects.updateOne(
|
||||
{ _id: new ObjectId(projectId), [pathToName]: { $in: [null, ''] } },
|
||||
{ $set: { [pathToName]: name } }
|
||||
{
|
||||
$set: {
|
||||
[pathToName]: name,
|
||||
lastUpdated,
|
||||
lastUpdatedBy: null, // unset lastUpdatedBy
|
||||
},
|
||||
}
|
||||
)
|
||||
return result.modifiedCount
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ async function processDoc(projectId, docId) {
|
||||
await ProjectEntityMongoUpdateHandler.promises.replaceDocWithFile(
|
||||
new ObjectId(projectId),
|
||||
new ObjectId(docId),
|
||||
fileRef
|
||||
fileRef,
|
||||
null // unset lastUpdatedBy
|
||||
)
|
||||
await deleteDocFromMongo(projectId, doc)
|
||||
await deleteDocFromRedis(projectId, docId)
|
||||
|
||||
@@ -5,6 +5,10 @@ import logger from '@overleaf/logger'
|
||||
import { filterOutput } from './helpers/settings.mjs'
|
||||
import { db, ObjectId } from '../../../app/src/infrastructure/mongodb.js'
|
||||
|
||||
const lastUpdated = new Date(42)
|
||||
const lastUpdatedBy = new ObjectId()
|
||||
const lastUpdatedChanged = new Date(1337)
|
||||
|
||||
async function runScriptFind() {
|
||||
try {
|
||||
const result = await promisify(exec)(
|
||||
@@ -36,7 +40,18 @@ async function runScriptFix(instructions) {
|
||||
|
||||
const findProjects = () =>
|
||||
db.projects
|
||||
.find({}, { projection: { rootFolder: 1, _id: 1, version: 1 } })
|
||||
.find(
|
||||
{},
|
||||
{
|
||||
projection: {
|
||||
rootFolder: 1,
|
||||
_id: 1,
|
||||
version: 1,
|
||||
lastUpdated: 1,
|
||||
lastUpdatedBy: 1,
|
||||
},
|
||||
}
|
||||
)
|
||||
.toArray()
|
||||
|
||||
const projectId = new ObjectId()
|
||||
@@ -75,13 +90,15 @@ const wellFormedProject = {
|
||||
fileRefs: [wellFormedFileRef('fr00'), wellFormedFileRef('fr01')],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
}
|
||||
|
||||
const testCases = [
|
||||
...[{}, { rootFolder: undefined }, { rootFolder: '1234' }].map(
|
||||
(project, idx) => ({
|
||||
name: `bad rootFolder ${idx + 1}`,
|
||||
project: { _id: projectId, ...project },
|
||||
project: { _id: projectId, ...project, lastUpdated, lastUpdatedBy },
|
||||
expectFind: [
|
||||
{
|
||||
_id: null,
|
||||
@@ -98,7 +115,7 @@ const testCases = [
|
||||
|
||||
{
|
||||
name: `missing rootFolder`,
|
||||
project: { _id: projectId, rootFolder: [] },
|
||||
project: { _id: projectId, rootFolder: [], lastUpdated, lastUpdatedBy },
|
||||
expectFind: [
|
||||
{
|
||||
_id: null,
|
||||
@@ -123,6 +140,8 @@ const testCases = [
|
||||
docs: [],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -132,6 +151,8 @@ const testCases = [
|
||||
project: {
|
||||
_id: projectId,
|
||||
rootFolder: [{ _id: '1234' }],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{ reason: 'bad folder id', path: 'rootFolder.0._id' },
|
||||
@@ -154,6 +175,8 @@ const testCases = [
|
||||
project: {
|
||||
_id: projectId,
|
||||
rootFolder: [{ _id: rootFolderId }],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{ reason: 'bad folder name', path: 'rootFolder.0.name' },
|
||||
@@ -180,6 +203,8 @@ const testCases = [
|
||||
name: 'rootFolder',
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -197,6 +222,8 @@ const testCases = [
|
||||
fileRefs: [null, null],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{
|
||||
@@ -235,6 +262,8 @@ const testCases = [
|
||||
folders: [],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -255,6 +284,8 @@ const testCases = [
|
||||
fileRefs: [{ _id: null, name: 'ref-a' }, { name: 'ref-b' }],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{ reason: 'bad folder id', path: 'rootFolder.0.folders.0._id', _id: 123 },
|
||||
@@ -291,6 +322,8 @@ const testCases = [
|
||||
fileRefs: [],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -314,6 +347,8 @@ const testCases = [
|
||||
],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{
|
||||
@@ -386,6 +421,8 @@ const testCases = [
|
||||
],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -403,6 +440,8 @@ const testCases = [
|
||||
],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{ path: 'rootFolder.0.fileRefs.0.hash', _id: strId('fa') },
|
||||
@@ -442,6 +481,8 @@ const testCases = [
|
||||
fileRefs: [null, null, { ...wellFormedFileRef('fr02'), name: null }],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{
|
||||
@@ -508,6 +549,8 @@ const testCases = [
|
||||
fileRefs: [{ ...wellFormedFileRef('fr02'), name: 'untitled' }],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -539,6 +582,8 @@ const testCases = [
|
||||
fileRefs: [],
|
||||
},
|
||||
],
|
||||
lastUpdated,
|
||||
lastUpdatedBy,
|
||||
},
|
||||
expectFind: [
|
||||
{
|
||||
@@ -637,6 +682,8 @@ const testCases = [
|
||||
fileRefs: [],
|
||||
},
|
||||
],
|
||||
lastUpdated: lastUpdatedChanged,
|
||||
lastUpdatedBy: null,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -674,6 +721,9 @@ describe('find_malformed_filetrees and fix_malformed_filetree scripts', function
|
||||
expect(expectFixStdout).to.be.a('string')
|
||||
expect(stdout).to.include(expectFixStdout)
|
||||
const [updatedProject] = await findProjects()
|
||||
if (updatedProject.lastUpdated > lastUpdated) {
|
||||
updatedProject.lastUpdated = lastUpdatedChanged
|
||||
}
|
||||
expectProject(updatedProject)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ const GLOBAL_BLOB_HASH = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
|
||||
describe('ClsiManager', function () {
|
||||
beforeEach(function () {
|
||||
tk.freeze(Date.now())
|
||||
|
||||
this.user_id = 'user-id'
|
||||
this.project = {
|
||||
_id: 'project-id',
|
||||
@@ -182,7 +184,6 @@ describe('ClsiManager', function () {
|
||||
'../History/HistoryManager': this.HistoryManager,
|
||||
},
|
||||
})
|
||||
tk.freeze(Date.now())
|
||||
})
|
||||
|
||||
after(function () {
|
||||
|
||||
@@ -518,7 +518,12 @@ describe('EditorController', function () {
|
||||
|
||||
it('should add the folder using the project entity handler', function () {
|
||||
return this.ProjectEntityUpdateHandler.addFolder
|
||||
.calledWith(this.project_id, this.folder_id, this.folderName)
|
||||
.calledWith(
|
||||
this.project_id,
|
||||
this.folder_id,
|
||||
this.folderName,
|
||||
this.user_id
|
||||
)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -540,6 +545,7 @@ describe('EditorController', function () {
|
||||
(this.folderA = { _id: 2, parentFolder_id: 1 }),
|
||||
(this.folderB = { _id: 3, parentFolder_id: 2 }),
|
||||
]
|
||||
this.userId = new ObjectId().toString()
|
||||
this.EditorController._notifyProjectUsersOfNewFolders = sinon
|
||||
.stub()
|
||||
.yields()
|
||||
@@ -549,13 +555,14 @@ describe('EditorController', function () {
|
||||
return this.EditorController.mkdirp(
|
||||
this.project_id,
|
||||
this.path,
|
||||
this.userId,
|
||||
this.callback
|
||||
)
|
||||
})
|
||||
|
||||
it('should create the folder using the project entity handler', function () {
|
||||
return this.ProjectEntityUpdateHandler.mkdirp
|
||||
.calledWith(this.project_id, this.path)
|
||||
.calledWith(this.project_id, this.path, this.userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('RestoreManager', function () {
|
||||
|
||||
it('should find the root folder', function () {
|
||||
this.RestoreManager.promises._findOrCreateFolder
|
||||
.calledWith(this.project_id, '')
|
||||
.calledWith(this.project_id, '', this.user_id)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -116,7 +116,7 @@ describe('RestoreManager', function () {
|
||||
|
||||
it('should find the folder', function () {
|
||||
this.RestoreManager.promises._findOrCreateFolder
|
||||
.calledWith(this.project_id, 'foo')
|
||||
.calledWith(this.project_id, 'foo', this.user_id)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -143,13 +143,14 @@ describe('RestoreManager', function () {
|
||||
})
|
||||
this.result = await this.RestoreManager.promises._findOrCreateFolder(
|
||||
this.project_id,
|
||||
'folder/name'
|
||||
'folder/name',
|
||||
this.user_id
|
||||
)
|
||||
})
|
||||
|
||||
it('should look up or create the folder', function () {
|
||||
this.EditorController.promises.mkdirp
|
||||
.calledWith(this.project_id, 'folder/name')
|
||||
.calledWith(this.project_id, 'folder/name', this.user_id)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ const MODULE_PATH =
|
||||
|
||||
describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
beforeEach(function () {
|
||||
tk.freeze(new Date())
|
||||
this.doc = {
|
||||
_id: new ObjectId(),
|
||||
name: 'test-doc.txt',
|
||||
@@ -209,19 +210,13 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
afterEach(function () {
|
||||
this.DeletedFileMock.restore()
|
||||
this.ProjectMock.restore()
|
||||
})
|
||||
|
||||
beforeEach(function () {
|
||||
tk.freeze(Date.now())
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
tk.reset()
|
||||
})
|
||||
|
||||
describe('addDoc', function () {
|
||||
beforeEach(async function () {
|
||||
const doc = { _id: new ObjectId(), name: 'other.txt' }
|
||||
const userId = new ObjectId().toString()
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
{
|
||||
@@ -231,6 +226,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.folders.0.docs': doc },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -238,7 +234,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.result = await this.subject.promises.addDoc(
|
||||
this.project._id,
|
||||
this.folder._id,
|
||||
doc
|
||||
doc,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -260,7 +257,9 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
})
|
||||
|
||||
describe('addFile', function () {
|
||||
let userId
|
||||
beforeEach(function () {
|
||||
userId = new ObjectId().toString()
|
||||
this.newFile = { _id: new ObjectId(), name: 'picture.jpg' }
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
@@ -271,6 +270,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.folders.0.fileRefs': this.newFile },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -282,7 +282,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.result = await this.subject.promises.addFile(
|
||||
this.project._id,
|
||||
this.folder._id,
|
||||
this.newFile
|
||||
this.newFile,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -318,7 +319,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.subject.promises.addFile(
|
||||
this.project._id,
|
||||
this.folder._id,
|
||||
this.newFile
|
||||
this.newFile,
|
||||
userId
|
||||
)
|
||||
).to.be.rejected
|
||||
})
|
||||
@@ -327,6 +329,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('addFolder', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
const folderName = 'New folder'
|
||||
this.FolderModel.withArgs({ name: folderName }).returns({
|
||||
_id: new ObjectId(),
|
||||
@@ -345,6 +348,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
}),
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -352,7 +356,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
await this.subject.promises.addFolder(
|
||||
this.project._id,
|
||||
this.folder._id,
|
||||
folderName
|
||||
folderName,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -393,6 +398,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
'rootFolder.0.fileRefs.0.created': sinon.match.date,
|
||||
'rootFolder.0.fileRefs.0.linkedFileData': newFile.linkedFileData,
|
||||
'rootFolder.0.fileRefs.0.hash': newFile.hash,
|
||||
lastUpdated: new Date(),
|
||||
lastUpdatedBy: 'userId',
|
||||
},
|
||||
$inc: {
|
||||
version: 1,
|
||||
@@ -408,7 +415,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
await this.subject.promises.replaceFileWithNew(
|
||||
this.project._id,
|
||||
this.file._id,
|
||||
newFile
|
||||
newFile,
|
||||
'userId'
|
||||
)
|
||||
})
|
||||
|
||||
@@ -460,6 +468,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('when the path is a new folder at the top level', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.newFolder = { _id: new ObjectId(), name: 'new-folder' }
|
||||
this.FolderModel.returns(this.newFolder)
|
||||
this.exactCaseMatch = false
|
||||
@@ -469,6 +478,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.folders': this.newFolder },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -476,6 +486,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.result = await this.subject.promises.mkdirp(
|
||||
this.project._id,
|
||||
'/new-folder/',
|
||||
userId,
|
||||
{ exactCaseMatch: this.exactCaseMatch }
|
||||
)
|
||||
})
|
||||
@@ -504,6 +515,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('adding a subfolder', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.newFolder = { _id: new ObjectId(), name: 'new-folder' }
|
||||
this.FolderModel.returns(this.newFolder)
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
@@ -519,13 +531,15 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
}),
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
.resolves(this.project)
|
||||
this.result = await this.subject.promises.mkdirp(
|
||||
this.project._id,
|
||||
'/test-folder/new-folder'
|
||||
'/test-folder/new-folder',
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -547,7 +561,9 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
})
|
||||
|
||||
describe('when mutliple folders are missing', async function () {
|
||||
let userId
|
||||
beforeEach(function () {
|
||||
userId = new ObjectId().toString()
|
||||
this.folder1 = { _id: new ObjectId(), name: 'folder1' }
|
||||
this.folder1Path = {
|
||||
fileSystem: '/test-folder/folder1',
|
||||
@@ -593,6 +609,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
}),
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -610,6 +627,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
}),
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -629,7 +647,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
beforeEach(async function () {
|
||||
this.result = await this.subject.promises.mkdirp(
|
||||
this.project._id,
|
||||
path
|
||||
path,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -661,6 +680,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
describe('moveEntity', function () {
|
||||
describe('moving a doc into a different folder', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.pathAfterMove = {
|
||||
fileSystem: '/somewhere/else.txt',
|
||||
}
|
||||
@@ -685,6 +705,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.folders.0.docs': this.doc },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -695,6 +716,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$pull: { 'rootFolder.0.docs': { _id: this.doc._id } },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -703,7 +725,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
this.folder._id,
|
||||
'doc'
|
||||
'doc',
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -770,12 +793,14 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('deleteEntity', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
{ _id: this.project._id },
|
||||
{
|
||||
$pull: { 'rootFolder.0.docs': { _id: this.doc._id } },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -783,7 +808,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
await this.subject.promises.deleteEntity(
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
'doc'
|
||||
'doc',
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -795,6 +821,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
describe('renameEntity', function () {
|
||||
describe('happy path', function () {
|
||||
beforeEach(async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.newName = 'new.tex'
|
||||
this.oldDocs = ['old-doc']
|
||||
this.oldFiles = ['old-file']
|
||||
@@ -812,7 +839,11 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
.withArgs(
|
||||
{ _id: this.project._id, 'rootFolder.0.docs.0': { $exists: true } },
|
||||
{
|
||||
$set: { 'rootFolder.0.docs.0.name': this.newName },
|
||||
$set: {
|
||||
'rootFolder.0.docs.0.name': this.newName,
|
||||
lastUpdated: new Date(),
|
||||
lastUpdatedBy: userId,
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
}
|
||||
)
|
||||
@@ -822,7 +853,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
'doc',
|
||||
this.newName
|
||||
this.newName,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -864,7 +896,9 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
describe('_putElement', function () {
|
||||
describe('updating the project', function () {
|
||||
describe('when the parent folder is given', function () {
|
||||
let userId
|
||||
beforeEach(function () {
|
||||
userId = new ObjectId().toString()
|
||||
this.newFile = { _id: new ObjectId(), name: 'new file.png' }
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
@@ -875,6 +909,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.folders.0.fileRefs': this.newFile },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -886,7 +921,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.project,
|
||||
this.folder._id,
|
||||
this.newFile,
|
||||
'files'
|
||||
'files',
|
||||
userId
|
||||
)
|
||||
this.ProjectMock.verify()
|
||||
})
|
||||
@@ -896,7 +932,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.project,
|
||||
this.folder._id,
|
||||
this.newFile,
|
||||
'file'
|
||||
'file',
|
||||
userId
|
||||
)
|
||||
this.ProjectMock.verify()
|
||||
})
|
||||
@@ -998,6 +1035,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('when the parent folder is not given', function () {
|
||||
it('should default to root folder insert', async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.newFile = { _id: new ObjectId(), name: 'new file.png' }
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
@@ -1005,6 +1043,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
{
|
||||
$push: { 'rootFolder.0.fileRefs': this.newFile },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
}
|
||||
)
|
||||
.chain('exec')
|
||||
@@ -1013,7 +1052,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
this.project,
|
||||
this.rootFolder._id,
|
||||
this.newFile,
|
||||
'file'
|
||||
'file',
|
||||
userId
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -1098,6 +1138,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('replaceDocWithFile', function () {
|
||||
it('should simultaneously remove the doc and add the file', async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
{ _id: this.project._id, 'rootFolder.0': { $exists: true } },
|
||||
@@ -1105,6 +1146,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
$pull: { 'rootFolder.0.docs': { _id: this.doc._id } },
|
||||
$push: { 'rootFolder.0.fileRefs': this.file },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
},
|
||||
{ new: true }
|
||||
)
|
||||
@@ -1113,7 +1155,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
await this.subject.promises.replaceDocWithFile(
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
this.file
|
||||
this.file,
|
||||
userId
|
||||
)
|
||||
this.ProjectMock.verify()
|
||||
})
|
||||
@@ -1121,6 +1164,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
|
||||
describe('replaceFileWithDoc', function () {
|
||||
it('should simultaneously remove the file and add the doc', async function () {
|
||||
const userId = new ObjectId().toString()
|
||||
this.ProjectMock.expects('findOneAndUpdate')
|
||||
.withArgs(
|
||||
{ _id: this.project._id, 'rootFolder.0': { $exists: true } },
|
||||
@@ -1128,6 +1172,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
$pull: { 'rootFolder.0.fileRefs': { _id: this.file._id } },
|
||||
$push: { 'rootFolder.0.docs': this.doc },
|
||||
$inc: { version: 1 },
|
||||
$set: { lastUpdated: new Date(), lastUpdatedBy: userId },
|
||||
},
|
||||
{ new: true }
|
||||
)
|
||||
@@ -1136,7 +1181,8 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
await this.subject.promises.replaceFileWithDoc(
|
||||
this.project._id,
|
||||
this.file._id,
|
||||
this.doc
|
||||
this.doc,
|
||||
userId
|
||||
)
|
||||
this.ProjectMock.verify()
|
||||
})
|
||||
|
||||
@@ -747,13 +747,6 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should mark the project as updated', function () {
|
||||
const args = this.ProjectUpdater.promises.markAsUpdated.args[0]
|
||||
args[0].should.equal(projectId)
|
||||
args[1].should.exist
|
||||
args[2].should.equal(userId)
|
||||
})
|
||||
|
||||
it('sends the change in project structure to the doc updater', function () {
|
||||
const newFiles = [
|
||||
{
|
||||
@@ -1181,7 +1174,8 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.replaceFileWithNew.should.have.been.calledWith(
|
||||
projectId,
|
||||
this.existingFile._id,
|
||||
this.file
|
||||
this.file,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1198,13 +1192,6 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should mark the project as updated', function () {
|
||||
const args = this.ProjectUpdater.promises.markAsUpdated.args[0]
|
||||
args[0].should.equal(projectId)
|
||||
args[1].should.exist
|
||||
args[2].should.equal(userId)
|
||||
})
|
||||
|
||||
it('updates the project structure in the doc updater', function () {
|
||||
const oldFiles = [
|
||||
{
|
||||
@@ -1394,7 +1381,12 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
it('replaces the existing doc with a file', function () {
|
||||
expect(
|
||||
this.ProjectEntityMongoUpdateHandler.promises.replaceDocWithFile
|
||||
).to.have.been.calledWith(projectId, this.existingDoc._id, this.newFile)
|
||||
).to.have.been.calledWith(
|
||||
projectId,
|
||||
this.existingDoc._id,
|
||||
this.newFile,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
it('updates the doc structure', function () {
|
||||
@@ -1475,7 +1467,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
|
||||
it('creates any necessary folders', function () {
|
||||
this.ProjectEntityUpdateHandler.promises.mkdirp.withoutLock
|
||||
.calledWith(projectId, '/folder')
|
||||
.calledWith(projectId, '/folder', userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -1620,7 +1612,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
|
||||
it('creates any necessary folders', function () {
|
||||
this.ProjectEntityUpdateHandler.promises.mkdirp.withoutLock
|
||||
.calledWith(projectId, '/folder')
|
||||
.calledWith(projectId, '/folder', userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -1767,7 +1759,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
|
||||
it('deletes the entity in mongo', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.deleteEntity
|
||||
.calledWith(projectId, docId, 'doc')
|
||||
.calledWith(projectId, docId, 'doc', userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -1873,12 +1865,17 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
beforeEach(function (done) {
|
||||
this.docPath = '/folder/doc.tex'
|
||||
this.ProjectEntityMongoUpdateHandler.promises.mkdirp.resolves({})
|
||||
this.ProjectEntityUpdateHandler.mkdirp(projectId, this.docPath, done)
|
||||
this.ProjectEntityUpdateHandler.mkdirp(
|
||||
projectId,
|
||||
this.docPath,
|
||||
userId,
|
||||
done
|
||||
)
|
||||
})
|
||||
|
||||
it('calls ProjectEntityMongoUpdateHandler', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.mkdirp
|
||||
.calledWith(projectId, this.docPath)
|
||||
.calledWith(projectId, this.docPath, userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
@@ -1890,13 +1887,14 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
this.ProjectEntityUpdateHandler.mkdirpWithExactCase(
|
||||
projectId,
|
||||
this.docPath,
|
||||
userId,
|
||||
done
|
||||
)
|
||||
})
|
||||
|
||||
it('calls ProjectEntityMongoUpdateHandler', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.mkdirp
|
||||
.calledWith(projectId, this.docPath, { exactCaseMatch: true })
|
||||
.calledWith(projectId, this.docPath, userId, { exactCaseMatch: true })
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
@@ -1911,13 +1909,14 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
projectId,
|
||||
this.parentFolderId,
|
||||
this.folderName,
|
||||
userId,
|
||||
done
|
||||
)
|
||||
})
|
||||
|
||||
it('calls ProjectEntityMongoUpdateHandler', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.addFolder
|
||||
.calledWith(projectId, this.parentFolderId, this.folderName)
|
||||
.calledWith(projectId, this.parentFolderId, this.folderName, userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
@@ -1973,7 +1972,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
|
||||
it('moves the entity in mongo', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.moveEntity
|
||||
.calledWith(projectId, docId, folderId, 'doc')
|
||||
.calledWith(projectId, docId, folderId, 'doc', userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -2035,7 +2034,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
|
||||
it('moves the entity in mongo', function () {
|
||||
this.ProjectEntityMongoUpdateHandler.promises.renameEntity
|
||||
.calledWith(projectId, docId, 'doc', this.newDocName)
|
||||
.calledWith(projectId, docId, 'doc', this.newDocName, userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
@@ -2320,25 +2319,29 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
projectId,
|
||||
'doc3',
|
||||
'doc',
|
||||
'duplicate.tex (1)'
|
||||
'duplicate.tex (1)',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'doc5',
|
||||
'doc',
|
||||
'duplicate.tex (2)'
|
||||
'duplicate.tex (2)',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'file3',
|
||||
'file',
|
||||
'duplicate.jpg (1)'
|
||||
'duplicate.jpg (1)',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'file4',
|
||||
'file',
|
||||
'another dupe (23)'
|
||||
'another dupe (23)',
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
@@ -2410,25 +2413,29 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
projectId,
|
||||
'doc1',
|
||||
'doc',
|
||||
'_d_e_f_test.tex'
|
||||
'_d_e_f_test.tex',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'doc2',
|
||||
'doc',
|
||||
'untitled'
|
||||
'untitled',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'file1',
|
||||
'file',
|
||||
'A_.png'
|
||||
'A_.png',
|
||||
null
|
||||
)
|
||||
expect(renameEntity).to.have.been.calledWith(
|
||||
projectId,
|
||||
'file2',
|
||||
'file',
|
||||
'A_.png (1)'
|
||||
'A_.png (1)',
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
@@ -2501,7 +2508,8 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
projectId,
|
||||
'folder2',
|
||||
'folder',
|
||||
'bad_'
|
||||
'bad_',
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
@@ -2558,7 +2566,8 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
projectId,
|
||||
'doc1',
|
||||
'doc',
|
||||
'chapters (1)'
|
||||
'chapters (1)',
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
@@ -2929,7 +2938,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
this.ProjectEntityUpdateHandler.convertDocToFile(
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
this.user._id,
|
||||
userId,
|
||||
this.source,
|
||||
done
|
||||
)
|
||||
@@ -2960,7 +2969,12 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
it('replaces the doc with the file', function () {
|
||||
expect(
|
||||
this.ProjectEntityMongoUpdateHandler.promises.replaceDocWithFile
|
||||
).to.have.been.calledWith(this.project._id, this.doc._id, this.file)
|
||||
).to.have.been.calledWith(
|
||||
this.project._id,
|
||||
this.doc._id,
|
||||
this.file,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
it('notifies document updater of changes', function () {
|
||||
@@ -2969,7 +2983,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
).to.have.been.calledWith(
|
||||
this.project._id,
|
||||
this.project.overleaf.history.id,
|
||||
this.user._id,
|
||||
userId,
|
||||
{
|
||||
oldDocs: [{ doc: this.doc, path: this.path }],
|
||||
newFiles: [
|
||||
|
||||
@@ -107,6 +107,7 @@ const mockApiRequest = function (options) {
|
||||
|
||||
describe('RecurlyWrapper', function () {
|
||||
beforeEach(function () {
|
||||
tk.freeze(Date.now()) // freeze the time for these tests
|
||||
this.settings = {
|
||||
plans: [
|
||||
{
|
||||
@@ -134,7 +135,6 @@ describe('RecurlyWrapper', function () {
|
||||
fetchStringWithResponse: sinon.stub(),
|
||||
RequestFailedError,
|
||||
}
|
||||
tk.freeze(Date.now()) // freeze the time for these tests
|
||||
this.RecurlyWrapper = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'@overleaf/settings': this.settings,
|
||||
|
||||
@@ -540,7 +540,8 @@ function expectFolderUpdateProcessed() {
|
||||
it('processes the folder update', function () {
|
||||
expect(this.UpdateMerger.promises.createFolder).to.have.been.calledWith(
|
||||
this.projects.active1._id,
|
||||
this.folderPath
|
||||
this.folderPath,
|
||||
this.userId
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -267,7 +267,8 @@ describe('ProjectUploadController', function () {
|
||||
|
||||
this.EditorController.promises.mkdirp.should.be.calledWith(
|
||||
this.project_id,
|
||||
'/test/foo/bar'
|
||||
'/test/foo/bar',
|
||||
this.user_id
|
||||
)
|
||||
|
||||
this.FileSystemImportManager.addEntity.should.be.calledOnceWith(
|
||||
|
||||
Reference in New Issue
Block a user