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

refs 112133: questionnaire cron test

Futa Arai 3 лет назад
Родитель
Сommit
472bc6f85e

+ 3 - 3
packages/app/src/server/crowi/index.js

@@ -81,6 +81,7 @@ function Crowi() {
   this.activityService = null;
   this.activityService = null;
   this.commentService = null;
   this.commentService = null;
   this.xss = new Xss();
   this.xss = new Xss();
+  this.questionnaireCronService = null;
 
 
   this.tokens = null;
   this.tokens = null;
 
 
@@ -308,9 +309,8 @@ Crowi.prototype.setupModels = async function() {
 };
 };
 
 
 Crowi.prototype.setupCron = function() {
 Crowi.prototype.setupCron = function() {
-  console.log(this.configManager?.getConfig('crowi', 'app:questionnaireCronSchedule'));
-  console.log(this.configManager?.getConfig('crowi', 'app:questionnaireCronMaxHoursUntilRequest'));
-  new QuestionnaireCronService(this).setUpCron();
+  this.questionnaireCronService = new QuestionnaireCronService(this);
+  this.questionnaireCronService.startCron();
 };
 };
 
 
 Crowi.prototype.scanRuntimeVersions = async function() {
 Crowi.prototype.scanRuntimeVersions = async function() {

+ 24 - 11
packages/app/src/server/service/questionnaire-cron.ts

@@ -1,4 +1,3 @@
-import { IQuestionnaireOrder } from '~/interfaces/questionnaire/questionnaire-order';
 import axios from '~/utils/axios';
 import axios from '~/utils/axios';
 
 
 import QuestionnaireOrder, { QuestionnaireOrderDocument } from '../models/questionnaire/questionnaire-order';
 import QuestionnaireOrder, { QuestionnaireOrderDocument } from '../models/questionnaire/questionnaire-order';
@@ -21,54 +20,68 @@ class QuestionnaireCronService {
 
 
   maxHoursUntilRequest: number;
   maxHoursUntilRequest: number;
 
 
+  cronJob;
+
   // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
   // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
   constructor(crowi) {
   constructor(crowi) {
     this.growiQuestionnaireUri = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireUri');
     this.growiQuestionnaireUri = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireUri');
     this.cronSchedule = crowi.configManager?.getConfig('crowi', 'app:questionnaireCronSchedule');
     this.cronSchedule = crowi.configManager?.getConfig('crowi', 'app:questionnaireCronSchedule');
     this.maxHoursUntilRequest = crowi.configManager?.getConfig('crowi', 'app:questionnaireCronMaxHoursUntilRequest');
     this.maxHoursUntilRequest = crowi.configManager?.getConfig('crowi', 'app:questionnaireCronMaxHoursUntilRequest');
+
+    const maxSecondsUntilRequest = this.maxHoursUntilRequest * 60 * 60;
+
+    this.cronJob = this.questionnaireOrderGetCron(this.cronSchedule, maxSecondsUntilRequest);
   }
   }
 
 
-  setUpCron(): void {
-    // const maxSecondsUntilRequest = this.maxHoursUntilRequest * 60 * 60;
-    const maxSecondsUntilRequest = 60;
-    this.questionnaireOrderGetCron(this.cronSchedule, maxSecondsUntilRequest);
+  startCron(): void {
+    this.cronJob.start();
   }
   }
 
 
-  questionnaireOrderGetCron(cronSchedule: string, maxSecondsUntilRequest: number): void {
+  stopCron(): void {
+    this.cronJob.stop();
+  }
+
+  private questionnaireOrderGetCron(cronSchedule: string, maxSecondsUntilRequest: number) {
     const saveOrders = async(questionnaireOrders: QuestionnaireOrderDocument[]) => {
     const saveOrders = async(questionnaireOrders: QuestionnaireOrderDocument[]) => {
+      console.log('こんにちは');
       const savedOrders: QuestionnaireOrderDocument[] = await QuestionnaireOrder.find();
       const savedOrders: QuestionnaireOrderDocument[] = await QuestionnaireOrder.find();
+      console.log(savedOrders);
       const savedOrderIds = savedOrders.map(order => order._id.toString());
       const savedOrderIds = savedOrders.map(order => order._id.toString());
       // 渡されたアンケートのうち未保存のものを保存する
       // 渡されたアンケートのうち未保存のものを保存する
       const nonSavedOrders = questionnaireOrders.filter(order => !savedOrderIds.includes(order._id));
       const nonSavedOrders = questionnaireOrders.filter(order => !savedOrderIds.includes(order._id));
       QuestionnaireOrder.insertMany(nonSavedOrders);
       QuestionnaireOrder.insertMany(nonSavedOrders);
     };
     };
 
 
-    const deleteFinishedOrders = () => {
+    const deleteFinishedOrders = async() => {
       const currentDate = new Date(Date.now());
       const currentDate = new Date(Date.now());
-      QuestionnaireOrder.deleteMany({
+      await QuestionnaireOrder.deleteMany({
         showUntil: {
         showUntil: {
           $lt: currentDate,
           $lt: currentDate,
         },
         },
       });
       });
     };
     };
 
 
-    nodeCron.schedule(cronSchedule, async() => {
+    return nodeCron.schedule(cronSchedule, async() => {
+      console.log('called');
       const secToSleep = getRandomInt(0, maxSecondsUntilRequest);
       const secToSleep = getRandomInt(0, maxSecondsUntilRequest);
 
 
       await sleep(secToSleep * 1000);
       await sleep(secToSleep * 1000);
 
 
       try {
       try {
         const response = await axios.get(`${this.growiQuestionnaireUri}/questionnaire-order/index`);
         const response = await axios.get(`${this.growiQuestionnaireUri}/questionnaire-order/index`);
+        console.log(response.data);
         const questionnaireOrders: QuestionnaireOrderDocument[] = JSON.parse(JSON.stringify(response.data)).questionnaireQrders;
         const questionnaireOrders: QuestionnaireOrderDocument[] = JSON.parse(JSON.stringify(response.data)).questionnaireQrders;
 
 
         await saveOrders(questionnaireOrders);
         await saveOrders(questionnaireOrders);
-        deleteFinishedOrders();
+        await deleteFinishedOrders();
+
+        console.log('executed');
       }
       }
       catch (e) {
       catch (e) {
         console.log(e);
         console.log(e);
       }
       }
 
 
-    }).start();
+    });
   }
   }
 
 
 }
 }

+ 138 - 0
packages/app/test/integration/service/questionnaire-cron.test.ts

@@ -0,0 +1,138 @@
+import QuestionnaireOrder from '../../../src/server/models/questionnaire/questionnaire-order';
+import axios from '../../../src/utils/axios';
+import { getInstance } from '../setup-crowi';
+
+
+const spyAxiosGet = jest.spyOn<typeof axios, 'get'>(
+  axios,
+  'get',
+);
+
+describe('QuestionnaireCronService', () => {
+  let crowi;
+
+  const mockResponse = {
+    data: {
+      questionnaireOrders: [
+        // 既に保存されている
+        {
+          _id: '63a8354837e7aa378e16f0b1',
+          showFrom: '2022-12-11',
+          showUntil: '2023-12-12',
+          questions: [
+            {
+              type: 'points',
+              text: 'Growi は使いやすいですか?',
+            },
+          ],
+          condition: {
+            user: {
+              types: ['admin', 'general'],
+            },
+            growi: {
+              types: ['cloud', 'private-cloud'],
+              versionRegExps: ['2\\.0\\.[0-9]', '1\\.9\\.[0-9]'],
+            },
+          },
+        },
+        // 新しいアンケート
+        {
+          _id: '63a8354837e7aa378e16f0b2',
+          showFrom: '2021-12-11',
+          showUntil: '2022-12-12',
+          questions: [
+            {
+              type: 'points',
+              text: 'アンケート機能は支障なく動いていますか?',
+            },
+          ],
+          condition: {
+            user: {
+              types: ['general'],
+            },
+            growi: {
+              types: ['cloud'],
+              versionRegExps: ['2\\.0\\.[0-9]', '1\\.9\\.[0-9]'],
+            },
+          },
+        },
+      ],
+    },
+  };
+
+  beforeAll(async() => {
+    process.env.QUESTIONNAIRE_CRON_SCHEDULE = '0 22 * * *';
+    process.env.QUESTIONNAIRE_CRON_MAX_HOURS_UNTIL_REQUEST = '4';
+
+    crowi = await getInstance();
+    // reload
+    await crowi.setupConfigManager();
+
+    // await QuestionnaireOrder.insertMany([
+    //   {
+    //     _id: '63a8354837e7aa378e16f0b1',
+    //     showFrom: '2021-12-11',
+    //     showUntil: '2022-12-12',
+    //     questions: [
+    //       {
+    //         type: 'points',
+    //         text: 'アンケート機能は支障なく動いていますか?',
+    //       },
+    //     ],
+    //     condition: {
+    //       user: {
+    //         types: ['general'],
+    //       },
+    //       growi: {
+    //         types: ['cloud'],
+    //         versionRegExps: ['2\\.0\\.[0-9]', '1\\.9\\.[0-9]'],
+    //       },
+    //     },
+    //   },
+    //   {
+    //     _id: '63a8354837e7aa378e16f0b3',
+    //     showFrom: '2020-12-11',
+    //     showUntil: '2021-12-12',
+    //     questions: [
+    //       {
+    //         type: 'points',
+    //         text: '最近どうですか?',
+    //       },
+    //     ],
+    //     condition: {
+    //       user: {
+    //         types: ['general'],
+    //       },
+    //       growi: {
+    //         types: ['cloud'],
+    //         versionRegExps: ['2\\.0\\.[0-9]', '1\\.9\\.[0-9]'],
+    //       },
+    //     },
+    //   },
+    // ]);
+
+    const mockDate = new Date(2022, 0, 1, 21, 59, 55); // cronjob 実行の 5 秒前
+    jest.useFakeTimers();
+    jest.setSystemTime(mockDate);
+
+    // useFakeTimers の後でないと設定した mock 時刻が反映されない
+    crowi.setupCron();
+  });
+
+  afterAll(() => {
+    jest.useRealTimers();
+    crowi.questionnaireCronService.stopCron();
+  });
+
+  describe('test test', () => {
+    test('hoge', async() => {
+      spyAxiosGet.mockResolvedValue(mockResponse);
+      jest.advanceTimersByTime(5 * 1000); // cronjob 実行時刻まで進める
+      jest.advanceTimersByTime(4 * 60 * 60 * 1000); // 待機時間の最大値まで進め、リクエストを実行する
+      // const savedOrders = await QuestionnaireOrder.find();
+      // const savedIds: string[] = savedOrders.map(order => order._id.toString());
+      const savedIds = ['a'];
+      expect(savedIds.sort()).toEqual(['63a8354837e7aa378e16f0b1', '63a8354837e7aa378e16f0b2']);
+    });
+  });
+});