ReadingASnapshotTests.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. import { expect } from 'chai'
  2. import mongodb from 'mongodb-legacy'
  3. import nock from 'nock'
  4. import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js'
  5. import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js'
  6. const { ObjectId } = mongodb
  7. const MockHistoryStore = () => nock('http://127.0.0.1:3100')
  8. const MockWeb = () => nock('http://127.0.0.1:3000')
  9. const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
  10. describe('ReadSnapshot', function () {
  11. beforeEach(function (done) {
  12. ProjectHistoryApp.ensureRunning(error => {
  13. if (error) {
  14. throw error
  15. }
  16. this.historyId = new ObjectId().toString()
  17. MockHistoryStore().post('/api/projects').reply(200, {
  18. projectId: this.historyId,
  19. })
  20. ProjectHistoryClient.initializeProject(
  21. this.historyId,
  22. (error, v1Project) => {
  23. if (error) {
  24. throw error
  25. }
  26. this.projectId = new ObjectId().toString()
  27. MockWeb()
  28. .get(`/project/${this.projectId}/details`)
  29. .reply(200, {
  30. name: 'Test Project',
  31. overleaf: { history: { id: v1Project.id } },
  32. })
  33. done()
  34. }
  35. )
  36. })
  37. })
  38. afterEach(function () {
  39. nock.cleanAll()
  40. })
  41. describe('of a text file', function () {
  42. it('should return the snapshot of a doc at the given version', function (done) {
  43. MockHistoryStore()
  44. .get(`/api/projects/${this.historyId}/versions/5/history`)
  45. .replyWithFile(200, fixture('chunks/4-6.json'))
  46. MockHistoryStore()
  47. .get(
  48. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  49. )
  50. .replyWithFile(
  51. 200,
  52. fixture('blobs/c6654ea913979e13e22022653d284444f284a172')
  53. )
  54. ProjectHistoryClient.getSnapshot(
  55. this.projectId,
  56. 'foo.tex',
  57. 5,
  58. (error, body) => {
  59. if (error) {
  60. throw error
  61. }
  62. expect(body).to.deep.equal(
  63. `\
  64. Hello world
  65. One two three
  66. Four five six
  67. Seven eight nine\
  68. `.replace(/^\t/g, '')
  69. )
  70. done()
  71. }
  72. )
  73. })
  74. it('should return the snapshot of a doc at a different version', function (done) {
  75. MockHistoryStore()
  76. .get(`/api/projects/${this.historyId}/versions/4/history`)
  77. .replyWithFile(200, fixture('chunks/4-6.json'))
  78. MockHistoryStore()
  79. .get(
  80. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  81. )
  82. .replyWithFile(
  83. 200,
  84. fixture('blobs/c6654ea913979e13e22022653d284444f284a172')
  85. )
  86. ProjectHistoryClient.getSnapshot(
  87. this.projectId,
  88. 'foo.tex',
  89. 4,
  90. (error, body) => {
  91. if (error) {
  92. throw error
  93. }
  94. expect(body).to.deep.equal(
  95. `\
  96. Hello world
  97. One two three
  98. Four five six
  99. Seven eight nince\
  100. `.replace(/^\t/g, '')
  101. )
  102. done()
  103. }
  104. )
  105. })
  106. it('should return the snapshot of a doc after a rename version', function (done) {
  107. MockHistoryStore()
  108. .get(`/api/projects/${this.historyId}/versions/6/history`)
  109. .replyWithFile(200, fixture('chunks/4-6.json'))
  110. MockHistoryStore()
  111. .get(
  112. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  113. )
  114. .replyWithFile(
  115. 200,
  116. fixture('blobs/c6654ea913979e13e22022653d284444f284a172')
  117. )
  118. ProjectHistoryClient.getSnapshot(
  119. this.projectId,
  120. 'bar.tex',
  121. 6,
  122. (error, body) => {
  123. if (error) {
  124. throw error
  125. }
  126. expect(body).to.deep.equal(
  127. `\
  128. Hello world
  129. One two three
  130. Four five six
  131. Seven eight nine\
  132. `.replace(/^\t/g, '')
  133. )
  134. done()
  135. }
  136. )
  137. })
  138. })
  139. describe('of a binary file', function () {
  140. beforeEach(function () {
  141. MockHistoryStore()
  142. .get(`/api/projects/${this.historyId}/versions/4/history`)
  143. .reply(200, {
  144. chunk: {
  145. history: {
  146. snapshot: {
  147. files: {
  148. binary_file: {
  149. hash: 'c6654ea913979e13e22022653d284444f284a172',
  150. byteLength: 41,
  151. },
  152. },
  153. },
  154. changes: [],
  155. },
  156. startVersion: 3,
  157. },
  158. authors: [],
  159. })
  160. })
  161. it('should return the snapshot of the file at the given version', function (done) {
  162. MockHistoryStore()
  163. .get(
  164. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  165. )
  166. .replyWithFile(
  167. 200,
  168. fixture('blobs/c6654ea913979e13e22022653d284444f284a172')
  169. )
  170. ProjectHistoryClient.getSnapshot(
  171. this.projectId,
  172. 'binary_file',
  173. 4,
  174. (error, body) => {
  175. if (error) {
  176. throw error
  177. }
  178. expect(body).to.deep.equal(
  179. `\
  180. Hello world
  181. One two three
  182. Four five six\
  183. `.replace(/^\t/g, '')
  184. )
  185. done()
  186. }
  187. )
  188. })
  189. it("should return an error when the blob doesn't exist", function (done) {
  190. MockHistoryStore()
  191. .get(`/api/projects/${this.historyId}/versions/4/history`)
  192. .reply(200, {
  193. chunk: {
  194. history: {
  195. snapshot: {
  196. files: {
  197. binary_file: {
  198. hash: 'c6654ea913979e13e22022653d284444f284a172',
  199. byteLength: 41,
  200. },
  201. },
  202. },
  203. changes: [],
  204. },
  205. startVersion: 3,
  206. },
  207. authors: [],
  208. })
  209. MockHistoryStore()
  210. .get(
  211. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  212. )
  213. .reply(404)
  214. ProjectHistoryClient.getSnapshot(
  215. this.projectId,
  216. 'binary_file',
  217. 4,
  218. { allowErrors: true },
  219. (error, body, statusCode) => {
  220. if (error) {
  221. throw error
  222. }
  223. expect(statusCode).to.equal(500)
  224. done()
  225. }
  226. )
  227. })
  228. it('should return an error when the blob request errors', function (done) {
  229. MockHistoryStore()
  230. .get(`/api/projects/${this.historyId}/versions/4/history`)
  231. .reply(200, {
  232. chunk: {
  233. history: {
  234. snapshot: {
  235. files: {
  236. binary_file: {
  237. hash: 'c6654ea913979e13e22022653d284444f284a172',
  238. byteLength: 41,
  239. },
  240. },
  241. },
  242. changes: [],
  243. },
  244. startVersion: 3,
  245. },
  246. authors: [],
  247. })
  248. MockHistoryStore()
  249. .get(
  250. `/api/projects/${this.historyId}/blobs/c6654ea913979e13e22022653d284444f284a172`
  251. )
  252. .replyWithError('oh no!')
  253. ProjectHistoryClient.getSnapshot(
  254. this.projectId,
  255. 'binary_file',
  256. 4,
  257. { allowErrors: true },
  258. (error, body, statusCode) => {
  259. if (error) {
  260. throw error
  261. }
  262. expect(statusCode).to.equal(500)
  263. done()
  264. }
  265. )
  266. })
  267. })
  268. })