mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Add an error guard around the version being present
This commit is contained in:
parent
ab527c3c5d
commit
144bae3a55
8 changed files with 56 additions and 69 deletions
|
@ -41,6 +41,9 @@ module.exports = DocManager =
|
||||||
return callback(null, docs)
|
return callback(null, docs)
|
||||||
|
|
||||||
updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) ->
|
updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) ->
|
||||||
|
if !lines? or !version?
|
||||||
|
return callback(new Error("no lines or version provided"))
|
||||||
|
|
||||||
DocManager.getDoc project_id, doc_id, {version: true}, (err, doc)->
|
DocManager.getDoc project_id, doc_id, {version: true}, (err, doc)->
|
||||||
if err? and !(err instanceof Errors.NotFoundError)
|
if err? and !(err instanceof Errors.NotFoundError)
|
||||||
logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update"
|
logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update"
|
||||||
|
@ -48,10 +51,7 @@ module.exports = DocManager =
|
||||||
|
|
||||||
isNewDoc = lines.length == 0
|
isNewDoc = lines.length == 0
|
||||||
linesAreSame = _.isEqual(doc?.lines, lines)
|
linesAreSame = _.isEqual(doc?.lines, lines)
|
||||||
if version?
|
versionsAreSame = (doc?.version == version)
|
||||||
versionsAreSame = (doc?.version == version)
|
|
||||||
else
|
|
||||||
versionsAreSame = true
|
|
||||||
|
|
||||||
if linesAreSame and versionsAreSame and !isNewDoc
|
if linesAreSame and versionsAreSame and !isNewDoc
|
||||||
logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating"
|
logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating"
|
||||||
|
@ -69,15 +69,8 @@ module.exports = DocManager =
|
||||||
}, "updating doc lines"
|
}, "updating doc lines"
|
||||||
MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)->
|
MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)->
|
||||||
return callback(callback) if error?
|
return callback(callback) if error?
|
||||||
# TODO: While rolling out this code, setting the version via the docstore is optional,
|
MongoManager.setDocVersion doc_id, version, (error) ->
|
||||||
# so if it hasn't been passed, just ignore it. Once the docupdater has totally
|
return callback(error) if error?
|
||||||
# handed control of this to the docstore, we can assume it will always be passed
|
|
||||||
# and an error guard on it not being set instead.
|
|
||||||
if version?
|
|
||||||
MongoManager.setDocVersion doc_id, version, (error) ->
|
|
||||||
return callback(error) if error?
|
|
||||||
callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc
|
|
||||||
else
|
|
||||||
callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc
|
callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc
|
||||||
|
|
||||||
deleteDoc: (project_id, doc_id, callback = (error) ->) ->
|
deleteDoc: (project_id, doc_id, callback = (error) ->) ->
|
||||||
|
|
|
@ -19,7 +19,7 @@ module.exports =
|
||||||
jobs = [
|
jobs = [
|
||||||
(cb)->
|
(cb)->
|
||||||
opts = getOpts()
|
opts = getOpts()
|
||||||
opts.json = {lines: lines}
|
opts.json = {lines: lines, version: 42}
|
||||||
request.post(opts, cb)
|
request.post(opts, cb)
|
||||||
(cb)->
|
(cb)->
|
||||||
opts = getOpts()
|
opts = getOpts()
|
||||||
|
|
|
@ -55,6 +55,11 @@ module.exports = HttpController =
|
||||||
logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided"
|
logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided"
|
||||||
res.send 400 # Bad Request
|
res.send 400 # Bad Request
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if !version? or typeof version is not "number"
|
||||||
|
logger.error project_id: project_id, doc_id: doc_id, "no doc version provided"
|
||||||
|
res.send 400 # Bad Request
|
||||||
|
return
|
||||||
|
|
||||||
logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc"
|
logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc"
|
||||||
DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) ->
|
DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) ->
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe "Archiving all docs", ->
|
||||||
(callback) =>
|
(callback) =>
|
||||||
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
|
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
|
||||||
doc.lines[0] = doc.lines[0]+" added"
|
doc.lines[0] = doc.lines[0]+" added"
|
||||||
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback
|
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback
|
||||||
async.series jobs, done
|
async.series jobs, done
|
||||||
|
|
||||||
afterEach (done) ->
|
afterEach (done) ->
|
||||||
|
@ -109,7 +109,7 @@ describe "Archiving all docs", ->
|
||||||
quarterMegInBytes = 250000
|
quarterMegInBytes = 250000
|
||||||
lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex")
|
lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex")
|
||||||
@docs[1].lines = [lines,lines,lines,lines]
|
@docs[1].lines = [lines,lines,lines,lines]
|
||||||
DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, null, =>
|
DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, 42, =>
|
||||||
DocstoreClient.archiveAllDoc @project_id, (error, @res) =>
|
DocstoreClient.archiveAllDoc @project_id, (error, @res) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe "Getting all docs", ->
|
||||||
(callback) =>
|
(callback) =>
|
||||||
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
|
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
|
||||||
doc.lines[0] = doc.lines[0]+" added"
|
doc.lines[0] = doc.lines[0]+" added"
|
||||||
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback
|
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback
|
||||||
async.series jobs, done
|
async.series jobs, done
|
||||||
|
|
||||||
it "should return all the docs", (done) ->
|
it "should return all the docs", (done) ->
|
||||||
|
|
|
@ -18,9 +18,9 @@ describe "Applying updates to a doc", ->
|
||||||
throw error if error?
|
throw error if error?
|
||||||
done()
|
done()
|
||||||
|
|
||||||
describe "when the content has changed", ->
|
describe "when the lines have changed", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
DocstoreClient.updateDoc @project_id, @doc_id, @newLines, null, (error, res, @body) =>
|
DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, (error, res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should return modified = true", ->
|
it "should return modified = true", ->
|
||||||
|
@ -35,9 +35,9 @@ describe "Applying updates to a doc", ->
|
||||||
doc.version.should.equal @version
|
doc.version.should.equal @version
|
||||||
done()
|
done()
|
||||||
|
|
||||||
describe "when the content has not been updated", ->
|
describe "when the lines and version have not been updated", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, res, @body) =>
|
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, (error, res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should return modified = false", ->
|
it "should return modified = false", ->
|
||||||
|
@ -51,7 +51,7 @@ describe "Applying updates to a doc", ->
|
||||||
describe "when the doc does not exist", ->
|
describe "when the doc does not exist", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
@missing_doc_id = ObjectId()
|
@missing_doc_id = ObjectId()
|
||||||
DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, null, (error, @res, @body) =>
|
DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, (error, @res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should create the doc", ->
|
it "should create the doc", ->
|
||||||
|
@ -66,7 +66,7 @@ describe "Applying updates to a doc", ->
|
||||||
describe "when malformed doc lines are provided", ->
|
describe "when malformed doc lines are provided", ->
|
||||||
describe "when the lines are not an array", ->
|
describe "when the lines are not an array", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, null, (error, @res, @body) =>
|
DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, (error, @res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should return 400", ->
|
it "should return 400", ->
|
||||||
|
@ -79,7 +79,7 @@ describe "Applying updates to a doc", ->
|
||||||
|
|
||||||
describe "when the lines are not present", ->
|
describe "when the lines are not present", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
DocstoreClient.updateDoc @project_id, @doc_id, null, null, (error, @res, @body) =>
|
DocstoreClient.updateDoc @project_id, @doc_id, null, @version, (error, @res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should return 400", ->
|
it "should return 400", ->
|
||||||
|
@ -89,12 +89,26 @@ describe "Applying updates to a doc", ->
|
||||||
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||||
doc.lines.should.deep.equal @originalLines
|
doc.lines.should.deep.equal @originalLines
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
describe "when no version is provided", ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, @res, @body) =>
|
||||||
|
done()
|
||||||
|
|
||||||
|
it "should return 400", ->
|
||||||
|
@res.statusCode.should.equal 400
|
||||||
|
|
||||||
|
it "should not update the doc in the API", (done) ->
|
||||||
|
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||||
|
doc.lines.should.deep.equal @originalLines
|
||||||
|
doc.version.should.equal @version
|
||||||
|
done()
|
||||||
|
|
||||||
describe "when the content is large", ->
|
describe "when the content is large", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
line = new Array(1025).join("x") # 1kb
|
line = new Array(1025).join("x") # 1kb
|
||||||
@largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb
|
@largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb
|
||||||
DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, null, (error, res, @body) =>
|
DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, (error, res, @body) =>
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should return modified = true", ->
|
it "should return modified = true", ->
|
||||||
|
|
|
@ -227,42 +227,19 @@ describe "DocManager", ->
|
||||||
it "should return the callback with the new rev", ->
|
it "should return the callback with the new rev", ->
|
||||||
@callback.calledWith(null, true, @rev + 1).should.equal true
|
@callback.calledWith(null, true, @rev + 1).should.equal true
|
||||||
|
|
||||||
describe "when the version is null and the lines are different", ->
|
describe "when the version is null", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
|
||||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback
|
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback
|
||||||
|
|
||||||
it "should get the existing doc with the version", ->
|
it "should return an error", ->
|
||||||
@DocManager.getDoc
|
@callback.calledWith(new Error("no lines or version provided")).should.equal true
|
||||||
.calledWith(@project_id, @doc_id, {version: true})
|
|
||||||
.should.equal true
|
|
||||||
|
|
||||||
it "should upsert the document to the doc collection", ->
|
describe "when the lines are null", ->
|
||||||
@MongoManager.upsertIntoDocCollection
|
|
||||||
.calledWith(@project_id, @doc_id, @newDocLines)
|
|
||||||
.should.equal true
|
|
||||||
|
|
||||||
it "should not update the version", ->
|
|
||||||
@MongoManager.setDocVersion
|
|
||||||
.called
|
|
||||||
.should.equal false
|
|
||||||
|
|
||||||
it "should return the callback with the new rev", ->
|
|
||||||
@callback.calledWith(null, true, @rev + 1).should.equal true
|
|
||||||
|
|
||||||
describe "when the version is null and the lines are the same", ->
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
@DocManager.updateDoc @project_id, @doc_id, null, @version, @callback
|
||||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines, null, @callback
|
|
||||||
|
|
||||||
it "should not update the version", ->
|
|
||||||
@MongoManager.setDocVersion.called.should.equal false
|
|
||||||
|
|
||||||
it "should not update the doc", ->
|
it "should return an error", ->
|
||||||
@MongoManager.upsertIntoDocCollection.called.should.equal false
|
@callback.calledWith(new Error("no lines or version provided")).should.equal true
|
||||||
|
|
||||||
it "should return the callback with the existing rev", ->
|
|
||||||
@callback.calledWith(null, false, @rev).should.equal true
|
|
||||||
|
|
||||||
describe "when there is a generic error getting the doc", ->
|
describe "when there is a generic error getting the doc", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
|
|
@ -195,12 +195,13 @@ describe "HttpController", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.body =
|
@req.body =
|
||||||
lines: @lines = ["hello", "world"]
|
lines: @lines = ["hello", "world"]
|
||||||
|
version: @version = 42
|
||||||
@DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5)
|
@DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5)
|
||||||
@HttpController.updateDoc @req, @res, @next
|
@HttpController.updateDoc @req, @res, @next
|
||||||
|
|
||||||
it "should update the document", ->
|
it "should update the document", ->
|
||||||
@DocManager.updateDoc
|
@DocManager.updateDoc
|
||||||
.calledWith(@project_id, @doc_id, @lines, undefined)
|
.calledWith(@project_id, @doc_id, @lines, @version)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should return a modified status", ->
|
it "should return a modified status", ->
|
||||||
|
@ -212,6 +213,7 @@ describe "HttpController", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.body =
|
@req.body =
|
||||||
lines: @lines = ["hello", "world"]
|
lines: @lines = ["hello", "world"]
|
||||||
|
version: @version = 42
|
||||||
@DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5)
|
@DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5)
|
||||||
@HttpController.updateDoc @req, @res, @next
|
@HttpController.updateDoc @req, @res, @next
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ describe "HttpController", ->
|
||||||
|
|
||||||
describe "when the doc lines are not provided", ->
|
describe "when the doc lines are not provided", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.body = {}
|
@req.body = { version: 42 }
|
||||||
@DocManager.updateDoc = sinon.stub().yields(null, false)
|
@DocManager.updateDoc = sinon.stub().yields(null, false)
|
||||||
@HttpController.updateDoc @req, @res, @next
|
@HttpController.updateDoc @req, @res, @next
|
||||||
|
|
||||||
|
@ -234,22 +236,18 @@ describe "HttpController", ->
|
||||||
.calledWith(400)
|
.calledWith(400)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
describe "when the doc version is provided", ->
|
describe "when the doc version is not provided", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.body =
|
@req.body = { lines : [ "foo" ]}
|
||||||
lines: @lines = ["hello", "world"]
|
@DocManager.updateDoc = sinon.stub().yields(null, false)
|
||||||
version: @version = 42
|
|
||||||
@DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5)
|
|
||||||
@HttpController.updateDoc @req, @res, @next
|
@HttpController.updateDoc @req, @res, @next
|
||||||
|
|
||||||
it "should update the document with the lines and version", ->
|
it "should not update the document", ->
|
||||||
@DocManager.updateDoc
|
@DocManager.updateDoc.called.should.equal false
|
||||||
.calledWith(@project_id, @doc_id, @lines, @version)
|
|
||||||
.should.equal true
|
|
||||||
|
|
||||||
it "should return a modified status", ->
|
it "should return a 400 (bad request) response", ->
|
||||||
@res.json
|
@res.send
|
||||||
.calledWith(modified: true, rev: @rev)
|
.calledWith(400)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
describe "deleteDoc", ->
|
describe "deleteDoc", ->
|
||||||
|
|
Loading…
Reference in a new issue