Browse Source

[web] Promisify AuthorizationTests (#28211)

* Promisify AuthorizationTests.mjs

* Replace reassigned response/body by separate consts

GitOrigin-RevId: db801a93919b7ecf2d8708dc38af231321a6b43b
Antoine Clausse 1 năm trước cách đây
mục cha
commit
b8852282cd

+ 277 - 485
services/web/test/acceptance/src/AuthorizationTests.mjs

@@ -1,159 +1,66 @@
 import { expect } from 'chai'
 import { expect } from 'chai'
-import async from 'async'
-import User from './helpers/User.mjs'
+import UserHelper from './helpers/User.mjs'
 import request from './helpers/request.js'
 import request from './helpers/request.js'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import Features from '../../../app/src/infrastructure/Features.js'
 import Features from '../../../app/src/infrastructure/Features.js'
 import expectErrorResponse from './helpers/expectErrorResponse.mjs'
 import expectErrorResponse from './helpers/expectErrorResponse.mjs'
+import { promisify } from '@overleaf/promise-utils'
 
 
-function tryReadAccess(user, projectId, test, callback) {
-  async.series(
-    [
-      cb =>
-        user.request.get(`/project/${projectId}`, (error, response, body) => {
-          if (error != null) {
-            return cb(error)
-          }
-          test(response, body)
-          cb()
-        }),
-      cb =>
-        user.request.get(
-          `/project/${projectId}/download/zip`,
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        ),
-    ],
-    callback
+const User = UserHelper.promises
+
+async function tryReadAccess(user, projectId, test) {
+  const projectRequest = await user.doRequest('get', `/project/${projectId}`)
+  test(projectRequest.response, projectRequest.body)
+  const zipRequest = await user.doRequest(
+    'get',
+    `/project/${projectId}/download/zip`
   )
   )
+  test(zipRequest.response, zipRequest.body)
 }
 }
 
 
-function tryRenameProjectAccess(user, projectId, test, callback) {
-  user.request.post(
-    {
-      uri: `/project/${projectId}/settings`,
-      json: {
-        name: 'new name',
-      },
-    },
-    (error, response, body) => {
-      if (error != null) {
-        return callback(error)
-      }
-      test(response, body)
-      callback()
-    }
-  )
+async function tryRenameProjectAccess(user, projectId, test) {
+  const { response, body } = await user.doRequest('post', {
+    url: `/project/${projectId}/settings`,
+    json: { name: 'new name' },
+  })
+  test(response, body)
 }
 }
 
 
-function trySettingsWriteAccess(user, projectId, test, callback) {
-  async.series(
-    [
-      cb =>
-        user.request.post(
-          {
-            uri: `/project/${projectId}/settings`,
-            json: {
-              compiler: 'latex',
-            },
-          },
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        ),
-    ],
-    callback
-  )
+async function trySettingsWriteAccess(user, projectId, test) {
+  const { response, body } = await user.doRequest('post', {
+    url: `/project/${projectId}/settings`,
+    json: { compiler: 'latex' },
+  })
+  test(response, body)
 }
 }
 
 
-function tryProjectAdminAccess(user, projectId, test, callback) {
-  async.series(
-    [
-      cb =>
-        user.request.post(
-          {
-            uri: `/project/${projectId}/rename`,
-            json: {
-              newProjectName: 'new-name',
-            },
-          },
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        ),
-      cb =>
-        user.request.post(
-          {
-            uri: `/project/${projectId}/settings/admin`,
-            json: {
-              publicAccessLevel: 'private',
-            },
-          },
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        ),
-    ],
-    callback
-  )
+async function tryProjectAdminAccess(user, projectId, test) {
+  const renameRequest = await user.doRequest('post', {
+    url: `/project/${projectId}/rename`,
+    json: { newProjectName: 'new-name' },
+  })
+  test(renameRequest.response, renameRequest.body)
+  const settingsRequest = await user.doRequest('post', {
+    url: `/project/${projectId}/settings/admin`,
+    json: { publicAccessLevel: 'private' },
+  })
+  test(settingsRequest.response, settingsRequest.body)
 }
 }
 
 
-function tryAdminAccess(user, test, callback) {
-  async.series(
-    [
-      cb =>
-        user.request.get(
-          {
-            uri: '/admin',
-          },
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        ),
-      cb => {
-        if (!Features.hasFeature('saas')) {
-          return cb()
-        }
-        user.request.get(
-          {
-            uri: `/admin/user/${user._id}`,
-          },
-          (error, response, body) => {
-            if (error != null) {
-              return cb(error)
-            }
-            test(response, body)
-            cb()
-          }
-        )
-      },
-    ],
-    callback
-  )
+async function tryAdminAccess(user, test) {
+  const { response, body } = await user.doRequest('get', '/admin')
+  test(response, body)
+
+  if (Features.hasFeature('saas')) {
+    const { response, body } = await user.doRequest(
+      'get',
+      `/admin/user/${user._id}`
+    )
+    test(response, body)
+  }
 }
 }
 
 
-function tryContentAccess(user, projectId, test, callback) {
+function tryContentAccessCb(user, projectId, test, callback) {
   // The real-time service calls this end point to determine the user's
   // The real-time service calls this end point to determine the user's
   // permissions.
   // permissions.
   let userId
   let userId
@@ -183,305 +90,216 @@ function tryContentAccess(user, projectId, test, callback) {
   )
   )
 }
 }
 
 
