Просмотр исходного кода

Convert return new Promise to await new Promise

GitOrigin-RevId: 49404748cc90cb7bdef0460f7e9837196f81cae8
Andrew Rumble 1 год назад
Родитель
Сommit
e76a8ff267
31 измененных файлов с 691 добавлено и 687 удалено
  1. 2 2
      services/web/modules/launchpad/test/unit/src/LaunchpadController.test.mjs
  2. 12 11
      services/web/modules/user-activate/test/unit/src/UserActivateController.test.mjs
  3. 6 6
      services/web/test/unit/src/Analytics/AnalyticsController.test.mjs
  4. 33 33
      services/web/test/unit/src/BetaProgram/BetaProgramController.test.mjs
  5. 16 16
      services/web/test/unit/src/BetaProgram/BetaProgramHandler.test.mjs
  6. 28 28
      services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs
  7. 52 52
      services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs
  8. 9 9
      services/web/test/unit/src/Contact/ContactController.test.mjs
  9. 8 8
      services/web/test/unit/src/Documents/DocumentController.test.mjs
  10. 6 6
      services/web/test/unit/src/Downloads/ProjectZipStreamManager.test.mjs
  11. 10 10
      services/web/test/unit/src/Exports/ExportsController.test.mjs
  12. 41 40
      services/web/test/unit/src/Exports/ExportsHandler.test.mjs
  13. 4 4
      services/web/test/unit/src/FileStore/FileStoreController.test.mjs
  14. 4 4
      services/web/test/unit/src/LinkedFiles/LinkedFilesController.test.mjs
  15. 6 6
      services/web/test/unit/src/Notifications/NotificationsController.test.mjs
  16. 52 52
      services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs
  17. 26 26
      services/web/test/unit/src/PasswordReset/PasswordResetHandler.test.mjs
  18. 2 2
      services/web/test/unit/src/Project/ProjectApiController.test.mjs
  19. 34 34
      services/web/test/unit/src/Project/ProjectListController.test.mjs
  20. 22 22
      services/web/test/unit/src/Referal/ReferalConnect.test.mjs
  21. 24 24
      services/web/test/unit/src/References/ReferencesController.test.mjs
  22. 28 28
      services/web/test/unit/src/References/ReferencesHandler.test.mjs
  23. 59 58
      services/web/test/unit/src/Subscription/SubscriptionGroupController.test.mjs
  24. 14 14
      services/web/test/unit/src/Subscription/TeamInvitesController.test.mjs
  25. 22 22
      services/web/test/unit/src/Tags/TagsController.test.mjs
  26. 28 28
      services/web/test/unit/src/ThirdPartyDataStore/TpdsController.test.mjs
  27. 2 2
      services/web/test/unit/src/ThirdPartyDataStore/TpdsUpdateHandler.test.mjs
  28. 49 48
      services/web/test/unit/src/TokenAccess/TokenAccessController.test.mjs
  29. 2 2
      services/web/test/unit/src/Uploads/ProjectUploadController.test.mjs
  30. 66 66
      services/web/test/unit/src/User/UserPagesController.test.mjs
  31. 24 24
      services/web/test/unit/src/UserMembership/UserMembershipController.test.mjs

+ 2 - 2
services/web/modules/launchpad/test/unit/src/LaunchpadController.test.mjs

@@ -281,8 +281,8 @@ describe('LaunchpadController', function () {
           .rejects(new Error('woops'))
       })
 
