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

Merge pull request #223 from overleaf/jpa-bulk-dependency-upgrades

[misc] bulk dependency upgrades
Jakob Ackermann 5 лет назад
Родитель
Сommit
72148dab12
66 измененных файлов с 1516 добавлено и 1590 удалено
  1. 15 2
      services/real-time/.eslintrc
  2. 1 1
      services/real-time/.github/dependabot.yml
  3. 1 1
      services/real-time/.nvmrc
  4. 5 1
      services/real-time/.prettierrc
  5. 1 1
      services/real-time/Dockerfile
  6. 9 9
      services/real-time/app.js
  7. 1 1
      services/real-time/app/js/AuthorizationManager.js
  8. 3 3
      services/real-time/app/js/ChannelManager.js
  9. 51 51
      services/real-time/app/js/ConnectedUsersManager.js
  10. 3 3
      services/real-time/app/js/DeploymentManager.js
  11. 9 9
      services/real-time/app/js/DocumentUpdaterController.js
  12. 21 19
      services/real-time/app/js/DocumentUpdaterManager.js
  13. 1 1
      services/real-time/app/js/DrainManager.js
  14. 4 4
      services/real-time/app/js/Errors.js
  15. 3 3
      services/real-time/app/js/EventLogger.js
  16. 1 1
      services/real-time/app/js/HttpApiController.js
  17. 5 5
      services/real-time/app/js/HttpController.js
  18. 2 2
      services/real-time/app/js/RedisClientManager.js
  19. 4 4
      services/real-time/app/js/RoomManager.js
  20. 50 45
      services/real-time/app/js/Router.js
  21. 2 2
      services/real-time/app/js/SafeJsonParse.js
  22. 1 1
      services/real-time/app/js/SessionSockets.js
  23. 5 5
      services/real-time/app/js/WebApiManager.js
  24. 182 184
      services/real-time/app/js/WebsocketController.js
  25. 13 14
      services/real-time/app/js/WebsocketLoadBalancer.js
  26. 2 2
      services/real-time/buildscript.txt
  27. 16 16
      services/real-time/config/settings.defaults.js
  28. 2 2
      services/real-time/config/settings.test.js
  29. 2 2
      services/real-time/docker-compose.yml
  30. 340 429
      services/real-time/package-lock.json
  31. 16 16
      services/real-time/package.json
  32. 59 61
      services/real-time/test/acceptance/js/ApplyUpdateTests.js
  33. 36 36
      services/real-time/test/acceptance/js/ClientTrackingTests.js
  34. 13 13
      services/real-time/test/acceptance/js/DrainManagerTests.js
  35. 31 31
      services/real-time/test/acceptance/js/EarlyDisconnect.js
  36. 11 11
      services/real-time/test/acceptance/js/HttpControllerTests.js
  37. 54 54
      services/real-time/test/acceptance/js/JoinDocTests.js
  38. 29 29
      services/real-time/test/acceptance/js/JoinProjectTests.js
  39. 10 10
      services/real-time/test/acceptance/js/LeaveDocTests.js
  40. 26 26
      services/real-time/test/acceptance/js/LeaveProjectTests.js
  41. 49 49
      services/real-time/test/acceptance/js/MatrixTests.js
  42. 37 37
      services/real-time/test/acceptance/js/PubSubRace.js
  43. 42 42
      services/real-time/test/acceptance/js/ReceiveUpdateTests.js
  44. 17 17
      services/real-time/test/acceptance/js/RouterTests.js
  45. 7 7
      services/real-time/test/acceptance/js/SessionSocketsTests.js
  46. 2 2
      services/real-time/test/acceptance/js/SessionTests.js
  47. 10 15
      services/real-time/test/acceptance/js/helpers/FixturesManager.js
  48. 4 4
      services/real-time/test/acceptance/js/helpers/MockDocUpdaterServer.js
  49. 4 4
      services/real-time/test/acceptance/js/helpers/MockWebServer.js
  50. 15 19
      services/real-time/test/acceptance/js/helpers/RealTimeClient.js
  51. 4 4
      services/real-time/test/acceptance/js/helpers/RealtimeServer.js
  52. 41 41
      services/real-time/test/acceptance/libs/XMLHttpRequest.js
  53. 5 5
      services/real-time/test/setup.js
  54. 17 17
      services/real-time/test/unit/js/AuthorizationManagerTests.js
  55. 5 5
      services/real-time/test/unit/js/ChannelManagerTests.js
  56. 30 30
      services/real-time/test/unit/js/ConnectedUsersManagerTests.js
  57. 25 23
      services/real-time/test/unit/js/DocumentUpdaterControllerTests.js
  58. 18 18
      services/real-time/test/unit/js/DocumentUpdaterManagerTests.js
  59. 10 10
      services/real-time/test/unit/js/DrainManagerTests.js
  60. 11 10
      services/real-time/test/unit/js/EventLoggerTests.js
  61. 10 10
      services/real-time/test/unit/js/RoomManagerTests.js
  62. 4 4
      services/real-time/test/unit/js/SafeJsonParseTest.js
  63. 12 12
      services/real-time/test/unit/js/SessionSocketsTests.js
  64. 16 16
      services/real-time/test/unit/js/WebApiManagerTests.js
  65. 51 49
      services/real-time/test/unit/js/WebsocketControllerTests.js
  66. 30 30
      services/real-time/test/unit/js/WebsocketLoadBalancerTests.js

+ 15 - 2
services/real-time/.eslintrc

@@ -3,9 +3,9 @@
 // https://github.com/sharelatex/sharelatex-dev-environment
 {
   "extends": [
+    "eslint:recommended",
     "standard",
-    "prettier",
-    "prettier/standard"
+    "prettier"
   ],
   "parserOptions": {
     "ecmaVersion": 2018
@@ -20,6 +20,19 @@
     "mocha": true
   },
   "rules": {
+    // TODO(das7pad): remove overrides after fixing all the violations manually (https://github.com/overleaf/issues/issues/3882#issuecomment-878999671)
+    // START of temporary overrides
+    "array-callback-return": "off",
+    "no-dupe-else-if": "off",
+    "no-var": "off",
+    "no-empty": "off",
+    "node/handle-callback-err": "off",
+    "no-loss-of-precision": "off",
+    "node/no-callback-literal": "off",
+    "node/no-path-concat": "off",
+    "prefer-regex-literals": "off",
+    // END of temporary overrides
+
     // Swap the no-unused-expressions rule with a more chai-friendly one
     "no-unused-expressions": 0,
     "chai-friendly/no-unused-expressions": "error",

+ 1 - 1
services/real-time/.github/dependabot.yml

@@ -20,4 +20,4 @@ updates:
     # future if we reorganise teams
     labels:
       - "dependencies"
-      - "Team-Magma"
+      - "type:maintenance"

+ 1 - 1
services/real-time/.nvmrc

@@ -1 +1 @@
-12.21.0
+12.22.3

+ 5 - 1
services/real-time/.prettierrc

@@ -2,6 +2,10 @@
 # Instead run bin/update_build_scripts from
 # https://github.com/sharelatex/sharelatex-dev-environment
 {
+  "arrowParens": "avoid",
   "semi": false,
-  "singleQuote": true
+  "singleQuote": true,
+  "trailingComma": "es5",
+  "tabWidth": 2,
+  "useTabs": false
 }

+ 1 - 1
services/real-time/Dockerfile

@@ -2,7 +2,7 @@
 # Instead run bin/update_build_scripts from
 # https://github.com/sharelatex/sharelatex-dev-environment
 
-FROM node:12.21.0 as base
+FROM node:12.22.3 as base
 
 WORKDIR /app
 

+ 9 - 9
services/real-time/app.js

@@ -1,5 +1,5 @@
 const Metrics = require('@overleaf/metrics')
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 Metrics.initialize(Settings.appName || 'real-time')
 const async = require('async')
 
@@ -34,7 +34,7 @@ const socketIoLogger = {
   },
   info() {},
   debug() {},
-  log() {}
+  log() {},
 }
 
 // monitor status file to take dark deployments out of the load-balancer
@@ -45,7 +45,7 @@ const app = express()
 
 const server = require('http').createServer(app)
 const io = require('socket.io').listen(server, {
-  logger: socketIoLogger
+  logger: socketIoLogger,
 })
 
 // Bind to sessions
@@ -78,7 +78,7 @@ io.configure(function () {
     'flashsocket',
     'htmlfile',
     'xhr-polling',
-    'jsonp-polling'
+    'jsonp-polling',
   ])
 })
 
@@ -195,10 +195,10 @@ function drainAndShutdown(signal) {
           const staleClients = io.sockets.clients()
           if (staleClients.length !== 0) {
             logger.warn(
-              { staleClients: staleClients.map((client) => client.id) },
+              { staleClients: staleClients.map(client => client.id) },
               'forcefully disconnecting stale clients'
             )
-            staleClients.forEach((client) => {
+            staleClients.forEach(client => {
               client.disconnect()
             })
           }
@@ -222,7 +222,7 @@ if (Settings.shutdownDrainTimeWindow) {
     'SIGUSR1',
     'SIGUSR2',
     'SIGTERM',
-    'SIGABRT'
+    'SIGABRT',
   ]) {
     process.on(signal, drainAndShutdown)
   } // signal is passed as argument to event handler
@@ -237,7 +237,7 @@ if (Settings.shutdownDrainTimeWindow) {
           'EHOSTUNREACH',
           'EPIPE',
           'ECONNRESET',
-          'ERR_STREAM_WRITE_AFTER_END'
+          'ERR_STREAM_WRITE_AFTER_END',
         ].includes(error.code)
       ) {
         Metrics.inc('disconnected_write', 1, { status: error.code })
@@ -266,7 +266,7 @@ if (Settings.continualPubsubTraffic) {
     const json = JSON.stringify({
       health_check: true,
       key: checker.id,
-      date: new Date().toString()
+      date: new Date().toString(),
     })
     Metrics.summary(`redis.publish.${channel}`, json.length)
     pubsubClient.publish(channel, json, function (err) {

+ 1 - 1
services/real-time/app/js/AuthorizationManager.js

@@ -63,5 +63,5 @@ module.exports = AuthorizationManager = {
   removeAccessToDoc(client, doc_id, callback) {
     delete client.ol_context[`doc:${doc_id}`]
     callback(null)
-  }
+  },
 }

+ 3 - 3
services/real-time/app/js/ChannelManager.js

@@ -1,6 +1,6 @@
 const logger = require('logger-sharelatex')
 const metrics = require('@overleaf/metrics')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const OError = require('@overleaf/o-error')
 
 const ClientMap = new Map() // for each redis client, store a Map of subscribed channels (channelname -> subscribe promise)
@@ -39,7 +39,7 @@ module.exports = {
           metrics.inc(`subscribe.failed.${baseChannel}`)
           // add context for the stack-trace at the call-site
           throw new OError('failed to subscribe to channel', {
-            channel
+            channel,
           }).withCause(err)
         })
     }
@@ -97,5 +97,5 @@ module.exports = {
     // we publish on a different client to the subscribe, so we can't
     // check for the channel existing here
     rclient.publish(channel, data)
-  }
+  },
 }

+ 51 - 51
services/real-time/app/js/ConnectedUsersManager.js

@@ -2,7 +2,7 @@
     camelcase,
 */
 const async = require('async')
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 const logger = require('logger-sharelatex')
 const redis = require('@overleaf/redis-wrapper')
 const OError = require('@overleaf/o-error')
@@ -111,66 +111,66 @@ module.exports = {
   },
 
   _getConnectedUser(project_id, client_id, callback) {
-    rclient.hgetall(Keys.connectedUser({ project_id, client_id }), function (
-      err,
-      result
-    ) {
-      if (err) {
-        err = new OError('problem fetching connected user details', {
-          other_client_id: client_id
-        }).withCause(err)
-        return callback(err)
-      }
-      if (!(result && result.user_id)) {
-        result = {
-          connected: false,
-          client_id
+    rclient.hgetall(
+      Keys.connectedUser({ project_id, client_id }),
+      function (err, result) {
+        if (err) {
+          err = new OError('problem fetching connected user details', {
+            other_client_id: client_id,
+          }).withCause(err)
+          return callback(err)
         }
-      } else {
-        result.connected = true
-        result.client_id = client_id
-        result.client_age =
-          (Date.now() - parseInt(result.last_updated_at, 10)) / 1000
-        if (result.cursorData) {
-          try {
-            result.cursorData = JSON.parse(result.cursorData)
-          } catch (e) {
-            OError.tag(e, 'error parsing cursorData JSON', {
-              other_client_id: client_id,
-              cursorData: result.cursorData
-            })
-            return callback(e)
+        if (!(result && result.user_id)) {
+          result = {
+            connected: false,
+            client_id,
+          }
+        } else {
+          result.connected = true
+          result.client_id = client_id
+          result.client_age =
+            (Date.now() - parseInt(result.last_updated_at, 10)) / 1000
+          if (result.cursorData) {
+            try {
+              result.cursorData = JSON.parse(result.cursorData)
+            } catch (e) {
+              OError.tag(e, 'error parsing cursorData JSON', {
+                other_client_id: client_id,
+                cursorData: result.cursorData,
+              })
+              return callback(e)
+            }
           }
         }
+        callback(err, result)
       }
-      callback(err, result)
-    })
+    )
   },
 
   getConnectedUsers(project_id, callback) {
     const self = this
-    rclient.smembers(Keys.clientsInProject({ project_id }), function (
-      err,
-      results
-    ) {
-      if (err) {
-        err = new OError('problem getting clients in project').withCause(err)
-        return callback(err)
-      }
-      const jobs = results.map((client_id) => (cb) =>
-        self._getConnectedUser(project_id, client_id, cb)
-      )
-      async.series(jobs, function (err, users) {
+    rclient.smembers(
+      Keys.clientsInProject({ project_id }),
+      function (err, results) {
         if (err) {
-          OError.tag(err, 'problem getting connected users')
+          err = new OError('problem getting clients in project').withCause(err)
           return callback(err)
         }
-        users = users.filter(
-          (user) =>
-            user && user.connected && user.client_age < REFRESH_TIMEOUT_IN_S
+        const jobs = results.map(
+          client_id => cb => self._getConnectedUser(project_id, client_id, cb)
         )
-        callback(null, users)
-      })
-    })
-  }
+        async.series(jobs, function (err, users) {
+          if (err) {
+            OError.tag(err, 'problem getting connected users')
+            return callback(err)
+          }
+          users = users.filter(
+            user =>
+              user && user.connected && user.client_age < REFRESH_TIMEOUT_IN_S
+          )
+          callback(null, users)
+        })
+      }
+    )
+  },
 }

+ 3 - 3
services/real-time/app/js/DeploymentManager.js

@@ -1,5 +1,5 @@
 const logger = require('logger-sharelatex')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const fs = require('fs')
 
 // Monitor a status file (e.g. /etc/real_time_status) periodically and close the
@@ -9,7 +9,7 @@ const FILE_CHECK_INTERVAL = 5000
 const statusFile = settings.deploymentFile
 const deploymentColour = settings.deploymentColour
 
-var serviceCloseTime
+let serviceCloseTime
 
 function updateDeploymentStatus(fileContent) {
   const closed = fileContent && !fileContent.includes(deploymentColour)
@@ -55,5 +55,5 @@ module.exports = {
   },
   deploymentIsClosed() {
     return settings.serviceIsClosed && Date.now() > serviceCloseTime
-  }
+  },
 }

+ 9 - 9
services/real-time/app/js/DocumentUpdaterController.js

@@ -2,7 +2,7 @@
     camelcase,
 */
 const logger = require('logger-sharelatex')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const RedisClientManager = require('./RedisClientManager')
 const SafeJsonParse = require('./SafeJsonParse')
 const EventLogger = require('./EventLogger')
@@ -50,7 +50,7 @@ module.exports = DocumentUpdaterController = {
   handleRoomUpdates(rclientSubList) {
     const roomEvents = RoomManager.eventSource()
     roomEvents.on('doc-active', function (doc_id) {
-      const subscribePromises = rclientSubList.map((rclient) =>
+      const subscribePromises = rclientSubList.map(rclient =>
         ChannelManager.subscribe(rclient, 'applied-ops', doc_id)
       )
       RoomManager.emitOnCompletion(
@@ -58,8 +58,8 @@ module.exports = DocumentUpdaterController = {
         `doc-subscribed-${doc_id}`
       )
     })
-    roomEvents.on('doc-empty', (doc_id) =>
-      rclientSubList.map((rclient) =>
+    roomEvents.on('doc-empty', doc_id =>
+      rclientSubList.map(rclient =>
         ChannelManager.unsubscribe(rclient, 'applied-ops', doc_id)
       )
     )
@@ -117,7 +117,7 @@ module.exports = DocumentUpdaterController = {
         doc_id,
         version: update.v,
         source: update.meta && update.meta.source,
-        socketIoClients: clientList.map((client) => client.id)
+        socketIoClients: clientList.map(client => client.id),
       },
       'distributing updates to clients'
     )
@@ -131,7 +131,7 @@ module.exports = DocumentUpdaterController = {
             {
               doc_id,
               version: update.v,
-              source: update.meta.source
+              source: update.meta.source,
             },
             'distributing update to sender'
           )
@@ -143,7 +143,7 @@ module.exports = DocumentUpdaterController = {
               doc_id,
               version: update.v,
               source: update.meta.source,
-              client_id: client.id
+              client_id: client.id,
             },
             'distributing update to collaborator'
           )
@@ -156,7 +156,7 @@ module.exports = DocumentUpdaterController = {
       logger.log(
         {
           doc_id,
-          socketIoClients: clientList.map((client) => client.id)
+          socketIoClients: clientList.map(client => client.id),
         },
         'discarded duplicate clients'
       )
@@ -172,5 +172,5 @@ module.exports = DocumentUpdaterController = {
       client.emit('otUpdateError', error, message)
       client.disconnect()
     }
-  }
+  },
 }

+ 21 - 19
services/real-time/app/js/DocumentUpdaterManager.js

@@ -5,13 +5,13 @@ const request = require('request')
 const _ = require('underscore')
 const OError = require('@overleaf/o-error')
 const logger = require('logger-sharelatex')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const metrics = require('@overleaf/metrics')
 const {
   ClientRequestedMissingOpsError,
   DocumentUpdaterRequestFailedError,
   NullBytesInOpError,
-  UpdateTooLargeError
+  UpdateTooLargeError,
 } = require('./Errors')
 
 const rclient = require('@overleaf/redis-wrapper').createClient(
@@ -105,7 +105,7 @@ const DocumentUpdaterManager = {
       'dupIfSource',
       'meta',
       'lastV',
-      'hash'
+      'hash',
     ]
     change = _.pick(change, allowedKeys)
     const jsonChange = JSON.stringify(change)
@@ -125,24 +125,26 @@ const DocumentUpdaterManager = {
     const doc_key = `${project_id}:${doc_id}`
     // Push onto pendingUpdates for doc_id first, because once the doc updater
     // gets an entry on pending-updates-list, it starts processing.
-    rclient.rpush(Keys.pendingUpdates({ doc_id }), jsonChange, function (
-      error
-    ) {
-      if (error) {
-        error = new OError('error pushing update into redis').withCause(error)
-        return callback(error)
-      }
-      const queueKey = DocumentUpdaterManager._getPendingUpdateListKey()
-      rclient.rpush(queueKey, doc_key, function (error) {
+    rclient.rpush(
+      Keys.pendingUpdates({ doc_id }),
+      jsonChange,
+      function (error) {
         if (error) {
-          error = new OError('error pushing doc_id into redis')
-            .withInfo({ queueKey })
-            .withCause(error)
+          error = new OError('error pushing update into redis').withCause(error)
+          return callback(error)
         }
-        callback(error)
-      })
-    })
-  }
+        const queueKey = DocumentUpdaterManager._getPendingUpdateListKey()
+        rclient.rpush(queueKey, doc_key, function (error) {
+          if (error) {
+            error = new OError('error pushing doc_id into redis')
+              .withInfo({ queueKey })
+              .withCause(error)
+          }
+          callback(error)
+        })
+      }
+    )
+  },
 }
 
 module.exports = DocumentUpdaterManager

+ 1 - 1
services/real-time/app/js/DrainManager.js

@@ -55,5 +55,5 @@ module.exports = {
       return true
     }
     return false
-  }
+  },
 }

+ 4 - 4
services/real-time/app/js/Errors.js

@@ -3,7 +3,7 @@ const OError = require('@overleaf/o-error')
 class ClientRequestedMissingOpsError extends OError {
   constructor(statusCode) {
     super('doc updater could not load requested ops', {
-      statusCode
+      statusCode,
     })
   }
 }