-function expectAdminAccess(user, callback) {
-  tryAdminAccess(
-    user,
-    response => expect(response.statusCode).to.be.oneOf([200, 204]),
-    callback
+const tryContentAccess = promisify(tryContentAccessCb)
+
+async function expectAdminAccess(user) {
+  await tryAdminAccess(user, response =>
+    expect(response.statusCode).to.be.oneOf([200, 204])
   )
   )
 }
 }
 
 
-function expectRedirectedAdminAccess(user, callback) {
-  tryAdminAccess(
-    user,
-    response => {
-      expect(response.statusCode).to.equal(302)
-      expect(response.headers.location).to.equal(
-        settings.adminUrl + response.request.uri.pathname
-      )
-    },
-    callback
-  )
+async function expectRedirectedAdminAccess(user) {
+  await tryAdminAccess(user, response => {
+    expect(response.statusCode).to.equal(302)
+    expect(response.headers.location).to.equal(
+      settings.adminUrl + response.request.uri.pathname
+    )
+  })
 }
 }
 
 
-function expectReadAccess(user, projectId, callback) {
-  async.series(
-    [
-      cb =>
-        tryReadAccess(
-          user,
-          projectId,
-          (response, body) =>
-            expect(response.statusCode).to.be.oneOf([200, 204]),
-          cb
-        ),
-      cb =>
-        tryContentAccess(
-          user,
-          projectId,
-          (response, body) =>
-            expect(body.privilegeLevel).to.be.oneOf([
-              'owner',
-              'readAndWrite',
-              'readOnly',
-            ]),
-          cb
-        ),
-    ],
-    callback
+async function expectReadAccess(user, projectId) {
+  await tryReadAccess(user, projectId, response =>
+    expect(response.statusCode).to.be.oneOf([200, 204])
+  )
+  await tryContentAccess(user, projectId, (response, body) =>
+    expect(body.privilegeLevel).to.be.oneOf([
+      'owner',
+      'readAndWrite',
+      'readOnly',
+    ])
   )
   )
 }
 }
 
 
-function expectContentWriteAccess(user, projectId, callback) {
-  tryContentAccess(
-    user,
-    projectId,
-    (response, body) =>
-      expect(body.privilegeLevel).to.be.oneOf(['owner', 'readAndWrite']),
-    callback
+async function expectContentWriteAccess(user, projectId) {
+  await tryContentAccess(user, projectId, (response, body) =>
+    expect(body.privilegeLevel).to.be.oneOf(['owner', 'readAndWrite'])
   )
   )
 }
 }
 
 
