mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-07 16:19:02 +02:00
Merge pull request #9658 from overleaf/em-dropbox-folder-sync
Sync folder creation from Dropbox to Overleaf GitOrigin-RevId: a2749ab8d9db7dd312818b46d6e72f1dbaaaff2e
This commit is contained in:
@@ -144,7 +144,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
path: '/',
|
||||
})
|
||||
)
|
||||
.resolves({ element: this.rootFolder, type: 'folder' })
|
||||
.resolves({ element: this.rootFolder, type: 'folder', folder: null })
|
||||
this.ProjectLocator.promises.findElementByPath
|
||||
.withArgs(
|
||||
sinon.match({
|
||||
@@ -152,7 +152,11 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
path: '/test-folder',
|
||||
})
|
||||
)
|
||||
.resolves({ element: this.folder, type: 'folder' })
|
||||
.resolves({
|
||||
element: this.folder,
|
||||
type: 'folder',
|
||||
folder: this.rootFolder,
|
||||
})
|
||||
this.ProjectLocator.promises.findElementByPath
|
||||
.withArgs(
|
||||
sinon.match({
|
||||
@@ -160,7 +164,11 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
path: '/test-folder/test-subfolder',
|
||||
})
|
||||
)
|
||||
.resolves({ element: this.subfolder, type: 'folder' })
|
||||
.resolves({
|
||||
element: this.subfolder,
|
||||
type: 'folder',
|
||||
folder: this.folder,
|
||||
})
|
||||
|
||||
this.ProjectGetter = {
|
||||
promises: {
|
||||
@@ -437,9 +445,7 @@ describe('ProjectEntityMongoUpdateHandler', function () {
|
||||
})
|
||||
|
||||
it('should report the parent folder', function () {
|
||||
expect(this.result.folder.parentFolder_id).not.equal(
|
||||
this.rootFolder._id
|
||||
)
|
||||
expect(this.result.folder.parentFolder_id).to.equal(this.rootFolder._id)
|
||||
})
|
||||
|
||||
it('should not return new folders', function () {
|
||||
|
||||
@@ -308,12 +308,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${doc1.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(doc1)
|
||||
expect(type).to.equal('doc')
|
||||
expect(folder).to.equal(rootFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -323,12 +324,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `/${doc1.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(doc1)
|
||||
expect(type).to.equal('doc')
|
||||
expect(folder).to.equal(rootFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -338,12 +340,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${subFolder.name}/${secondSubFolder.name}/${subSubDoc.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(subSubDoc)
|
||||
expect(type).to.equal('doc')
|
||||
expect(folder).to.equal(secondSubFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -353,12 +356,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${file1.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(file1)
|
||||
expect(type).to.equal('file')
|
||||
expect(folder).to.equal(rootFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -368,12 +372,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${subFolder.name}/${secondSubFolder.name}/${subSubFile.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(subSubFile)
|
||||
expect(type).to.equal('file')
|
||||
expect(folder).to.equal(secondSubFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -383,12 +388,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${subFolder.name.toUpperCase()}/${secondSubFolder.name.toUpperCase()}/${subSubFile.name.toUpperCase()}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(subSubFile)
|
||||
expect(type).to.equal('file')
|
||||
expect(folder).to.equal(secondSubFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -398,12 +404,13 @@ describe('ProjectLocator', function () {
|
||||
const path = `${subFolder.name}/${secondSubFolder.name}`
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(secondSubFolder)
|
||||
expect(type).to.equal('folder')
|
||||
expect(folder).to.equal(subFolder)
|
||||
done()
|
||||
}
|
||||
)
|
||||
@@ -413,12 +420,13 @@ describe('ProjectLocator', function () {
|
||||
const path = '/'
|
||||
this.locator.findElementByPath(
|
||||
{ project, path },
|
||||
(err, element, type) => {
|
||||
(err, element, type, folder) => {
|
||||
if (err != null) {
|
||||
return done(err)
|
||||
}
|
||||
element.should.deep.equal(rootFolder)
|
||||
expect(type).to.equal('folder')
|
||||
expect(folder).to.equal(null)
|
||||
done()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ describe('TpdsController', function () {
|
||||
promises: {
|
||||
newUpdate: sinon.stub().resolves(this.metadata),
|
||||
deleteUpdate: sinon.stub().resolves(),
|
||||
createFolder: sinon.stub().resolves(),
|
||||
},
|
||||
}
|
||||
this.UpdateMerger = {
|
||||
@@ -38,6 +39,9 @@ describe('TpdsController', function () {
|
||||
getQueues: sinon.stub().resolves('queues'),
|
||||
},
|
||||
}
|
||||
this.HttpErrorHandler = {
|
||||
conflict: sinon.stub(),
|
||||
}
|
||||
|
||||
this.TpdsController = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
@@ -45,6 +49,7 @@ describe('TpdsController', function () {
|
||||
'./UpdateMerger': this.UpdateMerger,
|
||||
'../Notifications/NotificationsBuilder': this.NotificationsBuilder,
|
||||
'../Authentication/SessionManager': this.SessionManager,
|
||||
'../Errors/HttpErrorHandler': this.HttpErrorHandler,
|
||||
'./TpdsQueueManager': this.TpdsQueueManager,
|
||||
},
|
||||
})
|
||||
@@ -166,6 +171,47 @@ describe('TpdsController', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateFolder', function () {
|
||||
beforeEach(function () {
|
||||
this.req = {
|
||||
body: { userId: this.user_id, path: '/abc/def/ghi.txt' },
|
||||
}
|
||||
this.res = {
|
||||
json: sinon.stub(),
|
||||
}
|
||||
})
|
||||
|
||||
it("creates a folder if it doesn't exist", function (done) {
|
||||
const metadata = {
|
||||
folderId: ObjectId(),
|
||||
projectId: ObjectId(),
|
||||
path: '/def/ghi.txt',
|
||||
parentFolderId: ObjectId(),
|
||||
}
|
||||
this.TpdsUpdateHandler.promises.createFolder.resolves(metadata)
|
||||
this.res.json.callsFake(body => {
|
||||
expect(body).to.deep.equal({
|
||||
entityId: metadata.folderId.toString(),
|
||||
projectId: metadata.projectId.toString(),
|
||||
path: metadata.path,
|
||||
folderId: metadata.parentFolderId.toString(),
|
||||
})
|
||||
done()
|
||||
})
|
||||
this.TpdsController.updateFolder(this.req, this.res)
|
||||
})
|
||||
|
||||
it("returns a 409 if the folder couldn't be created", function (done) {
|
||||
this.TpdsUpdateHandler.promises.createFolder.resolves(null)
|
||||
this.HttpErrorHandler.conflict.callsFake((req, res) => {
|
||||
expect(req).to.equal(this.req)
|
||||
expect(res).to.equal(this.res)
|
||||
done()
|
||||
})
|
||||
this.TpdsController.updateFolder(this.req, this.res)
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseParams', function () {
|
||||
it('should take the project name off the start and replace with slash', function () {
|
||||
const path = 'noSlashHere'
|
||||
|
||||
@@ -36,6 +36,11 @@ describe('TpdsUpdateHandler', function () {
|
||||
this.source = 'dropbox'
|
||||
this.path = `/some/file`
|
||||
this.update = {}
|
||||
this.folderPath = '/some/folder'
|
||||
this.folder = {
|
||||
_id: ObjectId(),
|
||||
parentFolder_id: ObjectId(),
|
||||
}
|
||||
|
||||
this.CooldownManager = {
|
||||
promises: {
|
||||
@@ -93,6 +98,7 @@ describe('TpdsUpdateHandler', function () {
|
||||
promises: {
|
||||
deleteUpdate: sinon.stub().resolves(),
|
||||
mergeUpdate: sinon.stub().resolves(),
|
||||
createFolder: sinon.stub().resolves(this.folder),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -281,6 +287,69 @@ describe('TpdsUpdateHandler', function () {
|
||||
expectDropboxUnlinked()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getting a folder update', function () {
|
||||
describe('with no matching project', function () {
|
||||
setupMatchingProjects([])
|
||||
receiveFolderUpdate()
|
||||
expectProjectCreated()
|
||||
expectFolderUpdateProcessed()
|
||||
})
|
||||
|
||||
describe('with one matching active project', function () {
|
||||
setupMatchingProjects(['active1'])
|
||||
receiveFolderUpdate()
|
||||
expectProjectNotCreated()
|
||||
expectFolderUpdateProcessed()
|
||||
})
|
||||
|
||||
describe('with one matching archived project', function () {
|
||||
setupMatchingProjects(['archived1'])
|
||||
receiveFolderUpdate()
|
||||
expectProjectNotCreated()
|
||||
expectFolderUpdateNotProcessed()
|
||||
expectDropboxNotUnlinked()
|
||||
})
|
||||
|
||||
describe('with two matching active projects', function () {
|
||||
setupMatchingProjects(['active1', 'active2'])
|
||||
receiveFolderUpdate()
|
||||
expectProjectNotCreated()
|
||||
expectFolderUpdateNotProcessed()
|
||||
expectDropboxUnlinked()
|
||||
})
|
||||
|
||||
describe('with two matching archived projects', function () {
|
||||
setupMatchingProjects(['archived1', 'archived2'])
|
||||
receiveFolderUpdate()
|
||||
expectProjectNotCreated()
|
||||
expectFolderUpdateNotProcessed()
|
||||
expectDropboxNotUnlinked()
|
||||
})
|
||||
|
||||
describe('with one matching active and one matching archived project', function () {
|
||||
setupMatchingProjects(['active1', 'archived1'])
|
||||
receiveFolderUpdate()
|
||||
expectProjectNotCreated()
|
||||
expectFolderUpdateNotProcessed()
|
||||
expectDropboxUnlinked()
|
||||
})
|
||||
|
||||
describe('update to a project on cooldown', async function () {
|
||||
setupMatchingProjects(['active1'])
|
||||
setupProjectOnCooldown()
|
||||
beforeEach(async function () {
|
||||
await expect(
|
||||
this.TpdsUpdateHandler.promises.createFolder(
|
||||
this.userId,
|
||||
this.projectName,
|
||||
this.path
|
||||
)
|
||||
).to.be.rejectedWith(Errors.TooManyRequestsError)
|
||||
})
|
||||
expectFolderUpdateNotProcessed()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/* Setup helpers */
|
||||
@@ -338,6 +407,16 @@ function receiveProjectDelete() {
|
||||
})
|
||||
}
|
||||
|
||||
function receiveFolderUpdate() {
|
||||
beforeEach(async function () {
|
||||
await this.TpdsUpdateHandler.promises.createFolder(
|
||||
this.userId,
|
||||
this.projectName,
|
||||
this.folderPath
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/* Expectations */
|
||||
|
||||
function expectProjectCreated() {
|
||||
@@ -388,6 +467,21 @@ function expectUpdateNotProcessed() {
|
||||
})
|
||||
}
|
||||
|
||||
function expectFolderUpdateProcessed() {
|
||||
it('processes the folder update', function () {
|
||||
expect(this.UpdateMerger.promises.createFolder).to.have.been.calledWith(
|
||||
this.projects.active1._id,
|
||||
this.folderPath
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
function expectFolderUpdateNotProcessed() {
|
||||
it("doesn't process the folder update", function () {
|
||||
expect(this.UpdateMerger.promises.createFolder).not.to.have.been.called
|
||||
})
|
||||
}
|
||||
|
||||
function expectDropboxUnlinked() {
|
||||
it('unlinks Dropbox', function () {
|
||||
expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
|
||||
Reference in New Issue
Block a user