@@ -24,7 +24,7 @@ class DataTooLargeToParseError extends OError {
   constructor(data) {
     super('data too large to parse', {
       head: data.slice(0, 1024),
-      length: data.length
+      length: data.length,
     })
   }
 }
@@ -33,7 +33,7 @@ class DocumentUpdaterRequestFailedError extends OError {
   constructor(action, statusCode) {
     super('doc updater returned a non-success status code', {
       action,
-      statusCode
+      statusCode,
     })
   }
 }
@@ -99,5 +99,5 @@ module.exports = {
   NullBytesInOpError,
   UnexpectedArgumentsError,
   UpdateTooLargeError,
-  WebApiRequestFailedError
+  WebApiRequestFailedError,
 }

+ 3 - 3
services/real-time/app/js/EventLogger.js

@@ -4,7 +4,7 @@
 let EventLogger
 const logger = require('logger-sharelatex')
 const metrics = require('@overleaf/metrics')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 
 // keep track of message counters to detect duplicate and out of order events
 // messsage ids have the format "UNIQUEHOSTKEY-COUNTER"
@@ -43,7 +43,7 @@ module.exports = EventLogger = {
     // store the last count in a hash for each host
     const previous = EventLogger._storeEventCount(key, count)
     if (!previous || count === previous + 1) {
-      metrics.inc(`event.${channel}.valid`, 0.001) // downsample high rate docupdater events
+      metrics.inc(`event.${channel}.valid`)
       return // order is ok
     }
     if (count === previous) {
@@ -80,5 +80,5 @@ module.exports = EventLogger = {
         delete EVENT_LOG_TIMESTAMP[key]
       }
     })
-  }
+  },
 }

+ 1 - 1
services/real-time/app/js/HttpApiController.js

@@ -48,5 +48,5 @@ module.exports = {
     logger.warn({ client_id }, 'api: requesting client disconnect')
     client.on('disconnect', () => res.sendStatus(204))
     client.disconnect()
-  }
+  },
 }

+ 5 - 5
services/real-time/app/js/HttpController.js

@@ -17,7 +17,7 @@ module.exports = HttpController = {
       first_name,
       last_name,
       email,
-      connected_time
+      connected_time,
     } = ioClient.ol_context
     const client = {
       client_id,
@@ -26,14 +26,14 @@ module.exports = HttpController = {
       first_name,
       last_name,
       email,
-      connected_time
+      connected_time,
     }
     client.rooms = Object.keys(ioClient.manager.roomClients[client_id] || {})
       // drop the namespace
-      .filter((room) => room !== '')
+      .filter(room => room !== '')
       // room names are composed as '<NAMESPACE>/<ROOM>' and the default
       //  namespace is empty (see comments in RoomManager), just drop the '/'
-      .map((fullRoomPath) => fullRoomPath.slice(1))
+      .map(fullRoomPath => fullRoomPath.slice(1))
     return client
   },
 
@@ -53,5 +53,5 @@ module.exports = HttpController = {
       return
     }
     res.json(HttpController._getConnectedClientView(ioClient))
-  }
+  },
 }

+ 2 - 2
services/real-time/app/js/RedisClientManager.js

@@ -4,7 +4,7 @@ const logger = require('logger-sharelatex')
 module.exports = {
   createClientList(...configs) {
     // create a dynamic list of redis clients, excluding any configurations which are not defined
-    return configs.filter(Boolean).map((x) => {
+    return configs.filter(Boolean).map(x => {
       const redisType = x.cluster
         ? 'cluster'
         : x.sentinels
@@ -15,5 +15,5 @@ module.exports = {
       logger.log({ redis: redisType }, 'creating redis client')
       return redis.createClient(x)
     })
-  }
+  },
 }

+ 4 - 4
services/real-time/app/js/RoomManager.js

@@ -49,7 +49,7 @@ module.exports = {
   emitOnCompletion(promiseList, eventName) {
     Promise.all(promiseList)
       .then(() => RoomEvents.emit(eventName))
-      .catch((err) => RoomEvents.emit(eventName, err))
+      .catch(err => RoomEvents.emit(eventName, err))
   },
 
   eventSource() {
@@ -150,15 +150,15 @@ module.exports = {
     return (
       Object.keys(rooms)
         // drop the namespace
-        .filter((room) => room !== '')
+        .filter(room => room !== '')
         // room names are composed as '<NAMESPACE>/<ROOM>' and the default
         //  namespace is empty (see comments above), just drop the '/'
-        .map((fullRoomPath) => fullRoomPath.slice(1))
+        .map(fullRoomPath => fullRoomPath.slice(1))
     )
   },
 
   _clientAlreadyInRoom(client, room) {
     const rooms = client.manager.roomClients[client.id] || {}
     return !!rooms['/' + room]
-  }
+  },
 }

+ 50 - 45
services/real-time/app/js/Router.js

@@ -3,7 +3,7 @@
 */
 const metrics = require('@overleaf/metrics')
 const logger = require('logger-sharelatex')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const WebsocketController = require('./WebsocketController')
 const HttpController = require('./HttpController')
 const HttpApiController = require('./HttpApiController')
@@ -52,7 +52,7 @@ module.exports = Router = {
       [
         'not authorized',
         'joinLeaveEpoch mismatch',
-        'doc updater could not load requested ops'
+        'doc updater could not load requested ops',
       ].includes(error.message)
     ) {
       logger.warn(attrs, error.message)
@@ -62,7 +62,7 @@ module.exports = Router = {
       logger.error(attrs, `server side error in ${method}`)
       // Don't return raw error to prevent leaking server side info
       const serializedError = {
-        message: 'Something went wrong in real-time service'
+        message: 'Something went wrong in real-time service',
       }
       callback(serializedError)
     }
@@ -201,7 +201,7 @@ module.exports = Router = {
             if (err) {
               Router._handleError(callback, err, client, 'joinProject', {
                 project_id: data.project_id,
-                user_id: user._id
+                user_id: user._id,
               })
             } else {
               callback(null, ...args)
@@ -263,7 +263,7 @@ module.exports = Router = {
             if (err) {
               Router._handleError(callback, err, client, 'joinDoc', {
                 doc_id,
-                fromVersion
+                fromVersion,
               })
             } else {
               callback(null, ...args)
@@ -280,7 +280,7 @@ module.exports = Router = {
         WebsocketController.leaveDoc(client, doc_id, function (err, ...args) {
           if (err) {
             Router._handleError(callback, err, client, 'leaveDoc', {
-              doc_id
+              doc_id,
             })
           } else {
             callback(null, ...args)
@@ -311,36 +311,38 @@ module.exports = Router = {
         })
       })
 
-      client.on('clientTracking.updatePosition', function (
-        cursorData,
-        callback
-      ) {
-        if (!callback) {
-          callback = function () {}
-        }
-        if (typeof callback !== 'function') {
-          return Router._handleInvalidArguments(
-            client,
-            'clientTracking.updatePosition',
-            arguments
-          )
-        }
-
-        WebsocketController.updateClientPosition(client, cursorData, function (
-          err
-        ) {
-          if (err) {
-            Router._handleError(
-              callback,
-              err,
+      client.on(
+        'clientTracking.updatePosition',
+        function (cursorData, callback) {
+          if (!callback) {
+            callback = function () {}
+          }
+          if (typeof callback !== 'function') {
+            return Router._handleInvalidArguments(
               client,
-              'clientTracking.updatePosition'
+              'clientTracking.updatePosition',
+              arguments
             )
-          } else {
-            callback()
           }
-        })
-      })
+
+          WebsocketController.updateClientPosition(
+            client,
+            cursorData,
+            function (err) {
+              if (err) {
+                Router._handleError(
+                  callback,
+                  err,
+                  client,
+                  'clientTracking.updatePosition'
+                )
+              } else {
+                callback()
+              }
+            }
+          )
+        }
+      )
 
       client.on('applyOtUpdate', function (doc_id, update, callback) {
         if (typeof callback !== 'function') {
@@ -351,19 +353,22 @@ module.exports = Router = {
           )
         }
 
-        WebsocketController.applyOtUpdate(client, doc_id, update, function (
-          err
-        ) {
-          if (err) {
-            Router._handleError(callback, err, client, 'applyOtUpdate', {
-              doc_id,
-              update
-            })
-          } else {
-            callback()
+        WebsocketController.applyOtUpdate(
+          client,
+          doc_id,
+          update,
+          function (err) {
+            if (err) {
+              Router._handleError(callback, err, client, 'applyOtUpdate', {
+                doc_id,
+                update,
+              })
+            } else {
+              callback()
+            }
           }
-        })
+        )
       })
     })
-  }
+  },
 }

+ 2 - 2
services/real-time/app/js/SafeJsonParse.js

@@ -1,4 +1,4 @@
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 const { DataTooLargeToParseError } = require('./Errors')
 
 module.exports = {
@@ -13,5 +13,5 @@ module.exports = {
       return callback(e)
     }
     callback(null, parsed)
-  }
+  },
 }

+ 1 - 1
services/real-time/app/js/SessionSockets.js

@@ -20,7 +20,7 @@ module.exports = function (io, sessionStore, cookieParser, cookieName) {
       sessionStore.get(sessionId, function (error, session) {
         if (error) {
           OError.tag(error, 'error getting session from sessionStore', {
-            sessionId
+            sessionId,
           })
           return next(error, socket)
         }

+ 5 - 5
services/real-time/app/js/WebApiManager.js

@@ -3,13 +3,13 @@
 */
 const request = require('request')
 const OError = require('@overleaf/o-error')
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const logger = require('logger-sharelatex')
 const {
   CodedError,
   CorruptedJoinProjectResponseError,
   NotAuthorizedError,
-  WebApiRequestFailedError
+  WebApiRequestFailedError,
 } = require('./Errors')
 
 module.exports = {
@@ -28,11 +28,11 @@ module.exports = {
         auth: {
           user: settings.apis.web.user,
           pass: settings.apis.web.pass,
-          sendImmediately: true
+          sendImmediately: true,
         },
         json: true,
         jar: false,
-        headers
+        headers,
       },
       function (error, response, data) {
         if (error) {
@@ -65,5 +65,5 @@ module.exports = {
         }
       }
     )
-  }
+  },
 }

+ 182 - 184
services/real-time/app/js/WebsocketController.js

@@ -13,7 +13,7 @@ const RoomManager = require('./RoomManager')
 const {
   JoinLeaveEpochMismatchError,
   NotAuthorizedError,
-  NotJoinedError
+  NotJoinedError,
 } = require('./Errors')
 
 let WebsocketController
@@ -26,7 +26,7 @@ module.exports = WebsocketController = {
   joinProject(client, user, project_id, callback) {
     if (client.disconnected) {
       metrics.inc('editor.join-project.disconnected', 1, {
-        status: 'immediately'
+        status: 'immediately',
       })
       return callback()
     }
@@ -37,71 +37,70 @@ module.exports = WebsocketController = {
       'user joining project'
     )
     metrics.inc('editor.join-project', 1, { status: client.transport })
-    WebApiManager.joinProject(project_id, user, function (
-      error,
-      project,
-      privilegeLevel,
-      isRestrictedUser
-    ) {
-      if (error) {
-        return callback(error)
-      }
-      if (client.disconnected) {
-        metrics.inc('editor.join-project.disconnected', 1, {
-          status: 'after-web-api-call'
-        })
-        return callback()
-      }
-
-      if (!privilegeLevel) {
-        return callback(new NotAuthorizedError())
-      }
+    WebApiManager.joinProject(
+      project_id,
+      user,
+      function (error, project, privilegeLevel, isRestrictedUser) {
+        if (error) {
+          return callback(error)
+        }
+        if (client.disconnected) {
+          metrics.inc('editor.join-project.disconnected', 1, {
+            status: 'after-web-api-call',
+          })
+          return callback()
+        }
 
-      client.ol_context = {}
-      client.ol_context.privilege_level = privilegeLevel
-      client.ol_context.user_id = user_id
-      client.ol_context.project_id = project_id
-      client.ol_context.owner_id = project.owner && project.owner._id
-      client.ol_context.first_name = user.first_name
-      client.ol_context.last_name = user.last_name
-      client.ol_context.email = user.email
-      client.ol_context.connected_time = new Date()
-      client.ol_context.signup_date = user.signUpDate
-      client.ol_context.login_count = user.loginCount
-      client.ol_context.is_restricted_user = !!isRestrictedUser
-
-      RoomManager.joinProject(client, project_id, function (err) {
-        if (err) {
-          return callback(err)
+        if (!privilegeLevel) {
+          return callback(new NotAuthorizedError())
         }
-        logger.log(
-          { user_id, project_id, client_id: client.id },
-          'user joined project'
-        )
-        callback(
-          null,
-          project,
-          privilegeLevel,
-          WebsocketController.PROTOCOL_VERSION
-        )
-      })
 
-      // No need to block for setting the user as connected in the cursor tracking
-      ConnectedUsersManager.updateUserPosition(
-        project_id,
-        client.publicId,
-        user,
-        null,
-        function (err) {
+        client.ol_context = {}
+        client.ol_context.privilege_level = privilegeLevel
+        client.ol_context.user_id = user_id
+        client.ol_context.project_id = project_id
+        client.ol_context.owner_id = project.owner && project.owner._id
+        client.ol_context.first_name = user.first_name
+        client.ol_context.last_name = user.last_name
+        client.ol_context.email = user.email
+        client.ol_context.connected_time = new Date()
+        client.ol_context.signup_date = user.signUpDate
+        client.ol_context.login_count = user.loginCount
+        client.ol_context.is_restricted_user = !!isRestrictedUser
+
+        RoomManager.joinProject(client, project_id, function (err) {
           if (err) {
-            logger.warn(
-              { err, project_id, user_id, client_id: client.id },
-              'background cursor update failed'
-            )
+            return callback(err)
           }
-        }
-      )
-    })
+          logger.log(
+            { user_id, project_id, client_id: client.id },
+            'user joined project'
+          )
+          callback(
+            null,
+            project,
+            privilegeLevel,
+            WebsocketController.PROTOCOL_VERSION
+          )
+        })
+
+        // No need to block for setting the user as connected in the cursor tracking
+        ConnectedUsersManager.updateUserPosition(
+          project_id,
+          client.publicId,
+          user,
+          null,
+          function (err) {
+            if (err) {
+              logger.warn(
+                { err, project_id, user_id, client_id: client.id },
+                'background cursor update failed'
+              )
+            }
+          }
+        )
+      }
+    )
   },
 
   // We want to flush a project if there are no more (local) connected clients
@@ -177,110 +176,112 @@ module.exports = WebsocketController = {
       'client joining doc'
     )
 
-    WebsocketController._assertClientAuthorization(client, doc_id, function (
-      error
-    ) {
-      if (error) {
-        return callback(error)
-      }
-      if (client.disconnected) {
-        metrics.inc('editor.join-doc.disconnected', 1, {
-          status: 'after-client-auth-check'
-        })
-        // the client will not read the response anyways
-        return callback()
-      }
-      if (joinLeaveEpoch !== client.joinLeaveEpoch) {
-        // another joinDoc or leaveDoc rpc overtook us
-        return callback(new JoinLeaveEpochMismatchError())
-      }
-      // ensure the per-doc applied-ops channel is subscribed before sending the
-      // doc to the client, so that no events are missed.
-      RoomManager.joinDoc(client, doc_id, function (error) {
+    WebsocketController._assertClientAuthorization(
+      client,
+      doc_id,
+      function (error) {
         if (error) {
           return callback(error)
         }
         if (client.disconnected) {
           metrics.inc('editor.join-doc.disconnected', 1, {
-            status: 'after-joining-room'
+            status: 'after-client-auth-check',
           })
           // the client will not read the response anyways
           return callback()
         }
+        if (joinLeaveEpoch !== client.joinLeaveEpoch) {
+          // another joinDoc or leaveDoc rpc overtook us
+          return callback(new JoinLeaveEpochMismatchError())
+        }
+        // ensure the per-doc applied-ops channel is subscribed before sending the
+        // doc to the client, so that no events are missed.
+        RoomManager.joinDoc(client, doc_id, function (error) {
+          if (error) {
+            return callback(error)
+          }
+          if (client.disconnected) {
+            metrics.inc('editor.join-doc.disconnected', 1, {
+              status: 'after-joining-room',
+            })
+            // the client will not read the response anyways
+            return callback()
+          }
 
-        DocumentUpdaterManager.getDocument(
-          project_id,
-          doc_id,
-          fromVersion,
-          function (error, lines, version, ranges, ops) {
-            if (error) {
-              return callback(error)
-            }
-            if (client.disconnected) {
-              metrics.inc('editor.join-doc.disconnected', 1, {
-                status: 'after-doc-updater-call'
-              })
-              // the client will not read the response anyways
-              return callback()
-            }
-
-            if (is_restricted_user && ranges && ranges.comments) {
-              ranges.comments = []
-            }
+          DocumentUpdaterManager.getDocument(
+            project_id,
+            doc_id,
+            fromVersion,
+            function (error, lines, version, ranges, ops) {
+              if (error) {
+                return callback(error)
+              }
+              if (client.disconnected) {
+                metrics.inc('editor.join-doc.disconnected', 1, {
+                  status: 'after-doc-updater-call',
+                })
+                // the client will not read the response anyways
+                return callback()
+              }
 
-            // Encode any binary bits of data so it can go via WebSockets
-            // See http://ecmanaut.blogspot.co.uk/2006/07/encoding-decoding-utf8-in-javascript.html
-            const encodeForWebsockets = (text) =>
-              unescape(encodeURIComponent(text))
-            const escapedLines = []
-            for (let line of lines) {
-              try {
-                line = encodeForWebsockets(line)
-              } catch (err) {
-                OError.tag(err, 'error encoding line uri component', { line })
-                return callback(err)
+              if (is_restricted_user && ranges && ranges.comments) {
+                ranges.comments = []
               }
-              escapedLines.push(line)
-            }
-            if (options.encodeRanges) {
-              try {
-                for (const comment of (ranges && ranges.comments) || []) {
-                  if (comment.op.c) {
-                    comment.op.c = encodeForWebsockets(comment.op.c)
-                  }
+
+              // Encode any binary bits of data so it can go via WebSockets
+              // See http://ecmanaut.blogspot.co.uk/2006/07/encoding-decoding-utf8-in-javascript.html
+              const encodeForWebsockets = text =>
+                unescape(encodeURIComponent(text))
+              const escapedLines = []
+              for (let line of lines) {
+                try {
+                  line = encodeForWebsockets(line)
+                } catch (err) {
+                  OError.tag(err, 'error encoding line uri component', { line })
+                  return callback(err)
                 }
-                for (const change of (ranges && ranges.changes) || []) {
-                  if (change.op.i) {
-                    change.op.i = encodeForWebsockets(change.op.i)
+                escapedLines.push(line)
+              }
+              if (options.encodeRanges) {
+                try {
+                  for (const comment of (ranges && ranges.comments) || []) {
+                    if (comment.op.c) {
+                      comment.op.c = encodeForWebsockets(comment.op.c)
+                    }
                   }
-                  if (change.op.d) {
-                    change.op.d = encodeForWebsockets(change.op.d)
+                  for (const change of (ranges && ranges.changes) || []) {
+                    if (change.op.i) {
+                      change.op.i = encodeForWebsockets(change.op.i)
+                    }
+                    if (change.op.d) {
+                      change.op.d = encodeForWebsockets(change.op.d)
+                    }
                   }
+                } catch (err) {
+                  OError.tag(err, 'error encoding range uri component', {
+                    ranges,
+                  })
+                  return callback(err)
                 }
-              } catch (err) {
-                OError.tag(err, 'error encoding range uri component', {
-                  ranges
-                })
-                return callback(err)
               }
-            }
 
-            AuthorizationManager.addAccessToDoc(client, doc_id, () => {})
-            logger.log(
-              {
-                user_id,
-                project_id,
-                doc_id,
-                fromVersion,
-                client_id: client.id
-              },
-              'client joined doc'
-            )
-            callback(null, escapedLines, version, ops, ranges)
-          }
-        )
-      })
-    })
+              AuthorizationManager.addAccessToDoc(client, doc_id, () => {})
+              logger.log(
+                {
+                  user_id,
+                  project_id,
+                  doc_id,
+                  fromVersion,
+                  client_id: client.id,
+                },
+                'client joined doc'
+              )
+              callback(null, escapedLines, version, ops, ranges)
+            }
+          )
+        })
+      }
+    )
   },
 
   _assertClientAuthorization(client, doc_id, callback) {
@@ -297,16 +298,18 @@ module.exports = WebsocketController = {
           if (error) {
             // No cached access, check docupdater
             const { project_id } = client.ol_context
-            DocumentUpdaterManager.checkDocument(project_id, doc_id, function (
-              error
-            ) {
-              if (error) {
-                return callback(error)
-              } else {
-                // Success
-                AuthorizationManager.addAccessToDoc(client, doc_id, callback)
+            DocumentUpdaterManager.checkDocument(
+              project_id,
+              doc_id,
+              function (error) {
+                if (error) {
+                  return callback(error)
+                } else {
+                  // Success
+                  AuthorizationManager.addAccessToDoc(client, doc_id, callback)
+                }
               }
-            })
+            )
           } else {
             // Access already cached
             callback()
@@ -339,15 +342,10 @@ module.exports = WebsocketController = {
     }
 
     metrics.inc('editor.update-client-position', 0.1, {
-      status: client.transport
+      status: client.transport,
     })
-    const {
-      project_id,
-      first_name,
-      last_name,
-      email,
-      user_id
-    } = client.ol_context
+    const { project_id, first_name, last_name, email, user_id } =
+      client.ol_context
     logger.log(
       { user_id, project_id, client_id: client.id, cursorData },
       'updating client position'
@@ -388,12 +386,12 @@ module.exports = WebsocketController = {
               first_name,
               last_name,
               email,
-              _id: user_id
+              _id: user_id,
             },
             {
               row: cursorData.row,
               column: cursorData.column,
-              doc_id: cursorData.doc_id
+              doc_id: cursorData.doc_id,
             },
             callback
           )
@@ -433,19 +431,19 @@ module.exports = WebsocketController = {
       WebsocketLoadBalancer.emitToRoom(project_id, 'clientTracking.refresh')
       setTimeout(
         () =>
-          ConnectedUsersManager.getConnectedUsers(project_id, function (
-            error,
-            users
-          ) {
-            if (error) {
-              return callback(error)
+          ConnectedUsersManager.getConnectedUsers(
+            project_id,
+            function (error, users) {
+              if (error) {
+                return callback(error)
+              }
+              logger.log(
+                { user_id, project_id, client_id: client.id },
+                'got connected users'
+              )
+              callback(null, users)
             }
-            logger.log(
-              { user_id, project_id, client_id: client.id },
-              'got connected users'
-            )
-            callback(null, users)
-          }),
+          ),
         WebsocketController.CLIENT_REFRESH_DELAY
       )
     })
@@ -485,7 +483,7 @@ module.exports = WebsocketController = {
             doc_id,
             project_id,
             client_id: client.id,
-            version: update.v
+            version: update.v,
           },
           'sending update to doc updater'
         )
@@ -510,13 +508,13 @@ module.exports = WebsocketController = {
               const message = {
                 project_id,
                 doc_id,
-                error: 'update is too large'
+                error: 'update is too large',
               }
               setTimeout(function () {
                 if (client.disconnected) {
                   // skip the message broadcast, the client has moved on
                   return metrics.inc('editor.doc-update.disconnected', 1, {
-                    status: 'at-otUpdateError'
+                    status: 'at-otUpdateError',
                   })
                 }
                 client.emit('otUpdateError', message.error, message)
@@ -527,7 +525,7 @@ module.exports = WebsocketController = {
 
             if (error) {
               OError.tag(error, 'document was not available for update', {
-                version: update.v
+                version: update.v,
               })
               client.disconnect()
             }
@@ -571,5 +569,5 @@ module.exports = WebsocketController = {
       }
     }
     return true
-  }
+  },
 }

+ 13 - 14
services/real-time/app/js/WebsocketLoadBalancer.js

@@ -1,7 +1,7 @@
 /* eslint-disable
     camelcase,
 */
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 const logger = require('logger-sharelatex')
 const RedisClientManager = require('./RedisClientManager')
 const SafeJsonParse = require('./SafeJsonParse')
@@ -19,7 +19,7 @@ const RESTRICTED_USER_MESSAGE_TYPE_PASS_LIST = [
   'reciveNewDoc',
   'reciveNewFile',
   'reciveNewFolder',
-  'removeEntity'
+  'removeEntity',
 ]
 
 let WebsocketLoadBalancer
@@ -38,14 +38,14 @@ module.exports = WebsocketLoadBalancer = {
     const data = JSON.stringify({
       room_id,
       message,
-      payload
+      payload,
     })
     logger.log(
       { room_id, message, payload, length: data.length },
       'emitting to room'
     )
 
-    this.rclientPubList.map((rclientPub) =>
+    this.rclientPubList.map(rclientPub =>
       ChannelManager.publish(rclientPub, 'editor-events', room_id, data)
     )
   },
@@ -74,7 +74,7 @@ module.exports = WebsocketLoadBalancer = {
   handleRoomUpdates(rclientSubList) {
     const roomEvents = RoomManager.eventSource()
     roomEvents.on('project-active', function (project_id) {
-      const subscribePromises = rclientSubList.map((rclient) =>
+      const subscribePromises = rclientSubList.map(rclient =>
         ChannelManager.subscribe(rclient, 'editor-events', project_id)
       )
       RoomManager.emitOnCompletion(
@@ -82,8 +82,8 @@ module.exports = WebsocketLoadBalancer = {
         `project-subscribed-${project_id}`
       )
     })
-    roomEvents.on('project-empty', (project_id) =>
-      rclientSubList.map((rclient) =>
+    roomEvents.on('project-empty', project_id =>
+      rclientSubList.map(rclient =>
         ChannelManager.unsubscribe(rclient, 'editor-events', project_id)
       )
     )
@@ -108,7 +108,7 @@ module.exports = WebsocketLoadBalancer = {
             message: message.message,
             room_id: message.room_id,
             message_id: message._id,
-            socketIoClients: clientList.map((client) => client.id)
+            socketIoClients: clientList.map(client => client.id),
           },
           'refreshing client list'
         )
@@ -127,15 +127,14 @@ module.exports = WebsocketLoadBalancer = {
           }
         }
 
-        const is_restricted_message = !RESTRICTED_USER_MESSAGE_TYPE_PASS_LIST.includes(
-          message.message
-        )
+        const is_restricted_message =
+          !RESTRICTED_USER_MESSAGE_TYPE_PASS_LIST.includes(message.message)
 
         // send messages only to unique clients (due to duplicate entries in io.sockets.clients)
         const clientList = io.sockets
           .clients(message.room_id)
           .filter(
-            (client) =>
+            client =>
               !(is_restricted_message && client.ol_context.is_restricted_user)
           )
 
@@ -149,7 +148,7 @@ module.exports = WebsocketLoadBalancer = {
             message: message.message,
             room_id: message.room_id,
             message_id: message._id,
-            socketIoClients: clientList.map((client) => client.id)
+            socketIoClients: clientList.map(client => client.id),
           },
           'distributing event to clients'
         )
@@ -168,5 +167,5 @@ module.exports = WebsocketLoadBalancer = {
         HealthCheckManager.check(channel, message.key)
       }
     })
-  }
+  },
 }

+ 2 - 2
services/real-time/buildscript.txt

@@ -3,6 +3,6 @@ real-time
 --docker-repos=gcr.io/overleaf-ops
 --env-add=
 --env-pass-through=
---node-version=12.21.0
+--node-version=12.22.3
 --public-repo=True
---script-version=3.8.0
+--script-version=3.11.0

+ 16 - 16
services/real-time/config/settings.defaults.js

@@ -12,7 +12,7 @@ const settings = {
         process.env.PUBSUB_REDIS_MAX_RETRIES_PER_REQUEST ||
           process.env.REDIS_MAX_RETRIES_PER_REQUEST ||
           '20'
-      )
+      ),
     },
 
     realtime: {
@@ -32,13 +32,13 @@ const settings = {
         },
         connectedUser({ project_id, client_id }) {
           return `connected_user:{${project_id}}:${client_id}`
-        }
+        },
       },
       maxRetriesPerRequest: parseInt(
         process.env.REAL_TIME_REDIS_MAX_RETRIES_PER_REQUEST ||
           process.env.REDIS_MAX_RETRIES_PER_REQUEST ||
           '20'
-      )
+      ),
     },
 
     documentupdater: {
@@ -55,13 +55,13 @@ const settings = {
       key_schema: {
         pendingUpdates({ doc_id }) {
           return `PendingUpdates:{${doc_id}}`
-        }
+        },
       },
       maxRetriesPerRequest: parseInt(
         process.env.DOC_UPDATER_REDIS_MAX_RETRIES_PER_REQUEST ||
           process.env.REDIS_MAX_RETRIES_PER_REQUEST ||
           '20'
-      )
+      ),
     },
 
     websessions: {
@@ -73,8 +73,8 @@ const settings = {
         process.env.WEB_REDIS_MAX_RETRIES_PER_REQUEST ||
           process.env.REDIS_MAX_RETRIES_PER_REQUEST ||
           '20'
-      )
-    }
+      ),
+    },
   },
 
   internal: {
@@ -82,8 +82,8 @@ const settings = {
       port: 3026,
       host: process.env.LISTEN_ADDRESS || 'localhost',
       user: 'sharelatex',
-      pass: 'password'
-    }
+      pass: 'password',
+    },
   },
 
   apis: {
@@ -92,19 +92,19 @@ const settings = {
         process.env.WEB_API_HOST || process.env.WEB_HOST || 'localhost'
       }:${process.env.WEB_API_PORT || process.env.WEB_PORT || 3000}`,
       user: process.env.WEB_API_USER || 'sharelatex',
-      pass: process.env.WEB_API_PASSWORD || 'password'
+      pass: process.env.WEB_API_PASSWORD || 'password',
     },
     documentupdater: {
       url: `http://${
         process.env.DOCUMENT_UPDATER_HOST ||
         process.env.DOCUPDATER_HOST ||
         'localhost'
-      }:3003`
-    }
+      }:3003`,
+    },
   },
 
   security: {
-    sessionSecret: process.env.SESSION_SECRET || 'secret-please-change'
+    sessionSecret: process.env.SESSION_SECRET || 'secret-please-change',
   },
 
   cookieName: process.env.COOKIE_NAME || 'sharelatex.sid',
@@ -155,13 +155,13 @@ const settings = {
   deploymentFile: process.env.DEPLOYMENT_FILE,
 
   sentry: {
-    dsn: process.env.SENTRY_DSN
+    dsn: process.env.SENTRY_DSN,
   },
 
   errors: {
     catchUncaughtErrors: true,
-    shutdownOnUncaughtError: true
-  }
+    shutdownOnUncaughtError: true,
+  },
 }
 
 // console.log settings.redis

+ 2 - 2
services/real-time/config/settings.test.js

@@ -1,5 +1,5 @@
 module.exports = {
   errors: {
-    catchUncaughtErrors: false
-  }
+    catchUncaughtErrors: false,
+  },
 }

