ProjectCRUDTests.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. const { expect } = require('chai')
  2. const User = require('./helpers/User').promises
  3. const { Project } = require('../../../app/src/models/Project')
  4. const { ObjectId } = require('mongodb-legacy')
  5. const cheerio = require('cheerio')
  6. const { Subscription } = require('../../../app/src/models/Subscription')
  7. const Features = require('../../../app/src/infrastructure/Features')
  8. describe('Project CRUD', function () {
  9. beforeEach(async function () {
  10. this.user = new User()
  11. await this.user.login()
  12. this.projectId = await this.user.createProject('example-project')
  13. })
  14. describe('project page', function () {
  15. const loadProject = async function (user, projectId) {
  16. const { response, body } = await user.doRequest(
  17. 'GET',
  18. `/project/${projectId}`
  19. )
  20. expect(response.statusCode).to.equal(200)
  21. return body
  22. }
  23. it('should cast refProviders to booleans', async function () {
  24. await this.user.mongoUpdate({
  25. $set: {
  26. refProviders: {
  27. mendeley: { encrypted: 'aaa' },
  28. zotero: { encrypted: 'bbb' },
  29. },
  30. },
  31. })
  32. const body = await loadProject(this.user, this.projectId)
  33. const dom = cheerio.load(body)
  34. const metaOlUser = dom('meta[name="ol-user"]')[0]
  35. const userData = JSON.parse(metaOlUser.attribs.content)
  36. expect(userData.refProviders.mendeley).to.equal(true)
  37. expect(userData.refProviders.zotero).to.equal(true)
  38. })
  39. it('should show UpgradePrompt for user without a subscription', async function () {
  40. const body = await loadProject(this.user, this.projectId)
  41. expect(body).to.include(
  42. Features.hasFeature('saas')
  43. ? // `content` means true in this context
  44. '<meta name="ol-showUpgradePrompt" data-type="boolean" content>'
  45. : '<meta name="ol-showUpgradePrompt" data-type="boolean">'
  46. )
  47. })
  48. it('should not show UpgradePrompt for user with a subscription', async function () {
  49. await Subscription.create({
  50. admin_id: this.user._id,
  51. manager_ids: [this.user._id],
  52. })
  53. const body = await loadProject(this.user, this.projectId)
  54. // having no `content` means false in this context
  55. expect(body).to.include(
  56. '<meta name="ol-showUpgradePrompt" data-type="boolean">'
  57. )
  58. })
  59. })
  60. describe("when project doesn't exist", function () {
  61. it('should return 404', async function () {
  62. const { response } = await this.user.doRequest(
  63. 'GET',
  64. '/project/aaaaaaaaaaaaaaaaaaaaaaaa'
  65. )
  66. expect(response.statusCode).to.equal(404)
  67. })
  68. })
  69. describe('when project has malformed id', function () {
  70. it('should return 404', async function () {
  71. const { response } = await this.user.doRequest('GET', '/project/blah')
  72. expect(response.statusCode).to.equal(404)
  73. })
  74. })
  75. describe('when trashing a project', function () {
  76. it('should mark the project as trashed for the user', async function () {
  77. const { response } = await this.user.doRequest(
  78. 'POST',
  79. `/project/${this.projectId}/trash`
  80. )
  81. expect(response.statusCode).to.equal(200)
  82. const trashedProject = await Project.findById(this.projectId).exec()
  83. expectObjectIdArrayEqual(trashedProject.trashed, [this.user._id])
  84. })
  85. it('does nothing if the user has already trashed the project', async function () {
  86. // Mark as trashed the first time
  87. await this.user.doRequest('POST', `/project/${this.projectId}/trash`)
  88. // And then a second time
  89. await this.user.doRequest('POST', `/project/${this.projectId}/trash`)
  90. const trashedProject = await Project.findById(this.projectId).exec()
  91. expectObjectIdArrayEqual(trashedProject.trashed, [this.user._id])
  92. })
  93. describe('with an array archived state', function () {
  94. it('should mark the project as not archived for the user', async function () {
  95. await Project.updateOne(
  96. { _id: this.projectId },
  97. { $set: { archived: [new ObjectId(this.user._id)] } }
  98. ).exec()
  99. const { response } = await this.user.doRequest(
  100. 'POST',
  101. `/project/${this.projectId}/trash`
  102. )
  103. expect(response.statusCode).to.equal(200)
  104. const trashedProject = await Project.findById(this.projectId).exec()
  105. expectObjectIdArrayEqual(trashedProject.archived, [])
  106. })
  107. })
  108. describe('with a legacy boolean state', function () {
  109. it('should mark the project as not archived for the user', async function () {
  110. await Project.updateOne(
  111. { _id: this.projectId },
  112. { $set: { archived: true } }
  113. ).exec()
  114. const { response } = await this.user.doRequest(
  115. 'POST',
  116. `/project/${this.projectId}/trash`
  117. )
  118. expect(response.statusCode).to.equal(200)
  119. const trashedProject = await Project.findById(this.projectId).exec()
  120. expectObjectIdArrayEqual(trashedProject.archived, [])
  121. })
  122. })
  123. })
  124. describe('when untrashing a project', function () {
  125. it('should mark the project as untrashed for the user', async function () {
  126. await Project.updateOne(
  127. { _id: this.projectId },
  128. { trashed: [new ObjectId(this.user._id)] }
  129. ).exec()
  130. const { response } = await this.user.doRequest(
  131. 'DELETE',
  132. `/project/${this.projectId}/trash`
  133. )
  134. expect(response.statusCode).to.equal(200)
  135. const trashedProject = await Project.findById(this.projectId).exec()
  136. expectObjectIdArrayEqual(trashedProject.trashed, [])
  137. })
  138. it('does nothing if the user has already untrashed the project', async function () {
  139. await Project.updateOne(
  140. { _id: this.projectId },
  141. { trashed: [new ObjectId(this.user._id)] }
  142. ).exec()
  143. // Mark as untrashed the first time
  144. await this.user.doRequest('DELETE', `/project/${this.projectId}/trash`)
  145. // And then a second time
  146. await this.user.doRequest('DELETE', `/project/${this.projectId}/trash`)
  147. const trashedProject = await Project.findById(this.projectId).exec()
  148. expectObjectIdArrayEqual(trashedProject.trashed, [])
  149. })
  150. it('sets trashed to an empty array if not set', async function () {
  151. await this.user.doRequest('DELETE', `/project/${this.projectId}/trash`)
  152. const trashedProject = await Project.findById(this.projectId).exec()
  153. expectObjectIdArrayEqual(trashedProject.trashed, [])
  154. })
  155. })
  156. })
  157. function expectObjectIdArrayEqual(objectIdArray, stringArray) {
  158. const stringifiedArray = objectIdArray.map(id => id.toString())
  159. expect(stringifiedArray).to.deep.equal(stringArray)
  160. }