ClientTrackingTests.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * decaffeinate suggestions:
  3. * DS101: Remove unnecessary use of Array.from
  4. * DS102: Remove unnecessary code created because of implicit returns
  5. * DS207: Consider shorter variations of null checks
  6. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  7. */
  8. const chai = require("chai");
  9. const {
  10. expect
  11. } = chai;
  12. chai.should();
  13. const RealTimeClient = require("./helpers/RealTimeClient");
  14. const MockWebServer = require("./helpers/MockWebServer");
  15. const FixturesManager = require("./helpers/FixturesManager");
  16. const async = require("async");
  17. describe("clientTracking", function() {
  18. describe("when a client updates its cursor location", function() {
  19. before(function(done) {
  20. return async.series([
  21. cb => {
  22. return FixturesManager.setUpProject({
  23. privilegeLevel: "owner",
  24. project: { name: "Test Project" }
  25. }, (error, {user_id, project_id}) => { this.user_id = user_id; this.project_id = project_id; return cb(); });
  26. },
  27. cb => {
  28. return FixturesManager.setUpDoc(this.project_id, {lines: this.lines, version: this.version, ops: this.ops}, (e, {doc_id}) => {
  29. this.doc_id = doc_id;
  30. return cb(e);
  31. });
  32. },
  33. cb => {
  34. this.clientA = RealTimeClient.connect();
  35. return this.clientA.on("connectionAccepted", cb);
  36. },
  37. cb => {
  38. this.clientB = RealTimeClient.connect();
  39. return this.clientB.on("connectionAccepted", cb);
  40. },
  41. cb => {
  42. return this.clientA.emit("joinProject", {
  43. project_id: this.project_id
  44. }, cb);
  45. },
  46. cb => {
  47. return this.clientA.emit("joinDoc", this.doc_id, cb);
  48. },
  49. cb => {
  50. return this.clientB.emit("joinProject", {
  51. project_id: this.project_id
  52. }, cb);
  53. },
  54. cb => {
  55. this.updates = [];
  56. this.clientB.on("clientTracking.clientUpdated", data => {
  57. return this.updates.push(data);
  58. });
  59. return this.clientA.emit("clientTracking.updatePosition", {
  60. row: (this.row = 42),
  61. column: (this.column = 36),
  62. doc_id: this.doc_id
  63. }, function(error) {
  64. if (error != null) { throw error; }
  65. return setTimeout(cb, 300);
  66. });
  67. } // Give the message a chance to reach client B.
  68. ], done);
  69. });
  70. it("should tell other clients about the update", function() {
  71. return this.updates.should.deep.equal([
  72. {
  73. row: this.row,
  74. column: this.column,
  75. doc_id: this.doc_id,
  76. id: this.clientA.publicId,
  77. user_id: this.user_id,
  78. name: "Joe Bloggs"
  79. }
  80. ]);
  81. });
  82. return it("should record the update in getConnectedUsers", function(done) {
  83. return this.clientB.emit("clientTracking.getConnectedUsers", (error, users) => {
  84. for (let user of Array.from(users)) {
  85. if (user.client_id === this.clientA.publicId) {
  86. expect(user.cursorData).to.deep.equal({
  87. row: this.row,
  88. column: this.column,
  89. doc_id: this.doc_id
  90. });
  91. return done();
  92. }
  93. }
  94. throw new Error("user was never found");
  95. });
  96. });
  97. });
  98. return describe("when an anonymous client updates its cursor location", function() {
  99. before(function(done) {
  100. return async.series([
  101. cb => {
  102. return FixturesManager.setUpProject({
  103. privilegeLevel: "owner",
  104. project: { name: "Test Project" },
  105. publicAccess: "readAndWrite"
  106. }, (error, {user_id, project_id}) => { this.user_id = user_id; this.project_id = project_id; return cb(); });
  107. },
  108. cb => {
  109. return FixturesManager.setUpDoc(this.project_id, {lines: this.lines, version: this.version, ops: this.ops}, (e, {doc_id}) => {
  110. this.doc_id = doc_id;
  111. return cb(e);
  112. });
  113. },
  114. cb => {
  115. this.clientA = RealTimeClient.connect();
  116. return this.clientA.on("connectionAccepted", cb);
  117. },
  118. cb => {
  119. return this.clientA.emit("joinProject", {
  120. project_id: this.project_id
  121. }, cb);
  122. },
  123. cb => {
  124. return RealTimeClient.setSession({}, cb);
  125. },
  126. cb => {
  127. this.anonymous = RealTimeClient.connect();
  128. return this.anonymous.on("connectionAccepted", cb);
  129. },
  130. cb => {
  131. return this.anonymous.emit("joinProject", {
  132. project_id: this.project_id
  133. }, cb);
  134. },
  135. cb => {
  136. return this.anonymous.emit("joinDoc", this.doc_id, cb);
  137. },
  138. cb => {
  139. this.updates = [];
  140. this.clientA.on("clientTracking.clientUpdated", data => {
  141. return this.updates.push(data);
  142. });
  143. return this.anonymous.emit("clientTracking.updatePosition", {
  144. row: (this.row = 42),
  145. column: (this.column = 36),
  146. doc_id: this.doc_id
  147. }, function(error) {
  148. if (error != null) { throw error; }
  149. return setTimeout(cb, 300);
  150. });
  151. } // Give the message a chance to reach client B.
  152. ], done);
  153. });
  154. return it("should tell other clients about the update", function() {
  155. return this.updates.should.deep.equal([
  156. {
  157. row: this.row,
  158. column: this.column,
  159. doc_id: this.doc_id,
  160. id: this.anonymous.publicId,
  161. user_id: "anonymous-user",
  162. name: ""
  163. }
  164. ]);
  165. });
  166. });
  167. });