+ 2 - 2
services/real-time/docker-compose.yml

@@ -6,7 +6,7 @@ version: "2.3"
 
 services:
   test_unit:
-    image: node:12.21.0
+    image: node:12.22.3
     volumes:
       - .:/app
     working_dir: /app
@@ -18,7 +18,7 @@ services:
     user: node
 
   test_acceptance:
-    image: node:12.21.0
+    image: node:12.22.3
     volumes:
       - .:/app
     working_dir: /app

Разница между файлами не показана из-за своего большого размера
+ 340 - 429
services/real-time/package-lock.json


+ 16 - 16
services/real-time/package.json

@@ -16,14 +16,16 @@
     "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
     "test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
     "nodemon": "nodemon --config nodemon.json",
-    "lint": "node_modules/.bin/eslint --max-warnings 0 .",
-    "format": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --list-different",
-    "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write"
+    "lint": "eslint --max-warnings 0 --format unix .",
+    "format": "prettier --list-different $PWD/'**/*.js'",
+    "format:fix": "prettier --write $PWD/'**/*.js'",
+    "lint:fix": "eslint --fix ."
   },
   "dependencies": {
     "@overleaf/metrics": "^3.5.1",
     "@overleaf/o-error": "^3.1.0",
     "@overleaf/redis-wrapper": "^2.0.0",
+    "@overleaf/settings": "^2.1.1",
     "async": "^0.9.0",
     "base64id": "0.1.0",
     "basic-auth-connect": "^1.0.0",
@@ -35,28 +37,26 @@
     "express-session": "^1.17.1",
     "logger-sharelatex": "^2.2.0",
     "request": "^2.88.2",
-    "settings-sharelatex": "^1.1.0",
     "socket.io": "https://github.com/overleaf/socket.io/archive/0.9.19-overleaf-5.tar.gz",
     "socket.io-client": "https://github.com/overleaf/socket.io-client/archive/0.9.17-overleaf-3.tar.gz",
     "underscore": "1.13.1"
   },
   "devDependencies": {
-    "chai": "~1.9.1",
+    "chai": "^4.2.0",
+    "chai-as-promised": "^7.1.1",
     "cookie-signature": "^1.1.0",
-    "eslint": "^6.8.0",
-    "eslint-config-prettier": "^6.10.0",
-    "eslint-config-standard": "^14.1.0",
-    "eslint-plugin-chai-expect": "^2.1.0",
-    "eslint-plugin-chai-friendly": "^0.5.0",
-    "eslint-plugin-import": "^2.20.1",
-    "eslint-plugin-mocha": "^6.3.0",
-    "eslint-plugin-node": "^11.0.0",
+    "eslint": "^7.21.0",
+    "eslint-config-prettier": "^8.1.0",
+    "eslint-config-standard": "^16.0.2",
+    "eslint-plugin-chai-expect": "^2.2.0",
+    "eslint-plugin-chai-friendly": "^0.6.0",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-mocha": "^8.0.0",
+    "eslint-plugin-node": "^11.1.0",
     "eslint-plugin-prettier": "^3.1.2",
     "eslint-plugin-promise": "^4.2.1",
-    "eslint-plugin-standard": "^4.0.1",
     "mocha": "^8.3.2",
-    "prettier": "^2.0.0",
-    "prettier-eslint-cli": "^5.0.0",
+    "prettier": "^2.2.1",
     "sandboxed-module": "~0.3.0",
     "sinon": "^9.2.4",
     "timekeeper": "0.0.4",

+ 59 - 61
services/real-time/test/acceptance/js/ApplyUpdateTests.js

@@ -18,13 +18,13 @@ const { expect } = require('chai')
 const RealTimeClient = require('./helpers/RealTimeClient')
 const FixturesManager = require('./helpers/FixturesManager')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.documentupdater)
 
 const redisSettings = settings.redis
 
