UpdatingDocsTests.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  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 sinon = require('sinon')
  13. const { ObjectId } = require('mongodb-legacy')
  14. const DocstoreApp = require('./helpers/DocstoreApp')
  15. const DocstoreClient = require('./helpers/DocstoreClient')
  16. describe('Applying updates to a doc', function () {
  17. beforeEach(function (done) {
  18. this.project_id = new ObjectId()
  19. this.doc_id = new ObjectId()
  20. this.originalLines = ['original', 'lines']
  21. this.newLines = ['new', 'lines']
  22. this.originalRanges = {
  23. changes: [
  24. {
  25. id: new ObjectId().toString(),
  26. op: { i: 'foo', p: 3 },
  27. meta: {
  28. user_id: new ObjectId().toString(),
  29. ts: new Date().toString(),
  30. },
  31. },
  32. ],
  33. }
  34. this.newRanges = {
  35. changes: [
  36. {
  37. id: new ObjectId().toString(),
  38. op: { i: 'bar', p: 6 },
  39. meta: {
  40. user_id: new ObjectId().toString(),
  41. ts: new Date().toString(),
  42. },
  43. },
  44. ],
  45. }
  46. this.version = 42
  47. return DocstoreApp.ensureRunning(() => {
  48. return DocstoreClient.createDoc(
  49. this.project_id,
  50. this.doc_id,
  51. this.originalLines,
  52. this.version,
  53. this.originalRanges,
  54. error => {
  55. if (error != null) {
  56. throw error
  57. }
  58. return done()
  59. }
  60. )
  61. })
  62. })
  63. describe('when nothing has been updated', function () {
  64. beforeEach(function (done) {
  65. return DocstoreClient.updateDoc(
  66. this.project_id,
  67. this.doc_id,
  68. this.originalLines,
  69. this.version,
  70. this.originalRanges,
  71. (error, res, body) => {
  72. if (error) return done(error)
  73. this.body = body
  74. return done()
  75. }
  76. )
  77. })
  78. it('should return modified = false', function () {
  79. return this.body.modified.should.equal(false)
  80. })
  81. return it('should not update the doc in the API', function (done) {
  82. return DocstoreClient.getDoc(
  83. this.project_id,
  84. this.doc_id,
  85. {},
  86. (error, res, doc) => {
  87. if (error) return done(error)
  88. doc.lines.should.deep.equal(this.originalLines)
  89. doc.version.should.equal(this.version)
  90. doc.ranges.should.deep.equal(this.originalRanges)
  91. return done()
  92. }
  93. )
  94. })
  95. })
  96. describe('when the lines have changed', function () {
  97. beforeEach(function (done) {
  98. return DocstoreClient.updateDoc(
  99. this.project_id,
  100. this.doc_id,
  101. this.newLines,
  102. this.version,
  103. this.originalRanges,
  104. (error, res, body) => {
  105. if (error) return done(error)
  106. this.body = body
  107. return done()
  108. }
  109. )
  110. })
  111. it('should return modified = true', function () {
  112. return this.body.modified.should.equal(true)
  113. })
  114. it('should return the rev', function () {
  115. return this.body.rev.should.equal(2)
  116. })
  117. return it('should update the doc in the API', function (done) {
  118. return DocstoreClient.getDoc(
  119. this.project_id,
  120. this.doc_id,
  121. {},
  122. (error, res, doc) => {
  123. if (error) return done(error)
  124. doc.lines.should.deep.equal(this.newLines)
  125. doc.version.should.equal(this.version)
  126. doc.ranges.should.deep.equal(this.originalRanges)
  127. return done()
  128. }
  129. )
  130. })
  131. })
  132. describe('when the version has changed', function () {
  133. beforeEach(function (done) {
  134. return DocstoreClient.updateDoc(
  135. this.project_id,
  136. this.doc_id,
  137. this.originalLines,
  138. this.version + 1,
  139. this.originalRanges,
  140. (error, res, body) => {
  141. if (error) return done(error)
  142. this.body = body
  143. return done()
  144. }
  145. )
  146. })
  147. it('should return modified = true', function () {
  148. return this.body.modified.should.equal(true)
  149. })
  150. it('should return the rev', function () {
  151. return this.body.rev.should.equal(1)
  152. })
  153. return it('should update the doc in the API', function (done) {
  154. return DocstoreClient.getDoc(
  155. this.project_id,
  156. this.doc_id,
  157. {},
  158. (error, res, doc) => {
  159. if (error) return done(error)
  160. doc.lines.should.deep.equal(this.originalLines)
  161. doc.version.should.equal(this.version + 1)
  162. doc.ranges.should.deep.equal(this.originalRanges)
  163. return done()
  164. }
  165. )
  166. })
  167. })
  168. describe('when the version was decremented', function () {
  169. beforeEach(function (done) {
  170. DocstoreClient.updateDoc(
  171. this.project_id,
  172. this.doc_id,
  173. this.newLines,
  174. this.version - 1,
  175. this.newRanges,
  176. (error, res, body) => {
  177. if (error) return done(error)
  178. this.res = res
  179. this.body = body
  180. done()
  181. }
  182. )
  183. })
  184. it('should return 409', function () {
  185. this.res.statusCode.should.equal(409)
  186. })
  187. it('should not update the doc in the API', function (done) {
  188. DocstoreClient.getDoc(
  189. this.project_id,
  190. this.doc_id,
  191. {},
  192. (error, res, doc) => {
  193. if (error) return done(error)
  194. doc.lines.should.deep.equal(this.originalLines)
  195. doc.version.should.equal(this.version)
  196. doc.ranges.should.deep.equal(this.originalRanges)
  197. done()
  198. }
  199. )
  200. })
  201. })
  202. describe('when the ranges have changed', function () {
  203. beforeEach(function (done) {
  204. return DocstoreClient.updateDoc(
  205. this.project_id,
  206. this.doc_id,
  207. this.originalLines,
  208. this.version,
  209. this.newRanges,
  210. (error, res, body) => {
  211. if (error) return done(error)
  212. this.body = body
  213. return done()
  214. }
  215. )
  216. })
  217. it('should return modified = true', function () {
  218. return this.body.modified.should.equal(true)
  219. })
  220. it('should return the rev', function () {
  221. return this.body.rev.should.equal(2)
  222. })
  223. return it('should update the doc in the API', function (done) {
  224. return DocstoreClient.getDoc(
  225. this.project_id,
  226. this.doc_id,
  227. {},
  228. (error, res, doc) => {
  229. if (error) return done(error)
  230. doc.lines.should.deep.equal(this.originalLines)
  231. doc.version.should.equal(this.version)
  232. doc.ranges.should.deep.equal(this.newRanges)
  233. return done()
  234. }
  235. )
  236. })
  237. })
  238. describe('when the doc does not exist', function () {
  239. beforeEach(function (done) {
  240. this.missing_doc_id = new ObjectId()
  241. return DocstoreClient.updateDoc(
  242. this.project_id,
  243. this.missing_doc_id,
  244. this.originalLines,
  245. 0,
  246. this.originalRanges,
  247. (error, res, body) => {
  248. if (error) return done(error)
  249. this.res = res
  250. this.body = body
  251. return done()
  252. }
  253. )
  254. })
  255. it('should create the doc', function () {
  256. return this.body.rev.should.equal(1)
  257. })
  258. return it('should be retreivable', function (done) {
  259. return DocstoreClient.getDoc(
  260. this.project_id,
  261. this.missing_doc_id,
  262. {},
  263. (error, res, doc) => {
  264. if (error) return done(error)
  265. doc.lines.should.deep.equal(this.originalLines)
  266. doc.version.should.equal(0)
  267. doc.ranges.should.deep.equal(this.originalRanges)
  268. return done()
  269. }
  270. )
  271. })
  272. })
  273. describe('when malformed doc lines are provided', function () {
  274. describe('when the lines are not an array', function () {
  275. beforeEach(function (done) {
  276. return DocstoreClient.updateDoc(
  277. this.project_id,
  278. this.doc_id,
  279. { foo: 'bar' },
  280. this.version,
  281. this.originalRanges,
  282. (error, res, body) => {
  283. if (error) return done(error)
  284. this.res = res
  285. this.body = body
  286. return done()
  287. }
  288. )
  289. })
  290. it('should return 400', function () {
  291. return this.res.statusCode.should.equal(400)
  292. })
  293. return it('should not update the doc in the API', function (done) {
  294. return DocstoreClient.getDoc(
  295. this.project_id,
  296. this.doc_id,
  297. {},
  298. (error, res, doc) => {
  299. if (error) return done(error)
  300. doc.lines.should.deep.equal(this.originalLines)
  301. return done()
  302. }
  303. )
  304. })
  305. })
  306. return describe('when the lines are not present', function () {
  307. beforeEach(function (done) {
  308. return DocstoreClient.updateDoc(
  309. this.project_id,
  310. this.doc_id,
  311. null,
  312. this.version,
  313. this.originalRanges,
  314. (error, res, body) => {
  315. if (error) return done(error)
  316. this.res = res
  317. this.body = body
  318. return done()
  319. }
  320. )
  321. })
  322. it('should return 400', function () {
  323. return this.res.statusCode.should.equal(400)
  324. })
  325. return it('should not update the doc in the API', function (done) {
  326. return DocstoreClient.getDoc(
  327. this.project_id,
  328. this.doc_id,
  329. {},
  330. (error, res, doc) => {
  331. if (error) return done(error)
  332. doc.lines.should.deep.equal(this.originalLines)
  333. return done()
  334. }
  335. )
  336. })
  337. })
  338. })
  339. describe('when no version is provided', function () {
  340. beforeEach(function (done) {
  341. return DocstoreClient.updateDoc(
  342. this.project_id,
  343. this.doc_id,
  344. this.originalLines,
  345. null,
  346. this.originalRanges,
  347. (error, res, body) => {
  348. if (error) return done(error)
  349. this.res = res
  350. this.body = body
  351. return done()
  352. }
  353. )
  354. })
  355. it('should return 400', function () {
  356. return this.res.statusCode.should.equal(400)
  357. })
  358. return it('should not update the doc in the API', function (done) {
  359. return DocstoreClient.getDoc(
  360. this.project_id,
  361. this.doc_id,
  362. {},
  363. (error, res, doc) => {
  364. if (error) return done(error)
  365. doc.lines.should.deep.equal(this.originalLines)
  366. doc.version.should.equal(this.version)
  367. return done()
  368. }
  369. )
  370. })
  371. })
  372. describe('when the content is large', function () {
  373. beforeEach(function (done) {
  374. const line = new Array(1025).join('x') // 1kb
  375. this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1mb
  376. return DocstoreClient.updateDoc(
  377. this.project_id,
  378. this.doc_id,
  379. this.largeLines,
  380. this.version,
  381. this.originalRanges,
  382. (error, res, body) => {
  383. if (error) return done(error)
  384. this.body = body
  385. return done()
  386. }
  387. )
  388. })
  389. it('should return modified = true', function () {
  390. return this.body.modified.should.equal(true)
  391. })
  392. return it('should update the doc in the API', function (done) {
  393. return DocstoreClient.getDoc(
  394. this.project_id,
  395. this.doc_id,
  396. {},
  397. (error, res, doc) => {
  398. if (error) return done(error)
  399. doc.lines.should.deep.equal(this.largeLines)
  400. return done()
  401. }
  402. )
  403. })
  404. })
  405. describe('when there is a large json payload', function () {
  406. beforeEach(function (done) {
  407. const line = new Array(1025).join('x') // 1kb
  408. this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb
  409. this.originalRanges.padding = Array.apply(null, Array(2049)).map(
  410. () => line
  411. ) // 2mb + 1kb
  412. return DocstoreClient.updateDoc(
  413. this.project_id,
  414. this.doc_id,
  415. this.largeLines,
  416. this.version,
  417. this.originalRanges,
  418. (error, res, body) => {
  419. if (error) return done(error)
  420. this.res = res
  421. this.body = body
  422. return done()
  423. }
  424. )
  425. })
  426. it('should return modified = true', function () {
  427. return this.body.modified.should.equal(true)
  428. })
  429. return it('should update the doc in the API', function (done) {
  430. return DocstoreClient.getDoc(
  431. this.project_id,
  432. this.doc_id,
  433. {},
  434. (error, res, doc) => {
  435. if (error) return done(error)
  436. doc.lines.should.deep.equal(this.largeLines)
  437. return done()
  438. }
  439. )
  440. })
  441. })
  442. describe('when the document body is too large', function () {
  443. beforeEach(function (done) {
  444. const line = new Array(1025).join('x') // 1kb
  445. this.largeLines = Array.apply(null, Array(2049)).map(() => line) // 2mb + 1kb
  446. return DocstoreClient.updateDoc(
  447. this.project_id,
  448. this.doc_id,
  449. this.largeLines,
  450. this.version,
  451. this.originalRanges,
  452. (error, res, body) => {
  453. if (error) return done(error)
  454. this.res = res
  455. this.body = body
  456. return done()
  457. }
  458. )
  459. })
  460. it('should return 413', function () {
  461. return this.res.statusCode.should.equal(413)
  462. })
  463. it('should report body too large', function () {
  464. return this.res.body.should.equal('document body too large')
  465. })
  466. return it('should not update the doc in the API', function (done) {
  467. return DocstoreClient.getDoc(
  468. this.project_id,
  469. this.doc_id,
  470. {},
  471. (error, res, doc) => {
  472. if (error) return done(error)
  473. doc.lines.should.deep.equal(this.originalLines)
  474. return done()
  475. }
  476. )
  477. })
  478. })
  479. return describe('when the json payload is too large', function () {
  480. beforeEach(function (done) {
  481. const line = new Array(1025).join('x') // 1kb
  482. this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb
  483. this.originalRanges.padding = Array.apply(null, Array(6144)).map(
  484. () => line
  485. ) // 6mb
  486. return DocstoreClient.updateDoc(
  487. this.project_id,
  488. this.doc_id,
  489. this.largeLines,
  490. this.version,
  491. this.originalRanges,
  492. (error, res, body) => {
  493. if (error) return done(error)
  494. this.res = res
  495. this.body = body
  496. return done()
  497. }
  498. )
  499. })
  500. return it('should not update the doc in the API', function (done) {
  501. return DocstoreClient.getDoc(
  502. this.project_id,
  503. this.doc_id,
  504. {},
  505. (error, res, doc) => {
  506. if (error) return done(error)
  507. doc.lines.should.deep.equal(this.originalLines)
  508. return done()
  509. }
  510. )
  511. })
  512. })
  513. })