mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #9647 from overleaf/bg-dropbox-to-overleaf-existing-doc
handle updates to existing doc in dropbox to overleaf metadata GitOrigin-RevId: e82955a4a76e62fb649263a94103fdb7f322de85
This commit is contained in:
parent
76e0265ed7
commit
59cdcccc26
9 changed files with 77 additions and 51 deletions
|
@ -238,14 +238,22 @@ module.exports = DocumentManager = {
|
||||||
// Otherwise we should remove it immediately since nothing else
|
// Otherwise we should remove it immediately since nothing else
|
||||||
// is using it.
|
// is using it.
|
||||||
if (alreadyLoaded) {
|
if (alreadyLoaded) {
|
||||||
DocumentManager.flushDocIfLoaded(projectId, docId, error => {
|
DocumentManager.flushDocIfLoaded(
|
||||||
|
projectId,
|
||||||
|
docId,
|
||||||
|
(error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
callback(null)
|
callback(null, result)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
DocumentManager.flushAndDeleteDoc(projectId, docId, {}, error => {
|
DocumentManager.flushAndDeleteDoc(
|
||||||
|
projectId,
|
||||||
|
docId,
|
||||||
|
{},
|
||||||
|
(error, result) => {
|
||||||
// There is no harm in flushing project history if the previous
|
// There is no harm in flushing project history if the previous
|
||||||
// call failed and sometimes it is required
|
// call failed and sometimes it is required
|
||||||
HistoryManager.flushProjectChangesAsync(projectId)
|
HistoryManager.flushProjectChangesAsync(projectId)
|
||||||
|
@ -253,8 +261,9 @@ module.exports = DocumentManager = {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
callback(null)
|
callback(null, result)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -302,11 +311,16 @@ module.exports = DocumentManager = {
|
||||||
ranges,
|
ranges,
|
||||||
lastUpdatedAt,
|
lastUpdatedAt,
|
||||||
lastUpdatedBy,
|
lastUpdatedBy,
|
||||||
error => {
|
(error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
RedisManager.clearUnflushedTime(docId, callback)
|
RedisManager.clearUnflushedTime(docId, err => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
callback(null, result)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -321,7 +335,7 @@ module.exports = DocumentManager = {
|
||||||
_callback(...args)
|
_callback(...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentManager.flushDocIfLoaded(projectId, docId, error => {
|
DocumentManager.flushDocIfLoaded(projectId, docId, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
if (options.ignoreFlushErrors) {
|
if (options.ignoreFlushErrors) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
|
@ -340,7 +354,7 @@ module.exports = DocumentManager = {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
callback(null)
|
callback(null, result)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -163,13 +163,13 @@ function setDoc(req, res, next) {
|
||||||
source,
|
source,
|
||||||
userId,
|
userId,
|
||||||
undoing,
|
undoing,
|
||||||
error => {
|
(error, result) => {
|
||||||
timer.done()
|
timer.done()
|
||||||
if (error) {
|
if (error) {
|
||||||
return next(error)
|
return next(error)
|
||||||
}
|
}
|
||||||
logger.debug({ projectId, docId }, 'set doc via http')
|
logger.debug({ projectId, docId }, 'set doc via http')
|
||||||
res.sendStatus(204) // No Content
|
res.json(result)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ function setDoc(
|
||||||
return callback(new Error('error connecting to web API'))
|
return callback(new Error('error connecting to web API'))
|
||||||
}
|
}
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
callback(null)
|
callback(null, body)
|
||||||
} else if (res.statusCode === 404) {
|
} else if (res.statusCode === 404) {
|
||||||
callback(new Errors.NotFoundError(`doc not not found: ${urlPath}`))
|
callback(new Errors.NotFoundError(`doc not not found: ${urlPath}`))
|
||||||
} else if (res.statusCode === 413) {
|
} else if (res.statusCode === 413) {
|
||||||
|
|
|
@ -76,6 +76,7 @@ describe('Setting a document', function () {
|
||||||
return done(error)
|
return done(error)
|
||||||
}
|
}
|
||||||
this.statusCode = res.statusCode
|
this.statusCode = res.statusCode
|
||||||
|
this.body = body
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -91,8 +92,8 @@ describe('Setting a document', function () {
|
||||||
MockWebApi.setDocument.resetHistory()
|
MockWebApi.setDocument.resetHistory()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 204 status code', function () {
|
it('should return a 200 status code', function () {
|
||||||
this.statusCode.should.equal(204)
|
this.statusCode.should.equal(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should send the updated doc lines and version to the web api', function () {
|
it('should send the updated doc lines and version to the web api', function () {
|
||||||
|
@ -141,6 +142,10 @@ describe('Setting a document', function () {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should return the mongo rev in the json response', function () {
|
||||||
|
this.body.should.deep.equal({ rev: '123' })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when the updated doc does not exist in the doc updater', function () {
|
describe('when the updated doc does not exist in the doc updater', function () {
|
||||||
|
@ -163,6 +168,7 @@ describe('Setting a document', function () {
|
||||||
return done(error)
|
return done(error)
|
||||||
}
|
}
|
||||||
this.statusCode = res.statusCode
|
this.statusCode = res.statusCode
|
||||||
|
this.body = body
|
||||||
setTimeout(done, 200)
|
setTimeout(done, 200)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -174,8 +180,8 @@ describe('Setting a document', function () {
|
||||||
MockWebApi.setDocument.resetHistory()
|
MockWebApi.setDocument.resetHistory()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 204 status code', function () {
|
it('should return a 200 status code', function () {
|
||||||
this.statusCode.should.equal(204)
|
this.statusCode.should.equal(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should send the updated doc lines to the web api', function () {
|
it('should send the updated doc lines to the web api', function () {
|
||||||
|
@ -206,6 +212,10 @@ describe('Setting a document', function () {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should return the mongo rev in the json response', function () {
|
||||||
|
this.body.should.deep.equal({ rev: '123' })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const DOC_TOO_LARGE_TEST_CASES = [
|
const DOC_TOO_LARGE_TEST_CASES = [
|
||||||
|
@ -302,6 +312,7 @@ describe('Setting a document', function () {
|
||||||
return done(error)
|
return done(error)
|
||||||
}
|
}
|
||||||
this.statusCode = res.statusCode
|
this.statusCode = res.statusCode
|
||||||
|
this.body = body
|
||||||
setTimeout(done, 200)
|
setTimeout(done, 200)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -313,8 +324,8 @@ describe('Setting a document', function () {
|
||||||
MockWebApi.setDocument.resetHistory()
|
MockWebApi.setDocument.resetHistory()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 204 status code', function () {
|
it('should return a 200 status code', function () {
|
||||||
this.statusCode.should.equal(204)
|
this.statusCode.should.equal(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should send the updated doc lines to the web api', function () {
|
it('should send the updated doc lines to the web api', function () {
|
||||||
|
@ -322,6 +333,10 @@ describe('Setting a document', function () {
|
||||||
.calledWith(this.project_id, this.doc_id, this.newLines)
|
.calledWith(this.project_id, this.doc_id, this.newLines)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should return the mongo rev in the json response', function () {
|
||||||
|
this.body.should.deep.equal({ rev: '123' })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('with track changes', function () {
|
describe('with track changes', function () {
|
||||||
|
|
|
@ -99,7 +99,7 @@ module.exports = MockWebApi = {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
} else {
|
} else {
|
||||||
return res.sendStatus(204)
|
return res.json({ rev: '123' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,6 +17,7 @@ describe('HttpController', function () {
|
||||||
'./RedisManager': (this.RedisManager = {}),
|
'./RedisManager': (this.RedisManager = {}),
|
||||||
'./Metrics': (this.Metrics = {}),
|
'./Metrics': (this.Metrics = {}),
|
||||||
'./Errors': Errors,
|
'./Errors': Errors,
|
||||||
|
'@overleaf/settings': { max_doc_length: 2 * 1024 * 1024 },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
this.Metrics.Timer = class Timer {}
|
this.Metrics.Timer = class Timer {}
|
||||||
|
@ -202,7 +203,9 @@ describe('HttpController', function () {
|
||||||
|
|
||||||
describe('successfully', function () {
|
describe('successfully', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.DocumentManager.setDocWithLock = sinon.stub().callsArgWith(6)
|
this.DocumentManager.setDocWithLock = sinon
|
||||||
|
.stub()
|
||||||
|
.callsArgWith(6, null, { rev: '123' })
|
||||||
this.HttpController.setDoc(this.req, this.res, this.next)
|
this.HttpController.setDoc(this.req, this.res, this.next)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -219,8 +222,8 @@ describe('HttpController', function () {
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a successful No Content response', function () {
|
it('should return a json response with the document rev from web', function () {
|
||||||
this.res.sendStatus.calledWith(204).should.equal(true)
|
this.res.json.calledWithMatch({ rev: '123' }).should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should log the request', function () {
|
it('should log the request', function () {
|
||||||
|
|
|
@ -94,7 +94,7 @@ function setDocument(req, res, next) {
|
||||||
ranges,
|
ranges,
|
||||||
lastUpdatedAt,
|
lastUpdatedAt,
|
||||||
lastUpdatedBy,
|
lastUpdatedBy,
|
||||||
error => {
|
(error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
OError.tag(error, 'error finding element for getDocument', {
|
OError.tag(error, 'error finding element for getDocument', {
|
||||||
docId,
|
docId,
|
||||||
|
@ -106,7 +106,7 @@ function setDocument(req, res, next) {
|
||||||
{ docId, projectId },
|
{ docId, projectId },
|
||||||
'finished receiving set document request from api (docupdater)'
|
'finished receiving set document request from api (docupdater)'
|
||||||
)
|
)
|
||||||
res.sendStatus(200)
|
res.json(result)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ const ProjectEntityUpdateHandler = {
|
||||||
)
|
)
|
||||||
// path will only be present if the doc is not deleted
|
// path will only be present if the doc is not deleted
|
||||||
if (!modified || isDeletedDoc) {
|
if (!modified || isDeletedDoc) {
|
||||||
return callback()
|
return callback(null, { rev })
|
||||||
}
|
}
|
||||||
// Don't need to block for marking as updated
|
// Don't need to block for marking as updated
|
||||||
ProjectUpdateHandler.markAsUpdated(
|
ProjectUpdateHandler.markAsUpdated(
|
||||||
|
@ -218,7 +218,12 @@ const ProjectEntityUpdateHandler = {
|
||||||
rev,
|
rev,
|
||||||
folderId: folder?._id,
|
folderId: folder?._id,
|
||||||
},
|
},
|
||||||
callback
|
err => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
callback(null, { rev, modified })
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -741,7 +746,7 @@ const ProjectEntityUpdateHandler = {
|
||||||
userId,
|
userId,
|
||||||
docLines,
|
docLines,
|
||||||
source,
|
source,
|
||||||
err => {
|
(err, result) => {
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
@ -749,16 +754,11 @@ const ProjectEntityUpdateHandler = {
|
||||||
{ projectId, docId: existingDoc._id },
|
{ projectId, docId: existingDoc._id },
|
||||||
'notifying users that the document has been updated'
|
'notifying users that the document has been updated'
|
||||||
)
|
)
|
||||||
DocumentUpdaterHandler.flushDocToMongo(
|
// there is no need to flush the doc to mongo at this point as docupdater
|
||||||
projectId,
|
// flushes it as part of setDoc.
|
||||||
existingDoc._id,
|
//
|
||||||
err => {
|
// combine rev from response with existing doc metadata
|
||||||
if (err != null) {
|
callback(null, { ...existingDoc, ...result }, existingDoc == null)
|
||||||
return callback(err)
|
|
||||||
}
|
|
||||||
callback(null, existingDoc, existingDoc == null)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -790,12 +790,6 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('flushes the doc contents', function () {
|
|
||||||
this.DocumentUpdaterHandler.flushDocToMongo
|
|
||||||
.calledWith(projectId, this.existingDoc._id)
|
|
||||||
.should.equal(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('returns the doc', function () {
|
it('returns the doc', function () {
|
||||||
this.callback.calledWith(null, this.existingDoc, false)
|
this.callback.calledWith(null, this.existingDoc, false)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue