diff --git a/services/project-history/app/js/UpdateTranslator.js b/services/project-history/app/js/UpdateTranslator.js index f0ab6d943d..395787813a 100644 --- a/services/project-history/app/js/UpdateTranslator.js +++ b/services/project-history/app/js/UpdateTranslator.js @@ -73,9 +73,18 @@ function _convertToChange(projectId, updateWithBlob) { throw error } + let v2Authors + if (update.meta.user_id === 'anonymous-user') { + // history-v1 uses null to represent an anonymous author + v2Authors = [null] + } else { + // user_id is missing on resync operations that update the contents of a doc + v2Authors = _.compact([update.meta.user_id]) + } + const rawChange = { operations, - v2Authors: _.compact([update.meta.user_id]), + v2Authors, timestamp: new Date(update.meta.ts).toISOString(), projectVersion, v2DocVersions: Object.keys(v2DocVersions).length ? v2DocVersions : null, diff --git a/services/project-history/test/unit/js/UpdateTranslator/UpdateTranslatorTests.js b/services/project-history/test/unit/js/UpdateTranslator/UpdateTranslatorTests.js index 6ea3c47c6f..f18211b2d3 100644 --- a/services/project-history/test/unit/js/UpdateTranslator/UpdateTranslatorTests.js +++ b/services/project-history/test/unit/js/UpdateTranslator/UpdateTranslatorTests.js @@ -447,6 +447,91 @@ describe('UpdateTranslator', function () { ) }) + it('sets a null author when user_id is "anonymous-user"', function (done) { + const updates = [ + { + update: { + doc: this.doc_id, + pathname: '/main.tex', + docLines: 'a\nb', + meta: { + user_id: 'anonymous-user', + ts: this.timestamp, + }, + }, + blobHash: this.mockBlobHash, + }, + ] + const assertion = (error, changes) => { + changes = changes.map(change => change.toRaw()) + expect(error).to.be.null + expect(changes).to.deep.equal([ + { + authors: [], + operations: [ + { + pathname: 'main.tex', + file: { + hash: this.mockBlobHash, + }, + }, + ], + v2Authors: [null], + timestamp: this.timestamp, + }, + ]) + done() + } + + this.UpdateTranslator.convertToChanges( + this.project_id, + updates, + assertion + ) + }) + + it('sets an empty array as author when there is no meta.user_id', function (done) { + const updates = [ + { + update: { + doc: this.doc_id, + pathname: '/main.tex', + docLines: 'a\nb', + meta: { + ts: this.timestamp, + }, + }, + blobHash: this.mockBlobHash, + }, + ] + const assertion = (error, changes) => { + changes = changes.map(change => change.toRaw()) + expect(error).to.be.null + expect(changes).to.deep.equal([ + { + authors: [], + operations: [ + { + pathname: 'main.tex', + file: { + hash: this.mockBlobHash, + }, + }, + ], + v2Authors: [], + timestamp: this.timestamp, + }, + ]) + done() + } + + this.UpdateTranslator.convertToChanges( + this.project_id, + updates, + assertion + ) + }) + describe('text updates', function () { it('can translate insertions', function (done) { const updates = [