Set and get ranges along with lines

This commit is contained in:
James Allen
2016-12-05 14:21:49 +00:00
parent ca96d168dd
commit 0a65a5eabf
11 changed files with 294 additions and 147 deletions

View File

@@ -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

View File

@@ -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)->

View 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

View File

@@ -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()

View File

@@ -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) ->

View File

@@ -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()

View File

@@ -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()

View File

@@ -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) ->) ->

View File

@@ -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", ->

View File

@@ -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", ->