Merge branch 'doc-collection-only'

Conflicts:
	app/coffee/DocManager.coffee
This commit is contained in:
Henry Oswald 2015-03-02 08:06:41 +00:00
commit 9e91d31abb
10 changed files with 119 additions and 360 deletions

View file

@ -5,97 +5,56 @@ _ = require "underscore"
async = require "async" async = require "async"
module.exports = DocManager = module.exports = DocManager =
getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) ->
MongoManager.findDoc doc_id, (err, docFromDocCollection)-> getDoc: (project_id, doc_id, callback = (error, doc) ->) ->
return callback(err) if err? MongoManager.findDoc doc_id, (err, doc)->
MongoManager.findProject project_id, (error, project) -> if err?
return callback(error) if error? return callback(err)
return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? else if !doc?
DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}")
return callback(error) if error? callback null, doc
if docFromDocCollection?
return callback null, docFromDocCollection, mongoPath
else if doc?
if doc?.lines?.length > 0
logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?"
return callback null, doc, mongoPath
else
return callback new Errors.NotFoundError("No such doc: #{project_id}")
getAllDocs: (project_id, callback = (error, docs) ->) -> getAllDocs: (project_id, callback = (error, docs) ->) ->
MongoManager.findProject project_id, (error, project) -> MongoManager.getProjectsDocs project_id, (error, docs) ->
return callback(error) if error? if err?
return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? return callback(error)
DocManager.findAllDocsInProject project, (error, docs) -> else if !docs?
return callback(error) if error? return callback new Errors.NotFoundError("No docs for project #{project_id}")
return callback null, docs else
return callback(null, docs)
updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) ->
DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> MongoManager.findDoc doc_id, (err, doc)->
return callback(error) if error? if err?
return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") if !doc? or !mongoPath? logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update"
return callback(err)
isNewDoc = lines.length == 0 isNewDoc = lines.length == 0
linesAreSame = _.isEqual(doc.lines, lines) linesAreSame = _.isEqual(doc?.lines, lines)
if linesAreSame and !isNewDoc if linesAreSame and !isNewDoc
logger.log { logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating"
project_id: project_id, doc_id: doc_id, rev: doc.rev return callback null, false, doc?.rev
}, "doc lines have not changed"
return callback null, false, doc.rev
else else
oldRev = doc?.rev || 0
logger.log { logger.log {
project_id: project_id project_id: project_id
doc_id: doc_id, doc_id: doc_id,
oldDocLines: doc.lines oldDocLines: doc?.lines
newDocLines: lines newDocLines: lines
rev: doc.rev rev: oldRev
}, "updating doc lines" }, "updating doc lines"
async.series [ MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)->
(cb)-> return callback(callback) if error?
MongoManager.upsertIntoDocCollection project_id, doc_id, lines, doc.rev, cb callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc
(cb)->
MongoManager.updateDoc project_id, mongoPath, lines, cb
], (error)->
return callback(error) if error?
callback null, true, doc.rev + 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) ->) ->
DocManager.getDoc project_id, doc_id, (error, doc) -> DocManager.getDoc project_id, doc_id, (error, doc) ->
return callback(error) if error? return callback(error) if error?
return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc?
MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) -> MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, (error) ->
return callback(error) if error? return callback(error) if error?
MongoManager.markDocAsDeleted doc_id, (error) -> MongoManager.markDocAsDeleted doc_id, (error) ->
return callback(error) if error? return callback(error) if error?
callback() callback()
findAllDocsInProject: (project, callback = (error, docs) ->) ->
callback null, @_findAllDocsInFolder project.rootFolder[0]
findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) ->
result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0"
if result?
callback null, result.doc, result.mongoPath
else
callback null, null, null
_findDocInFolder: (folder = {}, doc_id, currentPath) ->
for doc, i in folder.docs or []
if doc?._id? and doc._id.toString() == doc_id.toString()
return {
doc: doc
mongoPath: "#{currentPath}.docs.#{i}"
}
for childFolder, i in folder.folders or []
result = @_findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}"
return result if result?
return null
_findAllDocsInFolder: (folder = {}) ->
docs = folder.docs or []
for childFolder in folder.folders or []
docs = docs.concat @_findAllDocsInFolder childFolder
return docs

