ProjectHistoryClient.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import { expect } from 'chai'
  2. import request from 'request'
  3. import Settings from '@overleaf/settings'
  4. import RedisWrapper from '@overleaf/redis-wrapper'
  5. import { db } from '../../../../app/js/mongodb.js'
  6. const rclient = RedisWrapper.createClient(Settings.redis.project_history)
  7. const Keys = Settings.redis.project_history.key_schema
  8. export function resetDatabase(callback) {
  9. rclient.flushdb(callback)
  10. }
  11. export function initializeProject(historyId, callback) {
  12. request.post(
  13. {
  14. url: 'http://localhost:3054/project',
  15. json: { historyId },
  16. },
  17. (error, res, body) => {
  18. if (error) {
  19. return callback(error)
  20. }
  21. expect(res.statusCode).to.equal(200)
  22. callback(null, body.project)
  23. }
  24. )
  25. }
  26. export function flushProject(projectId, options, callback) {
  27. if (typeof options === 'function') {
  28. callback = options
  29. options = null
  30. }
  31. if (!options) {
  32. options = { allowErrors: false }
  33. }
  34. request.post(
  35. {
  36. url: `http://localhost:3054/project/${projectId}/flush`,
  37. },
  38. (error, res, body) => {
  39. if (error) {
  40. return callback(error)
  41. }
  42. if (!options.allowErrors) {
  43. expect(res.statusCode).to.equal(204)
  44. }
  45. callback(error, res)
  46. }
  47. )
  48. }
  49. export function getSummarizedUpdates(projectId, query, callback) {
  50. request.get(
  51. {
  52. url: `http://localhost:3054/project/${projectId}/updates`,
  53. qs: query,
  54. json: true,
  55. },
  56. (error, res, body) => {
  57. if (error) {
  58. return callback(error)
  59. }
  60. expect(res.statusCode).to.equal(200)
  61. callback(error, body)
  62. }
  63. )
  64. }
  65. export function getDiff(projectId, pathname, from, to, callback) {
  66. request.get(
  67. {
  68. url: `http://localhost:3054/project/${projectId}/diff`,
  69. qs: {
  70. pathname,
  71. from,
  72. to,
  73. },
  74. json: true,
  75. },
  76. (error, res, body) => {
  77. if (error) {
  78. return callback(error)
  79. }
  80. expect(res.statusCode).to.equal(200)
  81. callback(error, body)
  82. }
  83. )
  84. }
  85. export function getFileTreeDiff(projectId, from, to, callback) {
  86. request.get(
  87. {
  88. url: `http://localhost:3054/project/${projectId}/filetree/diff`,
  89. qs: {
  90. from,
  91. to,
  92. },
  93. json: true,
  94. },
  95. (error, res, body) => {
  96. if (error) {
  97. return callback(error)
  98. }
  99. callback(error, body, res.statusCode)
  100. }
  101. )
  102. }
  103. export function getSnapshot(projectId, pathname, version, options, callback) {
  104. if (typeof options === 'function') {
  105. callback = options
  106. options = null
  107. }
  108. if (!options) {
  109. options = { allowErrors: false }
  110. }
  111. request.get(
  112. {
  113. url: `http://localhost:3054/project/${projectId}/version/${version}/${encodeURIComponent(
  114. pathname
  115. )}`,
  116. },
  117. (error, res, body) => {
  118. if (error) {
  119. return callback(error)
  120. }
  121. if (!options.allowErrors) {
  122. expect(res.statusCode).to.equal(200)
  123. }
  124. callback(error, body, res.statusCode)
  125. }
  126. )
  127. }
  128. export function pushRawUpdate(projectId, update, callback) {
  129. rclient.rpush(
  130. Keys.projectHistoryOps({ project_id: projectId }),
  131. JSON.stringify(update),
  132. callback
  133. )
  134. }
  135. export function setFirstOpTimestamp(projectId, timestamp, callback) {
  136. rclient.set(
  137. Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
  138. timestamp,
  139. callback
  140. )
  141. }
  142. export function getFirstOpTimestamp(projectId, callback) {
  143. rclient.get(
  144. Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
  145. callback
  146. )
  147. }
  148. export function clearFirstOpTimestamp(projectId, callback) {
  149. rclient.del(
  150. Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
  151. callback
  152. )
  153. }
  154. export function getQueueLength(projectId, callback) {
  155. rclient.llen(Keys.projectHistoryOps({ project_id: projectId }), callback)
  156. }
  157. export function getQueueCounts(callback) {
  158. return request.get(
  159. {
  160. url: 'http://localhost:3054/status/queue',
  161. json: true,
  162. },
  163. callback
  164. )
  165. }
  166. export function resyncHistory(projectId, callback) {
  167. request.post(
  168. {
  169. url: `http://localhost:3054/project/${projectId}/resync`,
  170. json: true,
  171. body: { origin: { kind: 'test-origin' } },
  172. },
  173. (error, res, body) => {
  174. if (error) {
  175. return callback(error)
  176. }
  177. expect(res.statusCode).to.equal(204)
  178. callback(error)
  179. }
  180. )
  181. }
  182. export function createLabel(
  183. projectId,
  184. userId,
  185. version,
  186. comment,
  187. createdAt,
  188. callback
  189. ) {
  190. request.post(
  191. {
  192. url: `http://localhost:3054/project/${projectId}/user/${userId}/labels`,
  193. json: { comment, version, created_at: createdAt },
  194. },
  195. (error, res, body) => {
  196. if (error) {
  197. return callback(error)
  198. }
  199. expect(res.statusCode).to.equal(200)
  200. callback(null, body)
  201. }
  202. )
  203. }
  204. export function getLabels(projectId, callback) {
  205. request.get(
  206. {
  207. url: `http://localhost:3054/project/${projectId}/labels`,
  208. json: true,
  209. },
  210. (error, res, body) => {
  211. if (error) {
  212. return callback(error)
  213. }
  214. expect(res.statusCode).to.equal(200)
  215. callback(null, body)
  216. }
  217. )
  218. }
  219. export function deleteLabelForUser(projectId, userId, labelId, callback) {
  220. request.delete(
  221. {
  222. url: `http://localhost:3054/project/${projectId}/user/${userId}/labels/${labelId}`,
  223. },
  224. (error, res, body) => {
  225. if (error) {
  226. return callback(error)
  227. }
  228. expect(res.statusCode).to.equal(204)
  229. callback(null, body)
  230. }
  231. )
  232. }
  233. export function deleteLabel(projectId, labelId, callback) {
  234. request.delete(
  235. {
  236. url: `http://localhost:3054/project/${projectId}/labels/${labelId}`,
  237. },
  238. (error, res, body) => {
  239. if (error) {
  240. return callback(error)
  241. }
  242. expect(res.statusCode).to.equal(204)
  243. callback(null, body)
  244. }
  245. )
  246. }
  247. export function setFailure(failureEntry, callback) {
  248. db.projectHistoryFailures.deleteOne(
  249. { project_id: { $exists: true } },
  250. (err, result) => {
  251. if (err) {
  252. return callback(err)
  253. }
  254. db.projectHistoryFailures.insertOne(failureEntry, callback)
  255. }
  256. )
  257. }
  258. export function transferLabelOwnership(fromUser, toUser, callback) {
  259. request.post(
  260. {
  261. url: `http://localhost:3054/user/${fromUser}/labels/transfer/${toUser}`,
  262. },
  263. (error, res, body) => {
  264. if (error) {
  265. return callback(error)
  266. }
  267. expect(res.statusCode).to.equal(204)
  268. callback(null, body)
  269. }
  270. )
  271. }
  272. export function getDump(projectId, callback) {
  273. request.get(
  274. `http://localhost:3054/project/${projectId}/dump`,
  275. (err, res, body) => {
  276. if (err) {
  277. return callback(err)
  278. }
  279. expect(res.statusCode).to.equal(200)
  280. callback(null, JSON.parse(body))
  281. }
  282. )
  283. }
  284. export function deleteProject(projectId, callback) {
  285. request.delete(`http://localhost:3054/project/${projectId}`, (err, res) => {
  286. if (err) {
  287. return callback(err)
  288. }
  289. expect(res.statusCode).to.equal(204)
  290. callback()
  291. })
  292. }