mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-30 20:31:34 +02:00
Set and get ranges along with lines
This commit is contained in:
@@ -3,6 +3,7 @@ Errors = require "./Errors"
|
||||
logger = require "logger-sharelatex"
|
||||
_ = require "underscore"
|
||||
DocArchive = require "./DocArchiveManager"
|
||||
RangeManager = require "./RangeManager"
|
||||
|
||||
module.exports = DocManager =
|
||||
# TODO: For historical reasons, the doc version is currently stored in the docOps
|
||||
@@ -40,7 +41,7 @@ module.exports = DocManager =
|
||||
else
|
||||
return callback(null, docs)
|
||||
|
||||
updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) ->
|
||||
updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) ->
|
||||
if !lines? or !version?
|
||||
return callback(new Error("no lines or version provided"))
|
||||
|
||||
@@ -48,33 +49,56 @@ module.exports = DocManager =
|
||||
if err? and !(err instanceof Errors.NotFoundError)
|
||||
logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update"
|
||||
return callback(err)
|
||||
|
||||
ranges = RangeManager.jsonRangesToMongo(ranges)
|
||||
|
||||
isNewDoc = lines.length == 0
|
||||
linesAreSame = _.isEqual(doc?.lines, lines)
|
||||
versionsAreSame = (doc?.version == version)
|
||||
|
||||
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"
|
||||
return callback null, false, doc?.rev
|
||||
if !doc?
|
||||
# If the document doesn't exist, we'll make sure to create/update all parts of it.
|
||||
updateLines = true
|
||||
updateVersion = true
|
||||
updateRanges = true
|
||||
else
|
||||
oldRev = doc?.rev || 0
|
||||
logger.log {
|
||||
project_id: project_id
|
||||
doc_id: doc_id,
|
||||
oldDocLines: doc?.lines
|
||||
newDocLines: lines
|
||||
rev: oldRev
|
||||
oldVersion: doc?.version
|
||||
newVersion: version
|
||||
}, "updating doc lines"
|
||||
MongoManager.upsertIntoDocCollection project_id, doc_id, {lines}, (error)->
|
||||
updateLines = not _.isEqual(doc.lines, lines)
|
||||
updateVersion = (doc.version != version)
|
||||
updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges)
|
||||
|
||||
modified = false
|
||||
rev = doc?.rev || 0
|
||||
|
||||
updateLinesAndRangesIfNeeded = (cb) ->
|
||||
if updateLines or updateRanges
|
||||
update = {}
|
||||
if updateLines
|
||||
update.lines = lines
|
||||
if updateRanges
|
||||
update.ranges = ranges
|
||||
logger.log { project_id, doc_id, oldDoc: doc, update: update }, "updating doc lines and ranges"
|
||||
|
||||
modified = true
|
||||
rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection
|
||||
MongoManager.upsertIntoDocCollection project_id, doc_id, update, cb
|
||||
else
|
||||
logger.log { project_id, doc_id, }, "doc lines have not changed - not updating"
|
||||
cb()
|
||||
|
||||
updateVersionIfNeeded = (cb) ->
|
||||
if updateVersion
|
||||
logger.log { project_id, doc_id, oldVersion: doc?.version, newVersion: version }, "updating doc version"
|
||||
modified = true
|
||||
MongoManager.setDocVersion doc_id, version, cb
|
||||
else
|
||||
logger.log { project_id, doc_id, version }, "doc version has not changed - not updating"
|
||||
cb()
|
||||
|
||||
updateLinesAndRangesIfNeeded (error) ->
|
||||
return callback(error) if error?
|
||||
updateVersionIfNeeded (error) ->
|
||||
return callback(callback) if error?
|
||||
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
|
||||
callback null, modified, rev
|
||||
|
||||
deleteDoc: (project_id, doc_id, callback = (error) ->) ->
|
||||
DocManager.getDoc project_id, doc_id, { version: false }, (error, doc) ->
|
||||
return callback(error) if error?
|
||||
return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc?
|
||||
MongoManager.markDocAsDeleted project_id, doc_id, callback
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ module.exports = HttpController =
|
||||
doc_id = req.params.doc_id
|
||||
lines = req.body?.lines
|
||||
version = req.body?.version
|
||||
ranges = req.body?.ranges
|
||||
|
||||
if !lines? or lines not instanceof Array
|
||||
logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided"
|
||||
@@ -62,7 +63,7 @@ module.exports = HttpController =
|
||||
return
|
||||
|
||||
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, ranges, (error, modified, rev) ->
|
||||
return next(error) if error?
|
||||
res.json {
|
||||
modified: modified
|
||||
@@ -86,6 +87,8 @@ module.exports = HttpController =
|
||||
}
|
||||
if doc.version?
|
||||
doc_view.version = doc.version
|
||||
if doc.ranges?
|
||||
doc_view.ranges = doc.ranges
|
||||
return doc_view
|
||||
|
||||
_buildRawDocView: (doc)->
|
||||
|
||||
35
services/docstore/app/coffee/RangeManager.coffee
Normal file
35
services/docstore/app/coffee/RangeManager.coffee
Normal file
@@ -0,0 +1,35 @@
|
||||
_ = require "underscore"
|
||||
{ObjectId} = require("./mongojs")
|
||||
|
||||
module.exports = RangeManager =
|
||||
shouldUpdateRanges: (doc_ranges, incoming_ranges) ->
|
||||
# TODO: If we have no incoming_ranges, just ignore for now while
|
||||
# we're rolling this out, but eventually this should be a mandatory
|
||||
# field and this will become an error condition
|
||||
return false if !incoming_ranges?
|
||||
|
||||
# If the ranges are empty, we don't store them in the DB, so set
|
||||
# doc_ranges to an empty object as default, since this is was the
|
||||
# incoming_ranges will be for an empty range set.
|
||||
if !doc_ranges?
|
||||
doc_ranges = {}
|
||||
|
||||
return not _.isEqual(doc_ranges, incoming_ranges)
|
||||
|
||||
jsonRangesToMongo: (ranges) ->
|
||||
return null if !ranges?
|
||||
for change in ranges.changes or []
|
||||
change.id = @_safeObjectId(change.id)
|
||||
if change.metadata?.ts?
|
||||
change.metadata.ts = new Date(change.metadata.ts)
|
||||
for comment in ranges.comments or []
|
||||
comment.id = @_safeObjectId(comment.id)
|
||||
if comment.metadata?.ts?
|
||||
comment.metadata.ts = new Date(comment.metadata.ts)
|
||||
return ranges
|
||||
|
||||
_safeObjectId: (data) ->
|
||||
try
|
||||
return ObjectId(data)
|
||||
catch
|
||||
return data
|
||||
File diff suppressed because one or more lines are too long
@@ -11,7 +11,8 @@ describe "Deleting a doc", ->
|
||||
@doc_id = ObjectId()
|
||||
@lines = ["original", "lines"]
|
||||
@version = 42
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) =>
|
||||
@ranges = []
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) =>
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
|
||||
@@ -22,12 +22,14 @@ describe "Getting all docs", ->
|
||||
lines: ["111", "222", "333"]
|
||||
rev: 6
|
||||
}]
|
||||
version = 42
|
||||
ranges = 42
|
||||
jobs = for doc in @docs
|
||||
do (doc) =>
|
||||
(callback) =>
|
||||
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
|
||||
DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, ranges, (err)=>
|
||||
doc.lines[0] = doc.lines[0]+" added"
|
||||
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback
|
||||
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, version, ranges, callback
|
||||
async.series jobs, done
|
||||
|
||||
it "should return all the docs", (done) ->
|
||||
|
||||
@@ -10,7 +10,17 @@ describe "Getting a doc", ->
|
||||
@project_id = ObjectId()
|
||||
@doc_id = ObjectId()
|
||||
@lines = ["original", "lines"]
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) =>
|
||||
@version = 42
|
||||
@ranges = {
|
||||
changes: [{
|
||||
id: ObjectId().toString()
|
||||
op: { i: "foo", p: 3 }
|
||||
meta:
|
||||
user_id: ObjectId().toString()
|
||||
ts: new Date().toString()
|
||||
}]
|
||||
}
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) =>
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
@@ -18,6 +28,8 @@ describe "Getting a doc", ->
|
||||
it "should get the doc lines and version", (done) ->
|
||||
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||
doc.lines.should.deep.equal @lines
|
||||
doc.version.should.equal @version
|
||||
doc.ranges.should.deep.equal @ranges
|
||||
done()
|
||||
|
||||
describe "when the doc does not exist", ->
|
||||
@@ -30,11 +42,15 @@ describe "Getting a doc", ->
|
||||
describe "when the doc is a deleted doc", ->
|
||||
beforeEach (done) ->
|
||||
@deleted_doc_id = ObjectId()
|
||||
DocstoreClient.createDeletedDoc @project_id, @deleted_doc_id, @lines, done
|
||||
DocstoreClient.createDoc @project_id, @deleted_doc_id, @lines, @version, @ranges, (error) =>
|
||||
throw error if error?
|
||||
DocstoreClient.deleteDoc @project_id, @deleted_doc_id, done
|
||||
|
||||
it "should return the doc", (done) ->
|
||||
DocstoreClient.getDoc @project_id, @deleted_doc_id, {include_deleted:true},(error, res, doc) =>
|
||||
doc.lines.should.deep.equal @lines
|
||||
doc.version.should.equal @version
|
||||
doc.ranges.should.deep.equal @ranges
|
||||
doc.deleted.should.equal true
|
||||
done()
|
||||
|
||||
|
||||
@@ -11,33 +11,32 @@ describe "Applying updates to a doc", ->
|
||||
@doc_id = ObjectId()
|
||||
@originalLines = ["original", "lines"]
|
||||
@newLines = ["new", "lines"]
|
||||
@originalRanges = {
|
||||
changes: [{
|
||||
id: ObjectId().toString()
|
||||
op: { i: "foo", p: 3 }
|
||||
meta:
|
||||
user_id: ObjectId().toString()
|
||||
ts: new Date().toString()
|
||||
}]
|
||||
}
|
||||
@newRanges = {
|
||||
changes: [{
|
||||
id: ObjectId().toString()
|
||||
op: { i: "bar", p: 6 }
|
||||
meta:
|
||||
user_id: ObjectId().toString()
|
||||
ts: new Date().toString()
|
||||
}]
|
||||
}
|
||||
@version = 42
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @originalLines, (error) =>
|
||||
DocstoreClient.createDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error) =>
|
||||
throw error if error?
|
||||
DocstoreClient.setDocVersion @doc_id, @version, (error) =>
|
||||
throw error if error?
|
||||
done()
|
||||
done()
|
||||
|
||||
describe "when the lines have changed", ->
|
||||
describe "when nothing has been updated", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@body.modified.should.equal true
|
||||
|
||||
it "should return the rev", ->
|
||||
@body.rev.should.equal 2
|
||||
|
||||
it "should update the doc in the API but not change the version", (done) ->
|
||||
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||
doc.lines.should.deep.equal @newLines
|
||||
doc.version.should.equal @version
|
||||
done()
|
||||
|
||||
describe "when the lines and version have not been updated", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, (error, res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = false", ->
|
||||
@@ -46,12 +45,68 @@ describe "Applying updates to a doc", ->
|
||||
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
|
||||
doc.ranges.should.deep.equal @originalRanges
|
||||
done()
|
||||
|
||||
describe "when the lines have changed", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, @originalRanges, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@body.modified.should.equal true
|
||||
|
||||
it "should return the rev", ->
|
||||
@body.rev.should.equal 2
|
||||
|
||||
it "should update the doc in the API", (done) ->
|
||||
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||
doc.lines.should.deep.equal @newLines
|
||||
doc.version.should.equal @version
|
||||
doc.ranges.should.deep.equal @originalRanges
|
||||
done()
|
||||
|
||||
describe "when the version has changed", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, @originalRanges, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@body.modified.should.equal true
|
||||
|
||||
it "should return the rev", ->
|
||||
@body.rev.should.equal 2
|
||||
|
||||
it "should 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 + 1
|
||||
doc.ranges.should.deep.equal @originalRanges
|
||||
done()
|
||||
|
||||
describe "when the ranges have changed", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @newRanges, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@body.modified.should.equal true
|
||||
|
||||
it "should return the rev", ->
|
||||
@body.rev.should.equal 2
|
||||
|
||||
it "should 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
|
||||
doc.ranges.should.deep.equal @newRanges
|
||||
done()
|
||||
|
||||
describe "when the doc does not exist", ->
|
||||
beforeEach (done) ->
|
||||
@missing_doc_id = ObjectId()
|
||||
DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, (error, @res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, @originalRanges, (error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should create the doc", ->
|
||||
@@ -61,12 +116,13 @@ describe "Applying updates to a doc", ->
|
||||
DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) =>
|
||||
doc.lines.should.deep.equal @originalLines
|
||||
doc.version.should.equal 0
|
||||
doc.ranges.should.deep.equal @originalRanges
|
||||
done()
|
||||
|
||||
describe "when malformed doc lines are provided", ->
|
||||
describe "when the lines are not an array", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, (error, @res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, @originalRanges, (error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return 400", ->
|
||||
@@ -79,7 +135,7 @@ describe "Applying updates to a doc", ->
|
||||
|
||||
describe "when the lines are not present", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, null, @version, (error, @res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, null, @version, @originalRanges, (error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return 400", ->
|
||||
@@ -92,7 +148,7 @@ describe "Applying updates to a doc", ->
|
||||
|
||||
describe "when no version is provided", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, @res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, @originalRanges, (error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return 400", ->
|
||||
@@ -108,7 +164,7 @@ describe "Applying updates to a doc", ->
|
||||
beforeEach (done) ->
|
||||
line = new Array(1025).join("x") # 1kb
|
||||
@largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, (error, res, @body) =>
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@@ -118,21 +174,3 @@ describe "Applying updates to a doc", ->
|
||||
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
|
||||
doc.lines.should.deep.equal @largeLines
|
||||
done()
|
||||
|
||||
describe "when the version has changed", ->
|
||||
beforeEach (done) ->
|
||||
DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, (error, res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return modified = true", ->
|
||||
@body.modified.should.equal true
|
||||
|
||||
it "should return the rev", ->
|
||||
@body.rev.should.equal 2
|
||||
|
||||
it "should 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 + 1
|
||||
done()
|
||||
|
||||
|
||||
@@ -5,19 +5,8 @@ DocArchiveManager = require("../../../../app/js/DocArchiveManager.js")
|
||||
|
||||
module.exports = DocstoreClient =
|
||||
|
||||
createDoc: (project_id, doc_id, lines, callback = (error) ->) ->
|
||||
db.docs.save({_id: doc_id, project_id:project_id, lines: lines, rev:1}, callback)
|
||||
|
||||
setDocVersion: (doc_id, version, callback = (error) ->) ->
|
||||
db.docOps.save({doc_id: doc_id, version: version}, callback)
|
||||
|
||||
createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) ->
|
||||
db.docs.insert {
|
||||
_id: doc_id
|
||||
project_id: project_id
|
||||
lines: lines
|
||||
deleted: true
|
||||
}, callback
|
||||
createDoc: (project_id, doc_id, lines, version, ranges, callback = (error) ->) ->
|
||||
DocstoreClient.updateDoc project_id, doc_id, lines, version, ranges, callback
|
||||
|
||||
getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) ->
|
||||
request.get {
|
||||
@@ -32,12 +21,13 @@ module.exports = DocstoreClient =
|
||||
json: true
|
||||
}, callback
|
||||
|
||||
updateDoc: (project_id, doc_id, lines, version, callback = (error, res, body) ->) ->
|
||||
updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, res, body) ->) ->
|
||||
request.post {
|
||||
url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}"
|
||||
json:
|
||||
lines: lines
|
||||
version: version
|
||||
ranges: ranges
|
||||
}, callback
|
||||
|
||||
deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) ->
|
||||
|
||||
@@ -12,6 +12,10 @@ describe "DocManager", ->
|
||||
@DocManager = SandboxedModule.require modulePath, requires:
|
||||
"./MongoManager": @MongoManager = {}
|
||||
"./DocArchiveManager": @DocArchiveManager = {}
|
||||
"./RangeManager": @RangeManager = {
|
||||
jsonRangesToMongo: (r) -> r
|
||||
shouldUpdateRanges: sinon.stub().returns false
|
||||
}
|
||||
"logger-sharelatex": @logger =
|
||||
log: sinon.stub()
|
||||
warn:->
|
||||
@@ -160,17 +164,35 @@ describe "DocManager", ->
|
||||
beforeEach ->
|
||||
@oldDocLines = ["old", "doc", "lines"]
|
||||
@newDocLines = ["new", "doc", "lines"]
|
||||
@originalRanges = {
|
||||
changes: [{
|
||||
id: ObjectId().toString()
|
||||
op: { i: "foo", p: 3 }
|
||||
meta:
|
||||
user_id: ObjectId().toString()
|
||||
ts: new Date().toString()
|
||||
}]
|
||||
}
|
||||
@newRanges = {
|
||||
changes: [{
|
||||
id: ObjectId().toString()
|
||||
op: { i: "bar", p: 6 }
|
||||
meta:
|
||||
user_id: ObjectId().toString()
|
||||
ts: new Date().toString()
|
||||
}]
|
||||
}
|
||||
@version = 42
|
||||
@doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version }
|
||||
@doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version, ranges: @originalRanges }
|
||||
|
||||
@MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3)
|
||||
@MongoManager.setDocVersion = sinon.stub().yields()
|
||||
@DocManager.getDoc = sinon.stub()
|
||||
|
||||
describe "when the doc lines have changed", ->
|
||||
describe "when only the doc lines have changed", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback
|
||||
|
||||
it "should get the existing doc", ->
|
||||
@DocManager.getDoc
|
||||
@@ -182,61 +204,84 @@ describe "DocManager", ->
|
||||
.calledWith(@project_id, @doc_id, {lines: @newDocLines})
|
||||
.should.equal true
|
||||
|
||||
it "should update the version", ->
|
||||
@MongoManager.setDocVersion
|
||||
.calledWith(@doc_id, @version)
|
||||
.should.equal true
|
||||
|
||||
it "should log out the old and new doc lines", ->
|
||||
@logger.log
|
||||
.calledWith(
|
||||
project_id: @project_id
|
||||
doc_id: @doc_id
|
||||
oldDocLines: @oldDocLines
|
||||
newDocLines: @newDocLines
|
||||
rev: @doc.rev
|
||||
oldVersion: @version
|
||||
newVersion: @version
|
||||
"updating doc lines"
|
||||
)
|
||||
.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 has changed", ->
|
||||
describe "when the doc ranges have changed", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @callback
|
||||
@RangeManager.shouldUpdateRanges.returns true
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @newRanges, @callback
|
||||
|
||||
it "should get the existing doc", ->
|
||||
@DocManager.getDoc
|
||||
.calledWith(@project_id, @doc_id)
|
||||
.should.equal true
|
||||
|
||||
it "should upsert the ranges", ->
|
||||
@MongoManager.upsertIntoDocCollection
|
||||
.calledWith(@project_id, @doc_id, {ranges: @newRanges})
|
||||
.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 only the version has changed", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @originalRanges, @callback
|
||||
|
||||
it "should get the existing doc with the version", ->
|
||||
@DocManager.getDoc
|
||||
.calledWith(@project_id, @doc_id, {version: true})
|
||||
.should.equal true
|
||||
|
||||
it "should upsert the document to the doc collection", ->
|
||||
@MongoManager.upsertIntoDocCollection
|
||||
.calledWith(@project_id, @doc_id, {lines: @oldDocLines})
|
||||
.should.equal true
|
||||
it "should not change the lines or ranges", ->
|
||||
@MongoManager.upsertIntoDocCollection.called.should.equal false
|
||||
|
||||
it "should update the version", ->
|
||||
@MongoManager.setDocVersion
|
||||
.calledWith(@doc_id, @version + 1)
|
||||
.should.equal true
|
||||
|
||||
it "should return the callback with the new rev", ->
|
||||
@callback.calledWith(null, true, @rev + 1).should.equal true
|
||||
it "should return the callback with the old rev", ->
|
||||
@callback.calledWith(null, true, @rev).should.equal true
|
||||
|
||||
describe "when the doc has not changed at all", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @originalRanges, @callback
|
||||
|
||||
it "should get the existing doc", ->
|
||||
@DocManager.getDoc
|
||||
.calledWith(@project_id, @doc_id)
|
||||
.should.equal true
|
||||
|
||||
it "should not update the ranges or lines", ->
|
||||
@MongoManager.upsertIntoDocCollection.called.should.equal false
|
||||
|
||||
it "should not update the version", ->
|
||||
@MongoManager.setDocVersion.called.should.equal false
|
||||
|
||||
it "should return the callback with the old rev and modified == false", ->
|
||||
@callback.calledWith(null, false, @rev).should.equal true
|
||||
|
||||
describe "when the version is null", ->
|
||||
beforeEach ->
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @originalRanges, @callback
|
||||
|
||||
it "should return an error", ->
|
||||
@callback.calledWith(new Error("no lines or version provided")).should.equal true
|
||||
|
||||
describe "when the lines are null", ->
|
||||
beforeEach ->
|
||||
@DocManager.updateDoc @project_id, @doc_id, null, @version, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, null, @version, @originalRanges, @callback
|
||||
|
||||
it "should return an error", ->
|
||||
@callback.calledWith(new Error("no lines or version provided")).should.equal true
|
||||
@@ -245,7 +290,7 @@ describe "DocManager", ->
|
||||
beforeEach ->
|
||||
@error = new Error("doc could not be found")
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, @error, null, null)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback
|
||||
|
||||
it "should not upsert the document to the doc collection", ->
|
||||
@MongoManager.upsertIntoDocCollection.called.should.equal false
|
||||
@@ -256,7 +301,7 @@ describe "DocManager", ->
|
||||
describe "when the doc lines have not changed", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @originalRanges, @callback
|
||||
|
||||
it "should not update the doc", ->
|
||||
@MongoManager.upsertIntoDocCollection.called.should.equal false
|
||||
@@ -264,25 +309,19 @@ describe "DocManager", ->
|
||||
it "should return the callback with the existing rev", ->
|
||||
@callback.calledWith(null, false, @rev).should.equal true
|
||||
|
||||
describe "when the doc lines are an empty array", ->
|
||||
beforeEach ->
|
||||
@doc.lines = []
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback
|
||||
|
||||
it "should upsert the document to the doc collection", ->
|
||||
@MongoManager.upsertIntoDocCollection
|
||||
.calledWith(@project_id, @doc_id, {lines: @doc.lines})
|
||||
.should.equal true
|
||||
|
||||
describe "when the doc does not exist", ->
|
||||
beforeEach ->
|
||||
@DocManager.getDoc = sinon.stub().callsArgWith(3, null, null, null)
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback
|
||||
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback
|
||||
|
||||
it "should upsert the document to the doc collection", ->
|
||||
@MongoManager.upsertIntoDocCollection
|
||||
.calledWith(@project_id, @doc_id, {lines: @newDocLines})
|
||||
.calledWith(@project_id, @doc_id, {lines: @newDocLines, ranges: @originalRanges})
|
||||
.should.equal true
|
||||
|
||||
it "should set the version", ->
|
||||
@MongoManager.setDocVersion
|
||||
.calledWith(@doc_id, @version)
|
||||
.should.equal true
|
||||
|
||||
it "should return the callback with the new rev", ->
|
||||
|
||||
@@ -196,12 +196,13 @@ describe "HttpController", ->
|
||||
@req.body =
|
||||
lines: @lines = ["hello", "world"]
|
||||
version: @version = 42
|
||||
ranges: @ranges = { changes: "mock" }
|
||||
@DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5)
|
||||
@HttpController.updateDoc @req, @res, @next
|
||||
|
||||
it "should update the document", ->
|
||||
@DocManager.updateDoc
|
||||
.calledWith(@project_id, @doc_id, @lines, @version)
|
||||
.calledWith(@project_id, @doc_id, @lines, @version, @ranges)
|
||||
.should.equal true
|
||||
|
||||
it "should return a modified status", ->
|
||||
|
||||
Reference in New Issue
Block a user