InactiveProjectManager.test.mjs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { vi, expect } from 'vitest'
  2. import sinon from 'sinon'
  3. import mongodb, { ReadPreference } from 'mongodb-legacy'
  4. const { ObjectId } = mongodb
  5. const modulePath =
  6. '../../../../app/src/Features/InactiveData/InactiveProjectManager'
  7. describe('InactiveProjectManager', function () {
  8. beforeEach(async function (ctx) {
  9. ctx.settings = {}
  10. ctx.DocstoreManager = {
  11. promises: {
  12. unarchiveProject: sinon.stub(),
  13. archiveProject: sinon.stub(),
  14. },
  15. }
  16. ctx.DocumentUpdaterHandler = {
  17. promises: {
  18. flushProjectToMongoAndDelete: sinon.stub(),
  19. },
  20. }
  21. ctx.ProjectUpdateHandler = {
  22. promises: {
  23. markAsActive: sinon.stub(),
  24. markAsInactive: sinon.stub(),
  25. },
  26. }
  27. ctx.ProjectGetter = { promises: { getProject: sinon.stub() } }
  28. ctx.Modules = { promises: { hooks: { fire: sinon.stub() } } }
  29. vi.doMock('mongodb-legacy', () => ({
  30. default: { ObjectId },
  31. }))
  32. vi.doMock('@overleaf/settings', () => ({
  33. default: ctx.settings,
  34. }))
  35. vi.doMock('../../../../app/src/Features/Docstore/DocstoreManager', () => ({
  36. default: ctx.DocstoreManager,
  37. }))
  38. vi.doMock(
  39. '../../../../app/src/Features/DocumentUpdater/DocumentUpdaterHandler',
  40. () => ({
  41. default: ctx.DocumentUpdaterHandler,
  42. })
  43. )
  44. vi.doMock(
  45. '../../../../app/src/Features/Project/ProjectUpdateHandler',
  46. () => ({
  47. default: ctx.ProjectUpdateHandler,
  48. })
  49. )
  50. vi.doMock('../../../../app/src/models/Project', () => ({}))
  51. vi.doMock('../../../../app/src/infrastructure/Modules', () => ({
  52. default: ctx.Modules,
  53. }))
  54. vi.doMock('../../../../app/src/infrastructure/mongodb', () => ({
  55. default: {
  56. ObjectId,
  57. READ_PREFERENCE_SECONDARY: ReadPreference.secondaryPreferred.mode,
  58. },
  59. }))
  60. ctx.InactiveProjectManager = (await import(modulePath)).default
  61. ctx.project_id = '1234'
  62. })
  63. describe('reactivateProjectIfRequired', function () {
  64. beforeEach(function (ctx) {
  65. ctx.project = { _id: ctx.project_id, active: false }
  66. ctx.ProjectUpdateHandler.promises.markAsActive.resolves()
  67. })
  68. it('should call unarchiveProject', async function (ctx) {
  69. ctx.DocstoreManager.promises.unarchiveProject.resolves()
  70. await ctx.InactiveProjectManager.promises.reactivateProjectIfRequired(
  71. ctx.project
  72. )
  73. ctx.DocstoreManager.promises.unarchiveProject
  74. .calledWith(ctx.project_id)
  75. .should.equal(true)
  76. ctx.ProjectUpdateHandler.promises.markAsActive
  77. .calledWith(ctx.project_id)
  78. .should.equal(true)
  79. })
  80. it('should not mark project as active if error with unarchiving', async function (ctx) {
  81. ctx.DocstoreManager.promises.unarchiveProject.rejects()
  82. await expect(
  83. ctx.InactiveProjectManager.promises.reactivateProjectIfRequired(
  84. ctx.project
  85. )
  86. ).to.be.rejected
  87. ctx.DocstoreManager.promises.unarchiveProject
  88. .calledWith(ctx.project_id)
  89. .should.equal(true)
  90. ctx.ProjectUpdateHandler.promises.markAsActive
  91. .calledWith(ctx.project_id)
  92. .should.equal(false)
  93. })
  94. it('should not call unarchiveProject if it is active', async function (ctx) {
  95. ctx.project.active = true
  96. ctx.DocstoreManager.promises.unarchiveProject.resolves()
  97. await ctx.InactiveProjectManager.promises.reactivateProjectIfRequired(
  98. ctx.project
  99. )
  100. ctx.DocstoreManager.promises.unarchiveProject
  101. .calledWith(ctx.project_id)
  102. .should.equal(false)
  103. ctx.ProjectUpdateHandler.promises.markAsActive
  104. .calledWith(ctx.project_id)
  105. .should.equal(false)
  106. })
  107. })
  108. describe('deactivateProject', function () {
  109. it('should call archiveProject and markAsInactive after flushing', async function (ctx) {
  110. ctx.DocstoreManager.promises.archiveProject.resolves()
  111. ctx.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete.resolves()
  112. ctx.ProjectUpdateHandler.promises.markAsInactive.resolves()
  113. ctx.Modules.promises.hooks.fire.resolves()
  114. await ctx.InactiveProjectManager.promises.deactivateProject(
  115. ctx.project_id
  116. )
  117. ctx.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete
  118. .calledWith(ctx.project_id)
  119. .should.equal(true)
  120. ctx.Modules.promises.hooks.fire
  121. .calledWith('deactivateProject', ctx.project_id)
  122. .should.equal(true)
  123. ctx.DocstoreManager.promises.archiveProject
  124. .calledWith(ctx.project_id)
  125. .should.equal(true)
  126. ctx.ProjectUpdateHandler.promises.markAsInactive
  127. .calledWith(ctx.project_id)
  128. .should.equal(true)
  129. })
  130. it('should not call markAsInactive if there was a problem archiving in docstore', async function (ctx) {
  131. ctx.DocstoreManager.promises.archiveProject.rejects()
  132. ctx.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete.resolves()
  133. ctx.ProjectUpdateHandler.promises.markAsInactive.resolves()
  134. ctx.Modules.promises.hooks.fire.resolves()
  135. await expect(
  136. ctx.InactiveProjectManager.promises.deactivateProject(ctx.project_id)
  137. ).to.be.rejected
  138. ctx.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete
  139. .calledWith(ctx.project_id)
  140. .should.equal(true)
  141. ctx.DocstoreManager.promises.archiveProject
  142. .calledWith(ctx.project_id)
  143. .should.equal(true)
  144. ctx.ProjectUpdateHandler.promises.markAsInactive
  145. .calledWith(ctx.project_id)
  146. .should.equal(false)
  147. })
  148. })
  149. })