ReadingASnapshotTests.js 6.4 KB

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