ClientTrackingTests.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. * DS101: Remove unnecessary use of Array.from
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS207: Consider shorter variations of null checks
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. import { expect } from 'chai'
  14. import RealTimeClient from './helpers/RealTimeClient.js'
  15. import MockWebServer from './helpers/MockWebServer.js'
  16. import FixturesManager from './helpers/FixturesManager.js'
  17. import async from 'async'
  18. describe('clientTracking', function () {
  19. describe('when another logged in user joins a project', function () {
  20. before(function (done) {
  21. return async.series(
  22. [
  23. cb => {
  24. return FixturesManager.setUpProject(
  25. {
  26. privilegeLevel: 'owner',
  27. project: { name: 'Test Project' },
  28. },
  29. (error, { user_id: userId, project_id: projectId }) => {
  30. if (error) return done(error)
  31. this.user_id = userId
  32. this.project_id = projectId
  33. return cb()
  34. }
  35. )
  36. },
  37. cb => {
  38. return FixturesManager.setUpDoc(
  39. this.project_id,
  40. { lines: this.lines, version: this.version, ops: this.ops },
  41. (e, { doc_id: docId }) => {
  42. this.doc_id = docId
  43. return cb(e)
  44. }
  45. )
  46. },
  47. cb => {
  48. this.clientA = RealTimeClient.connect(this.project_id, cb)
  49. },
  50. cb => {
  51. RealTimeClient.countConnectedClients(
  52. this.project_id,
  53. (err, body) => {
  54. if (err) return cb(err)
  55. expect(body).to.deep.equal({ nConnectedClients: 1 })
  56. cb()
  57. }
  58. )
  59. },
  60. cb => {
  61. this.clientB = RealTimeClient.connect(this.project_id, cb)
  62. },
  63. ],
  64. done
  65. )
  66. })
  67. it('should record the initial state in getConnectedUsers', function (done) {
  68. this.clientA.emit('clientTracking.getConnectedUsers', (error, users) => {
  69. if (error) return done(error)
  70. for (const user of Array.from(users)) {
  71. if (user.client_id === this.clientB.publicId) {
  72. expect(user.cursorData).to.not.exist
  73. return done()
  74. }
  75. }
  76. throw new Error('other user was never found')
  77. })
  78. })
  79. it('should list both clients via HTTP', function (done) {
  80. RealTimeClient.countConnectedClients(this.project_id, (err, body) => {
  81. if (err) return done(err)
  82. expect(body).to.deep.equal({ nConnectedClients: 2 })
  83. done()
  84. })
  85. })
  86. })
  87. describe('when a client updates its cursor location', function () {
  88. before(function (done) {
  89. return async.series(
  90. [
  91. cb => {
  92. return FixturesManager.setUpProject(
  93. {
  94. privilegeLevel: 'owner',
  95. project: { name: 'Test Project' },
  96. },
  97. (error, { user_id: userId, project_id: projectId }) => {
  98. if (error) return done(error)
  99. this.user_id = userId
  100. this.project_id = projectId
  101. return cb()
  102. }
  103. )
  104. },
  105. cb => {
  106. return FixturesManager.setUpDoc(
  107. this.project_id,
  108. { lines: this.lines, version: this.version, ops: this.ops },
  109. (e, { doc_id: docId }) => {
  110. this.doc_id = docId
  111. return cb(e)
  112. }
  113. )
  114. },
  115. cb => {
  116. this.clientA = RealTimeClient.connect(this.project_id, cb)
  117. },
  118. cb => {
  119. this.clientB = RealTimeClient.connect(this.project_id, cb)
  120. },
  121. cb => {
  122. return this.clientA.emit('joinDoc', this.doc_id, cb)
  123. },
  124. cb => {
  125. this.updates = []
  126. this.clientB.on('clientTracking.clientUpdated', data => {
  127. return this.updates.push(data)
  128. })
  129. return this.clientA.emit(
  130. 'clientTracking.updatePosition',
  131. {
  132. row: (this.row = 42),
  133. column: (this.column = 36),
  134. doc_id: this.doc_id,
  135. },
  136. error => {
  137. if (error != null) {
  138. throw error
  139. }
  140. return setTimeout(cb, 300)
  141. }
  142. )
  143. }, // Give the message a chance to reach client B.
  144. ],
  145. done
  146. )
  147. })
  148. it('should tell other clients about the update', function () {
  149. return this.updates.should.deep.equal([
  150. {
  151. row: this.row,
  152. column: this.column,
  153. doc_id: this.doc_id,
  154. id: this.clientA.publicId,
  155. user_id: this.user_id,
  156. name: 'Joe Bloggs',
  157. },
  158. ])
  159. })
  160. return it('should record the update in getConnectedUsers', function (done) {
  161. return this.clientB.emit(
  162. 'clientTracking.getConnectedUsers',
  163. (error, users) => {
  164. if (error) return done(error)
  165. for (const user of Array.from(users)) {
  166. if (user.client_id === this.clientA.publicId) {
  167. expect(user.cursorData).to.deep.equal({
  168. row: this.row,
  169. column: this.column,
  170. doc_id: this.doc_id,
  171. })
  172. return done()
  173. }
  174. }
  175. throw new Error('user was never found')
  176. }
  177. )
  178. })
  179. })
  180. return describe('when an anonymous client updates its cursor location', function () {
  181. before(function (done) {
  182. return async.series(
  183. [
  184. cb => {
  185. return FixturesManager.setUpProject(
  186. {
  187. privilegeLevel: 'owner',
  188. project: { name: 'Test Project' },
  189. publicAccess: 'readAndWrite',
  190. },
  191. (
  192. error,
  193. { user_id: userId, project_id: projectId, anonymousAccessToken }
  194. ) => {
  195. if (error) return done(error)
  196. this.user_id = userId
  197. this.project_id = projectId
  198. this.anonymousAccessToken = anonymousAccessToken
  199. return cb()
  200. }
  201. )
  202. },
  203. cb => {
  204. return FixturesManager.setUpDoc(
  205. this.project_id,
  206. { lines: this.lines, version: this.version, ops: this.ops },
  207. (e, { doc_id: docId }) => {
  208. this.doc_id = docId
  209. return cb(e)
  210. }
  211. )
  212. },
  213. cb => {
  214. this.clientA = RealTimeClient.connect(this.project_id, cb)
  215. },
  216. cb => {
  217. RealTimeClient.setAnonSession(
  218. this.project_id,
  219. this.anonymousAccessToken,
  220. cb
  221. )
  222. },
  223. cb => {
  224. this.anonymous = RealTimeClient.connect(this.project_id, cb)
  225. },
  226. cb => {
  227. return this.anonymous.emit('joinDoc', this.doc_id, cb)
  228. },
  229. cb => {
  230. this.updates = []
  231. this.clientA.on('clientTracking.clientUpdated', data => {
  232. return this.updates.push(data)
  233. })
  234. return this.anonymous.emit(
  235. 'clientTracking.updatePosition',
  236. {
  237. row: (this.row = 42),
  238. column: (this.column = 36),
  239. doc_id: this.doc_id,
  240. },
  241. error => {
  242. if (error != null) {
  243. throw error
  244. }
  245. return setTimeout(cb, 300)
  246. }
  247. )
  248. }, // Give the message a chance to reach client B.
  249. ],
  250. done
  251. )
  252. })
  253. return it('should tell other clients about the update', function () {
  254. return this.updates.should.deep.equal([
  255. {
  256. row: this.row,
  257. column: this.column,
  258. doc_id: this.doc_id,
  259. id: this.anonymous.publicId,
  260. user_id: 'anonymous-user',
  261. name: '',
  262. },
  263. ])
  264. })
  265. })
  266. })