ProjectEditorHandlerTests.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS101: Remove unnecessary use of Array.from
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const chai = require('chai')
  14. const { expect } = chai
  15. const should = chai.should()
  16. const modulePath = '../../../../app/src/Features/Project/ProjectEditorHandler'
  17. const SandboxedModule = require('sandboxed-module')
  18. describe('ProjectEditorHandler', function() {
  19. beforeEach(function() {
  20. this.project = {
  21. _id: 'project-id',
  22. name: 'Project Name',
  23. rootDoc_id: 'file-id',
  24. publicAccesLevel: 'private',
  25. deletedByExternalDataSource: false,
  26. rootFolder: [
  27. {
  28. _id: 'root-folder-id',
  29. name: '',
  30. docs: [],
  31. fileRefs: [],
  32. folders: [
  33. {
  34. _id: 'sub-folder-id',
  35. name: 'folder',
  36. docs: [
  37. {
  38. _id: 'doc-id',
  39. name: 'main.tex',
  40. lines: (this.lines = ['line 1', 'line 2', 'line 3'])
  41. }
  42. ],
  43. fileRefs: [
  44. {
  45. _id: 'file-id',
  46. name: 'image.png',
  47. created: (this.created = new Date()),
  48. size: 1234
  49. }
  50. ],
  51. folders: []
  52. }
  53. ]
  54. }
  55. ],
  56. deletedDocs: [
  57. {
  58. _id: 'deleted-doc-id',
  59. name: 'main.tex',
  60. deletedAt: (this.deletedAt = new Date('2017-01-01'))
  61. }
  62. ]
  63. }
  64. this.members = [
  65. {
  66. user: (this.owner = {
  67. _id: 'owner-id',
  68. first_name: 'Owner',
  69. last_name: 'ShareLaTeX',
  70. email: 'owner@sharelatex.com'
  71. }),
  72. privilegeLevel: 'owner'
  73. },
  74. {
  75. user: {
  76. _id: 'read-only-id',
  77. first_name: 'Read',
  78. last_name: 'Only',
  79. email: 'read-only@sharelatex.com'
  80. },
  81. privilegeLevel: 'readOnly'
  82. },
  83. {
  84. user: {
  85. _id: 'read-write-id',
  86. first_name: 'Read',
  87. last_name: 'Write',
  88. email: 'read-write@sharelatex.com'
  89. },
  90. privilegeLevel: 'readAndWrite'
  91. }
  92. ]
  93. this.invites = [
  94. {
  95. _id: 'invite_one',
  96. email: 'user-one@example.com',
  97. privileges: 'readOnly',
  98. projectId: this.project._id
  99. },
  100. {
  101. _id: 'invite_two',
  102. email: 'user-two@example.com',
  103. privileges: 'readOnly',
  104. projectId: this.project._id
  105. }
  106. ]
  107. return (this.handler = SandboxedModule.require(modulePath))
  108. })
  109. describe('buildProjectModelView', function() {
  110. describe('with owner and members included', function() {
  111. beforeEach(function() {
  112. return (this.result = this.handler.buildProjectModelView(
  113. this.project,
  114. this.members,
  115. this.invites
  116. ))
  117. })
  118. it('should include the id', function() {
  119. should.exist(this.result._id)
  120. return this.result._id.should.equal('project-id')
  121. })
  122. it('should include the name', function() {
  123. should.exist(this.result.name)
  124. return this.result.name.should.equal('Project Name')
  125. })
  126. it('should include the root doc id', function() {
  127. should.exist(this.result.rootDoc_id)
  128. return this.result.rootDoc_id.should.equal('file-id')
  129. })
  130. it('should include the public access level', function() {
  131. should.exist(this.result.publicAccesLevel)
  132. return this.result.publicAccesLevel.should.equal('private')
  133. })
  134. it('should include the owner', function() {
  135. should.exist(this.result.owner)
  136. this.result.owner._id.should.equal('owner-id')
  137. this.result.owner.email.should.equal('owner@sharelatex.com')
  138. this.result.owner.first_name.should.equal('Owner')
  139. this.result.owner.last_name.should.equal('ShareLaTeX')
  140. return this.result.owner.privileges.should.equal('owner')
  141. })
  142. it('should include the deletedDocs', function() {
  143. should.exist(this.result.deletedDocs)
  144. return this.result.deletedDocs.should.equal(this.project.deletedDocs)
  145. })
  146. it('should gather readOnly_refs and collaberators_refs into a list of members', function() {
  147. const findMember = id => {
  148. for (let member of Array.from(this.result.members)) {
  149. if (member._id === id) {
  150. return member
  151. }
  152. }
  153. return null
  154. }
  155. this.result.members.length.should.equal(2)
  156. should.exist(findMember('read-only-id'))
  157. findMember('read-only-id').privileges.should.equal('readOnly')
  158. findMember('read-only-id').first_name.should.equal('Read')
  159. findMember('read-only-id').last_name.should.equal('Only')
  160. findMember('read-only-id').email.should.equal(
  161. 'read-only@sharelatex.com'
  162. )
  163. should.exist(findMember('read-write-id'))
  164. findMember('read-write-id').privileges.should.equal('readAndWrite')
  165. findMember('read-write-id').first_name.should.equal('Read')
  166. findMember('read-write-id').last_name.should.equal('Write')
  167. return findMember('read-write-id').email.should.equal(
  168. 'read-write@sharelatex.com'
  169. )
  170. })
  171. it('should include folders in the project', function() {
  172. this.result.rootFolder[0]._id.should.equal('root-folder-id')
  173. this.result.rootFolder[0].name.should.equal('')
  174. this.result.rootFolder[0].folders[0]._id.should.equal('sub-folder-id')
  175. return this.result.rootFolder[0].folders[0].name.should.equal('folder')
  176. })
  177. it('should not duplicate folder contents', function() {
  178. this.result.rootFolder[0].docs.length.should.equal(0)
  179. return this.result.rootFolder[0].fileRefs.length.should.equal(0)
  180. })
  181. it('should include files in the project', function() {
  182. this.result.rootFolder[0].folders[0].fileRefs[0]._id.should.equal(
  183. 'file-id'
  184. )
  185. this.result.rootFolder[0].folders[0].fileRefs[0].name.should.equal(
  186. 'image.png'
  187. )
  188. this.result.rootFolder[0].folders[0].fileRefs[0].created.should.equal(
  189. this.created
  190. )
  191. return should.not.exist(
  192. this.result.rootFolder[0].folders[0].fileRefs[0].size
  193. )
  194. })
  195. it('should include docs in the project but not the lines', function() {
  196. this.result.rootFolder[0].folders[0].docs[0]._id.should.equal('doc-id')
  197. this.result.rootFolder[0].folders[0].docs[0].name.should.equal(
  198. 'main.tex'
  199. )
  200. return should.not.exist(
  201. this.result.rootFolder[0].folders[0].docs[0].lines
  202. )
  203. })
  204. it('should include invites', function() {
  205. should.exist(this.result.invites)
  206. return this.result.invites.should.deep.equal(this.invites)
  207. })
  208. })
  209. describe('deletedByExternalDataSource', function() {
  210. it('should set the deletedByExternalDataSource flag to false when it is not there', function() {
  211. delete this.project.deletedByExternalDataSource
  212. const result = this.handler.buildProjectModelView(
  213. this.project,
  214. this.members,
  215. [],
  216. []
  217. )
  218. return result.deletedByExternalDataSource.should.equal(false)
  219. })
  220. it('should set the deletedByExternalDataSource flag to false when it is false', function() {
  221. const result = this.handler.buildProjectModelView(
  222. this.project,
  223. this.members,
  224. [],
  225. []
  226. )
  227. return result.deletedByExternalDataSource.should.equal(false)
  228. })
  229. it('should set the deletedByExternalDataSource flag to true when it is true', function() {
  230. this.project.deletedByExternalDataSource = true
  231. const result = this.handler.buildProjectModelView(
  232. this.project,
  233. this.members,
  234. [],
  235. []
  236. )
  237. return result.deletedByExternalDataSource.should.equal(true)
  238. })
  239. })
  240. describe('features', function() {
  241. beforeEach(function() {
  242. this.owner.features = {
  243. versioning: true,
  244. collaborators: 3,
  245. compileGroup: 'priority',
  246. compileTimeout: 96
  247. }
  248. return (this.result = this.handler.buildProjectModelView(
  249. this.project,
  250. this.members,
  251. [],
  252. []
  253. ))
  254. })
  255. it('should copy the owner features to the project', function() {
  256. this.result.features.versioning.should.equal(
  257. this.owner.features.versioning
  258. )
  259. this.result.features.collaborators.should.equal(
  260. this.owner.features.collaborators
  261. )
  262. this.result.features.compileGroup.should.equal(
  263. this.owner.features.compileGroup
  264. )
  265. return this.result.features.compileTimeout.should.equal(
  266. this.owner.features.compileTimeout
  267. )
  268. })
  269. })
  270. })
  271. describe('buildOwnerAndMembersViews', function() {
  272. beforeEach(function() {
  273. this.owner.features = {
  274. versioning: true,
  275. collaborators: 3,
  276. compileGroup: 'priority',
  277. compileTimeout: 22
  278. }
  279. return (this.result = this.handler.buildOwnerAndMembersViews(
  280. this.members
  281. ))
  282. })
  283. it('should produce an object with the right keys', function() {
  284. return expect(this.result).to.have.all.keys([
  285. 'owner',
  286. 'ownerFeatures',
  287. 'members'
  288. ])
  289. })
  290. it('should separate the owner from the members', function() {
  291. this.result.members.length.should.equal(this.members.length - 1)
  292. expect(this.result.owner._id).to.equal(this.owner._id)
  293. expect(this.result.owner.email).to.equal(this.owner.email)
  294. return expect(
  295. this.result.members.filter(m => m._id === this.owner._id).length
  296. ).to.equal(0)
  297. })
  298. it('should extract the ownerFeatures from the owner object', function() {
  299. return expect(this.result.ownerFeatures).to.deep.equal(
  300. this.owner.features
  301. )
  302. })
  303. describe('when there is no owner', function() {
  304. beforeEach(function() {
  305. // remove the owner from members list
  306. this.membersWithoutOwner = this.members.filter(
  307. m => m.user._id !== this.owner._id
  308. )
  309. return (this.result = this.handler.buildOwnerAndMembersViews(
  310. this.membersWithoutOwner
  311. ))
  312. })
  313. it('should produce an object with the right keys', function() {
  314. return expect(this.result).to.have.all.keys([
  315. 'owner',
  316. 'ownerFeatures',
  317. 'members'
  318. ])
  319. })
  320. it('should not separate out an owner', function() {
  321. this.result.members.length.should.equal(this.membersWithoutOwner.length)
  322. return expect(this.result.owner).to.equal(null)
  323. })
  324. it('should not extract the ownerFeatures from the owner object', function() {
  325. return expect(this.result.ownerFeatures).to.equal(null)
  326. })
  327. })
  328. })
  329. })