View file

@ -1,29 +1,21 @@
{db, ObjectId} = require "./mongojs" {db, ObjectId} = require "./mongojs"
module.exports = MongoManager = module.exports = MongoManager =
findProject: (project_id, callback = (error, project) ->) ->
db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) ->
callback error, projects[0]
findDoc: (doc_id, callback = (error, doc) ->) -> findDoc: (doc_id, callback = (error, doc) ->) ->
db.docs.find _id: ObjectId(doc_id.toString()), {}, (error, docs = []) -> db.docs.find _id: ObjectId(doc_id.toString()), {}, (error, docs = []) ->
callback error, docs[0] callback error, docs[0]
updateDoc: (project_id, docPath, lines, callback = (error) ->) -> getProjectsDocs: (project_id, callback)->
update = db.docs.find project_id: ObjectId(project_id.toString()), {}, callback
$set: {}
$inc: {}
update.$set["#{docPath}.lines"] = lines
update.$inc["#{docPath}.rev"] = 1
db.projects.update _id: ObjectId(project_id), update, callback upsertIntoDocCollection: (project_id, doc_id, lines, callback)->
upsertIntoDocCollection: (project_id, doc_id, lines, oldRev, callback)->
update = update =
$set:{} $set:{}
$inc:{}
update.$set["lines"] = lines update.$set["lines"] = lines
update.$set["project_id"] = ObjectId(project_id) update.$set["project_id"] = ObjectId(project_id)
update.$set["rev"] = oldRev + 1 update.$inc["rev"] = 1 #on new docs being created this will set the rev to 1
db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback

View file

@ -1,6 +1,6 @@
Settings = require "settings-sharelatex" Settings = require "settings-sharelatex"
mongojs = require "mongojs" mongojs = require "mongojs"
db = mongojs.connect(Settings.mongo.url, ["projects", "docs"]) db = mongojs.connect(Settings.mongo.url, ["docs"])
module.exports = module.exports =
db: db db: db
ObjectId: mongojs.ObjectId ObjectId: mongojs.ObjectId

View file

@ -11,14 +11,9 @@ describe "Deleting a doc", ->
@doc_id = ObjectId() @doc_id = ObjectId()
@lines = ["original", "lines"] @lines = ["original", "lines"]
@version = 42 @version = 42
DocstoreClient.createProject @project_id, (error) => DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) =>
throw error if error? throw error if error?
DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => done()
throw error if error?
done()
afterEach (done) ->
DocstoreClient.deleteProject @project_id, done
describe "when the doc exists", -> describe "when the doc exists", ->
beforeEach (done) -> beforeEach (done) ->

View file

@ -22,18 +22,13 @@ describe "Getting all docs", ->
lines: ["111", "222", "333"] lines: ["111", "222", "333"]
rev: 6 rev: 6
}] }]
DocstoreClient.createProject @project_id, (error) => jobs = for doc in @docs
throw error if error? do (doc) =>
jobs = for doc in @docs (callback) =>
do (doc) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=>
(callback) => doc.lines[0] = doc.lines[0]+" added"
DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback
doc.lines[0] = doc.lines[0]+" added" async.series jobs, done
DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback
async.series jobs, done
afterEach (done) ->
DocstoreClient.deleteProject @project_id, done
it "should return all the docs", (done) -> it "should return all the docs", (done) ->
DocstoreClient.getAllDocs @project_id, (error, res, docs) => DocstoreClient.getAllDocs @project_id, (error, res, docs) =>

View file

