ResourceStateManagerTests.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const SandboxedModule = require('sandboxed-module')
  13. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const should = require('chai').should()
  16. const modulePath = require('path').join(
  17. __dirname,
  18. '../../../app/js/ResourceStateManager'
  19. )
  20. const Path = require('path')
  21. const Errors = require('../../../app/js/Errors')
  22. describe('ResourceStateManager', function () {
  23. beforeEach(function () {
  24. this.ResourceStateManager = SandboxedModule.require(modulePath, {
  25. singleOnly: true,
  26. requires: {
  27. fs: (this.fs = {}),
  28. 'logger-sharelatex': { log: sinon.stub(), err: sinon.stub() },
  29. './SafeReader': (this.SafeReader = {})
  30. }
  31. })
  32. this.basePath = '/path/to/write/files/to'
  33. this.resources = [
  34. { path: 'resource-1-mock' },
  35. { path: 'resource-2-mock' },
  36. { path: 'resource-3-mock' }
  37. ]
  38. this.state = '1234567890'
  39. this.resourceFileName = `${this.basePath}/.project-sync-state`
  40. this.resourceFileContents = `${this.resources[0].path}\n${this.resources[1].path}\n${this.resources[2].path}\nstateHash:${this.state}`
  41. return (this.callback = sinon.stub())
  42. })
  43. describe('saveProjectState', function () {
  44. beforeEach(function () {
  45. return (this.fs.writeFile = sinon.stub().callsArg(2))
  46. })
  47. describe('when the state is specified', function () {
  48. beforeEach(function () {
  49. return this.ResourceStateManager.saveProjectState(
  50. this.state,
  51. this.resources,
  52. this.basePath,
  53. this.callback
  54. )
  55. })
  56. it('should write the resource list to disk', function () {
  57. return this.fs.writeFile
  58. .calledWith(this.resourceFileName, this.resourceFileContents)
  59. .should.equal(true)
  60. })
  61. return it('should call the callback', function () {
  62. return this.callback.called.should.equal(true)
  63. })
  64. })
  65. return describe('when the state is undefined', function () {
  66. beforeEach(function () {
  67. this.state = undefined
  68. this.fs.unlink = sinon.stub().callsArg(1)
  69. return this.ResourceStateManager.saveProjectState(
  70. this.state,
  71. this.resources,
  72. this.basePath,
  73. this.callback
  74. )
  75. })
  76. it('should unlink the resource file', function () {
  77. return this.fs.unlink
  78. .calledWith(this.resourceFileName)
  79. .should.equal(true)
  80. })
  81. it('should not write the resource list to disk', function () {
  82. return this.fs.writeFile.called.should.equal(false)
  83. })
  84. return it('should call the callback', function () {
  85. return this.callback.called.should.equal(true)
  86. })
  87. })
  88. })
  89. describe('checkProjectStateMatches', function () {
  90. describe('when the state matches', function () {
  91. beforeEach(function () {
  92. this.SafeReader.readFile = sinon
  93. .stub()
  94. .callsArgWith(3, null, this.resourceFileContents)
  95. return this.ResourceStateManager.checkProjectStateMatches(
  96. this.state,
  97. this.basePath,
  98. this.callback
  99. )
  100. })
  101. it('should read the resource file', function () {
  102. return this.SafeReader.readFile
  103. .calledWith(this.resourceFileName)
  104. .should.equal(true)
  105. })
  106. return it('should call the callback with the results', function () {
  107. return this.callback
  108. .calledWithMatch(null, this.resources)
  109. .should.equal(true)
  110. })
  111. })
  112. return describe('when the state does not match', function () {
  113. beforeEach(function () {
  114. this.SafeReader.readFile = sinon
  115. .stub()
  116. .callsArgWith(3, null, this.resourceFileContents)
  117. return this.ResourceStateManager.checkProjectStateMatches(
  118. 'not-the-original-state',
  119. this.basePath,
  120. this.callback
  121. )
  122. })
  123. it('should call the callback with an error', function () {
  124. this.callback
  125. .calledWith(sinon.match(Errors.FilesOutOfSyncError))
  126. .should.equal(true)
  127. const message = this.callback.args[0][0].message
  128. expect(message).to.include('invalid state for incremental update')
  129. })
  130. })
  131. })
  132. return describe('checkResourceFiles', function () {
  133. describe('when all the files are present', function () {
  134. beforeEach(function () {
  135. this.allFiles = [
  136. this.resources[0].path,
  137. this.resources[1].path,
  138. this.resources[2].path
  139. ]
  140. return this.ResourceStateManager.checkResourceFiles(
  141. this.resources,
  142. this.allFiles,
  143. this.basePath,
  144. this.callback
  145. )
  146. })
  147. return it('should call the callback', function () {
  148. return this.callback.calledWithExactly().should.equal(true)
  149. })
  150. })
  151. describe('when there is a missing file', function () {
  152. beforeEach(function () {
  153. this.allFiles = [this.resources[0].path, this.resources[1].path]
  154. this.fs.stat = sinon.stub().callsArgWith(1, new Error())
  155. return this.ResourceStateManager.checkResourceFiles(
  156. this.resources,
  157. this.allFiles,
  158. this.basePath,
  159. this.callback
  160. )
  161. })
  162. it('should call the callback with an error', function () {
  163. this.callback
  164. .calledWith(sinon.match(Errors.FilesOutOfSyncError))
  165. .should.equal(true)
  166. const message = this.callback.args[0][0].message
  167. expect(message).to.include(
  168. 'resource files missing in incremental update'
  169. )
  170. })
  171. })
  172. return describe('when a resource contains a relative path', function () {
  173. beforeEach(function () {
  174. this.resources[0].path = '../foo/bar.tex'
  175. this.allFiles = [
  176. this.resources[0].path,
  177. this.resources[1].path,
  178. this.resources[2].path
  179. ]
  180. return this.ResourceStateManager.checkResourceFiles(
  181. this.resources,
  182. this.allFiles,
  183. this.basePath,
  184. this.callback
  185. )
  186. })
  187. it('should call the callback with an error', function () {
  188. this.callback.calledWith(sinon.match(Error)).should.equal(true)
  189. const message = this.callback.args[0][0].message
  190. expect(message).to.include('relative path in resource file list')
  191. })
  192. })
  193. })
  194. })