-function expectRenameProjectAccess(user, projectId, callback) {
-  tryRenameProjectAccess(
-    user,
-    projectId,
-    (response, body) => {
-      expect(response.statusCode).to.be.oneOf([200, 204])
-    },
-    callback
-  )
+async function expectRenameProjectAccess(user, projectId) {
+  await tryRenameProjectAccess(user, projectId, response => {
+    expect(response.statusCode).to.be.oneOf([200, 204])
+  })
 }
 }
 
 
-function expectSettingsWriteAccess(user, projectId, callback) {
-  trySettingsWriteAccess(
-    user,
-    projectId,
-    (response, body) => expect(response.statusCode).to.be.oneOf([200, 204]),
-    callback
+async function expectSettingsWriteAccess(user, projectId) {
+  await trySettingsWriteAccess(user, projectId, response =>
+    expect(response.statusCode).to.be.oneOf([200, 204])
   )
   )
 }
 }
 
 
-function expectProjectAdminAccess(user, projectId, callback) {
-  tryProjectAdminAccess(
-    user,
-    projectId,
-    (response, body) => expect(response.statusCode).to.be.oneOf([200, 204]),
-    callback
+async function expectProjectAdminAccess(user, projectId) {
+  await tryProjectAdminAccess(user, projectId, response =>
+    expect(response.statusCode).to.be.oneOf([200, 204])
   )
   )
 }
 }
 
 
-function expectNoReadAccess(user, projectId, callback) {
-  async.series(
-    [
-      cb =>
-        tryReadAccess(user, projectId, expectErrorResponse.restricted.html, cb),
-      cb =>
-        tryContentAccess(
-          user,
-          projectId,
-          (response, body) => {
-            expect(response.statusCode).to.equal(403)
-            expect(body).to.equal('Forbidden')
-          },
-          cb
-        ),
-    ],
-    callback
-  )
+async function expectNoReadAccess(user, projectId) {
+  await tryReadAccess(user, projectId, expectErrorResponse.restricted.html)
+  await tryContentAccess(user, projectId, (response, body) => {
+    expect(response.statusCode).to.equal(403)
+    expect(body).to.equal('Forbidden')
+  })
 }
 }
 
 
-function expectNoContentWriteAccess(user, projectId, callback) {
-  tryContentAccess(
-    user,
-    projectId,
-    (response, body) =>
-      expect(body.privilegeLevel).to.be.oneOf([undefined, null, 'readOnly']),
-    callback
+async function expectNoContentWriteAccess(user, projectId) {
+  await tryContentAccess(user, projectId, (response, body) =>
+    expect(body.privilegeLevel).to.be.oneOf([undefined, null, 'readOnly'])
   )
   )
 }
 }
 
 
-function expectNoSettingsWriteAccess(user, projectId, callback) {
-  trySettingsWriteAccess(
+async function expectNoSettingsWriteAccess(user, projectId) {
+  await trySettingsWriteAccess(
     user,
     user,
     projectId,
     projectId,
-    expectErrorResponse.restricted.json,
-    callback
+    expectErrorResponse.restricted.json
   )
   )
 }
 }
 
 
-function expectNoRenameProjectAccess(user, projectId, callback) {
-  tryRenameProjectAccess(
+async function expectNoRenameProjectAccess(user, projectId) {
+  await tryRenameProjectAccess(
     user,
     user,
     projectId,
     projectId,
-    expectErrorResponse.restricted.json,
-    callback
+    expectErrorResponse.restricted.json
   )
   )
 }
 }
 
 
