DocUpdateTests.js 3.8 KB

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