From 1e30c4bc9beffc411d84dabbf38343a1584be7d8 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Sun, 18 Feb 2024 19:31:13 +0530 Subject: [PATCH 1/5] test: complete test suite for TriesOverview --- .../src/views/ExamReport/TriesOverview.vue | 21 ++- .../__tests__/TriesOverview.spec.js | 125 +++++++++++++++++- 2 files changed, 131 insertions(+), 15 deletions(-) diff --git a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue index 83a3b85a4ff..03f845ef2b5 100644 --- a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue +++ b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue @@ -115,30 +115,25 @@ return 0.0; } }, + // Returns the time spent on the best attempt or null if there are no attempts bestTimeSpent() { - const bestScoreAttempt = this.pastTries.find(t => t.correct === this.maxQuestionsCorrect); - if (!bestScoreAttempt) { - return null; - } - return bestScoreAttempt.time_spent; + return this.pastTries.length + ? this.pastTries.find(t => t.correct === this.maxQuestionsCorrect).time_spent + : null; }, + // Returns the number of questions correct in the best attempt or 0 if there are no attempts maxQuestionsCorrect() { - return this.pastTries.length ? Math.max(...this.pastTries.map(t => t.correct)) : null; + return this.pastTries.length ? Math.max(...this.pastTries.map(t => t.correct)) : 0; }, bestScore() { - return this.maxQuestionsCorrect !== null - ? this.maxQuestionsCorrect / this.totalQuestions - : null; + return this.maxQuestionsCorrect / this.totalQuestions; }, suggestedTimeAnnotation() { - if (!this.suggestedTime || this.bestTimeSpent === null) { + if (!this.suggestedTime || !this.bestTimeSpent) { return null; } const diff = Math.floor((this.bestTimeSpent - this.suggestedTime) / 60); - if (!diff) { - return null; - } return diff >= 1 ? this.$tr('practiceQuizReportSlowerSuggestedLabel', { value: diff }) diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js index 05acce0b770..1b0e0c5ab2b 100644 --- a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -12,7 +12,13 @@ tryValidatorModule.tryValidator = jest.fn(() => true); const renderComponent = props => { const commonCoreStrings = { methods: { - coreString: x => x, + // Add comma seperated options as key value pairs + coreString: (x, options) => + !options + ? x + : `${x} ${Object.keys(options) + .map(key => `${key}=${options[key]}`) + .join(', ')}`, }, }; @@ -40,6 +46,8 @@ describe('TriesOverview', () => { pastTries: [ { id: '1', + correct: 5, + time_spent: 100, completion_timestamp: 100, }, ], @@ -51,7 +59,13 @@ describe('TriesOverview', () => { test('renders progress icon and in-progress label when there is an in-progress try', () => { renderComponent({ - pastTries: [{ id: '2' }], + pastTries: [ + { + id: '2', + correct: 5, + time_spent: 100, + }, + ], }); expect(screen.getByTestId('progress-icon-0.5')).toBeInTheDocument(); @@ -65,4 +79,111 @@ describe('TriesOverview', () => { expect(screen.getByText('notStartedLabel')).toBeInTheDocument(); }); }); + + describe("Test the 'Best Score' table row", () => { + test('renders the best score when there are past tries', () => { + renderComponent({ + pastTries: [ + { + id: '1', + correct: 8, + time_spent: 100, + }, + { + id: '2', + correct: 9, + time_spent: 100, + }, + ], + totalQuestions: 10, + }); + + expect(screen.getByText('Best score')).toBeInTheDocument(); + expect(screen.getByText('90%')).toBeInTheDocument(); + + expect(screen.getByText('questionsCorrectLabel')).toBeInTheDocument(); + expect(screen.getByText('questionsCorrectValue correct=9, total=10')).toBeInTheDocument(); + }); + + test('renders the best score as 0 when there are no past tries', () => { + renderComponent(); + + expect(screen.getByText('Best score')).toBeInTheDocument(); + expect(screen.getByText('0%')).toBeInTheDocument(); + + expect(screen.getByText('questionsCorrectLabel')).toBeInTheDocument(); + expect(screen.getByText('questionsCorrectValue correct=0, total=20')).toBeInTheDocument(); + }); + }); + + describe("Test the 'Time Spent' table row", () => { + test('shows the time spent when there are past tries [Faster Quiz Report]', () => { + renderComponent({ + pastTries: [ + { + id: '1', + correct: 8, + time_spent: 100, + }, + { + id: '2', + correct: 9, + time_spent: 20, + }, + ], + suggestedTime: 100, + }); + + expect(screen.getByText('Best score time')).toBeInTheDocument(); + expect(screen.getByText('20 seconds')).toBeInTheDocument(); + expect(screen.getByText('2 minutes faster than the suggested time')).toBeInTheDocument(); + }); + + test('shows the time spent when there are past tries [Slower Quiz Report]', () => { + renderComponent({ + pastTries: [ + { + id: '1', + correct: 8, + time_spent: 100, + }, + { + id: '2', + correct: 9, + time_spent: 160, + }, + ], + suggestedTime: 100, + }); + + expect(screen.getByText('Best score time')).toBeInTheDocument(); + expect(screen.getByText('2 minutes')).toBeInTheDocument(); + expect(screen.getByText('1 minute slower than the suggested time')).toBeInTheDocument(); + }); + + test('shows the time spent when there are past tries but no suggested time [No Quiz Report]', () => { + renderComponent({ + pastTries: [ + { + id: '1', + correct: 8, + time_spent: 100, + }, + { + id: '2', + correct: 9, + time_spent: 20, + }, + ], + }); + + expect(screen.getByText('Best score time')).toBeInTheDocument(); + expect(screen.getByText('20 seconds')).toBeInTheDocument(); + }); + + test('does not render the row if there are no past tries', () => { + renderComponent(); + expect(screen.queryByText('Best score time')).not.toBeInTheDocument(); + }); + }); }); From e3f70769cd6ebe22c7de7485e677c245e6e08992 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Sun, 18 Feb 2024 20:03:10 +0530 Subject: [PATCH 2/5] test: change comment position for better readibility --- .../src/views/ExamReport/__tests__/TriesOverview.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js index 1b0e0c5ab2b..ddb980d45d1 100644 --- a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -12,11 +12,11 @@ tryValidatorModule.tryValidator = jest.fn(() => true); const renderComponent = props => { const commonCoreStrings = { methods: { - // Add comma seperated options as key value pairs coreString: (x, options) => !options ? x - : `${x} ${Object.keys(options) + : // Add comma seperated options as key value pairs at the end of the label + `${x} ${Object.keys(options) .map(key => `${key}=${options[key]}`) .join(', ')}`, }, From 575adfa4018b4207569a934ac08fb556fc8db966 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Tue, 20 Feb 2024 23:24:15 +0530 Subject: [PATCH 3/5] fix: remove double and add to contributors :) --- AUTHORS.md | 1 + .../assets/src/views/ExamReport/__tests__/TriesOverview.spec.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index bb1ac22f5a8..c35fcbba7d2 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -102,3 +102,4 @@ If you have contributed to Kolibri, feel free to add your name and Github accoun | Shivang Rawat | ShivangRawat30 | | Alex VĂ©lez | AlexVelezLl | | Mazen Oweiss | moweiss | +| Eshaan Aggarwal | EshaanAgg | diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js index ddb980d45d1..58f855fc915 100644 --- a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -26,7 +26,6 @@ const renderComponent = props => { pastTries: [], totalQuestions: 20, suggestedTime: 240, - ...props, }; return render(TriesOverview, { From 45e94e9d1169341e6d0f68b57d2d03e12a6b6cfd Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:56:31 +0530 Subject: [PATCH 4/5] fix: explicity pass empty arrays to render function --- .../src/views/ExamReport/__tests__/TriesOverview.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js index 58f855fc915..f8aca3e6b2f 100644 --- a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -72,7 +72,10 @@ describe('TriesOverview', () => { }); test('renders progress icon and not started label when there are no past tries', () => { - renderComponent(); + renderComponent({ + pastTries: [], + totalQuestions: 20, + }); expect(screen.getByTestId('progress-icon-0')).toBeInTheDocument(); expect(screen.getByText('notStartedLabel')).toBeInTheDocument(); From 8e608a9c1455040a8dfd906523e1d8a5b0f40b56 Mon Sep 17 00:00:00 2001 From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com> Date: Fri, 1 Mar 2024 18:52:04 +0530 Subject: [PATCH 5/5] fix: address review comments --- .../core/assets/src/views/ExamReport/TriesOverview.vue | 8 +++++--- .../src/views/ExamReport/__tests__/TriesOverview.spec.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue index 03f845ef2b5..21cc1d8f145 100644 --- a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue +++ b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue @@ -117,9 +117,11 @@ }, // Returns the time spent on the best attempt or null if there are no attempts bestTimeSpent() { - return this.pastTries.length - ? this.pastTries.find(t => t.correct === this.maxQuestionsCorrect).time_spent - : null; + const bestScoreAttempt = this.pastTries.find(t => t.correct === this.maxQuestionsCorrect); + if (!bestScoreAttempt) { + return null; + } + return bestScoreAttempt.time_spent; }, // Returns the number of questions correct in the best attempt or 0 if there are no attempts maxQuestionsCorrect() { diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js index f8aca3e6b2f..eff15339625 100644 --- a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -184,7 +184,7 @@ describe('TriesOverview', () => { }); test('does not render the row if there are no past tries', () => { - renderComponent(); + renderComponent({ pastTries: [] }); expect(screen.queryByText('Best score time')).not.toBeInTheDocument(); }); });