-function expectNoProjectAdminAccess(user, projectId, callback) {
-  tryProjectAdminAccess(
-    user,
-    projectId,
-    (response, body) => {
-      expect(response.statusCode).to.equal(403)
-    },
-    callback
-  )
+async function expectNoProjectAdminAccess(user, projectId) {
+  await tryProjectAdminAccess(user, projectId, response => {
+    expect(response.statusCode).to.equal(403)
+  })
 }
 }
 
 
-function expectNoAnonymousProjectAdminAccess(user, projectId, callback) {
-  tryProjectAdminAccess(
+async function expectNoAnonymousProjectAdminAccess(user, projectId) {
+  await tryProjectAdminAccess(
     user,
     user,
     projectId,
     projectId,
-    expectErrorResponse.requireLogin.json,
-    callback
+    expectErrorResponse.requireLogin.json
   )
   )
 }
 }
 
 
-function expectChatAccess(user, projectId, callback) {
-  user.request.get(
-    {
-      url: `/project/${projectId}/messages`,
-      json: true,
-    },
-    (error, response) => {
-      if (error != null) {
-        return callback(error)
-      }
-      expect(response.statusCode).to.equal(200)
-      callback()
-    }
+async function expectChatAccess(user, projectId) {
+  const { response } = await user.doRequest(
+    'get',
+    `/project/${projectId}/messages`
   )
   )
+  expect(response.statusCode).to.equal(200)
 }
 }
 
 
