From 349540f439d543e0bb4bc4b8c10a073930d8af14 Mon Sep 17 00:00:00 2001 From: dianeCdrPix Date: Mon, 6 Jan 2025 11:04:38 +0100 Subject: [PATCH] fix(scripts): include stepper in element count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Latzarus Co-authored-by: Diane Cordier Co-authored-by: Eric Lim --- api/scripts/modulix/get-modules-csv.js | 24 ++- .../scripts/get-modules-csv_test.js | 2 +- .../unit/scripts/get-modules-csv_test.js | 147 ++++++++++++++++++ 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 api/tests/devcomp/unit/scripts/get-modules-csv_test.js diff --git a/api/scripts/modulix/get-modules-csv.js b/api/scripts/modulix/get-modules-csv.js index 5ffef15661a..1c7e9f05640 100644 --- a/api/scripts/modulix/get-modules-csv.js +++ b/api/scripts/modulix/get-modules-csv.js @@ -3,6 +3,28 @@ import { fileURLToPath } from 'node:url'; import moduleDatasource from '../../src/devcomp/infrastructure/datasources/learning-content/module-datasource.js'; import { getCsvContent } from '../../src/shared/infrastructure/utils/csv/write-csv-utils.js'; +export function _getTotalElementsCount(grains) { + let totalElements = 0; + for (const grain of grains) { + for (const component of grain.components) { + switch (component.type) { + case 'element': + totalElements += 1; + break; + case 'stepper': + for (const step of component.steps) { + totalElements += step.elements.length; + } + break; + default: + throw new Error(`Component type "${component.type}" is not available`); + } + } + } + + return totalElements; +} + export async function getModulesListAsCsv(modules) { return await getCsvContent({ data: modules, @@ -11,7 +33,7 @@ export async function getModulesListAsCsv(modules) { { label: 'Module', value: 'slug' }, { label: 'ModuleTotalElements', - value: (row) => row.grains.map((grain) => grain.components.length).reduce((partialSum, a) => partialSum + a, 0), + value: (row) => _getTotalElementsCount(row.grains), }, { label: 'ModuleLink', value: (row) => `https://app.recette.pix.fr/modules/${row.slug}` }, { label: 'ModuleLevel', value: 'details.level' }, diff --git a/api/tests/devcomp/acceptance/scripts/get-modules-csv_test.js b/api/tests/devcomp/acceptance/scripts/get-modules-csv_test.js index cb3013a2a53..44dd5a80c4b 100644 --- a/api/tests/devcomp/acceptance/scripts/get-modules-csv_test.js +++ b/api/tests/devcomp/acceptance/scripts/get-modules-csv_test.js @@ -410,6 +410,6 @@ describe('Acceptance | Script | Get Modules as CSV', function () { expect(modulesListAsCsv).to.be.a('string'); expect(modulesListAsCsv).to .equal(`\ufeff"Module"\t"ModuleTotalElements"\t"ModuleLink"\t"ModuleLevel"\t"ModuleTotalGrains"\t"ModuleTotalLessons"\t"ModuleTotalActivities"\t"ModuleTotalChallenges"\t"ModuleTotalDiscoveries"\t"ModuleTotalSummaries"\t"ModuleDuration"\t"ModuleIsBeta" -"didacticiel-modulix"\t11\t"https://app.recette.pix.fr/modules/didacticiel-modulix"\t"Débutant"\t8\t1\t4\t1\t1\t1\t"=TEXT(5/24/60; ""mm:ss"")"\t"=TRUE"`); +"didacticiel-modulix"\t13\t"https://app.recette.pix.fr/modules/didacticiel-modulix"\t"Débutant"\t9\t1\t5\t1\t1\t1\t"=TEXT(5/24/60; ""mm:ss"")"\t"=TRUE"`); }); }); diff --git a/api/tests/devcomp/unit/scripts/get-modules-csv_test.js b/api/tests/devcomp/unit/scripts/get-modules-csv_test.js new file mode 100644 index 00000000000..827953a1759 --- /dev/null +++ b/api/tests/devcomp/unit/scripts/get-modules-csv_test.js @@ -0,0 +1,147 @@ +import { _getTotalElementsCount } from '../../../../scripts/modulix/get-modules-csv.js'; +import { catchErrSync, expect } from '../../../test-helper.js'; + +describe('Unit | Scripts | Get Modules as CSV', function () { + describe('#getTotalElements', function () { + it('should count elements inside component "element"', function () { + // given + const grains = [ + { + components: [ + { + type: 'element', + element: { + id: '84726001-1665-457d-8f13-4a74dc4768ea', + type: 'text', + content: + '

On commence avec les leçons.
Les leçons sont des textes, des images ou des vidéos. Les leçons sont là pour vous expliquer des concepts ou des méthodes.

', + }, + }, + { + type: 'element', + element: { + id: 'a2372bf4-86a4-4ecc-a188-b51f4f98bca2', + type: 'text', + content: + '

Voici un texte de leçon. Parfois, il y a des émojis pour aider à la lecture .
Et là, voici une image !

', + }, + }, + { + type: 'element', + element: { + id: '8d7687c8-4a02-4d7e-bf6c-693a6d481c78', + type: 'image', + url: 'https://images.pix.fr/modulix/didacticiel/ordi-spatial.svg', + alt: "Dessin détaillé dans l'alternative textuelle", + alternativeText: "Dessin d'un ordinateur dans un univers spatial.", + }, + }, + ], + }, + ]; + + // when + const result = _getTotalElementsCount(grains); + + //then + expect(result).to.equal(3); + }); + + it('should count elements inside stepper', function () { + // given + const grains = [ + { + components: [ + { + type: 'stepper', + steps: [ + { + elements: [ + { + id: '342183f7-af51-4e4e-ab4c-ebed1e195063', + type: 'text', + content: '

À la fin de cette vidéo, une question sera posée sur les compétences Pix.

', + }, + ], + }, + { + elements: [ + { + id: '342183f7-af51-4e4e-ab4c-ebed1e195063', + type: 'text', + content: '

À la fin de cette vidéo, une question sera posée sur les compétences Pix.

', + }, + ], + }, + ], + }, + ], + }, + ]; + + // when + const result = _getTotalElementsCount(grains); + + //then + expect(result).to.equal(2); + }); + + it('should not filter non existing element type', function () { + // given + const grains = [ + { + components: [ + { + type: 'stepper', + steps: [ + { + elements: [ + { + type: 'non-existing-element-type', + }, + ], + }, + ], + }, + ], + }, + { + components: [ + { + type: 'element', + element: { + type: 'non-existing-element-type', + }, + }, + ], + }, + ]; + + // when + const result = _getTotalElementsCount(grains); + + // then + expect(result).to.equal(2); + }); + + it('should throw if component type is not available', function () { + // given + const grains = [ + { + components: [ + { + type: 'non-existing-component-type', + }, + ], + }, + ]; + + // when + const err = catchErrSync(_getTotalElementsCount)(grains); + + // then + expect(err).to.be.an.instanceOf(Error); + expect(err.message).to.equal('Component type "non-existing-component-type" is not available'); + }); + }); +});