diff --git a/services/project-history/test/acceptance/js/FileTreeDiffTests.js b/services/project-history/test/acceptance/js/FileTreeDiffTests.js index 1b43dc1971..13591de8c4 100644 --- a/services/project-history/test/acceptance/js/FileTreeDiffTests.js +++ b/services/project-history/test/acceptance/js/FileTreeDiffTests.js @@ -1,72 +1,41 @@ -/* eslint-disable - no-undef, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -import sinon from 'sinon' import { expect } from 'chai' -import Settings from '@overleaf/settings' -import request from 'request' -import assert from 'node:assert' -import Path from 'node:path' import crypto from 'node:crypto' import mongodb from 'mongodb-legacy' import nock from 'nock' import * as ProjectHistoryClient from './helpers/ProjectHistoryClient.js' import * as ProjectHistoryApp from './helpers/ProjectHistoryApp.js' -import * as HistoryId from './helpers/HistoryId.js' const { ObjectId } = mongodb const MockHistoryStore = () => nock('http://127.0.0.1:3100') -const MockFileStore = () => nock('http://127.0.0.1:3009') const MockWeb = () => nock('http://127.0.0.1:3000') const sha = data => crypto.createHash('sha1').update(data).digest('hex') describe('FileTree Diffs', function () { - beforeEach(function (done) { - return ProjectHistoryApp.ensureRunning(error => { - if (error != null) { - throw error - } + beforeEach(async function () { + await ProjectHistoryApp.promises.ensureRunning() - this.historyId = new ObjectId().toString() - this.projectId = new ObjectId().toString() + this.historyId = new ObjectId().toString() + this.projectId = new ObjectId().toString() - MockHistoryStore().post('/api/projects').reply(200, { - projectId: this.historyId, - }) - MockWeb() - .get(`/project/${this.projectId}/details`) - .reply(200, { - name: 'Test Project', - overleaf: { history: { id: this.historyId } }, - }) - - return ProjectHistoryClient.initializeProject( - this.historyId, - (error, olProject) => { - if (error != null) { - throw error - } - return done() - } - ) + MockHistoryStore().post('/api/projects').reply(200, { + projectId: this.historyId, }) + MockWeb() + .get(`/project/${this.projectId}/details`) + .reply(200, { + name: 'Test Project', + overleaf: { history: { id: this.historyId } }, + }) + + await ProjectHistoryClient.promises.initializeProject(this.historyId) }) afterEach(function () { return nock.cleanAll() }) - it('should return a diff of the updates to a doc from a single chunk', function (done) { + it('should return a diff of the updates to a doc from a single chunk', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/7/history`) .reply(200, { @@ -139,45 +108,39 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 7, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'foo.tex', - operation: 'edited', - }, - { - pathname: 'deleted.tex', - operation: 'removed', - deletedAtV: 5, - editable: true, - }, - { - newPathname: 'newName.tex', - pathname: 'renamed.tex', - operation: 'renamed', - editable: true, - }, - { - pathname: 'added.tex', - operation: 'added', - editable: true, - }, - ], - }) - return done() - } + 7 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'foo.tex', + operation: 'edited', + }, + { + pathname: 'deleted.tex', + operation: 'removed', + deletedAtV: 5, + editable: true, + }, + { + newPathname: 'newName.tex', + pathname: 'renamed.tex', + operation: 'renamed', + editable: true, + }, + { + pathname: 'added.tex', + operation: 'added', + editable: true, + }, + ], + }) }) - it('should return a diff of the updates to a doc across multiple chunks', function (done) { + it('should return a diff of the updates to a doc across multiple chunks', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -299,53 +262,47 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 2, - 7, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'foo.tex', - operation: 'edited', - }, - { - pathname: 'bar.tex', - operation: 'edited', - }, - { - pathname: 'baz.tex', - editable: true, - }, - { - pathname: 'deleted.tex', - operation: 'removed', - deletedAtV: 4, - editable: true, - }, - { - newPathname: 'newName.tex', - pathname: 'renamed.tex', - operation: 'renamed', - editable: true, - }, - { - pathname: 'added.tex', - operation: 'added', - editable: true, - }, - ], - }) - return done() - } + 7 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'foo.tex', + operation: 'edited', + }, + { + pathname: 'bar.tex', + operation: 'edited', + }, + { + pathname: 'baz.tex', + editable: true, + }, + { + pathname: 'deleted.tex', + operation: 'removed', + deletedAtV: 4, + editable: true, + }, + { + newPathname: 'newName.tex', + pathname: 'renamed.tex', + operation: 'renamed', + editable: true, + }, + { + pathname: 'added.tex', + operation: 'added', + editable: true, + }, + ], + }) }) - it('should return a diff that includes multiple renames', function (done) { + it('should return a diff that includes multiple renames', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -387,30 +344,24 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - newPathname: 'three.tex', - pathname: 'one.tex', - operation: 'renamed', - editable: true, - }, - ], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [ + { + newPathname: 'three.tex', + pathname: 'one.tex', + operation: 'renamed', + editable: true, + }, + ], + }) }) - it('should handle deleting then re-adding a file', function (done) { + it('should handle deleting then re-adding a file', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -454,29 +405,23 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'one.tex', - operation: 'added', - editable: null, - }, - ], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'one.tex', + operation: 'added', + editable: null, + }, + ], + }) }) - it('should handle deleting the renaming a file to the same place', function (done) { + it('should handle deleting the renaming a file to the same place', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -522,30 +467,24 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'two.tex', - newPathname: 'one.tex', - operation: 'renamed', - editable: true, - }, - ], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'two.tex', + newPathname: 'one.tex', + operation: 'renamed', + editable: true, + }, + ], + }) }) - it('should handle adding then renaming a file', function (done) { + it('should handle adding then renaming a file', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -585,29 +524,23 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'two.tex', - operation: 'added', - editable: true, - }, - ], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'two.tex', + operation: 'added', + editable: true, + }, + ], + }) }) - it('should return 422 with a chunk with an invalid rename', function (done) { + it('should return 422 with a chunk with an invalid rename', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/6/history`) .reply(200, { @@ -643,21 +576,15 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { statusCode } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 5, - 6, - (error, diff, statusCode) => { - if (error != null) { - throw error - } - expect(statusCode).to.equal(422) - return done() - } + 6 ) + expect(statusCode).to.equal(422) }) - it('should return 200 with a chunk with an invalid add', function (done) { + it('should return 200 with a chunk with an invalid add', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/6/history`) .reply(200, { @@ -691,30 +618,24 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff, statusCode } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 5, - 6, - (error, diff, statusCode) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - pathname: 'foo.tex', - operation: 'added', - editable: null, - }, - ], - }) - expect(statusCode).to.equal(200) - return done() - } + 6 ) + expect(diff).to.deep.equal({ + diff: [ + { + pathname: 'foo.tex', + operation: 'added', + editable: null, + }, + ], + }) + expect(statusCode).to.equal(200) }) - it('should handle edits of missing/invalid files ', function (done) { + it('should handle edits of missing/invalid files ', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -751,28 +672,22 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [ - { - operation: 'edited', - pathname: 'new.tex', - }, - ], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [ + { + operation: 'edited', + pathname: 'new.tex', + }, + ], + }) }) - it('should handle deletions of missing/invalid files ', function (done) { + it('should handle deletions of missing/invalid files ', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -809,23 +724,17 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [], + }) }) - return it('should handle renames of missing/invalid files ', function (done) { + return it('should handle renames of missing/invalid files ', async function () { MockHistoryStore() .get(`/api/projects/${this.historyId}/versions/5/history`) .reply(200, { @@ -862,19 +771,13 @@ describe('FileTree Diffs', function () { authors: [{ id: 31, email: 'james.allen@overleaf.com', name: 'James' }], }) - return ProjectHistoryClient.getFileTreeDiff( + const { diff } = await ProjectHistoryClient.getFileTreeDiff( this.projectId, 3, - 5, - (error, diff) => { - if (error != null) { - throw error - } - expect(diff).to.deep.equal({ - diff: [], - }) - return done() - } + 5 ) + expect(diff).to.deep.equal({ + diff: [], + }) }) }) diff --git a/services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js b/services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js index 01e2c5952a..44cc1ea427 100644 --- a/services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js +++ b/services/project-history/test/acceptance/js/helpers/ProjectHistoryClient.js @@ -4,7 +4,11 @@ import Settings from '@overleaf/settings' import RedisWrapper from '@overleaf/redis-wrapper' import { db } from '../../../../app/js/mongodb.js' import { promisify } from '@overleaf/promise-utils' -import { fetchJsonWithResponse, fetchNothing } from '@overleaf/fetch-utils' +import { + fetchJsonWithResponse, + fetchNothing, + RequestFailedError, +} from '@overleaf/fetch-utils' const rclient = RedisWrapper.createClient(Settings.redis.project_history) const Keys = Settings.redis.project_history.key_schema @@ -81,23 +85,22 @@ export async function getDiff(projectId, pathname, from, to) { return json } -export function getFileTreeDiff(projectId, from, to, callback) { - request.get( - { - url: `http://127.0.0.1:3054/project/${projectId}/filetree/diff`, - qs: { - from, - to, - }, - json: true, - }, - (error, res, body) => { - if (error) { - return callback(error) - } - callback(error, body, res.statusCode) - } +export async function getFileTreeDiff(projectId, from, to) { + const url = new URL( + `http://127.0.0.1:3054/project/${projectId}/filetree/diff` ) + url.searchParams.set('from', from) + url.searchParams.set('to', to) + + try { + const { response, json } = await fetchJsonWithResponse(url.toString()) + return { diff: json, statusCode: response.status } + } catch (error) { + if (error instanceof RequestFailedError) { + return { diff: null, statusCode: error.response.status } + } + throw error + } } export function getChangesInChunkSince(projectId, since, options, callback) {