GettingADocumentTests.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 sinon = require("sinon");
  9. const chai = require("chai");
  10. chai.should();
  11. const {
  12. expect
  13. } = chai;
  14. const MockWebApi = require("./helpers/MockWebApi");
  15. const DocUpdaterClient = require("./helpers/DocUpdaterClient");
  16. const DocUpdaterApp = require("./helpers/DocUpdaterApp");
  17. describe("Getting a document", function() {
  18. before(function(done) {
  19. this.lines = ["one", "two", "three"];
  20. this.version = 42;
  21. return DocUpdaterApp.ensureRunning(done);
  22. });
  23. describe("when the document is not loaded", function() {
  24. before(function(done) {
  25. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  26. sinon.spy(MockWebApi, "getDocument");
  27. MockWebApi.insertDoc(this.project_id, this.doc_id, {lines: this.lines, version: this.version});
  28. return DocUpdaterClient.getDoc(this.project_id, this.doc_id, (error, res, returnedDoc) => { this.returnedDoc = returnedDoc; return done(); });
  29. });
  30. after(() => MockWebApi.getDocument.restore());
  31. it("should load the document from the web API", function() {
  32. return MockWebApi.getDocument
  33. .calledWith(this.project_id, this.doc_id)
  34. .should.equal(true);
  35. });
  36. it("should return the document lines", function() {
  37. return this.returnedDoc.lines.should.deep.equal(this.lines);
  38. });
  39. return it("should return the document at its current version", function() {
  40. return this.returnedDoc.version.should.equal(this.version);
  41. });
  42. });
  43. describe("when the document is already loaded", function() {
  44. before(function(done) {
  45. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  46. MockWebApi.insertDoc(this.project_id, this.doc_id, {lines: this.lines, version: this.version});
  47. return DocUpdaterClient.preloadDoc(this.project_id, this.doc_id, error => {
  48. if (error != null) { throw error; }
  49. sinon.spy(MockWebApi, "getDocument");
  50. return DocUpdaterClient.getDoc(this.project_id, this.doc_id, (error, res, returnedDoc) => { this.returnedDoc = returnedDoc; return done(); });
  51. });
  52. });
  53. after(() => MockWebApi.getDocument.restore());
  54. it("should not load the document from the web API", () => MockWebApi.getDocument.called.should.equal(false));
  55. return it("should return the document lines", function() {
  56. return this.returnedDoc.lines.should.deep.equal(this.lines);
  57. });
  58. });
  59. describe("when the request asks for some recent ops", function() {
  60. before(function(done) {
  61. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  62. MockWebApi.insertDoc(this.project_id, this.doc_id, {
  63. lines: (this.lines = ["one", "two", "three"])
  64. });
  65. this.updates = __range__(0, 199, true).map((v) => ({
  66. doc_id: this.doc_id,
  67. op: [{i: v.toString(), p: 0}],
  68. v
  69. }));
  70. return DocUpdaterClient.sendUpdates(this.project_id, this.doc_id, this.updates, error => {
  71. if (error != null) { throw error; }
  72. sinon.spy(MockWebApi, "getDocument");
  73. return done();
  74. });
  75. });
  76. after(() => MockWebApi.getDocument.restore());
  77. describe("when the ops are loaded", function() {
  78. before(function(done) {
  79. return DocUpdaterClient.getDocAndRecentOps(this.project_id, this.doc_id, 190, (error, res, returnedDoc) => { this.returnedDoc = returnedDoc; return done(); });
  80. });
  81. return it("should return the recent ops", function() {
  82. this.returnedDoc.ops.length.should.equal(10);
  83. return Array.from(this.updates.slice(190, -1)).map((update, i) =>
  84. this.returnedDoc.ops[i].op.should.deep.equal(update.op));
  85. });
  86. });
  87. return describe("when the ops are not all loaded", function() {
  88. before(function(done) {
  89. // We only track 100 ops
  90. return DocUpdaterClient.getDocAndRecentOps(this.project_id, this.doc_id, 10, (error, res, returnedDoc) => { this.res = res; this.returnedDoc = returnedDoc; return done(); });
  91. });
  92. return it("should return UnprocessableEntity", function() {
  93. return this.res.statusCode.should.equal(422);
  94. });
  95. });
  96. });
  97. describe("when the document does not exist", function() {
  98. before(function(done) {
  99. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  100. return DocUpdaterClient.getDoc(this.project_id, this.doc_id, (error, res, doc) => {
  101. this.statusCode = res.statusCode;
  102. return done();
  103. });
  104. });
  105. return it("should return 404", function() {
  106. return this.statusCode.should.equal(404);
  107. });
  108. });
  109. describe("when the web api returns an error", function() {
  110. before(function(done) {
  111. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  112. sinon.stub(MockWebApi, "getDocument", function(project_id, doc_id, callback) {
  113. if (callback == null) { callback = function(error, doc) {}; }
  114. return callback(new Error("oops"));
  115. });
  116. return DocUpdaterClient.getDoc(this.project_id, this.doc_id, (error, res, doc) => {
  117. this.statusCode = res.statusCode;
  118. return done();
  119. });
  120. });
  121. after(() => MockWebApi.getDocument.restore());
  122. return it("should return 500", function() {
  123. return this.statusCode.should.equal(500);
  124. });
  125. });
  126. return describe("when the web api http request takes a long time", function() {
  127. before(function(done) {
  128. this.timeout = 10000;
  129. [this.project_id, this.doc_id] = Array.from([DocUpdaterClient.randomId(), DocUpdaterClient.randomId()]);
  130. sinon.stub(MockWebApi, "getDocument", function(project_id, doc_id, callback) {
  131. if (callback == null) { callback = function(error, doc) {}; }
  132. return setTimeout(callback, 30000);
  133. });
  134. return done();
  135. });
  136. after(() => MockWebApi.getDocument.restore());
  137. return it("should return quickly(ish)", function(done) {
  138. const start = Date.now();
  139. return DocUpdaterClient.getDoc(this.project_id, this.doc_id, (error, res, doc) => {
  140. res.statusCode.should.equal(500);
  141. const delta = Date.now() - start;
  142. expect(delta).to.be.below(20000);
  143. return done();
  144. });
  145. });
  146. });
  147. });
  148. function __range__(left, right, inclusive) {
  149. let range = [];
  150. let ascending = left < right;
  151. let end = !inclusive ? right : ascending ? right + 1 : right - 1;
  152. for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
  153. range.push(i);
  154. }
  155. return range;
  156. }