RestoreManagerTests.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. no-unused-vars,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  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 SandboxedModule = require('sandboxed-module')
  14. const assert = require('assert')
  15. require('chai').should()
  16. const { expect } = require('chai')
  17. const sinon = require('sinon')
  18. const modulePath = require('path').join(
  19. __dirname,
  20. '../../../../app/src/Features/History/RestoreManager'
  21. )
  22. const Errors = require('../../../../app/src/Features/Errors/Errors')
  23. const tk = require('timekeeper')
  24. const moment = require('moment')
  25. describe('RestoreManager', function() {
  26. beforeEach(function() {
  27. tk.freeze(Date.now()) // freeze the time for these tests
  28. this.RestoreManager = SandboxedModule.require(modulePath, {
  29. globals: {
  30. console: console
  31. },
  32. requires: {
  33. 'settings-sharelatex': {},
  34. '../../infrastructure/FileWriter': (this.FileWriter = {}),
  35. '../Uploads/FileSystemImportManager': (this.FileSystemImportManager = {}),
  36. '../Project/ProjectEntityHandler': (this.ProjectEntityHandler = {}),
  37. '../Editor/EditorController': (this.EditorController = {}),
  38. 'logger-sharelatex': (this.logger = {
  39. log: sinon.stub(),
  40. err: sinon.stub()
  41. })
  42. }
  43. })
  44. this.user_id = 'mock-user-id'
  45. this.project_id = 'mock-project-id'
  46. this.version = 42
  47. return (this.callback = sinon.stub())
  48. })
  49. afterEach(function() {
  50. return tk.reset()
  51. })
  52. describe('restoreFileFromV2', function() {
  53. beforeEach(function() {
  54. this.RestoreManager._writeFileVersionToDisk = sinon
  55. .stub()
  56. .yields(null, (this.fsPath = '/tmp/path/on/disk'))
  57. this.RestoreManager._findOrCreateFolder = sinon
  58. .stub()
  59. .yields(null, (this.folder_id = 'mock-folder-id'))
  60. return (this.FileSystemImportManager.addEntity = sinon
  61. .stub()
  62. .yields(null, (this.entity = 'mock-entity')))
  63. })
  64. describe('with a file not in a folder', function() {
  65. beforeEach(function() {
  66. this.pathname = 'foo.tex'
  67. return this.RestoreManager.restoreFileFromV2(
  68. this.user_id,
  69. this.project_id,
  70. this.version,
  71. this.pathname,
  72. this.callback
  73. )
  74. })
  75. it('should write the file version to disk', function() {
  76. return this.RestoreManager._writeFileVersionToDisk
  77. .calledWith(this.project_id, this.version, this.pathname)
  78. .should.equal(true)
  79. })
  80. it('should find the root folder', function() {
  81. return this.RestoreManager._findOrCreateFolder
  82. .calledWith(this.project_id, '')
  83. .should.equal(true)
  84. })
  85. it('should add the entity', function() {
  86. return this.FileSystemImportManager.addEntity
  87. .calledWith(
  88. this.user_id,
  89. this.project_id,
  90. this.folder_id,
  91. 'foo.tex',
  92. this.fsPath,
  93. false
  94. )
  95. .should.equal(true)
  96. })
  97. it('should call the callback with the entity', function() {
  98. return this.callback.calledWith(null, this.entity).should.equal(true)
  99. })
  100. })
  101. describe('with a file in a folder', function() {
  102. beforeEach(function() {
  103. this.pathname = 'foo/bar.tex'
  104. return this.RestoreManager.restoreFileFromV2(
  105. this.user_id,
  106. this.project_id,
  107. this.version,
  108. this.pathname,
  109. this.callback
  110. )
  111. })
  112. it('should find the folder', function() {
  113. return this.RestoreManager._findOrCreateFolder
  114. .calledWith(this.project_id, 'foo')
  115. .should.equal(true)
  116. })
  117. it('should add the entity by its basename', function() {
  118. return this.FileSystemImportManager.addEntity
  119. .calledWith(
  120. this.user_id,
  121. this.project_id,
  122. this.folder_id,
  123. 'bar.tex',
  124. this.fsPath,
  125. false
  126. )
  127. .should.equal(true)
  128. })
  129. })
  130. })
  131. describe('_findOrCreateFolder', function() {
  132. beforeEach(function() {
  133. this.EditorController.mkdirp = sinon
  134. .stub()
  135. .yields(null, [], { _id: (this.folder_id = 'mock-folder-id') })
  136. return this.RestoreManager._findOrCreateFolder(
  137. this.project_id,
  138. 'folder/name',
  139. this.callback
  140. )
  141. })
  142. it('should look up or create the folder', function() {
  143. return this.EditorController.mkdirp
  144. .calledWith(this.project_id, 'folder/name')
  145. .should.equal(true)
  146. })
  147. it('should return the folder_id', function() {
  148. return this.callback.calledWith(null, this.folder_id).should.equal(true)
  149. })
  150. })
  151. describe('_addEntityWithUniqueName', function() {
  152. beforeEach(function() {
  153. this.addEntityWithName = sinon.stub()
  154. return (this.name = 'foo.tex')
  155. })
  156. describe('with a valid name', function() {
  157. beforeEach(function() {
  158. this.addEntityWithName.yields(null, (this.entity = 'mock-entity'))
  159. return this.RestoreManager._addEntityWithUniqueName(
  160. this.addEntityWithName,
  161. this.name,
  162. this.callback
  163. )
  164. })
  165. it('should add the entity', function() {
  166. return this.addEntityWithName.calledWith(this.name).should.equal(true)
  167. })
  168. it('should return the entity', function() {
  169. return this.callback.calledWith(null, this.entity).should.equal(true)
  170. })
  171. })
  172. describe('with an invalid name', function() {
  173. beforeEach(function() {
  174. this.addEntityWithName
  175. .onFirstCall()
  176. .yields(new Errors.InvalidNameError())
  177. this.addEntityWithName
  178. .onSecondCall()
  179. .yields(null, (this.entity = 'mock-entity'))
  180. return this.RestoreManager._addEntityWithUniqueName(
  181. this.addEntityWithName,
  182. this.name,
  183. this.callback
  184. )
  185. })
  186. it('should try to add the entity with its original name', function() {
  187. return this.addEntityWithName.calledWith('foo.tex').should.equal(true)
  188. })
  189. it('should try to add the entity with a unique name', function() {
  190. const date = moment(new Date()).format('Do MMM YY H:mm:ss')
  191. return this.addEntityWithName
  192. .calledWith(`foo (Restored on ${date}).tex`)
  193. .should.equal(true)
  194. })
  195. it('should return the entity', function() {
  196. return this.callback.calledWith(null, this.entity).should.equal(true)
  197. })
  198. })
  199. })
  200. })