ReceiveEditorEventTests.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* eslint-disable
  2. no-unused-vars,
  3. */
  4. // TODO: This file was created by bulk-decaffeinate.
  5. // Fix any style issues and re-enable lint.
  6. /*
  7. * decaffeinate suggestions:
  8. * DS102: Remove unnecessary code created because of implicit returns
  9. * DS207: Consider shorter variations of null checks
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const { expect } = require('chai')
  13. const RealTimeClient = require('./helpers/RealTimeClient')
  14. const FixturesManager = require('./helpers/FixturesManager')
  15. const async = require('async')
  16. const settings = require('@overleaf/settings')
  17. const redis = require('@overleaf/redis-wrapper')
  18. const rclient = redis.createClient(settings.redis.pubsub)
  19. describe('receiveEditorEvent', function () {
  20. beforeEach(function (done) {
  21. this.lines = ['test', 'doc', 'lines']
  22. this.version = 42
  23. this.ops = ['mock', 'doc', 'ops']
  24. /**
  25. * We will set up a project, a doc, and three users: the owner, user 'a' and user 'b'
  26. */
  27. this.project_id = null
  28. this.doc_id = null
  29. this.owner_user_id = null
  30. this.owner_client = null
  31. this.user_a_id = null
  32. this.user_a_client = null
  33. this.user_b_id = null
  34. this.user_b_client = null
  35. async.series(
  36. [
  37. /**
  38. * Create the project, doc, and owner
  39. */
  40. cb => {
  41. return FixturesManager.setUpProject(
  42. {
  43. privilegeLevel: 'owner',
  44. project: { name: 'Test Project' },
  45. },
  46. (error, { user_id: userId, project_id: projectId }) => {
  47. if (error) return done(error)
  48. this.owner_user_id = userId
  49. this.project_id = projectId
  50. return cb()
  51. }
  52. )
  53. },
  54. cb => {
  55. return FixturesManager.setUpDoc(
  56. this.project_id,
  57. { lines: this.lines, version: this.version, ops: this.ops },
  58. (e, { doc_id: docId }) => {
  59. this.doc_id = docId
  60. return cb(e)
  61. }
  62. )
  63. },
  64. /**
  65. * Connect owner to project/doc
  66. */
  67. cb => {
  68. this.owner_client = RealTimeClient.connect()
  69. return this.owner_client.on('connectionAccepted', cb)
  70. },
  71. cb => {
  72. return this.owner_client.emit(
  73. 'joinProject',
  74. {
  75. project_id: this.project_id,
  76. },
  77. cb
  78. )
  79. },
  80. cb => {
  81. return this.owner_client.emit('joinDoc', this.doc_id, cb)
  82. },
  83. /**
  84. * add user_a to project
  85. */
  86. cb => {
  87. return FixturesManager.setUpProject(
  88. {
  89. privilegeLevel: 'readAndWrite',
  90. project_id: this.project_id,
  91. },
  92. (error, { user_id: userIdSecond }) => {
  93. if (error) return done(error)
  94. this.user_a_id = userIdSecond
  95. return cb()
  96. }
  97. )
  98. },
  99. /**
  100. * Connect user_a to project/doc
  101. */
  102. cb => {
  103. this.user_a_client = RealTimeClient.connect()
  104. return this.user_a_client.on('connectionAccepted', cb)
  105. },
  106. cb => {
  107. return this.user_a_client.emit(
  108. 'joinProject',
  109. {
  110. project_id: this.project_id,
  111. },
  112. cb
  113. )
  114. },
  115. cb => {
  116. return this.user_a_client.emit('joinDoc', this.doc_id, cb)
  117. },
  118. /**
  119. * Set up user_b
  120. */
  121. cb => {
  122. return FixturesManager.setUpProject(
  123. {
  124. privilegeLevel: 'readAndWrite',
  125. project_id: this.project_id,
  126. },
  127. (error, { user_id: userIdThird }) => {
  128. if (error) return done(error)
  129. this.user_b_id = userIdThird
  130. return cb()
  131. }
  132. )
  133. },
  134. /**
  135. * Connect user_b to project/doc
  136. */
  137. cb => {
  138. this.user_b_client = RealTimeClient.connect()
  139. return this.user_b_client.on('connectionAccepted', cb)
  140. },
  141. cb => {
  142. return this.user_b_client.emit(
  143. 'joinProject',
  144. {
  145. project_id: this.project_id,
  146. },
  147. cb
  148. )
  149. },
  150. cb => {
  151. return this.user_b_client.emit('joinDoc', this.doc_id, cb)
  152. },
  153. /**
  154. * Listen for updates
  155. */
  156. cb => {
  157. const eventName = 'userRemovedFromProject'
  158. this.owner_updates = []
  159. this.owner_client.on(eventName, update =>
  160. this.owner_updates.push({ [eventName]: update })
  161. )
  162. this.user_a_updates = []
  163. this.user_a_client.on(eventName, update =>
  164. this.user_a_updates.push({ [eventName]: update })
  165. )
  166. this.user_b_updates = []
  167. this.user_b_client.on(eventName, update =>
  168. this.user_b_updates.push({ [eventName]: update })
  169. )
  170. return cb()
  171. },
  172. ],
  173. done
  174. )
  175. })
  176. afterEach(function () {
  177. if (this.owner_client) {
  178. this.owner_client.disconnect()
  179. }
  180. if (this.user_a_client) {
  181. this.user_a_client.disconnect()
  182. }
  183. if (this.user_b_client) {
  184. this.user_b_client.disconnect()
  185. }
  186. })
  187. describe('event: userRemovedFromProject', function () {
  188. let removedUserId
  189. beforeEach(function (done) {
  190. /**
  191. * We remove user_a from the project
  192. */
  193. removedUserId = `${this.user_a_id}`
  194. rclient.publish(
  195. 'editor-events',
  196. JSON.stringify({
  197. room_id: this.project_id,
  198. message: 'userRemovedFromProject',
  199. payload: [removedUserId],
  200. })
  201. )
  202. setTimeout(done, 200)
  203. })
  204. it('should disconnect the removed user', function () {
  205. expect(this.user_a_client.socket.connected).to.equal(false)
  206. })
  207. it('should not disconnect the other users', function () {
  208. expect(this.owner_client.socket.connected).to.equal(true)
  209. expect(this.user_b_client.socket.connected).to.equal(true)
  210. })
  211. it('should send the event to the remaining connected clients', function () {
  212. expect(this.owner_updates).to.deep.equal([
  213. { userRemovedFromProject: removedUserId },
  214. ])
  215. expect(this.user_a_updates.length).to.equal(0)
  216. expect(this.user_b_updates).to.deep.equal([
  217. { userRemovedFromProject: removedUserId },
  218. ])
  219. })
  220. })
  221. })