DocUpdateTests.mjs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import User from './helpers/User.mjs'
  2. import request from './helpers/request.js'
  3. import { expect } from 'chai'
  4. import settings from '@overleaf/settings'
  5. import mongodb from 'mongodb-legacy'
  6. const ObjectId = mongodb.ObjectId
  7. describe('DocUpdate', function () {
  8. beforeEach(function (done) {
  9. this.user = new User()
  10. this.projectName = 'wombat'
  11. this.user.ensureUserExists(() => {
  12. this.user.login(() => {
  13. this.user.createProject(this.projectName, (error, projectId) => {
  14. if (error) return done(error)
  15. this.projectId = projectId
  16. this.user.getProject(this.projectId, (error, project) => {
  17. if (error) return done(error)
  18. this.project = project
  19. this.user.createDocInProject(
  20. this.projectId,
  21. this.project.rootFolder[0]._id,
  22. 'potato',
  23. (error, docId) => {
  24. this.docId = docId
  25. done(error)
  26. }
  27. )
  28. })
  29. })
  30. })
  31. })
  32. })
  33. function writeContent(
  34. { projectId, docId, lines, version, ranges, lastUpdatedAt, lastUpdatedBy },
  35. callback
  36. ) {
  37. request(
  38. {
  39. method: 'POST',
  40. url: `/project/${projectId}/doc/${docId}`,
  41. auth: {
  42. user: settings.apis.web.user,
  43. pass: settings.apis.web.pass,
  44. sendImmediately: true,
  45. },
  46. json: { lines, version, ranges, lastUpdatedAt, lastUpdatedBy },
  47. },
  48. (error, res) => {
  49. if (error) return callback(error)
  50. if (res.statusCode !== 200)
  51. return callback(
  52. new Error(`non-success statusCode: ${res.statusCode}`)
  53. )
  54. callback()
  55. }
  56. )
  57. }
  58. function updateContent(options, callback) {
  59. writeContent(options, err => {
  60. if (err) return callback(err)
  61. options.lines.push('foo')
  62. options.version++
  63. writeContent(options, callback)
  64. })
  65. }
  66. function writeContentTwice(options, callback) {
  67. writeContent(options, err => {
  68. if (err) return callback(err)
  69. writeContent(options, callback)
  70. })
  71. }
  72. let writeOptions
  73. beforeEach(function () {
  74. writeOptions = {
  75. projectId: this.projectId,
  76. docId: this.docId,
  77. lines: ['a'],
  78. version: 1,
  79. ranges: {},
  80. lastUpdatedAt: new Date(),
  81. lastUpdatedBy: this.user.id,
  82. }
  83. })
  84. function shouldAcceptChanges() {
  85. it('should accept writes', function (done) {
  86. writeContent(writeOptions, done)
  87. })
  88. it('should accept updates', function (done) {
  89. updateContent(writeOptions, done)
  90. })
  91. it('should accept same write twice', function (done) {
  92. writeContentTwice(writeOptions, done)
  93. })
  94. }
  95. function shouldBlockChanges() {
  96. it('should block writes', function (done) {
  97. writeContent(writeOptions, err => {
  98. expect(err).to.exist
  99. expect(err.message).to.equal('non-success statusCode: 404')
  100. done()
  101. })
  102. })
  103. it('should block updates', function (done) {
  104. updateContent(writeOptions, err => {
  105. expect(err).to.exist
  106. expect(err.message).to.equal('non-success statusCode: 404')
  107. done()
  108. })
  109. })
  110. }
  111. describe('a regular doc', function () {
  112. shouldAcceptChanges()
  113. })
  114. describe('after deleting the doc', function () {
  115. beforeEach(function (done) {
  116. this.user.deleteItemInProject(this.projectId, 'doc', this.docId, done)
  117. })
  118. shouldAcceptChanges()
  119. })
  120. describe('unknown doc', function () {
  121. beforeEach(function () {
  122. writeOptions.docId = new ObjectId()
  123. })
  124. shouldBlockChanges()
  125. })
  126. describe('doc in another project', function () {
  127. beforeEach(function (done) {
  128. this.user.createProject('foo', (error, projectId) => {
  129. if (error) return done(error)
  130. writeOptions.projectId = projectId
  131. done()
  132. })
  133. })
  134. shouldBlockChanges()
  135. })
  136. })