Browse Source

impl retrievePageRedirectChains

Yuki Takei 3 years ago
parent
commit
08ecaf6d58

+ 24 - 0
packages/app/src/server/models/page-redirect.ts

@@ -6,6 +6,11 @@ import {
 
 import { getOrCreateModel } from '../util/mongoose-utils';
 
+export interface IPageRedirectChains {
+  start: IPageRedirect,
+  end: IPageRedirect,
+}
+
 export interface IPageRedirect {
   fromPath: string,
   toPath: string,
@@ -14,6 +19,7 @@ export interface IPageRedirect {
 export interface PageRedirectDocument extends IPageRedirect, Document {}
 
 export interface PageRedirectModel extends Model<PageRedirectDocument> {
+  retrievePageRedirectChains(fromPath: string, storedChains?: IPageRedirectChains): Promise<IPageRedirectChains>
   removePageRedirectByToPath(toPath: string): Promise<void>
 }
 
@@ -24,10 +30,28 @@ const schema = new Schema<PageRedirectDocument, PageRedirectModel>({
   toPath: { type: String, required: true },
 });
 
+schema.statics.retrievePageRedirectChains = async function(fromPath: string, storedChains?: IPageRedirectChains): Promise<IPageRedirectChains|null> {
+  const chainedRedirect = await this.findOne({ fromPath });
+
+  if (chainedRedirect == null) {
+    return storedChains ?? null;
+  }
+
+  const chains = storedChains ?? { start: chainedRedirect, end: chainedRedirect };
+  chains.end = chainedRedirect;
+
+  // find the end recursively
+  return this.retrievePageRedirectChains(chainedRedirect.toPath, chains);
+};
+
 schema.statics.removePageRedirectByToPath = async function(toPath: string): Promise<void> {
   await this.deleteMany({ toPath });
 
   return;
 };
 
+// schema.statics.removePageRedirectsByChains = async function(redirectChains: IPageRedirectChains): Promise<void> {
+//   return;
+// };
+
 export default getOrCreateModel<PageRedirectDocument, PageRedirectModel>('PageRedirect', schema);

+ 36 - 20
packages/app/test/integration/models/page-redirect.test.js

@@ -8,46 +8,35 @@ describe('PageRedirect', () => {
   let crowi;
   let PageRedirect;
 
-  let redirect1;
-  let redirect2;
-  let redirect3;
-
   beforeAll(async() => {
     crowi = await getInstance();
 
     PageRedirect = mongoose.model('PageRedirect');
-
-    await PageRedirect.insertMany([
-      { fromPath: '/org/path1', toPath: '/path1' },
-      { fromPath: '/org/path2', toPath: '/path2' },
-      { fromPath: '/org/path3', toPath: '/path3' },
-    ]);
-
-    redirect1 = await PageRedirect.findOne({ fromPath: '/org/path1' });
-    redirect2 = await PageRedirect.findOne({ fromPath: '/org/path2' });
-    redirect3 = await PageRedirect.findOne({ fromPath: '/org/path3' });
   });
 
   describe('.removePageRedirectByToPath', () => {
     test('works fine', async() => {
-      expect(redirect1).not.toBeNull();
-      expect(redirect2).not.toBeNull();
-      expect(redirect3).not.toBeNull();
-
-      // add document for this test
+      // setup:
       await PageRedirect.insertMany([
+        { fromPath: '/org/path1', toPath: '/path1' },
+        { fromPath: '/org/path2', toPath: '/path2' },
+        { fromPath: '/org/path3', toPath: '/path3' },
         { fromPath: '/org/path33', toPath: '/path3' },
       ]);
+      expect(await PageRedirect.findOne({ fromPath: '/org/path1' })).not.toBeNull();
+      expect(await PageRedirect.findOne({ fromPath: '/org/path2' })).not.toBeNull();
+      expect(await PageRedirect.findOne({ fromPath: '/org/path3' })).not.toBeNull();
       expect(await PageRedirect.findOne({ fromPath: '/org/path33' })).not.toBeNull();
 
+      // when:
       // remove all documents that have { toPath: '/path/3' }
       await PageRedirect.removePageRedirectByToPath('/path3');
 
+      // then:
       const r1 = await PageRedirect.findOne({ fromPath: '/org/path1' });
       const r2 = await PageRedirect.findOne({ fromPath: '/org/path2' });
       const r3 = await PageRedirect.findOne({ fromPath: '/org/path3' });
       const r4 = await PageRedirect.findOne({ fromPath: '/org/path33' });
-
       expect(r1).not.toBeNull();
       expect(r2).not.toBeNull();
       expect(r3).toBeNull();
@@ -55,4 +44,31 @@ describe('PageRedirect', () => {
     });
   });
 
+  describe('.retrievePageRedirectChains', () => {
+    test('shoud return IPageRedirectChains', async() => {
+      // setup:
+      await PageRedirect.insertMany([
+        { fromPath: '/path1', toPath: '/path2' },
+        { fromPath: '/path2', toPath: '/path3' },
+        { fromPath: '/path3', toPath: '/path4' },
+      ]);
+      expect(await PageRedirect.findOne({ fromPath: '/path1' })).not.toBeNull();
+      expect(await PageRedirect.findOne({ fromPath: '/path2' })).not.toBeNull();
+      expect(await PageRedirect.findOne({ fromPath: '/path3' })).not.toBeNull();
+
+      // when:
+      // retrieve
+      const chains = await PageRedirect.retrievePageRedirectChains('/path1');
+
+      // then:
+      expect(chains).not.toBeNull();
+      expect(chains.start).not.toBeNull();
+      expect(chains.start.fromPath).toEqual('/path1');
+      expect(chains.start.toPath).toEqual('/path2');
+      expect(chains.end).not.toBeNull();
+      expect(chains.end.fromPath).toEqual('/path3');
+      expect(chains.end.toPath).toEqual('/path4');
+    });
+  });
+
 });