From 98b5bf2694a89b3bfcf9f2ca6649ea4231fe6888 Mon Sep 17 00:00:00 2001 From: Jimmy Domagala-Tang Date: Mon, 3 Feb 2025 11:32:36 -0500 Subject: [PATCH] Merge pull request #23209 from overleaf/jdt-async-await-prj-entity-handler Async/await the ProjectEntityHandler GitOrigin-RevId: 873106c4ea56e13d864407b338a1924370ba6709 --- .../Features/Project/ProjectEntityHandler.js | 443 ++++++++---------- .../src/Project/ProjectEntityHandlerTests.js | 322 ++++++------- 2 files changed, 343 insertions(+), 422 deletions(-) diff --git a/services/web/app/src/Features/Project/ProjectEntityHandler.js b/services/web/app/src/Features/Project/ProjectEntityHandler.js index 8cc9b33c7d..b834f58d2a 100644 --- a/services/web/app/src/Features/Project/ProjectEntityHandler.js +++ b/services/web/app/src/Features/Project/ProjectEntityHandler.js @@ -2,260 +2,211 @@ const path = require('path') const DocstoreManager = require('../Docstore/DocstoreManager') const Errors = require('../Errors/Errors') const ProjectGetter = require('./ProjectGetter') -const { promisifyAll } = require('@overleaf/promise-utils') +const { callbackifyAll } = require('@overleaf/promise-utils') const OError = require('@overleaf/o-error') const { iterablePaths } = require('./IterablePath') -const ProjectEntityHandler = { - getAllDocs(projectId, callback) { - // We get the path and name info from the project, and the lines and - // version info from the doc store. - DocstoreManager.getAllDocs(projectId, (error, docContentsArray) => { - if (error != null) { - return callback(error) - } +async function getAllDocs(projectId) { + // We get the path and name info from the project, and the lines and + // version info from the doc store. + const docContentsArray = await DocstoreManager.promises.getAllDocs(projectId) - // Turn array from docstore into a dictionary based on doc id - const docContents = {} - for (const docContent of docContentsArray) { - docContents[docContent._id] = docContent - } + // Turn array from docstore into a dictionary based on doc id + const docContents = {} + for (const docContent of docContentsArray) { + docContents[docContent._id] = docContent + } - ProjectEntityHandler._getAllFolders(projectId, (error, folders) => { - if (error != null) { - return callback(error) - } - const docs = {} - for (const { path: folderPath, folder } of folders) { - for (const doc of iterablePaths(folder, 'docs')) { - const content = docContents[doc._id.toString()] - if (content != null) { - try { - docs[path.join(folderPath, doc.name)] = { - _id: doc._id, - name: doc.name, - lines: content.lines, - rev: content.rev, - folder, - } - } catch (err) { - return callback(err) - } - } - } - } - - callback(null, docs) - }) - }) - }, - - getAllFiles(projectId, callback) { - ProjectEntityHandler._getAllFolders(projectId, (err, folders) => { - if (err != null) { - return callback(err) - } - const files = {} - for (const { path: folderPath, folder } of folders) { - for (const file of iterablePaths(folder, 'fileRefs')) { - if (file != null) { - try { - files[path.join(folderPath, file.name)] = { ...file, folder } - } catch (err) { - return callback(err) - } - } - } - } - callback(null, files) - }) - }, - - getAllEntities(projectId, callback) { - ProjectGetter.getProject(projectId, (err, project) => { - if (err != null) { - return callback(err) - } - if (project == null) { - return callback(new Errors.NotFoundError('project not found')) - } - try { - const entities = ProjectEntityHandler.getAllEntitiesFromProject(project) - callback(null, entities) - } catch (err) { - callback(err) - } - }) - }, - - getAllEntitiesFromProject(project) { - const folders = ProjectEntityHandler._getAllFoldersFromProject(project) - const docs = [] - const files = [] - for (const { path: folderPath, folder } of folders) { - for (const doc of iterablePaths(folder, 'docs')) { - if (doc != null) { - docs.push({ path: path.join(folderPath, doc.name), doc }) - } - } - for (const file of iterablePaths(folder, 'fileRefs')) { - if (file != null) { - files.push({ path: path.join(folderPath, file.name), file }) + const folders = await _getAllFolders(projectId) + const docs = {} + for (const { path: folderPath, folder } of folders) { + for (const doc of iterablePaths(folder, 'docs')) { + const content = docContents[doc._id.toString()] + if (content != null) { + docs[path.join(folderPath, doc.name)] = { + _id: doc._id, + name: doc.name, + lines: content.lines, + rev: content.rev, + folder, } } } - return { docs, files, folders } - }, + } - getAllDocPathsFromProjectById(projectId, callback) { - ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => { - if (err != null) { - return callback(err) - } - if (project == null) { - return callback(Errors.NotFoundError('no project')) - } - try { - const docPaths = ProjectEntityHandler.getAllDocPathsFromProject(project) - callback(null, docPaths) - } catch (err) { - callback(err) - } - }) - }, - - getAllDocPathsFromProject(project) { - const folders = ProjectEntityHandler._getAllFoldersFromProject(project) - const docPath = {} - for (const { path: folderPath, folder } of folders) { - for (const doc of iterablePaths(folder, 'docs')) { - docPath[doc._id] = path.join(folderPath, doc.name) - } - } - return docPath - }, - - getDoc(projectId, docId, options, callback) { - if (options == null) { - options = {} - } - if (typeof options === 'function') { - callback = options - options = {} - } - - DocstoreManager.getDoc(projectId, docId, options, callback) - }, - - /** - * @param {ObjectId | string} projectId - * @param {ObjectId | string} docId - * @param {Function} callback - */ - getDocPathByProjectIdAndDocId(projectId, docId, callback) { - ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => { - if (err != null) { - return callback(err) - } - if (project == null) { - return callback(new Errors.NotFoundError('no project')) - } - ProjectEntityHandler.getDocPathFromProjectByDocId( - project, - docId, - (err, docPath) => { - if (err) return callback(Errors.OError.tag(err)) - if (docPath == null) { - return callback(new Errors.NotFoundError('no doc')) - } - callback(null, docPath) - } - ) - }) - }, - - /** - * @param {Project} project - * @param {ObjectId | string} docId - * @param {Function} callback - */ - getDocPathFromProjectByDocId(project, docId, callback) { - function recursivelyFindDocInFolder(basePath, docId, folder) { - const docInCurrentFolder = (folder.docs || []).find( - currentDoc => currentDoc._id.toString() === docId.toString() - ) - if (docInCurrentFolder != null) { - return path.join(basePath, docInCurrentFolder.name) - } else { - let docPath, childFolder - for (childFolder of iterablePaths(folder, 'folders')) { - docPath = recursivelyFindDocInFolder( - path.join(basePath, childFolder.name), - docId, - childFolder - ) - if (docPath != null) { - return docPath - } - } - return null - } - } - try { - const docPath = recursivelyFindDocInFolder( - '/', - docId, - project.rootFolder[0] - ) - callback(null, docPath) - } catch (err) { - callback(err) - } - }, - - _getAllFolders(projectId, callback) { - ProjectGetter.getProjectWithoutDocLines(projectId, (err, project) => { - if (err != null) { - return callback(err) - } - if (project == null) { - return callback(new Errors.NotFoundError('no project')) - } - try { - const folders = ProjectEntityHandler._getAllFoldersFromProject(project) - callback(null, folders) - } catch (err) { - callback(err) - } - }) - }, - - _getAllFoldersFromProject(project) { - const folders = [] - try { - const processFolder = (basePath, folder) => { - folders.push({ path: basePath, folder }) - if (folder.folders) { - for (const childFolder of iterablePaths(folder, 'folders')) { - if (childFolder.name != null) { - const childPath = path.join(basePath, childFolder.name) - processFolder(childPath, childFolder) - } - } - } - } - processFolder('/', project.rootFolder[0]) - return folders - } catch (err) { - throw OError.tag(err, 'Error getting folders', { projectId: project._id }) - } - }, + return docs } -module.exports = ProjectEntityHandler -module.exports.promises = promisifyAll(ProjectEntityHandler, { - without: ['getAllEntitiesFromProject'], - multiResult: { - getDoc: ['lines', 'rev', 'version', 'ranges'], - }, -}) +async function getAllFiles(projectId) { + const folders = await _getAllFolders(projectId) + const files = {} + for (const { path: folderPath, folder } of folders) { + for (const file of iterablePaths(folder, 'fileRefs')) { + if (file != null) { + files[path.join(folderPath, file.name)] = { ...file, folder } + } + } + } + return files +} + +async function getAllEntities(projectId) { + const project = await ProjectGetter.promises.getProject(projectId) + if (project == null) { + throw new Errors.NotFoundError('project not found') + } + const entities = getAllEntitiesFromProject(project) + return entities +} + +function getAllEntitiesFromProject(project) { + const folders = _getAllFoldersFromProject(project) + const docs = [] + const files = [] + for (const { path: folderPath, folder } of folders) { + for (const doc of iterablePaths(folder, 'docs')) { + if (doc != null) { + docs.push({ path: path.join(folderPath, doc.name), doc }) + } + } + for (const file of iterablePaths(folder, 'fileRefs')) { + if (file != null) { + files.push({ path: path.join(folderPath, file.name), file }) + } + } + } + return { docs, files, folders } +} + +async function getAllDocPathsFromProjectById(projectId) { + const project = + await ProjectGetter.promises.getProjectWithoutDocLines(projectId) + if (project == null) { + throw new Errors.NotFoundError('no project') + } + const docPaths = getAllDocPathsFromProject(project) + return docPaths +} + +function getAllDocPathsFromProject(project) { + const folders = _getAllFoldersFromProject(project) + const docPath = {} + for (const { path: folderPath, folder } of folders) { + for (const doc of iterablePaths(folder, 'docs')) { + docPath[doc._id] = path.join(folderPath, doc.name) + } + } + return docPath +} + +async function getDoc(projectId, docId) { + const { lines, rev, version, ranges } = await DocstoreManager.promises.getDoc( + projectId, + docId + ) + return { lines, rev, version, ranges } +} + +/** + * @param {ObjectId | string} projectId + * @param {ObjectId | string} docId + */ +async function getDocPathByProjectIdAndDocId(projectId, docId) { + const project = + await ProjectGetter.promises.getProjectWithoutDocLines(projectId) + if (project == null) { + throw new Errors.NotFoundError('no project') + } + const docPath = await getDocPathFromProjectByDocId(project, docId) + if (docPath == null) { + throw new Errors.NotFoundError('no doc') + } + return docPath +} + +function _recursivelyFindDocInFolder(basePath, docId, folder) { + const docInCurrentFolder = (folder.docs || []).find( + currentDoc => currentDoc._id.toString() === docId.toString() + ) + if (docInCurrentFolder != null) { + return path.join(basePath, docInCurrentFolder.name) + } else { + let docPath, childFolder + for (childFolder of iterablePaths(folder, 'folders')) { + docPath = _recursivelyFindDocInFolder( + path.join(basePath, childFolder.name), + docId, + childFolder + ) + if (docPath != null) { + return docPath + } + } + return null + } +} + +/** + * @param {Project} project + * @param {ObjectId | string} docId + * @param {Function} callback + */ +async function getDocPathFromProjectByDocId(project, docId) { + const docPath = _recursivelyFindDocInFolder('/', docId, project.rootFolder[0]) + return docPath +} + +async function _getAllFolders(projectId) { + const project = + await ProjectGetter.promises.getProjectWithoutDocLines(projectId) + + if (project == null) { + throw new Errors.NotFoundError('no project') + } + const folders = _getAllFoldersFromProject(project) + return folders +} + +function _getAllFoldersFromProject(project) { + const folders = [] + try { + const processFolder = (basePath, folder) => { + folders.push({ path: basePath, folder }) + if (folder.folders) { + for (const childFolder of iterablePaths(folder, 'folders')) { + if (childFolder.name != null) { + const childPath = path.join(basePath, childFolder.name) + processFolder(childPath, childFolder) + } + } + } + } + processFolder('/', project.rootFolder[0]) + return folders + } catch (err) { + throw OError.tag(err, 'Error getting folders', { projectId: project._id }) + } +} + +const ProjectEntityHandler = { + getAllDocs, + getAllFiles, + getAllEntities, + getAllDocPathsFromProjectById, + getDoc, + getDocPathByProjectIdAndDocId, + getDocPathFromProjectByDocId, + _getAllFolders, +} + +module.exports = { + ...callbackifyAll(ProjectEntityHandler, { + multiResult: { + getDoc: ['lines', 'rev', 'version', 'ranges'], + }, + }), + promises: ProjectEntityHandler, + getAllEntitiesFromProject, + getAllDocPathsFromProject, + _getAllFoldersFromProject, +} diff --git a/services/web/test/unit/src/Project/ProjectEntityHandlerTests.js b/services/web/test/unit/src/Project/ProjectEntityHandlerTests.js index 8f14a5ba42..f3cc6e0c06 100644 --- a/services/web/test/unit/src/Project/ProjectEntityHandlerTests.js +++ b/services/web/test/unit/src/Project/ProjectEntityHandlerTests.js @@ -31,14 +31,16 @@ describe('ProjectEntityHandler', function () { this.ProjectEntityHandler = SandboxedModule.require(modulePath, { requires: { - '../Docstore/DocstoreManager': (this.DocstoreManager = {}), + '../Docstore/DocstoreManager': (this.DocstoreManager = { + promises: {}, + }), '../../Features/DocumentUpdater/DocumentUpdaterHandler': this.DocumentUpdaterHandler, '../../models/Project': { Project: this.ProjectModel, }, './ProjectLocator': this.ProjectLocator, - './ProjectGetter': (this.ProjectGetter = {}), + './ProjectGetter': (this.ProjectGetter = { promises: {} }), '../ThirdPartyDataStore/TpdsUpdateSender': this.TpdsUpdateSender, }, }) @@ -82,13 +84,14 @@ describe('ProjectEntityHandler', function () { ], }, ] - this.ProjectGetter.getProjectWithoutDocLines = sinon + this.ProjectGetter.promises.getProjectWithoutDocLines = sinon .stub() - .yields(null, this.project) + .resolves(this.project) }) describe('getAllDocs', function () { - beforeEach(function () { + let fetchedDocs + beforeEach(async function () { this.docs = [ { _id: this.doc1._id, @@ -101,18 +104,21 @@ describe('ProjectEntityHandler', function () { rev: (this.rev2 = 2), }, ] - this.DocstoreManager.getAllDocs = sinon + this.DocstoreManager.promises.getAllDocs = sinon .stub() - .callsArgWith(1, null, this.docs) - this.ProjectEntityHandler.getAllDocs(projectId, this.callback) + .resolves(this.docs) + fetchedDocs = + await this.ProjectEntityHandler.promises.getAllDocs(projectId) }) it('should get the doc lines and rev from the docstore', function () { - this.DocstoreManager.getAllDocs.calledWith(projectId).should.equal(true) + this.DocstoreManager.promises.getAllDocs + .calledWith(projectId) + .should.equal(true) }) it('should call the callback with the docs with the lines and rev included', function () { - this.callback.should.have.been.calledWith(null, { + expect(fetchedDocs).to.deep.equal({ '/doc1': { _id: this.doc1._id, lines: this.lines1, @@ -132,13 +138,17 @@ describe('ProjectEntityHandler', function () { }) describe('getAllFiles', function () { - beforeEach(function () { + let allFiles + beforeEach(async function () { this.callback = sinon.stub() - this.ProjectEntityHandler.getAllFiles(projectId, this.callback) + allFiles = await this.ProjectEntityHandler.promises.getAllFiles( + projectId, + this.callback + ) }) it('should call the callback with the files', function () { - this.callback.should.have.been.calledWith(null, { + expect(allFiles).to.deep.equal({ '/file1': { ...this.file1, folder: this.project.rootFolder[0] }, '/folder1/file2': { ...this.file2, folder: this.folder1 }, }) @@ -176,83 +186,66 @@ describe('ProjectEntityHandler', function () { }) describe('getDocPathByProjectIdAndDocId', function () { - beforeEach(function () { - this.callback = sinon.stub() - }) - it('should call the callback with the path for an existing doc id at the root level', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.doc1._id, - this.callback - ) - this.callback.calledWith(null, `/${this.doc1.name}`).should.equal(true) + it('should call the callback with the path for an existing doc id at the root level', async function () { + const path = + await this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.doc1._id + ) + expect(path).to.deep.equal(`/${this.doc1.name}`) }) - it('should call the callback with the path for an existing doc id nested within a folder', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.doc2._id, - this.callback - ) - this.callback - .calledWith(null, `/folder1/${this.doc2.name}`) - .should.equal(true) + it('should call the callback with the path for an existing doc id nested within a folder', async function () { + const path = + await this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.doc2._id + ) + expect(path).to.deep.equal(`/folder1/${this.doc2.name}`) }) - it('should call the callback with a NotFoundError for a non-existing doc', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - 'non-existing-id', - this.callback - ) - expect(this.callback.firstCall.args[0]).to.be.an.instanceof( - Errors.NotFoundError - ) + it('should call the callback with a NotFoundError for a non-existing doc', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + 'non-existing-id' + ) + ).to.be.rejectedWith(Errors.NotFoundError) }) - it('should call the callback with a NotFoundError for an existing file', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.file1._id, - this.callback - ) - expect(this.callback.firstCall.args[0]).to.be.an.instanceof( - Errors.NotFoundError - ) + it('should call the callback with a NotFoundError for an existing file', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.file1._id + ) + ).to.be.rejectedWith(Errors.NotFoundError) }) }) - describe('_getAllFolders', function () { - beforeEach(function () { + describe('_getAllFolders', async function () { + let folders + beforeEach(async function () { this.callback = sinon.stub() - this.ProjectEntityHandler._getAllFolders(projectId, this.callback) + folders = + await this.ProjectEntityHandler.promises._getAllFolders(projectId) }) it('should get the project without the docs lines', function () { - this.ProjectGetter.getProjectWithoutDocLines + this.ProjectGetter.promises.getProjectWithoutDocLines .calledWith(projectId) .should.equal(true) }) it('should call the callback with the folders', function () { - this.callback - .calledWith(null, [ - { path: '/', folder: this.project.rootFolder[0] }, - { path: '/folder1', folder: this.folder1 }, - ]) - .should.equal(true) + expect(folders).to.deep.equal([ + { path: '/', folder: this.project.rootFolder[0] }, + { path: '/folder1', folder: this.folder1 }, + ]) }) }) describe('_getAllFoldersFromProject', function () { - beforeEach(function () { - this.callback = sinon.stub() - this.ProjectEntityHandler._getAllFoldersFromProject( - this.project, - this.callback - ) - }) - it('should return the folders', function () { expect( this.ProjectEntityHandler._getAllFoldersFromProject(this.project) @@ -303,13 +296,13 @@ describe('ProjectEntityHandler', function () { ], }, ] - this.ProjectGetter.getProjectWithoutDocLines = sinon + this.ProjectGetter.promises.getProjectWithoutDocLines = sinon .stub() - .yields(null, this.project) + .resolves(this.project) }) describe('getAllDocs', function () { - beforeEach(function () { + beforeEach(async function () { this.docs = [ { _id: this.doc1._id, @@ -322,128 +315,102 @@ describe('ProjectEntityHandler', function () { rev: (this.rev2 = 2), }, ] - this.DocstoreManager.getAllDocs = sinon + this.DocstoreManager.promises.getAllDocs = sinon .stub() - .callsArgWith(1, null, this.docs) - this.ProjectEntityHandler.getAllDocs(projectId, this.callback) + .resolves(this.docs) }) - it('should get the doc lines and rev from the docstore', function () { - this.DocstoreManager.getAllDocs.calledWith(projectId).should.equal(true) - }) - - it('should call the callback with an error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with an error', async function () { + await expect(this.ProjectEntityHandler.promises.getAllDocs(projectId)) + .to.be.rejected }) }) describe('getAllFiles', function () { - beforeEach(function () { - this.callback = sinon.stub() - this.ProjectEntityHandler.getAllFiles(projectId, this.callback) - }) - - it('should call the callback with and error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with and error', async function () { + await expect(this.ProjectEntityHandler.promises.getAllFiles(projectId)) + .to.be.rejected }) }) describe('getDocPathByProjectIdAndDocId', function () { - beforeEach(function () { - this.callback = sinon.stub() - }) - it('should call the callback with an error for an existing doc id at the root level', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.doc1._id, - this.callback - ) - this.callback.should.have.been.calledWith(sinon.match.instanceOf(Error)) + it('should call the callback with an error for an existing doc id at the root level', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.doc1._id + ) + ).to.be.rejectedWith(Error) }) - it('should call the callback with an error for an existing doc id nested within a folder', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.doc2._id, - this.callback - ) - this.callback.should.have.been.calledWith(sinon.match.instanceOf(Error)) + it('should call the callback with an error for an existing doc id nested within a folder', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.doc2._id + ) + ).to.be.rejectedWith(Error) }) - it('should call the callback with an error for a non-existing doc', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - 'non-existing-id', - this.callback - ) - this.callback.should.have.been.calledWith(sinon.match.instanceOf(Error)) + it('should call the callback with an error for a non-existing doc', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + 'non-existing-id' + ) + ).to.be.rejectedWith(Error) }) - it('should call the callback with an error for an existing file', function () { - this.ProjectEntityHandler.getDocPathByProjectIdAndDocId( - projectId, - this.file1._id, - this.callback - ) - this.callback.should.have.been.calledWith(sinon.match.instanceOf(Error)) + it('should call the callback with an error for an existing file', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathByProjectIdAndDocId( + projectId, + this.file1._id + ) + ).to.be.rejectedWith(Error) }) }) describe('_getAllFolders', function () { - beforeEach(function () { - this.callback = sinon.stub() - this.ProjectEntityHandler._getAllFolders(projectId, this.callback) - }) - - it('should get the project without the docs lines', function () { - this.ProjectGetter.getProjectWithoutDocLines - .calledWith(projectId) - .should.equal(true) - }) - - it('should call the callback with an error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with an error', async function () { + await expect( + this.ProjectEntityHandler.promises._getAllFolders(projectId) + ).to.be.rejected }) }) describe('getAllEntities', function () { beforeEach(function () { - this.ProjectGetter.getProject = sinon.stub().yields(null, this.project) - this.callback = sinon.stub() - this.ProjectEntityHandler.getAllEntities(projectId, this.callback) + this.ProjectGetter.promises.getProject = sinon + .stub() + .resolves(this.project) }) - it('should call the callback with an error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with an error', async function () { + await expect( + this.ProjectEntityHandler.promises.getAllEntities(projectId) + ).to.be.rejected }) }) describe('getAllDocPathsFromProjectById', function () { - beforeEach(function () { - this.callback = sinon.stub() - this.ProjectEntityHandler.getAllDocPathsFromProjectById( - projectId, - this.callback - ) - }) - - it('should call the callback with an error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with an error', async function () { + await expect( + this.ProjectEntityHandler.promises.getAllDocPathsFromProjectById( + projectId + ) + ).to.be.rejected }) }) describe('getDocPathFromProjectByDocId', function () { - beforeEach(function () { - this.callback = sinon.stub() - this.ProjectEntityHandler.getDocPathFromProjectByDocId( - projectId, - this.doc1._id, - this.callback - ) - }) - - it('should call the callback with an error', function () { - this.callback.should.have.been.calledWith(sinon.match.defined) + it('should call the callback with an error', async function () { + await expect( + this.ProjectEntityHandler.promises.getDocPathFromProjectByDocId( + projectId, + this.doc1._id + ) + ).to.be.rejected }) }) }) @@ -454,23 +421,23 @@ describe('ProjectEntityHandler', function () { this.rev = 5 this.version = 42 this.ranges = { mock: 'ranges' } - - this.DocstoreManager.getDoc = sinon - .stub() - .callsArgWith(3, null, this.lines, this.rev, this.version, this.ranges) - this.ProjectEntityHandler.getDoc(projectId, docId, this.callback) + this.callback = sinon.stub() + this.DocstoreManager.promises.getDoc = sinon.stub().resolves({ + lines: this.lines, + rev: this.rev, + version: this.version, + ranges: this.ranges, + }) }) - it('should call the docstore', function () { - this.DocstoreManager.getDoc - .calledWith(projectId, docId) - .should.equal(true) - }) - - it('should call the callback with the lines, version and rev', function () { - this.callback - .calledWith(null, this.lines, this.rev, this.version, this.ranges) - .should.equal(true) + it('should call the callback with the lines, version and rev', function (done) { + this.ProjectEntityHandler.getDoc(projectId, docId, doc => { + this.DocstoreManager.promises.getDoc + .calledWith(projectId, docId) + .should.equal(true) + expect(doc).to.exist + done() + }) }) }) @@ -483,14 +450,17 @@ describe('ProjectEntityHandler', function () { this.version = 42 this.ranges = { mock: 'ranges' } - this.DocstoreManager.getDoc = sinon - .stub() - .callsArgWith(3, null, this.lines, this.rev, this.version, this.ranges) + this.DocstoreManager.promises.getDoc = sinon.stub().resolves({ + lines: this.lines, + rev: this.rev, + version: this.version, + ranges: this.ranges, + }) result = await this.ProjectEntityHandler.promises.getDoc(projectId, docId) }) it('should call the docstore', function () { - this.DocstoreManager.getDoc + this.DocstoreManager.promises.getDoc .calledWith(projectId, docId) .should.equal(true) })