-      it('should call next with an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should call next with an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.next = sinon.stub().callsFake(err => {
             expect(err).to.be.instanceof(Error)
             ctx.next.callCount.should.equal(1)

+ 12 - 11
services/web/modules/user-activate/test/unit/src/UserActivateController.test.mjs

@@ -77,38 +77,39 @@ describe('UserActivateController', function () {
 
     it('should 404 without a user_id', async function (ctx) {
       delete ctx.req.query.user_id
-      return new Promise(resolve => {
+
+      await new Promise(resolve => {
         ctx.ErrorController.notFound = () => resolve()
         ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
       })
     })
 
-    it('should 404 without a token', function (ctx) {
-      return new Promise(resolve => {
+    it('should 404 without a token', async function (ctx) {
+      await new Promise(resolve => {
         delete ctx.req.query.token
         ctx.ErrorController.notFound = resolve
         ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
       })
     })
 
-    it('should 404 without a valid user_id', function (ctx) {
-      return new Promise(resolve => {
+    it('should 404 without a valid user_id', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserGetter.promises.getUser = sinon.stub().resolves(null)
         ctx.ErrorController.notFound = resolve
         ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
       })
     })
 
-    it('should 403 for complex user_id', function (ctx) {
-      return new Promise(resolve => {
+    it('should 403 for complex user_id', async function (ctx) {
+      await new Promise(resolve => {
         ctx.ErrorController.forbidden = resolve
         ctx.req.query.user_id = { first_name: 'X' }
         ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
       })
     })
 
-    it('should redirect activated users to login', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect activated users to login', async function (ctx) {
+      await new Promise(resolve => {
         ctx.user.loginCount = 1
         ctx.res.redirect = url => {
           sinon.assert.calledWith(ctx.UserGetter.promises.getUser, ctx.user_id)
@@ -119,8 +120,8 @@ describe('UserActivateController', function () {
       })
     })
 
-    it('render the activation page if the user has not logged in before', function (ctx) {
-      return new Promise(resolve => {
+    it('render the activation page if the user has not logged in before', async function (ctx) {
+      await new Promise(resolve => {
         ctx.user.loginCount = 0
         ctx.res.render = (page, opts) => {
           page.should.equal(VIEW_PATH)

+ 6 - 6
services/web/test/unit/src/Analytics/AnalyticsController.test.mjs

@@ -68,8 +68,8 @@ describe('AnalyticsController', function () {
         .resolves({ country_code: 'XY' })
     })
 
-    it('delegates to the AnalyticsManager', function (ctx) {
-      return new Promise(resolve => {
+    it('delegates to the AnalyticsManager', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SessionManager.getLoggedInUserId.returns('1234')
         ctx.res.callback = () => {
           sinon.assert.calledWith(
@@ -105,8 +105,8 @@ describe('AnalyticsController', function () {
       delete ctx.expectedData._csrf
     })
 
-    it('should use the session', function (ctx) {
-      return new Promise(resolve => {
+    it('should use the session', async function (ctx) {
+      await new Promise(resolve => {
         ctx.controller.recordEvent(ctx.req, ctx.res)
         sinon.assert.calledWith(
           ctx.AnalyticsManager.recordEventForSession,
@@ -118,8 +118,8 @@ describe('AnalyticsController', function () {
       })
     })
 
-    it('should remove the CSRF token before sending to the manager', function (ctx) {
-      return new Promise(resolve => {
+    it('should remove the CSRF token before sending to the manager', async function (ctx) {
+      await new Promise(resolve => {
         ctx.controller.recordEvent(ctx.req, ctx.res)
         sinon.assert.calledWith(
           ctx.AnalyticsManager.recordEventForSession,

+ 33 - 33
services/web/test/unit/src/BetaProgram/BetaProgramController.test.mjs

@@ -79,14 +79,14 @@ describe('BetaProgramController', function () {
   })
 
   describe('optIn', function () {
-    it("should redirect to '/beta/participate'", function (ctx) {
-      return new Promise(resolve => {
+    it("should redirect to '/beta/participate'", async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.redirectedTo.should.equal('/beta/participate')
           resolve()
         }
         ctx.BetaProgramController.optIn(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     it('should not call next with an error', function (ctx) {
@@ -99,8 +99,8 @@ describe('BetaProgramController', function () {
       ctx.BetaProgramHandler.promises.optIn.callCount.should.equal(1)
     })
 
-    it('should invoke the session maintenance', function (ctx) {
-      return new Promise(resolve => {
+    it('should invoke the session maintenance', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.SplitTestSessionHandler.promises.sessionMaintenance.should.have.been.calledWith(
             ctx.req
@@ -108,7 +108,7 @@ describe('BetaProgramController', function () {
           resolve()
         }
         ctx.BetaProgramController.optIn(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when BetaProgramHandler.opIn produces an error', function () {
@@ -121,50 +121,50 @@ describe('BetaProgramController', function () {
         ctx.res.redirect.callCount.should.equal(0)
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function(ctx) {
+        await new Promise(resolve => {
           ctx.BetaProgramController.optIn(ctx.req, ctx.res, err => {
             expect(err).to.be.instanceof(Error)
             resolve()
           })
-        })
+        });
       })
     })
   })
 
   describe('optOut', function () {
-    it("should redirect to '/beta/participate'", function (ctx) {
-      return new Promise(resolve => {
+    it("should redirect to '/beta/participate'", async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.res.redirectedTo).to.equal('/beta/participate')
           resolve()
         }
         ctx.BetaProgramController.optOut(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should not call next with an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not call next with an error', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.next.callCount.should.equal(0)
           resolve()
         }
         ctx.BetaProgramController.optOut(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should call BetaProgramHandler.optOut', function (ctx) {
-      return new Promise(resolve => {
+    it('should call BetaProgramHandler.optOut', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.BetaProgramHandler.promises.optOut.callCount.should.equal(1)
           resolve()
         }
         ctx.BetaProgramController.optOut(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should invoke the session maintenance', function (ctx) {
-      return new Promise(resolve => {
+    it('should invoke the session maintenance', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.SplitTestSessionHandler.promises.sessionMaintenance.should.have.been.calledWith(
             ctx.req,
@@ -173,7 +173,7 @@ describe('BetaProgramController', function () {
           resolve()
         }
         ctx.BetaProgramController.optOut(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when BetaProgramHandler.optOut produces an error', function () {
@@ -181,23 +181,23 @@ describe('BetaProgramController', function () {
         ctx.BetaProgramHandler.promises.optOut.throws(new Error('woops'))
       })
 
-      it("should not redirect to '/beta/participate'", function (ctx) {
-        return new Promise(resolve => {
+      it("should not redirect to '/beta/participate'", async function(ctx) {
+        await new Promise(resolve => {
           ctx.BetaProgramController.optOut(ctx.req, ctx.res, error => {
             expect(error).to.exist
             expect(ctx.res.redirected).to.equal(false)
             resolve()
           })
-        })
+        });
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function(ctx) {
+        await new Promise(resolve => {
           ctx.BetaProgramController.optOut(ctx.req, ctx.res, error => {
             expect(error).to.exist
             resolve()
           })
-        })
+        });
       })
     })
   })
@@ -207,14 +207,14 @@ describe('BetaProgramController', function () {
       ctx.UserGetter.promises.getUser.resolves(ctx.user)
     })
 
-    it('should render the opt-in page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render the opt-in page', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.res.renderedTemplate).to.equal('beta_program/opt_in')
           resolve()
         }
         ctx.BetaProgramController.optInPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when UserGetter.getUser produces an error', function () {
@@ -227,14 +227,14 @@ describe('BetaProgramController', function () {
         ctx.res.render.callCount.should.equal(0)
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function(ctx) {
+        await new Promise(resolve => {
           ctx.BetaProgramController.optInPage(ctx.req, ctx.res, error => {
             expect(error).to.exist
             expect(error).to.be.instanceof(Error)
             resolve()
           })
-        })
+        });
       })
     })
   })

+ 16 - 16
services/web/test/unit/src/BetaProgram/BetaProgramHandler.test.mjs

@@ -56,8 +56,8 @@ describe('BetaProgramHandler', function () {
       }
     })
 
-    it('should call userUpdater', function (ctx) {
-      return new Promise(resolve => {
+    it('should call userUpdater', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           ctx.UserUpdater.promises.updateUser.callCount.should.equal(1)
@@ -66,8 +66,8 @@ describe('BetaProgramHandler', function () {
       })
     })
 
-    it('should set beta-program user property to true', function (ctx) {
-      return new Promise(resolve => {
+    it('should set beta-program user property to true', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           sinon.assert.calledWith(
@@ -81,8 +81,8 @@ describe('BetaProgramHandler', function () {
       })
     })
 
-    it('should not produce an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not produce an error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           resolve()
@@ -95,8 +95,8 @@ describe('BetaProgramHandler', function () {
         ctx.UserUpdater.promises.updateUser.rejects()
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(err => {
             expect(err).to.exist
             expect(err).to.be.instanceof(Error)
@@ -115,8 +115,8 @@ describe('BetaProgramHandler', function () {
       }
     })
 
-    it('should call userUpdater', function (ctx) {
-      return new Promise(resolve => {
+    it('should call userUpdater', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           ctx.UserUpdater.promises.updateUser.callCount.should.equal(1)
@@ -125,8 +125,8 @@ describe('BetaProgramHandler', function () {
       })
     })
 
-    it('should set beta-program user property to false', function (ctx) {
-      return new Promise(resolve => {
+    it('should set beta-program user property to false', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           sinon.assert.calledWith(
@@ -140,8 +140,8 @@ describe('BetaProgramHandler', function () {
       })
     })
 
-    it('should not produce an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not produce an error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(err => {
           expect(err).to.not.exist
           resolve()
@@ -154,8 +154,8 @@ describe('BetaProgramHandler', function () {
         ctx.UserUpdater.promises.updateUser.rejects()
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(err => {
             expect(err).to.exist
             expect(err).to.be.instanceof(Error)

+ 28 - 28
services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs

@@ -169,8 +169,8 @@ describe('CollaboratorsController', function () {
   })
 
   describe('removeUserFromProject', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.params = {
           Project_id: ctx.projectId,
           user_id: ctx.user._id,
@@ -219,8 +219,8 @@ describe('CollaboratorsController', function () {
   })
 
   describe('removeSelfFromProject', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.params = { Project_id: ctx.projectId }
         ctx.res.sendStatus = sinon.spy(() => {
           resolve()
@@ -264,8 +264,8 @@ describe('CollaboratorsController', function () {
   })
 
   describe('getAllMembers', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.params = { Project_id: ctx.projectId }
         ctx.res.json = sinon.spy(() => {
           resolve()
@@ -294,8 +294,8 @@ describe('CollaboratorsController', function () {
     })
 
     describe('when CollaboratorsGetter.getAllInvitedMembers produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.json = sinon.stub()
           ctx.next = sinon.spy(() => {
             resolve()
@@ -329,8 +329,8 @@ describe('CollaboratorsController', function () {
       ctx.req.body = { privilegeLevel: 'readOnly' }
     })
 
-    it('should set the collaborator privilege level', function (ctx) {
-      return new Promise(resolve => {
+    it('should set the collaborator privilege level', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.sendStatus = status => {
           expect(status).to.equal(204)
           expect(
@@ -342,8 +342,8 @@ describe('CollaboratorsController', function () {
       })
     })
 
-    it('should return a 404 when the project or collaborator is not found', function (ctx) {
-      return new Promise(resolve => {
+    it('should return a 404 when the project or collaborator is not found', async function (ctx) {
+      await new Promise(resolve => {
         ctx.HttpErrorHandler.notFound = sinon.spy((req, res) => {
           expect(req).to.equal(ctx.req)
           expect(res).to.equal(ctx.res)
@@ -357,8 +357,8 @@ describe('CollaboratorsController', function () {
       })
     })
 
-    it('should pass the error to the next handler when setting the privilege level fails', function (ctx) {
-      return new Promise(resolve => {
+    it('should pass the error to the next handler when setting the privilege level fails', async function (ctx) {
+      await new Promise(resolve => {
         ctx.next = sinon.spy(err => {
           expect(err).instanceOf(Error)
           resolve()
@@ -381,8 +381,8 @@ describe('CollaboratorsController', function () {
       })
 
       describe('when owner can add new edit collaborators', function () {
-        it('should set privilege level after checking collaborators can be added', function (ctx) {
-          return new Promise(resolve => {
+        it('should set privilege level after checking collaborators can be added', async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.sendStatus = status => {
               expect(status).to.equal(204)
               expect(
@@ -407,8 +407,8 @@ describe('CollaboratorsController', function () {
           )
         })
 
-        it('should return a 403 if trying to set a new edit collaborator', function (ctx) {
-          return new Promise(resolve => {
+        it('should return a 403 if trying to set a new edit collaborator', async function (ctx) {
+          await new Promise(resolve => {
             ctx.HttpErrorHandler.forbidden = sinon.spy((req, res) => {
               expect(req).to.equal(ctx.req)
               expect(res).to.equal(ctx.res)
@@ -443,8 +443,8 @@ describe('CollaboratorsController', function () {
           )
         })
 
-        it('should always allow setting a collaborator to viewer even if user cant add edit collaborators', function (ctx) {
-          return new Promise(resolve => {
+        it('should always allow setting a collaborator to viewer even if user cant add edit collaborators', async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.sendStatus = status => {
               expect(status).to.equal(204)
               expect(ctx.LimitationsManager.promises.canAddXEditCollaborators)
@@ -466,8 +466,8 @@ describe('CollaboratorsController', function () {
       ctx.req.body = { user_id: ctx.user._id.toString() }
     })
 
-    it('returns 204 on success', function (ctx) {
-      return new Promise(resolve => {
+    it('returns 204 on success', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.sendStatus = status => {
           expect(status).to.equal(204)
           resolve()
@@ -476,8 +476,8 @@ describe('CollaboratorsController', function () {
       })
     })
 
-    it('returns 404 if the project does not exist', function (ctx) {
-      return new Promise(resolve => {
+    it('returns 404 if the project does not exist', async function (ctx) {
+      await new Promise(resolve => {
         ctx.HttpErrorHandler.notFound = sinon.spy((req, res, message) => {
           expect(req).to.equal(ctx.req)
           expect(res).to.equal(ctx.res)
@@ -491,8 +491,8 @@ describe('CollaboratorsController', function () {
       })
     })
 
-    it('returns 404 if the user does not exist', function (ctx) {
-      return new Promise(resolve => {
+    it('returns 404 if the user does not exist', async function (ctx) {
+      await new Promise(resolve => {
         ctx.HttpErrorHandler.notFound = sinon.spy((req, res, message) => {
           expect(req).to.equal(ctx.req)
           expect(res).to.equal(ctx.res)
@@ -506,8 +506,8 @@ describe('CollaboratorsController', function () {
       })
     })
 
-    it('invokes HTTP forbidden error handler if the user is not a collaborator', function (ctx) {
-      return new Promise(resolve => {
+    it('invokes HTTP forbidden error handler if the user is not a collaborator', async function (ctx) {
+      await new Promise(resolve => {
         ctx.HttpErrorHandler.forbidden = sinon.spy(() => resolve())
         ctx.OwnershipTransferHandler.promises.transferOwnership.rejects(
           new Errors.UserNotCollaboratorError()

+ 52 - 52
services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs

@@ -229,8 +229,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteGetter.promises.getAllInvites.resolves(
             ctx.fakeInvites
           )
@@ -263,8 +263,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when CollaboratorsInviteHandler.getAllInvites produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteGetter.promises.getAllInvites.rejects(
             new Error('woops')
           )
@@ -378,8 +378,8 @@ describe('CollaboratorsInviteController', function () {
       })
 
       describe('readAndWrite collaborator', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.privileges = 'readAndWrite'
             ctx.CollaboratorsInviteController._checkShouldInviteEmail = sinon
               .stub()
@@ -420,8 +420,8 @@ describe('CollaboratorsInviteController', function () {
       })
 
       describe('readOnly collaborator (always allowed)', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.req.body = {
               email: ctx.targetEmail,
               privileges: (ctx.privileges = 'readOnly'),
@@ -500,8 +500,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when inviteToProject produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteController._checkShouldInviteEmail = sinon
             .stub()
             .resolves(true)
@@ -559,8 +559,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when _checkShouldInviteEmail disallows the invite', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteController._checkShouldInviteEmail = sinon
             .stub()
             .resolves(false)
@@ -601,8 +601,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when _checkShouldInviteEmail produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteController._checkShouldInviteEmail = sinon
             .stub()
             .rejects(new Error('woops'))
@@ -748,8 +748,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when the token is valid', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.viewInvite(
             ctx.req,
@@ -802,8 +802,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when not logged in', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.SessionManager.getSessionUser.returns(null)
 
           ctx.res.callback = () => resolve()
@@ -833,8 +833,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when user is already a member of the project', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.resolves(
             true
           )
@@ -883,8 +883,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when isUserInvitedMemberOfProject produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.rejects(
             new Error('woops')
           )
@@ -927,8 +927,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when the getInviteByToken produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteGetter.promises.getInviteByToken.rejects(
             new Error('woops')
           )
@@ -974,8 +974,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when the getInviteByToken does not produce an invite', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(null)
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.viewInvite(
@@ -1023,8 +1023,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when User.getUser produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.UserGetter.promises.getUser.rejects(new Error('woops'))
           ctx.next.callsFake(() => resolve())
           ctx.CollaboratorsInviteController.viewInvite(
@@ -1068,8 +1068,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when User.getUser does not find a user', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.UserGetter.promises.getUser.resolves(null)
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.viewInvite(
@@ -1117,8 +1117,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when getProject produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectGetter.promises.getProject.rejects(new Error('woops'))
           ctx.next.callsFake(() => resolve())
           ctx.CollaboratorsInviteController.viewInvite(
@@ -1162,8 +1162,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when Project.getUser does not find a user', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectGetter.promises.getProject.resolves(null)
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.viewInvite(
@@ -1224,8 +1224,8 @@ describe('CollaboratorsInviteController', function () {
 
     describe('when generateNewInvite does not produce an error', function () {
       describe('and returns an invite object', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.callback = () => resolve()
             ctx.CollaboratorsInviteController.generateNewInvite(
               ctx.req,
@@ -1274,8 +1274,8 @@ describe('CollaboratorsInviteController', function () {
       })
 
       describe('and returns a null invite', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsInviteHandler.promises.generateNewInvite.resolves(
               null
             )
@@ -1303,8 +1303,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when generateNewInvite produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteHandler.promises.generateNewInvite.rejects(
             new Error('woops')
           )
@@ -1343,8 +1343,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when revokeInvite does not produce an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.revokeInvite(
             ctx.req,
@@ -1387,8 +1387,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when revokeInvite produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteHandler.promises.revokeInvite.rejects(
             new Error('woops')
           )
@@ -1427,8 +1427,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when acceptInvite does not produce an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = () => resolve()
           ctx.CollaboratorsInviteController.acceptInvite(
             ctx.req,
@@ -1476,8 +1476,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when the invite is not found', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteGetter.promises.getInviteByToken.resolves(null)
           ctx.next.callsFake(() => resolve())
           ctx.CollaboratorsInviteController.acceptInvite(
@@ -1496,8 +1496,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when acceptInvite produces an error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.CollaboratorsInviteHandler.promises.acceptInvite.rejects(
             new Error('woops')
           )
@@ -1527,8 +1527,8 @@ describe('CollaboratorsInviteController', function () {
     })
 
     describe('when the project audit log entry fails', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectAuditLogHandler.promises.addEntry.rejects(
             new Error('oops')
           )

+ 9 - 9
services/web/test/unit/src/Contact/ContactController.test.mjs

@@ -88,8 +88,8 @@ describe('ContactController', function () {
       ctx.ContactController.getContacts(ctx.req, ctx.res)
     })
 
-    it('should populate the users contacts ids', function (ctx) {
-      return new Promise(resolve => {
+    it('should populate the users contacts ids', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.UserGetter.promises.getUsers).to.have.been.calledWith(
             ctx.contact_ids,
@@ -103,11 +103,11 @@ describe('ContactController', function () {
           resolve()
         }
         ctx.ContactController.getContacts(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should fire the getContact module hook', function (ctx) {
-      return new Promise(resolve => {
+    it('should fire the getContact module hook', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
             'getContacts',
@@ -116,11 +116,11 @@ describe('ContactController', function () {
           resolve()
         }
         ctx.ContactController.getContacts(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should return a formatted list of contacts in contact list order, without holding accounts', function (ctx) {
-      return new Promise(resolve => {
+    it('should return a formatted list of contacts in contact list order, without holding accounts', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.json.args[0][0].contacts.should.deep.equal([
             {
@@ -141,7 +141,7 @@ describe('ContactController', function () {
           resolve()
         }
         ctx.ContactController.getContacts(ctx.req, ctx.res, resolve)
-      })
+      });
     })
   })
 })

+ 8 - 8
services/web/test/unit/src/Documents/DocumentController.test.mjs

@@ -125,8 +125,8 @@ describe('DocumentController', function () {
     })
 
     describe('when project exists with project history enabled', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = err => {
             resolve(err)
           }
@@ -151,8 +151,8 @@ describe('DocumentController', function () {
     })
 
     describe('when the project does not exist', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectGetter.promises.getProject.resolves(null)
           ctx.res.callback = err => {
             resolve(err)
@@ -176,8 +176,8 @@ describe('DocumentController', function () {
     })
 
     describe('when the document exists', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.body = {
             lines: ctx.doc_lines,
             version: ctx.version,
@@ -211,8 +211,8 @@ describe('DocumentController', function () {
     })
 
     describe("when the document doesn't exist", function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectEntityUpdateHandler.promises.updateDocLines.rejects(
             new Errors.NotFoundError('document does not exist')
           )

+ 6 - 6
services/web/test/unit/src/Downloads/ProjectZipStreamManager.test.mjs

@@ -72,8 +72,8 @@ describe('ProjectZipStreamManager', function () {
 
   describe('createZipStreamForMultipleProjects', function () {
     describe('successfully', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.project_ids = ['project-1', 'project-2']
           ctx.zip_streams = {
             'project-1': new EventEmitter(),
@@ -154,8 +154,8 @@ describe('ProjectZipStreamManager', function () {
     })
 
     describe('with a project not existing', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.project_ids = ['project-1', 'wrong-id']
           ctx.project_names = {
             'project-1': 'Project One Name',
@@ -346,8 +346,8 @@ describe('ProjectZipStreamManager', function () {
   })
 
   describe('addAllDocsToArchive', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.docs = {
           '/main.tex': {
             lines: [

+ 10 - 10
services/web/test/unit/src/Exports/ExportsController.test.mjs

@@ -65,8 +65,8 @@ describe('ExportsController', function () {
   })
 
   describe('without gallery fields', function () {
-    it('should ask the handler to perform the export', function (ctx) {
-      return new Promise(resolve => {
+    it('should ask the handler to perform the export', async function (ctx) {
+      await new Promise(resolve => {
         ctx.handler.exportProject = sinon
           .stub()
           .yields(null, { iAmAnExport: true, v1_id: 897 })
@@ -92,8 +92,8 @@ describe('ExportsController', function () {
   })
 
   describe('with a message from v1', function () {
-    it('should ask the handler to perform the export', function (ctx) {
-      return new Promise(resolve => {
+    it('should ask the handler to perform the export', async function (ctx) {
+      await new Promise(resolve => {
         ctx.handler.exportProject = sinon.stub().yields(null, {
           iAmAnExport: true,
           v1_id: 897,
@@ -129,8 +129,8 @@ describe('ExportsController', function () {
       return (ctx.req.body.showSource = true)
     })
 
-    it('should ask the handler to perform the export', function (ctx) {
-      return new Promise(resolve => {
+    it('should ask the handler to perform the export', async function (ctx) {
+      await new Promise(resolve => {
         ctx.handler.exportProject = sinon
           .stub()
           .yields(null, { iAmAnExport: true, v1_id: 897 })
@@ -161,8 +161,8 @@ describe('ExportsController', function () {
   })
 
   describe('with an error return from v1 to forward to the publish modal', function () {
-    it('should forward the response onward', function (ctx) {
-      return new Promise(resolve => {
+    it('should forward the response onward', async function (ctx) {
+      await new Promise(resolve => {
         ctx.error_json = { status: 422, message: 'nope' }
         ctx.handler.exportProject = sinon
           .stub()
@@ -175,8 +175,8 @@ describe('ExportsController', function () {
     })
   })
 
-  it('should ask the handler to return the status of an export', function (ctx) {
-    return new Promise(resolve => {
+  it('should ask the handler to return the status of an export', async function (ctx) {
+    await new Promise(resolve => {
       ctx.handler.fetchExport = sinon.stub().yields(
         null,
         `{

+ 41 - 40
services/web/test/unit/src/Exports/ExportsHandler.test.mjs

@@ -81,8 +81,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ExportsHandler.exportProject(
             ctx.export_params,
             (error, exportData) => {
@@ -111,8 +111,8 @@ describe('ExportsHandler', function () {
     })
 
     describe("when request can't be built", function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ExportsHandler._buildExport = sinon
             .stub()
             .yields(new Error('cannot export project without root doc'))
@@ -132,8 +132,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when export request returns an error to forward to the user', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.error_json = { status: 422, message: 'nope' }
           ctx.ExportsHandler._requestExport = sinon
             .stub()
@@ -158,8 +158,8 @@ describe('ExportsHandler', function () {
   })
 
   describe('_buildExport', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.project = {
           id: ctx.project_id,
           rootDoc_id: 'doc1_id',
@@ -202,8 +202,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ExportsHandler._buildExport(
             ctx.export_params,
             (error, exportData) => {
@@ -262,8 +262,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when we send replacement user first and last name', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.custom_first_name = 'FIRST'
           ctx.custom_last_name = 'LAST'
           ctx.export_params.first_name = ctx.custom_first_name
@@ -316,8 +316,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when project is not found', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ProjectGetter.getProject = sinon
             .stub()
             .yields(new Error('project not found'))
@@ -338,8 +338,8 @@ describe('ExportsHandler', function () {
 
     describe('when project has no root doc', function () {
       describe('when a root doc can be set automatically', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.project.rootDoc_id = null
             ctx.ProjectLocator.findRootDoc = sinon
               .stub()
@@ -400,8 +400,8 @@ describe('ExportsHandler', function () {
 
     describe('when project has an invalid root doc', function () {
       describe('when a new root doc can be set automatically', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.fakeDoc_id = '1a2b3c4d5e6f'
             ctx.project.rootDoc_id = ctx.fakeDoc_id
             ctx.ProjectLocator.findRootDoc = sinon
@@ -461,8 +461,8 @@ describe('ExportsHandler', function () {
       })
 
       describe('when no root doc can be identified', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.ProjectLocator.findRootDoc = sinon
               .stub()
               .yields(null, [null, null])
@@ -483,8 +483,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when user is not found', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.UserGetter.getUser = sinon
             .stub()
             .yields(new Error('user not found'))
@@ -504,8 +504,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when project history request fails', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.ExportsHandler._requestVersion = sinon
             .stub()
             .yields(new Error('project history call failed'))
@@ -526,8 +526,8 @@ describe('ExportsHandler', function () {
   })
 
   describe('_requestExport', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.settings.apis = {
           v1: {
             url: 'http://127.0.0.1:5000',
@@ -546,8 +546,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.stubRequest.post = ctx.stubPost
           ctx.ExportsHandler._requestExport(
             ctx.export_data,
@@ -579,8 +579,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when the request fails', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.stubRequest.post = sinon
             .stub()
             .yields(new Error('export request failed'))
@@ -600,13 +600,14 @@ describe('ExportsHandler', function () {
     })
 
     describe('when the request returns an error response to forward', function () {
-      beforeEach(function (ctx) {
+      beforeEach(async function (ctx) {
         ctx.error_code = 422
         ctx.error_json = { status: ctx.error_code, message: 'nope' }
         ctx.stubRequest.post = sinon
           .stub()
           .yields(null, { statusCode: ctx.error_code }, ctx.error_json)
-        return new Promise(resolve => {
+
+        await new Promise(resolve => {
           ctx.ExportsHandler._requestExport(
             ctx.export_data,
             (error, exportV1Id) => {
@@ -627,8 +628,8 @@ describe('ExportsHandler', function () {
   })
 
   describe('fetchExport', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.settings.apis = {
           v1: {
             url: 'http://127.0.0.1:5000',
@@ -647,8 +648,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.stubRequest.get = ctx.stubGet
           ctx.ExportsHandler.fetchExport(ctx.export_id, (error, body) => {
             ctx.callback(error, body)
@@ -678,8 +679,8 @@ describe('ExportsHandler', function () {
   })
 
   describe('fetchDownload', function () {
-    beforeEach(function (ctx) {
-      return new Promise(resolve => {
+    beforeEach(async function (ctx) {
+      await new Promise(resolve => {
         ctx.settings.apis = {
           v1: {
             url: 'http://127.0.0.1:5000',
@@ -699,8 +700,8 @@ describe('ExportsHandler', function () {
     })
 
     describe('when all goes well', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.stubRequest.get = ctx.stubGet
           ctx.ExportsHandler.fetchDownload(
             ctx.export_id,

+ 4 - 4
services/web/test/unit/src/FileStore/FileStoreController.test.mjs

@@ -214,8 +214,8 @@ describe('FileStoreController', function () {
       ctx.ProjectLocator.promises.findElement.resolves({ element: ctx.file })
     })
 
-    it('reports the file size', function (ctx) {
-      return new Promise(resolve => {
+    it('reports the file size', async function (ctx) {
+      await new Promise(resolve => {
         const expectedFileSize = 99393
         ctx.FileStoreHandler.promises.getFileSize.rejects(
           new Error('getFileSize: unexpected arguments')
@@ -237,8 +237,8 @@ describe('FileStoreController', function () {
       })
     })
 
-    it('returns 404 on NotFoundError', function (ctx) {
-      return new Promise(resolve => {
+    it('returns 404 on NotFoundError', async function (ctx) {
+      await new Promise(resolve => {
         ctx.FileStoreHandler.promises.getFileSize.rejects(
           new Errors.NotFoundError()
         )

+ 4 - 4
services/web/test/unit/src/LinkedFiles/LinkedFilesController.test.mjs

@@ -132,8 +132,8 @@ describe('LinkedFilesController', function () {
       ctx.next = sinon.stub()
     })
 
-    it('sets importedAt timestamp on linkedFileData', function (ctx) {
-      return new Promise(resolve => {
+    it('sets importedAt timestamp on linkedFileData', async function (ctx) {
+      await new Promise(resolve => {
         ctx.next = sinon.stub().callsFake(() => resolve('unexpected error'))
         ctx.res = {
           json: () => {
@@ -177,8 +177,8 @@ describe('LinkedFilesController', function () {
       ctx.next = sinon.stub()
     })
 
-    it('resets importedAt timestamp on linkedFileData', function (ctx) {
-      return new Promise(resolve => {
+    it('resets importedAt timestamp on linkedFileData', async function (ctx) {
+      await new Promise(resolve => {
         ctx.next = sinon.stub().callsFake(() => resolve('unexpected error'))
         ctx.res = {
           json: () => {

+ 6 - 6
services/web/test/unit/src/Notifications/NotificationsController.test.mjs

@@ -52,8 +52,8 @@ describe('NotificationsController', function () {
     ctx.controller = (await import(modulePath)).default
   })
 
-  it('should ask the handler for all unread notifications', function (ctx) {
-    return new Promise(resolve => {
+  it('should ask the handler for all unread notifications', async function (ctx) {
+    await new Promise(resolve => {
       const allNotifications = [{ _id: notificationId, user_id: userId }]
       ctx.handler.getUserNotifications = sinon
         .stub()
@@ -68,8 +68,8 @@ describe('NotificationsController', function () {
     })
   })
 
-  it('should send a delete request when a delete has been received to mark a notification', function (ctx) {
-    return new Promise(resolve => {
+  it('should send a delete request when a delete has been received to mark a notification', async function (ctx) {
+    await new Promise(resolve => {
       ctx.controller.markNotificationAsRead(ctx.req, {
         sendStatus: () => {
           ctx.handler.markAsRead
@@ -81,8 +81,8 @@ describe('NotificationsController', function () {
     })
   })
 
-  it('should get a notification by notification id', function (ctx) {
-    return new Promise(resolve => {
+  it('should get a notification by notification id', async function (ctx) {
+    await new Promise(resolve => {
       const notification = { _id: notificationId, user_id: userId }
       ctx.handler.getUserNotifications = sinon
         .stub()

+ 52 - 52
services/web/test/unit/src/PasswordReset/PasswordResetController.test.mjs

@@ -123,8 +123,8 @@ describe('PasswordResetController', function () {
   })
 
   describe('requestReset', function () {
-    it('should tell the handler to process that email', function (ctx) {
-      return new Promise(resolve => {
+    it('should tell the handler to process that email', async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.generateAndEmailResetToken.resolves(
           'primary'
         )
@@ -141,8 +141,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should send a 500 if there is an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should send a 500 if there is an error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.generateAndEmailResetToken.rejects(
           new Error('error')
         )
@@ -153,8 +153,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it("should send a 404 if the email doesn't exist", function (ctx) {
-      return new Promise(resolve => {
+    it("should send a 404 if the email doesn't exist", async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.generateAndEmailResetToken.resolves(
           null
         )
@@ -167,8 +167,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should send a 404 if the email is registered as a secondard email', function (ctx) {
-      return new Promise(resolve => {
+    it('should send a 404 if the email is registered as a secondard email', async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.generateAndEmailResetToken.resolves(
           'secondary'
         )
@@ -181,8 +181,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should normalize the email address', function (ctx) {
-      return new Promise(resolve => {
+    it('should normalize the email address', async function (ctx) {
+      await new Promise(resolve => {
         ctx.email = '  UPperCaseEMAILWithSpacesAround@example.Com '
         ctx.req.body.email = ctx.email
         ctx.PasswordResetHandler.promises.generateAndEmailResetToken.resolves(
@@ -203,8 +203,8 @@ describe('PasswordResetController', function () {
       ctx.req.session.resetToken = ctx.token
     })
 
-    it('should tell the user handler to reset the password', function (ctx) {
-      return new Promise(resolve => {
+    it('should tell the user handler to reset the password', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.sendStatus = code => {
           code.should.equal(200)
           ctx.PasswordResetHandler.promises.setNewUserPassword
@@ -216,8 +216,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should preserve spaces in the password', function (ctx) {
-      return new Promise(resolve => {
+    it('should preserve spaces in the password', async function (ctx) {
+      await new Promise(resolve => {
         ctx.password = ctx.req.body.password = ' oh! clever! spaces around!   '
         ctx.res.sendStatus = code => {
           code.should.equal(200)
@@ -231,8 +231,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should send 404 if the token was not found', function (ctx) {
-      return new Promise(resolve => {
+    it('should send 404 if the token was not found', async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.setNewUserPassword.resolves({
           found: false,
           reset: false,
@@ -250,8 +250,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should return 500 if not reset', function (ctx) {
-      return new Promise(resolve => {
+    it('should return 500 if not reset', async function (ctx) {
+      await new Promise(resolve => {
         ctx.PasswordResetHandler.promises.setNewUserPassword.resolves({
           found: true,
           reset: false,
@@ -269,8 +269,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should return 400 (Bad Request) if there is no password', function (ctx) {
-      return new Promise(resolve => {
+    it('should return 400 (Bad Request) if there is no password', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body.password = ''
         ctx.res.status = code => {
           code.should.equal(400)
@@ -287,8 +287,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should return 400 (Bad Request) if there is no passwordResetToken', function (ctx) {
-      return new Promise(resolve => {
+    it('should return 400 (Bad Request) if there is no passwordResetToken', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body.passwordResetToken = ''
         ctx.res.status = code => {
           code.should.equal(400)
@@ -305,8 +305,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should return 400 (Bad Request) if the password is invalid', function (ctx) {
-      return new Promise(resolve => {
+    it('should return 400 (Bad Request) if the password is invalid', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body.password = 'correct horse battery staple'
         const err = new Error('bad')
         err.name = 'InvalidPasswordError'
@@ -326,8 +326,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should clear sessions', function (ctx) {
-      return new Promise(resolve => {
+    it('should clear sessions', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.sendStatus = code => {
           ctx.UserSessionsManager.promises.removeSessionsFromRedis.callCount.should.equal(
             1
@@ -338,8 +338,8 @@ describe('PasswordResetController', function () {
       })
     })
 
-    it('should call removeReconfirmFlag if user.must_reconfirm', function (ctx) {
-      return new Promise(resolve => {
+    it('should call removeReconfirmFlag if user.must_reconfirm', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.sendStatus = code => {
           ctx.UserUpdater.promises.removeReconfirmFlag.callCount.should.equal(1)
           resolve()
@@ -349,8 +349,8 @@ describe('PasswordResetController', function () {
     })
 
     describe('catch errors', function () {
-      it('should return 404 for NotFoundError', function (ctx) {
-        return new Promise(resolve => {
+      it('should return 404 for NotFoundError', async function (ctx) {
+        await new Promise(resolve => {
           const anError = new Error('oops')
           anError.name = 'NotFoundError'
           ctx.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
@@ -365,8 +365,8 @@ describe('PasswordResetController', function () {
           ctx.PasswordResetController.setNewUserPassword(ctx.req, ctx.res)
         })
       })
-      it('should return 400 for InvalidPasswordError', function (ctx) {
-        return new Promise(resolve => {
+      it('should return 400 for InvalidPasswordError', async function (ctx) {
+        await new Promise(resolve => {
           const anError = new Error('oops')
           anError.name = 'InvalidPasswordError'
           ctx.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
@@ -381,8 +381,8 @@ describe('PasswordResetController', function () {
           ctx.PasswordResetController.setNewUserPassword(ctx.req, ctx.res)
         })
       })
-      it('should return 500 for other errors', function (ctx) {
-        return new Promise(resolve => {
+      it('should return 500 for other errors', async function (ctx) {
+        await new Promise(resolve => {
           const anError = new Error('oops')
           ctx.PasswordResetHandler.promises.setNewUserPassword.rejects(anError)
           ctx.res.status = code => {
@@ -412,8 +412,8 @@ describe('PasswordResetController', function () {
         ctx.req.session.doLoginAfterPasswordReset = 'true'
       })
 
-      it('should login user', function (ctx) {
-        return new Promise(resolve => {
+      it('should login user', async function (ctx) {
+        await new Promise(resolve => {
           ctx.AuthenticationController.finishLogin.callsFake((...args) => {
             expect(args[0]).to.equal(ctx.user)
             resolve()
@@ -430,8 +430,8 @@ describe('PasswordResetController', function () {
         ctx.req.query.passwordResetToken = ctx.token
       })
 
-      it('should set session.resetToken and redirect', function (ctx) {
-        return new Promise(resolve => {
+      it('should set session.resetToken and redirect', async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.session.should.not.have.property('resetToken')
           ctx.res.redirect = path => {
             path.should.equal('/user/password/set')
@@ -452,8 +452,8 @@ describe('PasswordResetController', function () {
           .resolves({ user: { _id: ctx.user_id }, remainingPeeks: 0 })
       })
 
-      it('should redirect to the reset request page with an error message', function (ctx) {
-        return new Promise(resolve => {
+      it('should redirect to the reset request page with an error message', async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.redirect = path => {
             path.should.equal('/user/password/reset?error=token_expired')
             ctx.req.session.should.not.have.property('resetToken')
@@ -473,8 +473,8 @@ describe('PasswordResetController', function () {
         ctx.req.query.email = 'foo@bar.com'
       })
 
-      it('should set session.resetToken and redirect with email', function (ctx) {
-        return new Promise(resolve => {
+      it('should set session.resetToken and redirect with email', async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.session.should.not.have.property('resetToken')
           ctx.res.redirect = path => {
             path.should.equal('/user/password/set?email=foo%40bar.com')
@@ -492,8 +492,8 @@ describe('PasswordResetController', function () {
         ctx.req.query.email = 'not-an-email'
       })
 
-      it('should set session.resetToken and redirect without email', function (ctx) {
-        return new Promise(resolve => {
+      it('should set session.resetToken and redirect without email', async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.session.should.not.have.property('resetToken')
           ctx.res.redirect = path => {
             path.should.equal('/user/password/set')
@@ -511,8 +511,8 @@ describe('PasswordResetController', function () {
         ctx.req.query.email = { foo: 'bar' }
       })
 
-      it('should set session.resetToken and redirect without email', function (ctx) {
-        return new Promise(resolve => {
+      it('should set session.resetToken and redirect without email', async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.session.should.not.have.property('resetToken')
           ctx.res.redirect = path => {
             path.should.equal('/user/password/set')
@@ -530,8 +530,8 @@ describe('PasswordResetController', function () {
           ctx.req.session.resetToken = ctx.token
         })
 
-        it('should render the page, passing the reset token', function (ctx) {
-          return new Promise(resolve => {
+        it('should render the page, passing the reset token', async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.render = (templatePath, options) => {
               options.passwordResetToken.should.equal(ctx.token)
               resolve()
@@ -540,8 +540,8 @@ describe('PasswordResetController', function () {
           })
         })
 
-        it('should clear the req.session.resetToken', function (ctx) {
-          return new Promise(resolve => {
+        it('should clear the req.session.resetToken', async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.render = (templatePath, options) => {
               ctx.req.session.should.not.have.property('resetToken')
               resolve()
@@ -552,8 +552,8 @@ describe('PasswordResetController', function () {
       })
 
       describe('without a token in session', function () {
-        it('should redirect to the reset request page', function (ctx) {
-          return new Promise(resolve => {
+        it('should redirect to the reset request page', async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.redirect = path => {
               path.should.equal('/user/password/reset')
               ctx.req.session.should.not.have.property('resetToken')

+ 26 - 26
services/web/test/unit/src/PasswordReset/PasswordResetHandler.test.mjs

@@ -103,8 +103,8 @@ describe('PasswordResetHandler', function () {
       )
     })
 
-    it('should send the email with the token', function (ctx) {
-      return new Promise(resolve => {
+    it('should send the email with the token', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserGetter.promises.getUserByAnyEmail.resolves(ctx.user)
         ctx.OneTimeTokenHandler.promises.getNewToken.resolves(ctx.token)
         ctx.EmailHandler.promises.sendEmail.resolves()
@@ -127,8 +127,8 @@ describe('PasswordResetHandler', function () {
       })
     })
 
-    it('should return errors from getUserByAnyEmail', function (ctx) {
-      return new Promise(resolve => {
+    it('should return errors from getUserByAnyEmail', async function (ctx) {
+      await new Promise(resolve => {
         const err = new Error('oops')
         ctx.UserGetter.promises.getUserByAnyEmail.rejects(err)
         ctx.PasswordResetHandler.generateAndEmailResetToken(
@@ -273,8 +273,8 @@ describe('PasswordResetHandler', function () {
             .yields(null, null)
         })
 
-        it('should return found == false and reset == false', function (ctx) {
-          return new Promise(resolve => {
+        it('should return found == false and reset == false', async function (ctx) {
+          await new Promise(resolve => {
             ctx.PasswordResetHandler.setNewUserPassword(
               ctx.token,
               ctx.password,
@@ -302,8 +302,8 @@ describe('PasswordResetHandler', function () {
           ctx.OneTimeTokenHandler.expireToken.callsArgWith(2, null)
         })
 
-        it('should return found == false and reset == false', function (ctx) {
-          return new Promise(resolve => {
+        it('should return found == false and reset == false', async function (ctx) {
+          await new Promise(resolve => {
             ctx.PasswordResetHandler.setNewUserPassword(
               ctx.token,
               ctx.password,
@@ -332,8 +332,8 @@ describe('PasswordResetHandler', function () {
               .callsArgWith(2, null)
           })
 
-          it('should update the user audit log', function (ctx) {
-            return new Promise(resolve => {
+          it('should update the user audit log', async function (ctx) {
+            await new Promise(resolve => {
               ctx.PasswordResetHandler.setNewUserPassword(
                 ctx.token,
                 ctx.password,
@@ -354,8 +354,8 @@ describe('PasswordResetHandler', function () {
             })
           })
 
-          it('should return reset == true and the user id', function (ctx) {
-            return new Promise(resolve => {
+          it('should return reset == true and the user id', async function (ctx) {
+            await new Promise(resolve => {
               ctx.PasswordResetHandler.setNewUserPassword(
                 ctx.token,
                 ctx.password,
@@ -371,8 +371,8 @@ describe('PasswordResetHandler', function () {
             })
           })
 
-          it('should expire the token', function (ctx) {
-            return new Promise(resolve => {
+          it('should expire the token', async function (ctx) {
+            await new Promise(resolve => {
               ctx.PasswordResetHandler.setNewUserPassword(
                 ctx.token,
                 ctx.password,
@@ -391,8 +391,8 @@ describe('PasswordResetHandler', function () {
             beforeEach(function (ctx) {
               ctx.auditLog.initiatorId = ctx.user_id
             })
-            it('should update the user audit log with initiatorId', function (ctx) {
-              return new Promise(resolve => {
+            it('should update the user audit log with initiatorId', async function (ctx) {
+              await new Promise(resolve => {
                 ctx.PasswordResetHandler.setNewUserPassword(
                   ctx.token,
                   ctx.password,
@@ -424,8 +424,8 @@ describe('PasswordResetHandler', function () {
                 .withArgs(ctx.user, ctx.password)
                 .rejects()
             })
-            it('should return the error', function (ctx) {
-              return new Promise(resolve => {
+            it('should return the error', async function (ctx) {
+              await new Promise(resolve => {
                 ctx.PasswordResetHandler.setNewUserPassword(
                   ctx.token,
                   ctx.password,
@@ -450,8 +450,8 @@ describe('PasswordResetHandler', function () {
                 new Error('oops')
               )
             })
-            it('should return the error', function (ctx) {
-              return new Promise(resolve => {
+            it('should return the error', async function (ctx) {
+              await new Promise(resolve => {
                 ctx.PasswordResetHandler.setNewUserPassword(
                   ctx.token,
                   ctx.password,
@@ -495,8 +495,8 @@ describe('PasswordResetHandler', function () {
             .yields(null, null)
         })
 
-        it('should return reset == false', function (ctx) {
-          return new Promise(resolve => {
+        it('should return reset == false', async function (ctx) {
+          await new Promise(resolve => {
             ctx.PasswordResetHandler.setNewUserPassword(
               ctx.token,
               ctx.password,
@@ -524,8 +524,8 @@ describe('PasswordResetHandler', function () {
           })
         })
 
-        it('should return reset == false', function (ctx) {
-          return new Promise(resolve => {
+        it('should return reset == false', async function (ctx) {
+          await new Promise(resolve => {
             ctx.PasswordResetHandler.setNewUserPassword(
               ctx.token,
               ctx.password,
@@ -549,8 +549,8 @@ describe('PasswordResetHandler', function () {
           ctx.UserGetter.promises.getUserByMainEmail.resolves(ctx.user)
         })
 
-        it('should return reset == true and the user id', function (ctx) {
-          return new Promise(resolve => {
+        it('should return reset == true and the user id', async function (ctx) {
+          await new Promise(resolve => {
             ctx.PasswordResetHandler.setNewUserPassword(
               ctx.token,
               ctx.password,

+ 2 - 2
services/web/test/unit/src/Project/ProjectApiController.test.mjs

@@ -30,8 +30,8 @@ describe('Project api controller', function () {
   })
 
   describe('getProjectDetails', function () {
-    it('should ask the project details handler for proj details', function (ctx) {
-      return new Promise(resolve => {
+    it('should ask the project details handler for proj details', async function (ctx) {
+      await new Promise(resolve => {
         ctx.ProjectDetailsHandler.getDetails.callsArgWith(
           1,
           null,

+ 34 - 34
services/web/test/unit/src/Project/ProjectListController.test.mjs

@@ -322,8 +322,8 @@ describe('ProjectListController', function () {
       ctx.ProjectGetter.promises.findAllUsersProjects.resolves(ctx.allProjects)
     })
 
-    it('should render the project/list-react page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render the project/list-react page', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           pageName.should.equal('project/list-react')
           resolve()
@@ -332,8 +332,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should invoke the session maintenance', function (ctx) {
-      return new Promise(resolve => {
+    it('should invoke the session maintenance', async function (ctx) {
+      await new Promise(resolve => {
         ctx.Features.hasFeature.withArgs('saas').returns(true)
         ctx.res.render = () => {
           ctx.SplitTestSessionHandler.promises.sessionMaintenance.should.have.been.calledWith(
@@ -346,8 +346,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should send the tags', function (ctx) {
-      return new Promise(resolve => {
+    it('should send the tags', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           opts.tags.length.should.equal(ctx.tags.length)
           resolve()
@@ -356,8 +356,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should create trigger ip matcher notifications', function (ctx) {
-      return new Promise(resolve => {
+    it('should create trigger ip matcher notifications', async function (ctx) {
+      await new Promise(resolve => {
         ctx.settings.overleaf = true
         ctx.req.ip = '111.111.111.111'
         ctx.res.render = (pageName, opts) => {
@@ -370,8 +370,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should send the projects', function (ctx) {
-      return new Promise(resolve => {
+    it('should send the projects', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           opts.prefetchedProjectsBlob.projects.length.should.equal(
             ctx.projects.length +
@@ -387,8 +387,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should send the user', function (ctx) {
-      return new Promise(resolve => {
+    it('should send the user', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           opts.user.should.deep.equal(ctx.user)
           resolve()
@@ -397,8 +397,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should inject the users', function (ctx) {
-      return new Promise(resolve => {
+    it('should inject the users', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           const projects = opts.prefetchedProjectsBlob.projects
 
@@ -426,8 +426,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it("should send the user's best subscription when saas feature present", function (ctx) {
-      return new Promise(resolve => {
+    it("should send the user's best subscription when saas feature present", async function (ctx) {
+      await new Promise(resolve => {
         ctx.Features.hasFeature.withArgs('saas').returns(true)
         ctx.res.render = (pageName, opts) => {
           expect(opts.usersBestSubscription).to.deep.include({ type: 'free' })
@@ -437,8 +437,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should not return a best subscription without saas feature', function (ctx) {
-      return new Promise(resolve => {
+    it('should not return a best subscription without saas feature', async function (ctx) {
+      await new Promise(resolve => {
         ctx.Features.hasFeature.withArgs('saas').returns(false)
         ctx.res.render = (pageName, opts) => {
           expect(opts.usersBestSubscription).to.be.undefined
@@ -448,8 +448,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should show INR Banner for Indian users with free account', function (ctx) {
-      return new Promise(resolve => {
+    it('should show INR Banner for Indian users with free account', async function (ctx) {
+      await new Promise(resolve => {
         // usersBestSubscription is only available when saas feature is present
         ctx.Features.hasFeature.withArgs('saas').returns(true)
         ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
@@ -470,8 +470,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should not show INR Banner for Indian users with premium account', function (ctx) {
-      return new Promise(resolve => {
+    it('should not show INR Banner for Indian users with premium account', async function (ctx) {
+      await new Promise(resolve => {
         // usersBestSubscription is only available when saas feature is present
         ctx.Features.hasFeature.withArgs('saas').returns(true)
         ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
@@ -493,8 +493,8 @@ describe('ProjectListController', function () {
     })
 
     describe('With Institution SSO feature', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.institutionEmail = 'test@overleaf.com'
           ctx.institutionName = 'Overleaf'
           ctx.Features.hasFeature.withArgs('saml').returns(true)
@@ -624,8 +624,8 @@ describe('ProjectListController', function () {
       })
 
       describe('for an unconfirmed domain for an SSO institution', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.UserGetter.promises.getUserFullEmails.resolves([
               {
                 email: 'test@overleaf-uncofirmed.com',
@@ -673,8 +673,8 @@ describe('ProjectListController', function () {
         })
       })
       describe('Institution with SSO beta testable', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.UserGetter.promises.getUserFullEmails.resolves([
               {
                 email: 'beta@beta.com',
@@ -720,8 +720,8 @@ describe('ProjectListController', function () {
     })
 
     describe('Without Institution SSO feature', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.Features.hasFeature.withArgs('saml').returns(false)
           resolve()
         })
@@ -859,8 +859,8 @@ describe('ProjectListController', function () {
       ctx.ProjectGetter.promises.findAllUsersProjects.resolves(ctx.allProjects)
     })
 
-    it('should render the project/list-react page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render the project/list-react page', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           pageName.should.equal('project/list-react')
           resolve()
@@ -869,8 +869,8 @@ describe('ProjectListController', function () {
       })
     })
 
-    it('should omit one of the projects', function (ctx) {
-      return new Promise(resolve => {
+    it('should omit one of the projects', async function (ctx) {
+      await new Promise(resolve => {
         ctx.res.render = (pageName, opts) => {
           opts.prefetchedProjectsBlob.projects.length.should.equal(
             ctx.projects.length +

+ 22 - 22
services/web/test/unit/src/Referal/ReferalConnect.test.mjs

@@ -8,8 +8,8 @@ describe('Referal connect middle wear', function () {
     ctx.connect = (await import(modulePath)).default
   })
 
-  it('should take a referal query string and put it on the session if it exists', function (ctx) {
-    return new Promise(resolve => {
+  it('should take a referal query string and put it on the session if it exists', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { referal: '12345' },
         session: {},
@@ -21,8 +21,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should not change the referal_id on the session if not in query', function (ctx) {
-    return new Promise(resolve => {
+  it('should not change the referal_id on the session if not in query', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: {},
         session: { referal_id: 'same' },
@@ -34,8 +34,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should take a facebook referal query string and put it on the session if it exists', function (ctx) {
-    return new Promise(resolve => {
+  it('should take a facebook referal query string and put it on the session if it exists', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { fb_ref: '12345' },
         session: {},
@@ -47,8 +47,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the facebook medium into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the facebook medium into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rm: 'fb' },
         session: {},
@@ -60,8 +60,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the twitter medium into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the twitter medium into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rm: 't' },
         session: {},
@@ -73,8 +73,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the google plus medium into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the google plus medium into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rm: 'gp' },
         session: {},
@@ -86,8 +86,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the email medium into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the email medium into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rm: 'e' },
         session: {},
@@ -99,8 +99,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the direct medium into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the direct medium into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rm: 'd' },
         session: {},
@@ -112,8 +112,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the bonus source into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the bonus source into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rs: 'b' },
         session: {},
@@ -125,8 +125,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the public share source into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the public share source into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rs: 'ps' },
         session: {},
@@ -138,8 +138,8 @@ describe('Referal connect middle wear', function () {
     })
   })
 
-  it('should map the collaborator invite into the session', function (ctx) {
-    return new Promise(resolve => {
+  it('should map the collaborator invite into the session', async function (ctx) {
+    await new Promise(resolve => {
       const req = {
         query: { rs: 'ci' },
         session: {},

+ 24 - 24
services/web/test/unit/src/References/ReferencesController.test.mjs

@@ -61,8 +61,8 @@ describe('ReferencesController', function () {
       }
     })
 
-    it('should not produce an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not produce an error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.res.sendStatus.callCount.should.equal(0)
           ctx.res.sendStatus.calledWith(500).should.equal(false)
@@ -72,8 +72,8 @@ describe('ReferencesController', function () {
       })
     })
 
-    it('should return data', function (ctx) {
-      return new Promise(resolve => {
+    it('should return data', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.res.json.callCount.should.equal(1)
           ctx.res.json.calledWith(ctx.fakeResponseData).should.equal(true)
@@ -82,8 +82,8 @@ describe('ReferencesController', function () {
       })
     })
 
-    it('should call ReferencesHandler.indexAll', function (ctx) {
-      return new Promise(resolve => {
+    it('should call ReferencesHandler.indexAll', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.ReferencesHandler.indexAll.callCount.should.equal(1)
           ctx.ReferencesHandler.indexAll
@@ -100,8 +100,8 @@ describe('ReferencesController', function () {
         ctx.req.body.shouldBroadcast = true
       })
 
-      it('should call EditorRealTimeController.emitToRoom', function (ctx) {
-        return new Promise(resolve => {
+      it('should call EditorRealTimeController.emitToRoom', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.EditorRealTimeController.emitToRoom.callCount.should.equal(1)
             resolve()
@@ -109,8 +109,8 @@ describe('ReferencesController', function () {
         })
       })
 
-      it('should not produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should not produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.res.sendStatus.callCount.should.equal(0)
             ctx.res.sendStatus.calledWith(500).should.equal(false)
@@ -120,8 +120,8 @@ describe('ReferencesController', function () {
         })
       })
 
-      it('should still return data', function (ctx) {
-        return new Promise(resolve => {
+      it('should still return data', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.res.json.callCount.should.equal(1)
             ctx.res.json.calledWith(ctx.fakeResponseData).should.equal(true)
@@ -137,8 +137,8 @@ describe('ReferencesController', function () {
         ctx.req.body.shouldBroadcast = false
       })
 
-      it('should not call EditorRealTimeController.emitToRoom', function (ctx) {
-        return new Promise(resolve => {
+      it('should not call EditorRealTimeController.emitToRoom', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.EditorRealTimeController.emitToRoom.callCount.should.equal(0)
             resolve()
@@ -146,8 +146,8 @@ describe('ReferencesController', function () {
         })
       })
 
-      it('should not produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should not produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.res.sendStatus.callCount.should.equal(0)
             ctx.res.sendStatus.calledWith(500).should.equal(false)
@@ -157,8 +157,8 @@ describe('ReferencesController', function () {
         })
       })
 
-      it('should still return data', function (ctx) {
-        return new Promise(resolve => {
+      it('should still return data', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.res.json.callCount.should.equal(1)
             ctx.res.json.calledWith(ctx.fakeResponseData).should.equal(true)
@@ -178,8 +178,8 @@ describe('ReferencesController', function () {
       }
     })
 
-    it('should not call EditorRealTimeController.emitToRoom', function (ctx) {
-      return new Promise(resolve => {
+    it('should not call EditorRealTimeController.emitToRoom', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.EditorRealTimeController.emitToRoom.callCount.should.equal(0)
           resolve()
@@ -187,8 +187,8 @@ describe('ReferencesController', function () {
       })
     })
 
-    it('should not produce an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not produce an error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.res.sendStatus.callCount.should.equal(0)
           ctx.res.sendStatus.calledWith(500).should.equal(false)
@@ -198,8 +198,8 @@ describe('ReferencesController', function () {
       })
     })
 
-    it('should send a response with an empty keys list', function (ctx) {
-      return new Promise(resolve => {
+    it('should send a response with an empty keys list', async function (ctx) {
+      await new Promise(resolve => {
         ctx.call(() => {
           ctx.res.json.called.should.equal(true)
           ctx.res.json

+ 28 - 28
services/web/test/unit/src/References/ReferencesHandler.test.mjs

@@ -113,8 +113,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should call _findBibDocIds', function (ctx) {
-      return new Promise(resolve => {
+    it('should call _findBibDocIds', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.be.null
           ctx.handler._findBibDocIds.callCount.should.equal(1)
@@ -126,8 +126,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should call _findBibFileRefs', function (ctx) {
-      return new Promise(resolve => {
+    it('should call _findBibFileRefs', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.be.null
           ctx.handler._findBibDocIds.callCount.should.equal(1)
@@ -139,8 +139,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should call DocumentUpdaterHandler.flushDocToMongo', function (ctx) {
-      return new Promise(resolve => {
+    it('should call DocumentUpdaterHandler.flushDocToMongo', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.be.null
           ctx.DocumentUpdaterHandler.flushDocToMongo.callCount.should.equal(2)
@@ -149,8 +149,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should make a request to references service', function (ctx) {
-      return new Promise(resolve => {
+    it('should make a request to references service', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.be.null
           ctx.request.post.callCount.should.equal(1)
@@ -189,8 +189,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should not produce an error', function (ctx) {
-      return new Promise(resolve => {
+    it('should not produce an error', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.equal(null)
           return resolve()
@@ -198,8 +198,8 @@ describe('ReferencesHandler', function () {
       })
     })
 
-    it('should return data', function (ctx) {
-      return new Promise(resolve => {
+    it('should return data', async function (ctx) {
+      await new Promise(resolve => {
         return ctx.call((err, data) => {
           expect(err).to.be.null
           expect(data).to.not.equal(null)
@@ -215,8 +215,8 @@ describe('ReferencesHandler', function () {
         ctx.ProjectGetter.getProject.callsArgWith(2, new Error('woops'))
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call((err, data) => {
             expect(err).to.not.equal(null)
             expect(err).to.be.instanceof(Error)
@@ -226,8 +226,8 @@ describe('ReferencesHandler', function () {
         })
       })
 
-      it('should not send request', function (ctx) {
-        return new Promise(resolve => {
+      it('should not send request', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.request.post.callCount.should.equal(0)
             resolve()
@@ -241,8 +241,8 @@ describe('ReferencesHandler', function () {
         ctx.ProjectGetter.getProject.callsArgWith(2, null)
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call((err, data) => {
             expect(err).to.not.equal(null)
             expect(err).to.be.instanceof(Errors.NotFoundError)
@@ -252,8 +252,8 @@ describe('ReferencesHandler', function () {
         })
       })
 
-      it('should not send request', function (ctx) {
-        return new Promise(resolve => {
+      it('should not send request', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.request.post.callCount.should.equal(0)
             resolve()
@@ -268,8 +268,8 @@ describe('ReferencesHandler', function () {
         ctx.handler._isFullIndex.callsArgWith(1, new Error('woops'))
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call((err, data) => {
             expect(err).to.not.equal(null)
             expect(err).to.be.instanceof(Error)
@@ -279,8 +279,8 @@ describe('ReferencesHandler', function () {
         })
       })
 
-      it('should not send request', function (ctx) {
-        return new Promise(resolve => {
+      it('should not send request', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.request.post.callCount.should.equal(0)
             resolve()
@@ -299,8 +299,8 @@ describe('ReferencesHandler', function () {
         )
       })
 
-      it('should produce an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should produce an error', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call((err, data) => {
             expect(err).to.not.equal(null)
             expect(err).to.be.instanceof(Error)
@@ -310,8 +310,8 @@ describe('ReferencesHandler', function () {
         })
       })
 
-      it('should not send request', function (ctx) {
-        return new Promise(resolve => {
+      it('should not send request', async function (ctx) {
+        await new Promise(resolve => {
           ctx.call(() => {
             ctx.request.post.callCount.should.equal(0)
             resolve()

+ 59 - 58
services/web/test/unit/src/Subscription/SubscriptionGroupController.test.mjs

@@ -231,8 +231,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('removeUserFromGroup', function () {
-    it('should use the subscription id for the logged in user and take the user id from the params', function (ctx) {
-      return new Promise(resolve => {
+    it('should use the subscription id for the logged in user and take the user id from the params', async function (ctx) {
+      await new Promise(resolve => {
         const userIdToRemove = '31231'
         ctx.req.params = { user_id: userIdToRemove }
         ctx.req.entity = ctx.subscription
@@ -252,8 +252,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should log that the user has been removed', function (ctx) {
-      return new Promise(resolve => {
+    it('should log that the user has been removed', async function (ctx) {
+      await new Promise(resolve => {
         const userIdToRemove = '31231'
         ctx.req.params = { user_id: userIdToRemove }
         ctx.req.entity = ctx.subscription
@@ -275,8 +275,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should call the group SSO hooks with group SSO enabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should call the group SSO hooks with group SSO enabled', async function (ctx) {
+      await new Promise(resolve => {
         const userIdToRemove = '31231'
         ctx.req.params = { user_id: userIdToRemove }
         ctx.req.entity = ctx.subscription
@@ -304,8 +304,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should call the group SSO hooks with group SSO disabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should call the group SSO hooks with group SSO disabled', async function (ctx) {
+      await new Promise(resolve => {
         const userIdToRemove = '31231'
         ctx.req.params = { user_id: userIdToRemove }
         ctx.req.entity = ctx.subscription
@@ -328,8 +328,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('removeSelfFromGroup', function () {
-    it('gets subscription and remove user', function (ctx) {
-      return new Promise(resolve => {
+    it('gets subscription and remove user', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.query = { subscriptionId: ctx.subscriptionId }
         const memberUserIdToremove = 123456789
         ctx.req.session.user._id = memberUserIdToremove
@@ -356,8 +356,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should log that the user has left the subscription', function (ctx) {
-      return new Promise(resolve => {
+    it('should log that the user has left the subscription', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.query = { subscriptionId: ctx.subscriptionId }
         const memberUserIdToremove = '123456789'
         ctx.req.session.user._id = memberUserIdToremove
@@ -379,8 +379,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should call the group SSO hooks with group SSO enabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should call the group SSO hooks with group SSO enabled', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.query = { subscriptionId: ctx.subscriptionId }
         const memberUserIdToremove = '123456789'
         ctx.req.session.user._id = memberUserIdToremove
@@ -409,8 +409,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should call the group SSO hooks with group SSO disabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should call the group SSO hooks with group SSO disabled', async function (ctx) {
+      await new Promise(resolve => {
         const userIdToRemove = '31231'
         ctx.req.session.user._id = userIdToRemove
         ctx.req.params = { user_id: userIdToRemove }
@@ -434,8 +434,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('addSeatsToGroupSubscription', function () {
-    it('should render the "add seats" page', function (ctx) {
-      return new Promise((resolve, reject) => {
+    it('should render the "add seats" page', async function (ctx) {
+      await new Promise((resolve, reject) => {
         const res = {
           render: (page, props) => {
             ctx.SubscriptionGroupHandler.promises.getUsersGroupSubscriptionDetails
@@ -470,8 +470,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subscription page when getting subscription details fails', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to subscription page when getting subscription details fails', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.getUsersGroupSubscriptionDetails =
           sinon.stub().rejects()
 
@@ -486,8 +486,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subscription page when flexible licensing is not enabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to subscription page when flexible licensing is not enabled', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.ensureFlexibleLicensingEnabled =
           sinon.stub().rejects()
 
@@ -502,8 +502,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to missing billing information page when billing information is missing', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to missing billing information page when billing information is missing', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.checkBillingInfoExistence = sinon
           .stub()
           .throws(new ctx.Errors.MissingBillingInfoError())
@@ -521,8 +521,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subscription page when there is a pending change', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to subscription page when there is a pending change', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.ensureSubscriptionHasNoPendingChanges =
           sinon.stub().throws(new ctx.Errors.PendingChangeError())
 
@@ -537,8 +537,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subscription page when subscription is not active', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to subscription page when subscription is not active', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.ensureSubscriptionIsActive = sinon
           .stub()
           .rejects()
@@ -554,10 +554,11 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subscription page when subscription has pending invoice', function (ctx) {
+    it('should redirect to subscription page when subscription has pending invoice', async function (ctx) {
       ctx.SubscriptionGroupHandler.promises.ensureSubscriptionHasNoPastDueInvoice =
         sinon.stub().rejects()
-      return new Promise(resolve => {
+
+      await new Promise(resolve => {
         const res = {
           redirect: url => {
             url.should.equal('/user/subscription')
@@ -571,8 +572,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('previewAddSeatsSubscriptionChange', function () {
-    it('should preview "add seats" change', function (ctx) {
-      return new Promise(resolve => {
+    it('should preview "add seats" change', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = { adding: 2 }
 
         const res = {
@@ -589,8 +590,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should fail previewing "add seats" change', function (ctx) {
-      return new Promise(resolve => {
+    it('should fail previewing "add seats" change', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.previewAddSeatsSubscriptionChange =
           sinon.stub().rejects()
 
@@ -610,8 +611,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should fail previewing "add seats" change with SubtotalLimitExceededError', function (ctx) {
-      return new Promise(resolve => {
+    it('should fail previewing "add seats" change with SubtotalLimitExceededError', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = { adding: 2 }
         ctx.SubscriptionGroupHandler.promises.previewAddSeatsSubscriptionChange =
           sinon.stub().throws(new ctx.Errors.SubtotalLimitExceededError())
@@ -638,8 +639,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('createAddSeatsSubscriptionChange', function () {
-    it('should apply "add seats" change', function (ctx) {
-      return new Promise(resolve => {
+    it('should apply "add seats" change', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = { adding: 2 }
 
         const res = {
@@ -656,8 +657,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should fail applying "add seats" change', function (ctx) {
-      return new Promise(resolve => {
+    it('should fail applying "add seats" change', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.createAddSeatsSubscriptionChange =
           sinon.stub().rejects()
 
@@ -677,8 +678,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should fail applying "add seats" change with SubtotalLimitExceededError', function (ctx) {
-      return new Promise(resolve => {
+    it('should fail applying "add seats" change with SubtotalLimitExceededError', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = { adding: 2 }
         ctx.SubscriptionGroupHandler.promises.createAddSeatsSubscriptionChange =
           sinon.stub().throws(new ctx.Errors.SubtotalLimitExceededError())
@@ -705,8 +706,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('submitForm', function () {
-    it('should build and pass the request body to the sales submit handler', function (ctx) {
-      return new Promise(resolve => {
+    it('should build and pass the request body to the sales submit handler', async function (ctx) {
+      await new Promise(resolve => {
         const adding = 100
         const poNumber = 'PO123456'
         ctx.req.body = { adding, poNumber }
@@ -747,8 +748,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('subscriptionUpgradePage', function () {
-    it('should render "subscription upgrade" page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render "subscription upgrade" page', async function (ctx) {
+      await new Promise(resolve => {
         const olSubscription = { membersLimit: 1, teamName: 'test team' }
         ctx.SubscriptionModel.Subscription.findOne = () => {
           return {
@@ -773,8 +774,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect if failed to generate preview', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect if failed to generate preview', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.getGroupPlanUpgradePreview = sinon
           .stub()
           .rejects()
@@ -790,8 +791,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to missing billing information page when billing information is missing', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to missing billing information page when billing information is missing', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.getGroupPlanUpgradePreview = sinon
           .stub()
           .throws(new ctx.Errors.MissingBillingInfoError())
@@ -809,8 +810,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to manually collected subscription error page when collection method is manual', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to manually collected subscription error page when collection method is manual', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.getGroupPlanUpgradePreview = sinon
           .stub()
           .throws(new ctx.Errors.ManuallyCollectedError())
@@ -828,8 +829,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should redirect to subtotal limit exceeded page', function (ctx) {
-      return new Promise(resolve => {
+    it('should redirect to subtotal limit exceeded page', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.getGroupPlanUpgradePreview = sinon
           .stub()
           .throws(new ctx.Errors.SubtotalLimitExceededError())
@@ -847,8 +848,8 @@ describe('SubscriptionGroupController', function () {
   })
 
   describe('upgradeSubscription', function () {
-    it('should send 200 response', function (ctx) {
-      return new Promise(resolve => {
+    it('should send 200 response', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.upgradeGroupPlan = sinon
           .stub()
           .resolves()
@@ -864,8 +865,8 @@ describe('SubscriptionGroupController', function () {
       })
     })
 
-    it('should send 500 response', function (ctx) {
-      return new Promise(resolve => {
+    it('should send 500 response', async function (ctx) {
+      await new Promise(resolve => {
         ctx.SubscriptionGroupHandler.promises.upgradeGroupPlan = sinon
           .stub()
           .rejects()

+ 14 - 14
services/web/test/unit/src/Subscription/TeamInvitesController.test.mjs

@@ -144,8 +144,8 @@ describe('TeamInvitesController', function () {
   })
 
   describe('acceptInvite', function () {
-    it('should add an audit log entry', function (ctx) {
-      return new Promise(resolve => {
+    it('should add an audit log entry', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.params.token = 'foo'
         ctx.req.session.user = ctx.user
         const res = {
@@ -176,8 +176,8 @@ describe('TeamInvitesController', function () {
     }
 
     describe('hasIndividualPaidSubscription', function () {
-      it('is true for personal subscription', function (ctx) {
-        return new Promise(resolve => {
+      it('is true for personal subscription', async function (ctx) {
+        await new Promise(resolve => {
           ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
             recurlySubscription_id: 'subscription123',
             groupPlan: false,
@@ -192,8 +192,8 @@ describe('TeamInvitesController', function () {
         })
       })
 
-      it('is true for group subscriptions', function (ctx) {
-        return new Promise(resolve => {
+      it('is true for group subscriptions', async function (ctx) {
+        await new Promise(resolve => {
           ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
             recurlySubscription_id: 'subscription123',
             groupPlan: true,
@@ -208,8 +208,8 @@ describe('TeamInvitesController', function () {
         })
       })
 
-      it('is false for canceled subscriptions', function (ctx) {
-        return new Promise(resolve => {
+      it('is false for canceled subscriptions', async function (ctx) {
+        await new Promise(resolve => {
           ctx.SubscriptionLocator.promises.getUsersSubscription.resolves({
             recurlySubscription_id: 'subscription123',
             groupPlan: false,
@@ -229,8 +229,8 @@ describe('TeamInvitesController', function () {
     })
 
     describe('when user is logged out', function () {
-      it('renders logged out invite page', function (ctx) {
-        return new Promise(resolve => {
+      it('renders logged out invite page', async function (ctx) {
+        await new Promise(resolve => {
           const res = {
             render: (template, data) => {
               expect(template).to.equal('subscriptions/team/invite_logged_out')
@@ -245,8 +245,8 @@ describe('TeamInvitesController', function () {
         })
       })
 
-      it('includes groupSSOActive flag when the group has SSO enabled', function (ctx) {
-        return new Promise(resolve => {
+      it('includes groupSSOActive flag when the group has SSO enabled', async function (ctx) {
+        await new Promise(resolve => {
           ctx.Modules.promises.hooks.fire = sinon.stub().resolves([true])
           const res = {
             render: (template, data) => {
@@ -262,8 +262,8 @@ describe('TeamInvitesController', function () {
       })
     })
 
-    it('renders the view', function (ctx) {
-      return new Promise(resolve => {
+    it('renders the view', async function (ctx) {
+      await new Promise(resolve => {
         const res = {
           render: template => {
             expect(template).to.equal('subscriptions/team/invite')

+ 22 - 22
services/web/test/unit/src/Tags/TagsController.test.mjs

@@ -56,8 +56,8 @@ describe('TagsController', function () {
     ctx.res.json = sinon.stub()
   })
 
-  it('get all tags', function (ctx) {
-    return new Promise(resolve => {
+  it('get all tags', async function (ctx) {
+    await new Promise(resolve => {
       const allTags = [{ name: 'tag', projects: ['123423', '423423'] }]
       ctx.TagsHandler.promises.getAllTags = sinon.stub().resolves(allTags)
       ctx.TagsController.getAllTags(ctx.req, {
@@ -74,8 +74,8 @@ describe('TagsController', function () {
   })
 
   describe('create a tag', function (done) {
-    it('without a color', function (ctx) {
-      return new Promise(resolve => {
+    it('without a color', async function (ctx) {
+      await new Promise(resolve => {
         ctx.tag = { mock: 'tag' }
         ctx.TagsHandler.promises.createTag = sinon.stub().resolves(ctx.tag)
         ctx.req.session.user._id = ctx.userId = 'user-id-123'
@@ -96,8 +96,8 @@ describe('TagsController', function () {
       })
     })
 
-    it('with a color', function (ctx) {
-      return new Promise(resolve => {
+    it('with a color', async function (ctx) {
+      await new Promise(resolve => {
         ctx.tag = { mock: 'tag' }
         ctx.TagsHandler.promises.createTag = sinon.stub().resolves(ctx.tag)
         ctx.req.session.user._id = ctx.userId = 'user-id-123'
@@ -123,8 +123,8 @@ describe('TagsController', function () {
     })
   })
 
-  it('delete a tag', function (ctx) {
-    return new Promise(resolve => {
+  it('delete a tag', async function (ctx) {
+    await new Promise(resolve => {
       ctx.req.params.tagId = ctx.tagId = 'tag-id-123'
       ctx.req.session.user._id = ctx.userId = 'user-id-123'
       ctx.TagsController.deleteTag(ctx.req, {
@@ -150,8 +150,8 @@ describe('TagsController', function () {
       ctx.req.session.user._id = ctx.userId = 'user-id-123'
     })
 
-    it('with a name and no color', function (ctx) {
-      return new Promise(resolve => {
+    it('with a name and no color', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = {
           name: (ctx.tagName = 'new-name'),
         }
@@ -173,8 +173,8 @@ describe('TagsController', function () {
       })
     })
 
-    it('with a name and color', function (ctx) {
-      return new Promise(resolve => {
+    it('with a name and color', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = {
           name: (ctx.tagName = 'new-name'),
           color: (ctx.color = '#FF0011'),
@@ -198,8 +198,8 @@ describe('TagsController', function () {
       })
     })
 
-    it('without a name', function (ctx) {
-      return new Promise(resolve => {
+    it('without a name', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body = { name: undefined }
         ctx.TagsController.renameTag(ctx.req, {
           status: code => {
@@ -215,8 +215,8 @@ describe('TagsController', function () {
     })
   })
 
-  it('add a project to a tag', function (ctx) {
-    return new Promise(resolve => {
+  it('add a project to a tag', async function (ctx) {
+    await new Promise(resolve => {
       ctx.req.params.tagId = ctx.tagId = 'tag-id-123'
       ctx.req.params.projectId = ctx.projectId = 'project-id-123'
       ctx.req.session.user._id = ctx.userId = 'user-id-123'
@@ -238,8 +238,8 @@ describe('TagsController', function () {
     })
   })
 
-  it('add projects to a tag', function (ctx) {
-    return new Promise(resolve => {
+  it('add projects to a tag', async function (ctx) {
+    await new Promise(resolve => {
       ctx.req.params.tagId = ctx.tagId = 'tag-id-123'
       ctx.req.body.projectIds = ctx.projectIds = [
         'project-id-123',
@@ -264,8 +264,8 @@ describe('TagsController', function () {
     })
   })
 
-  it('remove a project from a tag', function (ctx) {
-    return new Promise(resolve => {
+  it('remove a project from a tag', async function (ctx) {
+    await new Promise(resolve => {
       ctx.req.params.tagId = ctx.tagId = 'tag-id-123'
       ctx.req.params.projectId = ctx.projectId = 'project-id-123'
       ctx.req.session.user._id = ctx.userId = 'user-id-123'
@@ -287,8 +287,8 @@ describe('TagsController', function () {
     })
   })
 
-  it('remove projects from a tag', function (ctx) {
-    return new Promise(resolve => {
+  it('remove projects from a tag', async function (ctx) {
+    await new Promise(resolve => {
       ctx.req.params.tagId = ctx.tagId = 'tag-id-123'
       ctx.req.body.projectIds = ctx.projectIds = [
         'project-id-123',

+ 28 - 28
services/web/test/unit/src/ThirdPartyDataStore/TpdsController.test.mjs

@@ -116,8 +116,8 @@ describe('TpdsController', function () {
   })
 
   describe('creating a project', function () {
-    it('should yield the new projects id', function (ctx) {
-      return new Promise(resolve => {
+    it('should yield the new projects id', async function (ctx) {
+      await new Promise(resolve => {
         const res = new MockResponse()
         const req = new MockRequest()
         req.params.user_id = ctx.user_id
@@ -161,8 +161,8 @@ describe('TpdsController', function () {
       }
     })
 
-    it('should process the update with the update receiver by name', function (ctx) {
-      return new Promise(resolve => {
+    it('should process the update with the update receiver by name', async function (ctx) {
+      await new Promise(resolve => {
         const res = {
           json: payload => {
             expect(payload).to.deep.equal({
@@ -190,8 +190,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should indicate in the response when the update was rejected', function (ctx) {
-      return new Promise(resolve => {
+    it('should indicate in the response when the update was rejected', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TpdsUpdateHandler.promises.newUpdate.resolves(null)
         const res = {
           json: payload => {
@@ -203,8 +203,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should process the update with the update receiver by id', function (ctx) {
-      return new Promise(resolve => {
+    it('should process the update with the update receiver by id', async function (ctx) {
+      await new Promise(resolve => {
         const path = '/here.txt'
         const req = {
           pause() {},
@@ -233,8 +233,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should return a 500 error when the update receiver fails', function (ctx) {
-      return new Promise(resolve => {
+    it('should return a 500 error when the update receiver fails', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TpdsUpdateHandler.promises.newUpdate.rejects(new Error())
         const res = {
           json: sinon.stub(),
@@ -247,8 +247,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should return a 400 error when the project is too big', function (ctx) {
-      return new Promise(resolve => {
+    it('should return a 400 error when the project is too big', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TpdsUpdateHandler.promises.newUpdate.rejects({
           message: 'project_has_too_many_files',
         })
@@ -265,8 +265,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should return a 429 error when the update receiver fails due to too many requests error', function (ctx) {
-      return new Promise(resolve => {
+    it('should return a 429 error when the update receiver fails due to too many requests error', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TpdsUpdateHandler.promises.newUpdate.rejects(
           new Errors.TooManyRequestsError('project on cooldown')
         )
@@ -282,8 +282,8 @@ describe('TpdsController', function () {
   })
 
   describe('getting a delete update', function () {
-    it('should process the delete with the update receiver by name', function (ctx) {
-      return new Promise(resolve => {
+    it('should process the delete with the update receiver by name', async function (ctx) {
+      await new Promise(resolve => {
         const path = '/projectName/here.txt'
         const req = {
           params: { 0: path, user_id: ctx.user_id, project_id: '' },
@@ -312,8 +312,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('should process the delete with the update receiver by id', function (ctx) {
-      return new Promise(resolve => {
+    it('should process the delete with the update receiver by id', async function (ctx) {
+      await new Promise(resolve => {
         const path = '/here.txt'
         const req = {
           params: { 0: path, user_id: ctx.user_id, project_id: '123' },
@@ -351,8 +351,8 @@ describe('TpdsController', function () {
       }
     })
 
-    it("creates a folder if it doesn't exist", function (ctx) {
-      return new Promise(resolve => {
+    it("creates a folder if it doesn't exist", async function (ctx) {
+      await new Promise(resolve => {
         const metadata = {
           folderId: new ObjectId(),
           projectId: new ObjectId(),
@@ -373,8 +373,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it('supports top level folders', function (ctx) {
-      return new Promise(resolve => {
+    it('supports top level folders', async function (ctx) {
+      await new Promise(resolve => {
         const metadata = {
           folderId: new ObjectId(),
           projectId: new ObjectId(),
@@ -395,8 +395,8 @@ describe('TpdsController', function () {
       })
     })
 
-    it("returns a 409 if the folder couldn't be created", function (ctx) {
-      return new Promise(resolve => {
+    it("returns a 409 if the folder couldn't be created", async function (ctx) {
+      await new Promise(resolve => {
         ctx.TpdsUpdateHandler.promises.createFolder.resolves(null)
         ctx.HttpErrorHandler.conflict.callsFake((req, res) => {
           expect(req).to.equal(ctx.req)
@@ -523,8 +523,8 @@ describe('TpdsController', function () {
     })
 
     describe('success', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.json.callsFake(() => {
             resolve()
           })
@@ -546,8 +546,8 @@ describe('TpdsController', function () {
     })
 
     describe('error', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.err = new Error()
           ctx.TpdsQueueManager.promises.getQueues = sinon
             .stub()

+ 2 - 2
services/web/test/unit/src/ThirdPartyDataStore/TpdsUpdateHandler.test.mjs

@@ -491,8 +491,8 @@ function receiveFileDelete() {
 }
 
 function receiveFileDeleteById() {
-  beforeEach(function (ctx) {
-    return new Promise(resolve => {
+  beforeEach(async function (ctx) {
+    await new Promise(resolve => {
       ctx.TpdsUpdateHandler.deleteUpdate(
         ctx.userId,
         ctx.projectId,

+ 49 - 48
services/web/test/unit/src/TokenAccess/TokenAccessController.test.mjs

@@ -285,8 +285,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('normal case (edit slot available)', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.LimitationsManager.promises.canAcceptEditCollaboratorInvite.resolves(
             true
           )
@@ -361,8 +361,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('when there are no edit collaborator slots available', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.LimitationsManager.promises.canAcceptEditCollaboratorInvite.resolves(
             false
           )
@@ -439,8 +439,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('when the access was already granted', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.project.tokenAccessReadAndWrite_refs.push(ctx.user._id)
           ctx.req.params = { token: ctx.token }
           ctx.req.body = { confirmedByUser: true }
@@ -479,8 +479,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('hash prefix missing in request', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.params = { token: ctx.token }
           ctx.req.body = { confirmedByUser: true }
           ctx.res.callback = resolve
@@ -517,8 +517,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('user is owner of project', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.AuthorizationManager.promises.getPrivilegeLevelForProject.returns(
             PrivilegeLevels.OWNER
           )
@@ -555,8 +555,8 @@ describe('TokenAccessController', function () {
         ctx.req.body = { tokenHashPrefix: '#prefix' }
       })
       describe('ANONYMOUS_READ_AND_WRITE_ENABLED is undefined', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.res.callback = resolve
             ctx.TokenAccessController.grantTokenAccessReadAndWrite(
               ctx.req,
@@ -595,8 +595,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('ANONYMOUS_READ_AND_WRITE_ENABLED is true', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED = true
             ctx.res.callback = resolve
 
@@ -637,8 +637,8 @@ describe('TokenAccessController', function () {
         ctx.Settings.overleaf = {}
       })
       describe('when token is for v1 project', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.TokenAccessHandler.promises.getProjectByToken.resolves(
               undefined
             )
@@ -683,8 +683,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('when token is not for a v1 or v2 project', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.TokenAccessHandler.promises.getProjectByToken.resolves(
               undefined
             )
@@ -726,8 +726,8 @@ describe('TokenAccessController', function () {
         ctx.req.params = { token: ctx.token }
         ctx.req.body = { tokenHashPrefix: '#prefix' }
       })
-      it('passes Errors.NotFoundError to next when project not found and still checks token hash', function (ctx) {
-        return new Promise(resolve => {
+      it('passes Errors.NotFoundError to next when project not found and still checks token hash', async function (ctx) {
+        await new Promise(resolve => {
           ctx.TokenAccessController.grantTokenAccessReadAndWrite(
             ctx.req,
             ctx.res,
@@ -763,11 +763,12 @@ describe('TokenAccessController', function () {
         ctx.req.body = { confirmedByUser: true, tokenHashPrefix: '#prefix' }
       })
 
-      it('redirects if project owner is non-admin', function (ctx) {
+      it('redirects if project owner is non-admin', async function (ctx) {
         ctx.UserGetter.promises.getUserConfirmedEmails = sinon
           .stub()
           .resolves([{ email: 'test@not-overleaf.com' }])
-        return new Promise(resolve => {
+
+        await new Promise(resolve => {
           ctx.res.callback = () => {
             expect(ctx.res.json).to.have.been.calledWith({
               redirect: `${ctx.Settings.adminUrl}/#prefix`,
@@ -811,8 +812,8 @@ describe('TokenAccessController', function () {
       })
     })
 
-    it('passes Errors.NotFoundError to next when token access is not enabled but still checks token hash', function (ctx) {
-      return new Promise(resolve => {
+    it('passes Errors.NotFoundError to next when token access is not enabled but still checks token hash', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TokenAccessHandler.tokenAccessEnabledForProject.returns(false)
         ctx.req.params = { token: ctx.token }
         ctx.req.body = { tokenHashPrefix: '#prefix' }
@@ -852,8 +853,8 @@ describe('TokenAccessController', function () {
 
   describe('grantTokenAccessReadOnly', function () {
     describe('normal case', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.params = { token: ctx.token }
           ctx.req.body = { confirmedByUser: true, tokenHashPrefix: '#prefix' }
           ctx.res.callback = resolve
@@ -901,8 +902,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('when the access was already granted', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.project.tokenAccessReadOnly_refs.push(ctx.user._id)
           ctx.req.params = { token: ctx.token }
           ctx.req.body = { confirmedByUser: true }
@@ -942,8 +943,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('anonymous users', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.req.params = { token: ctx.token }
           ctx.SessionManager.getLoggedInUserId.returns(null)
           ctx.res.callback = resolve
@@ -972,8 +973,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('user is owner of project', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.AuthorizationManager.promises.getPrivilegeLevelForProject.returns(
             PrivilegeLevels.OWNER
           )
@@ -1003,8 +1004,8 @@ describe('TokenAccessController', function () {
       })
     })
 
-    it('passes Errors.NotFoundError to next when token access is not enabled but still checks token hash', function (ctx) {
-      return new Promise(resolve => {
+    it('passes Errors.NotFoundError to next when token access is not enabled but still checks token hash', async function (ctx) {
+      await new Promise(resolve => {
         ctx.TokenAccessHandler.tokenAccessEnabledForProject.returns(false)
         ctx.req.params = { token: ctx.token }
         ctx.req.body = { tokenHashPrefix: '#prefix' }
@@ -1040,8 +1041,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('when not in link sharing changes test', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.AsyncFormHelper.redirect = sinon.stub().callsFake(() => resolve())
           ctx.TokenAccessController.ensureUserCanUseSharingUpdatesConsentPage(
             ctx.req,
@@ -1068,8 +1069,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('when user is not an invited editor and is a read write token member', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsGetter.promises.isUserInvitedReadWriteMemberOfProject.resolves(
               false
             )
@@ -1099,8 +1100,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('when user is already an invited editor', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsGetter.promises.isUserInvitedReadWriteMemberOfProject.resolves(
               true
             )
@@ -1125,8 +1126,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('when user not a read write token member', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsGetter.promises.userIsReadWriteTokenMember.resolves(
               false
             )
@@ -1165,8 +1166,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('previously joined token access user moving to named collaborator', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.resolves(
               false
             )
@@ -1204,8 +1205,8 @@ describe('TokenAccessController', function () {
       })
 
       describe('previously joined token access user moving to named collaborator', function () {
-        beforeEach(function (ctx) {
-          return new Promise(resolve => {
+        beforeEach(async function (ctx) {
+          await new Promise(resolve => {
             ctx.CollaboratorsGetter.promises.isUserInvitedMemberOfProject.resolves(
               false
             )
@@ -1243,8 +1244,8 @@ describe('TokenAccessController', function () {
     })
 
     describe('previously joined token access user moving to anonymous viewer', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = resolve
           ctx.TokenAccessController.moveReadWriteToReadOnly(
             ctx.req,

+ 2 - 2
services/web/test/unit/src/Uploads/ProjectUploadController.test.mjs

@@ -264,8 +264,8 @@ describe('ProjectUploadController', function () {
     })
 
     describe('with folder structure', function () {
-      beforeEach(function (ctx) {
-        return new Promise(resolve => {
+      beforeEach(async function (ctx) {
+        await new Promise(resolve => {
           ctx.entity = {
             _id: '1234',
             type: 'file',

+ 66 - 66
services/web/test/unit/src/User/UserPagesController.test.mjs

@@ -160,18 +160,18 @@ describe('UserPagesController', function () {
   })
 
   describe('registerPage', function () {
-    it('should render the register page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render the register page', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/register')
           resolve()
         }
         ctx.UserPagesController.registerPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should set sharedProjectData', function (ctx) {
-      return new Promise(resolve => {
+    it('should set sharedProjectData', async function(ctx) {
+      await new Promise(resolve => {
         ctx.req.session.sharedProjectData = {
           project_name: 'myProject',
           user_first_name: 'user_first_name_here',
@@ -187,11 +187,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.registerPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should set newTemplateData', function (ctx) {
-      return new Promise(resolve => {
+    it('should set newTemplateData', async function(ctx) {
+      await new Promise(resolve => {
         ctx.req.session.templateData = { templateName: 'templateName' }
 
         ctx.res.callback = () => {
@@ -201,11 +201,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.registerPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should not set the newTemplateData if there is nothing in the session', function (ctx) {
-      return new Promise(resolve => {
+    it('should not set the newTemplateData if there is nothing in the session', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           assert.equal(
             ctx.res.renderedVariables.newTemplateData.templateName,
@@ -214,19 +214,19 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.registerPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
   })
 
   describe('loginForm', function () {
-    it('should render the login page', function (ctx) {
-      return new Promise(resolve => {
+    it('should render the login page', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/login')
           resolve()
         }
         ctx.UserPagesController.loginPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when an explicit redirect is set via query string', function () {
@@ -238,8 +238,8 @@ describe('UserPagesController', function () {
         ctx.req.query.redir = '/somewhere/in/particular'
       })
 
-      it('should set a redirect', function (ctx) {
-        return new Promise(resolve => {
+      it('should set a redirect', async function(ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = page => {
             ctx.AuthenticationController.setRedirectInSession.callCount.should.equal(
               1
@@ -250,7 +250,7 @@ describe('UserPagesController', function () {
             resolve()
           }
           ctx.UserPagesController.loginPage(ctx.req, ctx.res, resolve)
-        })
+        });
       })
     })
   })
@@ -260,18 +260,18 @@ describe('UserPagesController', function () {
       ctx.UserSessionsManager.getAllUserSessions.callsArgWith(2, null, [])
     })
 
-    it('should render user/sessions', function (ctx) {
-      return new Promise(resolve => {
+    it('should render user/sessions', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/sessions')
           resolve()
         }
         ctx.UserPagesController.sessionsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should include current session data in the view', function (ctx) {
-      return new Promise(resolve => {
+    it('should include current session data in the view', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.res.renderedVariables.currentSession).to.deep.equal({
             ip_address: '1.1.1.1',
@@ -280,17 +280,17 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.sessionsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should have called getAllUserSessions', function (ctx) {
-      return new Promise(resolve => {
+    it('should have called getAllUserSessions', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = page => {
           ctx.UserSessionsManager.getAllUserSessions.callCount.should.equal(1)
           resolve()
         }
         ctx.UserPagesController.sessionsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when getAllUserSessions produces an error', function () {
@@ -301,15 +301,15 @@ describe('UserPagesController', function () {
         )
       })
 
-      it('should call next with an error', function (ctx) {
-        return new Promise(resolve => {
+      it('should call next with an error', async function(ctx) {
+        await new Promise(resolve => {
           ctx.next = err => {
             assert(err !== null)
             assert(err instanceof Error)
             resolve()
           }
           ctx.UserPagesController.sessionsPage(ctx.req, ctx.res, ctx.next)
-        })
+        });
       })
     })
   })
@@ -319,8 +319,8 @@ describe('UserPagesController', function () {
       ctx.UserGetter.getUser = sinon.stub().yields(null, ctx.user)
     })
 
-    it('render page with subscribed status', function (ctx) {
-      return new Promise(resolve => {
+    it('render page with subscribed status', async function(ctx) {
+      await new Promise(resolve => {
         ctx.NewsletterManager.subscribed.yields(null, true)
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/email-preferences')
@@ -329,11 +329,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.emailPreferencesPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('render page with unsubscribed status', function (ctx) {
-      return new Promise(resolve => {
+    it('render page with unsubscribed status', async function(ctx) {
+      await new Promise(resolve => {
         ctx.NewsletterManager.subscribed.yields(null, false)
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/email-preferences')
@@ -342,7 +342,7 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.emailPreferencesPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
   })
 
@@ -354,39 +354,39 @@ describe('UserPagesController', function () {
       ctx.UserGetter.promises.getUser = sinon.stub().resolves(ctx.user)
     })
 
-    it('should render user/settings', function (ctx) {
-      return new Promise(resolve => {
+    it('should render user/settings', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedTemplate.should.equal('user/settings')
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should send user', function (ctx) {
-      return new Promise(resolve => {
+    it('should send user', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedVariables.user.id.should.equal(ctx.user._id)
           ctx.res.renderedVariables.user.email.should.equal(ctx.user.email)
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it("should set 'shouldAllowEditingDetails' to true", function (ctx) {
-      return new Promise(resolve => {
+    it("should set 'shouldAllowEditingDetails' to true", async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           ctx.res.renderedVariables.shouldAllowEditingDetails.should.equal(true)
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should restructure thirdPartyIdentifiers data for template use', function (ctx) {
-      return new Promise(resolve => {
+    it('should restructure thirdPartyIdentifiers data for template use', async function(ctx) {
+      await new Promise(resolve => {
         const expectedResult = {
           google: 'testId',
         }
@@ -397,11 +397,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it("should set and clear 'projectSyncSuccessMessage'", function (ctx) {
-      return new Promise(resolve => {
+    it("should set and clear 'projectSyncSuccessMessage'", async function(ctx) {
+      await new Promise(resolve => {
         ctx.req.session.projectSyncSuccessMessage = 'Some Sync Success'
         ctx.res.callback = () => {
           ctx.res.renderedVariables.projectSyncSuccessMessage.should.equal(
@@ -411,11 +411,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should cast refProviders to booleans', function (ctx) {
-      return new Promise(resolve => {
+    it('should cast refProviders to booleans', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(ctx.res.renderedVariables.user.refProviders).to.deep.equal({
             mendeley: true,
@@ -425,11 +425,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should send the correct managed user admin email', function (ctx) {
-      return new Promise(resolve => {
+    it('should send the correct managed user admin email', async function(ctx) {
+      await new Promise(resolve => {
         ctx.res.callback = () => {
           expect(
             ctx.res.renderedVariables.currentManagedUserAdminEmail
@@ -437,11 +437,11 @@ describe('UserPagesController', function () {
           resolve()
         }
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
-    it('should send info for groups with SSO enabled', function (ctx) {
-      return new Promise(resolve => {
+    it('should send info for groups with SSO enabled', async function(ctx) {
+      await new Promise(resolve => {
         ctx.user.enrollment = {
           sso: [
             {
@@ -492,7 +492,7 @@ describe('UserPagesController', function () {
         }
 
         ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-      })
+      });
     })
 
     describe('when ldap.updateUserDetailsOnLogin is true', function () {
@@ -504,8 +504,8 @@ describe('UserPagesController', function () {
         delete ctx.settings.ldap
       })
 
-      it('should set "shouldAllowEditingDetails" to false', function (ctx) {
-        return new Promise(resolve => {
+      it('should set "shouldAllowEditingDetails" to false', async function(ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = () => {
             ctx.res.renderedVariables.shouldAllowEditingDetails.should.equal(
               false
@@ -513,7 +513,7 @@ describe('UserPagesController', function () {
             resolve()
           }
           ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-        })
+        });
       })
     })
 
@@ -526,8 +526,8 @@ describe('UserPagesController', function () {
         delete ctx.settings.saml
       })
 
-      it('should set "shouldAllowEditingDetails" to false', function (ctx) {
-        return new Promise(resolve => {
+      it('should set "shouldAllowEditingDetails" to false', async function(ctx) {
+        await new Promise(resolve => {
           ctx.res.callback = () => {
             ctx.res.renderedVariables.shouldAllowEditingDetails.should.equal(
               false
@@ -535,7 +535,7 @@ describe('UserPagesController', function () {
             resolve()
           }
           ctx.UserPagesController.settingsPage(ctx.req, ctx.res, resolve)
-        })
+        });
       })
     })
   })

+ 24 - 24
services/web/test/unit/src/UserMembership/UserMembershipController.test.mjs

@@ -221,8 +221,8 @@ describe('UserMembershipController', function () {
       ctx.req.entityConfig = EntityConfigs.groupManagers
     })
 
-    it('add user', function (ctx) {
-      return new Promise(resolve => {
+    it('add user', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipController.add(ctx.req, {
           json: () => {
             sinon.assert.calledWithMatch(
@@ -237,8 +237,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('return user object', function (ctx) {
-      return new Promise(resolve => {
+    it('return user object', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipController.add(ctx.req, {
           json: payload => {
             payload.user.should.equal(ctx.newUser)
@@ -248,8 +248,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('handle readOnly entity', function (ctx) {
-      return new Promise(resolve => {
+    it('handle readOnly entity', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.entityConfig = EntityConfigs.group
         ctx.UserMembershipController.add(ctx.req, null, error => {
           expect(error).to.exist
@@ -259,8 +259,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('handle user already added', function (ctx) {
-      return new Promise(resolve => {
+    it('handle user already added', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipHandler.addUser.yields(new UserAlreadyAddedError())
         ctx.UserMembershipController.add(ctx.req, {
           status: () => ({
@@ -273,8 +273,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('handle user not found', function (ctx) {
-      return new Promise(resolve => {
+    it('handle user not found', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipHandler.addUser.yields(new UserNotFoundError())
         ctx.UserMembershipController.add(ctx.req, {
           status: () => ({
@@ -287,8 +287,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('handle invalid email', function (ctx) {
-      return new Promise(resolve => {
+    it('handle invalid email', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.body.email = 'not_valid_email'
         ctx.UserMembershipController.add(ctx.req, {
           status: () => ({
@@ -309,8 +309,8 @@ describe('UserMembershipController', function () {
       ctx.req.entityConfig = EntityConfigs.groupManagers
     })
 
-    it('remove user', function (ctx) {
-      return new Promise(resolve => {
+    it('remove user', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipController.remove(ctx.req, {
           sendStatus: () => {
             sinon.assert.calledWithMatch(
@@ -325,8 +325,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('handle readOnly entity', function (ctx) {
-      return new Promise(resolve => {
+    it('handle readOnly entity', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.entityConfig = EntityConfigs.group
         ctx.UserMembershipController.remove(ctx.req, null, error => {
           expect(error).to.exist
@@ -336,8 +336,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('prevent self removal', function (ctx) {
-      return new Promise(resolve => {
+    it('prevent self removal', async function (ctx) {
+      await new Promise(resolve => {
         ctx.req.params.userId = ctx.user._id
         ctx.UserMembershipController.remove(ctx.req, {
           status: () => ({
@@ -350,8 +350,8 @@ describe('UserMembershipController', function () {
       })
     })
 
-    it('prevent admin removal', function (ctx) {
-      return new Promise(resolve => {
+    it('prevent admin removal', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipHandler.removeUser.yields(new UserIsManagerError())
         ctx.UserMembershipController.remove(ctx.req, {
           status: () => ({
@@ -409,8 +409,8 @@ describe('UserMembershipController', function () {
       ctx.req.params.id = 'abc'
     })
 
-    it('renders view', function (ctx) {
-      return new Promise(resolve => {
+    it('renders view', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipController.new(ctx.req, {
           render: (viewPath, data) => {
             expect(data.entityName).to.eq('publisher')
@@ -429,8 +429,8 @@ describe('UserMembershipController', function () {
       ctx.req.params.id = 123
     })
 
-    it('creates institution', function (ctx) {
-      return new Promise(resolve => {
+    it('creates institution', async function (ctx) {
+      await new Promise(resolve => {
         ctx.UserMembershipController.create(ctx.req, {
           redirect: path => {
             expect(path).to.eq(EntityConfigs.institution.pathsFor(123).index)