Repository: Yoctol/bottender
Pull request #449 (2019-09-24 17:39:32)

changed(mongo): modify MongoSession's signature and make it configurable
- use only one object instead of (string + object) to config `MongoSession`, so it can write into `bottender.config.js`


Patch:
diff --git a/packages/bottender/src/cli/shared/types.ts b/packages/bottender/src/cli/shared/types.ts
index cb48626b..02343856 100644
--- a/packages/bottender/src/cli/shared/types.ts
+++ b/packages/bottender/src/cli/shared/types.ts
@@ -18,21 +18,24 @@ export type BottenderConfig = {
   plugins?: any[];
   session?: {
     driver: SessionDriver;
-    expiresIn: number;
+    expiresIn?: number;
     stores: {
       memory: {
-        maxSize: number;
+        maxSize?: number;
       };
       file: {
-        dirname: string;
+        dirname?: string;
       };
       redis: {
-        port: number;
-        host: string;
-        password: string;
+        port?: number;
+        host?: string;
+        password?: string;
         db: number;
       };
-      mongo: {};
+      mongo: {
+        url: string;
+        collectionName?: string;
+      };
     };
   };
   initialState: Record<string, any>;
diff --git a/packages/bottender/src/session/MemorySessionStore.ts b/packages/bottender/src/session/MemorySessionStore.ts
index 55067e19..9df6c6e4 100644
--- a/packages/bottender/src/session/MemorySessionStore.ts
+++ b/packages/bottender/src/session/MemorySessionStore.ts
@@ -11,7 +11,7 @@ type MemoryOption =
       maxSize?: number;
     };
 
-function getMaxSize(arg: MemoryOption): number | undefined {
+function getMaxSize(arg?: MemoryOption): number | undefined {
   if (typeof arg === 'number') {
     return arg;
   }
@@ -26,7 +26,7 @@ function getMaxSize(arg: MemoryOption): number | undefined {
 
 export default class MemorySessionStore extends CacheBasedSessionStore
   implements SessionStore {
-  constructor(arg: MemoryOption, expiresIn?: number) {
+  constructor(arg?: MemoryOption, expiresIn?: number) {
     const maxSize = getMaxSize(arg);
 
     const cache = new MemoryCacheStore(maxSize);
diff --git a/packages/bottender/src/session/MongoSessionStore.ts b/packages/bottender/src/session/MongoSessionStore.ts
index 8f1e5051..85990db0 100644
--- a/packages/bottender/src/session/MongoSessionStore.ts
+++ b/packages/bottender/src/session/MongoSessionStore.ts
@@ -7,6 +7,13 @@ import SessionStore from './SessionStore';
 
 const MINUTES_IN_ONE_YEAR = 365 * 24 * 60;
 
+type MongoOption =
+  | string
+  | {
+      url: string;
+      collectionName?: string;
+    };
+
 export default class MongoSessionStore implements SessionStore {
   _url: string;
 
@@ -17,13 +24,14 @@ export default class MongoSessionStore implements SessionStore {
 
   _connection?: Db;
 
-  constructor(
-    url: string,
-    options: { collectionName?: string } = {},
-    expiresIn?: number
-  ) {
-    this._url = url;
-    this._collectionName = options.collectionName || 'sessions';
+  constructor(options: MongoOption, expiresIn?: number) {
+    if (typeof options === 'string') {
+      this._url = options;
+      this._collectionName = 'sessions';
+    } else {
+      this._url = options.url;
+      this._collectionName = options.collectionName || 'sessions';
+    }
     this._expiresIn = expiresIn || MINUTES_IN_ONE_YEAR;
   }
 
diff --git a/packages/create-bottender-app/src/utils/generateConfig.ts b/packages/create-bottender-app/src/utils/generateConfig.ts
index b2b330b2..8c0f0c03 100644
--- a/packages/create-bottender-app/src/utils/generateConfig.ts
+++ b/packages/create-bottender-app/src/utils/generateConfig.ts
@@ -19,7 +19,10 @@ const generateConfig = (
         password: 'auth',
         db: 0,
       },
-      mongo: {},
+      mongo: {
+        url: 'mongodb://localhost:27017',
+        collectionName: 'sessions',
+      },
     },
   },
   initialState: {},


Test patch:
diff --git a/packages/bottender/src/session/__tests__/FileSessionStore.spec.ts b/packages/bottender/src/session/__tests__/FileSessionStore.spec.ts
index fba3e65c..f39c92a0 100644
--- a/packages/bottender/src/session/__tests__/FileSessionStore.spec.ts
+++ b/packages/bottender/src/session/__tests__/FileSessionStore.spec.ts
@@ -17,7 +17,7 @@ function setup() {
   };
 }
 
-it('should be instanceof CacheBasedSessionStore', () => {
+it('should be instanceof FileSessionStore', () => {
   expect(new FileSessionStore('.session')).toBeInstanceOf(FileSessionStore);
   expect(new FileSessionStore({ dirname: '.session' })).toBeInstanceOf(
     FileSessionStore
diff --git a/packages/bottender/src/session/__tests__/MongoSessionStore.spec.ts b/packages/bottender/src/session/__tests__/MongoSessionStore.spec.ts
index 001080e0..ded9e560 100644
--- a/packages/bottender/src/session/__tests__/MongoSessionStore.spec.ts
+++ b/packages/bottender/src/session/__tests__/MongoSessionStore.spec.ts
@@ -20,9 +20,9 @@ function setup(options = {}) {
     db: jest.fn(() => connection),
   };
   MongoClient.connect.mockResolvedValue(client);
+
   const store = new MongoSessionStore(
-    'mongodb://fakemongourl',
-    options,
+    { url: 'mongodb://fakemongourl', ...options },
     MINUTES_IN_ONE_YEAR
   );
 
@@ -33,6 +33,18 @@ function setup(options = {}) {
   };
 }
 
+it('should be instanceof MongoSessionStore', () => {
+  expect(
+    new MongoSessionStore('mongodb://fakemongourl', MINUTES_IN_ONE_YEAR)
+  ).toBeInstanceOf(MongoSessionStore);
+  expect(
+    new MongoSessionStore(
+      { url: 'mongodb://fakemongourl' },
+      MINUTES_IN_ONE_YEAR
+    )
+  ).toBeInstanceOf(MongoSessionStore);
+});
+
 describe('#init', () => {
   it('should return initialize store instance', async () => {
     const { store } = setup();