From 9723800b6865866eb4acc40982fc077c3cc11597 Mon Sep 17 00:00:00 2001 From: Miguel Serrano Date: Wed, 8 Oct 2025 10:06:11 +0200 Subject: [PATCH] Merge pull request #28868 from overleaf/msm-async-docstore-acceptance [docstore] async/await migration in acceptance tests + `request` removal GitOrigin-RevId: af1fe2b3de3d0b449ba3dad3555b309af3d35b62 --- package-lock.json | 3 +- services/docstore/package.json | 3 +- .../test/acceptance/js/ArchiveDocsTests.js | 746 +++++------------- .../test/acceptance/js/DeletingDocsTests.js | 479 +++++------ .../test/acceptance/js/GettingAllDocsTests.js | 119 +-- .../js/GettingDocsFromArchiveTest.js | 102 +-- .../test/acceptance/js/GettingDocsTests.js | 123 +-- .../test/acceptance/js/HealthCheckerTest.js | 13 +- .../test/acceptance/js/UpdatingDocsTests.js | 523 +++++------- .../test/acceptance/js/helpers/DocstoreApp.js | 49 +- .../acceptance/js/helpers/DocstoreClient.js | 220 +++--- 11 files changed, 811 insertions(+), 1569 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a0c1cf7fb..afe16bfdfc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51041,8 +51041,7 @@ "express": "^4.21.2", "lodash": "^4.17.21", "mongodb-legacy": "6.1.3", - "p-map": "^4.0.0", - "request": "^2.88.2" + "p-map": "^4.0.0" }, "devDependencies": { "@google-cloud/storage": "^6.10.1", diff --git a/services/docstore/package.json b/services/docstore/package.json index 4abdc25793..8cc69a868c 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -33,8 +33,7 @@ "express": "^4.21.2", "lodash": "^4.17.21", "mongodb-legacy": "6.1.3", - "p-map": "^4.0.0", - "request": "^2.88.2" + "p-map": "^4.0.0" }, "devDependencies": { "@google-cloud/storage": "^6.10.1", diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 7e254c7e84..54c915757c 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -1,16 +1,3 @@ -/* eslint-disable - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ - const Settings = require('@overleaf/settings') const { expect } = require('chai') const { db, ObjectId } = require('../../../app/js/mongodb') @@ -20,17 +7,16 @@ const DocstoreClient = require('./helpers/DocstoreClient') const { Storage } = require('@google-cloud/storage') const Persistor = require('../../../app/js/PersistorManager') const { ReadableString } = require('@overleaf/stream-utils') +const { callbackify } = require('node:util') -function uploadContent(path, json, callback) { +async function uploadContent(path, json) { const stream = new ReadableString(JSON.stringify(json)) - Persistor.sendStream(Settings.docstore.bucket, path, stream) - .then(() => callback()) - .catch(callback) + await Persistor.sendStream(Settings.docstore.bucket, path, stream) } describe('Archiving', function () { - before(function (done) { - return DocstoreApp.ensureRunning(done) + before(async function () { + await DocstoreApp.ensureRunning() }) before(async function () { @@ -65,118 +51,100 @@ describe('Archiving', function () { version: 4, }, ] - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { - return DocstoreClient.createDoc( - this.project_id, - doc._id, - doc.lines, - doc.version, - doc.ranges, - callback - ) - } + const jobs = this.docs.map(doc => + (doc => callback => { + callbackify(DocstoreClient.createDoc)( + this.project_id, + doc._id, + doc.lines, + doc.version, + doc.ranges, + callback + ) })(doc) ) - return async.series(jobs, error => { + async.series(jobs, error => { if (error != null) { throw error } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - if (error) return done(error) - this.res = res - return done() - }) + DocstoreClient.archiveAllDoc(this.project_id) + .then(res => { + this.res = res + done() + }) + .catch(done) }) }) - it('should archive all the docs', function (done) { - this.res.statusCode.should.equal(204) - return done() + it('should archive all the docs', function () { + this.res.status.should.equal(204) }) it('should set inS3 and unset lines and ranges in each doc', function (done) { - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { - return db.docs.findOne({ _id: doc._id }, (error, doc) => { + const jobs = this.docs.map(doc => + ( + doc => callback => + db.docs.findOne({ _id: doc._id }, (error, doc) => { if (error) return callback(error) expect(doc.lines).not.to.exist expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) - return callback() + callback() }) - } - })(doc) + )(doc) ) - return async.series(jobs, done) + async.series(jobs, done) }) it('should set the docs in s3 correctly', function (done) { - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { - return DocstoreClient.getS3Doc( - this.project_id, - doc._id, - (error, s3Doc) => { - if (error) return callback(error) + const jobs = this.docs.map(doc => + ( + doc => callback => + DocstoreClient.getS3Doc(this.project_id, doc._id) + .then(s3Doc => { s3Doc.lines.should.deep.equal(doc.lines) s3Doc.ranges.should.deep.equal(doc.ranges) callback() - } - ) - } - })(doc) + }) + .catch(callback) + )(doc) ) - return async.series(jobs, done) + async.series(jobs, done) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + describe('after unarchiving from a request for the project', function () { + before(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - it('should return the docs', function (done) { + it('should return the docs', function () { for (let i = 0; i < this.fetched_docs.length; i++) { const doc = this.fetched_docs[i] doc.lines.should.deep.equal(this.docs[i].lines) } - return done() }) - return it('should restore the docs to mongo', function (done) { - const jobs = Array.from(this.docs).map((doc, i) => - ((doc, i) => { - return callback => { - return db.docs.findOne({ _id: doc._id }, (error, doc) => { + it('should restore the docs to mongo', function (done) { + const jobs = this.docs.map((doc, i) => + ( + (doc, i) => callback => + db.docs.findOne({ _id: doc._id }, (error, doc) => { if (error) return callback(error) doc.lines.should.deep.equal(this.docs[i].lines) doc.ranges.should.deep.equal(this.docs[i].ranges) expect(doc.inS3).not.to.exist - return callback() + callback() }) - } - })(doc, i) + )(doc, i) ) - return async.series(jobs, done) + async.series(jobs, done) }) }) }) describe('a deleted doc', function () { - beforeEach(function (done) { + beforeEach(async function () { this.project_id = new ObjectId() this.doc = { _id: new ObjectId(), @@ -184,102 +152,51 @@ describe('Archiving', function () { ranges: {}, version: 2, } - return DocstoreClient.createDoc( + + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.deleteDoc( - this.project_id, - this.doc._id, - error => { - if (error != null) { - throw error - } - return DocstoreClient.archiveAllDoc( - this.project_id, - (error, res) => { - this.res = res - if (error != null) { - throw error - } - return done() - } - ) - } - ) - } + this.doc.ranges ) + await DocstoreClient.deleteDoc(this.project_id, this.doc._id) + this.res = await DocstoreClient.archiveAllDoc(this.project_id) }) - it('should successully archive the docs', function (done) { - this.res.statusCode.should.equal(204) - return done() + it('should successully archive the docs', function () { + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in each doc', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - doc.deleted.should.equal(true) - return done() - }) + it('should set inS3 and unset lines and ranges in each doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) + doc.deleted.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc._id, - (error, s3Doc) => { - if (error != null) { - throw error - } - s3Doc.lines.should.deep.equal(this.doc.lines) - s3Doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } - ) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + s3Doc.ranges.should.deep.equal(this.doc.ranges) }) describe('after unarchiving from a request for the project', function () { - beforeEach(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + beforeEach(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - it('should not included the deleted', function (done) { + it('should not included the deleted', function () { this.fetched_docs.length.should.equal(0) - return done() }) - return it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - doc.ranges.should.deep.equal(this.doc.ranges) - expect(doc.inS3).not.to.exist - doc.deleted.should.equal(true) - return done() - }) + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + expect(doc.inS3).not.to.exist + doc.deleted.should.equal(true) }) }) @@ -296,42 +213,27 @@ describe('Archiving', function () { }) describe('after unarchiving from a request for the project', function () { - beforeEach(function (done) { - DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error) { - return done(error) - } - done() - } - ) + beforeEach(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - it('should not included the deleted', function (done) { + it('should not included the deleted', function () { this.fetched_docs.length.should.equal(0) - done() }) - it('should not have restored the deleted doc to mongo', function (done) { - db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error) { - return done(error) - } - expect(doc.lines).to.not.exist - expect(doc.ranges).to.not.exist - expect(doc.inS3).to.equal(true) - expect(doc.deleted).to.equal(true) - done() - }) + it('should not have restored the deleted doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).to.not.exist + expect(doc.ranges).to.not.exist + expect(doc.inS3).to.equal(true) + expect(doc.deleted).to.equal(true) }) }) }) }) describe('archiving a single doc', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.timeout(1000 * 30) this.doc = { @@ -340,62 +242,36 @@ describe('Archiving', function () { ranges: {}, version: 2, } - DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error) { - return done(error) - } - DocstoreClient.archiveDoc( - this.project_id, - this.doc._id, - (error, res) => { - this.res = res - if (error) { - return done(error) - } - done() - } - ) - } + this.doc.ranges ) + this.res = await DocstoreClient.archiveDoc(this.project_id, this.doc._id) }) - it('should successully archive the doc', function (done) { - this.res.statusCode.should.equal(204) - done() + it('should successully archive the doc', function () { + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in the doc', function (done) { - db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error) { - return done(error) - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - done() - }) + it('should set inS3 and unset lines and ranges in the doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, s3Doc) => { - if (error) { - return done(error) - } - s3Doc.lines.should.deep.equal(this.doc.lines) - s3Doc.ranges.should.deep.equal(this.doc.ranges) - done() - }) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + s3Doc.ranges.should.deep.equal(this.doc.ranges) }) }) describe('a doc with large lines', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.timeout(1000 * 30) const quarterMegInBytes = 250000 @@ -408,89 +284,49 @@ describe('Archiving', function () { ranges: {}, version: 2, } - return DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res - if (error != null) { - throw error - } - return done() - }) - } + this.doc.ranges ) + this.res = await DocstoreClient.archiveAllDoc(this.project_id) }) - it('should successully archive the docs', function (done) { - this.res.statusCode.should.equal(204) - return done() + it('should successully archive the docs', function () { + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in each doc', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - return done() - }) + it('should set inS3 and unset lines and ranges in each doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc._id, - (error, s3Doc) => { - if (error != null) { - throw error - } - s3Doc.lines.should.deep.equal(this.doc.lines) - s3Doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } - ) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + s3Doc.ranges.should.deep.equal(this.doc.ranges) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + describe('after unarchiving from a request for the project', function () { + before(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - return it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - doc.ranges.should.deep.equal(this.doc.ranges) - expect(doc.inS3).not.to.exist - return done() - }) + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + expect(doc.inS3).not.to.exist }) }) }) describe('a doc with naughty strings', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.doc = { _id: new ObjectId(), @@ -882,89 +718,48 @@ describe('Archiving', function () { ranges: {}, version: 2, } - return DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res - if (error != null) { - throw error - } - return done() - }) - } + this.doc.ranges ) + this.res = await DocstoreClient.archiveAllDoc(this.project_id) }) - it('should successully archive the docs', function (done) { - this.res.statusCode.should.equal(204) - return done() + it('should successully archive the docs', function () { + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in each doc', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - return done() - }) + it('should set inS3 and unset lines and ranges in each doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc._id, - (error, s3Doc) => { - if (error != null) { - throw error - } - s3Doc.lines.should.deep.equal(this.doc.lines) - s3Doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } - ) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + s3Doc.ranges.should.deep.equal(this.doc.ranges) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + describe('after unarchiving from a request for the project', function () { + before(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - return it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - doc.ranges.should.deep.equal(this.doc.ranges) - expect(doc.inS3).not.to.exist - return done() - }) + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) }) }) }) describe('a doc with ranges', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.doc = { _id: new ObjectId(), @@ -1010,90 +805,50 @@ describe('Archiving', function () { }, ], } - return DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res - if (error != null) { - throw error - } - return done() - }) - } + this.doc.ranges ) + this.res = await DocstoreClient.archiveAllDoc(this.project_id) }) - it('should successully archive the docs', function (done) { - this.res.statusCode.should.equal(204) - return done() + it('should successully archive the docs', function () { + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in each doc', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - return done() - }) + it('should set inS3 and unset lines and ranges in each doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc._id, - (error, s3Doc) => { - if (error != null) { - throw error - } - s3Doc.lines.should.deep.equal(this.doc.lines) - const ranges = JSON.parse(JSON.stringify(this.fixedRanges)) // ObjectId -> String - s3Doc.ranges.should.deep.equal(ranges) - return done() - } - ) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + const ranges = JSON.parse(JSON.stringify(this.fixedRanges)) // ObjectId -> String + s3Doc.ranges.should.deep.equal(ranges) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + describe('after unarchiving from a request for the project', function () { + before(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - return it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - doc.ranges.should.deep.equal(this.fixedRanges) - expect(doc.inS3).not.to.exist - return done() - }) + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.fixedRanges) + expect(doc.inS3).not.to.exist }) }) }) describe('a doc that is archived twice', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.doc = { _id: new ObjectId(), @@ -1101,95 +856,50 @@ describe('Archiving', function () { ranges: {}, version: 2, } - return DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res - if (error != null) { - throw error - } - this.res.statusCode.should.equal(204) - return DocstoreClient.archiveAllDoc( - this.project_id, - (error, res1) => { - this.res = res1 - if (error != null) { - throw error - } - this.res.statusCode.should.equal(204) - return done() - } - ) - }) - } + this.doc.ranges ) + + this.res = await DocstoreClient.archiveAllDoc(this.project_id) + this.res.status.should.equal(204) + + this.res = await DocstoreClient.archiveAllDoc(this.project_id) + this.res.status.should.equal(204) }) - it('should set inS3 and unset lines and ranges in each doc', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - expect(doc.lines).not.to.exist - expect(doc.ranges).not.to.exist - doc.inS3.should.equal(true) - return done() - }) + it('should set inS3 and unset lines and ranges in each doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist + doc.inS3.should.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc._id, - (error, s3Doc) => { - if (error != null) { - throw error - } - s3Doc.lines.should.deep.equal(this.doc.lines) - s3Doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } - ) + it('should set the doc in s3 correctly', async function () { + const s3Doc = await DocstoreClient.getS3Doc(this.project_id, this.doc._id) + s3Doc.lines.should.deep.equal(this.doc.lines) + s3Doc.ranges.should.deep.equal(this.doc.ranges) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) + describe('after unarchiving from a request for the project', function () { + before(async function () { + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - return it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - doc.ranges.should.deep.equal(this.doc.ranges) - expect(doc.inS3).not.to.exist - return done() - }) + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + expect(doc.inS3).not.to.exist }) }) }) - return describe('a doc with the old schema (just an array of lines)', function () { - before(function (done) { + describe('a doc with the old schema (just an array of lines)', function () { + before(async function () { this.project_id = new ObjectId() this.doc = { _id: new ObjectId(), @@ -1197,52 +907,24 @@ describe('Archiving', function () { ranges: {}, version: 2, } - uploadContent( - `${this.project_id}/${this.doc._id}`, - this.doc.lines, - error => { - expect(error).not.to.exist - db.docs.insertOne( - { - project_id: this.project_id, - _id: this.doc._id, - rev: this.doc.version, - inS3: true, - }, - error => { - if (error != null) { - throw error - } - DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetchedDocs) => { - this.fetched_docs = fetchedDocs - if (error != null) { - throw error - } - return done() - } - ) - } - ) - } - ) - }) - - it('should restore the doc to mongo', function (done) { - return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { - if (error != null) { - throw error - } - doc.lines.should.deep.equal(this.doc.lines) - expect(doc.inS3).not.to.exist - return done() + await uploadContent(`${this.project_id}/${this.doc._id}`, this.doc.lines) + await db.docs.insertOne({ + project_id: this.project_id, + _id: this.doc._id, + rev: this.doc.version, + inS3: true, }) + this.fetched_docs = await DocstoreClient.getAllDocs(this.project_id) }) - return it('should return the doc', function (done) { + it('should restore the doc to mongo', async function () { + const doc = await db.docs.findOne({ _id: this.doc._id }) + doc.lines.should.deep.equal(this.doc.lines) + expect(doc.inS3).not.to.exist + }) + + it('should return the doc', function () { this.fetched_docs[0].lines.should.deep.equal(this.doc.lines) - return done() }) }) }) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 3959246767..1c624f322a 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -4,6 +4,9 @@ const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') const Settings = require('@overleaf/settings') const { Storage } = require('@google-cloud/storage') +const { promisify } = require('node:util') + +const sleep = promisify(setTimeout) const DocstoreClient = require('./helpers/DocstoreClient') @@ -24,85 +27,63 @@ function deleteTestSuite(deleteDoc) { await storage.bucket(`${Settings.docstore.bucket}-deleted`).delete() }) - beforeEach(function (done) { + beforeEach(async function () { this.project_id = new ObjectId() this.doc_id = new ObjectId() this.lines = ['original', 'lines'] this.version = 42 this.ranges = [] - DocstoreApp.ensureRunning(() => { - DocstoreClient.createDoc( - this.project_id, - this.doc_id, - this.lines, - this.version, - this.ranges, - error => { - if (error) { - throw error - } - done() - } - ) - }) - }) - - it('should show as not deleted on /deleted', function (done) { - DocstoreClient.isDocDeleted( + await DocstoreApp.ensureRunning() + await DocstoreClient.createDoc( this.project_id, this.doc_id, - (error, res, body) => { - if (error) return done(error) - expect(res.statusCode).to.equal(200) - expect(body).to.have.property('deleted').to.equal(false) - done() - } + this.lines, + this.version, + this.ranges ) }) + it('should show as not deleted on /deleted', async function () { + const { res, body } = await DocstoreClient.isDocDeleted( + this.project_id, + this.doc_id + ) + expect(res.status).to.equal(200) + expect(body).to.have.property('deleted').to.equal(false) + }) + describe('when the doc exists', function () { - beforeEach(function (done) { - deleteDoc(this.project_id, this.doc_id, (error, res, doc) => { - if (error) return done(error) - this.res = res - done() - }) + beforeEach(async function () { + this.res = await deleteDoc(this.project_id, this.doc_id) }) - afterEach(function (done) { - db.docs.deleteOne({ _id: this.doc_id }, done) + afterEach(async function () { + await db.docs.deleteOne({ _id: this.doc_id }) }) - it('should mark the doc as deleted on /deleted', function (done) { - DocstoreClient.isDocDeleted( + it('should mark the doc as deleted on /deleted', async function () { + const { res, body } = await DocstoreClient.isDocDeleted( this.project_id, - this.doc_id, - (error, res, body) => { - if (error) return done(error) - expect(res.statusCode).to.equal(200) - expect(body).to.have.property('deleted').to.equal(true) - done() - } + this.doc_id ) + expect(res.status).to.equal(200) + expect(body).to.have.property('deleted').to.equal(true) }) - it('should insert a deleted doc into the docs collection', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { - if (error) return done(error) - docs[0]._id.should.deep.equal(this.doc_id) - docs[0].lines.should.deep.equal(this.lines) - docs[0].deleted.should.equal(true) - done() - }) + it('should insert a deleted doc into the docs collection', async function () { + const docs = await db.docs.find({ _id: this.doc_id }).toArray() + docs[0]._id.should.deep.equal(this.doc_id) + docs[0].lines.should.deep.equal(this.lines) + docs[0].deleted.should.equal(true) }) - it('should not export the doc to s3', function (done) { - setTimeout(() => { - DocstoreClient.getS3Doc(this.project_id, this.doc_id, error => { - expect(error).to.be.instanceOf(Errors.NotFoundError) - done() - }) - }, 1000) + it('should not export the doc to s3', async function () { + await sleep(1000) + try { + await DocstoreClient.getS3Doc(this.project_id, this.doc_id) + } catch (error) { + expect(error).to.be.instanceOf(Errors.NotFoundError) + } }) }) @@ -116,12 +97,8 @@ function deleteTestSuite(deleteDoc) { Settings.docstore.archiveOnSoftDelete = archiveOnSoftDelete }) - beforeEach('delete Doc', function (done) { - deleteDoc(this.project_id, this.doc_id, (error, res) => { - if (error) return done(error) - this.res = res - done() - }) + beforeEach('delete Doc', async function () { + this.res = await deleteDoc(this.project_id, this.doc_id) }) beforeEach(function waitForBackgroundFlush(done) { @@ -132,81 +109,54 @@ function deleteTestSuite(deleteDoc) { db.docs.deleteOne({ _id: this.doc_id }, done) }) - it('should set the deleted flag in the doc', function (done) { - db.docs.findOne({ _id: this.doc_id }, (error, doc) => { - if (error) { - return done(error) - } - expect(doc.deleted).to.equal(true) - done() - }) + it('should set the deleted flag in the doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc_id }) + expect(doc.deleted).to.equal(true) }) - it('should set inS3 and unset lines and ranges in the doc', function (done) { - db.docs.findOne({ _id: this.doc_id }, (error, doc) => { - if (error) { - return done(error) - } - expect(doc.lines).to.not.exist - expect(doc.ranges).to.not.exist - expect(doc.inS3).to.equal(true) - done() - }) + it('should set inS3 and unset lines and ranges in the doc', async function () { + const doc = await db.docs.findOne({ _id: this.doc_id }) + expect(doc.lines).to.not.exist + expect(doc.ranges).to.not.exist + expect(doc.inS3).to.equal(true) }) - it('should set the doc in s3 correctly', function (done) { - DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error, s3doc) => { - if (error) { - return done(error) - } - expect(s3doc.lines).to.deep.equal(this.lines) - expect(s3doc.ranges).to.deep.equal(this.ranges) - done() - }) + it('should set the doc in s3 correctly', async function () { + const s3doc = await DocstoreClient.getS3Doc(this.project_id, this.doc_id) + expect(s3doc.lines).to.deep.equal(this.lines) + expect(s3doc.ranges).to.deep.equal(this.ranges) }) }) describe('when the doc exists in another project', function () { const otherProjectId = new ObjectId() - it('should show as not existing on /deleted', function (done) { - DocstoreClient.isDocDeleted(otherProjectId, this.doc_id, (error, res) => { - if (error) return done(error) - expect(res.statusCode).to.equal(404) - done() - }) + it('should show as not existing on /deleted', async function () { + expect(DocstoreClient.isDocDeleted(otherProjectId, this.doc_id)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) - it('should return a 404 when trying to delete', function (done) { - deleteDoc(otherProjectId, this.doc_id, (error, res) => { - if (error) return done(error) - expect(res.statusCode).to.equal(404) - done() - }) + it('should return a 404 when trying to delete', async function () { + expect(deleteDoc(otherProjectId, this.doc_id)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) }) describe('when the doc does not exist', function () { - it('should show as not existing on /deleted', function (done) { + it('should show as not existing on /deleted', async function () { const missingDocId = new ObjectId() - DocstoreClient.isDocDeleted( - this.project_id, - missingDocId, - (error, res) => { - if (error) return done(error) - expect(res.statusCode).to.equal(404) - done() - } - ) + expect(DocstoreClient.isDocDeleted(this.project_id, missingDocId)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) - it('should return a 404', function (done) { + it('should return a 404', async function () { const missingDocId = new ObjectId() - deleteDoc(this.project_id, missingDocId, (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(404) - done() - }) + await expect(deleteDoc(this.project_id, missingDocId)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) }) } @@ -215,21 +165,17 @@ describe('Delete via PATCH', function () { deleteTestSuite(DocstoreClient.deleteDoc) describe('when providing a custom doc name in the delete request', function () { - beforeEach(function (done) { - DocstoreClient.deleteDocWithName( + beforeEach(async function () { + await DocstoreClient.deleteDocWithName( this.project_id, this.doc_id, - 'wombat.tex', - done + 'wombat.tex' ) }) - it('should insert the doc name into the docs collection', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { - if (error) return done(error) - expect(docs[0].name).to.equal('wombat.tex') - done() - }) + it('should insert the doc name into the docs collection', async function () { + const docs = await db.docs.find({ _id: this.doc_id }).toArray() + expect(docs[0].name).to.equal('wombat.tex') }) }) @@ -239,172 +185,130 @@ describe('Delete via PATCH', function () { setTimeout(done, 5) }) - beforeEach('perform deletion with past date', function (done) { - DocstoreClient.deleteDocWithDate( + beforeEach('perform deletion with past date', async function () { + await DocstoreClient.deleteDocWithDate( this.project_id, this.doc_id, - this.deletedAt, - done + this.deletedAt ) }) - it('should insert the date into the docs collection', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { - if (error) return done(error) - expect(docs[0].deletedAt.toISOString()).to.equal( - this.deletedAt.toISOString() - ) - done() - }) + it('should insert the date into the docs collection', async function () { + const docs = await db.docs.find({ _id: this.doc_id }).toArray() + expect(docs[0].deletedAt.toISOString()).to.equal( + this.deletedAt.toISOString() + ) }) }) describe('when providing no doc name in the delete request', function () { - beforeEach(function (done) { - DocstoreClient.deleteDocWithName( - this.project_id, - this.doc_id, - '', - (error, res) => { - this.res = res - done(error) - } - ) - }) - it('should reject the request', function () { - expect(this.res.statusCode).to.equal(400) + expect(DocstoreClient.deleteDocWithName(this.project_id, this.doc_id)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 400 }) }) }) describe('when providing no date in the delete request', function () { - beforeEach(function (done) { - DocstoreClient.deleteDocWithDate( - this.project_id, - this.doc_id, - '', - (error, res) => { - this.res = res - done(error) - } - ) - }) - it('should reject the request', function () { - expect(this.res.statusCode).to.equal(400) + expect(DocstoreClient.deleteDocWithDate(this.project_id, this.doc_id)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 400 }) }) }) describe('before deleting anything', function () { - it('should show nothing in deleted docs response', function (done) { - DocstoreClient.getAllDeletedDocs( - this.project_id, - (error, deletedDocs) => { - if (error) return done(error) - expect(deletedDocs).to.deep.equal([]) - done() - } + it('should show nothing in deleted docs response', async function () { + const deletedDocs = await DocstoreClient.getAllDeletedDocs( + this.project_id ) + expect(deletedDocs).to.deep.equal([]) }) }) describe('when the doc gets a name on delete', function () { - beforeEach(function (done) { + beforeEach(async function () { this.deletedAt = new Date() - DocstoreClient.deleteDocWithDate( + await DocstoreClient.deleteDocWithDate( this.project_id, this.doc_id, - this.deletedAt, - done + this.deletedAt ) }) - it('should show the doc in deleted docs response', function (done) { - DocstoreClient.getAllDeletedDocs( - this.project_id, - (error, deletedDocs) => { - if (error) return done(error) - expect(deletedDocs).to.deep.equal([ - { - _id: this.doc_id.toString(), - name: 'main.tex', - deletedAt: this.deletedAt.toISOString(), - }, - ]) - done() - } + it('should show the doc in deleted docs response', async function () { + const deletedDocs = await DocstoreClient.getAllDeletedDocs( + this.project_id ) + expect(deletedDocs).to.deep.equal([ + { + _id: this.doc_id.toString(), + name: 'main.tex', + deletedAt: this.deletedAt.toISOString(), + }, + ]) }) describe('after deleting multiple docs', function () { - beforeEach('create doc2', function (done) { + beforeEach('create doc2', async function () { this.doc_id2 = new ObjectId() - DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc_id2, this.lines, this.version, - this.ranges, - done + this.ranges ) }) - beforeEach('delete doc2', function (done) { + beforeEach('delete doc2', async function () { this.deletedAt2 = new Date() - DocstoreClient.deleteDocWithDateAndName( + await DocstoreClient.deleteDocWithDateAndName( this.project_id, this.doc_id2, this.deletedAt2, - 'two.tex', - done + 'two.tex' ) }) - beforeEach('create doc3', function (done) { + beforeEach('create doc3', async function () { this.doc_id3 = new ObjectId() - DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc_id3, this.lines, this.version, - this.ranges, - done + this.ranges ) }) - beforeEach('delete doc3', function (done) { + beforeEach('delete doc3', async function () { this.deletedAt3 = new Date() - DocstoreClient.deleteDocWithDateAndName( + await DocstoreClient.deleteDocWithDateAndName( this.project_id, this.doc_id3, this.deletedAt3, - 'three.tex', - done + 'three.tex' ) }) - it('should show all the docs as deleted', function (done) { - DocstoreClient.getAllDeletedDocs( - this.project_id, - (error, deletedDocs) => { - if (error) return done(error) - - expect(deletedDocs).to.deep.equal([ - { - _id: this.doc_id3.toString(), - name: 'three.tex', - deletedAt: this.deletedAt3.toISOString(), - }, - { - _id: this.doc_id2.toString(), - name: 'two.tex', - deletedAt: this.deletedAt2.toISOString(), - }, - { - _id: this.doc_id.toString(), - name: 'main.tex', - deletedAt: this.deletedAt.toISOString(), - }, - ]) - done() - } + it('should show all the docs as deleted', async function () { + const deletedDocs = await DocstoreClient.getAllDeletedDocs( + this.project_id ) + expect(deletedDocs).to.deep.equal([ + { + _id: this.doc_id3.toString(), + name: 'three.tex', + deletedAt: this.deletedAt3.toISOString(), + }, + { + _id: this.doc_id2.toString(), + name: 'two.tex', + deletedAt: this.deletedAt2.toISOString(), + }, + { + _id: this.doc_id.toString(), + name: 'main.tex', + deletedAt: this.deletedAt.toISOString(), + }, + ]) }) describe('with one more than max_deleted_docs permits', function () { @@ -417,28 +321,23 @@ describe('Delete via PATCH', function () { Settings.max_deleted_docs = maxDeletedDocsBefore }) - it('should omit the first deleted doc', function (done) { - DocstoreClient.getAllDeletedDocs( - this.project_id, - (error, deletedDocs) => { - if (error) return done(error) - - expect(deletedDocs).to.deep.equal([ - { - _id: this.doc_id3.toString(), - name: 'three.tex', - deletedAt: this.deletedAt3.toISOString(), - }, - { - _id: this.doc_id2.toString(), - name: 'two.tex', - deletedAt: this.deletedAt2.toISOString(), - }, - // dropped main.tex - ]) - done() - } + it('should omit the first deleted doc', async function () { + const deletedDocs = await DocstoreClient.getAllDeletedDocs( + this.project_id ) + expect(deletedDocs).to.deep.equal([ + { + _id: this.doc_id3.toString(), + name: 'three.tex', + deletedAt: this.deletedAt3.toISOString(), + }, + { + _id: this.doc_id2.toString(), + name: 'two.tex', + deletedAt: this.deletedAt2.toISOString(), + }, + // dropped main.tex + ]) }) }) }) @@ -446,66 +345,54 @@ describe('Delete via PATCH', function () { }) describe("Destroying a project's documents", function () { - beforeEach(function (done) { + beforeEach(async function () { this.project_id = new ObjectId() this.doc_id = new ObjectId() this.lines = ['original', 'lines'] this.version = 42 this.ranges = [] - DocstoreApp.ensureRunning(() => { - DocstoreClient.createDoc( - this.project_id, - this.doc_id, - this.lines, - this.version, - this.ranges, - error => { - if (error) { - throw error - } - done() - } - ) - }) + await DocstoreApp.ensureRunning() + await DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.lines, + this.version, + this.ranges + ) }) describe('when the doc exists', function () { - beforeEach(function (done) { - DocstoreClient.destroyAllDoc(this.project_id, done) + beforeEach(async function () { + await DocstoreClient.destroyAllDoc(this.project_id) }) - it('should remove the doc from the docs collection', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((err, docs) => { - expect(err).not.to.exist - expect(docs).to.deep.equal([]) - done() - }) + it('should remove the doc from the docs collection', async function () { + const docs = await db.docs.find({ _id: this.doc_id }).toArray() + expect(docs).to.deep.equal([]) }) }) describe('when the doc is archived', function () { - beforeEach(function (done) { - DocstoreClient.archiveAllDoc(this.project_id, err => { - if (err) { - return done(err) - } - DocstoreClient.destroyAllDoc(this.project_id, done) - }) + beforeEach(async function () { + try { + await DocstoreClient.archiveAllDoc(this.project_id) + } catch (error) { + // noop + } + await DocstoreClient.destroyAllDoc(this.project_id) }) - it('should remove the doc from the docs collection', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((err, docs) => { - expect(err).not.to.exist - expect(docs).to.deep.equal([]) - done() - }) + it('should remove the doc from the docs collection', async function () { + const docs = await db.docs.find({ _id: this.doc_id }).toArray() + expect(docs).to.deep.equal([]) }) - it('should remove the doc contents from s3', function (done) { - DocstoreClient.getS3Doc(this.project_id, this.doc_id, error => { + it('should remove the doc contents from s3', async function () { + try { + await DocstoreClient.getS3Doc(this.project_id, this.doc_id) + } catch (error) { expect(error).to.be.instanceOf(Errors.NotFoundError) - done() - }) + } }) }) }) diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 57851b2c3b..8efe12a8ea 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -1,19 +1,7 @@ -/* eslint-disable - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const sinon = require('sinon') const { ObjectId } = require('mongodb-legacy') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') +const { callbackify } = require('node:util') const DocstoreClient = require('./helpers/DocstoreClient') @@ -90,10 +78,10 @@ describe('Getting all docs', function () { rev: 8, } const version = 42 - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { - return DocstoreClient.createDoc( + const jobs = this.docs.map(doc => + ( + doc => callback => + callbackify(DocstoreClient.createDoc)( this.project_id, doc._id, doc.lines, @@ -101,11 +89,10 @@ describe('Getting all docs', function () { doc.ranges, callback ) - } - })(doc) + )(doc) ) - jobs.push(cb => { - return DocstoreClient.createDoc( + jobs.push(cb => + callbackify(DocstoreClient.createDoc)( this.project_id, this.deleted_doc._id, this.deleted_doc.lines, @@ -113,72 +100,48 @@ describe('Getting all docs', function () { this.deleted_doc.ranges, err => { if (err) return done(err) - return DocstoreClient.deleteDoc( + callbackify(DocstoreClient.deleteDoc)( this.project_id, this.deleted_doc._id, cb ) } ) - }) - jobs.unshift(cb => DocstoreApp.ensureRunning(cb)) - return async.series(jobs, done) - }) - - it('getAllDocs should return all the (non-deleted) docs', function (done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, docs) => { - if (error != null) { - throw error - } - docs.length.should.equal(this.docs.length) - for (let i = 0; i < docs.length; i++) { - const doc = docs[i] - doc.lines.should.deep.equal(this.docs[i].lines) - } - return done() - }) - }) - - it('getAllRanges should return all the (non-deleted) doc ranges', function (done) { - return DocstoreClient.getAllRanges(this.project_id, (error, res, docs) => { - if (error != null) { - throw error - } - docs.length.should.equal(this.docs.length) - for (let i = 0; i < docs.length; i++) { - const doc = docs[i] - doc.ranges.should.deep.equal(this.fixedRanges[i]) - } - return done() - }) - }) - - it('getTrackedChangesUserIds should return all the user ids from (non-deleted) ranges', function (done) { - DocstoreClient.getTrackedChangesUserIds( - this.project_id, - (error, res, userIds) => { - if (error != null) { - throw error - } - userIds.should.deep.equal(['user-id-1', 'user-id-2']) - done() - } ) + jobs.unshift(cb => callbackify(DocstoreApp.ensureRunning)(cb)) + async.series(jobs, done) }) - it('getCommentThreadIds should return all the thread ids from (non-deleted) ranges', function (done) { - DocstoreClient.getCommentThreadIds( - this.project_id, - (error, res, threadIds) => { - if (error != null) { - throw error - } - threadIds.should.deep.equal({ - [this.docs[0]._id.toString()]: [this.threadId1], - [this.docs[2]._id.toString()]: [this.threadId2], - }) - done() - } + it('getAllDocs should return all the (non-deleted) docs', async function () { + const docs = await DocstoreClient.getAllDocs(this.project_id) + docs.length.should.equal(this.docs.length) + for (let i = 0; i < docs.length; i++) { + const doc = docs[i] + doc.lines.should.deep.equal(this.docs[i].lines) + } + }) + + it('getAllRanges should return all the (non-deleted) doc ranges', async function () { + const docs = await DocstoreClient.getAllRanges(this.project_id) + docs.length.should.equal(this.docs.length) + for (let i = 0; i < docs.length; i++) { + const doc = docs[i] + doc.ranges.should.deep.equal(this.fixedRanges[i]) + } + }) + + it('getTrackedChangesUserIds should return all the user ids from (non-deleted) ranges', async function () { + const userIds = await DocstoreClient.getTrackedChangesUserIds( + this.project_id ) + userIds.should.deep.equal(['user-id-1', 'user-id-2']) + }) + + it('getCommentThreadIds should return all the thread ids from (non-deleted) ranges', async function () { + const threadIds = await DocstoreClient.getCommentThreadIds(this.project_id) + threadIds.should.deep.equal({ + [this.docs[0]._id.toString()]: [this.threadId1], + [this.docs[2]._id.toString()]: [this.threadId2], + }) }) }) diff --git a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js index 8448f26280..a5e78a565e 100644 --- a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js +++ b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js @@ -5,8 +5,8 @@ const DocstoreClient = require('./helpers/DocstoreClient') const { Storage } = require('@google-cloud/storage') describe('Getting A Doc from Archive', function () { - before(function (done) { - return DocstoreApp.ensureRunning(done) + before(async function () { + await DocstoreApp.ensureRunning() }) before(async function () { @@ -25,7 +25,7 @@ describe('Getting A Doc from Archive', function () { }) describe('for an archived doc', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.timeout(1000 * 30) this.doc = { @@ -34,72 +34,46 @@ describe('Getting A Doc from Archive', function () { ranges: {}, version: 2, } - DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - error => { - if (error) { - return done(error) - } - DocstoreClient.archiveDoc( - this.project_id, - this.doc._id, - (error, res) => { - this.res = res - if (error) { - return done(error) - } - done() - } - ) - } + this.doc.ranges ) + this.res = await DocstoreClient.archiveDoc(this.project_id, this.doc._id) }) - it('should successully archive the doc', function (done) { - this.res.statusCode.should.equal(204) - done() + it('should successully archive the doc', function () { + this.res.status.should.equal(204) }) - it('should return the doc lines and version from persistent storage', function (done) { - return DocstoreClient.peekDoc( + it('should return the doc lines and version from persistent storage', async function () { + const { res, doc } = await DocstoreClient.peekDoc( this.project_id, - this.doc._id, - {}, - (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(200) - res.headers['x-doc-status'].should.equal('archived') - doc.lines.should.deep.equal(this.doc.lines) - doc.version.should.equal(this.doc.version) - doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } + this.doc._id ) + res.status.should.equal(200) + res.headers.get('x-doc-status').should.equal('archived') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) }) - it('should return the doc lines and version from persistent storage on subsequent requests', function (done) { - return DocstoreClient.peekDoc( + it('should return the doc lines and version from persistent storage on subsequent requests', async function () { + const { res, doc } = await DocstoreClient.peekDoc( this.project_id, - this.doc._id, - {}, - (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(200) - res.headers['x-doc-status'].should.equal('archived') - doc.lines.should.deep.equal(this.doc.lines) - doc.version.should.equal(this.doc.version) - doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } + this.doc._id ) + res.status.should.equal(200) + res.headers.get('x-doc-status').should.equal('archived') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) }) describe('for an non-archived doc', function () { - before(function (done) { + before(async function () { this.project_id = new ObjectId() this.timeout(1000 * 30) this.doc = { @@ -108,31 +82,25 @@ describe('Getting A Doc from Archive', function () { ranges: {}, version: 2, } - DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.doc._id, this.doc.lines, this.doc.version, - this.doc.ranges, - done + this.doc.ranges ) }) - it('should return the doc lines and version from mongo', function (done) { - return DocstoreClient.peekDoc( + it('should return the doc lines and version from mongo', async function () { + const { res, doc } = await DocstoreClient.peekDoc( this.project_id, - this.doc._id, - {}, - (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(200) - res.headers['x-doc-status'].should.equal('active') - doc.lines.should.deep.equal(this.doc.lines) - doc.version.should.equal(this.doc.version) - doc.ranges.should.deep.equal(this.doc.ranges) - return done() - } + this.doc._id ) + res.status.should.equal(200) + res.headers.get('x-doc-status').should.equal('active') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) }) }) }) diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index 1cfc53c5c6..b7527d8350 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -1,22 +1,11 @@ -/* eslint-disable - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const sinon = require('sinon') const { ObjectId } = require('mongodb-legacy') +const { expect } = require('chai') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') describe('Getting a doc', function () { - beforeEach(function (done) { + beforeEach(async function () { this.project_id = new ObjectId() this.doc_id = new ObjectId() this.lines = ['original', 'lines'] @@ -49,105 +38,63 @@ describe('Getting a doc', function () { { ...this.ranges.comments[0], id: this.ranges.comments[0].op.t }, ], } - return DocstoreApp.ensureRunning(() => { - return DocstoreClient.createDoc( - this.project_id, - this.doc_id, - this.lines, - this.version, - this.ranges, - error => { - if (error != null) { - throw error - } - return done() - } - ) - }) + await DocstoreApp.ensureRunning() + await DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.lines, + this.version, + this.ranges + ) }) describe('when the doc exists', function () { - return it('should get the doc lines and version', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.lines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.fixedRanges) - return done() - } - ) + it('should get the doc lines and version', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.lines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.fixedRanges) }) }) describe('when the doc does not exist', function () { - return it('should return a 404', function (done) { + it('should return a 404', async function () { const missingDocId = new ObjectId() - return DocstoreClient.getDoc( - this.project_id, - missingDocId, - {}, - (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(404) - return done() - } - ) + await expect(DocstoreClient.getDoc(this.project_id, missingDocId)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) }) - return describe('when the doc is a deleted doc', function () { - beforeEach(function (done) { + describe('when the doc is a deleted doc', function () { + beforeEach(async function () { this.deleted_doc_id = new ObjectId() - return DocstoreClient.createDoc( + await DocstoreClient.createDoc( this.project_id, this.deleted_doc_id, this.lines, this.version, - this.ranges, - error => { - if (error != null) { - throw error - } - return DocstoreClient.deleteDoc( - this.project_id, - this.deleted_doc_id, - done - ) - } + this.ranges ) + await DocstoreClient.deleteDoc(this.project_id, this.deleted_doc_id) }) - it('should return the doc', function (done) { - return DocstoreClient.getDoc( + it('should return the doc', async function () { + const doc = await DocstoreClient.getDoc( this.project_id, this.deleted_doc_id, - { include_deleted: true }, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.lines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.fixedRanges) - doc.deleted.should.equal(true) - return done() - } + { include_deleted: true } ) + doc.lines.should.deep.equal(this.lines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.fixedRanges) + doc.deleted.should.equal(true) }) - return it('should return a 404 when the query string is not set', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.deleted_doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - res.statusCode.should.equal(404) - return done() - } - ) + it('should return a 404 when the query string is not set', async function () { + await expect(DocstoreClient.getDoc(this.project_id, this.deleted_doc_id)) + .to.eventually.be.rejected.and.have.property('info') + .to.contain({ status: 404 }) }) }) }) diff --git a/services/docstore/test/acceptance/js/HealthCheckerTest.js b/services/docstore/test/acceptance/js/HealthCheckerTest.js index b25a45312b..e500a40e57 100644 --- a/services/docstore/test/acceptance/js/HealthCheckerTest.js +++ b/services/docstore/test/acceptance/js/HealthCheckerTest.js @@ -4,22 +4,19 @@ const DocstoreClient = require('./helpers/DocstoreClient') const { expect } = require('chai') describe('HealthChecker', function () { - beforeEach('start', function (done) { - DocstoreApp.ensureRunning(done) + beforeEach('start', async function () { + await DocstoreApp.ensureRunning() }) beforeEach('clear docs collection', async function () { await db.docs.deleteMany({}) }) let res - beforeEach('run health check', function (done) { - DocstoreClient.healthCheck((err, _res) => { - res = _res - done(err) - }) + beforeEach('run health check', async function () { + res = await DocstoreClient.healthCheck() }) it('should return 200', function () { - res.statusCode.should.equal(200) + res.status.should.equal(200) }) it('should not leave any cruft behind', async function () { diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 43f75b6976..a88cfe16c2 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -1,22 +1,10 @@ -/* eslint-disable - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const sinon = require('sinon') const { ObjectId } = require('mongodb-legacy') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') describe('Applying updates to a doc', function () { - beforeEach(function (done) { + beforeEach(async function () { this.project_id = new ObjectId() this.doc_id = new ObjectId() this.originalLines = ['original', 'lines'] @@ -45,511 +33,362 @@ describe('Applying updates to a doc', function () { }, ], } + this.version = 42 - return DocstoreApp.ensureRunning(() => { - return DocstoreClient.createDoc( - this.project_id, - this.doc_id, - this.originalLines, - this.version, - this.originalRanges, - error => { - if (error != null) { - throw error - } - return done() - } - ) - }) + await DocstoreApp.ensureRunning() + await DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.originalLines, + this.version, + this.originalRanges + ) }) describe('when nothing has been updated', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( + beforeEach(async function () { + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.originalLines, this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.body = body - return done() - } + this.originalRanges ) }) it('should return modified = false', function () { - return this.body.modified.should.equal(false) + this.body.modified.should.equal(false) }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.originalRanges) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.originalRanges) }) }) describe('when the lines have changed', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( + beforeEach(async function () { + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.newLines, this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.body = body - return done() - } + this.originalRanges ) }) it('should return modified = true', function () { - return this.body.modified.should.equal(true) + this.body.modified.should.equal(true) }) it('should return the rev', function () { - return this.body.rev.should.equal(2) + this.body.rev.should.equal(2) }) - return it('should update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.newLines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.originalRanges) - return done() - } - ) + it('should update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.newLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.originalRanges) }) }) describe('when the version has changed', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( + beforeEach(async function () { + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.originalLines, this.version + 1, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.body = body - return done() - } + this.originalRanges ) }) it('should return modified = true', function () { - return this.body.modified.should.equal(true) + this.body.modified.should.equal(true) }) it('should return the rev', function () { - return this.body.rev.should.equal(1) + this.body.rev.should.equal(1) }) - return it('should update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(this.version + 1) - doc.ranges.should.deep.equal(this.originalRanges) - return done() - } - ) + it('should update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version + 1) + doc.ranges.should.deep.equal(this.originalRanges) }) }) describe('when the version was decremented', function () { - beforeEach(function (done) { - DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - this.newLines, - this.version - 1, - this.newRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - done() - } - ) + let statusCode + beforeEach(async function () { + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.newLines, + this.version - 1, + this.newRanges + ) + } catch (error) { + statusCode = error.info.status + } }) it('should return 409', function () { - this.res.statusCode.should.equal(409) + statusCode.should.equal(409) }) - it('should not update the doc in the API', function (done) { - DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.originalRanges) - done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.originalRanges) }) }) describe('when the ranges have changed', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( + beforeEach(async function () { + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.originalLines, this.version, - this.newRanges, - (error, res, body) => { - if (error) return done(error) - this.body = body - return done() - } + this.newRanges ) }) it('should return modified = true', function () { - return this.body.modified.should.equal(true) + this.body.modified.should.equal(true) }) it('should return the rev', function () { - return this.body.rev.should.equal(2) + this.body.rev.should.equal(2) }) - return it('should update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(this.version) - doc.ranges.should.deep.equal(this.newRanges) - return done() - } - ) + it('should update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.newRanges) }) }) describe('when the doc does not exist', function () { - beforeEach(function (done) { + beforeEach(async function () { this.missing_doc_id = new ObjectId() - return DocstoreClient.updateDoc( + this.body = await DocstoreClient.updateDoc( this.project_id, this.missing_doc_id, this.originalLines, 0, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } + this.originalRanges ) }) it('should create the doc', function () { - return this.body.rev.should.equal(1) + this.body.rev.should.equal(1) }) - return it('should be retreivable', function (done) { - return DocstoreClient.getDoc( + it('should be retreivable', async function () { + const doc = await DocstoreClient.getDoc( this.project_id, - this.missing_doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(0) - doc.ranges.should.deep.equal(this.originalRanges) - return done() - } + this.missing_doc_id ) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(0) + doc.ranges.should.deep.equal(this.originalRanges) }) }) describe('when malformed doc lines are provided', function () { describe('when the lines are not an array', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - { foo: 'bar' }, - this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } - ) + let statusCode + beforeEach(async function () { + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + { foo: 'bar' }, + this.version, + this.originalRanges + ) + } catch (error) { + statusCode = error.info.status + } }) it('should return 400', function () { - return this.res.statusCode.should.equal(400) + statusCode.should.equal(400) }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) }) }) - return describe('when the lines are not present', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - null, - this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } - ) + describe('when the lines are not present', function () { + let statusCode + beforeEach(async function () { + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + null, + this.version, + this.originalRanges + ) + } catch (error) { + statusCode = error.info.status + } }) it('should return 400', function () { - return this.res.statusCode.should.equal(400) + statusCode.should.equal(400) }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) }) }) }) describe('when no version is provided', function () { - beforeEach(function (done) { - return DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - this.originalLines, - null, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } - ) + let statusCode + beforeEach(async function () { + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.originalLines, + null, + this.originalRanges + ) + } catch (error) { + statusCode = error.info.status + } }) it('should return 400', function () { - return this.res.statusCode.should.equal(400) + statusCode.should.equal(400) }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - doc.version.should.equal(this.version) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) }) }) describe('when the content is large', function () { - beforeEach(function (done) { + beforeEach(async function () { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1mb - return DocstoreClient.updateDoc( + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.largeLines, this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.body = body - return done() - } + this.originalRanges ) }) it('should return modified = true', function () { - return this.body.modified.should.equal(true) + this.body.modified.should.equal(true) }) - return it('should update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.largeLines) - return done() - } - ) + it('should update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.largeLines) }) }) describe('when there is a large json payload', function () { - beforeEach(function (done) { + beforeEach(async function () { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb this.originalRanges.padding = Array.apply(null, Array(2049)).map( () => line ) // 2mb + 1kb - return DocstoreClient.updateDoc( + this.body = await DocstoreClient.updateDoc( this.project_id, this.doc_id, this.largeLines, this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } + this.originalRanges ) }) it('should return modified = true', function () { - return this.body.modified.should.equal(true) + this.body.modified.should.equal(true) }) - return it('should update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.largeLines) - return done() - } - ) + it('should update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.largeLines) }) }) describe('when the document body is too large', function () { - beforeEach(function (done) { + let statusCode, body + beforeEach(async function () { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(2049)).map(() => line) // 2mb + 1kb - return DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - this.largeLines, - this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } - ) + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges + ) + } catch (error) { + statusCode = error.info.status + body = error.body + } }) it('should return 413', function () { - return this.res.statusCode.should.equal(413) + statusCode.should.equal(413) }) it('should report body too large', function () { - return this.res.body.should.equal('document body too large') + body.should.equal('document body too large') }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) }) }) - return describe('when the json payload is too large', function () { - beforeEach(function (done) { + describe('when the json payload is too large', function () { + beforeEach(async function () { const line = new Array(1024).join('x') // 1 KB this.largeLines = new Array(8192).fill(line) // 8 MB this.originalRanges.padding = new Array(6144).fill(line) // 6 MB - return DocstoreClient.updateDoc( - this.project_id, - this.doc_id, - this.largeLines, - this.version, - this.originalRanges, - (error, res, body) => { - if (error) return done(error) - this.res = res - this.body = body - return done() - } - ) + + try { + this.body = await DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges + ) + } catch (error) { + // ignore error response + } }) - return it('should not update the doc in the API', function (done) { - return DocstoreClient.getDoc( - this.project_id, - this.doc_id, - {}, - (error, res, doc) => { - if (error) return done(error) - doc.lines.should.deep.equal(this.originalLines) - return done() - } - ) + it('should not update the doc in the API', async function () { + const doc = await DocstoreClient.getDoc(this.project_id, this.doc_id) + doc.lines.should.deep.equal(this.originalLines) }) }) }) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 5e837b1277..27bced4699 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -1,26 +1,31 @@ const app = require('../../../../app') -const settings = require('@overleaf/settings') +const Settings = require('@overleaf/settings') + +function startApp() { + return new Promise((resolve, reject) => { + app.listen( + Settings.internal.docstore.port, + Settings.internal.docstore.host, + error => { + if (error) { + reject(error) + } else { + resolve() + } + } + ) + }) +} + +let appStartedPromise + +async function ensureRunning() { + if (!appStartedPromise) { + appStartedPromise = startApp() + } + await appStartedPromise +} module.exports = { - running: false, - initing: false, - callbacks: [], - ensureRunning(callback) { - if (this.running) { - return callback() - } else if (this.initing) { - return this.callbacks.push(callback) - } - this.initing = true - this.callbacks.push(callback) - app.listen(settings.internal.docstore.port, '127.0.0.1', error => { - if (error != null) { - throw error - } - this.running = true - for (callback of Array.from(this.callbacks)) { - callback() - } - }) - }, + ensureRunning, } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index cb8bce2579..98f354681b 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -1,5 +1,9 @@ let DocstoreClient -const request = require('request').defaults({ jar: false }) +const { + fetchNothing, + fetchJson, + fetchJsonWithResponse, +} = require('@overleaf/fetch-utils') const settings = require('@overleaf/settings') const Persistor = require('../../../../app/js/PersistorManager') @@ -19,204 +23,156 @@ async function getStringFromPersistor(persistor, bucket, key) { } module.exports = DocstoreClient = { - createDoc(projectId, docId, lines, version, ranges, callback) { - return DocstoreClient.updateDoc( + async createDoc(projectId, docId, lines, version, ranges) { + return await DocstoreClient.updateDoc( projectId, docId, lines, version, - ranges, - callback + ranges ) }, - getDoc(projectId, docId, qs, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, - json: true, - qs, - }, - callback + async getDoc(projectId, docId, qs = {}) { + const url = new URL( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}` + ) + for (const [key, value] of Object.entries(qs)) { + url.searchParams.append(key, value) + } + return await fetchJson(url) + }, + + async peekDoc(projectId, docId, qs = {}) { + const url = new URL( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/peek` + ) + for (const [key, value] of Object.entries(qs)) { + url.searchParams.append(key, value) + } + const { response, json } = await fetchJsonWithResponse(url) + return { res: response, doc: json } + }, + + async isDocDeleted(projectId, docId) { + const { response, json } = await fetchJsonWithResponse( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/deleted` + ) + return { res: response, body: json } + }, + + async getAllDocs(projectId) { + return await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc` ) }, - peekDoc(projectId, docId, qs, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/peek`, - json: true, - qs, - }, - callback + async getAllDeletedDocs(projectId, callback) { + return await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc-deleted` ) }, - isDocDeleted(projectId, docId, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/deleted`, - json: true, - }, - callback + async getAllRanges(projectId) { + return await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/ranges` ) }, - getAllDocs(projectId, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc`, - json: true, - }, - (req, res, body) => { - callback(req, res, body) - } + async getCommentThreadIds(projectId, callback) { + return await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/comment-thread-ids` ) }, - getAllDeletedDocs(projectId, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc-deleted`, - json: true, - }, - (error, res, body) => { - if (error) return callback(error) - if (res.statusCode !== 200) { - return callback(new Error('unexpected statusCode')) - } - callback(null, body) - } + async getTrackedChangesUserIds(projectId) { + return await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/tracked-changes-user-ids` ) }, - getAllRanges(projectId, callback) { - request.get( + async updateDoc(projectId, docId, lines, version, ranges) { + const res = await fetchJson( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/ranges`, - json: true, - }, - callback - ) - }, - - getCommentThreadIds(projectId, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/comment-thread-ids`, - json: true, - }, - callback - ) - }, - - getTrackedChangesUserIds(projectId, callback) { - request.get( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/tracked-changes-user-ids`, - json: true, - }, - callback - ) - }, - - updateDoc(projectId, docId, lines, version, ranges, callback) { - return request.post( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, + method: 'POST', json: { lines, version, ranges, }, - }, - callback + } ) + return res }, - deleteDoc(projectId, docId, callback) { - DocstoreClient.deleteDocWithDateAndName( + async deleteDoc(projectId, docId) { + return await DocstoreClient.deleteDocWithDateAndName( projectId, docId, new Date(), - 'main.tex', - callback + 'main.tex' ) }, - deleteDocWithDate(projectId, docId, date, callback) { - DocstoreClient.deleteDocWithDateAndName( + async deleteDocWithDate(projectId, docId, date) { + return await DocstoreClient.deleteDocWithDateAndName( projectId, docId, date, - 'main.tex', - callback + 'main.tex' ) }, - deleteDocWithName(projectId, docId, name, callback) { - DocstoreClient.deleteDocWithDateAndName( + async deleteDocWithName(projectId, docId, name) { + return await DocstoreClient.deleteDocWithDateAndName( projectId, docId, new Date(), - name, - callback + name ) }, - deleteDocWithDateAndName(projectId, docId, deletedAt, name, callback) { - request.patch( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, - json: { name, deleted: true, deletedAt }, - }, - callback + async deleteDocWithDateAndName(projectId, docId, deletedAt, name) { + return await fetchNothing( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, + { method: 'PATCH', json: { name, deleted: true, deletedAt } } ) }, - archiveAllDoc(projectId, callback) { - request.post( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/archive`, - }, - callback + async archiveAllDoc(projectId) { + return await fetchNothing( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/archive`, + { method: 'POST' } ) }, - archiveDoc(projectId, docId, callback) { - request.post( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/archive`, - }, - callback + async archiveDoc(projectId, docId) { + return await fetchNothing( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/archive`, + { method: 'POST' } ) }, - destroyAllDoc(projectId, callback) { - request.post( - { - url: `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/destroy`, - }, - callback + async destroyAllDoc(projectId) { + await fetchNothing( + `http://127.0.0.1:${settings.internal.docstore.port}/project/${projectId}/destroy`, + { method: 'POST' } ) }, - healthCheck(callback) { - request.get( - `http://127.0.0.1:${settings.internal.docstore.port}/health_check`, - callback + async healthCheck() { + return await fetchNothing( + `http://127.0.0.1:${settings.internal.docstore.port}/health_check` ) }, - getS3Doc(projectId, docId, callback) { - getStringFromPersistor( + async getS3Doc(projectId, docId) { + const data = await getStringFromPersistor( Persistor, settings.docstore.bucket, `${projectId}/${docId}` ) - .then(data => { - callback(null, JSON.parse(data)) - }) - .catch(callback) + return JSON.parse(data) }, }