diff --git a/services/project-history/app/js/ChunkTranslator.js b/services/project-history/app/js/ChunkTranslator.js index 90843d3929..544db19ef8 100644 --- a/services/project-history/app/js/ChunkTranslator.js +++ b/services/project-history/app/js/ChunkTranslator.js @@ -49,13 +49,14 @@ export function convertToDiffUpdates( let file = null for (const change of chunk.chunk.history.changes) { // Because we're referencing by pathname, which can change, we - // want to get the first file in the range fromVersion:toVersion + // want to get the last file in the range fromVersion:toVersion // that has the pathname we want. Note that this might not exist yet - // at fromVersion, so we'll just settle for the first one we find + // at fromVersion, so we'll just settle for the last existing one we find // after that. if (fromVersion <= version && version <= toVersion) { - if (file == null) { - file = builder.getFile(pathname) + const currentFile = builder.getFile(pathname) + if (currentFile) { + file = currentFile } } @@ -70,8 +71,9 @@ export function convertToDiffUpdates( // Versions act as fence posts, with updates taking us from one to another, // so we also need to check after the final update, when we're at the last version. if (fromVersion <= version && version <= toVersion) { - if (file == null) { - file = builder.getFile(pathname) + const currentFile = builder.getFile(pathname) + if (currentFile) { + file = currentFile } } diff --git a/services/project-history/test/unit/js/ChunkTranslator/ChunkTranslatorTests.js b/services/project-history/test/unit/js/ChunkTranslator/ChunkTranslatorTests.js index fa451ce807..e4b32c4c02 100644 --- a/services/project-history/test/unit/js/ChunkTranslator/ChunkTranslatorTests.js +++ b/services/project-history/test/unit/js/ChunkTranslator/ChunkTranslatorTests.js @@ -72,6 +72,51 @@ describe('ChunkTranslator', function () { timestamp: this.date.toISOString(), authors: [this.author1.id], }, + { + origin: { + kind: 'file-restore', + version: 1, + path: 'main.tex', + timestamp: this.date.toISOString(), + }, + operations: [ + { + pathname: 'main.tex', + newPathname: '', + }, + ], + timestamp: this.date.toISOString(), + authors: [this.author1.id], + }, + { + origin: { + kind: 'file-restore', + version: 1, + path: 'main.tex', + timestamp: this.date.toISOString(), + }, + operations: [ + { + pathname: 'main.tex', + file: { + hash: this.fileHash, + stringLength: 42, + }, + }, + ], + timestamp: this.date.toISOString(), + authors: [this.author1.id], + }, + { + operations: [ + { + pathname: 'main.tex', + newPathname: 'main2.tex', + }, + ], + timestamp: this.date.toISOString(), + authors: [this.author1.id], + }, ], }, }, @@ -162,6 +207,38 @@ describe('ChunkTranslator', function () { } ) }) + + it('should return the correct initial text in case of file restore', function (done) { + this.ChunkTranslator.convertToDiffUpdates( + this.projectId, + this.chunk, + 'main.tex', + 3, + 5, + (error, param) => { + const { initialContent } = param + expect(error).to.be.null + expect(initialContent).to.equal('Hello world, this is a test') + done() + } + ) + }) + + it('should still find original file in case it was renamed', function (done) { + this.ChunkTranslator.convertToDiffUpdates( + this.projectId, + this.chunk, + 'main.tex', + 5, + 6, + (error, param) => { + const { initialContent } = param + expect(error).to.be.null + expect(initialContent).to.equal('Hello world, this is a test') + done() + } + ) + }) }) describe('convertToSummarizedUpdates', function () { @@ -200,6 +277,67 @@ describe('ChunkTranslator', function () { }, v: 2, }, + { + pathnames: [], + project_ops: [ + { + remove: { + pathname: 'main.tex', + }, + }, + ], + meta: { + users: [this.author1.id], + start_ts: this.date.getTime(), + end_ts: this.date.getTime(), + origin: { + kind: 'file-restore', + version: 1, + path: 'main.tex', + timestamp: this.date.toISOString(), + }, + }, + v: 3, + }, + { + pathnames: [], + project_ops: [ + { + add: { + pathname: 'main.tex', + }, + }, + ], + meta: { + users: [this.author1.id], + start_ts: this.date.getTime(), + end_ts: this.date.getTime(), + origin: { + kind: 'file-restore', + version: 1, + path: 'main.tex', + timestamp: this.date.toISOString(), + }, + }, + v: 4, + }, + { + pathnames: [], + project_ops: [ + { + rename: { + pathname: 'main.tex', + newPathname: 'main2.tex', + }, + }, + ], + meta: { + users: [this.author1.id], + start_ts: this.date.getTime(), + end_ts: this.date.getTime(), + }, + v: 5, + }, ]) done() }