Ver código fonte

Merge pull request #23274 from overleaf/mj-restore-main-history

[web] Restore main documents with metadata as docs

GitOrigin-RevId: f3664689704e9098c2b9e317d65e4ab2633320cb
Mathias Jakobsen 1 ano atrás
pai
commit
67f3c468a1

+ 4 - 1
services/web/app/src/Features/History/RestoreManager.js

@@ -121,9 +121,12 @@ const RestoreManager = {
       pathname
     )
 
+    // Look for metadata indicating a linked file.
+    const isFileMetadata = metadata && 'provider' in metadata
+
     logger.debug({ metadata }, 'metadata from history')
 
-    if (importInfo.type === 'file' || metadata) {
+    if (importInfo.type === 'file' || isFileMetadata) {
       const newFile = await EditorController.promises.upsertFile(
         projectId,
         parentFolderId,

+ 161 - 96
services/web/test/unit/src/History/RestoreManagerTests.js

@@ -500,14 +500,10 @@ describe('RestoreManager', function () {
       })
     })
 
-    describe('reverting a document with metadata', function () {
-      beforeEach(async function () {
-        this.pathname = 'foo.tex'
+    describe('reverting a file or document with metadata', function () {
+      beforeEach(function () {
         this.ProjectLocator.promises.findElementByPath = sinon.stub().rejects()
         this.EditorController.promises.addDocWithRanges = sinon.stub()
-        this.FileSystemImportManager.promises.importFile = sinon
-          .stub()
-          .resolves({ type: 'doc', lines: ['foo', 'bar', 'baz'] })
         this.RestoreManager.promises._getUpdatesFromHistory = sinon
           .stub()
           .resolves([
@@ -517,110 +513,179 @@ describe('RestoreManager', function () {
         this.EditorController.promises.upsertFile = sinon
           .stub()
           .resolves({ _id: 'mock-file-id', type: 'file' })
-        this.RestoreManager.promises._getMetadataFromHistory = sinon
+        this.RestoreManager.promises._getRangesFromHistory = sinon
           .stub()
-          .resolves({ metadata: { foo: 'bar' } })
-        this.result = await this.RestoreManager.promises.revertFile(
-          this.user_id,
-          this.project_id,
-          this.version,
-          this.pathname
-        )
-      })
+          .resolves({
+            changes: [],
+            comments: [],
+          })
+        this.EditorController.promises.addDocWithRanges = sinon
+          .stub()
+          .resolves((this.addedFile = { _id: 'mock-doc-id', type: 'doc' }))
 
-      it('should revert it as a file', function () {
-        expect(this.result).to.deep.equal({ _id: 'mock-file-id', type: 'file' })
+        this.DocstoreManager.promises.getAllRanges = sinon.stub().resolves([])
+        this.ChatApiHandler.promises.generateThreadData = sinon
+          .stub()
+          .resolves({})
+        this.ChatManager.promises.injectUserInfoIntoThreads = sinon
+          .stub()
+          .resolves({})
+        this.EditorRealTimeController.emitToRoom = sinon.stub()
       })
 
-      it('should upload to the project as a file', function () {
-        expect(
-          this.EditorController.promises.upsertFile
-        ).to.have.been.calledWith(
-          this.project_id,
-          'mock-folder-id',
-          'foo.tex',
-          this.fsPath,
-          { foo: 'bar' },
-          {
-            kind: 'file-restore',
-            path: this.pathname,
-            version: this.version,
-            timestamp: new Date(this.endTs).toISOString(),
-          },
-          this.user_id
-        )
-      })
+      describe('when reverting a linked file', function () {
+        beforeEach(async function () {
+          this.pathname = 'foo.png'
+          this.FileSystemImportManager.promises.importFile = sinon
+            .stub()
+            .resolves({ type: 'file' })
+          this.RestoreManager.promises._getMetadataFromHistory = sinon
+            .stub()
+            .resolves({ metadata: { provider: 'bar' } })
+          this.result = await this.RestoreManager.promises.revertFile(
+            this.user_id,
+            this.project_id,
+            this.version,
+            this.pathname
+          )
+        })
 
-      it('should not look up ranges', function () {
-        expect(this.RestoreManager.promises._getRangesFromHistory).to.not.have
-          .been.called
-      })
+        it('should revert it as a file', function () {
+          expect(this.result).to.deep.equal({
+            _id: 'mock-file-id',
+            type: 'file',
+          })
+        })
 
-      it('should not try to add a file', function () {
-        expect(this.EditorController.promises.addDocWithRanges).to.not.have.been
-          .called
-      })
-    })
+        it('should upload to the project as a file', function () {
+          expect(
+            this.EditorController.promises.upsertFile
+          ).to.have.been.calledWith(
+            this.project_id,
+            'mock-folder-id',
+            'foo.png',
+            this.fsPath,
+            { provider: 'bar' },
+            {
+              kind: 'file-restore',
+              path: this.pathname,
+              version: this.version,
+              timestamp: new Date(this.endTs).toISOString(),
+            },
+            this.user_id
+          )
+        })
 
-    describe('reverting a file with metadata', function () {
-      beforeEach(async function () {
-        this.pathname = 'foo.png'
-        this.ProjectLocator.promises.findElementByPath = sinon.stub().rejects()
-        this.EditorController.promises.addDocWithRanges = sinon.stub()
-        this.FileSystemImportManager.promises.importFile = sinon
-          .stub()
-          .resolves({ type: 'file' })
-        this.RestoreManager.promises._getUpdatesFromHistory = sinon
-          .stub()
-          .resolves([
-            { toV: this.version, meta: { end_ts: (this.endTs = new Date()) } },
-          ])
+        it('should not look up ranges', function () {
+          expect(this.RestoreManager.promises._getRangesFromHistory).to.not.have
+            .been.called
+        })
 
-        this.EditorController.promises.upsertFile = sinon
-          .stub()
-          .resolves({ _id: 'mock-file-id', type: 'file' })
-        this.RestoreManager.promises._getMetadataFromHistory = sinon
-          .stub()
-          .resolves({ metadata: { foo: 'bar' } })
-        this.result = await this.RestoreManager.promises.revertFile(
-          this.user_id,
-          this.project_id,
-          this.version,
-          this.pathname
-        )
+        it('should not try to add a document', function () {
+          expect(this.EditorController.promises.addDocWithRanges).to.not.have
+            .been.called
+        })
       })
 
-      it('should revert it as a file', function () {
-        expect(this.result).to.deep.equal({ _id: 'mock-file-id', type: 'file' })
-      })
+      describe('when reverting a linked document with provider', function () {
+        beforeEach(async function () {
+          this.pathname = 'foo.tex'
+          this.FileSystemImportManager.promises.importFile = sinon
+            .stub()
+            .resolves({ type: 'doc', lines: ['foo', 'bar', 'baz'] })
+          this.RestoreManager.promises._getMetadataFromHistory = sinon
+            .stub()
+            .resolves({ metadata: { provider: 'bar' } })
+          this.result = await this.RestoreManager.promises.revertFile(
+            this.user_id,
+            this.project_id,
+            this.version,
+            this.pathname
+          )
+        })
 
-      it('should upload to the project as a file', function () {
-        expect(
-          this.EditorController.promises.upsertFile
-        ).to.have.been.calledWith(
-          this.project_id,
-          'mock-folder-id',
-          'foo.png',
-          this.fsPath,
-          { foo: 'bar' },
-          {
-            kind: 'file-restore',
-            path: this.pathname,
-            version: this.version,
-            timestamp: new Date(this.endTs).toISOString(),
-          },
-          this.user_id
-        )
-      })
+        it('should revert it as a file', function () {
+          expect(this.result).to.deep.equal({
+            _id: 'mock-file-id',
+            type: 'file',
+          })
+        })
+
+        it('should upload to the project as a file', function () {
+          expect(
+            this.EditorController.promises.upsertFile
+          ).to.have.been.calledWith(
+            this.project_id,
+            'mock-folder-id',
+            'foo.tex',
+            this.fsPath,
+            { provider: 'bar' },
+            {
+              kind: 'file-restore',
+              path: this.pathname,
+              version: this.version,
+              timestamp: new Date(this.endTs).toISOString(),
+            },
+            this.user_id
+          )
+        })
+
+        it('should not look up ranges', function () {
+          expect(this.RestoreManager.promises._getRangesFromHistory).to.not.have
+            .been.called
+        })
 
-      it('should not look up ranges', function () {
-        expect(this.RestoreManager.promises._getRangesFromHistory).to.not.have
-          .been.called
+        it('should not try to add a document', function () {
+          expect(this.EditorController.promises.addDocWithRanges).to.not.have
+            .been.called
+        })
       })
 
-      it('should not try to add a file', function () {
-        expect(this.EditorController.promises.addDocWithRanges).to.not.have.been
-          .called
+      describe('when reverting a linked document with { main: true }', function () {
+        beforeEach(async function () {
+          this.pathname = 'foo.tex'
+          this.FileSystemImportManager.promises.importFile = sinon
+            .stub()
+            .resolves({ type: 'doc', lines: ['foo', 'bar', 'baz'] })
+          this.RestoreManager.promises._getMetadataFromHistory = sinon
+            .stub()
+            .resolves({ metadata: { main: true } })
+          this.result = await this.RestoreManager.promises.revertFile(
+            this.user_id,
+            this.project_id,
+            this.version,
+            this.pathname
+          )
+        })
+
+        it('should revert it as a document', function () {
+          expect(this.result).to.deep.equal({
+            _id: 'mock-doc-id',
+            type: 'doc',
+          })
+        })
+
+        it('should not upload to the project as a file', function () {
+          expect(this.EditorController.promises.upsertFile).to.not.have.been
+            .called
+        })
+
+        it('should look up ranges', function () {
+          expect(this.RestoreManager.promises._getRangesFromHistory).to.have
+            .been.called
+        })
+
+        it('should add the document', function () {
+          expect(
+            this.EditorController.promises.addDocWithRanges
+          ).to.have.been.calledWith(
+            this.project_id,
+            this.folder_id,
+            'foo.tex',
+            ['foo', 'bar', 'baz'],
+            { changes: [], comments: [] }
+          )
+        })
       })
     })