DeletionTests.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. const User = require('./helpers/User')
  2. const request = require('./helpers/request')
  3. const async = require('async')
  4. const { expect } = require('chai')
  5. const settings = require('settings-sharelatex')
  6. const { db, ObjectId } = require('../../../app/src/infrastructure/mongojs')
  7. const { Subscription } = require('../../../app/src/models/Subscription')
  8. const SubscriptionViewModelBuilder = require('../../../app/src/Features/Subscription/SubscriptionViewModelBuilder')
  9. const MockDocstoreApi = require('./helpers/MockDocstoreApi')
  10. require('./helpers/MockTagsApi')
  11. require('./helpers/MockV1Api')
  12. describe('Deleting a user', function() {
  13. beforeEach(function(done) {
  14. this.user = new User()
  15. async.series(
  16. [
  17. this.user.ensureUserExists.bind(this.user),
  18. this.user.login.bind(this.user),
  19. this.user.activateSudoMode.bind(this.user)
  20. ],
  21. done
  22. )
  23. })
  24. it('Should remove the user from active users', function(done) {
  25. this.user.get((error, user) => {
  26. expect(error).not.to.exist
  27. expect(user).to.exist
  28. this.user.deleteUser(error => {
  29. expect(error).not.to.exist
  30. this.user.get((error, user) => {
  31. expect(error).not.to.exist
  32. expect(user).not.to.exist
  33. done()
  34. })
  35. })
  36. })
  37. })
  38. it('Should create a soft-deleted user', function(done) {
  39. this.user.get((error, user) => {
  40. expect(error).not.to.exist
  41. this.user.deleteUser(error => {
  42. expect(error).not.to.exist
  43. db.deletedUsers.findOne(
  44. { 'user._id': user._id },
  45. (error, deletedUser) => {
  46. expect(error).not.to.exist
  47. expect(deletedUser).to.exist
  48. // it should set the 'deleterData' correctly
  49. expect(deletedUser.deleterData.deleterId.toString()).to.equal(
  50. user._id.toString()
  51. )
  52. expect(deletedUser.deleterData.deletedUserId.toString()).to.equal(
  53. user._id.toString()
  54. )
  55. expect(deletedUser.deleterData.deletedUserReferralId).to.equal(
  56. user.referal_id
  57. )
  58. // it should set the 'user' correctly
  59. expect(deletedUser.user._id.toString()).to.equal(
  60. user._id.toString()
  61. )
  62. expect(deletedUser.user.email).to.equal(user.email)
  63. done()
  64. }
  65. )
  66. })
  67. })
  68. })
  69. it('Should fail if the user has a subscription', function(done) {
  70. Subscription.create(
  71. {
  72. admin_id: this.user._id,
  73. manager_ids: [this.user._id],
  74. planCode: 'collaborator'
  75. },
  76. error => {
  77. expect(error).not.to.exist
  78. SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel(
  79. this.user,
  80. error => {
  81. expect(error).not.to.exist
  82. this.user.deleteUser(error => {
  83. expect(error).to.exist
  84. done()
  85. })
  86. }
  87. )
  88. }
  89. )
  90. })
  91. it("Should delete the user's projects", function(done) {
  92. this.user.createProject('wombat', (error, projectId) => {
  93. expect(error).not.to.exist
  94. this.user.getProject(projectId, (error, project) => {
  95. expect(error).not.to.exist
  96. expect(project).to.exist
  97. this.user.deleteUser(error => {
  98. expect(error).not.to.exist
  99. this.user.getProject(projectId, (error, project) => {
  100. expect(error).not.to.exist
  101. expect(project).not.to.exist
  102. done()
  103. })
  104. })
  105. })
  106. })
  107. })
  108. describe('when scrubbing the user', function() {
  109. beforeEach(function(done) {
  110. this.user.get((error, user) => {
  111. if (error) {
  112. throw error
  113. }
  114. this.userId = user._id
  115. this.user.deleteUser(done)
  116. })
  117. })
  118. it('Should remove the user data from mongo', function(done) {
  119. db.deletedUsers.findOne(
  120. { 'deleterData.deletedUserId': this.userId },
  121. (error, deletedUser) => {
  122. expect(error).not.to.exist
  123. expect(deletedUser).to.exist
  124. expect(deletedUser.deleterData.deleterIpAddress).to.exist
  125. expect(deletedUser.user).to.exist
  126. request.post(
  127. `/internal/users/${this.userId}/expire`,
  128. {
  129. auth: {
  130. user: settings.apis.web.user,
  131. pass: settings.apis.web.pass,
  132. sendImmediately: true
  133. }
  134. },
  135. (error, res) => {
  136. expect(error).not.to.exist
  137. expect(res.statusCode).to.equal(204)
  138. db.deletedUsers.findOne(
  139. { 'deleterData.deletedUserId': this.userId },
  140. (error, deletedUser) => {
  141. expect(error).not.to.exist
  142. expect(deletedUser).to.exist
  143. expect(deletedUser.deleterData.deleterIpAddress).not.to.exist
  144. expect(deletedUser.user).not.to.exist
  145. done()
  146. }
  147. )
  148. }
  149. )
  150. }
  151. )
  152. })
  153. })
  154. })
  155. describe('Deleting a project', function() {
  156. beforeEach(function(done) {
  157. this.user = new User()
  158. this.projectName = 'wombat'
  159. this.user.ensureUserExists(() => {
  160. this.user.login(() => {
  161. this.user.createProject(this.projectName, (_e, projectId) => {
  162. this.projectId = projectId
  163. done()
  164. })
  165. })
  166. })
  167. })
  168. it('Should remove the project from active projects', function(done) {
  169. this.user.getProject(this.projectId, (error, project) => {
  170. expect(error).not.to.exist
  171. expect(project).to.exist
  172. this.user.deleteProject(this.projectId, error => {
  173. expect(error).not.to.exist
  174. this.user.getProject(this.projectId, (error, project) => {
  175. expect(error).not.to.exist
  176. expect(project).not.to.exist
  177. done()
  178. })
  179. })
  180. })
  181. })
  182. it('Should create a soft-deleted project', function(done) {
  183. this.user.getProject(this.projectId, (error, project) => {
  184. expect(error).not.to.exist
  185. this.user.get((error, user) => {
  186. expect(error).not.to.exist
  187. this.user.deleteProject(this.projectId, error => {
  188. expect(error).not.to.exist
  189. db.deletedProjects.findOne(
  190. { 'deleterData.deletedProjectId': project._id },
  191. (error, deletedProject) => {
  192. expect(error).not.to.exist
  193. expect(deletedProject).to.exist
  194. // it should set the 'deleterData' correctly
  195. expect(deletedProject.deleterData.deleterId.toString()).to.equal(
  196. user._id.toString()
  197. )
  198. expect(
  199. deletedProject.deleterData.deletedProjectId.toString()
  200. ).to.equal(project._id.toString())
  201. expect(
  202. deletedProject.deleterData.deletedProjectOwnerId.toString()
  203. ).to.equal(user._id.toString())
  204. // it should set the 'user' correctly
  205. expect(deletedProject.project._id.toString()).to.equal(
  206. project._id.toString()
  207. )
  208. expect(deletedProject.project.name).to.equal(this.projectName)
  209. done()
  210. }
  211. )
  212. })
  213. })
  214. })
  215. })
  216. describe('When the project has docs', function() {
  217. beforeEach(function(done) {
  218. this.user.getProject(this.projectId, (error, project) => {
  219. if (error) {
  220. throw error
  221. }
  222. this.user.createDocInProject(
  223. this.projectId,
  224. project.rootFolder[0]._id,
  225. 'potato',
  226. (error, docId) => {
  227. if (error) {
  228. throw error
  229. }
  230. this.docId = docId
  231. done()
  232. }
  233. )
  234. })
  235. })
  236. it('should mark the docs as deleted', function(done) {
  237. let doc =
  238. MockDocstoreApi.docs[this.projectId.toString()][this.docId.toString()]
  239. expect(doc).to.exist
  240. expect(doc.deleted).to.be.falsey
  241. this.user.deleteProject(this.projectId, error => {
  242. expect(error).not.to.exist
  243. let doc =
  244. MockDocstoreApi.docs[this.projectId.toString()][this.docId.toString()]
  245. expect(doc).to.exist
  246. expect(doc.deleted).to.be.truthy
  247. done()
  248. })
  249. })
  250. describe('When the deleted project is expired', function() {
  251. beforeEach(function(done) {
  252. this.user.deleteProject(this.projectId, error => {
  253. if (error) {
  254. throw error
  255. }
  256. done()
  257. })
  258. })
  259. it('Should destroy the docs', function(done) {
  260. expect(
  261. MockDocstoreApi.docs[this.projectId.toString()][this.docId.toString()]
  262. ).to.exist
  263. request.post(
  264. `/internal/project/${this.projectId}/expire-deleted-project`,
  265. {
  266. auth: {
  267. user: settings.apis.web.user,
  268. pass: settings.apis.web.pass,
  269. sendImmediately: true
  270. }
  271. },
  272. (error, res) => {
  273. expect(error).not.to.exist
  274. expect(res.statusCode).to.equal(200)
  275. expect(MockDocstoreApi.docs[this.projectId.toString()]).not.to.exist
  276. done()
  277. }
  278. )
  279. })
  280. it('Should remove the project data from mongo', function(done) {
  281. db.deletedProjects.findOne(
  282. { 'deleterData.deletedProjectId': ObjectId(this.projectId) },
  283. (error, deletedProject) => {
  284. expect(error).not.to.exist
  285. expect(deletedProject).to.exist
  286. expect(deletedProject.project).to.exist
  287. expect(deletedProject.deleterData.deleterIpAddress).to.exist
  288. expect(deletedProject.deleterData.deletedAt).to.exist
  289. request.post(
  290. `/internal/project/${this.projectId}/expire-deleted-project`,
  291. {
  292. auth: {
  293. user: settings.apis.web.user,
  294. pass: settings.apis.web.pass,
  295. sendImmediately: true
  296. }
  297. },
  298. (error, res) => {
  299. expect(error).not.to.exist
  300. expect(res.statusCode).to.equal(200)
  301. db.deletedProjects.findOne(
  302. { 'deleterData.deletedProjectId': ObjectId(this.projectId) },
  303. (error, deletedProject) => {
  304. expect(error).not.to.exist
  305. expect(deletedProject).to.exist
  306. expect(deletedProject.project).not.to.exist
  307. expect(deletedProject.deleterData.deleterIpAddress).not.to
  308. .exist
  309. expect(deletedProject.deleterData.deletedAt).to.exist
  310. done()
  311. }
  312. )
  313. }
  314. )
  315. }
  316. )
  317. })
  318. })
  319. })
  320. })