From 819aa378d99bb749804dd190d613159a3bbce56b Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:32:05 -0400 Subject: [PATCH 01/14] Decaf cleanup: remove Array.from() --- .../document-updater/app/js/ProjectManager.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 2955904adb..d48cdef0d2 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -7,7 +7,6 @@ // 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 @@ -30,7 +29,7 @@ module.exports = ProjectManager = { const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') const callback = function (...args) { timer.done() - return _callback(...Array.from(args || [])) + return _callback(...args) } return RedisManager.getDocIdsInProject(project_id, function ( @@ -42,7 +41,7 @@ module.exports = ProjectManager = { } const jobs = [] const errors = [] - for (const doc_id of Array.from(doc_ids || [])) { + for (const doc_id of doc_ids) { ;((doc_id) => jobs.push((callback) => DocumentManager.flushDocIfLoadedWithLock( @@ -92,7 +91,7 @@ module.exports = ProjectManager = { ) const callback = function (...args) { timer.done() - return _callback(...Array.from(args || [])) + return _callback(...args) } return RedisManager.getDocIdsInProject(project_id, function ( @@ -104,7 +103,7 @@ module.exports = ProjectManager = { } const jobs = [] const errors = [] - for (const doc_id of Array.from(doc_ids || [])) { + for (const doc_id of doc_ids) { ;((doc_id) => jobs.push((callback) => DocumentManager.flushAndDeleteDocWithLock( @@ -210,7 +209,7 @@ module.exports = ProjectManager = { ) const callback = function (...args) { timer.done() - return _callback(...Array.from(args || [])) + return _callback(...args) } return RedisManager.checkOrSetProjectState( @@ -243,7 +242,7 @@ module.exports = ProjectManager = { return callback(error) } const jobs = [] - for (const doc_id of Array.from(doc_ids || [])) { + for (const doc_id of doc_ids) { ;((doc_id) => jobs.push(( cb // get the doc lines from redis @@ -298,7 +297,7 @@ module.exports = ProjectManager = { const timer = new Metrics.Timer('projectManager.updateProject') const callback = function (...args) { timer.done() - return _callback(...Array.from(args || [])) + return _callback(...args) } const project_version = version @@ -389,5 +388,5 @@ module.exports = ProjectManager = { return callback() }) }) - } + }, } From 2bff83137c8ea61abf4fc76579396425f86b0b3d Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:35:10 -0400 Subject: [PATCH 02/14] Decaf cleanup: unnecessary returns --- .../document-updater/app/js/ProjectManager.js | 183 ++++++++---------- 1 file changed, 80 insertions(+), 103 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index d48cdef0d2..cc39f3f399 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -7,7 +7,6 @@ // 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 */ @@ -29,13 +28,10 @@ module.exports = ProjectManager = { const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') const callback = function (...args) { timer.done() - return _callback(...args) + _callback(...args) } - return RedisManager.getDocIdsInProject(project_id, function ( - error, - doc_ids - ) { + RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { if (error != null) { return callback(error) } @@ -53,16 +49,16 @@ module.exports = ProjectManager = { { err: error, project_id, doc_id }, 'found deleted doc when flushing' ) - return callback() + callback() } else if (error != null) { logger.error( { err: error, project_id, doc_id }, 'error flushing doc' ) errors.push(error) - return callback() + callback() } else { - return callback() + callback() } } ) @@ -70,13 +66,11 @@ module.exports = ProjectManager = { } logger.log({ project_id, doc_ids }, 'flushing docs') - return async.series(jobs, function () { + async.series(jobs, function () { if (errors.length > 0) { - return callback( - new Error('Errors flushing docs. See log for details') - ) + callback(new Error('Errors flushing docs. See log for details')) } else { - return callback(null) + callback(null) } }) }) @@ -91,13 +85,10 @@ module.exports = ProjectManager = { ) const callback = function (...args) { timer.done() - return _callback(...args) + _callback(...args) } - return RedisManager.getDocIdsInProject(project_id, function ( - error, - doc_ids - ) { + RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { if (error != null) { return callback(error) } @@ -118,14 +109,14 @@ module.exports = ProjectManager = { ) errors.push(error) } - return callback() + callback() } ) ))(doc_id) } logger.log({ project_id, doc_ids }, 'deleting docs') - return async.series(jobs, () => + async.series(jobs, () => // When deleting the project here we want to ensure that project // history is completely flushed because the project may be // deleted in web after this call completes, and so further @@ -134,13 +125,11 @@ module.exports = ProjectManager = { error ) { if (errors.length > 0) { - return callback( - new Error('Errors deleting docs. See log for details') - ) + callback(new Error('Errors deleting docs. See log for details')) } else if (error != null) { - return callback(error) + callback(error) } else { - return callback(null) + callback(null) } }) ) @@ -151,9 +140,7 @@ module.exports = ProjectManager = { if (callback == null) { callback = function (error) {} } - return RedisManager.queueFlushAndDeleteProject(project_id, function ( - error - ) { + RedisManager.queueFlushAndDeleteProject(project_id, function (error) { if (error != null) { logger.error( { project_id, error }, @@ -162,7 +149,7 @@ module.exports = ProjectManager = { return callback(error) } Metrics.inc('queued-delete') - return callback() + callback() }) }, @@ -170,24 +157,18 @@ module.exports = ProjectManager = { if (callback == null) { callback = function (error) {} } - return RedisManager.getDocIdsInProject(project_id, function ( - error, - doc_ids - ) { + RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { if (error != null) { return callback(error) } if (!(doc_ids != null ? doc_ids.length : undefined)) { return callback(null, []) } - return RedisManager.getDocTimestamps(doc_ids, function ( - error, - timestamps - ) { + RedisManager.getDocTimestamps(doc_ids, function (error, timestamps) { if (error != null) { return callback(error) } - return callback(null, timestamps) + callback(null, timestamps) }) }) }, @@ -209,77 +190,73 @@ module.exports = ProjectManager = { ) const callback = function (...args) { timer.done() - return _callback(...args) + _callback(...args) } - return RedisManager.checkOrSetProjectState( - project_id, - projectStateHash, - function (error, projectStateChanged) { + RedisManager.checkOrSetProjectState(project_id, projectStateHash, function ( + error, + projectStateChanged + ) { + if (error != null) { + logger.error( + { err: error, project_id }, + 'error getting/setting project state in getProjectDocsAndFlushIfOld' + ) + return callback(error) + } + // we can't return docs if project structure has changed + if (projectStateChanged) { + return callback( + Errors.ProjectStateChangedError('project state changed') + ) + } + // project structure hasn't changed, return doc content from redis + RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { if (error != null) { logger.error( { err: error, project_id }, - 'error getting/setting project state in getProjectDocsAndFlushIfOld' + 'error getting doc ids in getProjectDocs' ) return callback(error) } - // we can't return docs if project structure has changed - if (projectStateChanged) { - return callback( - Errors.ProjectStateChangedError('project state changed') - ) + const jobs = [] + for (const doc_id of doc_ids) { + ;((doc_id) => + jobs.push(( + cb // get the doc lines from redis + ) => + DocumentManager.getDocAndFlushIfOldWithLock( + project_id, + doc_id, + function (err, lines, version) { + if (err != null) { + logger.error( + { err, project_id, doc_id }, + 'error getting project doc lines in getProjectDocsAndFlushIfOld' + ) + return cb(err) + } + const doc = { _id: doc_id, lines, v: version } // create a doc object to return + cb(null, doc) + } + ) + ))(doc_id) } - // project structure hasn't changed, return doc content from redis - return RedisManager.getDocIdsInProject(project_id, function ( - error, - doc_ids - ) { + async.series(jobs, function (error, docs) { if (error != null) { - logger.error( - { err: error, project_id }, - 'error getting doc ids in getProjectDocs' - ) return callback(error) } - const jobs = [] - for (const doc_id of doc_ids) { - ;((doc_id) => - jobs.push(( - cb // get the doc lines from redis - ) => - DocumentManager.getDocAndFlushIfOldWithLock( - project_id, - doc_id, - function (err, lines, version) { - if (err != null) { - logger.error( - { err, project_id, doc_id }, - 'error getting project doc lines in getProjectDocsAndFlushIfOld' - ) - return cb(err) - } - const doc = { _id: doc_id, lines, v: version } // create a doc object to return - return cb(null, doc) - } - ) - ))(doc_id) - } - return async.series(jobs, function (error, docs) { - if (error != null) { - return callback(error) - } - return callback(null, docs) - }) + callback(null, docs) }) - } - ) + }) + }) }, clearProjectState(project_id, callback) { if (callback == null) { callback = function (error) {} } - return RedisManager.clearProjectState(project_id, callback) + RedisManager.clearProjectState(project_id, callback) }, updateProjectWithLocks( @@ -297,7 +274,7 @@ module.exports = ProjectManager = { const timer = new Metrics.Timer('projectManager.updateProject') const callback = function (...args) { timer.done() - return _callback(...args) + _callback(...args) } const project_version = version @@ -309,7 +286,7 @@ module.exports = ProjectManager = { const doc_id = projectUpdate.id projectUpdate.version = `${project_version}.${project_subversion++}` if (projectUpdate.docLines != null) { - return ProjectHistoryRedisManager.queueAddEntity( + ProjectHistoryRedisManager.queueAddEntity( project_id, projectHistoryId, 'doc', @@ -318,11 +295,11 @@ module.exports = ProjectManager = { projectUpdate, function (error, count) { project_ops_length = count - return cb(error) + cb(error) } ) } else { - return DocumentManager.renameDocWithLock( + DocumentManager.renameDocWithLock( project_id, doc_id, user_id, @@ -330,7 +307,7 @@ module.exports = ProjectManager = { projectHistoryId, function (error, count) { project_ops_length = count - return cb(error) + cb(error) } ) } @@ -340,7 +317,7 @@ module.exports = ProjectManager = { const file_id = projectUpdate.id projectUpdate.version = `${project_version}.${project_subversion++}` if (projectUpdate.url != null) { - return ProjectHistoryRedisManager.queueAddEntity( + ProjectHistoryRedisManager.queueAddEntity( project_id, projectHistoryId, 'file', @@ -349,11 +326,11 @@ module.exports = ProjectManager = { projectUpdate, function (error, count) { project_ops_length = count - return cb(error) + cb(error) } ) } else { - return ProjectHistoryRedisManager.queueRenameEntity( + ProjectHistoryRedisManager.queueRenameEntity( project_id, projectHistoryId, 'file', @@ -362,17 +339,17 @@ module.exports = ProjectManager = { projectUpdate, function (error, count) { project_ops_length = count - return cb(error) + cb(error) } ) } } - return async.eachSeries(docUpdates, handleDocUpdate, function (error) { + async.eachSeries(docUpdates, handleDocUpdate, function (error) { if (error != null) { return callback(error) } - return async.eachSeries(fileUpdates, handleFileUpdate, function (error) { + async.eachSeries(fileUpdates, handleFileUpdate, function (error) { if (error != null) { return callback(error) } @@ -385,7 +362,7 @@ module.exports = ProjectManager = { ) { HistoryManager.flushProjectChangesAsync(project_id) } - return callback() + callback() }) }) }, From f2c67b66fa236e7e26b81bc10fea65914278c85f Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:50:04 -0400 Subject: [PATCH 03/14] Decaf cleanup: remove default callbacks --- .../document-updater/app/js/ProjectManager.js | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index cc39f3f399..4c06ffdcdf 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -22,9 +22,6 @@ const Errors = require('./Errors') module.exports = ProjectManager = { flushProjectWithLocks(project_id, _callback) { - if (_callback == null) { - _callback = function (error) {} - } const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') const callback = function (...args) { timer.done() @@ -77,9 +74,6 @@ module.exports = ProjectManager = { }, flushAndDeleteProjectWithLocks(project_id, options, _callback) { - if (_callback == null) { - _callback = function (error) {} - } const timer = new Metrics.Timer( 'projectManager.flushAndDeleteProjectWithLocks' ) @@ -137,9 +131,6 @@ module.exports = ProjectManager = { }, queueFlushAndDeleteProject(project_id, callback) { - if (callback == null) { - callback = function (error) {} - } RedisManager.queueFlushAndDeleteProject(project_id, function (error) { if (error != null) { logger.error( @@ -154,9 +145,6 @@ module.exports = ProjectManager = { }, getProjectDocsTimestamps(project_id, callback) { - if (callback == null) { - callback = function (error) {} - } RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { if (error != null) { return callback(error) @@ -179,12 +167,6 @@ module.exports = ProjectManager = { excludeVersions, _callback ) { - if (excludeVersions == null) { - excludeVersions = {} - } - if (_callback == null) { - _callback = function (error, docs) {} - } const timer = new Metrics.Timer( 'projectManager.getProjectDocsAndFlushIfOld' ) @@ -253,9 +235,6 @@ module.exports = ProjectManager = { }, clearProjectState(project_id, callback) { - if (callback == null) { - callback = function (error) {} - } RedisManager.clearProjectState(project_id, callback) }, @@ -268,9 +247,6 @@ module.exports = ProjectManager = { version, _callback ) { - if (_callback == null) { - _callback = function (error) {} - } const timer = new Metrics.Timer('projectManager.updateProject') const callback = function (...args) { timer.done() From 6b5760ca282619573446d1b209e308765d8f55f4 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:53:22 -0400 Subject: [PATCH 04/14] Decaf cleanup: simplify null checks --- .../document-updater/app/js/ProjectManager.js | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 4c06ffdcdf..c83710cdb4 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -3,13 +3,6 @@ handle-callback-err, no-unused-vars, */ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ let ProjectManager const RedisManager = require('./RedisManager') const ProjectHistoryRedisManager = require('./ProjectHistoryRedisManager') @@ -29,7 +22,7 @@ module.exports = ProjectManager = { } RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { - if (error != null) { + if (error) { return callback(error) } const jobs = [] @@ -41,13 +34,13 @@ module.exports = ProjectManager = { project_id, doc_id, function (error) { - if (error != null && error instanceof Errors.NotFoundError) { + if (error instanceof Errors.NotFoundError) { logger.warn( { err: error, project_id, doc_id }, 'found deleted doc when flushing' ) callback() - } else if (error != null) { + } else if (error) { logger.error( { err: error, project_id, doc_id }, 'error flushing doc' @@ -83,7 +76,7 @@ module.exports = ProjectManager = { } RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { - if (error != null) { + if (error) { return callback(error) } const jobs = [] @@ -96,7 +89,7 @@ module.exports = ProjectManager = { doc_id, {}, function (error) { - if (error != null) { + if (error) { logger.error( { err: error, project_id, doc_id }, 'error deleting doc' @@ -120,7 +113,7 @@ module.exports = ProjectManager = { ) { if (errors.length > 0) { callback(new Error('Errors deleting docs. See log for details')) - } else if (error != null) { + } else if (error) { callback(error) } else { callback(null) @@ -132,7 +125,7 @@ module.exports = ProjectManager = { queueFlushAndDeleteProject(project_id, callback) { RedisManager.queueFlushAndDeleteProject(project_id, function (error) { - if (error != null) { + if (error) { logger.error( { project_id, error }, 'error adding project to flush and delete queue' @@ -146,14 +139,14 @@ module.exports = ProjectManager = { getProjectDocsTimestamps(project_id, callback) { RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { - if (error != null) { + if (error) { return callback(error) } - if (!(doc_ids != null ? doc_ids.length : undefined)) { + if (doc_ids.length === 0) { return callback(null, []) } RedisManager.getDocTimestamps(doc_ids, function (error, timestamps) { - if (error != null) { + if (error) { return callback(error) } callback(null, timestamps) @@ -179,7 +172,7 @@ module.exports = ProjectManager = { error, projectStateChanged ) { - if (error != null) { + if (error) { logger.error( { err: error, project_id }, 'error getting/setting project state in getProjectDocsAndFlushIfOld' @@ -194,7 +187,7 @@ module.exports = ProjectManager = { } // project structure hasn't changed, return doc content from redis RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { - if (error != null) { + if (error) { logger.error( { err: error, project_id }, 'error getting doc ids in getProjectDocs' @@ -211,7 +204,7 @@ module.exports = ProjectManager = { project_id, doc_id, function (err, lines, version) { - if (err != null) { + if (err) { logger.error( { err, project_id, doc_id }, 'error getting project doc lines in getProjectDocsAndFlushIfOld' @@ -225,7 +218,7 @@ module.exports = ProjectManager = { ))(doc_id) } async.series(jobs, function (error, docs) { - if (error != null) { + if (error) { return callback(error) } callback(null, docs) @@ -322,11 +315,11 @@ module.exports = ProjectManager = { } async.eachSeries(docUpdates, handleDocUpdate, function (error) { - if (error != null) { + if (error) { return callback(error) } async.eachSeries(fileUpdates, handleFileUpdate, function (error) { - if (error != null) { + if (error) { return callback(error) } if ( From ceb77f4c937ac7f6d085db2997ee702e0880300f Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:54:08 -0400 Subject: [PATCH 05/14] Decaf cleanup: remove unused variables --- services/document-updater/app/js/ProjectManager.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index c83710cdb4..3da062995b 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -1,9 +1,7 @@ /* eslint-disable camelcase, handle-callback-err, - no-unused-vars, */ -let ProjectManager const RedisManager = require('./RedisManager') const ProjectHistoryRedisManager = require('./ProjectHistoryRedisManager') const DocumentManager = require('./DocumentManager') @@ -13,7 +11,7 @@ const logger = require('logger-sharelatex') const Metrics = require('./Metrics') const Errors = require('./Errors') -module.exports = ProjectManager = { +module.exports = { flushProjectWithLocks(project_id, _callback) { const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') const callback = function (...args) { From 7a5a782dc72b21d512b3f235b70efea05c9812ca Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 16:58:57 -0400 Subject: [PATCH 06/14] Decaf cleanup: camel case variables --- .../document-updater/app/js/ProjectManager.js | 140 +++++++++--------- .../flushAndDeleteProjectTests.js | 2 +- .../js/ProjectManager/flushProjectTests.js | 2 +- .../js/ProjectManager/getProjectDocsTests.js | 2 +- 4 files changed, 71 insertions(+), 75 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 3da062995b..d3dc0b14f7 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -1,7 +1,3 @@ -/* eslint-disable - camelcase, - handle-callback-err, -*/ const RedisManager = require('./RedisManager') const ProjectHistoryRedisManager = require('./ProjectHistoryRedisManager') const DocumentManager = require('./DocumentManager') @@ -12,35 +8,35 @@ const Metrics = require('./Metrics') const Errors = require('./Errors') module.exports = { - flushProjectWithLocks(project_id, _callback) { + flushProjectWithLocks(projectId, _callback) { const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') const callback = function (...args) { timer.done() _callback(...args) } - RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { + RedisManager.getDocIdsInProject(projectId, function (error, docIds) { if (error) { return callback(error) } const jobs = [] const errors = [] - for (const doc_id of doc_ids) { - ;((doc_id) => + for (const docId of docIds) { + ;((docId) => jobs.push((callback) => DocumentManager.flushDocIfLoadedWithLock( - project_id, - doc_id, + projectId, + docId, function (error) { if (error instanceof Errors.NotFoundError) { logger.warn( - { err: error, project_id, doc_id }, + { err: error, projectId, docId }, 'found deleted doc when flushing' ) callback() } else if (error) { logger.error( - { err: error, project_id, doc_id }, + { err: error, projectId, docId }, 'error flushing doc' ) errors.push(error) @@ -50,10 +46,10 @@ module.exports = { } } ) - ))(doc_id) + ))(docId) } - logger.log({ project_id, doc_ids }, 'flushing docs') + logger.log({ projectId, docIds }, 'flushing docs') async.series(jobs, function () { if (errors.length > 0) { callback(new Error('Errors flushing docs. See log for details')) @@ -64,7 +60,7 @@ module.exports = { }) }, - flushAndDeleteProjectWithLocks(project_id, options, _callback) { + flushAndDeleteProjectWithLocks(projectId, options, _callback) { const timer = new Metrics.Timer( 'projectManager.flushAndDeleteProjectWithLocks' ) @@ -73,23 +69,23 @@ module.exports = { _callback(...args) } - RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { + RedisManager.getDocIdsInProject(projectId, function (error, docIds) { if (error) { return callback(error) } const jobs = [] const errors = [] - for (const doc_id of doc_ids) { - ;((doc_id) => + for (const docId of docIds) { + ;((docId) => jobs.push((callback) => DocumentManager.flushAndDeleteDocWithLock( - project_id, - doc_id, + projectId, + docId, {}, function (error) { if (error) { logger.error( - { err: error, project_id, doc_id }, + { err: error, projectId, docId }, 'error deleting doc' ) errors.push(error) @@ -97,16 +93,16 @@ module.exports = { callback() } ) - ))(doc_id) + ))(docId) } - logger.log({ project_id, doc_ids }, 'deleting docs') + logger.log({ projectId, docIds }, 'deleting docs') async.series(jobs, () => // When deleting the project here we want to ensure that project // history is completely flushed because the project may be // deleted in web after this call completes, and so further // attempts to flush would fail after that. - HistoryManager.flushProjectChanges(project_id, options, function ( + HistoryManager.flushProjectChanges(projectId, options, function ( error ) { if (errors.length > 0) { @@ -121,11 +117,11 @@ module.exports = { }) }, - queueFlushAndDeleteProject(project_id, callback) { - RedisManager.queueFlushAndDeleteProject(project_id, function (error) { + queueFlushAndDeleteProject(projectId, callback) { + RedisManager.queueFlushAndDeleteProject(projectId, function (error) { if (error) { logger.error( - { project_id, error }, + { projectId, error }, 'error adding project to flush and delete queue' ) return callback(error) @@ -135,15 +131,15 @@ module.exports = { }) }, - getProjectDocsTimestamps(project_id, callback) { - RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { + getProjectDocsTimestamps(projectId, callback) { + RedisManager.getDocIdsInProject(projectId, function (error, docIds) { if (error) { return callback(error) } - if (doc_ids.length === 0) { + if (docIds.length === 0) { return callback(null, []) } - RedisManager.getDocTimestamps(doc_ids, function (error, timestamps) { + RedisManager.getDocTimestamps(docIds, function (error, timestamps) { if (error) { return callback(error) } @@ -153,7 +149,7 @@ module.exports = { }, getProjectDocsAndFlushIfOld( - project_id, + projectId, projectStateHash, excludeVersions, _callback @@ -166,13 +162,13 @@ module.exports = { _callback(...args) } - RedisManager.checkOrSetProjectState(project_id, projectStateHash, function ( + RedisManager.checkOrSetProjectState(projectId, projectStateHash, function ( error, projectStateChanged ) { if (error) { logger.error( - { err: error, project_id }, + { err: error, projectId }, 'error getting/setting project state in getProjectDocsAndFlushIfOld' ) return callback(error) @@ -184,36 +180,36 @@ module.exports = { ) } // project structure hasn't changed, return doc content from redis - RedisManager.getDocIdsInProject(project_id, function (error, doc_ids) { + RedisManager.getDocIdsInProject(projectId, function (error, docIds) { if (error) { logger.error( - { err: error, project_id }, + { err: error, projectId }, 'error getting doc ids in getProjectDocs' ) return callback(error) } const jobs = [] - for (const doc_id of doc_ids) { - ;((doc_id) => + for (const docId of docIds) { + ;((docId) => jobs.push(( cb // get the doc lines from redis ) => DocumentManager.getDocAndFlushIfOldWithLock( - project_id, - doc_id, + projectId, + docId, function (err, lines, version) { if (err) { logger.error( - { err, project_id, doc_id }, + { err, projectId, docId }, 'error getting project doc lines in getProjectDocsAndFlushIfOld' ) return cb(err) } - const doc = { _id: doc_id, lines, v: version } // create a doc object to return + const doc = { _id: docId, lines, v: version } // create a doc object to return cb(null, doc) } ) - ))(doc_id) + ))(docId) } async.series(jobs, function (error, docs) { if (error) { @@ -225,14 +221,14 @@ module.exports = { }) }, - clearProjectState(project_id, callback) { - RedisManager.clearProjectState(project_id, callback) + clearProjectState(projectId, callback) { + RedisManager.clearProjectState(projectId, callback) }, updateProjectWithLocks( - project_id, + projectId, projectHistoryId, - user_id, + userId, docUpdates, fileUpdates, version, @@ -244,36 +240,36 @@ module.exports = { _callback(...args) } - const project_version = version - let project_subversion = 0 // project versions can have multiple operations + const projectVersion = version + let projectSubversion = 0 // project versions can have multiple operations - let project_ops_length = 0 + let projectOpsLength = 0 const handleDocUpdate = function (projectUpdate, cb) { - const doc_id = projectUpdate.id - projectUpdate.version = `${project_version}.${project_subversion++}` + const docId = projectUpdate.id + projectUpdate.version = `${projectVersion}.${projectSubversion++}` if (projectUpdate.docLines != null) { ProjectHistoryRedisManager.queueAddEntity( - project_id, + projectId, projectHistoryId, 'doc', - doc_id, - user_id, + docId, + userId, projectUpdate, function (error, count) { - project_ops_length = count + projectOpsLength = count cb(error) } ) } else { DocumentManager.renameDocWithLock( - project_id, - doc_id, - user_id, + projectId, + docId, + userId, projectUpdate, projectHistoryId, function (error, count) { - project_ops_length = count + projectOpsLength = count cb(error) } ) @@ -281,31 +277,31 @@ module.exports = { } const handleFileUpdate = function (projectUpdate, cb) { - const file_id = projectUpdate.id - projectUpdate.version = `${project_version}.${project_subversion++}` + const fileId = projectUpdate.id + projectUpdate.version = `${projectVersion}.${projectSubversion++}` if (projectUpdate.url != null) { ProjectHistoryRedisManager.queueAddEntity( - project_id, + projectId, projectHistoryId, 'file', - file_id, - user_id, + fileId, + userId, projectUpdate, function (error, count) { - project_ops_length = count + projectOpsLength = count cb(error) } ) } else { ProjectHistoryRedisManager.queueRenameEntity( - project_id, + projectId, projectHistoryId, 'file', - file_id, - user_id, + fileId, + userId, projectUpdate, function (error, count) { - project_ops_length = count + projectOpsLength = count cb(error) } ) @@ -322,12 +318,12 @@ module.exports = { } if ( HistoryManager.shouldFlushHistoryOps( - project_ops_length, + projectOpsLength, docUpdates.length + fileUpdates.length, HistoryManager.FLUSH_PROJECT_EVERY_N_OPS ) ) { - HistoryManager.flushProjectChangesAsync(project_id) + HistoryManager.flushProjectChangesAsync(projectId) } callback() }) diff --git a/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js index 7afa407e7c..266d1d1a2e 100644 --- a/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js @@ -140,7 +140,7 @@ describe('ProjectManager - flushAndDeleteProject', function () { it('should record the error', function () { return this.logger.error .calledWith( - { err: this.error, project_id: this.project_id, doc_id: 'doc-id-1' }, + { err: this.error, projectId: this.project_id, docId: 'doc-id-1' }, 'error deleting doc' ) .should.equal(true) diff --git a/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js index 110a827e64..1907a26228 100644 --- a/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js @@ -129,7 +129,7 @@ describe('ProjectManager - flushProject', function () { it('should record the error', function () { return this.logger.error .calledWith( - { err: this.error, project_id: this.project_id, doc_id: 'doc-id-1' }, + { err: this.error, projectId: this.project_id, docId: 'doc-id-1' }, 'error flushing doc' ) .should.equal(true) diff --git a/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js b/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js index 72ffe39ec1..a10b328864 100644 --- a/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js @@ -187,7 +187,7 @@ describe('ProjectManager - getProjectDocsAndFlushIfOld', function () { it('should record the error', function () { return this.logger.error .calledWith( - { err: this.error, project_id: this.project_id, doc_id: 'doc-id-2' }, + { err: this.error, projectId: this.project_id, docId: 'doc-id-2' }, 'error getting project doc lines in getProjectDocsAndFlushIfOld' ) .should.equal(true) From 751d9ea718082b8791a4a8a662292e4bfac628a0 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 17:03:14 -0400 Subject: [PATCH 07/14] Decaf cleanup: simplify loops --- .../document-updater/app/js/ProjectManager.js | 124 ++++++++---------- 1 file changed, 53 insertions(+), 71 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index d3dc0b14f7..16997df3cf 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -19,35 +19,26 @@ module.exports = { if (error) { return callback(error) } - const jobs = [] const errors = [] - for (const docId of docIds) { - ;((docId) => - jobs.push((callback) => - DocumentManager.flushDocIfLoadedWithLock( - projectId, - docId, - function (error) { - if (error instanceof Errors.NotFoundError) { - logger.warn( - { err: error, projectId, docId }, - 'found deleted doc when flushing' - ) - callback() - } else if (error) { - logger.error( - { err: error, projectId, docId }, - 'error flushing doc' - ) - errors.push(error) - callback() - } else { - callback() - } - } + const jobs = docIds.map((docId) => (callback) => { + DocumentManager.flushDocIfLoadedWithLock(projectId, docId, function ( + error + ) { + if (error instanceof Errors.NotFoundError) { + logger.warn( + { err: error, projectId, docId }, + 'found deleted doc when flushing' ) - ))(docId) - } + callback() + } else if (error) { + logger.error({ err: error, projectId, docId }, 'error flushing doc') + errors.push(error) + callback() + } else { + callback() + } + }) + }) logger.log({ projectId, docIds }, 'flushing docs') async.series(jobs, function () { @@ -73,28 +64,24 @@ module.exports = { if (error) { return callback(error) } - const jobs = [] const errors = [] - for (const docId of docIds) { - ;((docId) => - jobs.push((callback) => - DocumentManager.flushAndDeleteDocWithLock( - projectId, - docId, - {}, - function (error) { - if (error) { - logger.error( - { err: error, projectId, docId }, - 'error deleting doc' - ) - errors.push(error) - } - callback() - } - ) - ))(docId) - } + const jobs = docIds.map((docId) => (callback) => { + DocumentManager.flushAndDeleteDocWithLock( + projectId, + docId, + {}, + function (error) { + if (error) { + logger.error( + { err: error, projectId, docId }, + 'error deleting doc' + ) + errors.push(error) + } + callback() + } + ) + }) logger.log({ projectId, docIds }, 'deleting docs') async.series(jobs, () => @@ -188,29 +175,24 @@ module.exports = { ) return callback(error) } - const jobs = [] - for (const docId of docIds) { - ;((docId) => - jobs.push(( - cb // get the doc lines from redis - ) => - DocumentManager.getDocAndFlushIfOldWithLock( - projectId, - docId, - function (err, lines, version) { - if (err) { - logger.error( - { err, projectId, docId }, - 'error getting project doc lines in getProjectDocsAndFlushIfOld' - ) - return cb(err) - } - const doc = { _id: docId, lines, v: version } // create a doc object to return - cb(null, doc) - } - ) - ))(docId) - } + // get the doc lines from redis + const jobs = docIds.map((docId) => (cb) => { + DocumentManager.getDocAndFlushIfOldWithLock( + projectId, + docId, + function (err, lines, version) { + if (err) { + logger.error( + { err, projectId, docId }, + 'error getting project doc lines in getProjectDocsAndFlushIfOld' + ) + return cb(err) + } + const doc = { _id: docId, lines, v: version } // create a doc object to return + cb(null, doc) + } + ) + }) async.series(jobs, function (error, docs) { if (error) { return callback(error) From 3d000bcbe67603aa22b44b6f33f59de8b450b594 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 17:05:59 -0400 Subject: [PATCH 08/14] Decaf cleanup: use arrow functions for callbacks --- .../document-updater/app/js/ProjectManager.js | 117 +++++++++--------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 16997df3cf..25de54f3d1 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -15,15 +15,13 @@ module.exports = { _callback(...args) } - RedisManager.getDocIdsInProject(projectId, function (error, docIds) { + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { if (error) { return callback(error) } const errors = [] const jobs = docIds.map((docId) => (callback) => { - DocumentManager.flushDocIfLoadedWithLock(projectId, docId, function ( - error - ) { + DocumentManager.flushDocIfLoadedWithLock(projectId, docId, (error) => { if (error instanceof Errors.NotFoundError) { logger.warn( { err: error, projectId, docId }, @@ -41,7 +39,7 @@ module.exports = { }) logger.log({ projectId, docIds }, 'flushing docs') - async.series(jobs, function () { + async.series(jobs, () => { if (errors.length > 0) { callback(new Error('Errors flushing docs. See log for details')) } else { @@ -60,7 +58,7 @@ module.exports = { _callback(...args) } - RedisManager.getDocIdsInProject(projectId, function (error, docIds) { + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { if (error) { return callback(error) } @@ -70,7 +68,7 @@ module.exports = { projectId, docId, {}, - function (error) { + (error) => { if (error) { logger.error( { err: error, projectId, docId }, @@ -89,9 +87,7 @@ module.exports = { // history is completely flushed because the project may be // deleted in web after this call completes, and so further // attempts to flush would fail after that. - HistoryManager.flushProjectChanges(projectId, options, function ( - error - ) { + HistoryManager.flushProjectChanges(projectId, options, (error) => { if (errors.length > 0) { callback(new Error('Errors deleting docs. See log for details')) } else if (error) { @@ -105,7 +101,7 @@ module.exports = { }, queueFlushAndDeleteProject(projectId, callback) { - RedisManager.queueFlushAndDeleteProject(projectId, function (error) { + RedisManager.queueFlushAndDeleteProject(projectId, (error) => { if (error) { logger.error( { projectId, error }, @@ -119,14 +115,14 @@ module.exports = { }, getProjectDocsTimestamps(projectId, callback) { - RedisManager.getDocIdsInProject(projectId, function (error, docIds) { + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { if (error) { return callback(error) } if (docIds.length === 0) { return callback(null, []) } - RedisManager.getDocTimestamps(docIds, function (error, timestamps) { + RedisManager.getDocTimestamps(docIds, (error, timestamps) => { if (error) { return callback(error) } @@ -149,58 +145,59 @@ module.exports = { _callback(...args) } - RedisManager.checkOrSetProjectState(projectId, projectStateHash, function ( - error, - projectStateChanged - ) { - if (error) { - logger.error( - { err: error, projectId }, - 'error getting/setting project state in getProjectDocsAndFlushIfOld' - ) - return callback(error) - } - // we can't return docs if project structure has changed - if (projectStateChanged) { - return callback( - Errors.ProjectStateChangedError('project state changed') - ) - } - // project structure hasn't changed, return doc content from redis - RedisManager.getDocIdsInProject(projectId, function (error, docIds) { + RedisManager.checkOrSetProjectState( + projectId, + projectStateHash, + (error, projectStateChanged) => { if (error) { logger.error( { err: error, projectId }, - 'error getting doc ids in getProjectDocs' + 'error getting/setting project state in getProjectDocsAndFlushIfOld' ) return callback(error) } - // get the doc lines from redis - const jobs = docIds.map((docId) => (cb) => { - DocumentManager.getDocAndFlushIfOldWithLock( - projectId, - docId, - function (err, lines, version) { - if (err) { - logger.error( - { err, projectId, docId }, - 'error getting project doc lines in getProjectDocsAndFlushIfOld' - ) - return cb(err) - } - const doc = { _id: docId, lines, v: version } // create a doc object to return - cb(null, doc) - } + // we can't return docs if project structure has changed + if (projectStateChanged) { + return callback( + Errors.ProjectStateChangedError('project state changed') ) - }) - async.series(jobs, function (error, docs) { + } + // project structure hasn't changed, return doc content from redis + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { if (error) { + logger.error( + { err: error, projectId }, + 'error getting doc ids in getProjectDocs' + ) return callback(error) } - callback(null, docs) + // get the doc lines from redis + const jobs = docIds.map((docId) => (cb) => { + DocumentManager.getDocAndFlushIfOldWithLock( + projectId, + docId, + (err, lines, version) => { + if (err) { + logger.error( + { err, projectId, docId }, + 'error getting project doc lines in getProjectDocsAndFlushIfOld' + ) + return cb(err) + } + const doc = { _id: docId, lines, v: version } // create a doc object to return + cb(null, doc) + } + ) + }) + async.series(jobs, (error, docs) => { + if (error) { + return callback(error) + } + callback(null, docs) + }) }) - }) - }) + } + ) }, clearProjectState(projectId, callback) { @@ -238,7 +235,7 @@ module.exports = { docId, userId, projectUpdate, - function (error, count) { + (error, count) => { projectOpsLength = count cb(error) } @@ -250,7 +247,7 @@ module.exports = { userId, projectUpdate, projectHistoryId, - function (error, count) { + (error, count) => { projectOpsLength = count cb(error) } @@ -269,7 +266,7 @@ module.exports = { fileId, userId, projectUpdate, - function (error, count) { + (error, count) => { projectOpsLength = count cb(error) } @@ -282,7 +279,7 @@ module.exports = { fileId, userId, projectUpdate, - function (error, count) { + (error, count) => { projectOpsLength = count cb(error) } @@ -290,11 +287,11 @@ module.exports = { } } - async.eachSeries(docUpdates, handleDocUpdate, function (error) { + async.eachSeries(docUpdates, handleDocUpdate, (error) => { if (error) { return callback(error) } - async.eachSeries(fileUpdates, handleFileUpdate, function (error) { + async.eachSeries(fileUpdates, handleFileUpdate, (error) => { if (error) { return callback(error) } From 6269ace987a5dd5e8872f79635a748aeeacff1cd Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Thu, 14 May 2020 17:09:01 -0400 Subject: [PATCH 09/14] Decaf cleanup: move functions to top level --- .../document-updater/app/js/ProjectManager.js | 519 +++++++++--------- 1 file changed, 261 insertions(+), 258 deletions(-) diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 25de54f3d1..768ab3e759 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -8,304 +8,307 @@ const Metrics = require('./Metrics') const Errors = require('./Errors') module.exports = { - flushProjectWithLocks(projectId, _callback) { - const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') - const callback = function (...args) { - timer.done() - _callback(...args) + flushProjectWithLocks, + flushAndDeleteProjectWithLocks, + queueFlushAndDeleteProject, + getProjectDocsTimestamps, + getProjectDocsAndFlushIfOld, + clearProjectState, + updateProjectWithLocks +} + +function flushProjectWithLocks(projectId, _callback) { + const timer = new Metrics.Timer('projectManager.flushProjectWithLocks') + const callback = function (...args) { + timer.done() + _callback(...args) + } + + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { + if (error) { + return callback(error) } - - RedisManager.getDocIdsInProject(projectId, (error, docIds) => { - if (error) { - return callback(error) - } - const errors = [] - const jobs = docIds.map((docId) => (callback) => { - DocumentManager.flushDocIfLoadedWithLock(projectId, docId, (error) => { - if (error instanceof Errors.NotFoundError) { - logger.warn( - { err: error, projectId, docId }, - 'found deleted doc when flushing' - ) - callback() - } else if (error) { - logger.error({ err: error, projectId, docId }, 'error flushing doc') - errors.push(error) - callback() - } else { - callback() - } - }) + const errors = [] + const jobs = docIds.map((docId) => (callback) => { + DocumentManager.flushDocIfLoadedWithLock(projectId, docId, (error) => { + if (error instanceof Errors.NotFoundError) { + logger.warn( + { err: error, projectId, docId }, + 'found deleted doc when flushing' + ) + callback() + } else if (error) { + logger.error({ err: error, projectId, docId }, 'error flushing doc') + errors.push(error) + callback() + } else { + callback() + } }) + }) - logger.log({ projectId, docIds }, 'flushing docs') - async.series(jobs, () => { + logger.log({ projectId, docIds }, 'flushing docs') + async.series(jobs, () => { + if (errors.length > 0) { + callback(new Error('Errors flushing docs. See log for details')) + } else { + callback(null) + } + }) + }) +} + +function flushAndDeleteProjectWithLocks(projectId, options, _callback) { + const timer = new Metrics.Timer( + 'projectManager.flushAndDeleteProjectWithLocks' + ) + const callback = function (...args) { + timer.done() + _callback(...args) + } + + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { + if (error) { + return callback(error) + } + const errors = [] + const jobs = docIds.map((docId) => (callback) => { + DocumentManager.flushAndDeleteDocWithLock( + projectId, + docId, + {}, + (error) => { + if (error) { + logger.error({ err: error, projectId, docId }, 'error deleting doc') + errors.push(error) + } + callback() + } + ) + }) + + logger.log({ projectId, docIds }, 'deleting docs') + async.series(jobs, () => + // When deleting the project here we want to ensure that project + // history is completely flushed because the project may be + // deleted in web after this call completes, and so further + // attempts to flush would fail after that. + HistoryManager.flushProjectChanges(projectId, options, (error) => { if (errors.length > 0) { - callback(new Error('Errors flushing docs. See log for details')) + callback(new Error('Errors deleting docs. See log for details')) + } else if (error) { + callback(error) } else { callback(null) } }) - }) - }, - - flushAndDeleteProjectWithLocks(projectId, options, _callback) { - const timer = new Metrics.Timer( - 'projectManager.flushAndDeleteProjectWithLocks' ) - const callback = function (...args) { - timer.done() - _callback(...args) - } + }) +} - RedisManager.getDocIdsInProject(projectId, (error, docIds) => { - if (error) { - return callback(error) - } - const errors = [] - const jobs = docIds.map((docId) => (callback) => { - DocumentManager.flushAndDeleteDocWithLock( - projectId, - docId, - {}, - (error) => { - if (error) { - logger.error( - { err: error, projectId, docId }, - 'error deleting doc' - ) - errors.push(error) - } - callback() - } - ) - }) - - logger.log({ projectId, docIds }, 'deleting docs') - async.series(jobs, () => - // When deleting the project here we want to ensure that project - // history is completely flushed because the project may be - // deleted in web after this call completes, and so further - // attempts to flush would fail after that. - HistoryManager.flushProjectChanges(projectId, options, (error) => { - if (errors.length > 0) { - callback(new Error('Errors deleting docs. See log for details')) - } else if (error) { - callback(error) - } else { - callback(null) - } - }) +function queueFlushAndDeleteProject(projectId, callback) { + RedisManager.queueFlushAndDeleteProject(projectId, (error) => { + if (error) { + logger.error( + { projectId, error }, + 'error adding project to flush and delete queue' ) - }) - }, + return callback(error) + } + Metrics.inc('queued-delete') + callback() + }) +} - queueFlushAndDeleteProject(projectId, callback) { - RedisManager.queueFlushAndDeleteProject(projectId, (error) => { - if (error) { - logger.error( - { projectId, error }, - 'error adding project to flush and delete queue' - ) - return callback(error) - } - Metrics.inc('queued-delete') - callback() - }) - }, - - getProjectDocsTimestamps(projectId, callback) { - RedisManager.getDocIdsInProject(projectId, (error, docIds) => { +function getProjectDocsTimestamps(projectId, callback) { + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { + if (error) { + return callback(error) + } + if (docIds.length === 0) { + return callback(null, []) + } + RedisManager.getDocTimestamps(docIds, (error, timestamps) => { if (error) { return callback(error) } - if (docIds.length === 0) { - return callback(null, []) - } - RedisManager.getDocTimestamps(docIds, (error, timestamps) => { - if (error) { - return callback(error) - } - callback(null, timestamps) - }) + callback(null, timestamps) }) - }, + }) +} - getProjectDocsAndFlushIfOld( +function getProjectDocsAndFlushIfOld( + projectId, + projectStateHash, + excludeVersions, + _callback +) { + const timer = new Metrics.Timer('projectManager.getProjectDocsAndFlushIfOld') + const callback = function (...args) { + timer.done() + _callback(...args) + } + + RedisManager.checkOrSetProjectState( projectId, projectStateHash, - excludeVersions, - _callback - ) { - const timer = new Metrics.Timer( - 'projectManager.getProjectDocsAndFlushIfOld' - ) - const callback = function (...args) { - timer.done() - _callback(...args) - } - - RedisManager.checkOrSetProjectState( - projectId, - projectStateHash, - (error, projectStateChanged) => { + (error, projectStateChanged) => { + if (error) { + logger.error( + { err: error, projectId }, + 'error getting/setting project state in getProjectDocsAndFlushIfOld' + ) + return callback(error) + } + // we can't return docs if project structure has changed + if (projectStateChanged) { + return callback( + Errors.ProjectStateChangedError('project state changed') + ) + } + // project structure hasn't changed, return doc content from redis + RedisManager.getDocIdsInProject(projectId, (error, docIds) => { if (error) { logger.error( { err: error, projectId }, - 'error getting/setting project state in getProjectDocsAndFlushIfOld' + 'error getting doc ids in getProjectDocs' ) return callback(error) } - // we can't return docs if project structure has changed - if (projectStateChanged) { - return callback( - Errors.ProjectStateChangedError('project state changed') + // get the doc lines from redis + const jobs = docIds.map((docId) => (cb) => { + DocumentManager.getDocAndFlushIfOldWithLock( + projectId, + docId, + (err, lines, version) => { + if (err) { + logger.error( + { err, projectId, docId }, + 'error getting project doc lines in getProjectDocsAndFlushIfOld' + ) + return cb(err) + } + const doc = { _id: docId, lines, v: version } // create a doc object to return + cb(null, doc) + } ) - } - // project structure hasn't changed, return doc content from redis - RedisManager.getDocIdsInProject(projectId, (error, docIds) => { + }) + async.series(jobs, (error, docs) => { if (error) { - logger.error( - { err: error, projectId }, - 'error getting doc ids in getProjectDocs' - ) return callback(error) } - // get the doc lines from redis - const jobs = docIds.map((docId) => (cb) => { - DocumentManager.getDocAndFlushIfOldWithLock( - projectId, - docId, - (err, lines, version) => { - if (err) { - logger.error( - { err, projectId, docId }, - 'error getting project doc lines in getProjectDocsAndFlushIfOld' - ) - return cb(err) - } - const doc = { _id: docId, lines, v: version } // create a doc object to return - cb(null, doc) - } - ) - }) - async.series(jobs, (error, docs) => { - if (error) { - return callback(error) - } - callback(null, docs) - }) + callback(null, docs) }) - } - ) - }, - - clearProjectState(projectId, callback) { - RedisManager.clearProjectState(projectId, callback) - }, - - updateProjectWithLocks( - projectId, - projectHistoryId, - userId, - docUpdates, - fileUpdates, - version, - _callback - ) { - const timer = new Metrics.Timer('projectManager.updateProject') - const callback = function (...args) { - timer.done() - _callback(...args) + }) } + ) +} - const projectVersion = version - let projectSubversion = 0 // project versions can have multiple operations +function clearProjectState(projectId, callback) { + RedisManager.clearProjectState(projectId, callback) +} - let projectOpsLength = 0 +function updateProjectWithLocks( + projectId, + projectHistoryId, + userId, + docUpdates, + fileUpdates, + version, + _callback +) { + const timer = new Metrics.Timer('projectManager.updateProject') + const callback = function (...args) { + timer.done() + _callback(...args) + } - const handleDocUpdate = function (projectUpdate, cb) { - const docId = projectUpdate.id - projectUpdate.version = `${projectVersion}.${projectSubversion++}` - if (projectUpdate.docLines != null) { - ProjectHistoryRedisManager.queueAddEntity( - projectId, - projectHistoryId, - 'doc', - docId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } else { - DocumentManager.renameDocWithLock( - projectId, - docId, - userId, - projectUpdate, - projectHistoryId, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } + const projectVersion = version + let projectSubversion = 0 // project versions can have multiple operations + + let projectOpsLength = 0 + + const handleDocUpdate = function (projectUpdate, cb) { + const docId = projectUpdate.id + projectUpdate.version = `${projectVersion}.${projectSubversion++}` + if (projectUpdate.docLines != null) { + ProjectHistoryRedisManager.queueAddEntity( + projectId, + projectHistoryId, + 'doc', + docId, + userId, + projectUpdate, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + } else { + DocumentManager.renameDocWithLock( + projectId, + docId, + userId, + projectUpdate, + projectHistoryId, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) } + } - const handleFileUpdate = function (projectUpdate, cb) { - const fileId = projectUpdate.id - projectUpdate.version = `${projectVersion}.${projectSubversion++}` - if (projectUpdate.url != null) { - ProjectHistoryRedisManager.queueAddEntity( - projectId, - projectHistoryId, - 'file', - fileId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } else { - ProjectHistoryRedisManager.queueRenameEntity( - projectId, - projectHistoryId, - 'file', - fileId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } + const handleFileUpdate = function (projectUpdate, cb) { + const fileId = projectUpdate.id + projectUpdate.version = `${projectVersion}.${projectSubversion++}` + if (projectUpdate.url != null) { + ProjectHistoryRedisManager.queueAddEntity( + projectId, + projectHistoryId, + 'file', + fileId, + userId, + projectUpdate, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + } else { + ProjectHistoryRedisManager.queueRenameEntity( + projectId, + projectHistoryId, + 'file', + fileId, + userId, + projectUpdate, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) } + } - async.eachSeries(docUpdates, handleDocUpdate, (error) => { + async.eachSeries(docUpdates, handleDocUpdate, (error) => { + if (error) { + return callback(error) + } + async.eachSeries(fileUpdates, handleFileUpdate, (error) => { if (error) { return callback(error) } - async.eachSeries(fileUpdates, handleFileUpdate, (error) => { - if (error) { - return callback(error) - } - if ( - HistoryManager.shouldFlushHistoryOps( - projectOpsLength, - docUpdates.length + fileUpdates.length, - HistoryManager.FLUSH_PROJECT_EVERY_N_OPS - ) - ) { - HistoryManager.flushProjectChangesAsync(projectId) - } - callback() - }) + if ( + HistoryManager.shouldFlushHistoryOps( + projectOpsLength, + docUpdates.length + fileUpdates.length, + HistoryManager.FLUSH_PROJECT_EVERY_N_OPS + ) + ) { + HistoryManager.flushProjectChangesAsync(projectId) + } + callback() }) - }, + }) } From 9e4280916a434f9edb2e478c334b53973cc922dc Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Fri, 15 May 2020 08:31:06 -0400 Subject: [PATCH 10/14] Decaf cleanup: unnecessary returns --- .../js/ProjectManager/updateProjectTests.js | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js index 5b439ef839..8c16c950d3 100644 --- a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js @@ -6,7 +6,6 @@ // Fix any style issues and re-enable lint. /* * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns * DS206: Consider reworking classes to avoid initClass * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ @@ -50,10 +49,10 @@ describe('ProjectManager', function () { this.version = 1234567 this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(false) this.HistoryManager.flushProjectChangesAsync = sinon.stub() - return (this.callback = sinon.stub()) + this.callback = sinon.stub() }) - return describe('updateProjectWithLocks', function () { + describe('updateProjectWithLocks', function () { describe('rename operations', function () { beforeEach(function () { this.firstDocUpdate = { @@ -74,14 +73,14 @@ describe('ProjectManager', function () { } this.fileUpdates = [this.firstFileUpdate] this.DocumentManager.renameDocWithLock = sinon.stub().yields() - return (this.ProjectHistoryRedisManager.queueRenameEntity = sinon + this.ProjectHistoryRedisManager.queueRenameEntity = sinon .stub() - .yields()) + .yields() }) describe('successfully', function () { beforeEach(function () { - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -110,7 +109,7 @@ describe('ProjectManager', function () { this.projectHistoryId ) .should.equal(true) - return this.DocumentManager.renameDocWithLock + this.DocumentManager.renameDocWithLock .calledWith( this.project_id, this.secondDocUpdate.id, @@ -127,7 +126,7 @@ describe('ProjectManager', function () { this.firstFileUpdate, { version: `${this.version}.2` } ) - return this.ProjectHistoryRedisManager.queueRenameEntity + this.ProjectHistoryRedisManager.queueRenameEntity .calledWith( this.project_id, this.projectHistoryId, @@ -140,13 +139,13 @@ describe('ProjectManager', function () { }) it('should not flush the history', function () { - return this.HistoryManager.flushProjectChangesAsync + this.HistoryManager.flushProjectChangesAsync .calledWith(this.project_id) .should.equal(false) }) - return it('should call the callback', function () { - return this.callback.called.should.equal(true) + it('should call the callback', function () { + this.callback.called.should.equal(true) }) }) @@ -156,7 +155,7 @@ describe('ProjectManager', function () { this.DocumentManager.renameDocWithLock = sinon .stub() .yields(this.error) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -167,8 +166,8 @@ describe('ProjectManager', function () { ) }) - return it('should call the callback with the error', function () { - return this.callback.calledWith(this.error).should.equal(true) + it('should call the callback with the error', function () { + this.callback.calledWith(this.error).should.equal(true) }) }) @@ -178,7 +177,7 @@ describe('ProjectManager', function () { this.ProjectHistoryRedisManager.queueRenameEntity = sinon .stub() .yields(this.error) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -189,15 +188,15 @@ describe('ProjectManager', function () { ) }) - return it('should call the callback with the error', function () { - return this.callback.calledWith(this.error).should.equal(true) + it('should call the callback with the error', function () { + this.callback.calledWith(this.error).should.equal(true) }) }) - return describe('with enough ops to flush', function () { + describe('with enough ops to flush', function () { beforeEach(function () { this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -208,15 +207,15 @@ describe('ProjectManager', function () { ) }) - return it('should flush the history', function () { - return this.HistoryManager.flushProjectChangesAsync + it('should flush the history', function () { + this.HistoryManager.flushProjectChangesAsync .calledWith(this.project_id) .should.equal(true) }) }) }) - return describe('add operations', function () { + describe('add operations', function () { beforeEach(function () { this.firstDocUpdate = { id: 1, @@ -236,14 +235,12 @@ describe('ProjectManager', function () { url: 'filestore.example.com/3' } this.fileUpdates = [this.firstFileUpdate, this.secondFileUpdate] - return (this.ProjectHistoryRedisManager.queueAddEntity = sinon - .stub() - .yields()) + this.ProjectHistoryRedisManager.queueAddEntity = sinon.stub().yields() }) describe('successfully', function () { beforeEach(function () { - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -274,7 +271,7 @@ describe('ProjectManager', function () { firstDocUpdateWithVersion ) .should.equal(true) - return this.ProjectHistoryRedisManager.queueAddEntity + this.ProjectHistoryRedisManager.queueAddEntity .getCall(1) .calledWith( this.project_id, @@ -309,7 +306,7 @@ describe('ProjectManager', function () { firstFileUpdateWithVersion ) .should.equal(true) - return this.ProjectHistoryRedisManager.queueAddEntity + this.ProjectHistoryRedisManager.queueAddEntity .getCall(3) .calledWith( this.project_id, @@ -323,13 +320,13 @@ describe('ProjectManager', function () { }) it('should not flush the history', function () { - return this.HistoryManager.flushProjectChangesAsync + this.HistoryManager.flushProjectChangesAsync .calledWith(this.project_id) .should.equal(false) }) - return it('should call the callback', function () { - return this.callback.called.should.equal(true) + it('should call the callback', function () { + this.callback.called.should.equal(true) }) }) @@ -339,7 +336,7 @@ describe('ProjectManager', function () { this.ProjectHistoryRedisManager.queueAddEntity = sinon .stub() .yields(this.error) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -350,8 +347,8 @@ describe('ProjectManager', function () { ) }) - return it('should call the callback with the error', function () { - return this.callback.calledWith(this.error).should.equal(true) + it('should call the callback with the error', function () { + this.callback.calledWith(this.error).should.equal(true) }) }) @@ -361,7 +358,7 @@ describe('ProjectManager', function () { this.ProjectHistoryRedisManager.queueAddEntity = sinon .stub() .yields(this.error) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -372,15 +369,15 @@ describe('ProjectManager', function () { ) }) - return it('should call the callback with the error', function () { - return this.callback.calledWith(this.error).should.equal(true) + it('should call the callback with the error', function () { + this.callback.calledWith(this.error).should.equal(true) }) }) - return describe('with enough ops to flush', function () { + describe('with enough ops to flush', function () { beforeEach(function () { this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true) - return this.ProjectManager.updateProjectWithLocks( + this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, this.user_id, @@ -391,8 +388,8 @@ describe('ProjectManager', function () { ) }) - return it('should flush the history', function () { - return this.HistoryManager.flushProjectChangesAsync + it('should flush the history', function () { + this.HistoryManager.flushProjectChangesAsync .calledWith(this.project_id) .should.equal(true) }) From 86747ba64f0947f7196c98957a3a44a33d342c96 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Fri, 15 May 2020 08:40:11 -0400 Subject: [PATCH 11/14] Decaf cleanup: stub setup in tests --- .../js/ProjectManager/updateProjectTests.js | 82 ++++++++----------- 1 file changed, 34 insertions(+), 48 deletions(-) diff --git a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js index 8c16c950d3..94d132f962 100644 --- a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js @@ -2,13 +2,6 @@ no-return-assign, no-unused-vars, */ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS206: Consider reworking classes to avoid initClass - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ const sinon = require('sinon') const chai = require('chai') const should = chai.should() @@ -18,28 +11,36 @@ const _ = require('lodash') describe('ProjectManager', function () { beforeEach(function () { - let Timer + this.RedisManager = {} + this.ProjectHistoryRedisManager = { + queueRenameEntity: sinon.stub().yields(), + queueAddEntity: sinon.stub().yields() + } + this.DocumentManager = { + renameDocWithLock: sinon.stub().yields() + } + this.HistoryManager = { + flushProjectChangesAsync: sinon.stub(), + shouldFlushHistoryOps: sinon.stub().returns(false) + } + this.Metrics = { + Timer: class Timer {} + } + this.Metrics.Timer.prototype.done = sinon.stub() + + this.logger = { + log: sinon.stub(), + error: sinon.stub() + } + this.ProjectManager = SandboxedModule.require(modulePath, { requires: { - './RedisManager': (this.RedisManager = {}), - './ProjectHistoryRedisManager': (this.ProjectHistoryRedisManager = {}), - './DocumentManager': (this.DocumentManager = {}), - 'logger-sharelatex': (this.logger = { - log: sinon.stub(), - error: sinon.stub() - }), - './HistoryManager': (this.HistoryManager = {}), - './Metrics': (this.Metrics = { - Timer: (Timer = (function () { - Timer = class Timer { - static initClass() { - this.prototype.done = sinon.stub() - } - } - Timer.initClass() - return Timer - })()) - }) + './RedisManager': this.RedisManager, + './ProjectHistoryRedisManager': this.ProjectHistoryRedisManager, + './DocumentManager': this.DocumentManager, + 'logger-sharelatex': this.logger, + './HistoryManager': this.HistoryManager, + './Metrics': this.Metrics } }) @@ -47,8 +48,6 @@ describe('ProjectManager', function () { this.projectHistoryId = 'history-id-123' this.user_id = 'user-id-123' this.version = 1234567 - this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(false) - this.HistoryManager.flushProjectChangesAsync = sinon.stub() this.callback = sinon.stub() }) @@ -72,10 +71,6 @@ describe('ProjectManager', function () { newPathname: 'bar2' } this.fileUpdates = [this.firstFileUpdate] - this.DocumentManager.renameDocWithLock = sinon.stub().yields() - this.ProjectHistoryRedisManager.queueRenameEntity = sinon - .stub() - .yields() }) describe('successfully', function () { @@ -152,9 +147,7 @@ describe('ProjectManager', function () { describe('when renaming a doc fails', function () { beforeEach(function () { this.error = new Error('error') - this.DocumentManager.renameDocWithLock = sinon - .stub() - .yields(this.error) + this.DocumentManager.renameDocWithLock.yields(this.error) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, @@ -174,9 +167,7 @@ describe('ProjectManager', function () { describe('when renaming a file fails', function () { beforeEach(function () { this.error = new Error('error') - this.ProjectHistoryRedisManager.queueRenameEntity = sinon - .stub() - .yields(this.error) + this.ProjectHistoryRedisManager.queueRenameEntity.yields(this.error) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, @@ -195,7 +186,7 @@ describe('ProjectManager', function () { describe('with enough ops to flush', function () { beforeEach(function () { - this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true) + this.HistoryManager.shouldFlushHistoryOps.returns(true) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, @@ -235,7 +226,6 @@ describe('ProjectManager', function () { url: 'filestore.example.com/3' } this.fileUpdates = [this.firstFileUpdate, this.secondFileUpdate] - this.ProjectHistoryRedisManager.queueAddEntity = sinon.stub().yields() }) describe('successfully', function () { @@ -333,9 +323,7 @@ describe('ProjectManager', function () { describe('when adding a doc fails', function () { beforeEach(function () { this.error = new Error('error') - this.ProjectHistoryRedisManager.queueAddEntity = sinon - .stub() - .yields(this.error) + this.ProjectHistoryRedisManager.queueAddEntity.yields(this.error) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, @@ -355,9 +343,7 @@ describe('ProjectManager', function () { describe('when adding a file fails', function () { beforeEach(function () { this.error = new Error('error') - this.ProjectHistoryRedisManager.queueAddEntity = sinon - .stub() - .yields(this.error) + this.ProjectHistoryRedisManager.queueAddEntity.yields(this.error) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, @@ -376,7 +362,7 @@ describe('ProjectManager', function () { describe('with enough ops to flush', function () { beforeEach(function () { - this.HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true) + this.HistoryManager.shouldFlushHistoryOps.returns(true) this.ProjectManager.updateProjectWithLocks( this.project_id, this.projectHistoryId, From 759d385be8a1c6d5550c1b56e5fdf86939403f6c Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Fri, 15 May 2020 08:41:18 -0400 Subject: [PATCH 12/14] Decaf cleanup: unused variables --- .../test/unit/js/ProjectManager/updateProjectTests.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js index 94d132f962..d17f80d44b 100644 --- a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js @@ -1,10 +1,4 @@ -/* eslint-disable - no-return-assign, - no-unused-vars, -*/ const sinon = require('sinon') -const chai = require('chai') -const should = chai.should() const modulePath = '../../../../app/js/ProjectManager.js' const SandboxedModule = require('sandboxed-module') const _ = require('lodash') From 65fe74fd2dde6f36abeef9ac6de96807a21bf838 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Fri, 15 May 2020 14:29:49 -0400 Subject: [PATCH 13/14] Upgrade Sinon --- services/document-updater/package-lock.json | 445 +++++++++++------- services/document-updater/package.json | 2 +- .../test/acceptance/js/FlushingDocsTests.js | 38 +- .../acceptance/js/GettingADocumentTests.js | 28 +- .../acceptance/js/SettingADocumentTests.js | 36 +- .../DocumentManager/DocumentManagerTests.js | 17 +- .../HistoryRedisManagerTests.js | 2 +- .../js/HttpController/HttpControllerTests.js | 24 +- .../unit/js/LockManager/ReleasingTheLock.js | 2 +- .../test/unit/js/LockManager/getLockTests.js | 10 +- .../test/unit/js/LockManager/tryLockTests.js | 5 +- .../PersistenceManagerTests.js | 17 +- .../flushAndDeleteProjectTests.js | 4 +- .../js/ProjectManager/flushProjectTests.js | 4 +- .../js/ProjectManager/getProjectDocsTests.js | 11 +- .../RealTimeRedisManagerTests.js | 2 +- .../unit/js/RedisManager/RedisManagerTests.js | 24 +- .../test/unit/js/ShareJsDB/ShareJsDBTests.js | 5 +- .../ShareJsUpdateManagerTests.js | 4 +- 19 files changed, 404 insertions(+), 276 deletions(-) diff --git a/services/document-updater/package-lock.json b/services/document-updater/package-lock.json index e3d34fc959..6d838e6217 100644 --- a/services/document-updater/package-lock.json +++ b/services/document-updater/package-lock.json @@ -160,7 +160,7 @@ "@google-cloud/debug-agent": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.2.0.tgz", - "integrity": "sha512-fP87kYbS6aeDna08BivwQ1J260mwJGchRi99XdWCgqbRwuFac8ul0OT5i2wEeDSc5QaDX8ZuWQQ0igZvh1rTyQ==", + "integrity": "sha1-2qdjWhaYpWY31dxXzhED536uKdM=", "requires": { "@google-cloud/common": "^0.32.0", "@sindresorhus/is": "^0.15.0", @@ -393,7 +393,7 @@ "@google-cloud/profiler": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", - "integrity": "sha512-rNvtrFtIebIxZEJ/O0t8n7HciZGIXBo8DvHxWqAmsCaeLvkTtsaL6HmPkwxrNQ1IhbYWAxF+E/DwCiHyhKmgTg==", + "integrity": "sha1-Fj3738Mwuug1X+RuHlvgZTV7H1w=", "requires": { "@google-cloud/common": "^0.26.0", "@types/console-log-level": "^1.4.0", @@ -415,7 +415,7 @@ "@google-cloud/common": { "version": "0.26.2", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz", - "integrity": "sha512-xJ2M/q3MrUbnYZuFlpF01caAlEhAUoRn0NXp93Hn3pkFpfSOG8YfbKbpBAHvcKVbBOAKVIwPsleNtuyuabUwLQ==", + "integrity": "sha1-nFTiRxqEqgMelaJIJJduCA8lVkU=", "requires": { "@google-cloud/projectify": "^0.3.2", "@google-cloud/promisify": "^0.3.0", @@ -439,7 +439,7 @@ "@google-cloud/promisify": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", - "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" + "integrity": "sha1-9kHm2USo4KBe4MsQkd+mAIm+zbo=" }, "agent-base": { "version": "4.3.0", @@ -452,7 +452,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "debug": { "version": "3.2.6", @@ -476,7 +476,7 @@ "gcp-metadata": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz", - "integrity": "sha512-caV4S84xAjENtpezLCT/GILEAF5h/bC4cNqZFmt/tjTn8t+JBtTkQrgBrJu3857YdsnlM8rxX/PMcKGtE8hUlw==", + "integrity": "sha1-H510lfdGChRSZIHynhFZbdVj3SY=", "requires": { "gaxios": "^1.0.2", "json-bigint": "^0.3.0" @@ -485,7 +485,7 @@ "google-auth-library": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", - "integrity": "sha512-FURxmo1hBVmcfLauuMRKOPYAPKht3dGuI2wjeJFalDUThO0HoYVjr4yxt5cgYSFm1dgUpmN9G/poa7ceTFAIiA==", + "integrity": "sha1-ejFdIDZ0Svavyth7IQ7mY4tA9Xs=", "requires": { "axios": "^0.18.0", "gcp-metadata": "^0.7.0", @@ -499,7 +499,7 @@ "gcp-metadata": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz", - "integrity": "sha512-ffjC09amcDWjh3VZdkDngIo7WoluyC5Ag9PAYxZbmQLOLNI8lvPtoKTSCyU54j2gwy5roZh6sSMTfkY2ct7K3g==", + "integrity": "sha1-bDXbtSvaMqQnu5yY9UI33dG1QG8=", "requires": { "axios": "^0.18.0", "extend": "^3.0.1", @@ -602,7 +602,7 @@ "@google-cloud/trace-agent": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", - "integrity": "sha512-KDo85aPN4gSxJ7oEIOlKd7aGENZFXAM1kbIn1Ds+61gh/K1CQWSyepgJo3nUpAwH6D1ezDWV7Iaf8ueoITc8Uw==", + "integrity": "sha1-W+dEE5TQ6ldY8o25IqUAT/PwO+w=", "requires": { "@google-cloud/common": "^0.32.1", "builtin-modules": "^3.0.0", @@ -829,27 +829,27 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" }, "@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU=" }, "@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs=" }, "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -858,32 +858,93 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@sindresorhus/is": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz", - "integrity": "sha512-lu8BpxjAtRCAo5ifytTpCPCj99LF7o/2Myn+NXyNCBqvPYn7Pjd76AMmUB5l7XF1U6t0hcWrlEM5ESufW7wAeA==" + "integrity": "sha1-lpFbqgXmpqHRN7rfSYTT/AWCC7Y=" + }, + "@sinonjs/commons": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", + "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + }, + "dependencies": { + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/formatio": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", + "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^5.0.2" + } + }, + "@sinonjs/samsam": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.0.3.tgz", + "integrity": "sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + }, + "dependencies": { + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true }, "@tootallnate/once": { "version": "1.0.0", @@ -893,7 +954,7 @@ "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + "integrity": "sha1-9l09Y4ngHutFi9VNyPUrlalGO8g=" }, "@types/color-name": { "version": "1.1.1", @@ -904,12 +965,12 @@ "@types/console-log-level": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", - "integrity": "sha512-x+OscEQwcx5Biair4enH7ov9W+clcqUWaZRaxn5IkT4yNWWjRr2oiYDkY/x1uXSTVZOQ2xlbFQySaQGB+VdXGQ==" + "integrity": "sha1-7/ccQa689RyLpa2LBdfVQkviuPM=" }, "@types/duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", + "integrity": "sha1-38grZL06IWj1vSZESvFlvwI33Ng=", "requires": { "@types/node": "*" } @@ -970,7 +1031,7 @@ "@types/semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + "integrity": "sha1-FGwqKe59O65L8vyydGNuJkyBPEU=" }, "@types/tough-cookie": { "version": "2.3.6", @@ -1033,7 +1094,7 @@ "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "integrity": "sha1-6vVNU7YrrkE46AnKIlyEOabvs5I=", "requires": { "event-target-shim": "^5.0.0" } @@ -1182,7 +1243,7 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=" }, "asn1": { "version": "0.2.4", @@ -1200,7 +1261,7 @@ "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "integrity": "sha1-5gtrDo8wG9l+U3UhW9pAbIURjAs=", "dev": true }, "ast-types-flow": { @@ -1226,7 +1287,7 @@ "async-listener": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "integrity": "sha1-p8l6vlcLpgLXgic8DeYKUePhfLw=", "requires": { "semver": "^5.3.0", "shimmer": "^1.1.0" @@ -1242,12 +1303,12 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.9.1", @@ -1257,7 +1318,7 @@ "axios": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "integrity": "sha1-/z8N4ue10YDnV62YAA8Qgbh7zqM=", "requires": { "follow-redirects": "1.5.10", "is-buffer": "^2.0.2" @@ -1286,7 +1347,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { "version": "1.3.1", @@ -1304,12 +1365,12 @@ "bignumber.js": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + "integrity": "sha1-gMBIdZ2CaACAfEv9Uh5Q7bulel8=" }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", "requires": { "file-uri-to-path": "1.0.0" } @@ -1317,7 +1378,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "2.2.0", @@ -1379,7 +1440,7 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", "dev": true }, "bson": { @@ -1390,17 +1451,17 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "builtin-modules": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" + "integrity": "sha1-qtl8FRMet2tltQ7yCOdYTNdqdIQ=" }, "bunyan": { "version": "0.22.3", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha512-v9dd5qmd6nJHEi7fiNo1fR2pMpE8AiB47Ap984p4iJKj+dEA69jSccmq6grFQn6pxIh0evvKpC5XO1SKfiaRoQ==", + "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", "requires": { "dtrace-provider": "0.2.8", "mv": "~2" @@ -1414,21 +1475,6 @@ } } }, - "buster-core": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/buster-core/-/buster-core-0.6.4.tgz", - "integrity": "sha512-WxitPqvzr2J7AA2eLEddv72XYaunQUDI0ICZhd1ucT/HhQI6JqfA7WQtoBoVZSgUn1+7uf9r7Plhh8PdO2+Kjg==", - "dev": true - }, - "buster-format": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/buster-format/-/buster-format-0.5.6.tgz", - "integrity": "sha512-AiH2uZZSwyhgtM7l8/A/7HaqUBJnXwcj9oUPIrSvTKTOo/Go0KJiqnGnRRl4zGqIf3IK3pC/KfkgJMgn6lpyzw==", - "dev": true, - "requires": { - "buster-core": "=0.6.4" - } - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -1470,12 +1516,12 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha512-eRYY0vPS2a9zt5w5Z0aCeWbrXTEyvk7u/Xf71EzNObrjSCPgMm1Nku/D/u2tiqHBX5j40wWhj54YJLtgn8g55A==", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", "dev": true, "requires": { "assertion-error": "^1.0.1", @@ -1486,7 +1532,7 @@ "chai-spies": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/chai-spies/-/chai-spies-0.7.1.tgz", - "integrity": "sha512-ezo+u5DUDjPhOYkgsjbbVhtdzsnVr6n2CL/juJA89YnBsWO4ocL14Ake0txlGrGZo/HwcfhFGaV0czdunr3tHA==", + "integrity": "sha1-ND2Z9RJEIS6LF+ZLk5lv97LCqbE=", "dev": true }, "chalk": { @@ -1576,12 +1622,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-log-level": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", - "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" + "integrity": "sha1-nFprue8e9lsFq6gwKLD/iUzfYwo=" }, "contains-path": { "version": "0.1.0", @@ -1605,7 +1651,7 @@ "continuation-local-storage": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "integrity": "sha1-EfYT906RT+mzTJKtLSj+auHbf/s=", "requires": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" @@ -1644,7 +1690,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cp-file": { "version": "6.2.0", @@ -1697,7 +1743,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "^1.0.0" } @@ -1718,7 +1764,7 @@ "deep-eql": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", "dev": true, "requires": { "type-detect": "0.1.1" @@ -1727,7 +1773,7 @@ "type-detect": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", "dev": true } } @@ -1758,7 +1804,7 @@ "delay": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", - "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==" + "integrity": "sha1-7+6/uPVFV5yzlrOnIkQ+yW0UxQ4=" }, "delayed-stream": { "version": "1.0.0", @@ -1768,7 +1814,7 @@ "denque": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", - "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + "integrity": "sha1-Z0T/dkHBSMP4ppwwflEjXB9KN88=" }, "depd": { "version": "1.1.2", @@ -1783,7 +1829,7 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", "dev": true }, "dlv": { @@ -1821,7 +1867,7 @@ "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "integrity": "sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk=", "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -1861,7 +1907,7 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" }, "ecc-jsbn": { "version": "0.1.2", @@ -1875,7 +1921,7 @@ "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "integrity": "sha1-rg8PothQRe8UqBfao86azQSJ5b8=", "requires": { "safe-buffer": "^5.0.1" } @@ -1883,7 +1929,7 @@ "emitter-listener": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "integrity": "sha1-VrFA6PaZI3Wz18ssqxzHQy2WMug=", "requires": { "shimmer": "^1.2.0" } @@ -1909,7 +1955,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, "error-ex": { "version": "1.3.2", @@ -1957,12 +2003,12 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "integrity": "sha1-TrIVlMlyvEBVPSduUQU5FD21Pgo=" }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { "es6-promise": "^4.0.3" } @@ -1975,7 +2021,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { "version": "6.6.0", @@ -2565,7 +2611,7 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + "integrity": "sha1-XU0+vflYPWOlMzzi3rdICrKwV4k=" }, "eventid": { "version": "1.0.0", @@ -2632,7 +2678,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "3.1.1", @@ -2659,7 +2705,7 @@ "fast-text-encoding": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", - "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" + "integrity": "sha1-PlzoKTQJz6pxd6cbnKhOGx5vJe8=" }, "figures": { "version": "3.2.0", @@ -2682,7 +2728,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=" }, "finalhandler": { "version": "1.1.2", @@ -2719,7 +2765,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat-cache": { "version": "2.0.1", @@ -2766,7 +2812,7 @@ "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", "requires": { "debug": "=3.1.0" }, @@ -2828,7 +2874,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.1", @@ -2877,7 +2923,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "^1.0.0" } @@ -2885,7 +2931,7 @@ "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "optional": true, "requires": { "inflight": "^1.0.4", @@ -3009,7 +3055,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", @@ -3075,13 +3121,13 @@ "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, "hex2dec": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", - "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" + "integrity": "sha1-jhzkvvNqdPfVcjw/swkMKGAHczg=" }, "hosted-git-info": { "version": "2.8.8", @@ -3217,7 +3263,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3389,7 +3435,7 @@ "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" + "integrity": "sha1-Yc/23TxBk9uUo9YlggcrROVkXXk=" }, "is-arrayish": { "version": "0.2.1", @@ -3475,7 +3521,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "isarray": { "version": "1.0.0", @@ -3490,7 +3536,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -3612,7 +3658,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsesc": { "version": "2.5.2", @@ -3622,7 +3668,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", "requires": { "bignumber.js": "^7.0.0" } @@ -3635,7 +3681,7 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", @@ -3651,12 +3697,12 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -3674,6 +3720,12 @@ "object.assign": "^4.1.0" } }, + "just-extend": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "dev": true + }, "jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", @@ -3748,18 +3800,24 @@ "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", @@ -3780,7 +3838,7 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" }, "lodash.unescape": { "version": "4.0.1", @@ -3912,7 +3970,7 @@ "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=" }, "loose-envify": { "version": "1.4.0", @@ -3926,7 +3984,7 @@ "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=", "requires": { "yallist": "^3.0.2" } @@ -3934,7 +3992,7 @@ "lsmod": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha512-Y+6V75r+mGWzWEPr9h6PFmStielICu5JBHLUg18jCsD2VFmEfgHbq/EgnY4inElsUD9eKL9id1qp34w46rSIKQ==" + "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" }, "lynx": { "version": "0.1.1", @@ -4011,7 +4069,7 @@ "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha512-XoSUL+nF8hMTKGQxUs8r3Btdsf1yuKKBdCCGbh3YXgCXuVKishpZv1CNc385w9s8t4Ynwc5h61BwW/FCVulkbg==" + "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" }, "messageformat": { "version": "2.3.0", @@ -4090,7 +4148,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "^1.1.7" } @@ -4098,17 +4156,17 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==" + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=" }, "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", "dev": true, "requires": { "browser-stdout": "1.3.1", @@ -4127,7 +4185,7 @@ "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "integrity": "sha1-30boZ9D8Kuxmo0ZitAapzK//Ww8=", "dev": true }, "debug": { @@ -4142,7 +4200,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -4156,7 +4214,7 @@ "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -4173,12 +4231,12 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "integrity": "sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s=", "optional": true }, "mongodb": { @@ -4223,7 +4281,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -4234,7 +4292,7 @@ "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "optional": true, "requires": { "minimist": "0.0.8" @@ -4256,7 +4314,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, "negotiator": { @@ -4275,10 +4333,40 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "nise": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", + "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "integrity": "sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0=" }, "node-forge": { "version": "0.9.1", @@ -4452,7 +4540,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } @@ -4510,7 +4598,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=" }, "package-hash": { "version": "3.0.0", @@ -4549,12 +4637,12 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" }, "parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" + "integrity": "sha1-NIVlp1PUOR+lJAKZVrFyy3dTCX0=" }, "parseurl": { "version": "1.3.3", @@ -4569,7 +4657,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -4586,7 +4674,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=" }, "path-to-regexp": { "version": "0.1.7", @@ -4611,12 +4699,12 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=" }, "pkg-dir": { "version": "3.0.0", @@ -5282,7 +5370,7 @@ "pretty-ms": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", - "integrity": "sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q==", + "integrity": "sha1-Mbr0G5T9AiJwmKqgO9YmCOsNbpI=", "requires": { "parse-ms": "^2.0.0" } @@ -5320,7 +5408,7 @@ "protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "integrity": "sha1-yLTxKC/XqQ5vWxCe0RyEr4KQjnw=", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -5396,7 +5484,7 @@ "q": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/q/-/q-0.9.2.tgz", - "integrity": "sha512-ZOxMuWPMJnsUdYhuQ9glpZwKhB4cm8ubYFy1nNCY8TkSAuZun5fd8jCDTlf2ykWnK8x9HGn1stNtLeG179DebQ==" + "integrity": "sha1-I8BsRsgTKGFqrhaNPuI6Vr1D2vY=" }, "qs": { "version": "6.7.0", @@ -5423,7 +5511,7 @@ "raven": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha512-RYov4wAaflZasWiCrZuizd3jNXxCOkW1WrXgWsGVb8kRpdHNZ+vPY27R6RhVtqzWp+DG9a5l6iP0QUPK4EgzaQ==", + "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", "requires": { "cookie": "0.3.1", "json-stringify-safe": "5.0.1", @@ -5435,7 +5523,7 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "uuid": { "version": "3.0.0", @@ -5493,22 +5581,22 @@ "redis": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/redis/-/redis-0.11.0.tgz", - "integrity": "sha512-wkgzIZ9HuxJ6Sul1IW/6FG13Ecv6q8kmdHb5xo09Hu6bgWzz5qsnM06SVMpDxFNbyApaRjy8CwnmVaRMMhAMWg==" + "integrity": "sha1-/cAdSrTL5LO7LLKByP5WnDhX9XE=" }, "redis-commands": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz", - "integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==" + "integrity": "sha1-gNLiBpj+aI8icSf/nlFkp90X54U=" }, "redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==" + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" }, "redis-parser": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", "requires": { "redis-errors": "^1.0.0" } @@ -5516,7 +5604,7 @@ "redis-sentinel": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/redis-sentinel/-/redis-sentinel-0.1.1.tgz", - "integrity": "sha512-cKtLSUzDsKmsB50J1eIV/SH11DSMiHgsm/gDPRCU5lXz5OyTSuLKWg9oc8d5n74kZwtAyRkfJP0x8vYXvlPjFQ==", + "integrity": "sha1-Vj3TQduZMgMfSX+v3Td+hkj/s+U=", "requires": { "q": "0.9.2", "redis": "0.11.x" @@ -5673,7 +5761,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", "dev": true }, "require-main-filename": { @@ -5690,7 +5778,7 @@ "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" @@ -5714,7 +5802,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -5729,7 +5817,7 @@ "retry-axios": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz", - "integrity": "sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ==" + "integrity": "sha1-V1fID1hbTMTEmGqi/9R6YMbTXhM=" }, "retry-request": { "version": "4.1.1", @@ -5758,7 +5846,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", "optional": true, "requires": { "glob": "^6.0.1" @@ -5787,7 +5875,7 @@ "safe-json-stringify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", - "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "integrity": "sha1-NW5EvJjx+TzkXfFLzXwBzahuCv0=", "optional": true }, "safer-buffer": { @@ -5798,7 +5886,7 @@ "sandboxed-module": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.2.2.tgz", - "integrity": "sha512-1QAd90eCdAnqVn2sLkRCCeFphH/TKLfoTcdyI6h9h2E+YEY+aKovggwzWWWi5IMObafl0W1wr+dQ5F6LFmjpzA==", + "integrity": "sha1-bL3sghOAx31FdcjIeDi5ET5kulA=", "dev": true, "requires": { "require-like": "0.1.2", @@ -5808,7 +5896,7 @@ "stack-trace": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "integrity": "sha512-5/6uZt7RYjjAl8z2j1mXWAewz+I4Hk2/L/3n6NRLIQ31+uQ7nMd9O6G69QCdrrufHv0QGRRHl/jwUEGTqhelTA==", + "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", "dev": true } } @@ -5878,7 +5966,7 @@ "settings-sharelatex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", + "integrity": "sha1-Tv4vUpPbjxwVlnEEx5BfqHD/mS0=", "requires": { "coffee-script": "1.6.0" }, @@ -5886,7 +5974,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" } } }, @@ -5908,7 +5996,7 @@ "shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + "integrity": "sha1-YQhZ994ye1h+/r9QH7QxF/mv8zc=" }, "side-channel": { "version": "1.0.2", @@ -5926,12 +6014,41 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "sinon": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.5.2.tgz", - "integrity": "sha512-4I5YC02+PBQpCCPUydFuUpH4X4+t4IpFmKbP1gHthoFiD7yyLPx179im5jgUPw/O2BytFYnl6NLL4ijh585uiA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz", + "integrity": "sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A==", "dev": true, "requires": { - "buster-format": "~0.5" + "@sinonjs/commons": "^1.7.2", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.0.3", + "diff": "^4.0.2", + "nise": "^4.0.1", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "slice-ansi": { @@ -5957,7 +6074,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" }, "sparse-bitfield": { "version": "3.0.3", @@ -6048,7 +6165,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "requires": { "through": "2" } @@ -6077,17 +6194,17 @@ "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==" + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" }, "standard-as-callback": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.0.1.tgz", - "integrity": "sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==" + "integrity": "sha1-7YuyVkjhWDF1m2Ajvbh+a2CzgSY=" }, "statsd-parser": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha512-7XO+ur89EalMXXFQaydsczB8sclr5nDsNIoUu0IzJx1pIbHUhO3LtpSzBwetIuU9DyTLMiVaJBMtWS/Nb2KR4g==" + "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" }, "statuses": { "version": "1.5.0", @@ -6228,7 +6345,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } @@ -6287,7 +6404,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "3.0.1", @@ -6350,7 +6467,7 @@ "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" }, "to-no-case": { "version": "1.0.2", @@ -6411,7 +6528,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", @@ -6451,7 +6568,7 @@ "underscore": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" }, "unpipe": { "version": "1.0.0", @@ -6461,7 +6578,7 @@ "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", "requires": { "punycode": "^2.1.0" } @@ -6469,7 +6586,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", @@ -6504,7 +6621,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -6593,7 +6710,7 @@ "when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", - "integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw==" + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" }, "which": { "version": "1.3.1", @@ -6627,7 +6744,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", diff --git a/services/document-updater/package.json b/services/document-updater/package.json index af5f3ff6ac..3f0b1e2de0 100644 --- a/services/document-updater/package.json +++ b/services/document-updater/package.json @@ -55,7 +55,7 @@ "prettier": "^2.0.5", "prettier-eslint-cli": "^5.0.0", "sandboxed-module": "~0.2.0", - "sinon": "~1.5.2", + "sinon": "^9.0.2", "timekeeper": "^2.0.0" } } diff --git a/services/document-updater/test/acceptance/js/FlushingDocsTests.js b/services/document-updater/test/acceptance/js/FlushingDocsTests.js index 5556870f8e..109f89d434 100644 --- a/services/document-updater/test/acceptance/js/FlushingDocsTests.js +++ b/services/document-updater/test/acceptance/js/FlushingDocsTests.js @@ -121,26 +121,26 @@ describe('Flushing a doc to Mongo', function () { version: this.version }) let t = 30000 - sinon.stub( - MockWebApi, - 'setDocument', - ( - project_id, - doc_id, - lines, - version, - ranges, - lastUpdatedAt, - lastUpdatedBy, - callback - ) => { - if (callback == null) { - callback = function (error) {} + sinon + .stub(MockWebApi, 'setDocument') + .callsFake( + ( + project_id, + doc_id, + lines, + version, + ranges, + lastUpdatedAt, + lastUpdatedBy, + callback + ) => { + if (callback == null) { + callback = function (error) {} + } + setTimeout(callback, t) + return (t = 0) } - setTimeout(callback, t) - return (t = 0) - } - ) + ) return DocUpdaterClient.preloadDoc(this.project_id, this.doc_id, done) }) diff --git a/services/document-updater/test/acceptance/js/GettingADocumentTests.js b/services/document-updater/test/acceptance/js/GettingADocumentTests.js index fc97c8d825..a0b9de5773 100644 --- a/services/document-updater/test/acceptance/js/GettingADocumentTests.js +++ b/services/document-updater/test/acceptance/js/GettingADocumentTests.js @@ -216,12 +216,14 @@ describe('Getting a document', function () { DocUpdaterClient.randomId(), DocUpdaterClient.randomId() ]) - sinon.stub(MockWebApi, 'getDocument', (project_id, doc_id, callback) => { - if (callback == null) { - callback = function (error, doc) {} - } - return callback(new Error('oops')) - }) + sinon + .stub(MockWebApi, 'getDocument') + .callsFake((project_id, doc_id, callback) => { + if (callback == null) { + callback = function (error, doc) {} + } + return callback(new Error('oops')) + }) return DocUpdaterClient.getDoc( this.project_id, this.doc_id, @@ -248,12 +250,14 @@ describe('Getting a document', function () { DocUpdaterClient.randomId(), DocUpdaterClient.randomId() ]) - sinon.stub(MockWebApi, 'getDocument', (project_id, doc_id, callback) => { - if (callback == null) { - callback = function (error, doc) {} - } - return setTimeout(callback, 30000) - }) + sinon + .stub(MockWebApi, 'getDocument') + .callsFake((project_id, doc_id, callback) => { + if (callback == null) { + callback = function (error, doc) {} + } + return setTimeout(callback, 30000) + }) return done() }) diff --git a/services/document-updater/test/acceptance/js/SettingADocumentTests.js b/services/document-updater/test/acceptance/js/SettingADocumentTests.js index 484d51b57c..54ca9d00d0 100644 --- a/services/document-updater/test/acceptance/js/SettingADocumentTests.js +++ b/services/document-updater/test/acceptance/js/SettingADocumentTests.js @@ -88,9 +88,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it('should return a 204 status code', function () { @@ -171,9 +171,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it('should return a 204 status code', function () { @@ -254,9 +254,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it(`should return a ${testCase.expectedStatusCode} status code`, function () { @@ -310,9 +310,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it('should return a 204 status code', function () { @@ -388,9 +388,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it('should undo the tracked changes', function (done) { @@ -451,9 +451,9 @@ describe('Setting a document', function () { }) after(function () { - MockTrackChangesApi.flushDoc.reset() - MockProjectHistoryApi.flushProject.reset() - MockWebApi.setDocument.reset() + MockTrackChangesApi.flushDoc.resetHistory() + MockProjectHistoryApi.flushProject.resetHistory() + MockWebApi.setDocument.resetHistory() }) it('should not undo the tracked changes', function (done) { diff --git a/services/document-updater/test/unit/js/DocumentManager/DocumentManagerTests.js b/services/document-updater/test/unit/js/DocumentManager/DocumentManagerTests.js index 4baa5cee8d..295a643cee 100644 --- a/services/document-updater/test/unit/js/DocumentManager/DocumentManagerTests.js +++ b/services/document-updater/test/unit/js/DocumentManager/DocumentManagerTests.js @@ -52,7 +52,8 @@ describe('DocumentManager', function () { './RealTimeRedisManager': (this.RealTimeRedisManager = {}), './DiffCodec': (this.DiffCodec = {}), './UpdateManager': (this.UpdateManager = {}), - './RangesManager': (this.RangesManager = {}) + './RangesManager': (this.RangesManager = {}), + './Errors': Errors } }) this.project_id = 'project-id-123' @@ -765,10 +766,9 @@ describe('DocumentManager', function () { }) return it('should call the callback with a not found error', function () { - const error = new Errors.NotFoundError( - `document not found: ${this.doc_id}` - ) - return this.callback.calledWith(error).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) + .should.equal(true) }) }) }) @@ -848,10 +848,9 @@ describe('DocumentManager', function () { }) return it('should call the callback with a not found error', function () { - const error = new Errors.NotFoundError( - `document not found: ${this.doc_id}` - ) - return this.callback.calledWith(error).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) + .should.equal(true) }) }) }) diff --git a/services/document-updater/test/unit/js/HistoryRedisManager/HistoryRedisManagerTests.js b/services/document-updater/test/unit/js/HistoryRedisManager/HistoryRedisManagerTests.js index 68321533b3..c578a6be22 100644 --- a/services/document-updater/test/unit/js/HistoryRedisManager/HistoryRedisManagerTests.js +++ b/services/document-updater/test/unit/js/HistoryRedisManager/HistoryRedisManagerTests.js @@ -95,7 +95,7 @@ describe('HistoryRedisManager', function () { return it('should call the callback with an error', function () { return this.callback - .calledWith(new Error('cannot push no ops')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) diff --git a/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js b/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js index 64751e55db..36cf990724 100644 --- a/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js +++ b/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js @@ -159,7 +159,7 @@ describe('HttpController', function () { it('should call next with NotFoundError', function () { this.next - .calledWith(new Errors.NotFoundError('not found')) + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) .should.equal(true) }) }) @@ -173,7 +173,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -252,7 +252,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) @@ -327,7 +327,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -387,7 +387,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -477,7 +477,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -550,7 +550,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -640,7 +640,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -703,7 +703,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -804,7 +804,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -870,7 +870,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) @@ -925,7 +925,7 @@ describe('HttpController', function () { }) it('should call next with the error', function () { - this.next.calledWith(new Error('oops')).should.equal(true) + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) }) }) }) diff --git a/services/document-updater/test/unit/js/LockManager/ReleasingTheLock.js b/services/document-updater/test/unit/js/LockManager/ReleasingTheLock.js index d0c88940cc..82b0bc7da7 100644 --- a/services/document-updater/test/unit/js/LockManager/ReleasingTheLock.js +++ b/services/document-updater/test/unit/js/LockManager/ReleasingTheLock.js @@ -92,7 +92,7 @@ describe('LockManager - releasing the lock', function () { return it('should return an error if the lock has expired', function () { return this.callback - .calledWith(new Error('tried to release timed out lock')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) diff --git a/services/document-updater/test/unit/js/LockManager/getLockTests.js b/services/document-updater/test/unit/js/LockManager/getLockTests.js index 1c41f2b0b4..cbe805040b 100644 --- a/services/document-updater/test/unit/js/LockManager/getLockTests.js +++ b/services/document-updater/test/unit/js/LockManager/getLockTests.js @@ -119,9 +119,13 @@ describe('LockManager - getting the lock', function () { }) return it('should return the callback with an error', function () { - const e = new Error('Timeout') - e.doc_id = this.doc_id - return this.callback.calledWith(e).should.equal(true) + return this.callback + .calledWith( + sinon.match + .instanceOf(Error) + .and(sinon.match.has('doc_id', this.doc_id)) + ) + .should.equal(true) }) }) }) diff --git a/services/document-updater/test/unit/js/LockManager/tryLockTests.js b/services/document-updater/test/unit/js/LockManager/tryLockTests.js index 77aecd87d1..36be6321bd 100644 --- a/services/document-updater/test/unit/js/LockManager/tryLockTests.js +++ b/services/document-updater/test/unit/js/LockManager/tryLockTests.js @@ -142,8 +142,9 @@ describe('LockManager - trying the lock', function () { }) return it('should return the callback with an error', function () { - const e = new Error('tried to release timed out lock') - return this.callback.calledWith(e).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Error)) + .should.equal(true) }) }) }) diff --git a/services/document-updater/test/unit/js/PersistenceManager/PersistenceManagerTests.js b/services/document-updater/test/unit/js/PersistenceManager/PersistenceManagerTests.js index 98039d7823..645ee8a59b 100644 --- a/services/document-updater/test/unit/js/PersistenceManager/PersistenceManagerTests.js +++ b/services/document-updater/test/unit/js/PersistenceManager/PersistenceManagerTests.js @@ -41,7 +41,8 @@ describe('PersistenceManager', function () { 'logger-sharelatex': (this.logger = { log: sinon.stub(), err: sinon.stub() - }) + }), + './Errors': Errors } }) this.project_id = 'project-id-123' @@ -171,7 +172,7 @@ describe('PersistenceManager', function () { it('should return a NotFoundError', function () { return this.callback - .calledWith(new Errors.NotFoundError('not found')) + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) .should.equal(true) }) @@ -198,7 +199,7 @@ describe('PersistenceManager', function () { it('should return an error', function () { return this.callback - .calledWith(new Error('web api error')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) @@ -231,7 +232,7 @@ describe('PersistenceManager', function () { return it('should return and error', function () { return this.callback - .calledWith(new Error('web API response had no doc lines')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -254,7 +255,7 @@ describe('PersistenceManager', function () { return it('should return and error', function () { return this.callback - .calledWith(new Error('web API response had no valid doc version')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -277,7 +278,7 @@ describe('PersistenceManager', function () { return it('should return and error', function () { return this.callback - .calledWith(new Error('web API response had no valid doc pathname')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -386,7 +387,7 @@ describe('PersistenceManager', function () { it('should return a NotFoundError', function () { return this.callback - .calledWith(new Errors.NotFoundError('not found')) + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) .should.equal(true) }) @@ -418,7 +419,7 @@ describe('PersistenceManager', function () { it('should return an error', function () { return this.callback - .calledWith(new Error('web api error')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) diff --git a/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js index 266d1d1a2e..9589d42054 100644 --- a/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/flushAndDeleteProjectTests.js @@ -147,7 +147,9 @@ describe('ProjectManager - flushAndDeleteProject', function () { }) it('should call the callback with an error', function () { - return this.callback.calledWith(new Error()).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Error)) + .should.equal(true) }) return it('should time the execution', function () { diff --git a/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js index 1907a26228..c0bb668f49 100644 --- a/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/flushProjectTests.js @@ -136,7 +136,9 @@ describe('ProjectManager - flushProject', function () { }) it('should call the callback with an error', function () { - return this.callback.calledWith(new Error()).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Error)) + .should.equal(true) }) return it('should time the execution', function () { diff --git a/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js b/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js index a10b328864..db9f31e4ad 100644 --- a/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/getProjectDocsTests.js @@ -40,7 +40,8 @@ describe('ProjectManager - getProjectDocsAndFlushIfOld', function () { Timer.initClass() return Timer })()) - }) + }), + './Errors': Errors } }) this.project_id = 'project-id-123' @@ -146,9 +147,7 @@ describe('ProjectManager - getProjectDocsAndFlushIfOld', function () { it('should call the callback with an error', function () { return this.callback - .calledWith( - new Errors.ProjectStateChangedError('project state changed') - ) + .calledWith(sinon.match.instanceOf(Errors.ProjectStateChangedError)) .should.equal(true) }) @@ -194,7 +193,9 @@ describe('ProjectManager - getProjectDocsAndFlushIfOld', function () { }) it('should call the callback with an error', function () { - return this.callback.calledWith(new Error('oops')).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Error)) + .should.equal(true) }) return it('should time the execution', function () { diff --git a/services/document-updater/test/unit/js/RealTimeRedisManager/RealTimeRedisManagerTests.js b/services/document-updater/test/unit/js/RealTimeRedisManager/RealTimeRedisManagerTests.js index 9e2f2e270f..cda00ca9d8 100644 --- a/services/document-updater/test/unit/js/RealTimeRedisManager/RealTimeRedisManagerTests.js +++ b/services/document-updater/test/unit/js/RealTimeRedisManager/RealTimeRedisManagerTests.js @@ -118,7 +118,7 @@ describe('RealTimeRedisManager', function () { return it('should return an error to the callback', function () { return this.callback - .calledWith(new Error('JSON parse error')) + .calledWith(sinon.match.has('name', 'SyntaxError')) .should.equal(true) }) }) diff --git a/services/document-updater/test/unit/js/RedisManager/RedisManagerTests.js b/services/document-updater/test/unit/js/RedisManager/RedisManagerTests.js index e36df094f1..467c9a3c2f 100644 --- a/services/document-updater/test/unit/js/RedisManager/RedisManagerTests.js +++ b/services/document-updater/test/unit/js/RedisManager/RedisManagerTests.js @@ -398,7 +398,7 @@ describe('RedisManager', function () { return it('should return an error', function () { return this.callback - .calledWith(new Error('redis getDoc exceeded timeout')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -426,7 +426,7 @@ describe('RedisManager', function () { return it('should return an error', function () { return this.callback - .calledWith(new Errors.NotFoundError('not found')) + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) .should.equal(true) }) }) @@ -543,11 +543,7 @@ describe('RedisManager', function () { it('should return an error', function () { return this.callback - .calledWith( - new Errors.OpRangeNotAvailableError( - 'doc ops range is not loaded in redis' - ) - ) + .calledWith(sinon.match.instanceOf(Errors.OpRangeNotAvailableError)) .should.equal(true) }) @@ -588,7 +584,7 @@ describe('RedisManager', function () { return it('should return an error', function () { return this.callback - .calledWith(new Error('redis getPreviousDocOps exceeded timeout')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -854,9 +850,7 @@ describe('RedisManager', function () { return it('should call the callback with an error', function () { return this.callback - .calledWith( - new Error(`Version mismatch. '${this.doc_id}' is corrupted.`) - ) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -954,7 +948,7 @@ describe('RedisManager', function () { return it('should call the callback with an error', function () { return this.callback - .calledWith(new Error('null bytes found in doc lines')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -985,7 +979,7 @@ describe('RedisManager', function () { return it('should call the callback with the error', function () { return this.callback - .calledWith(new Error('ranges are too large')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -1157,7 +1151,7 @@ describe('RedisManager', function () { return it('should call the callback with an error', function () { return this.callback - .calledWith(new Error('null bytes found in doc lines')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) @@ -1185,7 +1179,7 @@ describe('RedisManager', function () { return it('should call the callback with the error', function () { return this.callback - .calledWith(new Error('ranges are too large')) + .calledWith(sinon.match.instanceOf(Error)) .should.equal(true) }) }) diff --git a/services/document-updater/test/unit/js/ShareJsDB/ShareJsDBTests.js b/services/document-updater/test/unit/js/ShareJsDB/ShareJsDBTests.js index 7f7d377c1d..ddf98775d8 100644 --- a/services/document-updater/test/unit/js/ShareJsDB/ShareJsDBTests.js +++ b/services/document-updater/test/unit/js/ShareJsDB/ShareJsDBTests.js @@ -26,7 +26,8 @@ describe('ShareJsDB', function () { this.callback = sinon.stub() this.ShareJsDB = SandboxedModule.require(modulePath, { requires: { - './RedisManager': (this.RedisManager = {}) + './RedisManager': (this.RedisManager = {}), + './Errors': Errors } }) @@ -68,7 +69,7 @@ describe('ShareJsDB', function () { return it('should return the callback with a NotFoundError', function () { return this.callback - .calledWith(new Errors.NotFoundError('not found')) + .calledWith(sinon.match.instanceOf(Errors.NotFoundError)) .should.equal(true) }) }) diff --git a/services/document-updater/test/unit/js/ShareJsUpdateManager/ShareJsUpdateManagerTests.js b/services/document-updater/test/unit/js/ShareJsUpdateManager/ShareJsUpdateManagerTests.js index 56afe4c584..ff8b74b8e6 100644 --- a/services/document-updater/test/unit/js/ShareJsUpdateManager/ShareJsUpdateManagerTests.js +++ b/services/document-updater/test/unit/js/ShareJsUpdateManager/ShareJsUpdateManagerTests.js @@ -194,7 +194,9 @@ describe('ShareJsUpdateManager', function () { }) return it('should call the callback with the error', function () { - return this.callback.calledWith(this.error).should.equal(true) + return this.callback + .calledWith(sinon.match.instanceOf(Error)) + .should.equal(true) }) }) }) From 9799b94752e1b53975039921dfedb42ea80e554d Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Fri, 15 May 2020 15:54:31 -0400 Subject: [PATCH 14/14] Accept ordered doc and file updates Add an `updates` parameter to the project update endpoint. It can be used instead of `docUpdates` and `fileUpdates` to provide a single list of updates in the order they should be processed. --- services/document-updater/.eslintrc | 2 +- .../document-updater/app/js/HttpController.js | 32 +++- .../document-updater/app/js/ProjectManager.js | 154 +++++++++--------- .../js/HttpController/HttpControllerTests.js | 113 ++++++++++++- .../js/ProjectManager/updateProjectTests.js | 64 +++++--- 5 files changed, 250 insertions(+), 115 deletions(-) diff --git a/services/document-updater/.eslintrc b/services/document-updater/.eslintrc index 2e945d6ffb..76dad1561d 100644 --- a/services/document-updater/.eslintrc +++ b/services/document-updater/.eslintrc @@ -8,7 +8,7 @@ "prettier/standard" ], "parserOptions": { - "ecmaVersion": 2017 + "ecmaVersion": 2018 }, "plugins": [ "mocha", diff --git a/services/document-updater/app/js/HttpController.js b/services/document-updater/app/js/HttpController.js index 646a8578df..d2904eb898 100644 --- a/services/document-updater/app/js/HttpController.js +++ b/services/document-updater/app/js/HttpController.js @@ -330,19 +330,23 @@ function updateProject(req, res, next) { userId, docUpdates, fileUpdates, + updates, version } = req.body logger.log( - { projectId, docUpdates, fileUpdates, version }, + { projectId, updates, docUpdates, fileUpdates, version }, 'updating project via http' ) - + const allUpdates = _mergeUpdates( + docUpdates || [], + fileUpdates || [], + updates || [] + ) ProjectManager.updateProjectWithLocks( projectId, projectHistoryId, userId, - docUpdates, - fileUpdates, + allUpdates, version, (error) => { timer.done() @@ -412,3 +416,23 @@ function flushQueuedProjects(req, res, next) { } }) } + +/** + * Merge updates from the previous project update interface (docUpdates + + * fileUpdates) and the new update interface (updates). + */ +function _mergeUpdates(docUpdates, fileUpdates, updates) { + const mergedUpdates = [] + for (const update of docUpdates) { + const type = update.docLines != null ? 'add-doc' : 'rename-doc' + mergedUpdates.push({ type, ...update }) + } + for (const update of fileUpdates) { + const type = update.url != null ? 'add-file' : 'rename-file' + mergedUpdates.push({ type, ...update }) + } + for (const update of updates) { + mergedUpdates.push(update) + } + return mergedUpdates +} diff --git a/services/document-updater/app/js/ProjectManager.js b/services/document-updater/app/js/ProjectManager.js index 768ab3e759..07284a692a 100644 --- a/services/document-updater/app/js/ProjectManager.js +++ b/services/document-updater/app/js/ProjectManager.js @@ -212,9 +212,8 @@ function updateProjectWithLocks( projectId, projectHistoryId, userId, - docUpdates, - fileUpdates, - version, + updates, + projectVersion, _callback ) { const timer = new Metrics.Timer('projectManager.updateProject') @@ -223,92 +222,85 @@ function updateProjectWithLocks( _callback(...args) } - const projectVersion = version let projectSubversion = 0 // project versions can have multiple operations - let projectOpsLength = 0 - const handleDocUpdate = function (projectUpdate, cb) { - const docId = projectUpdate.id - projectUpdate.version = `${projectVersion}.${projectSubversion++}` - if (projectUpdate.docLines != null) { - ProjectHistoryRedisManager.queueAddEntity( - projectId, - projectHistoryId, - 'doc', - docId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } else { - DocumentManager.renameDocWithLock( - projectId, - docId, - userId, - projectUpdate, - projectHistoryId, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) + function handleUpdate(update, cb) { + update.version = `${projectVersion}.${projectSubversion++}` + switch (update.type) { + case 'add-doc': + ProjectHistoryRedisManager.queueAddEntity( + projectId, + projectHistoryId, + 'doc', + update.id, + userId, + update, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + break + case 'rename-doc': + DocumentManager.renameDocWithLock( + projectId, + update.id, + userId, + update, + projectHistoryId, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + break + case 'add-file': + ProjectHistoryRedisManager.queueAddEntity( + projectId, + projectHistoryId, + 'file', + update.id, + userId, + update, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + break + case 'rename-file': + ProjectHistoryRedisManager.queueRenameEntity( + projectId, + projectHistoryId, + 'file', + update.id, + userId, + update, + (error, count) => { + projectOpsLength = count + cb(error) + } + ) + break + default: + cb(new Error(`Unknown update type: ${update.type}`)) } } - const handleFileUpdate = function (projectUpdate, cb) { - const fileId = projectUpdate.id - projectUpdate.version = `${projectVersion}.${projectSubversion++}` - if (projectUpdate.url != null) { - ProjectHistoryRedisManager.queueAddEntity( - projectId, - projectHistoryId, - 'file', - fileId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } else { - ProjectHistoryRedisManager.queueRenameEntity( - projectId, - projectHistoryId, - 'file', - fileId, - userId, - projectUpdate, - (error, count) => { - projectOpsLength = count - cb(error) - } - ) - } - } - - async.eachSeries(docUpdates, handleDocUpdate, (error) => { + async.eachSeries(updates, handleUpdate, (error) => { if (error) { return callback(error) } - async.eachSeries(fileUpdates, handleFileUpdate, (error) => { - if (error) { - return callback(error) - } - if ( - HistoryManager.shouldFlushHistoryOps( - projectOpsLength, - docUpdates.length + fileUpdates.length, - HistoryManager.FLUSH_PROJECT_EVERY_N_OPS - ) - ) { - HistoryManager.flushProjectChangesAsync(projectId) - } - callback() - }) + if ( + HistoryManager.shouldFlushHistoryOps( + projectOpsLength, + updates.length, + HistoryManager.FLUSH_PROJECT_EVERY_N_OPS + ) + ) { + HistoryManager.flushProjectChangesAsync(projectId) + } + callback() }) } diff --git a/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js b/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js index 36cf990724..4d9790926a 100644 --- a/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js +++ b/services/document-updater/test/unit/js/HttpController/HttpControllerTests.js @@ -809,12 +809,34 @@ describe('HttpController', function () { }) }) - describe('updateProject', function () { + describe('updateProject (split doc and file updates)', function () { beforeEach(function () { this.projectHistoryId = 'history-id-123' this.userId = 'user-id-123' - this.docUpdates = sinon.stub() - this.fileUpdates = sinon.stub() + this.docUpdates = [ + { id: 1, pathname: 'thesis.tex', newPathname: 'book.tex' }, + { id: 2, pathname: 'article.tex', docLines: 'hello' } + ] + this.fileUpdates = [ + { id: 3, pathname: 'apple.png', newPathname: 'banana.png' }, + { id: 4, url: 'filestore.example.com/4' } + ] + this.expectedUpdates = [ + { + type: 'rename-doc', + id: 1, + pathname: 'thesis.tex', + newPathname: 'book.tex' + }, + { type: 'add-doc', id: 2, pathname: 'article.tex', docLines: 'hello' }, + { + type: 'rename-file', + id: 3, + pathname: 'apple.png', + newPathname: 'banana.png' + }, + { type: 'add-file', id: 4, url: 'filestore.example.com/4' } + ] this.version = 1234567 this.req = { query: {}, @@ -833,9 +855,7 @@ describe('HttpController', function () { describe('successfully', function () { beforeEach(function () { - this.ProjectManager.updateProjectWithLocks = sinon - .stub() - .callsArgWith(6) + this.ProjectManager.updateProjectWithLocks = sinon.stub().yields() this.HttpController.updateProject(this.req, this.res, this.next) }) @@ -845,8 +865,7 @@ describe('HttpController', function () { this.project_id, this.projectHistoryId, this.userId, - this.docUpdates, - this.fileUpdates, + this.expectedUpdates, this.version ) .should.equal(true) @@ -865,7 +884,83 @@ describe('HttpController', function () { beforeEach(function () { this.ProjectManager.updateProjectWithLocks = sinon .stub() - .callsArgWith(6, new Error('oops')) + .yields(new Error('oops')) + this.HttpController.updateProject(this.req, this.res, this.next) + }) + + it('should call next with the error', function () { + this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true) + }) + }) + }) + + describe('updateProject (single updates parameter)', function () { + beforeEach(function () { + this.projectHistoryId = 'history-id-123' + this.userId = 'user-id-123' + this.updates = [ + { + type: 'rename-doc', + id: 1, + pathname: 'thesis.tex', + newPathname: 'book.tex' + }, + { type: 'add-doc', id: 2, pathname: 'article.tex', docLines: 'hello' }, + { + type: 'rename-file', + id: 3, + pathname: 'apple.png', + newPathname: 'banana.png' + }, + { type: 'add-file', id: 4, url: 'filestore.example.com/4' } + ] + this.version = 1234567 + this.req = { + query: {}, + body: { + projectHistoryId: this.projectHistoryId, + userId: this.userId, + updates: this.updates, + version: this.version + }, + params: { + project_id: this.project_id + } + } + }) + + describe('successfully', function () { + beforeEach(function () { + this.ProjectManager.updateProjectWithLocks = sinon.stub().yields() + this.HttpController.updateProject(this.req, this.res, this.next) + }) + + it('should accept the change', function () { + this.ProjectManager.updateProjectWithLocks + .calledWith( + this.project_id, + this.projectHistoryId, + this.userId, + this.updates, + this.version + ) + .should.equal(true) + }) + + it('should return a successful No Content response', function () { + this.res.sendStatus.calledWith(204).should.equal(true) + }) + + it('should time the request', function () { + this.Metrics.Timer.prototype.done.called.should.equal(true) + }) + }) + + describe('when an errors occurs', function () { + beforeEach(function () { + this.ProjectManager.updateProjectWithLocks = sinon + .stub() + .yields(new Error('oops')) this.HttpController.updateProject(this.req, this.res, this.next) }) diff --git a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js index d17f80d44b..aa3db813a0 100644 --- a/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js +++ b/services/document-updater/test/unit/js/ProjectManager/updateProjectTests.js @@ -49,22 +49,28 @@ describe('ProjectManager', function () { describe('rename operations', function () { beforeEach(function () { this.firstDocUpdate = { + type: 'rename-doc', id: 1, pathname: 'foo', newPathname: 'foo' } this.secondDocUpdate = { + type: 'rename-doc', id: 2, pathname: 'bar', newPathname: 'bar2' } - this.docUpdates = [this.firstDocUpdate, this.secondDocUpdate] this.firstFileUpdate = { + type: 'rename-file', id: 2, pathname: 'bar', newPathname: 'bar2' } - this.fileUpdates = [this.firstFileUpdate] + this.updates = [ + this.firstDocUpdate, + this.secondDocUpdate, + this.firstFileUpdate + ] }) describe('successfully', function () { @@ -73,8 +79,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -146,8 +151,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -166,8 +170,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -185,8 +188,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -203,23 +205,31 @@ describe('ProjectManager', function () { describe('add operations', function () { beforeEach(function () { this.firstDocUpdate = { + type: 'add-doc', id: 1, docLines: 'a\nb' } this.secondDocUpdate = { + type: 'add-doc', id: 2, docLines: 'a\nb' } - this.docUpdates = [this.firstDocUpdate, this.secondDocUpdate] this.firstFileUpdate = { + type: 'add-file', id: 3, url: 'filestore.example.com/2' } this.secondFileUpdate = { + type: 'add-file', id: 4, url: 'filestore.example.com/3' } - this.fileUpdates = [this.firstFileUpdate, this.secondFileUpdate] + this.updates = [ + this.firstDocUpdate, + this.secondDocUpdate, + this.firstFileUpdate, + this.secondFileUpdate + ] }) describe('successfully', function () { @@ -228,8 +238,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -322,8 +331,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -342,8 +350,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -361,8 +368,7 @@ describe('ProjectManager', function () { this.project_id, this.projectHistoryId, this.user_id, - this.docUpdates, - this.fileUpdates, + this.updates, this.version, this.callback ) @@ -375,5 +381,23 @@ describe('ProjectManager', function () { }) }) }) + + describe('when given an unknown operation type', function () { + beforeEach(function () { + this.updates = [{ type: 'brew-coffee' }] + this.ProjectManager.updateProjectWithLocks( + this.project_id, + this.projectHistoryId, + this.user_id, + this.updates, + this.version, + this.callback + ) + }) + + it('should call back with an error', function () { + this.callback.calledWith(sinon.match.instanceOf(Error)).should.be.true + }) + }) }) })