-const PENDING_UPDATES_LIST_KEYS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((n) => {
+const PENDING_UPDATES_LIST_KEYS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => {
   let key = 'pending-updates-list'
   if (n !== 0) {
     key += `-${n}`
@@ -33,10 +33,8 @@ const PENDING_UPDATES_LIST_KEYS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((n) => {
 })
 
 function getPendingUpdatesList(cb) {
-  Promise.all(
-    PENDING_UPDATES_LIST_KEYS.map((key) => rclient.lrange(key, 0, -1))
-  )
-    .then((results) => {
+  Promise.all(PENDING_UPDATES_LIST_KEYS.map(key => rclient.lrange(key, 0, -1)))
+    .then(results => {
       cb(
         null,
         results.reduce((acc, more) => {
@@ -51,7 +49,7 @@ function getPendingUpdatesList(cb) {
 }
 
 function clearPendingUpdatesList(cb) {
-  Promise.all(PENDING_UPDATES_LIST_KEYS.map((key) => rclient.del(key)))
+  Promise.all(PENDING_UPDATES_LIST_KEYS.map(key => rclient.del(key)))
     .then(() => cb(null))
     .catch(cb)
 }
@@ -59,17 +57,17 @@ function clearPendingUpdatesList(cb) {
 describe('applyOtUpdate', function () {
   before(function () {
     return (this.update = {
-      op: [{ i: 'foo', p: 42 }]
+      op: [{ i: 'foo', p: 42 }],
     })
   })
   describe('when authorized', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -79,7 +77,7 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -90,12 +88,12 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -103,18 +101,18 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'applyOtUpdate',
               this.doc_id,
               this.update,
               cb
             )
-          }
+          },
         ],
         done
       )
@@ -132,7 +130,7 @@ describe('applyOtUpdate', function () {
     it('should push the update into redis', function (done) {
       rclient.lrange(
         redisSettings.documentupdater.key_schema.pendingUpdates({
-          doc_id: this.doc_id
+          doc_id: this.doc_id,
         }),
         0,
         -1,
@@ -142,7 +140,7 @@ describe('applyOtUpdate', function () {
           update.op.should.deep.equal(this.update.op)
           update.meta.should.deep.equal({
             source: this.client.publicId,
-            user_id: this.user_id
+            user_id: this.user_id,
           })
           return done()
         }
@@ -153,20 +151,20 @@ describe('applyOtUpdate', function () {
     return after(function (done) {
       return async.series(
         [
-          (cb) => clearPendingUpdatesList(cb),
-          (cb) =>
+          cb => clearPendingUpdatesList(cb),
+          cb =>
             rclient.del(
               'DocsWithPendingUpdates',
               `${this.project_id}:${this.doc_id}`,
               cb
             ),
-          (cb) =>
+          cb =>
             rclient.del(
               redisSettings.documentupdater.key_schema.pendingUpdates(
                 this.doc_id
               ),
               cb
-            )
+            ),
         ],
         done
       )
@@ -178,15 +176,15 @@ describe('applyOtUpdate', function () {
       this.update = {
         op: {
           p: 12,
-          t: 'update is too large'.repeat(1024 * 400) // >7MB
-        }
+          t: 'update is too large'.repeat(1024 * 400), // >7MB
+        },
       }
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -196,7 +194,7 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -207,15 +205,15 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             this.client.on('connectionAccepted', cb)
-            return this.client.on('otUpdateError', (otUpdateError) => {
+            return this.client.on('otUpdateError', otUpdateError => {
               this.otUpdateError = otUpdateError
             })
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -223,21 +221,21 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'applyOtUpdate',
               this.doc_id,
               this.update,
-              (error) => {
+              error => {
                 this.error = error
                 return cb()
               }
             )
-          }
+          },
         ],
         done
       )
@@ -264,7 +262,7 @@ describe('applyOtUpdate', function () {
     return it('should not put the update in redis', function (done) {
       rclient.llen(
         redisSettings.documentupdater.key_schema.pendingUpdates({
-          doc_id: this.doc_id
+          doc_id: this.doc_id,
         }),
         (error, len) => {
           len.should.equal(0)
@@ -279,10 +277,10 @@ describe('applyOtUpdate', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readOnly'
+                privilegeLevel: 'readOnly',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -292,7 +290,7 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -303,12 +301,12 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -316,21 +314,21 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'applyOtUpdate',
               this.doc_id,
               this.update,
-              (error) => {
+              error => {
                 this.error = error
                 return cb()
               }
             )
-          }
+          },
         ],
         done
       )
@@ -350,7 +348,7 @@ describe('applyOtUpdate', function () {
     return it('should not put the update in redis', function (done) {
       rclient.llen(
         redisSettings.documentupdater.key_schema.pendingUpdates({
-          doc_id: this.doc_id
+          doc_id: this.doc_id,
         }),
         (error, len) => {
           len.should.equal(0)
@@ -364,14 +362,14 @@ describe('applyOtUpdate', function () {
   return describe('when authorized to read-only with a comment update', function () {
     before(function (done) {
       this.comment_update = {
-        op: [{ c: 'foo', p: 42 }]
+        op: [{ c: 'foo', p: 42 }],
       }
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readOnly'
+                privilegeLevel: 'readOnly',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -381,7 +379,7 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -392,12 +390,12 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -405,18 +403,18 @@ describe('applyOtUpdate', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'applyOtUpdate',
               this.doc_id,
               this.comment_update,
               cb
             )
-          }
+          },
         ],
         done
       )
@@ -434,7 +432,7 @@ describe('applyOtUpdate', function () {
     it('should push the update into redis', function (done) {
       rclient.lrange(
         redisSettings.documentupdater.key_schema.pendingUpdates({
-          doc_id: this.doc_id
+          doc_id: this.doc_id,
         }),
         0,
         -1,
@@ -444,7 +442,7 @@ describe('applyOtUpdate', function () {
           update.op.should.deep.equal(this.comment_update.op)
           update.meta.should.deep.equal({
             source: this.client.publicId,
-            user_id: this.user_id
+            user_id: this.user_id,
           })
           return done()
         }
@@ -455,20 +453,20 @@ describe('applyOtUpdate', function () {
     return after(function (done) {
       return async.series(
         [
-          (cb) => clearPendingUpdatesList(cb),
-          (cb) =>
+          cb => clearPendingUpdatesList(cb),
+          cb =>
             rclient.del(
               'DocsWithPendingUpdates',
               `${this.project_id}:${this.doc_id}`,
               cb
             ),
-          (cb) =>
+          cb =>
             rclient.del(
               redisSettings.documentupdater.key_schema.pendingUpdates({
-                doc_id: this.doc_id
+                doc_id: this.doc_id,
               }),
               cb
-            )
+            ),
         ],
         done
       )

+ 36 - 36
services/real-time/test/acceptance/js/ClientTrackingTests.js

@@ -25,11 +25,11 @@ describe('clientTracking', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
-                project: { name: 'Test Project' }
+                project: { name: 'Test Project' },
               },
               (error, { user_id, project_id }) => {
                 this.user_id = user_id
@@ -39,7 +39,7 @@ describe('clientTracking', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -50,43 +50,43 @@ describe('clientTracking', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.clientB = RealTimeClient.connect()
             return this.clientB.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               {
-                project_id: this.project_id
+                project_id: this.project_id,
               },
               cb
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientB.emit(
               'joinProject',
               {
-                project_id: this.project_id
+                project_id: this.project_id,
               },
               cb
             )
           },
 
-          (cb) => {
+          cb => {
             this.updates = []
-            this.clientB.on('clientTracking.clientUpdated', (data) => {
+            this.clientB.on('clientTracking.clientUpdated', data => {
               return this.updates.push(data)
             })
 
@@ -95,16 +95,16 @@ describe('clientTracking', function () {
               {
                 row: (this.row = 42),
                 column: (this.column = 36),
-                doc_id: this.doc_id
+                doc_id: this.doc_id,
               },
-              (error) => {
+              error => {
                 if (error != null) {
                   throw error
                 }
                 return setTimeout(cb, 300)
               }
             )
-          } // Give the message a chance to reach client B.
+          }, // Give the message a chance to reach client B.
         ],
         done
       )
@@ -118,8 +118,8 @@ describe('clientTracking', function () {
           doc_id: this.doc_id,
           id: this.clientA.publicId,
           user_id: this.user_id,
-          name: 'Joe Bloggs'
-        }
+          name: 'Joe Bloggs',
+        },
       ])
     })
 
@@ -132,7 +132,7 @@ describe('clientTracking', function () {
               expect(user.cursorData).to.deep.equal({
                 row: this.row,
                 column: this.column,
-                doc_id: this.doc_id
+                doc_id: this.doc_id,
               })
               return done()
             }
@@ -147,12 +147,12 @@ describe('clientTracking', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: { name: 'Test Project' },
-                publicAccess: 'readAndWrite'
+                publicAccess: 'readAndWrite',
               },
               (error, { user_id, project_id }) => {
                 this.user_id = user_id
@@ -162,7 +162,7 @@ describe('clientTracking', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -173,47 +173,47 @@ describe('clientTracking', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               {
-                project_id: this.project_id
+                project_id: this.project_id,
               },
               cb
             )
           },
 
-          (cb) => {
+          cb => {
             return RealTimeClient.setSession({}, cb)
           },
 
-          (cb) => {
+          cb => {
             this.anonymous = RealTimeClient.connect()
             return this.anonymous.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.anonymous.emit(
               'joinProject',
               {
-                project_id: this.project_id
+                project_id: this.project_id,
               },
               cb
             )
           },
 
-          (cb) => {
+          cb => {
             return this.anonymous.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             this.updates = []
-            this.clientA.on('clientTracking.clientUpdated', (data) => {
+            this.clientA.on('clientTracking.clientUpdated', data => {
               return this.updates.push(data)
             })
 
@@ -222,16 +222,16 @@ describe('clientTracking', function () {
               {
                 row: (this.row = 42),
                 column: (this.column = 36),
-                doc_id: this.doc_id
+                doc_id: this.doc_id,
               },
-              (error) => {
+              error => {
                 if (error != null) {
                   throw error
                 }
                 return setTimeout(cb, 300)
               }
             )
-          } // Give the message a chance to reach client B.
+          }, // Give the message a chance to reach client B.
         ],
         done
       )
@@ -245,8 +245,8 @@ describe('clientTracking', function () {
           doc_id: this.doc_id,
           id: this.anonymous.publicId,
           user_id: 'anonymous-user',
-          name: ''
-        }
+          name: '',
+        },
       ])
     })
   })

+ 13 - 13
services/real-time/test/acceptance/js/DrainManagerTests.js

@@ -16,7 +16,7 @@ const { expect } = require('chai')
 const async = require('async')
 const request = require('request')
 
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 
 const drain = function (rate, callback) {
   request.post(
@@ -24,8 +24,8 @@ const drain = function (rate, callback) {
       url: `http://localhost:3026/drain?rate=${rate}`,
       auth: {
         user: Settings.internal.realTime.user,
-        pass: Settings.internal.realTime.pass
-      }
+        pass: Settings.internal.realTime.pass,
+      },
     },
     (error, response, data) => callback(error, data)
   )
@@ -38,8 +38,8 @@ describe('DrainManagerTests', function () {
       {
         privilegeLevel: 'owner',
         project: {
-          name: 'Test Project'
-        }
+          name: 'Test Project',
+        },
       },
       (e, { project_id, user_id }) => {
         this.project_id = project_id
@@ -71,17 +71,17 @@ describe('DrainManagerTests', function () {
     beforeEach(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.clientB = RealTimeClient.connect()
             return this.clientB.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -89,13 +89,13 @@ describe('DrainManagerTests', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientB.emit(
               'joinProject',
               { project_id: this.project_id },
               cb
             )
-          }
+          },
         ],
         done
       )
@@ -105,14 +105,14 @@ describe('DrainManagerTests', function () {
       beforeEach(function (done) {
         return async.parallel(
           [
-            (cb) => {
+            cb => {
               return this.clientA.on('reconnectGracefully', cb)
             },
-            (cb) => {
+            cb => {
               return this.clientB.on('reconnectGracefully', cb)
             },
 
-            (cb) => drain(2, cb)
+            cb => drain(2, cb),
           ],
           done
         )

+ 31 - 31
services/real-time/test/acceptance/js/EarlyDisconnect.js

@@ -18,7 +18,7 @@ const MockDocUpdaterServer = require('./helpers/MockDocUpdaterServer')
 const MockWebServer = require('./helpers/MockWebServer')
 const FixturesManager = require('./helpers/FixturesManager')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.pubsub)
 const rclientRT = redis.createClient(settings.redis.realtime)
@@ -45,13 +45,13 @@ describe('EarlyDisconnect', function () {
     beforeEach(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -61,12 +61,12 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -77,10 +77,10 @@ describe('EarlyDisconnect', function () {
             return this.clientA.disconnect()
           },
 
-          (cb) => {
+          cb => {
             // wait for joinDoc and subscribe
             return setTimeout(cb, 500)
-          }
+          },
         ],
         done
       )
@@ -88,7 +88,7 @@ describe('EarlyDisconnect', function () {
 
     // we can force the race condition, there is no need to repeat too often
     return Array.from(Array.from({ length: 5 }).map((_, i) => i + 1)).map(
-      (attempt) =>
+      attempt =>
         it(`should not subscribe to the pub/sub channel anymore (race ${attempt})`, function (done) {
           rclient.pubsub('CHANNELS', (err, resp) => {
             if (err) {
@@ -106,13 +106,13 @@ describe('EarlyDisconnect', function () {
     beforeEach(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -122,12 +122,12 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -140,7 +140,7 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -151,17 +151,17 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit('joinDoc', this.doc_id, () => {})
             // disconnect before joinDoc completes
             this.clientA.on('disconnect', () => cb())
             return this.clientA.disconnect()
           },
 
-          (cb) => {
+          cb => {
             // wait for subscribe and unsubscribe
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )
@@ -169,7 +169,7 @@ describe('EarlyDisconnect', function () {
 
     // we can not force the race condition, so we have to try many times
     return Array.from(Array.from({ length: 20 }).map((_, i) => i + 1)).map(
-      (attempt) =>
+      attempt =>
         it(`should not subscribe to the pub/sub channels anymore (race ${attempt})`, function (done) {
           rclient.pubsub('CHANNELS', (err, resp) => {
             if (err) {
@@ -194,13 +194,13 @@ describe('EarlyDisconnect', function () {
     beforeEach(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -210,12 +210,12 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -228,7 +228,7 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -239,17 +239,17 @@ describe('EarlyDisconnect', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit(
               'clientTracking.updatePosition',
               {
                 row: 42,
                 column: 36,
-                doc_id: this.doc_id
+                doc_id: this.doc_id,
               },
               () => {}
             )
@@ -258,10 +258,10 @@ describe('EarlyDisconnect', function () {
             return this.clientA.disconnect()
           },
 
-          (cb) => {
+          cb => {
             // wait for updateClientPosition
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )
@@ -269,7 +269,7 @@ describe('EarlyDisconnect', function () {
 
     // we can not force the race condition, so we have to try many times
     return Array.from(Array.from({ length: 20 }).map((_, i) => i + 1)).map(
-      (attempt) =>
+      attempt =>
         it(`should not show the client as connected (race ${attempt})`, function (done) {
           rclientRT.smembers(
             KeysRT.clientsInProject({ project_id: this.project_id }),

+ 11 - 11
services/real-time/test/acceptance/js/HttpControllerTests.js

@@ -11,7 +11,7 @@
 const async = require('async')
 const { expect } = require('chai')
 const request = require('request').defaults({
-  baseUrl: 'http://localhost:3026'
+  baseUrl: 'http://localhost:3026',
 })
 
 const RealTimeClient = require('./helpers/RealTimeClient')
@@ -24,7 +24,7 @@ describe('HttpControllerTests', function () {
       return request.get(
         {
           url: `/clients/${client_id}`,
-          json: true
+          json: true,
         },
         (error, response, data) => {
           if (error) {
@@ -41,10 +41,10 @@ describe('HttpControllerTests', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'owner'
+                privilegeLevel: 'owner',
               },
               (error, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -54,7 +54,7 @@ describe('HttpControllerTests', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {},
@@ -65,12 +65,12 @@ describe('HttpControllerTests', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -78,9 +78,9 @@ describe('HttpControllerTests', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit('joinDoc', this.doc_id, cb)
-          }
+          },
         ],
         done
       )
@@ -90,7 +90,7 @@ describe('HttpControllerTests', function () {
       return request.get(
         {
           url: `/clients/${this.client.socket.sessionid}`,
-          json: true
+          json: true,
         },
         (error, response, data) => {
           if (error) {
@@ -107,7 +107,7 @@ describe('HttpControllerTests', function () {
             last_name: 'Bloggs',
             project_id: this.project_id,
             user_id: this.user_id,
-            rooms: [this.project_id, this.doc_id]
+            rooms: [this.project_id, this.doc_id],
           })
           return done()
         }

+ 54 - 54
services/real-time/test/acceptance/js/JoinDocTests.js

@@ -31,10 +31,10 @@ describe('joinDoc', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -44,14 +44,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -60,12 +60,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -73,7 +73,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -82,7 +82,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -99,7 +99,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 
@@ -118,10 +118,10 @@ describe('joinDoc', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readOnly'
+                privilegeLevel: 'readOnly',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -131,14 +131,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -147,12 +147,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -160,7 +160,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -169,7 +169,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -186,7 +186,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 
@@ -205,10 +205,10 @@ describe('joinDoc', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'owner'
+                privilegeLevel: 'owner',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -218,14 +218,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -234,12 +234,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -247,7 +247,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -256,7 +256,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -273,7 +273,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 
@@ -297,10 +297,10 @@ describe('joinDoc', function () {
       this.fromVersion = 36
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -310,14 +310,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -326,12 +326,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -339,7 +339,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -349,7 +349,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -366,7 +366,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 
@@ -386,10 +386,10 @@ describe('joinDoc', function () {
       this.options = { encodeRanges: true }
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -399,14 +399,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -415,12 +415,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -428,7 +428,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -438,7 +438,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -455,7 +455,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 
@@ -476,10 +476,10 @@ describe('joinDoc', function () {
       this.options = { encodeRanges: true }
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -489,14 +489,14 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               {
                 lines: this.lines,
                 version: this.version,
                 ops: this.ops,
-                ranges: this.ranges
+                ranges: this.ranges,
               },
               (e, { doc_id }) => {
                 this.doc_id = doc_id
@@ -505,12 +505,12 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -518,7 +518,7 @@ describe('joinDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -529,7 +529,7 @@ describe('joinDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -546,7 +546,7 @@ describe('joinDoc', function () {
         this.lines,
         this.version,
         this.ops,
-        this.ranges
+        this.ranges,
       ])
     })
 

+ 29 - 29
services/real-time/test/acceptance/js/JoinProjectTests.js

@@ -23,13 +23,13 @@ describe('joinProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -39,12 +39,12 @@ describe('joinProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -55,7 +55,7 @@ describe('joinProject', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -69,7 +69,7 @@ describe('joinProject', function () {
 
     it('should return the project', function () {
       return this.project.should.deep.equal({
-        name: 'Test Project'
+        name: 'Test Project',
       })
     })
 
@@ -118,13 +118,13 @@ describe('joinProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: null,
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -134,12 +134,12 @@ describe('joinProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -151,7 +151,7 @@ describe('joinProject', function () {
                 return cb()
               }
             )
-          }
+          },
         ],
         done
       )
@@ -178,14 +178,14 @@ describe('joinProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 project_id: 'forbidden',
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -195,12 +195,12 @@ describe('joinProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -212,7 +212,7 @@ describe('joinProject', function () {
                 cb()
               }
             )
-          }
+          },
         ],
         done
       )
@@ -239,14 +239,14 @@ describe('joinProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 project_id: 'not-found',
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -256,12 +256,12 @@ describe('joinProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -273,7 +273,7 @@ describe('joinProject', function () {
                 cb()
               }
             )
-          }
+          },
         ],
         done
       )
@@ -300,21 +300,21 @@ describe('joinProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: 'rate-limited' },
-              (error) => {
+              error => {
                 this.error = error
                 return cb()
               }
             )
-          }
+          },
         ],
         done
       )

+ 10 - 10
services/real-time/test/acceptance/js/LeaveDocTests.js

@@ -44,10 +44,10 @@ describe('leaveDoc', function () {
     beforeEach(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
-                privilegeLevel: 'readAndWrite'
+                privilegeLevel: 'readAndWrite',
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -57,7 +57,7 @@ describe('leaveDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -68,12 +68,12 @@ describe('leaveDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.client = RealTimeClient.connect()
             return this.client.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -81,7 +81,7 @@ describe('leaveDoc', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.client.emit(
               'joinDoc',
               this.doc_id,
@@ -90,7 +90,7 @@ describe('leaveDoc', function () {
                 return cb(error)
               }
             )
-          }
+          },
         ],
         done
       )
@@ -98,7 +98,7 @@ describe('leaveDoc', function () {
 
     describe('then leaving the doc', function () {
       beforeEach(function (done) {
-        return this.client.emit('leaveDoc', this.doc_id, (error) => {
+        return this.client.emit('leaveDoc', this.doc_id, error => {
           if (error != null) {
             throw error
           }
@@ -123,7 +123,7 @@ describe('leaveDoc', function () {
       beforeEach(function (done) {
         this.client.emit('leaveDoc', this.doc_id, () => {})
         this.client.emit('joinDoc', this.doc_id, () => {})
-        return this.client.emit('leaveDoc', this.doc_id, (error) => {
+        return this.client.emit('leaveDoc', this.doc_id, error => {
           if (error != null) {
             throw error
           }
@@ -154,7 +154,7 @@ describe('leaveDoc', function () {
 
     return describe('when sending a leaveDoc for a room the client has not joined ', function () {
       beforeEach(function (done) {
-        return this.client.emit('leaveDoc', this.other_doc_id, (error) => {
+        return this.client.emit('leaveDoc', this.other_doc_id, error => {
           if (error != null) {
             throw error
           }

+ 26 - 26
services/real-time/test/acceptance/js/LeaveProjectTests.js

@@ -17,7 +17,7 @@ const FixturesManager = require('./helpers/FixturesManager')
 
 const async = require('async')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.pubsub)
 
@@ -30,13 +30,13 @@ describe('leaveProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -46,25 +46,25 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connectionAccepted', cb)
           },
 
-          (cb) => {
+          cb => {
             this.clientB = RealTimeClient.connect()
             this.clientB.on('connectionAccepted', cb)
 
             this.clientBDisconnectMessages = []
             return this.clientB.on(
               'clientTracking.clientDisconnected',
-              (data) => {
+              data => {
                 return this.clientBDisconnectMessages.push(data)
               }
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -77,7 +77,7 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientB.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -90,7 +90,7 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -101,23 +101,23 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit('joinDoc', this.doc_id, cb)
           },
-          (cb) => {
+          cb => {
             return this.clientB.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             // leaveProject is called when the client disconnects
             this.clientA.on('disconnect', () => cb())
             return this.clientA.disconnect()
           },
 
-          (cb) => {
+          cb => {
             // The API waits a little while before flushing changes
             return setTimeout(done, 1000)
-          }
+          },
         ],
         done
       )
@@ -125,7 +125,7 @@ describe('leaveProject', function () {
 
     it('should emit a disconnect message to the room', function () {
       return this.clientBDisconnectMessages.should.deep.equal([
-        this.clientA.publicId
+        this.clientA.publicId,
       ])
     })
 
@@ -176,13 +176,13 @@ describe('leaveProject', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -192,12 +192,12 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connect', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -210,7 +210,7 @@ describe('leaveProject', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -220,20 +220,20 @@ describe('leaveProject', function () {
               }
             )
           },
-          (cb) => {
+          cb => {
             return this.clientA.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             // leaveProject is called when the client disconnects
             this.clientA.on('disconnect', () => cb())
             return this.clientA.disconnect()
           },
 
-          (cb) => {
+          cb => {
             // The API waits a little while before flushing changes
             return setTimeout(done, 1000)
-          }
+          },
         ],
         done
       )

+ 49 - 49
services/real-time/test/acceptance/js/MatrixTests.js

@@ -53,7 +53,7 @@ const async = require('async')
 const RealTimeClient = require('./helpers/RealTimeClient')
 const FixturesManager = require('./helpers/FixturesManager')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const Keys = settings.redis.documentupdater.key_schema
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.pubsub)
@@ -81,7 +81,7 @@ describe('MatrixTests', function () {
           privateClient.emit(
             'joinProject',
             { project_id: privateProjectId },
-            (err) => {
+            err => {
               if (err) return done(err)
               privateClient.emit('joinDoc', privateDocId, done)
             }
@@ -94,7 +94,7 @@ describe('MatrixTests', function () {
   before(function setupReadWriteProject(done) {
     FixturesManager.setUpEditorSession(
       {
-        publicAccess: 'readAndWrite'
+        publicAccess: 'readAndWrite',
       },
       (err, { project_id, doc_id }) => {
         readWriteProjectId = project_id
@@ -107,13 +107,13 @@ describe('MatrixTests', function () {
   const USER_SETUP = {
     anonymous: {
       setup(cb) {
-        RealTimeClient.setSession({}, (err) => {
+        RealTimeClient.setSession({}, err => {
           if (err) return cb(err)
           cb(null, {
-            client: RealTimeClient.connect()
+            client: RealTimeClient.connect(),
           })
         })
-      }
+      },
     },
 
     registered: {
@@ -124,18 +124,18 @@ describe('MatrixTests', function () {
             user: {
               _id: user_id,
               first_name: 'Joe',
-              last_name: 'Bloggs'
-            }
+              last_name: 'Bloggs',
+            },
           },
-          (err) => {
+          err => {
             if (err) return cb(err)
             cb(null, {
               user_id,
-              client: RealTimeClient.connect()
+              client: RealTimeClient.connect(),
             })
           }
         )
-      }
+      },
     },
 
     registeredWithOwnedProject: {
@@ -148,16 +148,16 @@ describe('MatrixTests', function () {
               user_id,
               project_id,
               doc_id,
-              client: RealTimeClient.connect()
+              client: RealTimeClient.connect(),
             })
           }
         )
       },
-      hasOwnProject: true
-    }
+      hasOwnProject: true,
+    },
   }
 
-  Object.entries(USER_SETUP).forEach((level0) => {
+  Object.entries(USER_SETUP).forEach(level0 => {
     const [userDescription, userItem] = level0
     let options, client
 
@@ -166,46 +166,46 @@ describe('MatrixTests', function () {
         getActions(cb) {
           cb(null, [])
         },
-        needsOwnProject: false
+        needsOwnProject: false,
       },
 
       joinReadWriteProject: {
         getActions(cb) {
           cb(null, [
-            { rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] }
+            { rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] },
           ])
         },
-        needsOwnProject: false
+        needsOwnProject: false,
       },
 
       joinReadWriteProjectAndDoc: {
         getActions(cb) {
           cb(null, [
             { rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] },
-            { rpc: 'joinDoc', args: [readWriteDocId] }
+            { rpc: 'joinDoc', args: [readWriteDocId] },
           ])
         },
-        needsOwnProject: false
+        needsOwnProject: false,
       },
 
       joinOwnProject: {
         getActions(cb) {
           cb(null, [
-            { rpc: 'joinProject', args: [{ project_id: options.project_id }] }
+            { rpc: 'joinProject', args: [{ project_id: options.project_id }] },
           ])
         },
-        needsOwnProject: true
+        needsOwnProject: true,
       },
 
       joinOwnProjectAndDoc: {
         getActions(cb) {
           cb(null, [
             { rpc: 'joinProject', args: [{ project_id: options.project_id }] },
-            { rpc: 'joinDoc', args: [options.doc_id] }
+            { rpc: 'joinDoc', args: [options.doc_id] },
           ])
         },
-        needsOwnProject: true
-      }
+        needsOwnProject: true,
+      },
     }
 
     function performActions(getActions, done) {
@@ -245,13 +245,13 @@ describe('MatrixTests', function () {
         })
       })
 
-      Object.entries(SESSION_SETUP).forEach((level1) => {
+      Object.entries(SESSION_SETUP).forEach(level1 => {
         const [sessionSetupDescription, sessionSetupItem] = level1
         const INVALID_REQUESTS = {
           noop: {
             getActions(cb) {
               cb(null, [])
-            }
+            },
           },
 
           joinProjectWithDocId: {
@@ -260,16 +260,16 @@ describe('MatrixTests', function () {
                 {
                   rpc: 'joinProject',
                   args: [{ project_id: privateDocId }],
-                  fails: 1
-                }
+                  fails: 1,
+                },
               ])
-            }
+            },
           },
 
           joinDocWithDocId: {
             getActions(cb) {
               cb(null, [{ rpc: 'joinDoc', args: [privateDocId], fails: 1 }])
-            }
+            },
           },
 
           joinProjectWithProjectId: {
@@ -278,16 +278,16 @@ describe('MatrixTests', function () {
                 {
                   rpc: 'joinProject',
                   args: [{ project_id: privateProjectId }],
-                  fails: 1
-                }
+                  fails: 1,
+                },
               ])
-            }
+            },
           },
 
           joinDocWithProjectId: {
             getActions(cb) {
               cb(null, [{ rpc: 'joinDoc', args: [privateProjectId], fails: 1 }])
-            }
+            },
           },
 
           joinProjectWithProjectIdThenJoinDocWithDocId: {
@@ -296,12 +296,12 @@ describe('MatrixTests', function () {
                 {
                   rpc: 'joinProject',
                   args: [{ project_id: privateProjectId }],
-                  fails: 1
+                  fails: 1,
                 },
-                { rpc: 'joinDoc', args: [privateDocId], fails: 1 }
+                { rpc: 'joinDoc', args: [privateDocId], fails: 1 },
               ])
-            }
-          }
+            },
+          },
         }
 
         // skip some areas of the matrix
@@ -314,7 +314,7 @@ describe('MatrixTests', function () {
             performActions(sessionSetupItem.getActions, done)
           })
 
-          Object.entries(INVALID_REQUESTS).forEach((level2) => {
+          Object.entries(INVALID_REQUESTS).forEach(level2 => {
             const [InvalidRequestDescription, InvalidRequestItem] = level2
             describe(InvalidRequestDescription, function () {
               beforeEach(function performInvalidRequests(done) {
@@ -354,10 +354,10 @@ describe('MatrixTests', function () {
                       meta: { source: privateClient.publicId },
                       v: 42,
                       doc: privateDocId,
-                      op: [{ i: 'foo', p: 50 }]
-                    }
+                      op: [{ i: 'foo', p: 50 }],
+                    },
                   }
-                  client.on('otUpdateApplied', (update) => {
+                  client.on('otUpdateApplied', update => {
                     receivedMessages.push(update)
                   })
                   privateClient.once('otUpdateApplied', () => {
@@ -378,7 +378,7 @@ describe('MatrixTests', function () {
                     room_id: privateProjectId,
                     message: 'removeEntity',
                     payload: ['foo', 'convertDocToFile'],
-                    _id: 'web:123'
+                    _id: 'web:123',
                   }
                   client.on('removeEntity', (...args) => {
                     receivedMessages.push(args)
@@ -408,14 +408,14 @@ describe('MatrixTests', function () {
                       v: 43,
                       lastV: 42,
                       doc: privateDocId,
-                      op: [{ i: 'foo', p: 50 }]
-                    }
+                      op: [{ i: 'foo', p: 50 }],
+                    },
                   }
                 })
 
                 beforeEach(function sendAsUser(done) {
                   const userUpdate = Object.assign({}, update, {
-                    hash: 'user'
+                    hash: 'user',
                   })
 
                   client.emit(
@@ -431,7 +431,7 @@ describe('MatrixTests', function () {
 
                 beforeEach(function sendAsPrivateUserForReferenceOp(done) {
                   const privateUpdate = Object.assign({}, update, {
-                    hash: 'private'
+                    hash: 'private',
                   })
 
                   privateClient.emit(
@@ -457,7 +457,7 @@ describe('MatrixTests', function () {
                   expect(
                     [
                       'no project_id found on client',
-                      'not authorized'
+                      'not authorized',
                     ].includes(receivedArgs[0].message)
                   ).to.equal(true)
                 })

+ 37 - 37
services/real-time/test/acceptance/js/PubSubRace.js

@@ -15,7 +15,7 @@ const FixturesManager = require('./helpers/FixturesManager')
 
 const async = require('async')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.pubsub)
 
@@ -28,13 +28,13 @@ describe('PubSubRace', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -44,12 +44,12 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connect', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -62,7 +62,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -73,16 +73,16 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit('joinDoc', this.doc_id, () => {})
             // leave before joinDoc completes
             return this.clientA.emit('leaveDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             // wait for subscribe and unsubscribe
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )
@@ -104,13 +104,13 @@ describe('PubSubRace', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -120,12 +120,12 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connect', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -138,7 +138,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -149,7 +149,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit('joinDoc', this.doc_id, () => {})
             this.clientA.emit('leaveDoc', this.doc_id, () => {})
             this.clientA.emit('joinDoc', this.doc_id, () => {})
@@ -162,10 +162,10 @@ describe('PubSubRace', function () {
             return this.clientA.emit('leaveDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             // wait for subscribe and unsubscribe
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )
@@ -187,13 +187,13 @@ describe('PubSubRace', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -203,12 +203,12 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connect', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -221,7 +221,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -232,7 +232,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA.emit('joinDoc', this.doc_id, () => {})
             this.clientA.emit('leaveDoc', this.doc_id, () => {})
             this.clientA.emit('joinDoc', this.doc_id, () => {})
@@ -244,10 +244,10 @@ describe('PubSubRace', function () {
             return this.clientA.emit('joinDoc', this.doc_id, cb)
           },
 
-          (cb) => {
+          cb => {
             // wait for subscribe and unsubscribe
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )
@@ -269,13 +269,13 @@ describe('PubSubRace', function () {
     before(function (done) {
       return async.series(
         [
-          (cb) => {
+          cb => {
             return FixturesManager.setUpProject(
               {
                 privilegeLevel: 'owner',
                 project: {
-                  name: 'Test Project'
-                }
+                  name: 'Test Project',
+                },
               },
               (e, { project_id, user_id }) => {
                 this.project_id = project_id
@@ -285,12 +285,12 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             this.clientA = RealTimeClient.connect()
             return this.clientA.on('connect', cb)
           },
 
-          (cb) => {
+          cb => {
             return this.clientA.emit(
               'joinProject',
               { project_id: this.project_id },
@@ -303,7 +303,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             return FixturesManager.setUpDoc(
               this.project_id,
               { lines: this.lines, version: this.version, ops: this.ops },
@@ -314,7 +314,7 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             let joinDocCompleted = false
             this.clientA.emit(
               'joinDoc',
@@ -339,10 +339,10 @@ describe('PubSubRace', function () {
             )
           },
 
-          (cb) => {
+          cb => {
             // wait for subscribe and unsubscribe
             return setTimeout(cb, 100)
-          }
+          },
         ],
         done
       )

+ 42 - 42
services/real-time/test/acceptance/js/ReceiveUpdateTests.js

@@ -19,7 +19,7 @@ const FixturesManager = require('./helpers/FixturesManager')
 
 const async = require('async')
 
-const settings = require('settings-sharelatex')
+const settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(settings.redis.pubsub)
 
@@ -31,11 +31,11 @@ describe('receiveUpdate', function () {
 
     return async.series(
       [
-        (cb) => {
+        cb => {
           return FixturesManager.setUpProject(
             {
               privilegeLevel: 'owner',
-              project: { name: 'Test Project' }
+              project: { name: 'Test Project' },
             },
             (error, { user_id, project_id }) => {
               this.user_id = user_id
@@ -45,7 +45,7 @@ describe('receiveUpdate', function () {
           )
         },
 
-        (cb) => {
+        cb => {
           return FixturesManager.setUpDoc(
             this.project_id,
             { lines: this.lines, version: this.version, ops: this.ops },
@@ -56,49 +56,49 @@ describe('receiveUpdate', function () {
           )
         },
 
-        (cb) => {
+        cb => {
           this.clientA = RealTimeClient.connect()
           return this.clientA.on('connectionAccepted', cb)
         },
 
-        (cb) => {
+        cb => {
           this.clientB = RealTimeClient.connect()
           return this.clientB.on('connectionAccepted', cb)
         },
 
-        (cb) => {
+        cb => {
           return this.clientA.emit(
             'joinProject',
             {
-              project_id: this.project_id
+              project_id: this.project_id,
             },
             cb
           )
         },
 
-        (cb) => {
+        cb => {
           return this.clientA.emit('joinDoc', this.doc_id, cb)
         },
 
-        (cb) => {
+        cb => {
           return this.clientB.emit(
             'joinProject',
             {
-              project_id: this.project_id
+              project_id: this.project_id,
             },
             cb
           )
         },
 
-        (cb) => {
+        cb => {
           return this.clientB.emit('joinDoc', this.doc_id, cb)
         },
 
-        (cb) => {
+        cb => {
           return FixturesManager.setUpProject(
             {
               privilegeLevel: 'owner',
-              project: { name: 'Test Project' }
+              project: { name: 'Test Project' },
             },
             (
               error,
@@ -111,7 +111,7 @@ describe('receiveUpdate', function () {
           )
         },
 
-        (cb) => {
+        cb => {
           return FixturesManager.setUpDoc(
             this.project_id_second,
             { lines: this.lines, version: this.version, ops: this.ops },
@@ -122,52 +122,52 @@ describe('receiveUpdate', function () {
           )
         },
 
-        (cb) => {
+        cb => {
           this.clientC = RealTimeClient.connect()
           return this.clientC.on('connectionAccepted', cb)
         },
 
-        (cb) => {
+        cb => {
           return this.clientC.emit(
             'joinProject',
             {
-              project_id: this.project_id_second
+              project_id: this.project_id_second,
             },
             cb
           )
         },
-        (cb) => {
+        cb => {
           return this.clientC.emit('joinDoc', this.doc_id_second, cb)
         },
 
-        (cb) => {
+        cb => {
           this.clientAUpdates = []
-          this.clientA.on('otUpdateApplied', (update) =>
+          this.clientA.on('otUpdateApplied', update =>
             this.clientAUpdates.push(update)
           )
           this.clientBUpdates = []
-          this.clientB.on('otUpdateApplied', (update) =>
+          this.clientB.on('otUpdateApplied', update =>
             this.clientBUpdates.push(update)
           )
           this.clientCUpdates = []
-          this.clientC.on('otUpdateApplied', (update) =>
+          this.clientC.on('otUpdateApplied', update =>
             this.clientCUpdates.push(update)
           )
 
           this.clientAErrors = []
-          this.clientA.on('otUpdateError', (error) =>
+          this.clientA.on('otUpdateError', error =>
             this.clientAErrors.push(error)
           )
           this.clientBErrors = []
-          this.clientB.on('otUpdateError', (error) =>
+          this.clientB.on('otUpdateError', error =>
             this.clientBErrors.push(error)
           )
           this.clientCErrors = []
-          this.clientC.on('otUpdateError', (error) =>
+          this.clientC.on('otUpdateError', error =>
             this.clientCErrors.push(error)
           )
           return cb()
-        }
+        },
       ],
       done
     )
@@ -189,12 +189,12 @@ describe('receiveUpdate', function () {
         doc_id: this.doc_id,
         op: {
           meta: {
-            source: this.clientA.publicId
+            source: this.clientA.publicId,
           },
           v: this.version,
           doc: this.doc_id,
-          op: [{ i: 'foo', p: 50 }]
-        }
+          op: [{ i: 'foo', p: 50 }],
+        },
       }
       rclient.publish('applied-ops', JSON.stringify(this.update))
       return setTimeout(done, 200)
@@ -208,8 +208,8 @@ describe('receiveUpdate', function () {
       return this.clientAUpdates.should.deep.equal([
         {
           v: this.version,
-          doc: this.doc_id
-        }
+          doc: this.doc_id,
+        },
       ])
     })
 
@@ -224,12 +224,12 @@ describe('receiveUpdate', function () {
         doc_id: this.doc_id_second,
         op: {
           meta: {
-            source: this.clientC.publicId
+            source: this.clientC.publicId,
           },
           v: this.version,
           doc: this.doc_id_second,
-          op: [{ i: 'update from clientC', p: 50 }]
-        }
+          op: [{ i: 'update from clientC', p: 50 }],
+        },
       }
       rclient.publish('applied-ops', JSON.stringify(this.update))
       return setTimeout(done, 200)
@@ -247,8 +247,8 @@ describe('receiveUpdate', function () {
       return this.clientCUpdates.should.deep.equal([
         {
           v: this.version,
-          doc: this.doc_id_second
-        }
+          doc: this.doc_id_second,
+        },
       ])
     })
   })
@@ -259,12 +259,12 @@ describe('receiveUpdate', function () {
         doc_id: this.doc_id,
         op: {
           meta: {
-            source: 'this-is-a-remote-client-id'
+            source: 'this-is-a-remote-client-id',
           },
           v: this.version,
           doc: this.doc_id,
-          op: [{ i: 'foo', p: 50 }]
-        }
+          op: [{ i: 'foo', p: 50 }],
+        },
       }
       rclient.publish('applied-ops', JSON.stringify(this.update))
       return setTimeout(done, 200)
@@ -289,7 +289,7 @@ describe('receiveUpdate', function () {
         'applied-ops',
         JSON.stringify({
           doc_id: this.doc_id,
-          error: (this.error = 'something went wrong')
+          error: (this.error = 'something went wrong'),
         })
       )
       return setTimeout(done, 200)
@@ -320,7 +320,7 @@ describe('receiveUpdate', function () {
         'applied-ops',
         JSON.stringify({
           doc_id: this.doc_id_second,
-          error: (this.error = 'something went wrong')
+          error: (this.error = 'something went wrong'),
         })
       )
       return setTimeout(done, 200)

+ 17 - 17
services/real-time/test/acceptance/js/RouterTests.js

@@ -22,17 +22,17 @@ describe('Router', function () {
       })
 
       before(function (done) {
-        this.onUnhandled = (error) => done(error)
+        this.onUnhandled = error => done(error)
         process.on('unhandledRejection', this.onUnhandled)
         return async.series(
           [
-            (cb) => {
+            cb => {
               return FixturesManager.setUpProject(
                 {
                   privilegeLevel: 'owner',
                   project: {
-                    name: 'Test Project'
-                  }
+                    name: 'Test Project',
+                  },
                 },
                 (e, { project_id, user_id }) => {
                   this.project_id = project_id
@@ -42,20 +42,20 @@ describe('Router', function () {
               )
             },
 
-            (cb) => {
+            cb => {
               this.client = RealTimeClient.connect()
               return this.client.on('connectionAccepted', cb)
             },
 
-            (cb) => {
+            cb => {
               this.client = RealTimeClient.connect()
               return this.client.on('connectionAccepted', cb)
             },
 
-            (cb) => {
+            cb => {
               this.client.emit('joinProject', { project_id: this.project_id })
               return setTimeout(cb, 100)
-            }
+            },
           ],
           done
         )
@@ -72,17 +72,17 @@ describe('Router', function () {
       })
 
       before(function (done) {
-        this.onUnhandled = (error) => done(error)
+        this.onUnhandled = error => done(error)
         process.on('unhandledRejection', this.onUnhandled)
         return async.series(
           [
-            (cb) => {
+            cb => {
               return FixturesManager.setUpProject(
                 {
                   privilegeLevel: 'owner',
                   project: {
-                    name: 'Test Project'
-                  }
+                    name: 'Test Project',
+                  },
                 },
                 (e, { project_id, user_id }) => {
                   this.project_id = project_id
@@ -92,22 +92,22 @@ describe('Router', function () {
               )
             },
 
-            (cb) => {
+            cb => {
               this.client = RealTimeClient.connect()
               return this.client.on('connectionAccepted', cb)
             },
 
-            (cb) => {
+            cb => {
               this.client = RealTimeClient.connect()
               return this.client.on('connectionAccepted', cb)
             },
 
-            (cb) => {
-              return this.client.emit('joinProject', 1, 2, 3, 4, 5, (error) => {
+            cb => {
+              return this.client.emit('joinProject', 1, 2, 3, 4, 5, error => {
                 this.error = error
                 return cb()
               })
-            }
+            },
           ],
           done
         )

+ 7 - 7
services/real-time/test/acceptance/js/SessionSocketsTests.js

@@ -9,7 +9,7 @@
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
 const RealTimeClient = require('./helpers/RealTimeClient')
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 const { expect } = require('chai')
 
 describe('SessionSockets', function () {
@@ -28,7 +28,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a lookup error', function (done) {
-      return this.checkSocket((error) => {
+      return this.checkSocket(error => {
         expect(error).to.exist
         expect(error.message).to.equal('invalid session')
         return done()
@@ -42,7 +42,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a lookup error', function (done) {
-      return this.checkSocket((error) => {
+      return this.checkSocket(error => {
         expect(error).to.exist
         expect(error.message).to.equal('invalid session')
         return done()
@@ -52,7 +52,7 @@ describe('SessionSockets', function () {
 
   describe('with an invalid cookie', function () {
     before(function (done) {
-      RealTimeClient.setSession({}, (error) => {
+      RealTimeClient.setSession({}, error => {
         if (error) {
           return done(error)
         }
@@ -65,7 +65,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a lookup error', function (done) {
-      return this.checkSocket((error) => {
+      return this.checkSocket(error => {
         expect(error).to.exist
         expect(error.message).to.equal('invalid session')
         return done()
@@ -79,7 +79,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a lookup error', function (done) {
-      return this.checkSocket((error) => {
+      return this.checkSocket(error => {
         expect(error).to.exist
         expect(error.message).to.equal('invalid session')
         return done()
@@ -94,7 +94,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should not return an error', function (done) {
-      return this.checkSocket((error) => {
+      return this.checkSocket(error => {
         expect(error).to.not.exist
         return done()
       })

+ 2 - 2
services/real-time/test/acceptance/js/SessionTests.js

@@ -21,9 +21,9 @@ describe('Session', function () {
       this.user_id = 'mock-user-id'
       RealTimeClient.setSession(
         {
-          user: { _id: this.user_id }
+          user: { _id: this.user_id },
         },
-        (error) => {
+        error => {
           if (error != null) {
             throw error
           }

+ 10 - 15
services/real-time/test/acceptance/js/helpers/FixturesManager.js

@@ -32,13 +32,8 @@ module.exports = FixturesManager = {
     if (!options.project) {
       options.project = { name: 'Test Project' }
     }
-    const {
-      project_id,
-      user_id,
-      privilegeLevel,
-      project,
-      publicAccess
-    } = options
+    const { project_id, user_id, privilegeLevel, project, publicAccess } =
+      options
 
     const privileges = {}
     privileges[user_id] = privilegeLevel
@@ -47,7 +42,7 @@ module.exports = FixturesManager = {
     }
 
     MockWebServer.createMockProject(project_id, privileges, project)
-    return MockWebServer.run((error) => {
+    return MockWebServer.run(error => {
       if (error != null) {
         throw error
       }
@@ -56,10 +51,10 @@ module.exports = FixturesManager = {
           user: {
             _id: user_id,
             first_name: 'Joe',
-            last_name: 'Bloggs'
-          }
+            last_name: 'Bloggs',
+          },
         },
-        (error) => {
+        error => {
           if (error != null) {
             throw error
           }
@@ -67,7 +62,7 @@ module.exports = FixturesManager = {
             project_id,
             user_id,
             privilegeLevel,
-            project
+            project,
           })
         }
       )
@@ -99,9 +94,9 @@ module.exports = FixturesManager = {
       lines,
       version,
       ops,
-      ranges
+      ranges,
     })
-    return MockDocUpdaterServer.run((error) => {
+    return MockDocUpdaterServer.run(error => {
       if (error != null) {
         throw error
       }
@@ -131,5 +126,5 @@ module.exports = FixturesManager = {
       .update(Math.random().toString())
       .digest('hex')
       .slice(0, 24)
-  }
+  },
 }

+ 4 - 4
services/real-time/test/acceptance/js/helpers/MockDocUpdaterServer.js

@@ -53,7 +53,7 @@ module.exports = MockDocUpdaterServer = {
 
   deleteProjectRequest(req, res, next) {
     const { project_id } = req.params
-    return MockDocUpdaterServer.deleteProject(project_id, (error) => {
+    return MockDocUpdaterServer.deleteProject(project_id, error => {
       if (error != null) {
         return next(error)
       }
@@ -79,15 +79,15 @@ module.exports = MockDocUpdaterServer = {
       MockDocUpdaterServer.deleteProjectRequest
     )
     return app
-      .listen(3003, (error) => {
+      .listen(3003, error => {
         MockDocUpdaterServer.running = true
         return callback(error)
       })
-      .on('error', (error) => {
+      .on('error', error => {
         console.error('error starting MockDocUpdaterServer:', error.message)
         return process.exit(1)
       })
-  }
+  },
 }
 
 sinon.spy(MockDocUpdaterServer, 'getDocument')

+ 4 - 4
services/real-time/test/acceptance/js/helpers/MockWebServer.js

@@ -57,7 +57,7 @@ module.exports = MockWebServer = {
           }
           return res.json({
             project,
-            privilegeLevel
+            privilegeLevel,
           })
         }
       )
@@ -75,15 +75,15 @@ module.exports = MockWebServer = {
     const app = express()
     app.post('/project/:project_id/join', MockWebServer.joinProjectRequest)
     return app
-      .listen(3000, (error) => {
+      .listen(3000, error => {
         MockWebServer.running = true
         return callback(error)
       })
-      .on('error', (error) => {
+      .on('error', error => {
         console.error('error starting MockWebServer:', error.message)
         return process.exit(1)
       })
-  }
+  },
 }
 
 sinon.spy(MockWebServer, 'joinProject')

+ 15 - 19
services/real-time/test/acceptance/js/helpers/RealTimeClient.js

@@ -17,7 +17,7 @@ const io = require('socket.io-client')
 const async = require('async')
 
 const request = require('request')
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 const redis = require('@overleaf/redis-wrapper')
 const rclient = redis.createClient(Settings.redis.websessions)
 
@@ -45,19 +45,15 @@ module.exports = Client = {
     }
     const sessionId = uid(24)
     session.cookie = {}
-    return rclient.set(
-      'sess:' + sessionId,
-      JSON.stringify(session),
-      (error) => {
-        if (error != null) {
-          return callback(error)
-        }
-        const secret = Settings.security.sessionSecret
-        const cookieKey = 's:' + signature.sign(sessionId, secret)
-        Client.cookie = `${Settings.cookieName}=${cookieKey}`
-        return callback()
+    return rclient.set('sess:' + sessionId, JSON.stringify(session), error => {
+      if (error != null) {
+        return callback(error)
       }
-    )
+      const secret = Settings.security.sessionSecret
+      const cookieKey = 's:' + signature.sign(sessionId, secret)
+      Client.cookie = `${Settings.cookieName}=${cookieKey}`
+      return callback()
+    })
   },
 
   unsetSession(callback) {
@@ -70,7 +66,7 @@ module.exports = Client = {
 
   connect(cookie) {
     const client = io.connect('http://localhost:3026', {
-      'force new connection': true
+      'force new connection': true,
     })
     client.on(
       'connectionAccepted',
@@ -86,7 +82,7 @@ module.exports = Client = {
     return request.get(
       {
         url: 'http://localhost:3026/clients',
-        json: true
+        json: true,
       },
       (error, response, data) => callback(error, data)
     )
@@ -99,7 +95,7 @@ module.exports = Client = {
     return request.get(
       {
         url: `http://localhost:3026/clients/${client_id}`,
-        json: true
+        json: true,
       },
       (error, response, data) => callback(error, data)
     )
@@ -111,8 +107,8 @@ module.exports = Client = {
         url: `http://localhost:3026/client/${client_id}/disconnect`,
         auth: {
           user: Settings.internal.realTime.user,
-          pass: Settings.internal.realTime.pass
-        }
+          pass: Settings.internal.realTime.pass,
+        },
       },
       (error, response, data) => callback(error, data)
     )
@@ -127,5 +123,5 @@ module.exports = Client = {
         callback
       )
     )
-  }
+  },
 }

+ 4 - 4
services/real-time/test/acceptance/js/helpers/RealtimeServer.js

@@ -14,7 +14,7 @@
  */
 const app = require('../../../../app')
 const logger = require('logger-sharelatex')
-const Settings = require('settings-sharelatex')
+const Settings = require('@overleaf/settings')
 
 module.exports = {
   running: false,
@@ -34,10 +34,10 @@ module.exports = {
       return app.listen(
         __guard__(
           Settings.internal != null ? Settings.internal.realtime : undefined,
-          (x) => x.port
+          x => x.port
         ),
         'localhost',
-        (error) => {
+        error => {
           if (error != null) {
             throw error
           }
@@ -54,7 +54,7 @@ module.exports = {
         }
       )
     }
-  }
+  },
 }
 
 function __guard__(value, transform) {

+ 41 - 41
services/real-time/test/acceptance/libs/XMLHttpRequest.js

@@ -12,36 +12,36 @@
  */
 
 const { URL } = require('url')
-var spawn = require('child_process').spawn
-var fs = require('fs')
+const spawn = require('child_process').spawn
+const fs = require('fs')
 
 exports.XMLHttpRequest = function () {
   /**
    * Private variables
    */
-  var self = this
-  var http = require('http')
-  var https = require('https')
+  const self = this
+  const http = require('http')
+  const https = require('https')
 
   // Holds http.js objects
-  var request
-  var response
+  let request
+  let response
 
   // Request settings
-  var settings = {}
+  let settings = {}
 
   // Set some default headers
-  var defaultHeaders = {
+  const defaultHeaders = {
     'User-Agent': 'node-XMLHttpRequest',
-    Accept: '*/*'
+    Accept: '*/*',
   }
 
-  var headers = defaultHeaders
+  let headers = defaultHeaders
 
   // These headers are not user setable.
   // The following are allowed but banned in the spec:
   // * user-agent
-  var forbiddenRequestHeaders = [
+  const forbiddenRequestHeaders = [
     'accept-charset',
     'accept-encoding',
     'access-control-request-headers',
@@ -61,19 +61,19 @@ exports.XMLHttpRequest = function () {
     'trailer',
     'transfer-encoding',
     'upgrade',
-    'via'
+    'via',
   ]
 
   // These request methods are not allowed
-  var forbiddenRequestMethods = ['TRACE', 'TRACK', 'CONNECT']
+  const forbiddenRequestMethods = ['TRACE', 'TRACK', 'CONNECT']
 
   // Send flag
-  var sendFlag = false
+  let sendFlag = false
   // Error flag, used when errors occur or abort is called
-  var errorFlag = false
+  let errorFlag = false
 
   // Event listeners
-  var listeners = {}
+  const listeners = {}
 
   /**
    * Constants
@@ -111,7 +111,7 @@ exports.XMLHttpRequest = function () {
    * @param string header Header to validate
    * @return boolean False if not allowed, otherwise true
    */
-  var isAllowedHttpHeader = function (header) {
+  const isAllowedHttpHeader = function (header) {
     return (
       header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1
     )
@@ -123,7 +123,7 @@ exports.XMLHttpRequest = function () {
    * @param string method Request method to validate
    * @return boolean False if not allowed, otherwise true
    */
-  var isAllowedHttpMethod = function (method) {
+  const isAllowedHttpMethod = function (method) {
     return method && forbiddenRequestMethods.indexOf(method) === -1
   }
 
@@ -154,7 +154,7 @@ exports.XMLHttpRequest = function () {
       url: url.toString(),
       async: typeof async !== 'boolean' ? true : async,
       user: user || null,
-      password: password || null
+      password: password || null,
     }
 
     setState(this.OPENED)
@@ -210,9 +210,9 @@ exports.XMLHttpRequest = function () {
     if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
       return ''
     }
-    var result = ''
+    let result = ''
 
-    for (var i in response.headers) {
+    for (const i in response.headers) {
       // Cookie headers are excluded
       if (i !== 'set-cookie' && i !== 'set-cookie2') {
         result += i + ': ' + response.headers[i] + '\r\n'
@@ -252,10 +252,10 @@ exports.XMLHttpRequest = function () {
       throw new Error('INVALID_STATE_ERR: send has already been called')
     }
 
-    var host
-    var ssl = false
-    var local = false
-    var url = new URL(settings.url)
+    let host
+    let ssl = false
+    let local = false
+    const url = new URL(settings.url)
 
     // Determine the server
     switch (url.protocol) {
@@ -311,9 +311,9 @@ exports.XMLHttpRequest = function () {
 
     // Default to port 80. If accessing localhost on another port be sure
     // to use http://localhost:port/path
-    var port = url.port || (ssl ? 443 : 80)
+    const port = url.port || (ssl ? 443 : 80)
     // Add query string if one is used
-    var uri = url.pathname + (url.search ? url.search : '')
+    const uri = url.pathname + (url.search ? url.search : '')
 
     // Set the Host header or the server may reject the request
     headers.Host = host
@@ -326,7 +326,7 @@ exports.XMLHttpRequest = function () {
       if (typeof settings.password === 'undefined') {
         settings.password = ''
       }
-      var authBuf = Buffer.from(settings.user + ':' + settings.password)
+      const authBuf = Buffer.from(settings.user + ':' + settings.password)
       headers.Authorization = 'Basic ' + authBuf.toString('base64')
     }
 
@@ -345,12 +345,12 @@ exports.XMLHttpRequest = function () {
       headers['Content-Length'] = 0
     }
 
-    var options = {
+    const options = {
       host: host,
       port: port,
       path: uri,
       method: settings.method,
-      headers: headers
+      headers: headers,
     }
 
     // Reset error flag
@@ -359,7 +359,7 @@ exports.XMLHttpRequest = function () {
     // Handle async requests
     if (settings.async) {
       // Use the proper protocol
-      var doRequest = ssl ? https.request : http.request
+      const doRequest = ssl ? https.request : http.request
 
       // Request is being sent, set send flag
       sendFlag = true
@@ -368,14 +368,14 @@ exports.XMLHttpRequest = function () {
       self.dispatchEvent('readystatechange')
 
       // Create the request
-      request = doRequest(options, (resp) => {
+      request = doRequest(options, resp => {
         response = resp
         response.setEncoding('utf8')
 
         setState(self.HEADERS_RECEIVED)
         self.status = response.statusCode
 
-        response.on('data', (chunk) => {
+        response.on('data', chunk => {
           // Make sure there's some data
           if (chunk) {
             self.responseText += chunk
@@ -394,10 +394,10 @@ exports.XMLHttpRequest = function () {
           }
         })
 
-        response.on('error', (error) => {
+        response.on('error', error => {
           self.handleError(error)
         })
-      }).on('error', (error) => {
+      }).on('error', error => {
         self.handleError(error)
       })
 
@@ -412,10 +412,10 @@ exports.XMLHttpRequest = function () {
     } else {
       // Synchronous
       // Create a temporary file for communication with the other Node process
-      var syncFile = '.node-xmlhttprequest-sync-' + process.pid
+      const syncFile = '.node-xmlhttprequest-sync-' + process.pid
       fs.writeFileSync(syncFile, '', 'utf8')
       // The async request the other Node process executes
-      var execString =
+      const execString =
         "var http = require('http'), https = require('https'), fs = require('fs');" +
         'var doRequest = http' +
         (ssl ? 's' : '') +
@@ -457,7 +457,7 @@ exports.XMLHttpRequest = function () {
       fs.unlinkSync(syncFile)
       if (self.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) {
         // If the file returned an error, handle it
-        var errorObj = self.responseText.replace(
+        const errorObj = self.responseText.replace(
           /^NODE-XMLHTTPREQUEST-ERROR:/,
           ''
         )
@@ -532,7 +532,7 @@ exports.XMLHttpRequest = function () {
   this.removeEventListener = function (event, callback) {
     if (event in listeners) {
       // Filter will return a new array with the callback removed
-      listeners[event] = listeners[event].filter((ev) => {
+      listeners[event] = listeners[event].filter(ev => {
         return ev !== callback
       })
     }
@@ -546,7 +546,7 @@ exports.XMLHttpRequest = function () {
       self['on' + event]()
     }
     if (event in listeners) {
-      for (var i = 0, len = listeners[event].length; i < len; i++) {
+      for (let i = 0, len = listeners[event].length; i < len; i++) {
         listeners[event][i].call(self)
       }
     }

+ 5 - 5
services/real-time/test/setup.js

@@ -14,16 +14,16 @@ const stubs = {
     info: sandbox.stub(),
     warn: sandbox.stub(),
     err: sandbox.stub(),
-    error: sandbox.stub()
-  }
+    error: sandbox.stub(),
+  },
 }
 
 // SandboxedModule configuration
 SandboxedModule.configure({
   requires: {
-    'logger-sharelatex': stubs.logger
+    'logger-sharelatex': stubs.logger,
   },
-  globals: { Buffer, JSON, console, process }
+  globals: { Buffer, JSON, console, process },
 })
 
 // Mocha hooks
@@ -34,5 +34,5 @@ exports.mochaHooks = {
 
   afterEach() {
     sandbox.reset()
-  }
+  },
 }

+ 17 - 17
services/real-time/test/unit/js/AuthorizationManagerTests.js

@@ -20,7 +20,7 @@ describe('AuthorizationManager', function () {
     this.client = { ol_context: {} }
 
     return (this.AuthorizationManager = SandboxedModule.require(modulePath, {
-      requires: {}
+      requires: {},
     }))
   })
 
@@ -29,7 +29,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'readOnly'
       return this.AuthorizationManager.assertClientCanViewProject(
         this.client,
-        (error) => {
+        error => {
           expect(error).to.be.null
           return done()
         }
@@ -40,7 +40,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'readAndWrite'
       return this.AuthorizationManager.assertClientCanViewProject(
         this.client,
-        (error) => {
+        error => {
           expect(error).to.be.null
           return done()
         }
@@ -51,7 +51,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'owner'
       return this.AuthorizationManager.assertClientCanViewProject(
         this.client,
-        (error) => {
+        error => {
           expect(error).to.be.null
           return done()
         }
@@ -62,7 +62,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'unknown'
       return this.AuthorizationManager.assertClientCanViewProject(
         this.client,
-        (error) => {
+        error => {
           error.message.should.equal('not authorized')
           return done()
         }
@@ -75,7 +75,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'readOnly'
       return this.AuthorizationManager.assertClientCanEditProject(
         this.client,
-        (error) => {
+        error => {
           error.message.should.equal('not authorized')
           return done()
         }
@@ -86,7 +86,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'readAndWrite'
       return this.AuthorizationManager.assertClientCanEditProject(
         this.client,
-        (error) => {
+        error => {
           expect(error).to.be.null
           return done()
         }
@@ -97,7 +97,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'owner'
       return this.AuthorizationManager.assertClientCanEditProject(
         this.client,
-        (error) => {
+        error => {
           expect(error).to.be.null
           return done()
         }
@@ -108,7 +108,7 @@ describe('AuthorizationManager', function () {
       this.client.ol_context.privilege_level = 'unknown'
       return this.AuthorizationManager.assertClientCanEditProject(
         this.client,
-        (error) => {
+        error => {
           error.message.should.equal('not authorized')
           return done()
         }
@@ -134,7 +134,7 @@ describe('AuthorizationManager', function () {
         return this.AuthorizationManager.assertClientCanViewProjectAndDoc(
           this.client,
           this.doc_id,
-          (err) => err.message.should.equal('not authorized')
+          err => err.message.should.equal('not authorized')
         )
       })
 
@@ -151,7 +151,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanViewProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })
@@ -167,7 +167,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanViewProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })
@@ -210,7 +210,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanViewProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })
@@ -233,7 +233,7 @@ describe('AuthorizationManager', function () {
         return this.AuthorizationManager.assertClientCanEditProjectAndDoc(
           this.client,
           this.doc_id,
-          (err) => err.message.should.equal('not authorized')
+          err => err.message.should.equal('not authorized')
         )
       })
 
@@ -250,7 +250,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanEditProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })
@@ -266,7 +266,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanEditProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })
@@ -309,7 +309,7 @@ describe('AuthorizationManager', function () {
           return this.AuthorizationManager.assertClientCanEditProjectAndDoc(
             this.client,
             this.doc_id,
-            (err) => err.message.should.equal('not authorized')
+            err => err.message.should.equal('not authorized')
           )
         })
       })

+ 5 - 5
services/real-time/test/unit/js/ChannelManagerTests.js

@@ -20,12 +20,12 @@ describe('ChannelManager', function () {
     this.other_rclient = {}
     return (this.ChannelManager = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': (this.settings = {}),
+        '@overleaf/settings': (this.settings = {}),
         '@overleaf/metrics': (this.metrics = {
           inc: sinon.stub(),
-          summary: sinon.stub()
-        })
-      }
+          summary: sinon.stub(),
+        }),
+      },
     }))
   })
 
@@ -83,7 +83,7 @@ describe('ChannelManager', function () {
           '1234567890abcdef'
         )
         p.then(() => done(new Error('should not subscribe but fail'))).catch(
-          (err) => {
+          err => {
             err.message.should.equal('failed to subscribe to channel')
             err.cause.message.should.equal('some redis error')
             this.ChannelManager.getClientMapEntry(this.rclient)

+ 30 - 30
services/real-time/test/unit/js/ConnectedUsersManagerTests.js

@@ -31,10 +31,10 @@ describe('ConnectedUsersManager', function () {
             },
             connectedUser({ project_id, client_id }) {
               return `connected_user:${project_id}:${client_id}`
-            }
-          }
-        }
-      }
+            },
+          },
+        },
+      },
     }
     this.rClient = {
       auth() {},
@@ -50,19 +50,19 @@ describe('ConnectedUsersManager', function () {
       exec: sinon.stub(),
       multi: () => {
         return this.rClient
-      }
+      },
     }
     tk.freeze(new Date())
 
     this.ConnectedUsersManager = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': this.settings,
+        '@overleaf/settings': this.settings,
         '@overleaf/redis-wrapper': {
           createClient: () => {
             return this.rClient
-          }
-        }
-      }
+          },
+        },
+      },
     })
     this.client_id = '32132132'
     this.project_id = 'dskjh2u21321'
@@ -70,12 +70,12 @@ describe('ConnectedUsersManager', function () {
       _id: 'user-id-123',
       first_name: 'Joe',
       last_name: 'Bloggs',
-      email: 'joe@example.com'
+      email: 'joe@example.com',
     }
     return (this.cursorData = {
       row: 12,
       column: 9,
-      doc_id: '53c3b8c85fee64000023dc6e'
+      doc_id: '53c3b8c85fee64000023dc6e',
     })
   })
 
@@ -94,7 +94,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -113,7 +113,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -132,7 +132,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -151,7 +151,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -170,7 +170,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -189,7 +189,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.sadd
             .calledWith(`clients_in_project:${this.project_id}`, this.client_id)
             .should.equal(true)
@@ -204,7 +204,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.expire
             .calledWith(
               `clients_in_project:${this.project_id}`,
@@ -222,7 +222,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         null,
-        (err) => {
+        err => {
           this.rClient.expire
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -240,7 +240,7 @@ describe('ConnectedUsersManager', function () {
         this.client_id,
         this.user,
         this.cursorData,
-        (err) => {
+        err => {
           this.rClient.hset
             .calledWith(
               `connected_user:${this.project_id}:${this.client_id}`,
@@ -263,7 +263,7 @@ describe('ConnectedUsersManager', function () {
       return this.ConnectedUsersManager.markUserAsDisconnected(
         this.project_id,
         this.client_id,
-        (err) => {
+        err => {
           this.rClient.srem
             .calledWith(`clients_in_project:${this.project_id}`, this.client_id)
             .should.equal(true)
@@ -276,7 +276,7 @@ describe('ConnectedUsersManager', function () {
       return this.ConnectedUsersManager.markUserAsDisconnected(
         this.project_id,
         this.client_id,
-        (err) => {
+        err => {
           this.rClient.del
             .calledWith(`connected_user:${this.project_id}:${this.client_id}`)
             .should.equal(true)
@@ -289,7 +289,7 @@ describe('ConnectedUsersManager', function () {
       return this.ConnectedUsersManager.markUserAsDisconnected(
         this.project_id,
         this.client_id,
-        (err) => {
+        err => {
           this.rClient.expire
             .calledWith(
               `clients_in_project:${this.project_id}`,
@@ -309,7 +309,7 @@ describe('ConnectedUsersManager', function () {
         connected_at: new Date(),
         user_id: this.user._id,
         last_updated_at: `${Date.now()}`,
-        cursorData
+        cursorData,
       })
       return this.ConnectedUsersManager._getConnectedUser(
         this.project_id,
@@ -359,28 +359,28 @@ describe('ConnectedUsersManager', function () {
         .callsArgWith(2, null, {
           connected: true,
           client_age: 2,
-          client_id: this.users[0]
+          client_id: this.users[0],
         })
       this.ConnectedUsersManager._getConnectedUser
         .withArgs(this.project_id, this.users[1])
         .callsArgWith(2, null, {
           connected: false,
           client_age: 1,
-          client_id: this.users[1]
+          client_id: this.users[1],
         })
       this.ConnectedUsersManager._getConnectedUser
         .withArgs(this.project_id, this.users[2])
         .callsArgWith(2, null, {
           connected: true,
           client_age: 3,
-          client_id: this.users[2]
+          client_id: this.users[2],
         })
       return this.ConnectedUsersManager._getConnectedUser
         .withArgs(this.project_id, this.users[3])
         .callsArgWith(2, null, {
           connected: true,
           client_age: 11,
-          client_id: this.users[3]
+          client_id: this.users[3],
         })
     }) // connected but old
 
@@ -392,12 +392,12 @@ describe('ConnectedUsersManager', function () {
           users[0].should.deep.equal({
             client_id: this.users[0],
             client_age: 2,
-            connected: true
+            connected: true,
           })
           users[1].should.deep.equal({
             client_id: this.users[2],
             client_age: 3,
-            connected: true
+            connected: true,
           })
           return done()
         }

+ 25 - 23
services/real-time/test/unit/js/DocumentUpdaterControllerTests.js

@@ -28,40 +28,40 @@ describe('DocumentUpdaterController', function () {
     this.RoomEvents = { on: sinon.stub() }
     this.EditorUpdatesController = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': (this.settings = {
+        '@overleaf/settings': (this.settings = {
           redis: {
             documentupdater: {
               key_schema: {
                 pendingUpdates({ doc_id }) {
                   return `PendingUpdates:${doc_id}`
-                }
-              }
+                },
+              },
             },
-            pubsub: null
-          }
+            pubsub: null,
+          },
         }),
         './RedisClientManager': {
           createClientList: () => {
             this.redis = {
-              createClient: (name) => {
+              createClient: name => {
                 let rclientStub
                 this.rclient.push((rclientStub = { name }))
                 return rclientStub
-              }
+              },
             }
-          }
+          },
         },
         './SafeJsonParse': (this.SafeJsonParse = {
-          parse: (data, cb) => cb(null, JSON.parse(data))
+          parse: (data, cb) => cb(null, JSON.parse(data)),
         }),
         './EventLogger': (this.EventLogger = { checkEventOrder: sinon.stub() }),
         './HealthCheckManager': { check: sinon.stub() },
         '@overleaf/metrics': (this.metrics = { inc: sinon.stub() }),
         './RoomManager': (this.RoomManager = {
-          eventSource: sinon.stub().returns(this.RoomEvents)
+          eventSource: sinon.stub().returns(this.RoomEvents),
         }),
-        './ChannelManager': (this.ChannelManager = {})
-      }
+        './ChannelManager': (this.ChannelManager = {}),
+      },
     })
   })
 
@@ -70,7 +70,7 @@ describe('DocumentUpdaterController', function () {
       this.rclient.length = 0 // clear any existing clients
       this.EditorUpdatesController.rclientList = [
         this.redis.createClient('first'),
-        this.redis.createClient('second')
+        this.redis.createClient('second'),
       ]
       this.rclient[0].subscribe = sinon.stub()
       this.rclient[0].on = sinon.stub()
@@ -115,9 +115,10 @@ describe('DocumentUpdaterController', function () {
       beforeEach(function () {
         this.message = {
           doc_id: this.doc_id,
-          op: { t: 'foo', p: 12 }
+          op: { t: 'foo', p: 12 },
         }
-        this.EditorUpdatesController._applyUpdateFromDocumentUpdater = sinon.stub()
+        this.EditorUpdatesController._applyUpdateFromDocumentUpdater =
+          sinon.stub()
         return this.EditorUpdatesController._processMessageFromDocumentUpdater(
           this.io,
           'applied-ops',
@@ -136,9 +137,10 @@ describe('DocumentUpdaterController', function () {
       beforeEach(function () {
         this.message = {
           doc_id: this.doc_id,
-          error: 'Something went wrong'
+          error: 'Something went wrong',
         }
-        this.EditorUpdatesController._processErrorFromDocumentUpdater = sinon.stub()
+        this.EditorUpdatesController._processErrorFromDocumentUpdater =
+          sinon.stub()
         return this.EditorUpdatesController._processMessageFromDocumentUpdater(
           this.io,
           'applied-ops',
@@ -162,7 +164,7 @@ describe('DocumentUpdaterController', function () {
         op: [{ t: 'foo', p: 12 }],
         meta: { source: this.sourceClient.publicId },
         v: (this.version = 42),
-        doc: this.doc_id
+        doc: this.doc_id,
       }
       return (this.io.sockets = {
         clients: sinon
@@ -170,8 +172,8 @@ describe('DocumentUpdaterController', function () {
           .returns([
             this.sourceClient,
             ...Array.from(this.otherClients),
-            this.sourceClient
-          ])
+            this.sourceClient,
+          ]),
       })
     }) // include a duplicate client
 
@@ -198,7 +200,7 @@ describe('DocumentUpdaterController', function () {
       })
 
       return it('should send the full update to the other clients', function () {
-        return Array.from(this.otherClients).map((client) =>
+        return Array.from(this.otherClients).map(client =>
           client.emit
             .calledWith('otUpdateApplied', this.update)
             .should.equal(true)
@@ -223,7 +225,7 @@ describe('DocumentUpdaterController', function () {
       })
 
       return it("should not send anything to the other clients (they've already had the op)", function () {
-        return Array.from(this.otherClients).map((client) =>
+        return Array.from(this.otherClients).map(client =>
           client.emit.calledWith('otUpdateApplied').should.equal(false)
         )
       })
@@ -247,7 +249,7 @@ describe('DocumentUpdaterController', function () {
 
     return it('should disconnect all clients in that document', function () {
       this.io.sockets.clients.calledWith(this.doc_id).should.equal(true)
-      return Array.from(this.clients).map((client) =>
+      return Array.from(this.clients).map(client =>
         client.disconnect.called.should.equal(true)
       )
     })

+ 18 - 18
services/real-time/test/unit/js/DocumentUpdaterManagerTests.js

@@ -30,27 +30,27 @@ describe('DocumentUpdaterManager', function () {
           key_schema: {
             pendingUpdates({ doc_id }) {
               return `PendingUpdates:${doc_id}`
-            }
-          }
-        }
+            },
+          },
+        },
       },
       maxUpdateSize: 7 * 1024 * 1024,
-      pendingUpdateListShardCount: 10
+      pendingUpdateListShardCount: 10,
     }
     this.rclient = { auth() {} }
 
     return (this.DocumentUpdaterManager = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': this.settings,
+        '@overleaf/settings': this.settings,
         request: (this.request = {}),
         '@overleaf/redis-wrapper': { createClient: () => this.rclient },
         '@overleaf/metrics': (this.Metrics = {
           summary: sinon.stub(),
           Timer: (Timer = class Timer {
             done() {}
-          })
-        })
-      }
+          }),
+        }),
+      },
     }))
   }) // avoid modifying JSON object directly
 
@@ -65,7 +65,7 @@ describe('DocumentUpdaterManager', function () {
           lines: this.lines,
           version: this.version,
           ops: (this.ops = ['mock-op-1', 'mock-op-2']),
-          ranges: (this.ranges = { mock: 'ranges' })
+          ranges: (this.ranges = { mock: 'ranges' }),
         })
         this.fromVersion = 2
         this.request.get = sinon
@@ -113,7 +113,7 @@ describe('DocumentUpdaterManager', function () {
         return this.callback.calledWith(this.error).should.equal(true)
       })
     })
-    ;[404, 422].forEach((statusCode) =>
+    ;[404, 422].forEach(statusCode =>
       describe(`when the document updater returns a ${statusCode} status code`, function () {
         beforeEach(function () {
           this.request.get = sinon
@@ -133,7 +133,7 @@ describe('DocumentUpdaterManager', function () {
             .calledWith(
               sinon.match({
                 message: 'doc updater could not load requested ops',
-                info: { statusCode }
+                info: { statusCode },
               })
             )
             .should.equal(true)
@@ -164,8 +164,8 @@ describe('DocumentUpdaterManager', function () {
               message: 'doc updater returned a non-success status code',
               info: {
                 action: 'getDocument',
-                statusCode: 500
-              }
+                statusCode: 500,
+              },
             })
           )
           .should.equal(true)
@@ -240,8 +240,8 @@ describe('DocumentUpdaterManager', function () {
               message: 'doc updater returned a non-success status code',
               info: {
                 action: 'flushProjectToMongoAndDelete',
-                statusCode: 500
-              }
+                statusCode: 500,
+              },
             })
           )
           .should.equal(true)
@@ -254,7 +254,7 @@ describe('DocumentUpdaterManager', function () {
       this.change = {
         doc: '1234567890',
         op: [{ d: 'test', p: 345 }],
-        v: 789
+        v: 789,
       }
       this.rclient.rpush = sinon.stub().yields()
       return (this.callback = sinon.stub())
@@ -345,7 +345,7 @@ describe('DocumentUpdaterManager', function () {
     describe('when the update is too large', function () {
       beforeEach(function () {
         this.change = {
-          op: { p: 12, t: 'update is too large'.repeat(1024 * 400) }
+          op: { p: 12, t: 'update is too large'.repeat(1024 * 400) },
         }
         return this.DocumentUpdaterManager.queueChange(
           this.project_id,
@@ -374,7 +374,7 @@ describe('DocumentUpdaterManager', function () {
       beforeEach(function () {
         this.change = {
           op: [{ d: 'test', p: 345 }],
-          version: 789 // not a valid key
+          version: 789, // not a valid key
         }
         return this.DocumentUpdaterManager.queueChange(
           this.project_id,

+ 10 - 10
services/real-time/test/unit/js/DrainManagerTests.js

@@ -19,8 +19,8 @@ describe('DrainManager', function () {
     this.DrainManager = SandboxedModule.require(modulePath, {})
     return (this.io = {
       sockets: {
-        clients: sinon.stub()
-      }
+        clients: sinon.stub(),
+      },
     })
   })
 
@@ -30,7 +30,7 @@ describe('DrainManager', function () {
       for (let i = 0; i <= 5399; i++) {
         this.clients[i] = {
           id: i,
-          emit: sinon.stub()
+          emit: sinon.stub(),
         }
       }
       this.io.sockets.clients.returns(this.clients)
@@ -50,7 +50,7 @@ describe('DrainManager', function () {
       for (let i = 0; i <= 9; i++) {
         this.clients[i] = {
           id: i,
-          emit: sinon.stub()
+          emit: sinon.stub(),
         }
       }
       return this.io.sockets.clients.returns(this.clients)
@@ -62,7 +62,7 @@ describe('DrainManager', function () {
       })
 
       it('should reconnect the first 3 clients', function () {
-        return [0, 1, 2].map((i) =>
+        return [0, 1, 2].map(i =>
           this.clients[i].emit
             .calledWith('reconnectGracefully')
             .should.equal(true)
@@ -70,7 +70,7 @@ describe('DrainManager', function () {
       })
 
       it('should not reconnect any more clients', function () {
-        return [3, 4, 5, 6, 7, 8, 9].map((i) =>
+        return [3, 4, 5, 6, 7, 8, 9].map(i =>
           this.clients[i].emit
             .calledWith('reconnectGracefully')
             .should.equal(false)
@@ -83,7 +83,7 @@ describe('DrainManager', function () {
         })
 
         it('should reconnect the next 3 clients', function () {
-          return [3, 4, 5].map((i) =>
+          return [3, 4, 5].map(i =>
             this.clients[i].emit
               .calledWith('reconnectGracefully')
               .should.equal(true)
@@ -91,7 +91,7 @@ describe('DrainManager', function () {
         })
 
         it('should not reconnect any more clients', function () {
-          return [6, 7, 8, 9].map((i) =>
+          return [6, 7, 8, 9].map(i =>
             this.clients[i].emit
               .calledWith('reconnectGracefully')
               .should.equal(false)
@@ -99,7 +99,7 @@ describe('DrainManager', function () {
         })
 
         it('should not reconnect the first 3 clients again', function () {
-          return [0, 1, 2].map((i) =>
+          return [0, 1, 2].map(i =>
             this.clients[i].emit.calledOnce.should.equal(true)
           )
         })
@@ -110,7 +110,7 @@ describe('DrainManager', function () {
           })
 
           it('should not reconnect the first 6 clients again', function () {
-            return [0, 1, 2, 3, 4, 5].map((i) =>
+            return [0, 1, 2, 3, 4, 5].map(i =>
               this.clients[i].emit.calledOnce.should.equal(true)
             )
           })

+ 11 - 10
services/real-time/test/unit/js/EventLoggerTests.js

@@ -20,8 +20,8 @@ describe('EventLogger', function () {
     tk.freeze(new Date(this.start))
     this.EventLogger = SandboxedModule.require(modulePath, {
       requires: {
-        '@overleaf/metrics': (this.metrics = { inc: sinon.stub() })
-      }
+        '@overleaf/metrics': (this.metrics = { inc: sinon.stub() }),
+      },
     })
     this.channel = 'applied-ops'
     this.id_1 = 'random-hostname:abc-1'
@@ -54,8 +54,9 @@ describe('EventLogger', function () {
       })
 
       return it('should increment the valid event metric', function () {
-        return this.metrics.inc.calledWith(`event.${this.channel}.valid`, 1)
-          .should.equal.true
+        return this.metrics.inc
+          .calledWith(`event.${this.channel}.valid`)
+          .should.equals(true)
       })
     })
 
@@ -78,8 +79,9 @@ describe('EventLogger', function () {
       })
 
       return it('should increment the duplicate event metric', function () {
-        return this.metrics.inc.calledWith(`event.${this.channel}.duplicate`, 1)
-          .should.equal.true
+        return this.metrics.inc
+          .calledWith(`event.${this.channel}.duplicate`)
+          .should.equals(true)
       })
     })
 
@@ -107,10 +109,9 @@ describe('EventLogger', function () {
       })
 
       return it('should increment the out-of-order event metric', function () {
-        return this.metrics.inc.calledWith(
-          `event.${this.channel}.out-of-order`,
-          1
-        ).should.equal.true
+        return this.metrics.inc
+          .calledWith(`event.${this.channel}.out-of-order`)
+          .should.equals(true)
       })
     })
 

+ 10 - 10
services/real-time/test/unit/js/RoomManagerTests.js

@@ -23,9 +23,9 @@ describe('RoomManager', function () {
     this.client = { namespace: { name: '' }, id: 'first-client' }
     this.RoomManager = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': (this.settings = {}),
-        '@overleaf/metrics': (this.metrics = { gauge: sinon.stub() })
-      }
+        '@overleaf/settings': (this.settings = {}),
+        '@overleaf/metrics': (this.metrics = { gauge: sinon.stub() }),
+      },
     })
     this.RoomManager._clientsInRoom = sinon.stub()
     this.RoomManager._clientAlreadyInRoom = sinon.stub()
@@ -41,7 +41,7 @@ describe('RoomManager', function () {
       })
 
       beforeEach(function (done) {
-        this.onUnhandled = (error) => {
+        this.onUnhandled = error => {
           this.unhandledError = error
           return done(new Error(`unhandledRejection: ${error.message}`))
         }
@@ -71,7 +71,7 @@ describe('RoomManager', function () {
           .returns(0)
         this.client.join = sinon.stub()
         this.callback = sinon.stub()
-        this.RoomEvents.on('project-active', (id) => {
+        this.RoomEvents.on('project-active', id => {
           return setTimeout(() => {
             return this.RoomEvents.emit(`project-subscribed-${id}`)
           }, 100)
@@ -79,7 +79,7 @@ describe('RoomManager', function () {
         return this.RoomManager.joinProject(
           this.client,
           this.project_id,
-          (err) => {
+          err => {
             this.callback(err)
             return done()
           }
@@ -136,12 +136,12 @@ describe('RoomManager', function () {
           .returns(0)
         this.client.join = sinon.stub()
         this.callback = sinon.stub()
-        this.RoomEvents.on('doc-active', (id) => {
+        this.RoomEvents.on('doc-active', id => {
           return setTimeout(() => {
             return this.RoomEvents.emit(`doc-subscribed-${id}`)
           }, 100)
         })
-        return this.RoomManager.joinDoc(this.client, this.doc_id, (err) => {
+        return this.RoomManager.joinDoc(this.client, this.doc_id, err => {
           this.callback(err)
           return done()
         })
@@ -301,12 +301,12 @@ describe('RoomManager', function () {
             .returns(true)
             .withArgs(this.client, this.project_id)
             .returns(true)
-          this.RoomEvents.on('project-active', (id) => {
+          this.RoomEvents.on('project-active', id => {
             return setTimeout(() => {
               return this.RoomEvents.emit(`project-subscribed-${id}`)
             }, 100)
           })
-          this.RoomEvents.on('doc-active', (id) => {
+          this.RoomEvents.on('doc-active', id => {
             return setTimeout(() => {
               return this.RoomEvents.emit(`doc-subscribed-${id}`)
             }, 100)

+ 4 - 4
services/real-time/test/unit/js/SafeJsonParseTest.js

@@ -19,10 +19,10 @@ describe('SafeJsonParse', function () {
   beforeEach(function () {
     return (this.SafeJsonParse = SandboxedModule.require(modulePath, {
       requires: {
-        'settings-sharelatex': (this.Settings = {
-          maxUpdateSize: 16 * 1024
-        })
-      }
+        '@overleaf/settings': (this.Settings = {
+          maxUpdateSize: 16 * 1024,
+        }),
+      },
     }))
   })
 

+ 12 - 12
services/real-time/test/unit/js/SessionSocketsTests.js

@@ -23,7 +23,7 @@ describe('SessionSockets', function () {
     this.id2 = Math.random().toString()
     const redisResponses = {
       error: [new Error('Redis: something went wrong'), null],
-      unknownId: [null, null]
+      unknownId: [null, null],
     }
     redisResponses[this.id1] = [null, { user: { _id: '123' } }]
     redisResponses[this.id2] = [null, { user: { _id: 'abc' } }]
@@ -31,7 +31,7 @@ describe('SessionSockets', function () {
     this.sessionStore = {
       get: sinon
         .stub()
-        .callsFake((id, fn) => fn.apply(null, redisResponses[id]))
+        .callsFake((id, fn) => fn.apply(null, redisResponses[id])),
     }
     this.cookieParser = function (req, res, next) {
       req.signedCookies = req._signedCookies
@@ -55,7 +55,7 @@ describe('SessionSockets', function () {
     })
 
     it('should return a lookup error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.exist
         expect(error.message).to.equal('could not look up session by key')
         return done()
@@ -76,7 +76,7 @@ describe('SessionSockets', function () {
     })
 
     it('should return a lookup error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.exist
         expect(error.message).to.equal('could not look up session by key')
         return done()
@@ -94,7 +94,7 @@ describe('SessionSockets', function () {
   describe('with a valid cookie and a failing session lookup', function () {
     before(function () {
       return (this.socket = {
-        handshake: { _signedCookies: { 'ol.sid': 'error' } }
+        handshake: { _signedCookies: { 'ol.sid': 'error' } },
       })
     })
 
@@ -106,7 +106,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a redis error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.exist
         expect(error.message).to.equal('Redis: something went wrong')
         return done()
@@ -117,7 +117,7 @@ describe('SessionSockets', function () {
   describe('with a valid cookie and no matching session', function () {
     before(function () {
       return (this.socket = {
-        handshake: { _signedCookies: { 'ol.sid': 'unknownId' } }
+        handshake: { _signedCookies: { 'ol.sid': 'unknownId' } },
       })
     })
 
@@ -129,7 +129,7 @@ describe('SessionSockets', function () {
     })
 
     return it('should return a lookup error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.exist
         expect(error.message).to.equal('could not look up session by key')
         return done()
@@ -140,7 +140,7 @@ describe('SessionSockets', function () {
   describe('with a valid cookie and a matching session', function () {
     before(function () {
       return (this.socket = {
-        handshake: { _signedCookies: { 'ol.sid': this.id1 } }
+        handshake: { _signedCookies: { 'ol.sid': this.id1 } },
       })
     })
 
@@ -152,7 +152,7 @@ describe('SessionSockets', function () {
     })
 
     it('should not return an error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.not.exist
         return done()
       })
@@ -169,7 +169,7 @@ describe('SessionSockets', function () {
   return describe('with a different valid cookie and matching session', function () {
     before(function () {
       return (this.socket = {
-        handshake: { _signedCookies: { 'ol.sid': this.id2 } }
+        handshake: { _signedCookies: { 'ol.sid': this.id2 } },
       })
     })
 
@@ -181,7 +181,7 @@ describe('SessionSockets', function () {
     })
 
     it('should not return an error', function (done) {
-      return this.checkSocket(this.socket, (error) => {
+      return this.checkSocket(this.socket, error => {
         expect(error).to.not.exist
         return done()
       })

+ 16 - 16
services/real-time/test/unit/js/WebApiManagerTests.js

@@ -23,16 +23,16 @@ describe('WebApiManager', function () {
     return (this.WebApiManager = SandboxedModule.require(modulePath, {
       requires: {
         request: (this.request = {}),
-        'settings-sharelatex': (this.settings = {
+        '@overleaf/settings': (this.settings = {
           apis: {
             web: {
               url: 'http://web.example.com',
               user: 'username',
-              pass: 'password'
-            }
-          }
-        })
-      }
+              pass: 'password',
+            },
+          },
+        }),
+      },
     }))
   })
 
@@ -42,7 +42,7 @@ describe('WebApiManager', function () {
         this.response = {
           project: { name: 'Test project' },
           privilegeLevel: 'owner',
-          isRestrictedUser: true
+          isRestrictedUser: true,
         }
         this.request.post = sinon
           .stub()
@@ -59,16 +59,16 @@ describe('WebApiManager', function () {
           .calledWith({
             url: `${this.settings.apis.web.url}/project/${this.project_id}/join`,
             qs: {
-              user_id: this.user_id
+              user_id: this.user_id,
             },
             auth: {
               user: this.settings.apis.web.user,
               pass: this.settings.apis.web.pass,
-              sendImmediately: true
+              sendImmediately: true,
             },
             json: true,
             jar: false,
-            headers: {}
+            headers: {},
           })
           .should.equal(true)
       })
@@ -101,7 +101,7 @@ describe('WebApiManager', function () {
         this.callback
           .calledWith(
             sinon.match({
-              message: 'not authorized'
+              message: 'not authorized',
             })
           )
           .should.equal(true)
@@ -125,7 +125,7 @@ describe('WebApiManager', function () {
           .calledWith(
             sinon.match({
               message: 'project not found',
-              info: { code: 'ProjectNotFound' }
+              info: { code: 'ProjectNotFound' },
             })
           )
           .should.equal(true)
@@ -149,7 +149,7 @@ describe('WebApiManager', function () {
           .calledWith(
             sinon.match({
               message: 'non-success status code from web',
-              info: { statusCode: 500 }
+              info: { statusCode: 500 },
             })
           )
           .should.equal(true)
@@ -172,7 +172,7 @@ describe('WebApiManager', function () {
         return this.callback
           .calledWith(
             sinon.match({
-              message: 'no data returned from joinProject request'
+              message: 'no data returned from joinProject request',
             })
           )
           .should.equal(true)
@@ -197,8 +197,8 @@ describe('WebApiManager', function () {
             sinon.match({
               message: 'rate-limit hit when joining project',
               info: {
-                code: 'TooManyRequests'
-              }
+                code: 'TooManyRequests',
+              },
             })
           )
           .should.equal(true)

+ 51 - 49
services/real-time/test/unit/js/WebsocketControllerTests.js

@@ -29,7 +29,7 @@ describe('WebsocketController', function () {
       last_name: 'Allen',
       email: 'james@example.com',
       signUpDate: new Date('2014-01-01'),
-      loginCount: 42
+      loginCount: 42,
     }
     this.callback = sinon.stub()
     this.client = {
@@ -39,7 +39,7 @@ describe('WebsocketController', function () {
       ol_context: {},
       joinLeaveEpoch: 0,
       join: sinon.stub(),
-      leave: sinon.stub()
+      leave: sinon.stub(),
     }
     return (this.WebsocketController = SandboxedModule.require(modulePath, {
       requires: {
@@ -50,10 +50,10 @@ describe('WebsocketController', function () {
         './WebsocketLoadBalancer': (this.WebsocketLoadBalancer = {}),
         '@overleaf/metrics': (this.metrics = {
           inc: sinon.stub(),
-          set: sinon.stub()
+          set: sinon.stub(),
         }),
-        './RoomManager': (this.RoomManager = {})
-      }
+        './RoomManager': (this.RoomManager = {}),
+      },
     }))
   })
 
@@ -68,8 +68,8 @@ describe('WebsocketController', function () {
         this.project = {
           name: 'Test Project',
           owner: {
-            _id: (this.owner_id = 'mock-owner-id-123')
-          }
+            _id: (this.owner_id = 'mock-owner-id-123'),
+          },
         }
         this.privilegeLevel = 'owner'
         this.ConnectedUsersManager.updateUserPosition = sinon
@@ -205,8 +205,8 @@ describe('WebsocketController', function () {
         this.project = {
           name: 'Test Project',
           owner: {
-            _id: (this.owner_id = 'mock-owner-id-123')
-          }
+            _id: (this.owner_id = 'mock-owner-id-123'),
+          },
         }
         this.privilegeLevel = 'owner'
         this.ConnectedUsersManager.updateUserPosition = sinon
@@ -264,7 +264,7 @@ describe('WebsocketController', function () {
       return it('should increment the editor.join-project.disconnected metric with a status', function () {
         return expect(
           this.metrics.inc.calledWith('editor.join-project.disconnected', 1, {
-            status: 'immediately'
+            status: 'immediately',
           })
         ).to.equal(true)
       })
@@ -297,7 +297,7 @@ describe('WebsocketController', function () {
       return it('should increment the editor.join-project.disconnected metric with a status', function () {
         return expect(
           this.metrics.inc.calledWith('editor.join-project.disconnected', 1, {
-            status: 'after-web-api-call'
+            status: 'after-web-api-call',
           })
         ).to.equal(true)
       })
@@ -317,13 +317,13 @@ describe('WebsocketController', function () {
       this.clientsInRoom = []
       this.io = {
         sockets: {
-          clients: (room_id) => {
+          clients: room_id => {
             if (room_id !== this.project_id) {
               throw 'expected room_id to be project_id'
             }
             return this.clientsInRoom
-          }
-        }
+          },
+        },
       }
       this.client.ol_context.project_id = this.project_id
       this.client.ol_context.user_id = this.user_id
@@ -396,13 +396,13 @@ describe('WebsocketController', function () {
         this.clientsInRoom = ['mock-remaining-client']
         this.io = {
           sockets: {
-            clients: (room_id) => {
+            clients: room_id => {
               if (room_id !== this.project_id) {
                 throw 'expected room_id to be project_id'
               }
               return this.clientsInRoom
-            }
-          }
+            },
+          },
         }
         return this.WebsocketController.leaveProject(this.io, this.client, done)
       })
@@ -729,7 +729,7 @@ describe('WebsocketController', function () {
       it('should increment the editor.join-doc.disconnected metric with a status', function () {
         return expect(
           this.metrics.inc.calledWith('editor.join-doc.disconnected', 1, {
-            status: 'immediately'
+            status: 'immediately',
           })
         ).to.equal(true)
       })
@@ -775,7 +775,7 @@ describe('WebsocketController', function () {
       it('should increment the editor.join-doc.disconnected metric with a status', function () {
         expect(
           this.metrics.inc.calledWith('editor.join-doc.disconnected', 1, {
-            status: 'after-client-auth-check'
+            status: 'after-client-auth-check',
           })
         ).to.equal(true)
       })
@@ -894,7 +894,7 @@ describe('WebsocketController', function () {
       it('should increment the editor.join-doc.disconnected metric with a status', function () {
         return expect(
           this.metrics.inc.calledWith('editor.join-doc.disconnected', 1, {
-            status: 'after-joining-room'
+            status: 'after-joining-room',
           })
         ).to.equal(true)
       })
@@ -940,7 +940,7 @@ describe('WebsocketController', function () {
       return it('should increment the editor.join-doc.disconnected metric with a status', function () {
         return expect(
           this.metrics.inc.calledWith('editor.join-doc.disconnected', 1, {
-            status: 'after-doc-updater-call'
+            status: 'after-doc-updater-call',
           })
         ).to.equal(true)
       })
@@ -1110,7 +1110,7 @@ describe('WebsocketController', function () {
       return (this.update = {
         doc_id: (this.doc_id = 'doc-id-123'),
         row: (this.row = 42),
-        column: (this.column = 37)
+        column: (this.column = 37),
       })
     })
 
@@ -1121,7 +1121,7 @@ describe('WebsocketController', function () {
           first_name: (this.first_name = 'Douglas'),
           last_name: (this.last_name = 'Adams'),
           email: (this.email = 'joe@example.com'),
-          user_id: (this.user_id = 'user-id-123')
+          user_id: (this.user_id = 'user-id-123'),
         }
 
         this.populatedCursorData = {
@@ -1131,7 +1131,7 @@ describe('WebsocketController', function () {
           row: this.row,
           column: this.column,
           email: this.email,
-          user_id: this.user_id
+          user_id: this.user_id,
         }
         this.WebsocketController.updateClientPosition(
           this.client,
@@ -1159,12 +1159,12 @@ describe('WebsocketController', function () {
               _id: this.user_id,
               email: this.email,
               first_name: this.first_name,
-              last_name: this.last_name
+              last_name: this.last_name,
             },
             {
               row: this.row,
               column: this.column,
-              doc_id: this.doc_id
+              doc_id: this.doc_id,
             }
           )
           .should.equal(true)
@@ -1185,7 +1185,7 @@ describe('WebsocketController', function () {
           first_name: (this.first_name = 'Douglas'),
           last_name: undefined,
           email: (this.email = 'joe@example.com'),
-          user_id: (this.user_id = 'user-id-123')
+          user_id: (this.user_id = 'user-id-123'),
         }
 
         this.populatedCursorData = {
@@ -1195,7 +1195,7 @@ describe('WebsocketController', function () {
           row: this.row,
           column: this.column,
           email: this.email,
-          user_id: this.user_id
+          user_id: this.user_id,
         }
         this.WebsocketController.updateClientPosition(
           this.client,
@@ -1223,12 +1223,12 @@ describe('WebsocketController', function () {
               _id: this.user_id,
               email: this.email,
               first_name: this.first_name,
-              last_name: undefined
+              last_name: undefined,
             },
             {
               row: this.row,
               column: this.column,
-              doc_id: this.doc_id
+              doc_id: this.doc_id,
             }
           )
           .should.equal(true)
@@ -1249,7 +1249,7 @@ describe('WebsocketController', function () {
           first_name: undefined,
           last_name: (this.last_name = 'Adams'),
           email: (this.email = 'joe@example.com'),
-          user_id: (this.user_id = 'user-id-123')
+          user_id: (this.user_id = 'user-id-123'),
         }
 
         this.populatedCursorData = {
@@ -1259,7 +1259,7 @@ describe('WebsocketController', function () {
           row: this.row,
           column: this.column,
           email: this.email,
-          user_id: this.user_id
+          user_id: this.user_id,
         }
         this.WebsocketController.updateClientPosition(
           this.client,
@@ -1287,12 +1287,12 @@ describe('WebsocketController', function () {
               _id: this.user_id,
               email: this.email,
               first_name: undefined,
-              last_name: this.last_name
+              last_name: this.last_name,
             },
             {
               row: this.row,
               column: this.column,
-              doc_id: this.doc_id
+              doc_id: this.doc_id,
             }
           )
           .should.equal(true)
@@ -1312,7 +1312,7 @@ describe('WebsocketController', function () {
           first_name: undefined,
           last_name: undefined,
           email: (this.email = 'joe@example.com'),
-          user_id: (this.user_id = 'user-id-123')
+          user_id: (this.user_id = 'user-id-123'),
         }
         return this.WebsocketController.updateClientPosition(
           this.client,
@@ -1330,7 +1330,7 @@ describe('WebsocketController', function () {
             name: '',
             row: this.row,
             column: this.column,
-            email: this.email
+            email: this.email,
           })
           .should.equal(true)
       })
@@ -1339,7 +1339,7 @@ describe('WebsocketController', function () {
     describe('with an anonymous user', function () {
       beforeEach(function (done) {
         this.client.ol_context = {
-          project_id: this.project_id
+          project_id: this.project_id,
         }
         return this.WebsocketController.updateClientPosition(
           this.client,
@@ -1355,7 +1355,7 @@ describe('WebsocketController', function () {
             id: this.client.publicId,
             name: '',
             row: this.row,
-            column: this.column
+            column: this.column,
           })
           .should.equal(true)
       })
@@ -1369,7 +1369,8 @@ describe('WebsocketController', function () {
     return describe('when the client has disconnected', function () {
       beforeEach(function (done) {
         this.client.disconnected = true
-        this.AuthorizationManager.assertClientCanViewProjectAndDoc = sinon.stub()
+        this.AuthorizationManager.assertClientCanViewProjectAndDoc =
+          sinon.stub()
         return this.WebsocketController.updateClientPosition(
           this.client,
           this.update,
@@ -1526,9 +1527,9 @@ describe('WebsocketController', function () {
             user_id: this.user_id,
             project_id: this.project_id,
             doc_id: this.doc_id,
-            updateSize: 7372835
+            updateSize: 7372835,
           },
-          'update is too large'
+          'update is too large',
         ])
       })
 
@@ -1565,7 +1566,7 @@ describe('WebsocketController', function () {
         return it('should increment the editor.doc-update.disconnected metric with a status', function () {
           return expect(
             this.metrics.inc.calledWith('editor.doc-update.disconnected', 1, {
-              status: 'at-otUpdateError'
+              status: 'at-otUpdateError',
             })
           ).to.equal(true)
         })
@@ -1578,12 +1579,13 @@ describe('WebsocketController', function () {
       this.edit_update = {
         op: [
           { i: 'foo', p: 42 },
-          { c: 'bar', p: 132 }
-        ]
+          { c: 'bar', p: 132 },
+        ],
       } // comments may still be in an edit op
       this.comment_update = { op: [{ c: 'bar', p: 132 }] }
       this.AuthorizationManager.assertClientCanEditProjectAndDoc = sinon.stub()
-      return (this.AuthorizationManager.assertClientCanViewProjectAndDoc = sinon.stub())
+      return (this.AuthorizationManager.assertClientCanViewProjectAndDoc =
+        sinon.stub())
     })
 
     describe('with a read-write client', function () {
@@ -1593,7 +1595,7 @@ describe('WebsocketController', function () {
           this.client,
           this.doc_id,
           this.edit_update,
-          (error) => {
+          error => {
             expect(error).to.be.null
             return done()
           }
@@ -1611,7 +1613,7 @@ describe('WebsocketController', function () {
           this.client,
           this.doc_id,
           this.edit_update,
-          (error) => {
+          error => {
             expect(error.message).to.equal('not authorized')
             return done()
           }
@@ -1629,7 +1631,7 @@ describe('WebsocketController', function () {
           this.client,
           this.doc_id,
           this.comment_update,
-          (error) => {
+          error => {
             expect(error).to.be.null
             return done()
           }
@@ -1649,7 +1651,7 @@ describe('WebsocketController', function () {
           this.client,
           this.doc_id,
           this.comment_update,
-          (error) => {
+          error => {
             expect(error.message).to.equal('not authorized')
             return done()
           }

+ 30 - 30
services/real-time/test/unit/js/WebsocketLoadBalancerTests.js

@@ -23,29 +23,29 @@ describe('WebsocketLoadBalancer', function () {
     this.WebsocketLoadBalancer = SandboxedModule.require(modulePath, {
       requires: {
         './RedisClientManager': {
-          createClientList: () => []
+          createClientList: () => [],
         },
         './SafeJsonParse': (this.SafeJsonParse = {
-          parse: (data, cb) => cb(null, JSON.parse(data))
+          parse: (data, cb) => cb(null, JSON.parse(data)),
         }),
         './EventLogger': { checkEventOrder: sinon.stub() },
         './HealthCheckManager': { check: sinon.stub() },
         './RoomManager': (this.RoomManager = {
-          eventSource: sinon.stub().returns(this.RoomEvents)
+          eventSource: sinon.stub().returns(this.RoomEvents),
         }),
         './ChannelManager': (this.ChannelManager = { publish: sinon.stub() }),
         './ConnectedUsersManager': (this.ConnectedUsersManager = {
-          refreshClient: sinon.stub()
-        })
-      }
+          refreshClient: sinon.stub(),
+        }),
+      },
     })
     this.io = {}
     this.WebsocketLoadBalancer.rclientPubList = [{ publish: sinon.stub() }]
     this.WebsocketLoadBalancer.rclientSubList = [
       {
         subscribe: sinon.stub(),
-        on: sinon.stub()
-      }
+        on: sinon.stub(),
+      },
     ]
 
     this.room_id = 'room-id'
@@ -71,7 +71,7 @@ describe('WebsocketLoadBalancer', function () {
           JSON.stringify({
             room_id: this.room_id,
             message: this.message,
-            payload: this.payload
+            payload: this.payload,
           })
         )
         .should.equal(true)
@@ -139,24 +139,24 @@ describe('WebsocketLoadBalancer', function () {
             {
               id: 'client-id-1',
               emit: (this.emit1 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-2',
               emit: (this.emit2 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-1',
               emit: (this.emit3 = sinon.stub()),
-              ol_context: {}
-            } // duplicate client
-          ])
+              ol_context: {},
+            }, // duplicate client
+          ]),
         }
         const data = JSON.stringify({
           room_id: this.room_id,
           message: this.message,
-          payload: this.payload
+          payload: this.payload,
         })
         return this.WebsocketLoadBalancer._processEditorEvent(
           this.io,
@@ -184,29 +184,29 @@ describe('WebsocketLoadBalancer', function () {
             {
               id: 'client-id-1',
               emit: (this.emit1 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-2',
               emit: (this.emit2 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-1',
               emit: (this.emit3 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             }, // duplicate client
             {
               id: 'client-id-4',
               emit: (this.emit4 = sinon.stub()),
-              ol_context: { is_restricted_user: true }
-            }
-          ])
+              ol_context: { is_restricted_user: true },
+            },
+          ]),
         }
         const data = JSON.stringify({
           room_id: this.room_id,
           message: this.message,
-          payload: this.payload
+          payload: this.payload,
         })
         return this.WebsocketLoadBalancer._processEditorEvent(
           this.io,
@@ -235,29 +235,29 @@ describe('WebsocketLoadBalancer', function () {
             {
               id: 'client-id-1',
               emit: (this.emit1 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-2',
               emit: (this.emit2 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             },
             {
               id: 'client-id-1',
               emit: (this.emit3 = sinon.stub()),
-              ol_context: {}
+              ol_context: {},
             }, // duplicate client
             {
               id: 'client-id-4',
               emit: (this.emit4 = sinon.stub()),
-              ol_context: { is_restricted_user: true }
-            }
-          ])
+              ol_context: { is_restricted_user: true },
+            },
+          ]),
         }
         const data = JSON.stringify({
           room_id: this.room_id,
           message: (this.restrictedMessage = 'new-comment'),
-          payload: this.payload
+          payload: this.payload,
         })
         return this.WebsocketLoadBalancer._processEditorEvent(
           this.io,
@@ -285,7 +285,7 @@ describe('WebsocketLoadBalancer', function () {
         const data = JSON.stringify({
           room_id: 'all',
           message: this.message,
-          payload: this.payload
+          payload: this.payload,
         })
         return this.WebsocketLoadBalancer._processEditorEvent(
           this.io,

Некоторые файлы не были показаны из-за большого количества измененных файлов