From de99fe668745f93b9f25839b780c76bbce4b1154 Mon Sep 17 00:00:00 2001 From: Georgy Berezhnoy Date: Sun, 5 Dec 2021 04:01:46 +0300 Subject: [PATCH 1/2] Save affected users info to daily events --- lib/utils.js | 4 ++++ workers/grouper/src/index.ts | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index 418aa43f..b8609683 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -50,6 +50,10 @@ function deepDiff(source, target) { function arrayDiff(source, target) { const diffArray = []; + if (!Array.isArray(source)) { + return target; + } + for (let i = 0; i < target.length; i++) { diffArray[i] = deepDiff(source[i], target[i]); } diff --git a/workers/grouper/src/index.ts b/workers/grouper/src/index.ts index e39370e1..a879ca5a 100644 --- a/workers/grouper/src/index.ts +++ b/workers/grouper/src/index.ts @@ -164,10 +164,12 @@ export default class GrouperWorker extends Worker { repetitionId = await this.saveRepetition(task.projectId, newRepetition); } + const eventUser = task.event.user; + /** * Store events counter by days */ - await this.saveDailyEvents(task.projectId, uniqueEventHash, task.event.timestamp, repetitionId); + await this.saveDailyEvents(task.projectId, uniqueEventHash, task.event.timestamp, repetitionId, eventUser?.id); /** * Add task for NotifierWorker @@ -205,13 +207,13 @@ export default class GrouperWorker extends Worker { */ private async findSimilarEvent(projectId: string, event: EventDataAccepted): Promise { const eventsCountToCompare = 60; - const diffTreshold = 0.35; + const diffThreshold = 0.35; const lastUniqueEvents = await this.findLastEvents(projectId, eventsCountToCompare); return lastUniqueEvents.filter(prevEvent => { const distance = levenshtein(event.title, prevEvent.payload.title); - const threshold = event.title.length * diffTreshold; + const threshold = event.title.length * diffThreshold; return distance < threshold; }).pop(); @@ -384,13 +386,15 @@ export default class GrouperWorker extends Worker { * @param {string} eventHash - event hash * @param {string} eventTimestamp - timestamp of the last event * @param {string|null} repetitionId - event's last repetition id + * @param {string} userId - affected user id * @returns {Promise} */ private async saveDailyEvents( projectId: string, eventHash: string, eventTimestamp: number, - repetitionId: string | null + repetitionId: string | null, + userId = 'anonymous' ): Promise { if (!projectId || !mongodb.ObjectID.isValid(projectId)) { throw new ValidationError('GrouperWorker.saveDailyEvents: Project ID is invalid or missed'); @@ -423,6 +427,7 @@ export default class GrouperWorker extends Worker { lastRepetitionId: repetitionId, }, $inc: { count: 1 }, + $addToSet: { affectedUsers: userId }, }, { upsert: true }); } catch (err) { From 33d059ebd8bb0afbc74031ab55c8c96017430780 Mon Sep 17 00:00:00 2001 From: Georgy Berezhnoy Date: Sun, 26 Dec 2021 01:11:57 +0300 Subject: [PATCH 2/2] Add tests for affected users set --- workers/grouper/tests/index.test.ts | 32 +++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/workers/grouper/tests/index.test.ts b/workers/grouper/tests/index.test.ts index 36203a35..00d24360 100644 --- a/workers/grouper/tests/index.test.ts +++ b/workers/grouper/tests/index.test.ts @@ -19,10 +19,12 @@ jest.mock('../../../lib/cache/controller', () => { } // eslint-disable-next-line @typescript-eslint/no-empty-function, jsdoc/require-jsdoc - public flushAll(): void {} + public flushAll(): void { + } // eslint-disable-next-line @typescript-eslint/no-empty-function, jsdoc/require-jsdoc - public set(): void {} + public set(): void { + } }; }); @@ -214,6 +216,32 @@ describe('GrouperWorker', () => { expect((await dailyEventsCollection.findOne({})).lastRepetitionId).toEqual(repetition._id); }); + + test('Should update affected users list', async () => { + const task1 = generateTask(); + const task2 = generateTask(); + + await worker.handle(task1); + await worker.handle(task2); + + expect((await dailyEventsCollection.findOne({})).affectedUsers).toEqual([task1.event.user.id, task2.event.user.id]); + }); + + test('Should add anonymous user to affected users list if user is not passed with event', async () => { + await worker.handle(generateTask({ user: undefined })); + + expect((await dailyEventsCollection.findOne({})).affectedUsers).toEqual([ 'anonymous' ]); + }); + + test('Should not add user to affected users list if its already there', async () => { + const task1 = generateTask(); + const task2 = generateTask({ user: { id: task1.event.user.id } }); + + await worker.handle(task1); + await worker.handle(task2); + + expect((await dailyEventsCollection.findOne({})).affectedUsers).toEqual([ task1.event.user.id ]); + }); }); describe('Saving repetitions', () => {