ProjectDuplicatorTests.coffee 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. sinon = require('sinon')
  2. chai = require('chai').should()
  3. modulePath = "../../../../app/js/Features/Project/ProjectDuplicator.js"
  4. SandboxedModule = require('sandboxed-module')
  5. describe 'ProjectDuplicator', ->
  6. beforeEach ->
  7. @level2folder =
  8. name: "level2folderName"
  9. _id:"level2folderId"
  10. docs:[@doc2 = {_id: "doc2_id", name:"level2folderDocName"}, undefined]
  11. folders:[]
  12. fileRefs:[{name:"file2", _id:"file2"}]
  13. @level1folder =
  14. name:"level1folder"
  15. _id:"level1folderId"
  16. docs:[@doc1 = {_id: "doc1_id", name:"level1folderDocName"}]
  17. folders:[@level2folder]
  18. fileRefs:[{name:"file1", _id:"file1"}, null] # the null is intentional to test null docs/files
  19. @rootFolder =
  20. name:"rootFolder"
  21. _id:"rootFolderId"
  22. docs:[@doc0 = {_id: "doc0_id", name:"rootDocHere"}]
  23. folders:[@level1folder, {}]
  24. fileRefs:[{name:"file0", _id:"file0"}]
  25. @project =
  26. _id: @old_project_id = "this_is_the_old_project_id"
  27. rootDoc_id: "rootDoc_id"
  28. rootFolder:[@rootFolder]
  29. compiler: "this_is_a_Compiler"
  30. @docContents = [{
  31. _id: @doc0._id
  32. lines: @doc0_lines = ["zero"]
  33. }, {
  34. _id: @doc1._id
  35. lines: @doc1_lines = ["one"]
  36. }, {
  37. _id: @doc2._id
  38. lines: @doc2_lines = ["two"]
  39. }]
  40. @DocstoreManager =
  41. getAllDocs: sinon.stub().callsArgWith(1, null, @docContents)
  42. @owner = {_id:"this_is_the_owner"}
  43. @stubbedNewProject =
  44. _id: @new_project_id = "new_project_id"
  45. readOnly_refs:[]
  46. collaberator_refs:[]
  47. rootFolder:[
  48. {_id:"new_root_folder_id"}
  49. ]
  50. @foundRootDoc = {_id:"rootDocId", name:"rootDocHere"}
  51. @creationHandler =
  52. createBlankProject : sinon.stub().callsArgWith(2, null, @stubbedNewProject)
  53. @newFolder = {_id: "newFolderId"}
  54. @locator =
  55. findRootDoc : sinon.stub().callsArgWith(1, null, @foundRootDoc, {})
  56. @projectOptionsHandler =
  57. setCompiler : sinon.stub().callsArg(2)
  58. @ProjectEntityUpdateHandler =
  59. addDoc: sinon.stub().callsArgWith(5, null, {name:"somDoc"})
  60. copyFileFromExistingProjectWithProject: sinon.stub()
  61. setRootDoc: sinon.stub()
  62. addFolder: sinon.stub().callsArgWith(3, null, @newFolder)
  63. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject.withArgs(sinon.match.any, sinon.match.any, sinon.match.any, "BROKEN-FILE", sinon.match.any, sinon.match.any).callsArgWith(5, new Error("failed"))
  64. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject.withArgs(sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.object, sinon.match.any).callsArg(5)
  65. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject.withArgs(sinon.match.any, sinon.match.any, sinon.match.any, null, sinon.match.any).callsArg(5)
  66. @DocumentUpdaterHandler =
  67. flushProjectToMongo: sinon.stub().callsArg(1)
  68. @Project =
  69. findById: sinon.stub().callsArgWith(1, null, @project)
  70. @ProjectGetter =
  71. getProject: sinon.stub()
  72. @ProjectGetter.getProject.withArgs(@old_project_id, sinon.match.any).callsArgWith(2, null, @project)
  73. @ProjectGetter.getProject.withArgs(@new_project_id, sinon.match.any).callsArgWith(2, null, @stubbedNewProject)
  74. @ProjectDeleter =
  75. deleteProject: sinon.stub().callsArgWith(1,null)
  76. @duplicator = SandboxedModule.require modulePath, requires:
  77. '../../models/Project':{Project:@Project}
  78. "../DocumentUpdater/DocumentUpdaterHandler": @DocumentUpdaterHandler
  79. './ProjectCreationHandler': @creationHandler
  80. './ProjectEntityUpdateHandler': @ProjectEntityUpdateHandler
  81. './ProjectLocator': @locator
  82. './ProjectDeleter': @ProjectDeleter
  83. './ProjectOptionsHandler': @projectOptionsHandler
  84. "../Docstore/DocstoreManager": @DocstoreManager
  85. "./ProjectGetter":@ProjectGetter
  86. 'logger-sharelatex':{
  87. log:->
  88. err:->
  89. }
  90. describe "when the copy succeeds", ->
  91. it "should look up the original project", (done) ->
  92. newProjectName = "someProj"
  93. @duplicator.duplicate @owner, @old_project_id, newProjectName, (err, newProject)=>
  94. @ProjectGetter.getProject.calledWith(@old_project_id).should.equal true
  95. done()
  96. it "should flush the original project to mongo", (done) ->
  97. newProjectName = "someProj"
  98. @duplicator.duplicate @owner, @old_project_id, newProjectName, (err, newProject)=>
  99. @DocumentUpdaterHandler.flushProjectToMongo.calledWith(@old_project_id).should.equal true
  100. done()
  101. it 'should create a blank project', (done)->
  102. newProjectName = "someProj"
  103. @duplicator.duplicate @owner, @old_project_id, newProjectName, (err, newProject)=>
  104. newProject._id.should.equal @stubbedNewProject._id
  105. @creationHandler.createBlankProject.calledWith(@owner._id, newProjectName).should.equal true
  106. done()
  107. it 'should use the same compiler', (done)->
  108. @ProjectEntityUpdateHandler.addDoc.callsArgWith(5, null, @rootFolder.docs[0], @owner._id)
  109. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  110. @projectOptionsHandler.setCompiler.calledWith(@stubbedNewProject._id, @project.compiler).should.equal true
  111. done()
  112. it 'should use the same root doc', (done)->
  113. @ProjectEntityUpdateHandler.addDoc.callsArgWith(5, null, @rootFolder.docs[0], @owner._id)
  114. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  115. @ProjectEntityUpdateHandler.setRootDoc.calledWith(@stubbedNewProject._id, @rootFolder.docs[0]._id).should.equal true
  116. done()
  117. it 'should not copy the collaberators or read only refs', (done)->
  118. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  119. newProject.collaberator_refs.length.should.equal 0
  120. newProject.readOnly_refs.length.should.equal 0
  121. done()
  122. it 'should copy all the folders', (done)->
  123. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  124. @ProjectEntityUpdateHandler.addFolder.calledWith(@new_project_id, @stubbedNewProject.rootFolder[0]._id, @level1folder.name).should.equal true
  125. @ProjectEntityUpdateHandler.addFolder.calledWith(@new_project_id, @newFolder._id, @level2folder.name).should.equal true
  126. @ProjectEntityUpdateHandler.addFolder.callCount.should.equal 2
  127. done()
  128. it 'should copy all the docs', (done)->
  129. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  130. @DocstoreManager.getAllDocs.calledWith(@old_project_id).should.equal true
  131. @ProjectEntityUpdateHandler.addDoc
  132. .calledWith(@new_project_id, @stubbedNewProject.rootFolder[0]._id, @doc0.name, @doc0_lines, @owner._id)
  133. .should.equal true
  134. @ProjectEntityUpdateHandler.addDoc
  135. .calledWith(@new_project_id, @newFolder._id, @doc1.name, @doc1_lines, @owner._id)
  136. .should.equal true
  137. @ProjectEntityUpdateHandler.addDoc
  138. .calledWith(@new_project_id, @newFolder._id, @doc2.name, @doc2_lines, @owner._id)
  139. .should.equal true
  140. done()
  141. it 'should copy all the files', (done)->
  142. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  143. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject
  144. .calledWith(@stubbedNewProject, @stubbedNewProject.rootFolder[0]._id, @project._id, @rootFolder.fileRefs[0], @owner._id)
  145. .should.equal true
  146. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject
  147. .calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level1folder.fileRefs[0], @owner._id)
  148. .should.equal true
  149. @ProjectEntityUpdateHandler.copyFileFromExistingProjectWithProject
  150. .calledWith(@stubbedNewProject, @newFolder._id, @project._id, @level2folder.fileRefs[0], @owner._id)
  151. .should.equal true
  152. done()
  153. describe 'when there is an error', ->
  154. beforeEach ->
  155. @rootFolder.fileRefs = [{name:"file0", _id:"file0"}, "BROKEN-FILE", {name:"file1", _id:"file1"}, {name:"file2", _id:"file2"}]
  156. it 'should delete the broken cloned project', (done) ->
  157. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  158. @ProjectDeleter.deleteProject
  159. .calledWith(@stubbedNewProject._id)
  160. .should.equal true
  161. done()
  162. it 'should not delete the original project', (done) ->
  163. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  164. @ProjectDeleter.deleteProject
  165. .calledWith(@old_project_id)
  166. .should.equal false
  167. done()
  168. it 'should return an error', (done) ->
  169. @duplicator.duplicate @owner, @old_project_id, "", (err, newProject)=>
  170. err.should.not.equal null
  171. done()