@ -10,14 +10,9 @@ describe "Getting a doc", ->
@project_id = ObjectId() @project_id = ObjectId()
@doc_id = ObjectId() @doc_id = ObjectId()
@lines = ["original", "lines"] @lines = ["original", "lines"]
DocstoreClient.createProject @project_id, (error) => DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) =>
throw error if error? throw error if error?
DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => done()
throw error if error?
done()
afterEach (done) ->
DocstoreClient.deleteProject @project_id, done
describe "when the doc exists", -> describe "when the doc exists", ->
it "should get the doc lines and version", (done) -> it "should get the doc lines and version", (done) ->

View file

@ -11,14 +11,9 @@ describe "Applying updates to a doc", ->
@doc_id = ObjectId() @doc_id = ObjectId()
@originalLines = ["original", "lines"] @originalLines = ["original", "lines"]
@newLines = ["new", "lines"] @newLines = ["new", "lines"]
DocstoreClient.createProject @project_id, (error) => DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) =>
throw error if error? throw error if error?
DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => done()
throw error if error?
done()
afterEach (done) ->
DocstoreClient.deleteProject @project_id, done
describe "when the content has changed", -> describe "when the content has changed", ->
beforeEach (done) -> beforeEach (done) ->
@ -28,6 +23,9 @@ describe "Applying updates to a doc", ->
it "should return modified = true", -> it "should return modified = true", ->
@body.modified.should.equal 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) -> it "should update the doc in the API", (done) ->
DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) =>
doc.lines.should.deep.equal @newLines doc.lines.should.deep.equal @newLines
@ -48,22 +46,18 @@ 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, (error, @res, @body) => DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, (error, @res, @body) =>
done() done()
it "should return a 404", -> it "should create the doc", ->
@res.statusCode.should.equal 404 @body.rev.should.equal 1
describe "when the project does not exist", -> it "should be retreivable", (done)->
beforeEach (done) -> DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) =>
missing_project_id = ObjectId() doc.lines.should.deep.equal @originalLines
DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, (error, @res, @body) =>
done() done()
it "should return a 404", ->
@res.statusCode.should.equal 404
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) ->

View file

