Merge pull request #7581 from overleaf/em-docstore-decaf

Decaf cleanup in docstore

GitOrigin-RevId: 84553cec7f184d567dc796c4016d6a412fb8db99
This commit is contained in:
Eric Mc Sween 2022-04-19 08:28:47 -04:00 committed by Copybot
parent e0d5cf4b42
commit 552d6d4baa
4 changed files with 643 additions and 709 deletions

View file

@ -1,66 +1,45 @@
/* eslint-disable
camelcase,
valid-typeof,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
let HttpController
const DocManager = require('./DocManager') const DocManager = require('./DocManager')
const logger = require('@overleaf/logger') const logger = require('@overleaf/logger')
const DocArchive = require('./DocArchiveManager') const DocArchive = require('./DocArchiveManager')
const HealthChecker = require('./HealthChecker') const HealthChecker = require('./HealthChecker')
const Settings = require('@overleaf/settings') const Settings = require('@overleaf/settings')
module.exports = HttpController = { function getDoc(req, res, next) {
getDoc(req, res, next) { const { doc_id: docId, project_id: projectId } = req.params
if (next == null) { const includeDeleted = req.query.include_deleted === 'true'
next = function () {} logger.log({ projectId, docId }, 'getting doc')
} DocManager.getFullDoc(projectId, docId, function (error, doc) {
const { project_id } = req.params if (error) {
const { doc_id } = req.params
const include_deleted =
(req.query != null ? req.query.include_deleted : undefined) === 'true'
logger.log({ project_id, doc_id }, 'getting doc')
return DocManager.getFullDoc(project_id, doc_id, function (error, doc) {
if (error != null) {
return next(error) return next(error)
} }
logger.log({ doc_id, project_id }, 'got doc') logger.log({ docId, projectId }, 'got doc')
if (doc == null) { if (doc == null) {
return res.sendStatus(404) res.sendStatus(404)
} else if (doc.deleted && !include_deleted) { } else if (doc.deleted && !includeDeleted) {
return res.sendStatus(404) res.sendStatus(404)
} else { } else {
return res.json(HttpController._buildDocView(doc)) res.json(_buildDocView(doc))
} }
}) })
}, }
peekDoc(req, res, next) { function peekDoc(req, res, next) {
const { project_id } = req.params const { doc_id: docId, project_id: projectId } = req.params
const { doc_id } = req.params logger.log({ projectId, docId }, 'peeking doc')
logger.log({ project_id, doc_id }, 'peeking doc') DocManager.peekDoc(projectId, docId, function (error, doc) {
DocManager.peekDoc(project_id, doc_id, function (error, doc) {
if (error) { if (error) {
return next(error) return next(error)
} }
if (doc == null) { if (doc == null) {
return res.sendStatus(404) res.sendStatus(404)
} else { } else {
res.setHeader('x-doc-status', doc.inS3 ? 'archived' : 'active') res.setHeader('x-doc-status', doc.inS3 ? 'archived' : 'active')
return res.json(HttpController._buildDocView(doc)) res.json(_buildDocView(doc))
} }
}) })
}, }
isDocDeleted(req, res, next) { function isDocDeleted(req, res, next) {
const { doc_id: docId, project_id: projectId } = req.params const { doc_id: docId, project_id: projectId } = req.params
DocManager.isDocDeleted(projectId, docId, function (error, deleted) { DocManager.isDocDeleted(projectId, docId, function (error, deleted) {
if (error) { if (error) {
@ -68,153 +47,134 @@ module.exports = HttpController = {
} }
res.json({ deleted }) res.json({ deleted })
}) })
},
getRawDoc(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
const { doc_id } = req.params function getRawDoc(req, res, next) {
logger.log({ project_id, doc_id }, 'getting raw doc') const { doc_id: docId, project_id: projectId } = req.params
return DocManager.getDocLines(project_id, doc_id, function (error, doc) { logger.log({ projectId, docId }, 'getting raw doc')
if (error != null) { DocManager.getDocLines(projectId, docId, function (error, doc) {
if (error) {
return next(error) return next(error)
} }
if (doc == null) { if (doc == null) {
return res.sendStatus(404) res.sendStatus(404)
} else { } else {
res.setHeader('content-type', 'text/plain') res.setHeader('content-type', 'text/plain')
return res.send(HttpController._buildRawDocView(doc)) res.send(_buildRawDocView(doc))
} }
}) })
},
getAllDocs(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
logger.log({ project_id }, 'getting all docs') function getAllDocs(req, res, next) {
return DocManager.getAllNonDeletedDocs( const { project_id: projectId } = req.params
project_id, logger.log({ projectId }, 'getting all docs')
DocManager.getAllNonDeletedDocs(
projectId,
{ lines: true, rev: true }, { lines: true, rev: true },
function (error, docs) { function (error, docs) {
if (docs == null) { if (docs == null) {
docs = [] docs = []
} }
if (error != null) { if (error) {
return next(error) return next(error)
} }
return res.json(HttpController._buildDocsArrayView(project_id, docs)) res.json(_buildDocsArrayView(projectId, docs))
} }
) )
}, }
getAllDeletedDocs(req, res, next) { function getAllDeletedDocs(req, res, next) {
const { project_id } = req.params const { project_id: projectId } = req.params
logger.log({ project_id }, 'getting all deleted docs') logger.log({ projectId }, 'getting all deleted docs')
DocManager.getAllDeletedDocs( DocManager.getAllDeletedDocs(
project_id, projectId,
{ name: true, deletedAt: true }, { name: true, deletedAt: true },
function (error, docs) { function (error, docs) {
if (error) { if (error) {
return next(error) return next(error)
} }
res.json( res.json(
docs.map(doc => { docs.map(doc => ({
return {
_id: doc._id.toString(), _id: doc._id.toString(),
name: doc.name, name: doc.name,
deletedAt: doc.deletedAt, deletedAt: doc.deletedAt,
} }))
})
) )
} }
) )
}, }
getAllRanges(req, res, next) { function getAllRanges(req, res, next) {
if (next == null) { const { project_id: projectId } = req.params
next = function () {} logger.log({ projectId }, 'getting all ranges')
} DocManager.getAllNonDeletedDocs(
const { project_id } = req.params projectId,
logger.log({ project_id }, 'getting all ranges')
return DocManager.getAllNonDeletedDocs(
project_id,
{ ranges: true }, { ranges: true },
function (error, docs) { function (error, docs) {
if (docs == null) { if (docs == null) {
docs = [] docs = []
} }
if (error != null) { if (error) {
return next(error) return next(error)
} }
return res.json(HttpController._buildDocsArrayView(project_id, docs)) res.json(_buildDocsArrayView(projectId, docs))
} }
) )
},
updateDoc(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
const { doc_id } = req.params function updateDoc(req, res, next) {
const lines = req.body != null ? req.body.lines : undefined const { doc_id: docId, project_id: projectId } = req.params
const version = req.body != null ? req.body.version : undefined const lines = req.body?.lines
const ranges = req.body != null ? req.body.ranges : undefined const version = req.body?.version
const ranges = req.body?.ranges
if (lines == null || !(lines instanceof Array)) { if (lines == null || !(lines instanceof Array)) {
logger.error({ project_id, doc_id }, 'no doc lines provided') logger.error({ projectId, docId }, 'no doc lines provided')
res.sendStatus(400) // Bad Request res.sendStatus(400) // Bad Request
return return
} }
if (version == null || typeof version === !'number') { if (version == null || typeof version !== 'number') {
logger.error({ project_id, doc_id }, 'no doc version provided') logger.error({ projectId, docId }, 'no doc version provided')
res.sendStatus(400) // Bad Request res.sendStatus(400) // Bad Request
return return
} }
if (ranges == null) { if (ranges == null) {
logger.error({ project_id, doc_id }, 'no doc ranges provided') logger.error({ projectId, docId }, 'no doc ranges provided')
res.sendStatus(400) // Bad Request res.sendStatus(400) // Bad Request
return return
} }
const bodyLength = lines.reduce((len, line) => line.length + len, 0) const bodyLength = lines.reduce((len, line) => line.length + len, 0)
if (bodyLength > Settings.max_doc_length) { if (bodyLength > Settings.max_doc_length) {
logger.error( logger.error({ projectId, docId, bodyLength }, 'document body too large')
{ project_id, doc_id, bodyLength },
'document body too large'
)
res.status(413).send('document body too large') res.status(413).send('document body too large')
return return
} }
logger.log({ project_id, doc_id }, 'got http request to update doc') logger.log({ projectId, docId }, 'got http request to update doc')
return DocManager.updateDoc( DocManager.updateDoc(
project_id, projectId,
doc_id, docId,
lines, lines,
version, version,
ranges, ranges,
function (error, modified, rev) { function (error, modified, rev) {
if (error != null) { if (error) {
return next(error) return next(error)
} }
return res.json({ res.json({
modified, modified,
rev, rev,
}) })
} }
) )
}, }
patchDoc(req, res, next) { function patchDoc(req, res, next) {
const { project_id, doc_id } = req.params const { doc_id: docId, project_id: projectId } = req.params
logger.log({ project_id, doc_id }, 'patching doc') logger.log({ projectId, docId }, 'patching doc')
const allowedFields = ['deleted', 'deletedAt', 'name'] const allowedFields = ['deleted', 'deletedAt', 'name']
const meta = {} const meta = {}
@ -225,105 +185,112 @@ module.exports = HttpController = {
logger.fatal({ field }, 'joi validation for pathDoc is broken') logger.fatal({ field }, 'joi validation for pathDoc is broken')
} }
}) })
DocManager.patchDoc(project_id, doc_id, meta, function (error) { DocManager.patchDoc(projectId, docId, meta, function (error) {
if (error) { if (error) {
return next(error) return next(error)
} }
res.sendStatus(204) res.sendStatus(204)
}) })
}, }
_buildDocView(doc) { function _buildDocView(doc) {
const doc_view = { _id: doc._id != null ? doc._id.toString() : undefined } const docView = { _id: doc._id?.toString() }
for (const attribute of ['lines', 'rev', 'version', 'ranges', 'deleted']) { for (const attribute of ['lines', 'rev', 'version', 'ranges', 'deleted']) {
if (doc[attribute] != null) { if (doc[attribute] != null) {
doc_view[attribute] = doc[attribute] docView[attribute] = doc[attribute]
} }
} }
return doc_view return docView
}, }
_buildRawDocView(doc) { function _buildRawDocView(doc) {
return ((doc != null ? doc.lines : undefined) || []).join('\n') return (doc?.lines ?? []).join('\n')
}, }
_buildDocsArrayView(project_id, docs) { function _buildDocsArrayView(projectId, docs) {
const docViews = [] const docViews = []
for (const doc of Array.from(docs)) { for (const doc of docs) {
if (doc != null) { if (doc != null) {
// There can end up being null docs for some reason :( (probably a race condition) // There can end up being null docs for some reason :( (probably a race condition)
docViews.push(HttpController._buildDocView(doc)) docViews.push(_buildDocView(doc))
} else { } else {
logger.error( logger.error(
{ err: new Error('null doc'), project_id }, { err: new Error('null doc'), projectId },
'encountered null doc' 'encountered null doc'
) )
} }
} }
return docViews return docViews
},
archiveAllDocs(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
logger.log({ project_id }, 'archiving all docs')
return DocArchive.archiveAllDocs(project_id, function (error) {
if (error != null) {
return next(error)
}
return res.sendStatus(204)
})
},
archiveDoc(req, res, next) { function archiveAllDocs(req, res, next) {
const { project_id, doc_id } = req.params const { project_id: projectId } = req.params
logger.log({ project_id, doc_id }, 'archiving a doc') logger.log({ projectId }, 'archiving all docs')
DocArchive.archiveDocById(project_id, doc_id, function (error) { DocArchive.archiveAllDocs(projectId, function (error) {
if (error) { if (error) {
return next(error) return next(error)
} }
res.sendStatus(204) res.sendStatus(204)
}) })
},
unArchiveAllDocs(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
logger.log({ project_id }, 'unarchiving all docs') function archiveDoc(req, res, next) {
return DocArchive.unArchiveAllDocs(project_id, function (error) { const { doc_id: docId, project_id: projectId } = req.params
if (error != null) { logger.log({ projectId, docId }, 'archiving a doc')
DocArchive.archiveDocById(projectId, docId, function (error) {
if (error) {
return next(error) return next(error)
} }
return res.sendStatus(200) res.sendStatus(204)
}) })
},
destroyAllDocs(req, res, next) {
if (next == null) {
next = function () {}
} }
const { project_id } = req.params
logger.log({ project_id }, 'destroying all docs') function unArchiveAllDocs(req, res, next) {
return DocArchive.destroyAllDocs(project_id, function (error) { const { project_id: projectId } = req.params
if (error != null) { logger.log({ projectId }, 'unarchiving all docs')
DocArchive.unArchiveAllDocs(projectId, function (error) {
if (error) {
return next(error) return next(error)
} }
return res.sendStatus(204) res.sendStatus(200)
}) })
}, }
healthCheck(req, res) { function destroyAllDocs(req, res, next) {
return HealthChecker.check(function (err) { const { project_id: projectId } = req.params
if (err != null) { logger.log({ projectId }, 'destroying all docs')
DocArchive.destroyAllDocs(projectId, function (error) {
if (error) {
return next(error)
}
res.sendStatus(204)
})
}
function healthCheck(req, res) {
HealthChecker.check(function (err) {
if (err) {
logger.err({ err }, 'error performing health check') logger.err({ err }, 'error performing health check')
return res.sendStatus(500) res.sendStatus(500)
} else { } else {
return res.sendStatus(200) res.sendStatus(200)
} }
}) })
}, }
module.exports = {
getDoc,
peekDoc,
isDocDeleted,
getRawDoc,
getAllDocs,
getAllDeletedDocs,
getAllRanges,
updateDoc,
patchDoc,
archiveAllDocs,
archiveDoc,
unArchiveAllDocs,
destroyAllDocs,
healthCheck,
} }

View file

@ -1,15 +1,3 @@
/* eslint-disable
camelcase,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
let MongoManager
const { db, ObjectId } = require('./mongodb') const { db, ObjectId } = require('./mongodb')
const logger = require('@overleaf/logger') const logger = require('@overleaf/logger')
const metrics = require('@overleaf/metrics') const metrics = require('@overleaf/metrics')
@ -17,28 +5,24 @@ const Settings = require('@overleaf/settings')
const Errors = require('./Errors') const Errors = require('./Errors')
const { promisify } = require('util') const { promisify } = require('util')
module.exports = MongoManager = { function findDoc(projectId, docId, filter, callback) {
findDoc(project_id, doc_id, filter, callback) {
if (callback == null) {
callback = function () {}
}
db.docs.findOne( db.docs.findOne(
{ {
_id: ObjectId(doc_id.toString()), _id: ObjectId(docId.toString()),
project_id: ObjectId(project_id.toString()), project_id: ObjectId(projectId.toString()),
}, },
{ {
projection: filter, projection: filter,
}, },
callback callback
) )
}, }
getProjectsDeletedDocs(project_id, filter, callback) { function getProjectsDeletedDocs(projectId, filter, callback) {
db.docs db.docs
.find( .find(
{ {
project_id: ObjectId(project_id.toString()), project_id: ObjectId(projectId.toString()),
deleted: true, deleted: true,
}, },
{ {
@ -48,10 +32,10 @@ module.exports = MongoManager = {
} }
) )
.toArray(callback) .toArray(callback)
}, }
getProjectsDocs(project_id, options, filter, callback) { function getProjectsDocs(projectId, options, filter, callback) {
const query = { project_id: ObjectId(project_id.toString()) } const query = { project_id: ObjectId(projectId.toString()) }
if (!options.include_deleted) { if (!options.include_deleted) {
query.deleted = { $ne: true } query.deleted = { $ne: true }
} }
@ -62,38 +46,38 @@ module.exports = MongoManager = {
queryOptions.limit = options.limit queryOptions.limit = options.limit
} }
db.docs.find(query, queryOptions).toArray(callback) db.docs.find(query, queryOptions).toArray(callback)
}, }
getArchivedProjectDocs(project_id, maxResults, callback) { function getArchivedProjectDocs(projectId, maxResults, callback) {
const query = { const query = {
project_id: ObjectId(project_id.toString()), project_id: ObjectId(projectId.toString()),
inS3: true, inS3: true,
} }
db.docs db.docs
.find(query, { projection: { _id: 1 }, limit: maxResults }) .find(query, { projection: { _id: 1 }, limit: maxResults })
.toArray(callback) .toArray(callback)
}, }
getNonArchivedProjectDocs(project_id, maxResults, callback) { function getNonArchivedProjectDocs(projectId, maxResults, callback) {
const query = { const query = {
project_id: ObjectId(project_id.toString()), project_id: ObjectId(projectId.toString()),
inS3: { $ne: true }, inS3: { $ne: true },
} }
db.docs.find(query, { limit: maxResults }).toArray(callback) db.docs.find(query, { limit: maxResults }).toArray(callback)
}, }
getNonDeletedArchivedProjectDocs(project_id, maxResults, callback) { function getNonDeletedArchivedProjectDocs(projectId, maxResults, callback) {
const query = { const query = {
project_id: ObjectId(project_id.toString()), project_id: ObjectId(projectId.toString()),
deleted: { $ne: true }, deleted: { $ne: true },
inS3: true, inS3: true,
} }
db.docs db.docs
.find(query, { projection: { _id: 1 }, limit: maxResults }) .find(query, { projection: { _id: 1 }, limit: maxResults })
.toArray(callback) .toArray(callback)
}, }
upsertIntoDocCollection(project_id, doc_id, updates, callback) { function upsertIntoDocCollection(projectId, docId, updates, callback) {
const update = { const update = {
$set: updates, $set: updates,
$inc: { $inc: {
@ -103,27 +87,27 @@ module.exports = MongoManager = {
inS3: true, inS3: true,
}, },
} }
update.$set.project_id = ObjectId(project_id) update.$set.project_id = ObjectId(projectId)
db.docs.updateOne( db.docs.updateOne(
{ _id: ObjectId(doc_id) }, { _id: ObjectId(docId) },
update, update,
{ upsert: true }, { upsert: true },
callback callback
) )
}, }
patchDoc(project_id, doc_id, meta, callback) { function patchDoc(projectId, docId, meta, callback) {
db.docs.updateOne( db.docs.updateOne(
{ {
_id: ObjectId(doc_id), _id: ObjectId(docId),
project_id: ObjectId(project_id), project_id: ObjectId(projectId),
}, },
{ $set: meta }, { $set: meta },
callback callback
) )
}, }
markDocAsArchived(doc_id, rev, callback) { function markDocAsArchived(docId, rev, callback) {
const update = { const update = {
$set: {}, $set: {},
$unset: {}, $unset: {},
@ -132,19 +116,16 @@ module.exports = MongoManager = {
update.$unset.lines = true update.$unset.lines = true
update.$unset.ranges = true update.$unset.ranges = true
const query = { const query = {
_id: doc_id, _id: docId,
rev, rev,
} }
db.docs.updateOne(query, update, callback) db.docs.updateOne(query, update, callback)
},
getDocVersion(doc_id, callback) {
if (callback == null) {
callback = function () {}
} }
function getDocVersion(docId, callback) {
db.docOps.findOne( db.docOps.findOne(
{ {
doc_id: ObjectId(doc_id), doc_id: ObjectId(docId),
}, },
{ {
projection: { projection: {
@ -152,21 +133,18 @@ module.exports = MongoManager = {
}, },
}, },
function (error, doc) { function (error, doc) {
if (error != null) { if (error) {
return callback(error) return callback(error)
} }
callback(null, (doc && doc.version) || 0) callback(null, (doc && doc.version) || 0)
} }
) )
},
setDocVersion(doc_id, version, callback) {
if (callback == null) {
callback = function () {}
} }
function setDocVersion(docId, version, callback) {
db.docOps.updateOne( db.docOps.updateOne(
{ {
doc_id: ObjectId(doc_id), doc_id: ObjectId(docId),
}, },
{ {
$set: { version }, $set: { version },
@ -176,32 +154,32 @@ module.exports = MongoManager = {
}, },
callback callback
) )
}, }
getDocRev(doc_id, callback) { function getDocRev(docId, callback) {
db.docs.findOne( db.docs.findOne(
{ {
_id: ObjectId(doc_id.toString()), _id: ObjectId(docId.toString()),
}, },
{ {
projection: { rev: 1 }, projection: { rev: 1 },
}, },
function (err, doc) { function (err, doc) {
if (err != null) { if (err) {
return callback(err) return callback(err)
} }
callback(null, doc && doc.rev) callback(null, doc && doc.rev)
} }
) )
}, }
// Helper method to support optimistic locking. Call the provided method for // Helper method to support optimistic locking. Call the provided method for
// an existing doc and return the result if the rev in mongo is unchanged when // an existing doc and return the result if the rev in mongo is unchanged when
// checked afterwards. If the rev has changed, return a DocModifiedError. // checked afterwards. If the rev has changed, return a DocModifiedError.
withRevCheck(doc, method, callback) { function withRevCheck(doc, method, callback) {
method(doc._id, function (err, result) { method(doc._id, function (err, result) {
if (err) return callback(err) if (err) return callback(err)
MongoManager.getDocRev(doc._id, function (err, currentRev) { getDocRev(doc._id, function (err, currentRev) {
if (err) return callback(err) if (err) return callback(err)
if (isNaN(currentRev) || isNaN(doc.rev)) { if (isNaN(currentRev) || isNaN(doc.rev)) {
return callback( return callback(
@ -221,35 +199,49 @@ module.exports = MongoManager = {
}) })
) )
} }
return callback(null, result) callback(null, result)
}) })
}) })
}, }
destroyDoc(doc_id, callback) { function destroyDoc(docId, callback) {
db.docs.deleteOne( db.docs.deleteOne(
{ {
_id: ObjectId(doc_id), _id: ObjectId(docId),
}, },
function (err) { function (err) {
if (err != null) { if (err) {
return callback(err) return callback(err)
} }
db.docOps.deleteOne( db.docOps.deleteOne(
{ {
doc_id: ObjectId(doc_id), doc_id: ObjectId(docId),
}, },
callback callback
) )
} }
) )
},
} }
const methods = Object.getOwnPropertyNames(MongoManager) module.exports = {
findDoc,
getProjectsDeletedDocs,
getProjectsDocs,
getArchivedProjectDocs,
getNonArchivedProjectDocs,
getNonDeletedArchivedProjectDocs,
upsertIntoDocCollection,
patchDoc,
markDocAsArchived,
getDocVersion,
setDocVersion,
withRevCheck,
destroyDoc,
}
const methods = Object.getOwnPropertyNames(module.exports)
module.exports.promises = {} module.exports.promises = {}
for (const method of methods) { for (const method of methods) {
metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) metrics.timeAsyncMethod(module.exports, method, 'mongo.MongoManager', logger)
module.exports.promises[method] = promisify(module.exports[method]) module.exports.promises[method] = promisify(module.exports[method])
} }

View file

@ -1,14 +1,3 @@
/* eslint-disable
no-return-assign,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const SandboxedModule = require('sandboxed-module') const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon') const sinon = require('sinon')
const { assert, expect } = require('chai') const { assert, expect } = require('chai')
@ -40,46 +29,46 @@ describe('HttpController', function () {
this.res.status = sinon.stub().returns(this.res) this.res.status = sinon.stub().returns(this.res)
this.req = { query: {} } this.req = { query: {} }
this.next = sinon.stub() this.next = sinon.stub()
this.project_id = 'mock-project-id' this.projectId = 'mock-project-id'
this.doc_id = 'mock-doc-id' this.docId = 'mock-doc-id'
this.doc = { this.doc = {
_id: this.doc_id, _id: this.docId,
lines: ['mock', 'lines', ' here', '', '', ' spaces '], lines: ['mock', 'lines', ' here', '', '', ' spaces '],
version: 42, version: 42,
rev: 5, rev: 5,
} }
return (this.deletedDoc = { this.deletedDoc = {
deleted: true, deleted: true,
_id: this.doc_id, _id: this.docId,
lines: ['mock', 'lines', ' here', '', '', ' spaces '], lines: ['mock', 'lines', ' here', '', '', ' spaces '],
version: 42, version: 42,
rev: 5, rev: 5,
}) }
}) })
describe('getDoc', function () { describe('getDoc', function () {
describe('without deleted docs', function () { describe('without deleted docs', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { this.req.params = {
project_id: this.project_id, project_id: this.projectId,
doc_id: this.doc_id, doc_id: this.docId,
} }
this.DocManager.getFullDoc = sinon this.DocManager.getFullDoc = sinon
.stub() .stub()
.callsArgWith(2, null, this.doc) .callsArgWith(2, null, this.doc)
return this.HttpController.getDoc(this.req, this.res, this.next) this.HttpController.getDoc(this.req, this.res, this.next)
}) })
it('should get the document with the version (including deleted)', function () { it('should get the document with the version (including deleted)', function () {
return this.DocManager.getFullDoc this.DocManager.getFullDoc
.calledWith(this.project_id, this.doc_id) .calledWith(this.projectId, this.docId)
.should.equal(true) .should.equal(true)
}) })
return it('should return the doc as JSON', function () { it('should return the doc as JSON', function () {
return this.res.json this.res.json
.calledWith({ .calledWith({
_id: this.doc_id, _id: this.docId,
lines: this.doc.lines, lines: this.doc.lines,
rev: this.doc.rev, rev: this.doc.rev,
version: this.doc.version, version: this.doc.version,
@ -88,35 +77,35 @@ describe('HttpController', function () {
}) })
}) })
return describe('which is deleted', function () { describe('which is deleted', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { this.req.params = {
project_id: this.project_id, project_id: this.projectId,
doc_id: this.doc_id, doc_id: this.docId,
} }
return (this.DocManager.getFullDoc = sinon this.DocManager.getFullDoc = sinon
.stub() .stub()
.callsArgWith(2, null, this.deletedDoc)) .callsArgWith(2, null, this.deletedDoc)
}) })
it('should get the doc from the doc manager', function () { it('should get the doc from the doc manager', function () {
this.HttpController.getDoc(this.req, this.res, this.next) this.HttpController.getDoc(this.req, this.res, this.next)
return this.DocManager.getFullDoc this.DocManager.getFullDoc
.calledWith(this.project_id, this.doc_id) .calledWith(this.projectId, this.docId)
.should.equal(true) .should.equal(true)
}) })
it('should return 404 if the query string delete is not set ', function () { it('should return 404 if the query string delete is not set ', function () {
this.HttpController.getDoc(this.req, this.res, this.next) this.HttpController.getDoc(this.req, this.res, this.next)
return this.res.sendStatus.calledWith(404).should.equal(true) this.res.sendStatus.calledWith(404).should.equal(true)
}) })
return it('should return the doc as JSON if include_deleted is set to true', function () { it('should return the doc as JSON if include_deleted is set to true', function () {
this.req.query.include_deleted = 'true' this.req.query.include_deleted = 'true'
this.HttpController.getDoc(this.req, this.res, this.next) this.HttpController.getDoc(this.req, this.res, this.next)
return this.res.json this.res.json
.calledWith({ .calledWith({
_id: this.doc_id, _id: this.docId,
lines: this.doc.lines, lines: this.doc.lines,
rev: this.doc.rev, rev: this.doc.rev,
deleted: true, deleted: true,
@ -130,27 +119,27 @@ describe('HttpController', function () {
describe('getRawDoc', function () { describe('getRawDoc', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { this.req.params = {
project_id: this.project_id, project_id: this.projectId,
doc_id: this.doc_id, doc_id: this.docId,
} }
this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc) this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc)
return this.HttpController.getRawDoc(this.req, this.res, this.next) this.HttpController.getRawDoc(this.req, this.res, this.next)
}) })
it('should get the document without the version', function () { it('should get the document without the version', function () {
return this.DocManager.getDocLines this.DocManager.getDocLines
.calledWith(this.project_id, this.doc_id) .calledWith(this.projectId, this.docId)
.should.equal(true) .should.equal(true)
}) })
it('should set the content type header', function () { it('should set the content type header', function () {
return this.res.setHeader this.res.setHeader
.calledWith('content-type', 'text/plain') .calledWith('content-type', 'text/plain')
.should.equal(true) .should.equal(true)
}) })
return it('should send the raw version of the doc', function () { it('should send the raw version of the doc', function () {
return assert.deepEqual( assert.deepEqual(
this.res.send.args[0][0], this.res.send.args[0][0],
`${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}` `${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}`
) )
@ -160,7 +149,7 @@ describe('HttpController', function () {
describe('getAllDocs', function () { describe('getAllDocs', function () {
describe('normally', function () { describe('normally', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { project_id: this.project_id } this.req.params = { project_id: this.projectId }
this.docs = [ this.docs = [
{ {
_id: ObjectId(), _id: ObjectId(),
@ -176,17 +165,17 @@ describe('HttpController', function () {
this.DocManager.getAllNonDeletedDocs = sinon this.DocManager.getAllNonDeletedDocs = sinon
.stub() .stub()
.callsArgWith(2, null, this.docs) .callsArgWith(2, null, this.docs)
return this.HttpController.getAllDocs(this.req, this.res, this.next) this.HttpController.getAllDocs(this.req, this.res, this.next)
}) })
it('should get all the (non-deleted) docs', function () { it('should get all the (non-deleted) docs', function () {
return this.DocManager.getAllNonDeletedDocs this.DocManager.getAllNonDeletedDocs
.calledWith(this.project_id, { lines: true, rev: true }) .calledWith(this.projectId, { lines: true, rev: true })
.should.equal(true) .should.equal(true)
}) })
return it('should return the doc as JSON', function () { it('should return the doc as JSON', function () {
return this.res.json this.res.json
.calledWith([ .calledWith([
{ {
_id: this.docs[0]._id.toString(), _id: this.docs[0]._id.toString(),
@ -203,9 +192,9 @@ describe('HttpController', function () {
}) })
}) })
return describe('with a null doc', function () { describe('with a null doc', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { project_id: this.project_id } this.req.params = { project_id: this.projectId }
this.docs = [ this.docs = [
{ {
_id: ObjectId(), _id: ObjectId(),
@ -222,11 +211,11 @@ describe('HttpController', function () {
this.DocManager.getAllNonDeletedDocs = sinon this.DocManager.getAllNonDeletedDocs = sinon
.stub() .stub()
.callsArgWith(2, null, this.docs) .callsArgWith(2, null, this.docs)
return this.HttpController.getAllDocs(this.req, this.res, this.next) this.HttpController.getAllDocs(this.req, this.res, this.next)
}) })
it('should return the non null docs as JSON', function () { it('should return the non null docs as JSON', function () {
return this.res.json this.res.json
.calledWith([ .calledWith([
{ {
_id: this.docs[0]._id.toString(), _id: this.docs[0]._id.toString(),
@ -242,12 +231,12 @@ describe('HttpController', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should log out an error', function () { it('should log out an error', function () {
return this.logger.error this.logger.error
.calledWith( .calledWith(
{ {
err: sinon.match.has('message', 'null doc'), err: sinon.match.has('message', 'null doc'),
project_id: this.project_id, projectId: this.projectId,
}, },
'encountered null doc' 'encountered null doc'
) )
@ -257,9 +246,9 @@ describe('HttpController', function () {
}) })
describe('getAllRanges', function () { describe('getAllRanges', function () {
return describe('normally', function () { describe('normally', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { project_id: this.project_id } this.req.params = { project_id: this.projectId }
this.docs = [ this.docs = [
{ {
_id: ObjectId(), _id: ObjectId(),
@ -273,17 +262,17 @@ describe('HttpController', function () {
this.DocManager.getAllNonDeletedDocs = sinon this.DocManager.getAllNonDeletedDocs = sinon
.stub() .stub()
.callsArgWith(2, null, this.docs) .callsArgWith(2, null, this.docs)
return this.HttpController.getAllRanges(this.req, this.res, this.next) this.HttpController.getAllRanges(this.req, this.res, this.next)
}) })
it('should get all the (non-deleted) doc ranges', function () { it('should get all the (non-deleted) doc ranges', function () {
return this.DocManager.getAllNonDeletedDocs this.DocManager.getAllNonDeletedDocs
.calledWith(this.project_id, { ranges: true }) .calledWith(this.projectId, { ranges: true })
.should.equal(true) .should.equal(true)
}) })
return it('should return the doc as JSON', function () { it('should return the doc as JSON', function () {
return this.res.json this.res.json
.calledWith([ .calledWith([
{ {
_id: this.docs[0]._id.toString(), _id: this.docs[0]._id.toString(),
@ -301,10 +290,10 @@ describe('HttpController', function () {
describe('updateDoc', function () { describe('updateDoc', function () {
beforeEach(function () { beforeEach(function () {
return (this.req.params = { this.req.params = {
project_id: this.project_id, project_id: this.projectId,
doc_id: this.doc_id, doc_id: this.docId,
}) }
}) })
describe('when the doc lines exist and were updated', function () { describe('when the doc lines exist and were updated', function () {
@ -317,14 +306,14 @@ describe('HttpController', function () {
this.DocManager.updateDoc = sinon this.DocManager.updateDoc = sinon
.stub() .stub()
.yields(null, true, (this.rev = 5)) .yields(null, true, (this.rev = 5))
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
it('should update the document', function () { it('should update the document', function () {
return this.DocManager.updateDoc this.DocManager.updateDoc
.calledWith( .calledWith(
this.project_id, this.projectId,
this.doc_id, this.docId,
this.lines, this.lines,
this.version, this.version,
this.ranges this.ranges
@ -332,8 +321,8 @@ describe('HttpController', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should return a modified status', function () { it('should return a modified status', function () {
return this.res.json this.res.json
.calledWith({ modified: true, rev: this.rev }) .calledWith({ modified: true, rev: this.rev })
.should.equal(true) .should.equal(true)
}) })
@ -349,11 +338,11 @@ describe('HttpController', function () {
this.DocManager.updateDoc = sinon this.DocManager.updateDoc = sinon
.stub() .stub()
.yields(null, false, (this.rev = 5)) .yields(null, false, (this.rev = 5))
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
return it('should return a modified status', function () { it('should return a modified status', function () {
return this.res.json this.res.json
.calledWith({ modified: false, rev: this.rev }) .calledWith({ modified: false, rev: this.rev })
.should.equal(true) .should.equal(true)
}) })
@ -363,15 +352,15 @@ describe('HttpController', function () {
beforeEach(function () { beforeEach(function () {
this.req.body = { version: 42, ranges: {} } this.req.body = { version: 42, ranges: {} }
this.DocManager.updateDoc = sinon.stub().yields(null, false) this.DocManager.updateDoc = sinon.stub().yields(null, false)
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
it('should not update the document', function () { it('should not update the document', function () {
return this.DocManager.updateDoc.called.should.equal(false) this.DocManager.updateDoc.called.should.equal(false)
}) })
return it('should return a 400 (bad request) response', function () { it('should return a 400 (bad request) response', function () {
return this.res.sendStatus.calledWith(400).should.equal(true) this.res.sendStatus.calledWith(400).should.equal(true)
}) })
}) })
@ -379,15 +368,15 @@ describe('HttpController', function () {
beforeEach(function () { beforeEach(function () {
this.req.body = { version: 42, lines: ['hello world'] } this.req.body = { version: 42, lines: ['hello world'] }
this.DocManager.updateDoc = sinon.stub().yields(null, false) this.DocManager.updateDoc = sinon.stub().yields(null, false)
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
it('should not update the document', function () { it('should not update the document', function () {
return this.DocManager.updateDoc.called.should.equal(false) this.DocManager.updateDoc.called.should.equal(false)
}) })
return it('should return a 400 (bad request) response', function () { it('should return a 400 (bad request) response', function () {
return this.res.sendStatus.calledWith(400).should.equal(true) this.res.sendStatus.calledWith(400).should.equal(true)
}) })
}) })
@ -395,34 +384,34 @@ describe('HttpController', function () {
beforeEach(function () { beforeEach(function () {
this.req.body = { lines: ['foo'], version: 42 } this.req.body = { lines: ['foo'], version: 42 }
this.DocManager.updateDoc = sinon.stub().yields(null, false) this.DocManager.updateDoc = sinon.stub().yields(null, false)
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
it('should not update the document', function () { it('should not update the document', function () {
return this.DocManager.updateDoc.called.should.equal(false) this.DocManager.updateDoc.called.should.equal(false)
}) })
return it('should return a 400 (bad request) response', function () { it('should return a 400 (bad request) response', function () {
return this.res.sendStatus.calledWith(400).should.equal(true) this.res.sendStatus.calledWith(400).should.equal(true)
}) })
}) })
return describe('when the doc body is too large', function () { describe('when the doc body is too large', function () {
beforeEach(function () { beforeEach(function () {
this.req.body = { this.req.body = {
lines: (this.lines = Array(2049).fill('a'.repeat(1024))), lines: (this.lines = Array(2049).fill('a'.repeat(1024))),
version: (this.version = 42), version: (this.version = 42),
ranges: (this.ranges = { changes: 'mock' }), ranges: (this.ranges = { changes: 'mock' }),
} }
return this.HttpController.updateDoc(this.req, this.res, this.next) this.HttpController.updateDoc(this.req, this.res, this.next)
}) })
it('should return a 413 (too large) response', function () { it('should return a 413 (too large) response', function () {
return sinon.assert.calledWith(this.res.status, 413) sinon.assert.calledWith(this.res.status, 413)
}) })
return it('should report that the document body is too large', function () { it('should report that the document body is too large', function () {
return sinon.assert.calledWith(this.res.send, 'document body too large') sinon.assert.calledWith(this.res.send, 'document body too large')
}) })
}) })
}) })
@ -430,8 +419,8 @@ describe('HttpController', function () {
describe('patchDoc', function () { describe('patchDoc', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { this.req.params = {
project_id: this.project_id, project_id: this.projectId,
doc_id: this.doc_id, doc_id: this.docId,
} }
this.req.body = { name: 'foo.tex' } this.req.body = { name: 'foo.tex' }
this.DocManager.patchDoc = sinon.stub().yields(null) this.DocManager.patchDoc = sinon.stub().yields(null)
@ -440,8 +429,8 @@ describe('HttpController', function () {
it('should delete the document', function () { it('should delete the document', function () {
expect(this.DocManager.patchDoc).to.have.been.calledWith( expect(this.DocManager.patchDoc).to.have.been.calledWith(
this.project_id, this.projectId,
this.doc_id this.docId
) )
}) })
@ -466,8 +455,8 @@ describe('HttpController', function () {
it('should not pass the invalid field along', function () { it('should not pass the invalid field along', function () {
expect(this.DocManager.patchDoc).to.have.been.calledWith( expect(this.DocManager.patchDoc).to.have.been.calledWith(
this.project_id, this.projectId,
this.doc_id, this.docId,
{} {}
) )
}) })
@ -476,38 +465,38 @@ describe('HttpController', function () {
describe('archiveAllDocs', function () { describe('archiveAllDocs', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { project_id: this.project_id } this.req.params = { project_id: this.projectId }
this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1) this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1)
return this.HttpController.archiveAllDocs(this.req, this.res, this.next) this.HttpController.archiveAllDocs(this.req, this.res, this.next)
}) })
it('should archive the project', function () { it('should archive the project', function () {
return this.DocArchiveManager.archiveAllDocs this.DocArchiveManager.archiveAllDocs
.calledWith(this.project_id) .calledWith(this.projectId)
.should.equal(true) .should.equal(true)
}) })
return it('should return a 204 (No Content)', function () { it('should return a 204 (No Content)', function () {
return this.res.sendStatus.calledWith(204).should.equal(true) this.res.sendStatus.calledWith(204).should.equal(true)
}) })
}) })
return describe('destroyAllDocs', function () { describe('destroyAllDocs', function () {
beforeEach(function () { beforeEach(function () {
this.req.params = { project_id: this.project_id } this.req.params = { project_id: this.projectId }
this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1) this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1)
return this.HttpController.destroyAllDocs(this.req, this.res, this.next) this.HttpController.destroyAllDocs(this.req, this.res, this.next)
}) })
it('should destroy the docs', function () { it('should destroy the docs', function () {
return sinon.assert.calledWith( sinon.assert.calledWith(
this.DocArchiveManager.destroyAllDocs, this.DocArchiveManager.destroyAllDocs,
this.project_id this.projectId
) )
}) })
return it('should return 204', function () { it('should return 204', function () {
return sinon.assert.calledWith(this.res.sendStatus, 204) sinon.assert.calledWith(this.res.sendStatus, 204)
}) })
}) })
}) })

View file

@ -1,13 +1,3 @@
/* eslint-disable
no-return-assign,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const SandboxedModule = require('sandboxed-module') const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon') const sinon = require('sinon')
const modulePath = require('path').join( const modulePath = require('path').join(
@ -34,7 +24,7 @@ describe('MongoManager', function () {
this.project_id = ObjectId().toString() this.project_id = ObjectId().toString()
this.doc_id = ObjectId().toString() this.doc_id = ObjectId().toString()
this.callback = sinon.stub() this.callback = sinon.stub()
return (this.stubbedErr = new Error('hello world')) this.stubbedErr = new Error('hello world')
}) })
describe('findDoc', function () { describe('findDoc', function () {
@ -42,7 +32,7 @@ describe('MongoManager', function () {
this.doc = { name: 'mock-doc' } this.doc = { name: 'mock-doc' }
this.db.docs.findOne = sinon.stub().callsArgWith(2, null, this.doc) this.db.docs.findOne = sinon.stub().callsArgWith(2, null, this.doc)
this.filter = { lines: true } this.filter = { lines: true }
return this.MongoManager.findDoc( this.MongoManager.findDoc(
this.project_id, this.project_id,
this.doc_id, this.doc_id,
this.filter, this.filter,
@ -64,8 +54,8 @@ describe('MongoManager', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should call the callback with the doc', function () { it('should call the callback with the doc', function () {
return this.callback.calledWith(null, this.doc).should.equal(true) this.callback.calledWith(null, this.doc).should.equal(true)
}) })
}) })
@ -112,7 +102,7 @@ describe('MongoManager', function () {
describe('with included_deleted = false', function () { describe('with included_deleted = false', function () {
beforeEach(function () { beforeEach(function () {
return this.MongoManager.getProjectsDocs( this.MongoManager.getProjectsDocs(
this.project_id, this.project_id,
{ include_deleted: false }, { include_deleted: false },
this.filter, this.filter,
@ -121,7 +111,7 @@ describe('MongoManager', function () {
}) })
it('should find the non-deleted docs via the project_id', function () { it('should find the non-deleted docs via the project_id', function () {
return this.db.docs.find this.db.docs.find
.calledWith( .calledWith(
{ {
project_id: ObjectId(this.project_id), project_id: ObjectId(this.project_id),
@ -134,16 +124,16 @@ describe('MongoManager', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should call the callback with the docs', function () { it('should call the callback with the docs', function () {
return this.callback this.callback
.calledWith(null, [this.doc, this.doc3, this.doc4]) .calledWith(null, [this.doc, this.doc3, this.doc4])
.should.equal(true) .should.equal(true)
}) })
}) })
return describe('with included_deleted = true', function () { describe('with included_deleted = true', function () {
beforeEach(function () { beforeEach(function () {
return this.MongoManager.getProjectsDocs( this.MongoManager.getProjectsDocs(
this.project_id, this.project_id,
{ include_deleted: true }, { include_deleted: true },
this.filter, this.filter,
@ -152,7 +142,7 @@ describe('MongoManager', function () {
}) })
it('should find all via the project_id', function () { it('should find all via the project_id', function () {
return this.db.docs.find this.db.docs.find
.calledWith( .calledWith(
{ {
project_id: ObjectId(this.project_id), project_id: ObjectId(this.project_id),
@ -164,8 +154,8 @@ describe('MongoManager', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should call the callback with the docs', function () { it('should call the callback with the docs', function () {
return this.callback this.callback
.calledWith(null, [this.doc, this.doc3, this.doc4]) .calledWith(null, [this.doc, this.doc3, this.doc4])
.should.equal(true) .should.equal(true)
}) })
@ -218,11 +208,11 @@ describe('MongoManager', function () {
describe('upsertIntoDocCollection', function () { describe('upsertIntoDocCollection', function () {
beforeEach(function () { beforeEach(function () {
this.db.docs.updateOne = sinon.stub().callsArgWith(3, this.stubbedErr) this.db.docs.updateOne = sinon.stub().callsArgWith(3, this.stubbedErr)
return (this.oldRev = 77) this.oldRev = 77
}) })
it('should upsert the document', function (done) { it('should upsert the document', function (done) {
return this.MongoManager.upsertIntoDocCollection( this.MongoManager.upsertIntoDocCollection(
this.project_id, this.project_id,
this.doc_id, this.doc_id,
{ lines: this.lines }, { lines: this.lines },
@ -233,19 +223,19 @@ describe('MongoManager', function () {
assert.equal(args[1].$set.lines, this.lines) assert.equal(args[1].$set.lines, this.lines)
assert.equal(args[1].$inc.rev, 1) assert.equal(args[1].$inc.rev, 1)
assert.deepEqual(args[1].$set.project_id, ObjectId(this.project_id)) assert.deepEqual(args[1].$set.project_id, ObjectId(this.project_id))
return done() done()
} }
) )
}) })
return it('should return the error', function (done) { it('should return the error', function (done) {
return this.MongoManager.upsertIntoDocCollection( this.MongoManager.upsertIntoDocCollection(
this.project_id, this.project_id,
this.doc_id, this.doc_id,
{ lines: this.lines }, { lines: this.lines },
err => { err => {
err.should.equal(this.stubbedErr) err.should.equal(this.stubbedErr)
return done() done()
} }
) )
}) })
@ -255,17 +245,17 @@ describe('MongoManager', function () {
beforeEach(function (done) { beforeEach(function (done) {
this.db.docs.deleteOne = sinon.stub().yields() this.db.docs.deleteOne = sinon.stub().yields()
this.db.docOps.deleteOne = sinon.stub().yields() this.db.docOps.deleteOne = sinon.stub().yields()
return this.MongoManager.destroyDoc('123456789012', done) this.MongoManager.destroyDoc('123456789012', done)
}) })
it('should destroy the doc', function () { it('should destroy the doc', function () {
return sinon.assert.calledWith(this.db.docs.deleteOne, { sinon.assert.calledWith(this.db.docs.deleteOne, {
_id: ObjectId('123456789012'), _id: ObjectId('123456789012'),
}) })
}) })
return it('should destroy the docOps', function () { it('should destroy the docOps', function () {
return sinon.assert.calledWith(this.db.docOps.deleteOne, { sinon.assert.calledWith(this.db.docOps.deleteOne, {
doc_id: ObjectId('123456789012'), doc_id: ObjectId('123456789012'),
}) })
}) })
@ -276,11 +266,11 @@ describe('MongoManager', function () {
beforeEach(function () { beforeEach(function () {
this.doc = { version: (this.version = 42) } this.doc = { version: (this.version = 42) }
this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, this.doc) this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, this.doc)
return this.MongoManager.getDocVersion(this.doc_id, this.callback) this.MongoManager.getDocVersion(this.doc_id, this.callback)
}) })
it('should look for the doc in the database', function () { it('should look for the doc in the database', function () {
return this.db.docOps.findOne this.db.docOps.findOne
.calledWith( .calledWith(
{ doc_id: ObjectId(this.doc_id) }, { doc_id: ObjectId(this.doc_id) },
{ {
@ -290,19 +280,19 @@ describe('MongoManager', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should call the callback with the version', function () { it('should call the callback with the version', function () {
return this.callback.calledWith(null, this.version).should.equal(true) this.callback.calledWith(null, this.version).should.equal(true)
}) })
}) })
return describe("when the doc doesn't exist", function () { describe("when the doc doesn't exist", function () {
beforeEach(function () { beforeEach(function () {
this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, null) this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, null)
return this.MongoManager.getDocVersion(this.doc_id, this.callback) this.MongoManager.getDocVersion(this.doc_id, this.callback)
}) })
return it('should call the callback with 0', function () { it('should call the callback with 0', function () {
return this.callback.calledWith(null, 0).should.equal(true) this.callback.calledWith(null, 0).should.equal(true)
}) })
}) })
}) })
@ -311,15 +301,11 @@ describe('MongoManager', function () {
beforeEach(function () { beforeEach(function () {
this.version = 42 this.version = 42
this.db.docOps.updateOne = sinon.stub().callsArg(3) this.db.docOps.updateOne = sinon.stub().callsArg(3)
return this.MongoManager.setDocVersion( this.MongoManager.setDocVersion(this.doc_id, this.version, this.callback)
this.doc_id,
this.version,
this.callback
)
}) })
it('should update the doc version', function () { it('should update the doc version', function () {
return this.db.docOps.updateOne this.db.docOps.updateOne
.calledWith( .calledWith(
{ {
doc_id: ObjectId(this.doc_id), doc_id: ObjectId(this.doc_id),
@ -336,8 +322,8 @@ describe('MongoManager', function () {
.should.equal(true) .should.equal(true)
}) })
return it('should call the callback', function () { it('should call the callback', function () {
return this.callback.called.should.equal(true) this.callback.called.should.equal(true)
}) })
}) })