From 17225f9a65e7edcee788faeb199b7699a2b99571 Mon Sep 17 00:00:00 2001 From: MisRob Date: Thu, 5 Oct 2023 14:04:51 +0200 Subject: [PATCH] Fix order in which notification updates are commited to state Commit updates to state sorted by timestamp. Fixes https://github.com/learningequality/kolibri/issues/11302 where "Completed" update was commited before "Started" update. --- .../classSummary/__test__/actions.spec.js | 65 +++++++++++++++++++ .../src/modules/classSummary/actions.js | 11 +++- 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 kolibri/plugins/coach/assets/src/modules/classSummary/__test__/actions.spec.js diff --git a/kolibri/plugins/coach/assets/src/modules/classSummary/__test__/actions.spec.js b/kolibri/plugins/coach/assets/src/modules/classSummary/__test__/actions.spec.js new file mode 100644 index 00000000000..f70b4636db8 --- /dev/null +++ b/kolibri/plugins/coach/assets/src/modules/classSummary/__test__/actions.spec.js @@ -0,0 +1,65 @@ +import { NotificationObjects } from '../../../constants/notificationsConstants'; +import { updateWithNotifications } from '../actions'; + +const { QUIZ } = NotificationObjects; + +describe('classSummary/actions', () => { + describe('updateWithNotifications', () => { + it('commits quiz notifications updates in a correct order (sorted by their datetime)', () => { + const state = { + learnerMap: { 'user-id': {} }, + examMap: { 'quiz-id': {} }, + contentNodeMap: {}, + lessonMap: {}, + }; + const commit = jest.fn(); + const dispatch = jest.fn(); + + const quizNotifications = [ + { + id: 1, + user_id: 'user-id', + object: QUIZ, + event: 'Completed', + timestamp: '2023-10-05T13:35:00+02:00', + quiz_num_correct: 1, + quiz_num_answered: 2, + quiz_id: 'quiz-id', + }, + { + id: 2, + user_id: 'user-id', + object: QUIZ, + event: 'Started', + timestamp: '2023-10-05T13:30:00+02:00', + quiz_num_correct: 2, + quiz_num_answered: 3, + quiz_id: 'quiz-id', + }, + ]; + + updateWithNotifications({ state, commit, dispatch }, quizNotifications); + + expect(commit).toHaveBeenCalledTimes(1); + expect(commit.mock.calls[0][0]).toBe('APPLY_NOTIFICATION_UPDATES'); + expect(commit.mock.calls[0][1].examLearnerStatusMapUpdates).toEqual([ + { + learner_id: 'user-id', + status: 'Started', + last_activity: new Date('2023-10-05T11:30:00.000Z'), + num_correct: 2, + num_answered: 3, + exam_id: 'quiz-id', + }, + { + learner_id: 'user-id', + status: 'Completed', + last_activity: new Date('2023-10-05T11:35:00.000Z'), + num_correct: 1, + num_answered: 2, + exam_id: 'quiz-id', + }, + ]); + }); + }); +}); diff --git a/kolibri/plugins/coach/assets/src/modules/classSummary/actions.js b/kolibri/plugins/coach/assets/src/modules/classSummary/actions.js index 22a88f146f8..85008edecec 100644 --- a/kolibri/plugins/coach/assets/src/modules/classSummary/actions.js +++ b/kolibri/plugins/coach/assets/src/modules/classSummary/actions.js @@ -9,8 +9,15 @@ export function updateWithNotifications(store, notifications) { const contentLearnerStatusMapUpdates = []; const { learnerMap, examMap, contentNodeMap, lessonMap } = store.state; - for (const nIdx in notifications) { - const notification = notifications[nIdx]; + if (!notifications || !notifications.length) { + return; + } + const sortedNotifications = notifications.sort((n1, n2) => { + return new Date(n1.timestamp) - new Date(n2.timestamp); + }); + + for (const nIdx in sortedNotifications) { + const notification = sortedNotifications[nIdx]; const { object } = notification; // Short-circuit the update if there are missing learners, exams, lessons,