-function expectNoChatAccess(user, projectId, callback) {
-  user.request.get(
-    {
-      url: `/project/${projectId}/messages`,
-      json: true,
-    },
-    (error, response) => {
-      if (error != null) {
-        return callback(error)
-      }
-      expect(response.statusCode).to.equal(403)
-      callback()
-    }
+async function expectNoChatAccess(user, projectId) {
+  const { response } = await user.doRequest(
+    'get',
+    `/project/${projectId}/messages`
   )
   )
+  expect(response.statusCode).to.equal(403)
 }
 }
 
 
 describe('Authorization', function () {
 describe('Authorization', function () {
-  beforeEach(function (done) {
+  beforeEach(async function () {
     this.timeout(90000)
     this.timeout(90000)
     this.owner = new User()
     this.owner = new User()
     this.other1 = new User()
     this.other1 = new User()
     this.other2 = new User()
     this.other2 = new User()
     this.anon = new User()
     this.anon = new User()
     this.site_admin = new User({ email: 'admin@example.com' })
     this.site_admin = new User({ email: 'admin@example.com' })
-    async.parallel(
-      [
-        cb => this.owner.login(cb),
-        cb => this.other1.login(cb),
-        cb => this.other2.login(cb),
-        cb => this.anon.getCsrfToken(cb),
-        cb => {
-          this.site_admin.ensureUserExists(err => {
-            if (err) return cb(err)
-            this.site_admin.ensureAdmin(err => {
-              if (err != null) {
-                return cb(err)
-              }
-              return this.site_admin.login(cb)
-            })
-          })
-        },
-      ],
-      done
-    )
+    await Promise.all([
+      this.owner.login(),
+      this.other1.login(),
+      this.other2.login(),
+      this.anon.getCsrfToken(),
+      (async () => {
+        await this.site_admin.ensureUserExists()
+        await this.site_admin.ensureAdmin()
+        await this.site_admin.login()
+      })(),
+    ])
   })
   })
 
 
   describe('private project', function () {
   describe('private project', function () {
-    beforeEach(function (done) {
-      this.owner.createProject('private-project', (error, projectId) => {
-        if (error != null) {
-          return done(error)
-        }
-        this.projectId = projectId
-        done()
-      })
+    beforeEach(async function () {
+      this.projectId = await this.owner.createProject('private-project')
     })
     })
 
 
-    it('should allow the owner read access to it', function (done) {
-      expectReadAccess(this.owner, this.projectId, done)
+    it('should allow the owner read access to it', async function () {
+      await expectReadAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should allow the owner write access to its content', function (done) {
-      expectContentWriteAccess(this.owner, this.projectId, done)
+    it('should allow the owner write access to its content', async function () {
+      await expectContentWriteAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should allow the owner write access to its settings', function (done) {
-      expectSettingsWriteAccess(this.owner, this.projectId, done)
+    it('should allow the owner write access to its settings', async function () {
+      await expectSettingsWriteAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should allow the owner to rename the project', function (done) {
-      expectRenameProjectAccess(this.owner, this.projectId, done)
+    it('should allow the owner to rename the project', async function () {
+      await expectRenameProjectAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should allow the owner project admin access to it', function (done) {
-      expectProjectAdminAccess(this.owner, this.projectId, done)
+    it('should allow the owner project admin access to it', async function () {
+      await expectProjectAdminAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should allow the owner user chat messages access', function (done) {
-      expectChatAccess(this.owner, this.projectId, done)
+    it('should allow the owner user chat messages access', async function () {
+      await expectChatAccess(this.owner, this.projectId)
     })
     })
 
 
-    it('should not allow another user read access to the project', function (done) {
-      expectNoReadAccess(this.other1, this.projectId, done)
+    it('should not allow another user read access to the project', async function () {
+      await expectNoReadAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow another user write access to its content', function (done) {
-      expectNoContentWriteAccess(this.other1, this.projectId, done)
+    it('should not allow another user write access to its content', async function () {
+      await expectNoContentWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow another user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.other1, this.projectId, done)
+    it('should not allow another user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow another user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.other1, this.projectId, done)
+    it('should not allow another user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow another user project admin access to it', function (done) {
-      expectNoProjectAdminAccess(this.other1, this.projectId, done)
+    it('should not allow another user project admin access to it', async function () {
+      await expectNoProjectAdminAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow another user chat messages access', function (done) {
-      expectNoChatAccess(this.other1, this.projectId, done)
+    it('should not allow another user chat messages access', async function () {
+      await expectNoChatAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user read access to it', function (done) {
-      expectNoReadAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user read access to it', async function () {
+      await expectNoReadAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user write access to its content', function (done) {
-      expectNoContentWriteAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user write access to its content', async function () {
+      await expectNoContentWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user project admin access to it', function (done) {
-      expectNoAnonymousProjectAdminAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user project admin access to it', async function () {
+      await expectNoAnonymousProjectAdminAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow anonymous user chat messages access', function (done) {
-      expectNoChatAccess(this.anon, this.projectId, done)
+    it('should not allow anonymous user chat messages access', async function () {
+      await expectNoChatAccess(this.anon, this.projectId)
     })
     })
 
 
     describe('with admin privilege available', function () {
     describe('with admin privilege available', function () {
@@ -489,28 +307,28 @@ describe('Authorization', function () {
         settings.adminPrivilegeAvailable = true
         settings.adminPrivilegeAvailable = true
       })
       })
 
 
-      it('should allow site admin users read access to it', function (done) {
-        expectReadAccess(this.site_admin, this.projectId, done)
+      it('should allow site admin users read access to it', async function () {
+        await expectReadAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should allow site admin users write access to its content', function (done) {
-        expectContentWriteAccess(this.site_admin, this.projectId, done)
+      it('should allow site admin users write access to its content', async function () {
+        await expectContentWriteAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should allow site admin users write access to its settings', function (done) {
-        expectSettingsWriteAccess(this.site_admin, this.projectId, done)
+      it('should allow site admin users write access to its settings', async function () {
+        await expectSettingsWriteAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should allow site admin users to rename the project', function (done) {
-        expectRenameProjectAccess(this.site_admin, this.projectId, done)
+      it('should allow site admin users to rename the project', async function () {
+        await expectRenameProjectAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should allow site admin users project admin access to it', function (done) {
-        expectProjectAdminAccess(this.site_admin, this.projectId, done)
+      it('should allow site admin users project admin access to it', async function () {
+        await expectProjectAdminAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should allow site admin users site admin access to site admin endpoints', function (done) {
-        expectAdminAccess(this.site_admin, done)
+      it('should allow site admin users site admin access to site admin endpoints', async function () {
+        await expectAdminAccess(this.site_admin)
       })
       })
     })
     })
 
 
@@ -522,111 +340,95 @@ describe('Authorization', function () {
         settings.adminPrivilegeAvailable = true
         settings.adminPrivilegeAvailable = true
       })
       })
 
 
-      it('should not allow site admin users read access to it', function (done) {
-        expectNoReadAccess(this.site_admin, this.projectId, done)
+      it('should not allow site admin users read access to it', async function () {
+        await expectNoReadAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should not allow site admin users write access to its content', function (done) {
-        expectNoContentWriteAccess(this.site_admin, this.projectId, done)
+      it('should not allow site admin users write access to its content', async function () {
+        await expectNoContentWriteAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should not allow site admin users write access to its settings', function (done) {
-        expectNoSettingsWriteAccess(this.site_admin, this.projectId, done)
+      it('should not allow site admin users write access to its settings', async function () {
+        await expectNoSettingsWriteAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should not allow site admin users to rename the project', function (done) {
-        expectNoRenameProjectAccess(this.site_admin, this.projectId, done)
+      it('should not allow site admin users to rename the project', async function () {
+        await expectNoRenameProjectAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should not allow site admin users project admin access to it', function (done) {
-        expectNoProjectAdminAccess(this.site_admin, this.projectId, done)
+      it('should not allow site admin users project admin access to it', async function () {
+        await expectNoProjectAdminAccess(this.site_admin, this.projectId)
       })
       })
 
 
-      it('should redirect site admin users when accessing site admin endpoints', function (done) {
-        expectRedirectedAdminAccess(this.site_admin, done)
+      it('should redirect site admin users when accessing site admin endpoints', async function () {
+        await expectRedirectedAdminAccess(this.site_admin)
       })
       })
     })
     })
   })
   })
 
 
   describe('shared project', function () {
   describe('shared project', function () {
-    beforeEach(function (done) {
+    beforeEach(async function () {
       this.rw_user = this.other1
       this.rw_user = this.other1
       this.ro_user = this.other2
       this.ro_user = this.other2
-      this.owner.createProject('private-project', (error, projectId) => {
-        if (error != null) {
-          return done(error)
-        }
-        this.projectId = projectId
-        this.owner.addUserToProject(
-          this.projectId,
-          this.ro_user,
-          'readOnly',
-          error => {
-            if (error != null) {
-              return done(error)
-            }
-            this.owner.addUserToProject(
-              this.projectId,
-              this.rw_user,
-              'readAndWrite',
-              error => {
-                if (error != null) {
-                  return done(error)
-                }
-                done()
-              }
-            )
-          }
-        )
-      })
+      this.projectId = await this.owner.createProject('private-project')
+      await this.owner.addUserToProject(
+        this.projectId,
+        this.ro_user,
+        'readOnly'
+      )
+      await this.owner.addUserToProject(
+        this.projectId,
+        this.rw_user,
+        'readAndWrite'
+      )
     })
     })
 
 
-    it('should allow the read-only user read access to it', function (done) {
-      expectReadAccess(this.ro_user, this.projectId, done)
+    it('should allow the read-only user read access to it', async function () {
+      await expectReadAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should allow the read-only user chat messages access', function (done) {
-      expectChatAccess(this.ro_user, this.projectId, done)
+    it('should allow the read-only user chat messages access', async function () {
+      await expectChatAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-only user write access to its content', function (done) {
-      expectNoContentWriteAccess(this.ro_user, this.projectId, done)
+    it('should not allow the read-only user write access to its content', async function () {
+      await expectNoContentWriteAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-only user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.ro_user, this.projectId, done)
+    it('should not allow the read-only user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-only user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.ro_user, this.projectId, done)
+    it('should not allow the read-only user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-only user project admin access to it', function (done) {
-      expectNoProjectAdminAccess(this.ro_user, this.projectId, done)
+    it('should not allow the read-only user project admin access to it', async function () {
+      await expectNoProjectAdminAccess(this.ro_user, this.projectId)
     })
     })
 
 
-    it('should allow the read-write user read access to it', function (done) {
-      expectReadAccess(this.rw_user, this.projectId, done)
+    it('should allow the read-write user read access to it', async function () {
+      await expectReadAccess(this.rw_user, this.projectId)
     })
     })
 
 
-    it('should allow the read-write user write access to its content', function (done) {
-      expectContentWriteAccess(this.rw_user, this.projectId, done)
+    it('should allow the read-write user write access to its content', async function () {
+      await expectContentWriteAccess(this.rw_user, this.projectId)
     })
     })
 
 
-    it('should allow the read-write user write access to its settings', function (done) {
-      expectSettingsWriteAccess(this.rw_user, this.projectId, done)
+    it('should allow the read-write user write access to its settings', async function () {
+      await expectSettingsWriteAccess(this.rw_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-write user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.rw_user, this.projectId, done)
+    it('should not allow the read-write user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.rw_user, this.projectId)
     })
     })
 
 
-    it('should not allow the read-write user project admin access to it', function (done) {
-      expectNoProjectAdminAccess(this.rw_user, this.projectId, done)
+    it('should not allow the read-write user project admin access to it', async function () {
+      await expectNoProjectAdminAccess(this.rw_user, this.projectId)
     })
     })
 
 
-    it('should allow the read-write user chat messages access', function (done) {
-      expectChatAccess(this.rw_user, this.projectId, done)
+    it('should allow the read-write user chat messages access', async function () {
+      await expectChatAccess(this.rw_user, this.projectId)
     })
     })
   })
   })
 
 
@@ -635,67 +437,62 @@ describe('Authorization', function () {
      * Note: this is a test for the legacy "public access" feature.
      * Note: this is a test for the legacy "public access" feature.
      * See documentation comment in `Authorization/PublicAccessLevels`
      * See documentation comment in `Authorization/PublicAccessLevels`
      * */
      * */
-    beforeEach(function (done) {
-      this.owner.createProject('public-rw-project', (error, projectId) => {
-        if (error != null) {
-          return done(error)
-        }
-        this.projectId = projectId
-        this.owner.makePublic(this.projectId, 'readAndWrite', done)
-      })
+    beforeEach(async function () {
+      this.projectId = await this.owner.createProject('public-rw-project')
+      await this.owner.makePublic(this.projectId, 'readAndWrite')
     })
     })
 
 
-    it('should allow a user read access to it', function (done) {
-      expectReadAccess(this.other1, this.projectId, done)
+    it('should allow a user read access to it', async function () {
+      await expectReadAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should allow a user write access to its content', function (done) {
-      expectContentWriteAccess(this.other1, this.projectId, done)
+    it('should allow a user write access to its content', async function () {
+      await expectContentWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should allow a user chat messages access', function (done) {
-      expectChatAccess(this.other1, this.projectId, done)
+    it('should allow a user chat messages access', async function () {
+      await expectChatAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.other1, this.projectId, done)
+    it('should not allow a user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.other1, this.projectId, done)
+    it('should not allow a user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user project admin access to it', function (done) {
-      expectNoProjectAdminAccess(this.other1, this.projectId, done)
+    it('should not allow a user project admin access to it', async function () {
+      await expectNoProjectAdminAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should allow an anonymous user read access to it', function (done) {
-      expectReadAccess(this.anon, this.projectId, done)
+    it('should allow an anonymous user read access to it', async function () {
+      await expectReadAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should allow an anonymous user write access to its content', function (done) {
-      expectContentWriteAccess(this.anon, this.projectId, done)
+    it('should allow an anonymous user write access to its content', async function () {
+      await expectContentWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should allow an anonymous user chat messages access', function (done) {
+    it('should allow an anonymous user chat messages access', async function () {
       // chat access for anonymous users is a CE/SP-only feature, although currently broken
       // chat access for anonymous users is a CE/SP-only feature, although currently broken
       // https://github.com/overleaf/internal/issues/10944
       // https://github.com/overleaf/internal/issues/10944
       if (Features.hasFeature('saas')) {
       if (Features.hasFeature('saas')) {
         this.skip()
         this.skip()
       }
       }
-      expectChatAccess(this.anon, this.projectId, done)
+      await expectChatAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user project admin access to it', function (done) {
-      expectNoAnonymousProjectAdminAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user project admin access to it', async function () {
+      await expectNoAnonymousProjectAdminAccess(this.anon, this.projectId)
     })
     })
   })
   })
 
 
@@ -704,63 +501,58 @@ describe('Authorization', function () {
      * Note: this is a test for the legacy "public access" feature.
      * Note: this is a test for the legacy "public access" feature.
      * See documentation comment in `Authorization/PublicAccessLevels`
      * See documentation comment in `Authorization/PublicAccessLevels`
      * */
      * */
-    beforeEach(function (done) {
-      this.owner.createProject('public-ro-project', (error, projectId) => {
-        if (error != null) {
-          return done(error)
-        }
-        this.projectId = projectId
-        this.owner.makePublic(this.projectId, 'readOnly', done)
-      })
+    beforeEach(async function () {
+      this.projectId = await this.owner.createProject('public-ro-project')
+      await this.owner.makePublic(this.projectId, 'readOnly')
     })
     })
 
 
-    it('should allow a user read access to it', function (done) {
-      expectReadAccess(this.other1, this.projectId, done)
+    it('should allow a user read access to it', async function () {
+      await expectReadAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user write access to its content', function (done) {
-      expectNoContentWriteAccess(this.other1, this.projectId, done)
+    it('should not allow a user write access to its content', async function () {
+      await expectNoContentWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.other1, this.projectId, done)
+    it('should not allow a user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.other1, this.projectId, done)
+    it('should not allow a user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should not allow a user project admin access to it', function (done) {
-      expectNoProjectAdminAccess(this.other1, this.projectId, done)
+    it('should not allow a user project admin access to it', async function () {
+      await expectNoProjectAdminAccess(this.other1, this.projectId)
     })
     })
 
 
     // NOTE: legacy readOnly access does not count as 'restricted' in the new model
     // NOTE: legacy readOnly access does not count as 'restricted' in the new model
-    it('should allow a user chat messages access', function (done) {
-      expectChatAccess(this.other1, this.projectId, done)
+    it('should allow a user chat messages access', async function () {
+      await expectChatAccess(this.other1, this.projectId)
     })
     })
 
 
-    it('should allow an anonymous user read access to it', function (done) {
-      expectReadAccess(this.anon, this.projectId, done)
+    it('should allow an anonymous user read access to it', async function () {
+      await expectReadAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user write access to its content', function (done) {
-      expectNoContentWriteAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user write access to its content', async function () {
+      await expectNoContentWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user write access to its settings', function (done) {
-      expectNoSettingsWriteAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user write access to its settings', async function () {
+      await expectNoSettingsWriteAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user to rename the project', function (done) {
-      expectNoRenameProjectAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user to rename the project', async function () {
+      await expectNoRenameProjectAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user project admin access to it', function (done) {
-      expectNoAnonymousProjectAdminAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user project admin access to it', async function () {
+      await expectNoAnonymousProjectAdminAccess(this.anon, this.projectId)
     })
     })
 
 
-    it('should not allow an anonymous user chat messages access', function (done) {
-      expectNoChatAccess(this.anon, this.projectId, done)
+    it('should not allow an anonymous user chat messages access', async function () {
+      await expectNoChatAccess(this.anon, this.projectId)
     })
     })
   })
   })
 })
 })