@ -2,23 +2,9 @@ request = require("request").defaults(jar: false)
{db, ObjectId} = require("../../../../app/js/mongojs") {db, ObjectId} = require("../../../../app/js/mongojs")
module.exports = DocstoreClient = module.exports = DocstoreClient =
createProject: (project_id, callback = (error) ->) ->
db.projects.insert {
_id: project_id
rootFolder: [{ docs: [] }]
}, callback
createDoc: (project_id, doc_id, lines, callback = (error) ->) -> createDoc: (project_id, doc_id, lines, callback = (error) ->) ->
db.projects.update { db.docs.save({_id: doc_id, project_id:project_id, lines: lines, rev:1}, callback)
_id: project_id
}, {
$push: {
"rootFolder.0.docs": {
_id: doc_id
lines: lines
}
}
}, callback
createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) -> createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) ->
db.docs.insert { db.docs.insert {
@ -28,9 +14,6 @@ module.exports = DocstoreClient =
deleted: true deleted: true
}, callback }, callback
deleteProject: (project_id, callback = (error, res, body) ->) ->
db.projects.remove _id: project_id, callback
getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) ->
request.get { request.get {
url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}"

View file

@ -11,7 +11,10 @@ describe "DocManager", ->
beforeEach -> beforeEach ->
@DocManager = SandboxedModule.require modulePath, requires: @DocManager = SandboxedModule.require modulePath, requires:
"./MongoManager": @MongoManager = {} "./MongoManager": @MongoManager = {}
"logger-sharelatex": @logger = {log: sinon.stub(), warn:->} "logger-sharelatex": @logger =
log: sinon.stub()
warn:->
err:->
@doc_id = ObjectId().toString() @doc_id = ObjectId().toString()
@project_id = ObjectId().toString() @project_id = ObjectId().toString()
@callback = sinon.stub() @callback = sinon.stub()
@ -27,8 +30,6 @@ describe "DocManager", ->
beforeEach -> beforeEach ->
@MongoManager.findDoc = sinon.stub() @MongoManager.findDoc = sinon.stub()
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project)
@DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath)
it "should get the doc from the doc collection when it is present there", (done)-> it "should get the doc from the doc collection when it is present there", (done)->
@MongoManager.findDoc.callsArgWith(1, null, @docCollectionDoc) @MongoManager.findDoc.callsArgWith(1, null, @docCollectionDoc)
@ -42,46 +43,8 @@ describe "DocManager", ->
err.should.equal @stubbedError err.should.equal @stubbedError
done() done()
describe "when the project exists and the doc is in it", ->
beforeEach ->
@mongoPath = "mock.mongo.path"
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project)
@MongoManager.findDoc = sinon.stub().callsArg(1)
@DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath)
@DocManager.getDoc @project_id, @doc_id, @callback
it "should get the project from the database", ->
@MongoManager.findProject
.calledWith(@project_id)
.should.equal true
it "should find the doc in the project", ->
@DocManager.findDocInProject
.calledWith(@project, @doc_id)
.should.equal true
it "should return the doc", ->
@callback.calledWith(null, @doc, @mongoPath).should.equal true
describe "when the project does not exist", ->
beforeEach ->
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, null)
@MongoManager.findDoc = sinon.stub().callsArg(1)
@DocManager.findDocInProject = sinon.stub()
@DocManager.getDoc @project_id, @doc_id, @callback
it "should not try to find the doc in the project", ->
@DocManager.findDocInProject.called.should.equal false
it "should return a NotFoundError", ->
@callback
.calledWith(new Errors.NotFoundError("No such project: #{@project_id}"))
.should.equal true
describe "when the doc is deleted", -> describe "when the doc is deleted", ->
beforeEach -> beforeEach ->
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project)
@DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null)
@MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc)
@DocManager.getDoc @project_id, @doc_id, @callback @DocManager.getDoc @project_id, @doc_id, @callback
@ -96,55 +59,39 @@ describe "DocManager", ->
.calledWith(null, @doc) .calledWith(null, @doc)
.should.equal true .should.equal true
describe "when the doc does not exist anywhere", -> describe "when the doc does not exist anywhere", ->
beforeEach -> beforeEach ->
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project)
@DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null)
@MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null)
@DocManager.getDoc @project_id, @doc_id, @callback @DocManager.getDoc @project_id, @doc_id, @callback
it "should return a NotFoundError", -> it "should return a NotFoundError", ->
@callback @callback
.calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id} in project #{@project_id}"))
.should.equal true .should.equal true
describe "getAllDocs", -> describe "getAllDocs", ->
describe "when the project exists", -> describe "when the project exists", ->
beforeEach -> beforeEach ->
@project = { name: "mock-project" }
@docs = [{ _id: @doc_id, lines: ["mock-lines"] }] @docs = [{ _id: @doc_id, lines: ["mock-lines"] }]
@mongoPath = "mock.mongo.path" @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs)
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project)
@DocManager.findAllDocsInProject = sinon.stub().callsArgWith(1, null, @docs)
@DocManager.getAllDocs @project_id, @callback @DocManager.getAllDocs @project_id, @callback
it "should get the project from the database", -> it "should get the project from the database", ->
@MongoManager.findProject @MongoManager.getProjectsDocs
.calledWith(@project_id) .calledWith(@project_id)
.should.equal true .should.equal true
it "should find all the docs in the project", ->
@DocManager.findAllDocsInProject
.calledWith(@project)
.should.equal true
it "should return the docs", -> it "should return the docs", ->
@callback.calledWith(null, @docs).should.equal true @callback.calledWith(null, @docs).should.equal true
describe "when the project does not exist", -> describe "when there are no docs for the project", ->
beforeEach -> beforeEach ->
@MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null)
@DocManager.findAllDocsInProject = sinon.stub()
@DocManager.getAllDocs @project_id, @callback @DocManager.getAllDocs @project_id, @callback
it "should not try to find the doc in the project", ->
@DocManager.findAllDocsInProject.called.should.equal false
it "should return a NotFoundError", -> it "should return a NotFoundError", ->
@callback @callback
.calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) .calledWith(new Errors.NotFoundError("No such docs for project #{@project_id}"))
.should.equal true .should.equal true
describe "deleteDoc", -> describe "deleteDoc", ->
@ -153,7 +100,7 @@ describe "DocManager", ->
@lines = ["mock", "doc", "lines"] @lines = ["mock", "doc", "lines"]
@rev = 77 @rev = 77
@DocManager.getDoc = sinon.stub().callsArgWith(2, null, {lines: @lines, rev:@rev}) @DocManager.getDoc = sinon.stub().callsArgWith(2, null, {lines: @lines, rev:@rev})
@MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3)
@MongoManager.markDocAsDeleted = sinon.stub().callsArg(1) @MongoManager.markDocAsDeleted = sinon.stub().callsArg(1)
@DocManager.deleteDoc @project_id, @doc_id, @callback @DocManager.deleteDoc @project_id, @doc_id, @callback
@ -164,7 +111,7 @@ describe "DocManager", ->
it "should update the doc lines", -> it "should update the doc lines", ->
@MongoManager.upsertIntoDocCollection @MongoManager.upsertIntoDocCollection
.calledWith(@project_id, @doc_id, @lines, @rev) .calledWith(@project_id, @doc_id, @lines)
.should.equal true .should.equal true
it "should mark doc as deleted", -> it "should mark doc as deleted", ->
@ -194,29 +141,23 @@ describe "DocManager", ->
@oldDocLines = ["old", "doc", "lines"] @oldDocLines = ["old", "doc", "lines"]
@newDocLines = ["new", "doc", "lines"] @newDocLines = ["new", "doc", "lines"]
@doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 }
@mongoPath = "mock.mongo.path"
@MongoManager.updateDoc = sinon.stub().callsArg(3) @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3)
@MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) @MongoManager.findDoc = sinon.stub()
describe "when the doc lines have changed", -> describe "when the doc lines have changed", ->
beforeEach -> beforeEach ->
@DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc)
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback
it "should get the existing doc", -> it "should get the existing doc", ->
@DocManager.getDoc @MongoManager.findDoc
.calledWith(@project_id, @doc_id) .calledWith(@doc_id)
.should.equal true
it "should update the doc with the new doc lines", ->
@MongoManager.updateDoc
.calledWith(@project_id, @mongoPath, @newDocLines)
.should.equal true .should.equal true
it "should upsert the document to the doc collection", -> it "should upsert the document to the doc collection", ->
@MongoManager.upsertIntoDocCollection @MongoManager.upsertIntoDocCollection
.calledWith(@project_id, @doc_id, @newDocLines, @rev) .calledWith(@project_id, @doc_id, @newDocLines)
.should.equal true .should.equal true
it "should log out the old and new doc lines", -> it "should log out the old and new doc lines", ->
@ -234,13 +175,25 @@ 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 there is a generic error getting the doc", ->
beforeEach ->
@error = new Error("doc could not be found")
@MongoManager.findDoc = sinon.stub().callsArgWith(1, @error, null, null)
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback
it "should not upsert the document to the doc collection", ->
@MongoManager.upsertIntoDocCollection.called.should.equal false
it "should return the callback with the error", ->
@callback.calledWith(@error).should.equal true
describe "when the doc lines have not changed", -> describe "when the doc lines have not changed", ->
beforeEach -> beforeEach ->
@DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc)
@DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback
it "should not update the doc", -> it "should not update the doc", ->
@MongoManager.updateDoc.called.should.equal false
@MongoManager.upsertIntoDocCollection.called.should.equal false @MongoManager.upsertIntoDocCollection.called.should.equal false
it "should return the callback with the existing rev", -> it "should return the callback with the existing rev", ->
@ -251,114 +204,27 @@ describe "DocManager", ->
beforeEach -> beforeEach ->
@doc.lines = [] @doc.lines = []
@DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc)
@DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback
it "should still upsert the doc even though the lines are the same", ->
@MongoManager.updateDoc
.calledWith(@project_id, @mongoPath, [])
.should.equal true
it "should upsert the document to the doc collection", -> it "should upsert the document to the doc collection", ->
@MongoManager.upsertIntoDocCollection @MongoManager.upsertIntoDocCollection
.calledWith(@project_id, @doc_id, [], @rev) .calledWith(@project_id, @doc_id, @doc.lines)
.should.equal true .should.equal true
describe "when the doc does not exist", -> describe "when the doc does not exist", ->
beforeEach -> beforeEach ->
@DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null, null)
@DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback
it "should upsert the document to the doc collection", ->
@MongoManager.upsertIntoDocCollection
.calledWith(@project_id, @doc_id, @newDocLines)
.should.equal true
it "should not try to update the doc", -> it "should return the callback with the new rev", ->
@MongoManager.updateDoc.called.should.equal false @callback.calledWith(null, true, 1).should.equal true
@MongoManager.upsertIntoDocCollection.called.should.equal false
it "should return a NotFoundError", ->
@callback
.calledWith(new Errors.NotFoundError("No such project/doc: #{@project_id}/#{@doc_id}"))
.should.equal true
describe "findDocInProject", ->
it "should find the doc when it is in the root folder", (done) ->
@DocManager.findDocInProject {
rootFolder: [{
docs: [{
_id: ObjectId(@doc_id)
}]
}]
}, @doc_id, (error, doc, mongoPath) =>
expect(doc).to.deep.equal { _id: ObjectId(@doc_id) }
mongoPath.should.equal "rootFolder.0.docs.0"
done()
it "should find the doc when it is in a sub folder", (done) ->
@DocManager.findDocInProject {
rootFolder: [{
folders: [{
docs: [{
_id: ObjectId(@doc_id)
}]
}]
}]
}, @doc_id, (error, doc, mongoPath) =>
expect(doc).to.deep.equal { _id: ObjectId(@doc_id) }
mongoPath.should.equal "rootFolder.0.folders.0.docs.0"
done()
it "should find the doc when it there are other docs", (done) ->
@DocManager.findDocInProject {
rootFolder: [{
folders: [{
docs: [{
_id: ObjectId()
}]
}, {
docs: [{
_id: ObjectId()
}, {
_id: ObjectId(@doc_id)
}]
}],
docs: [{
_id: ObjectId()
}]
}]
}, @doc_id, (error, doc, mongoPath) =>
expect(doc).to.deep.equal { _id: ObjectId(@doc_id) }
mongoPath.should.equal "rootFolder.0.folders.1.docs.1"
done()
it "should return null when the doc doesn't exist", (done) ->
@DocManager.findDocInProject {
rootFolder: [{
folders: [{
docs: []
}]
}]
}, @doc_id, (error, doc, mongoPath) =>
expect(doc).to.be.null
expect(mongoPath).to.be.null
done()
describe "findAllDocsInProject", ->
it "should return all the docs", (done) ->
@DocManager.findAllDocsInProject {
rootFolder: [{
docs: [
@doc1 = { _id: ObjectId() }
],
folders: [{
docs: [
@doc2 = { _id: ObjectId() }
]
}, {
docs: [
@doc3 = { _id: ObjectId() }
@doc4 = { _id: ObjectId() }
]
}]
}]
}, (error, docs) =>
expect(docs).to.deep.equal [@doc1, @doc2, @doc3, @doc4]
done()

