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

Merge pull request #7451 from arafubeatbox/imprv/114334-116948-add-days-since-creation-to-user-condition

Imprv/114334 116948 add days since creation to user condition
Ryoji Shimizu 3 лет назад
Родитель
Сommit
eadbe155ef

+ 4 - 0
packages/app/src/interfaces/questionnaire/condition.ts

@@ -5,6 +5,10 @@ import { UserType } from './user-info';
 
 interface UserCondition {
   types: UserType[] // user types to show questionnaire
+  daysSinceCreation?: {
+    moreThanOrEqualTo?: number
+    lessThanOrEqualTo?: number
+  }
 }
 
 interface GrowiCondition {

+ 12 - 0
packages/app/src/server/models/questionnaire/schema/condition.ts

@@ -7,6 +7,18 @@ import { UserType } from '~/interfaces/questionnaire/user-info';
 const conditionSchema = new Schema<ICondition>({
   user: {
     types: [{ type: String, enum: Object.values(UserType) }],
+    daysSinceCreation: {
+      moreThanOrEqualTo: { type: Number, min: 0 },
+      lessThanOrEqualTo: {
+        type: Number,
+        min: 0,
+        validate: [
+          function(value) {
+            return this.user.daysSinceCreation.moreThanOrEqualTo == null || this.user.daysSinceCreation.moreThanOrEqualTo <= value;
+          }, 'daysSinceCreation.lessThanOrEqualTo must be greater than moreThanOrEqualTo',
+        ],
+      },
+    },
   },
   growi: {
     types: [{ type: String, enum: Object.values(GrowiServiceType) }],

+ 32 - 3
packages/app/src/server/util/questionnaire/condition.ts

@@ -1,13 +1,42 @@
 import { ICondition } from '~/interfaces/questionnaire/condition';
 import { IGrowiInfo } from '~/interfaces/questionnaire/growi-info';
 import { IQuestionnaireOrder } from '~/interfaces/questionnaire/questionnaire-order';
-import { IUserInfo } from '~/interfaces/questionnaire/user-info';
+import { IUserInfo, UserType } from '~/interfaces/questionnaire/user-info';
 
 
 const checkUserInfo = (condition: ICondition, userInfo: IUserInfo): boolean => {
-  const { user: { types } } = condition;
+  const { user: { types, daysSinceCreation } } = condition;
 
-  return types.includes(userInfo.type);
+  if (!types.includes(userInfo.type)) {
+    return false;
+  }
+
+  // Check if "time passed since user creation" is between specified range
+  if (userInfo.type !== UserType.guest) {
+    const createdAt = userInfo.userCreatedAt;
+    const moreThanOrEqualTo = daysSinceCreation?.moreThanOrEqualTo;
+    const lessThanOrEqualTo = daysSinceCreation?.lessThanOrEqualTo;
+    const currentDate = new Date();
+
+    const isValidLeftThreshold = (() => {
+      if (moreThanOrEqualTo == null) {
+        return true;
+      }
+      const leftThreshold = new Date(createdAt.getTime() + 60 * 1000 * 60 * 24 * moreThanOrEqualTo);
+      return leftThreshold <= currentDate;
+    })();
+    const isValidRightThreshold = (() => {
+      if (lessThanOrEqualTo == null) {
+        return true;
+      }
+      const rightThreshold = new Date(createdAt.getTime() + 60 * 1000 * 60 * 24 * lessThanOrEqualTo);
+      return currentDate <= rightThreshold;
+    })();
+
+    return isValidLeftThreshold && isValidRightThreshold;
+  }
+
+  return true;
 };
 
 const checkGrowiInfo = (condition: ICondition, growiInfo: IGrowiInfo): boolean => {

+ 62 - 2
packages/app/test/integration/service/questionnaire.test.ts

@@ -26,7 +26,7 @@ describe('QuestionnaireService', () => {
       username: 'questionnaire test user',
       email: 'questionnaireTestUser@example.com',
       password: 'usertestpass',
-      createdAt: '2023-01-01',
+      createdAt: '2000-01-01',
     });
   });
 
@@ -80,7 +80,7 @@ describe('QuestionnaireService', () => {
 
       delete userInfo.userIdHash;
 
-      expect(userInfo).toEqual({ type: 'general', userCreatedAt: new Date('2023-01-01') });
+      expect(userInfo).toEqual({ type: 'general', userCreatedAt: new Date('2000-01-01') });
     });
 
     test('Should get correct user info when user is null', () => {
@@ -106,6 +106,10 @@ describe('QuestionnaireService', () => {
         condition: {
           user: {
             types: ['general'],
+            daysSinceCreation: {
+              moreThanOrEqualTo: 365,
+              lessThanOrEqualTo: 365 * 1000,
+            },
           },
           growi: {
             types: ['on-premise'],
@@ -183,6 +187,58 @@ describe('QuestionnaireService', () => {
             },
           },
         },
+        // for users that used GROWI for less than or equal to a year
+        {
+          ...questionnaireToBeShown,
+          _id: '63b8354837e7aa378e16f0b9',
+          condition: {
+            user: {
+              types: ['general'],
+              daysSinceCreation: {
+                lessThanOrEqualTo: 365,
+              },
+            },
+            growi: {
+              types: ['on-premise'],
+              versionRegExps: [crowi.version],
+            },
+          },
+        },
+        // for users that used GROWI for more than or equal to 1000 years
+        {
+          ...questionnaireToBeShown,
+          _id: '63b8354837e7aa378e16f0c1',
+          condition: {
+            user: {
+              types: ['general'],
+              daysSinceCreation: {
+                moreThanOrEqualTo: 365 * 1000,
+              },
+            },
+            growi: {
+              types: ['on-premise'],
+              versionRegExps: [crowi.version],
+            },
+          },
+        },
+        // for users that used GROWI for more than a month and less than 6 months
+        {
+          ...questionnaireToBeShown,
+          _id: '63b8354837e7aa378e16f0c2',
+          condition: {
+            user: {
+              types: ['general'],
+              daysSinceCreation: {
+                moreThanOrEqualTo: 30,
+                lessThanOrEqualTo: 30 * 6,
+              },
+            },
+            growi: {
+              types: ['on-premise'],
+              versionRegExps: [crowi.version],
+            },
+          },
+        },
       ]);
 
       await QuestionnaireAnswerStatus.insertMany([
@@ -231,6 +287,10 @@ describe('QuestionnaireService', () => {
           condition: {
             user: {
               types: ['general'],
+              daysSinceCreation: {
+                moreThanOrEqualTo: 365,
+                lessThanOrEqualTo: 365 * 1000,
+              },
             },
             growi: {
               types: ['on-premise'],