GettingADocumentTests.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /* eslint-disable
  2. camelcase,
  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. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const MockWebApi = require('./helpers/MockWebApi')
  16. const DocUpdaterClient = require('./helpers/DocUpdaterClient')
  17. const DocUpdaterApp = require('./helpers/DocUpdaterApp')
  18. describe('Getting a document', function () {
  19. before(function (done) {
  20. this.lines = ['one', 'two', 'three']
  21. this.version = 42
  22. return DocUpdaterApp.ensureRunning(done)
  23. })
  24. describe('when the document is not loaded', function () {
  25. before(function (done) {
  26. ;[this.project_id, this.doc_id] = Array.from([
  27. DocUpdaterClient.randomId(),
  28. DocUpdaterClient.randomId(),
  29. ])
  30. sinon.spy(MockWebApi, 'getDocument')
  31. MockWebApi.insertDoc(this.project_id, this.doc_id, {
  32. lines: this.lines,
  33. version: this.version,
  34. })
  35. return DocUpdaterClient.getDoc(
  36. this.project_id,
  37. this.doc_id,
  38. (error, res, returnedDoc) => {
  39. if (error) return done(error)
  40. this.returnedDoc = returnedDoc
  41. return done()
  42. }
  43. )
  44. })
  45. after(function () {
  46. return MockWebApi.getDocument.restore()
  47. })
  48. it('should load the document from the web API', function () {
  49. return MockWebApi.getDocument
  50. .calledWith(this.project_id, this.doc_id)
  51. .should.equal(true)
  52. })
  53. it('should return the document lines', function () {
  54. return this.returnedDoc.lines.should.deep.equal(this.lines)
  55. })
  56. return it('should return the document at its current version', function () {
  57. return this.returnedDoc.version.should.equal(this.version)
  58. })
  59. })
  60. describe('when the document is already loaded', function () {
  61. before(function (done) {
  62. ;[this.project_id, this.doc_id] = Array.from([
  63. DocUpdaterClient.randomId(),
  64. DocUpdaterClient.randomId(),
  65. ])
  66. MockWebApi.insertDoc(this.project_id, this.doc_id, {
  67. lines: this.lines,
  68. version: this.version,
  69. })
  70. return DocUpdaterClient.preloadDoc(
  71. this.project_id,
  72. this.doc_id,
  73. error => {
  74. if (error != null) {
  75. throw error
  76. }
  77. sinon.spy(MockWebApi, 'getDocument')
  78. return DocUpdaterClient.getDoc(
  79. this.project_id,
  80. this.doc_id,
  81. (error, res, returnedDoc) => {
  82. if (error) return done(error)
  83. this.returnedDoc = returnedDoc
  84. return done()
  85. }
  86. )
  87. }
  88. )
  89. })
  90. after(function () {
  91. return MockWebApi.getDocument.restore()
  92. })
  93. it('should not load the document from the web API', function () {
  94. return MockWebApi.getDocument.called.should.equal(false)
  95. })
  96. return it('should return the document lines', function () {
  97. return this.returnedDoc.lines.should.deep.equal(this.lines)
  98. })
  99. })
  100. describe('when the request asks for some recent ops', function () {
  101. before(function (done) {
  102. ;[this.project_id, this.doc_id] = Array.from([
  103. DocUpdaterClient.randomId(),
  104. DocUpdaterClient.randomId(),
  105. ])
  106. MockWebApi.insertDoc(this.project_id, this.doc_id, {
  107. lines: (this.lines = ['one', 'two', 'three']),
  108. })
  109. this.updates = __range__(0, 199, true).map(v => ({
  110. doc_id: this.doc_id,
  111. op: [{ i: v.toString(), p: 0 }],
  112. v,
  113. }))
  114. return DocUpdaterClient.sendUpdates(
  115. this.project_id,
  116. this.doc_id,
  117. this.updates,
  118. error => {
  119. if (error != null) {
  120. throw error
  121. }
  122. sinon.spy(MockWebApi, 'getDocument')
  123. return done()
  124. }
  125. )
  126. })
  127. after(function () {
  128. return MockWebApi.getDocument.restore()
  129. })
  130. describe('when the ops are loaded', function () {
  131. before(function (done) {
  132. return DocUpdaterClient.getDocAndRecentOps(
  133. this.project_id,
  134. this.doc_id,
  135. 190,
  136. (error, res, returnedDoc) => {
  137. if (error) return done(error)
  138. this.returnedDoc = returnedDoc
  139. return done()
  140. }
  141. )
  142. })
  143. return it('should return the recent ops', function () {
  144. this.returnedDoc.ops.length.should.equal(10)
  145. return Array.from(this.updates.slice(190, -1)).map((update, i) =>
  146. this.returnedDoc.ops[i].op.should.deep.equal(update.op)
  147. )
  148. })
  149. })
  150. return describe('when the ops are not all loaded', function () {
  151. before(function (done) {
  152. // We only track 100 ops
  153. return DocUpdaterClient.getDocAndRecentOps(
  154. this.project_id,
  155. this.doc_id,
  156. 10,
  157. (error, res, returnedDoc) => {
  158. if (error) return done(error)
  159. this.res = res
  160. this.returnedDoc = returnedDoc
  161. return done()
  162. }
  163. )
  164. })
  165. return it('should return UnprocessableEntity', function () {
  166. return this.res.statusCode.should.equal(422)
  167. })
  168. })
  169. })
  170. describe('when the document does not exist', function () {
  171. before(function (done) {
  172. ;[this.project_id, this.doc_id] = Array.from([
  173. DocUpdaterClient.randomId(),
  174. DocUpdaterClient.randomId(),
  175. ])
  176. return DocUpdaterClient.getDoc(
  177. this.project_id,
  178. this.doc_id,
  179. (error, res, doc) => {
  180. if (error) return done(error)
  181. this.statusCode = res.statusCode
  182. return done()
  183. }
  184. )
  185. })
  186. return it('should return 404', function () {
  187. return this.statusCode.should.equal(404)
  188. })
  189. })
  190. describe('when the web api returns an error', function () {
  191. before(function (done) {
  192. ;[this.project_id, this.doc_id] = Array.from([
  193. DocUpdaterClient.randomId(),
  194. DocUpdaterClient.randomId(),
  195. ])
  196. sinon
  197. .stub(MockWebApi, 'getDocument')
  198. .callsFake((project_id, doc_id, callback) => {
  199. if (callback == null) {
  200. callback = function () {}
  201. }
  202. return callback(new Error('oops'))
  203. })
  204. return DocUpdaterClient.getDoc(
  205. this.project_id,
  206. this.doc_id,
  207. (error, res, doc) => {
  208. if (error) return done(error)
  209. this.statusCode = res.statusCode
  210. return done()
  211. }
  212. )
  213. })
  214. after(function () {
  215. return MockWebApi.getDocument.restore()
  216. })
  217. return it('should return 500', function () {
  218. return this.statusCode.should.equal(500)
  219. })
  220. })
  221. return describe('when the web api http request takes a long time', function () {
  222. before(function (done) {
  223. this.timeout = 10000
  224. ;[this.project_id, this.doc_id] = Array.from([
  225. DocUpdaterClient.randomId(),
  226. DocUpdaterClient.randomId(),
  227. ])
  228. sinon
  229. .stub(MockWebApi, 'getDocument')
  230. .callsFake((project_id, doc_id, callback) => {
  231. if (callback == null) {
  232. callback = function () {}
  233. }
  234. return setTimeout(callback, 30000)
  235. })
  236. return done()
  237. })
  238. after(function () {
  239. return MockWebApi.getDocument.restore()
  240. })
  241. return it('should return quickly(ish)', function (done) {
  242. const start = Date.now()
  243. return DocUpdaterClient.getDoc(
  244. this.project_id,
  245. this.doc_id,
  246. (error, res, doc) => {
  247. if (error) return done(error)
  248. res.statusCode.should.equal(500)
  249. const delta = Date.now() - start
  250. expect(delta).to.be.below(20000)
  251. return done()
  252. }
  253. )
  254. })
  255. })
  256. })
  257. function __range__(left, right, inclusive) {
  258. const range = []
  259. const ascending = left < right
  260. const end = !inclusive ? right : ascending ? right + 1 : right - 1
  261. for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
  262. range.push(i)
  263. }
  264. return range
  265. }