View file

@ -9,29 +9,13 @@ describe "MongoManager", ->
beforeEach -> beforeEach ->
@MongoManager = SandboxedModule.require modulePath, requires: @MongoManager = SandboxedModule.require modulePath, requires:
"./mongojs": "./mongojs":
db: @db = { projects: {}, docs: {} } db: @db = { docs: {} }
ObjectId: ObjectId ObjectId: ObjectId
@project_id = ObjectId().toString() @project_id = ObjectId().toString()
@doc_id = ObjectId().toString() @doc_id = ObjectId().toString()
@callback = sinon.stub() @callback = sinon.stub()
@stubbedErr = new Error("hello world") @stubbedErr = new Error("hello world")
describe "findProject", ->
beforeEach ->
@project = { name: "mock-project" }
@db.projects.find = sinon.stub().callsArgWith(2, null, [@project])
@MongoManager.findProject @project_id, @callback
it "should find the project", ->
@db.projects.find
.calledWith({
_id: ObjectId(@project_id)
}, {})
.should.equal true
it "should call the callback with the project", ->
@callback.calledWith(null, @project).should.equal true
describe "findDoc", -> describe "findDoc", ->
beforeEach -> beforeEach ->
@doc = { name: "mock-doc" } @doc = { name: "mock-doc" }
@ -48,28 +32,24 @@ describe "MongoManager", ->
it "should call the callback with the doc", -> it "should call the callback with the doc", ->
@callback.calledWith(null, @doc).should.equal true @callback.calledWith(null, @doc).should.equal true
describe "updateDoc", -> describe "getProjectsDocs", ->
beforeEach -> beforeEach ->
@lines = ["mock-lines"] @doc1 = { name: "mock-doc1" }
@docPath = "rootFolder.0.folders.1.docs.0" @doc2 = { name: "mock-doc2" }
@db.projects.update = sinon.stub().callsArg(2) @doc3 = { name: "mock-doc3" }
@MongoManager.updateDoc @project_id, @docPath, @lines, @callback @doc4 = { name: "mock-doc4" }
@db.docs.find = sinon.stub().callsArgWith(2, null, [@doc, @doc3, @doc4])
@MongoManager.getProjectsDocs @project_id, @callback
it "should update the doc lines and increment the TPDS rev", -> it "should find the docs via the project_id", ->
@db.projects.update @db.docs.find
.calledWith({ .calledWith({
_id: ObjectId(@project_id) project_id: ObjectId(@project_id)
}, { }, {})
$set:
"rootFolder.0.folders.1.docs.0.lines": @lines
$inc:
"rootFolder.0.folders.1.docs.0.rev": 1
})
.should.equal true .should.equal true
it "should call the callback with the project", -> it "should call the callback with the docs", ->
@callback.called.should.equal true @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true
describe "upsertIntoDocCollection", -> describe "upsertIntoDocCollection", ->
beforeEach -> beforeEach ->
@ -77,16 +57,16 @@ describe "MongoManager", ->
@oldRev = 77 @oldRev = 77
it "should upsert the document", (done)-> it "should upsert the document", (done)->
@MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=>
args = @db.docs.update.args[0] args = @db.docs.update.args[0]
assert.deepEqual args[0], {_id: ObjectId(@doc_id)} assert.deepEqual args[0], {_id: ObjectId(@doc_id)}
assert.equal args[1]["$set"]["lines"], @lines assert.equal args[1]["$set"]["lines"], @lines
assert.equal args[1]["$set"]["rev"], 78 assert.equal args[1]["$inc"]["rev"], 1
assert.deepEqual args[1]["$set"]["project_id"], ObjectId(@project_id) assert.deepEqual args[1]["$set"]["project_id"], ObjectId(@project_id)
done() done()
it "should return the error", (done)-> it "should return the error", (done)->
@MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=>
err.should.equal @stubbedErr err.should.equal @stubbedErr
done() done()