Просмотр исходного кода

Merge branch 'imprv/refacter-recursively' into imprv/create-duplicateTags-test

zahmis 5 лет назад
Родитель
Сommit
193176bc5d
2 измененных файлов с 159 добавлено и 12 удалено
  1. 8 1
      src/server/service/page.js
  2. 151 11
      src/test/service/page.test.js

+ 8 - 1
src/server/service/page.js

@@ -95,9 +95,12 @@ class PageService {
     const unorderedBulkOp = pageCollection.initializeUnorderedBulkOp();
     const unorderedBulkOp = pageCollection.initializeUnorderedBulkOp();
     const createRediectPageBulkOp = pageCollection.initializeUnorderedBulkOp();
     const createRediectPageBulkOp = pageCollection.initializeUnorderedBulkOp();
     const revisionUnorderedBulkOp = revisionCollection.initializeUnorderedBulkOp();
     const revisionUnorderedBulkOp = revisionCollection.initializeUnorderedBulkOp();
+    const createRediectRevisionBulkOp = revisionCollection.initializeUnorderedBulkOp();
 
 
     pages.forEach((page) => {
     pages.forEach((page) => {
       const newPagePath = page.path.replace(oldPagePathPrefix, newPagePathPrefix);
       const newPagePath = page.path.replace(oldPagePathPrefix, newPagePathPrefix);
+      const revisionId = new mongoose.Types.ObjectId();
+
       if (updateMetadata) {
       if (updateMetadata) {
         unorderedBulkOp.find({ _id: page._id }).update([{ $set: { path: newPagePath, lastUpdateUser: user._id, updatedAt: { $toDate: Date.now() } } }]);
         unorderedBulkOp.find({ _id: page._id }).update([{ $set: { path: newPagePath, lastUpdateUser: user._id, updatedAt: { $toDate: Date.now() } } }]);
       }
       }
@@ -106,7 +109,10 @@ class PageService {
       }
       }
       if (createRedirectPage) {
       if (createRedirectPage) {
         createRediectPageBulkOp.insert({
         createRediectPageBulkOp.insert({
-          path: page.path, body: `redirect ${newPagePath}`, creator: user._id, lastUpdateUser: user._id, status: Page.STATUS_PUBLISHED, redirectTo: newPagePath,
+          path: page.path, revision: revisionId, creator: user._id, lastUpdateUser: user._id, status: Page.STATUS_PUBLISHED, redirectTo: newPagePath,
+        });
+        createRediectRevisionBulkOp.insert({
+          _id: revisionId, path: page.path, body: `redirect ${newPagePath}`, author: user._id, format: 'markdown',
         });
         });
       }
       }
       revisionUnorderedBulkOp.find({ path: page.path }).update({ $set: { path: newPagePath } }, { multi: true });
       revisionUnorderedBulkOp.find({ path: page.path }).update({ $set: { path: newPagePath } }, { multi: true });
@@ -118,6 +124,7 @@ class PageService {
       // Execute after unorderedBulkOp to prevent duplication
       // Execute after unorderedBulkOp to prevent duplication
       if (createRedirectPage) {
       if (createRedirectPage) {
         await createRediectPageBulkOp.execute();
         await createRediectPageBulkOp.execute();
+        await createRediectRevisionBulkOp.execute();
       }
       }
     }
     }
     catch (err) {
     catch (err) {

+ 151 - 11
src/test/service/page.test.js

@@ -13,12 +13,17 @@ let parentForRename2;
 let parentForRename3;
 let parentForRename3;
 let parentForRename4;
 let parentForRename4;
 
 
+let childForRename1;
+let childForRename2;
+let childForRename3;
+
 let parentForDuplicate;
 let parentForDuplicate;
 let parentForDelete;
 let parentForDelete;
 let parentForDeleteCompletely;
 let parentForDeleteCompletely;
-let parentForRevert;
 
 
-let childForRename;
+let parentForRevert1;
+let parentForRevert2;
+
 let childForDuplicate;
 let childForDuplicate;
 let childForDelete;
 let childForDelete;
 let childForDeleteCompletely;
 let childForDeleteCompletely;
@@ -82,6 +87,18 @@ describe('PageService', () => {
         creator: testUser1,
         creator: testUser1,
         lastUpdateUser: testUser1,
         lastUpdateUser: testUser1,
       },
       },
+      {
+        path: '/parentForRename2/child',
+        grant: Page.GRANT_PUBLIC,
+        creator: testUser1,
+        lastUpdateUser: testUser1,
+      },
+      {
+        path: '/parentForRename3/child',
+        grant: Page.GRANT_PUBLIC,
+        creator: testUser1,
+        lastUpdateUser: testUser1,
+      },
       {
       {
         path: '/parentForDuplicate',
         path: '/parentForDuplicate',
         grant: Page.GRANT_PUBLIC,
         grant: Page.GRANT_PUBLIC,
@@ -120,13 +137,22 @@ describe('PageService', () => {
         lastUpdateUser: testUser1,
         lastUpdateUser: testUser1,
       },
       },
       {
       {
-        path: '/parentForRevert',
+        path: '/trash/parentForRevert1',
+        status: Page.STATUS_DELETED,
         grant: Page.GRANT_PUBLIC,
         grant: Page.GRANT_PUBLIC,
         creator: testUser1,
         creator: testUser1,
         lastUpdateUser: testUser1,
         lastUpdateUser: testUser1,
       },
       },
       {
       {
-        path: '/parentForRevert/child',
+        path: '/trash/parentForRevert2',
+        status: Page.STATUS_DELETED,
+        grant: Page.GRANT_PUBLIC,
+        creator: testUser1,
+        lastUpdateUser: testUser1,
+      },
+      {
+        path: '/trash/parentForRevert/child',
+        status: Page.STATUS_DELETED,
         grant: Page.GRANT_PUBLIC,
         grant: Page.GRANT_PUBLIC,
         creator: testUser1,
         creator: testUser1,
         lastUpdateUser: testUser1,
         lastUpdateUser: testUser1,
@@ -137,16 +163,21 @@ describe('PageService', () => {
     parentForRename2 = await Page.findOne({ path: '/parentForRename2' });
     parentForRename2 = await Page.findOne({ path: '/parentForRename2' });
     parentForRename3 = await Page.findOne({ path: '/parentForRename3' });
     parentForRename3 = await Page.findOne({ path: '/parentForRename3' });
     parentForRename4 = await Page.findOne({ path: '/parentForRename4' });
     parentForRename4 = await Page.findOne({ path: '/parentForRename4' });
+
     parentForDuplicate = await Page.findOne({ path: '/parentForDuplicate' });
     parentForDuplicate = await Page.findOne({ path: '/parentForDuplicate' });
     parentForDelete = await Page.findOne({ path: '/parentForDelete' });
     parentForDelete = await Page.findOne({ path: '/parentForDelete' });
     parentForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely' });
     parentForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely' });
-    parentForRevert = await Page.findOne({ path: '/parentForRevert' });
+    parentForRevert1 = await Page.findOne({ path: '/trash/parentForRevert1' });
+    parentForRevert2 = await Page.findOne({ path: '/trash/parentForRevert2' });
+
+    childForRename1 = await Page.findOne({ path: '/parentForRename1/child' });
+    childForRename2 = await Page.findOne({ path: '/parentForRename2/child' });
+    childForRename3 = await Page.findOne({ path: '/parentForRename3/child' });
 
 
-    childForRename = await Page.findOne({ path: '/parentForRename1/child' });
     childForDuplicate = await Page.findOne({ path: '/parentForDuplicate/child' });
     childForDuplicate = await Page.findOne({ path: '/parentForDuplicate/child' });
     childForDelete = await Page.findOne({ path: '/parentForDelete/child' });
     childForDelete = await Page.findOne({ path: '/parentForDelete/child' });
     childForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely/child' });
     childForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely/child' });
-    childForRevert = await Page.findOne({ path: '/parentForRevert/child' });
+    childForRevert = await Page.findOne({ path: '/trash/parentForRevert/child' });
 
 
 
 
     await Tag.insertMany([
     await Tag.insertMany([
@@ -274,8 +305,69 @@ describe('PageService', () => {
 
 
     });
     });
 
 
-    test('renameDescendants()', () => {
-      expect(3).toBe(3);
+    test('renameDescendants without options', async() => {
+      const oldPagePathPrefix = new RegExp('^/parentForRename1', 'i');
+      const newPagePathPrefix = '/renamed1';
+
+      await crowi.pageService.renameDescendants([childForRename1], testUser2, {}, oldPagePathPrefix, newPagePathPrefix);
+      const resultPage = await Page.findOne({ path: '/renamed1/child' });
+      const redirectedFromPage = await Page.findOne({ path: '/parentForRename1/child' });
+      const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename1/child' });
+
+      expect(resultPage).not.toBeNull();
+      expect(pageEventSpy).toHaveBeenCalledWith('updateMany', [childForRename1], testUser2);
+
+      expect(resultPage.path).toBe('/renamed1/child');
+      expect(resultPage.updatedAt).toEqual(childForRename1.updatedAt);
+      expect(resultPage.lastUpdateUser).toEqual(testUser1._id);
+
+      expect(redirectedFromPage).toBeNull();
+      expect(redirectedFromPageRevision).toBeNull();
+    });
+
+    test('renameDescendants with updateMetadata option', async() => {
+      const oldPagePathPrefix = new RegExp('^/parentForRename2', 'i');
+      const newPagePathPrefix = '/renamed2';
+
+      await crowi.pageService.renameDescendants([childForRename2], testUser2, { updateMetadata: true }, oldPagePathPrefix, newPagePathPrefix);
+      const resultPage = await Page.findOne({ path: '/renamed2/child' });
+      const redirectedFromPage = await Page.findOne({ path: '/parentForRename2/child' });
+      const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename2/child' });
+
+      expect(resultPage).not.toBeNull();
+      expect(pageEventSpy).toHaveBeenCalledWith('updateMany', [childForRename2], testUser2);
+
+      expect(resultPage.path).toBe('/renamed2/child');
+      expect(resultPage.updatedAt).toEqual(dateToUse);
+      expect(resultPage.lastUpdateUser).toEqual(testUser2._id);
+
+      expect(redirectedFromPage).toBeNull();
+      expect(redirectedFromPageRevision).toBeNull();
+    });
+
+    test('renameDescendants with createRedirectPage option', async() => {
+      const oldPagePathPrefix = new RegExp('^/parentForRename3', 'i');
+      const newPagePathPrefix = '/renamed3';
+
+      await crowi.pageService.renameDescendants([childForRename3], testUser2, { createRedirectPage: true }, oldPagePathPrefix, newPagePathPrefix);
+      const resultPage = await Page.findOne({ path: '/renamed3/child' });
+      const redirectedFromPage = await Page.findOne({ path: '/parentForRename3/child' });
+      const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename3/child' });
+
+      expect(resultPage).not.toBeNull();
+      expect(pageEventSpy).toHaveBeenCalledWith('updateMany', [childForRename3], testUser2);
+
+      expect(resultPage.path).toBe('/renamed3/child');
+      expect(resultPage.updatedAt).toEqual(childForRename3.updatedAt);
+      expect(resultPage.lastUpdateUser).toEqual(testUser1._id);
+
+      expect(redirectedFromPage).not.toBeNull();
+      expect(redirectedFromPage.path).toBe('/parentForRename3/child');
+      expect(redirectedFromPage.redirectTo).toBe('/renamed3/child');
+
+      expect(redirectedFromPageRevision).not.toBeNull();
+      expect(redirectedFromPageRevision.path).toBe('/parentForRename3/child');
+      expect(redirectedFromPageRevision.body).toBe('redirect /renamed3/child');
     });
     });
   });
   });
 
 
@@ -383,8 +475,56 @@ describe('PageService', () => {
   });
   });
 
 
   describe('revert page', () => {
   describe('revert page', () => {
-    test('revertDeletedPage()', () => {
-      expect(3).toBe(3);
+    let getRevertDeletedPageNameSpy;
+    let findByPathSpy;
+    let deleteCompletelySpy;
+    let revertDeletedDescendantsWithStreamSpy;
+
+    beforeEach(async(done) => {
+      getRevertDeletedPageNameSpy = jest.spyOn(Page, 'getRevertDeletedPageName');
+      deleteCompletelySpy = jest.spyOn(crowi.pageService, 'deleteCompletely').mockImplementation();
+      revertDeletedDescendantsWithStreamSpy = jest.spyOn(crowi.pageService, 'revertDeletedDescendantsWithStream').mockImplementation();
+      done();
+    });
+
+    test('revert deleted page when the redirect from page exists', async() => {
+
+      findByPathSpy = jest.spyOn(Page, 'findByPath').mockImplementation(() => {
+        return { redirectTo: '/trash/parentForRevert1' };
+      });
+
+      const resultPage = await crowi.pageService.revertDeletedPage(parentForRevert1, testUser2);
+
+      expect(getRevertDeletedPageNameSpy).toHaveBeenCalledWith(parentForRevert1.path);
+      expect(findByPathSpy).toHaveBeenCalledWith('/parentForRevert1');
+      expect(deleteCompletelySpy).toHaveBeenCalled();
+      expect(revertDeletedDescendantsWithStreamSpy).not.toHaveBeenCalled();
+
+      expect(resultPage.path).toBe('/parentForRevert1');
+      expect(resultPage.lastUpdateUser._id).toEqual(testUser2._id);
+      expect(resultPage.status).toBe(Page.STATUS_PUBLISHED);
+      expect(resultPage.deleteUser).toBeNull();
+      expect(resultPage.deletedAt).toBeNull();
+    });
+
+    test('revert deleted page when the redirect from page does not exist', async() => {
+
+      findByPathSpy = jest.spyOn(Page, 'findByPath').mockImplementation(() => {
+        return null;
+      });
+
+      const resultPage = await crowi.pageService.revertDeletedPage(parentForRevert2, testUser2, {}, true);
+
+      expect(getRevertDeletedPageNameSpy).toHaveBeenCalledWith(parentForRevert2.path);
+      expect(findByPathSpy).toHaveBeenCalledWith('/parentForRevert2');
+      expect(deleteCompletelySpy).not.toHaveBeenCalled();
+      expect(revertDeletedDescendantsWithStreamSpy).toHaveBeenCalled();
+
+      expect(resultPage.path).toBe('/parentForRevert2');
+      expect(resultPage.lastUpdateUser._id).toEqual(testUser2._id);
+      expect(resultPage.status).toBe(Page.STATUS_PUBLISHED);
+      expect(resultPage.deleteUser).toBeNull();
+      expect(resultPage.deletedAt).toBeNull();
     });
     });
 
 
     test('revertDeletedPages()', () => {
     test('revertDeletedPages()', () => {