From 56d8b519f6dbf3929914e093cc42b0a81ad6c71c Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Thu, 14 Nov 2024 14:46:08 +0100 Subject: [PATCH 1/9] refactor(api): remove random scenario in simulator --- .../scenario-simulator-controller.js | 10 +- .../application/scenario-simulator-route.js | 9 -- api/src/shared/infrastructure/utils/random.js | 16 +-- .../scenario-simulator-controller_test.js | 27 ---- .../scenario-simulator-controller_test.js | 126 ------------------ .../unit/infrastructure/utils/random_test.js | 22 --- 6 files changed, 2 insertions(+), 208 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index 3bb32150a5f..19983649c8e 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -96,24 +96,16 @@ async function simulateFlashAssessmentScenario( } function _getPickAnswerStatusMethod(pickAnswerStatusService, payload) { - const { type, probabilities, length, capacity, answerStatusArray } = payload; + const { type, capacity, answerStatusArray } = payload; switch (type) { case 'deterministic': return pickAnswerStatusService.pickAnswerStatusFromArray(answerStatusArray); - case 'random': { - const answer = _generateAnswerStatusArray(random, probabilities, length); - return pickAnswerStatusService.pickAnswerStatusFromArray(answer); - } case 'capacity': return pickAnswerStatusService.pickAnswerStatusForCapacity(capacity); } } -function _generateAnswerStatusArray(random, probabilities, length) { - return random.weightedRandoms(probabilities, length); -} - function _minimumEstimatedSuccessRateRangesToDomain(successRateRanges) { if (!successRateRanges) { return undefined; diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index 5614e73ab6f..5e43fb5a570 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -59,15 +59,6 @@ const register = async (server) => { .items(Joi.string().allow('ok', 'ko', 'aband')) .required(), }), - _baseScenarioParametersValidator.keys({ - type: Joi.string().valid('random').required(), - probabilities: Joi.object({ - ok: Joi.number(), - ko: Joi.number(), - aband: Joi.number(), - }), - length: Joi.number().integer().min(0).required(), - }), _baseScenarioParametersValidator.keys({ type: Joi.string().valid('capacity').required(), capacity: Joi.number().min(-8).max(8).required(), diff --git a/api/src/shared/infrastructure/utils/random.js b/api/src/shared/infrastructure/utils/random.js index 9293124ce5f..a4b188ef580 100644 --- a/api/src/shared/infrastructure/utils/random.js +++ b/api/src/shared/infrastructure/utils/random.js @@ -1,17 +1,3 @@ -const weightedRandom = (values) => { - let probabilitiesSum = 0; - const randomFloat = Math.random(); - for (const key in values) { - probabilitiesSum += values[key]; - const shouldSelectCurrentKey = probabilitiesSum > randomFloat; - if (shouldSelectCurrentKey) { - return key; - } - } -}; - -const weightedRandoms = (values, length) => [...new Array(length)].map(() => weightedRandom(values)); - const binaryTreeRandom = (probability, length) => { if (length === 1) { return 0; @@ -26,4 +12,4 @@ const binaryTreeRandom = (probability, length) => { return 1 + binaryTreeRandom(probability, length - 1); }; -export const random = { weightedRandoms, binaryTreeRandom }; +export const random = { binaryTreeRandom }; diff --git a/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js b/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js index ce783d15530..c5791f23dee 100644 --- a/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js +++ b/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js @@ -16,7 +16,6 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () let server; let adminAuthorization; let validDeterministicPayload; - let validRandomPayload; let validCapacityPayload; let stopAtChallenge; const answerStatusArray = ['ok', 'ko', 'aband']; @@ -40,17 +39,6 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () stopAtChallenge, }; - validRandomPayload = { - type: 'random', - probabilities: { - ok: 0.3, - ko: 0.5, - aband: 0.2, - }, - length: 5, - stopAtChallenge, - }; - validCapacityPayload = { capacity: 4.5, type: 'capacity', @@ -211,21 +199,6 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () }); }); - describe('when the scenario is random', function () { - it('should return a payload with simulation random scenario results', async function () { - // given - options.headers.authorization = adminAuthorization; - options.payload = validRandomPayload; - - // when - const response = await server.inject(options); - - // then - const parsedResponse = parseJsonStream(response); - expect(parsedResponse[0].simulationReport).to.have.lengthOf(2); - }); - }); - describe('when the scenario is capacity', function () { it('should return a payload with simulation the capacity scenario results', async function () { // given diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index 7c5f65fb78a..06e1b1eeb4f 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -3,7 +3,6 @@ import { usecases } from '../../../../../src/certification/flash-certification/d import { pickAnswerStatusService } from '../../../../../src/certification/shared/domain/services/pick-answer-status-service.js'; import { pickChallengeService } from '../../../../../src/evaluation/domain/services/pick-challenge-service.js'; import { securityPreHandlers } from '../../../../../src/shared/application/security-pre-handlers.js'; -import { random } from '../../../../../src/shared/infrastructure/utils/random.js'; import { domainBuilder, expect, HttpTestServer, parseJsonStream, sinon } from '../../../../test-helper.js'; describe('Integration | Application | scenario-simulator-controller', function () { @@ -18,7 +17,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( beforeEach(async function () { sinon.stub(usecases, 'simulateFlashDeterministicAssessmentScenario'); sinon.stub(securityPreHandlers, 'checkAdminMemberHasRoleSuperAdmin'); - sinon.stub(random, 'weightedRandoms'); sinon.stub(pickAnswerStatusService, 'pickAnswerStatusFromArray'); sinon.stub(pickAnswerStatusService, 'pickAnswerStatusForCapacity'); sinon.stub(pickChallengeService, 'chooseNextChallenge'); @@ -760,130 +758,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); }); - context('When the scenario is random', function () { - context('When the route is called with correct arguments', function () { - context('When the route is called without an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { - // given - const length = 1; - const probabilities = { ok: 0.3, ko: 0.4, aband: 0.3 }; - random.weightedRandoms.withArgs(probabilities, length).returns(['ok']); - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); - - usecases.simulateFlashDeterministicAssessmentScenario - .withArgs({ - pickChallenge: pickChallengeImplementation, - locale: 'en', - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - type: 'random', - probabilities, - length, - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - - context('When the route is called with an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { - // given - const length = 1; - const probabilities = { ok: 0.3, ko: 0.4, aband: 0.3 }; - random.weightedRandoms.withArgs(probabilities, length).returns(['ok']); - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); - - usecases.simulateFlashDeterministicAssessmentScenario - .withArgs({ - pickChallenge: pickChallengeImplementation, - locale: 'en', - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, - initialCapacity, - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - type: 'random', - probabilities, - initialCapacity, - length, - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - }); - }); - context('When the scenario is capacity', function () { context('When the route is called with correct arguments', function () { context('When the route is called without an initial capacity', function () { diff --git a/api/tests/shared/unit/infrastructure/utils/random_test.js b/api/tests/shared/unit/infrastructure/utils/random_test.js index 35a8e0066fe..719e3def19f 100644 --- a/api/tests/shared/unit/infrastructure/utils/random_test.js +++ b/api/tests/shared/unit/infrastructure/utils/random_test.js @@ -4,28 +4,6 @@ import { random } from '../../../../../src/shared/infrastructure/utils/random.js import { expect } from '../../../../test-helper.js'; describe('Unit | Infrastructure | Utils | Random', function () { - describe('#weightedRandoms', function () { - context('randomDistributionTest', function () { - it('should have a decent distribution', function () { - const length = 100000; - const values = { - ok: 0.1, - ko: 0.3, - aband: 0.6, - }; - - const results = random.weightedRandoms(values, length); - - const resultDistribution = _.countBy(results); - - const computeDistance = (value, expected) => Math.abs(value / length - expected); - expect(computeDistance(resultDistribution.ok, values.ok)).to.be.lessThan(0.01); - expect(computeDistance(resultDistribution.ko, values.ko)).to.be.lessThan(0.01); - expect(computeDistance(resultDistribution.aband, values.aband)).to.be.lessThan(0.01); - }); - }); - }); - describe('#binaryTreeRandom', function () { context('randomDistributionTest', function () { it('should have a decent distribution', function () { From 35592c656442d522ce72bf88f34c8c3a9f79d7aa Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Thu, 14 Nov 2024 15:16:45 +0100 Subject: [PATCH 2/9] refactor(api): remove deterministic scenario in simulator --- .../scenario-simulator-controller.js | 14 +- .../application/scenario-simulator-route.js | 15 +- .../scenario-simulator-controller_test.js | 30 +- .../scenario-simulator-controller_test.js | 273 +++--------------- 4 files changed, 45 insertions(+), 287 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index 19983649c8e..58ed1eb15a1 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -36,9 +36,10 @@ async function simulateFlashAssessmentScenario( doubleMeasuresUntil, variationPercent, variationPercentUntil, + capacity, } = request.payload; - const pickAnswerStatus = _getPickAnswerStatusMethod(dependencies.pickAnswerStatusService, request.payload); + const pickAnswerStatus = dependencies.pickAnswerStatusService.pickAnswerStatusForCapacity(capacity); const locale = dependencies.extractLocaleFromRequest(request); @@ -95,17 +96,6 @@ async function simulateFlashAssessmentScenario( return h.response(generatedResponse).type('text/event-stream; charset=utf-8'); } -function _getPickAnswerStatusMethod(pickAnswerStatusService, payload) { - const { type, capacity, answerStatusArray } = payload; - - switch (type) { - case 'deterministic': - return pickAnswerStatusService.pickAnswerStatusFromArray(answerStatusArray); - case 'capacity': - return pickAnswerStatusService.pickAnswerStatusForCapacity(capacity); - } -} - function _minimumEstimatedSuccessRateRangesToDomain(successRateRanges) { if (!successRateRanges) { return undefined; diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index 5e43fb5a570..cb179e28052 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -52,18 +52,11 @@ const register = async (server) => { options: { allowUnknown: true, }, - payload: Joi.alternatives([ - _baseScenarioParametersValidator.keys({ - type: Joi.string().valid('deterministic').required(), - answerStatusArray: Joi.array() - .items(Joi.string().allow('ok', 'ko', 'aband')) - .required(), - }), - _baseScenarioParametersValidator.keys({ - type: Joi.string().valid('capacity').required(), + payload: _baseScenarioParametersValidator + .keys({ capacity: Joi.number().min(-8).max(8).required(), - }), - ]).required(), + }) + .required(), }, handler: scenarioSimulatorController.simulateFlashAssessmentScenario, tags: ['api'], diff --git a/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js b/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js index c5791f23dee..53db3317e61 100644 --- a/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js +++ b/api/tests/acceptance/application/scenario-simulator/scenario-simulator-controller_test.js @@ -15,10 +15,8 @@ const { describe('Acceptance | Controller | scenario-simulator-controller', function () { let server; let adminAuthorization; - let validDeterministicPayload; let validCapacityPayload; let stopAtChallenge; - const answerStatusArray = ['ok', 'ko', 'aband']; beforeEach(async function () { const { id: adminId } = databaseBuilder.factory.buildUser.withRole({ @@ -33,15 +31,8 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () adminAuthorization = generateValidRequestAuthorizationHeader(adminId); await databaseBuilder.commit(); - validDeterministicPayload = { - answerStatusArray, - type: 'deterministic', - stopAtChallenge, - }; - validCapacityPayload = { capacity: 4.5, - type: 'capacity', stopAtChallenge, }; @@ -158,10 +149,10 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () }); describe('when a number of challenges to pass is specified', function () { - it('should return a payload with the same number of simulation deterministic scenario results', async function () { + it('should return a payload with the same number of simulation scenario results', async function () { // given const validPayload = { - ...validDeterministicPayload, + ...validCapacityPayload, stopAtChallenge, }; options.headers.authorization = adminAuthorization; @@ -184,21 +175,6 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () }); }); - describe('when the scenario is deterministic', function () { - it('should return a payload with simulation deterministic scenario results', async function () { - // given - options.headers.authorization = adminAuthorization; - options.payload = validDeterministicPayload; - - // when - const response = await server.inject(options); - // then - expect(response).to.have.property('statusCode', 200); - const parsedResponse = parseJsonStream(response); - expect(parsedResponse[0].simulationReport).to.have.lengthOf(2); - }); - }); - describe('when the scenario is capacity', function () { it('should return a payload with simulation the capacity scenario results', async function () { // given @@ -233,7 +209,7 @@ describe('Acceptance | Controller | scenario-simulator-controller', function () const { id: userId } = databaseBuilder.factory.buildUser(); options.headers.authorization = generateValidRequestAuthorizationHeader(userId); await databaseBuilder.commit(); - options.payload = validDeterministicPayload; + options.payload = validCapacityPayload; // when const response = await server.inject(options); diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index 06e1b1eeb4f..02da0867bda 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -60,19 +60,18 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When there is no warmup', function () { it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { // given - const answerStatusArray = ['ok']; const forcedCompetences = ['compA', 'compB', 'compC']; const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -87,8 +86,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, forcedCompetences, }, null, @@ -122,19 +120,18 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When the scenario is forced to space competences', function () { it('should call the usecase with the right parameters', async function () { // given - const answerStatusArray = ['ok']; const challengesBetweenSameCompetence = 2; const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -149,8 +146,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, challengesBetweenSameCompetence, }, null, @@ -183,21 +179,20 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When configuring the challenge pick probability', function () { it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { // given - const answerStatusArray = ['ok']; const challengePickProbability = 40; const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge .withArgs(challengePickProbability) .returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -211,8 +206,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, challengePickProbability, }, null, @@ -246,18 +240,17 @@ describe('Integration | Application | scenario-simulator-controller', function ( it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { // given const limitToOneQuestionPerTube = true; - const answerStatusArray = ['ok']; const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -272,8 +265,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, limitToOneQuestionPerTube, }, null, @@ -307,8 +299,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When providing valid parameters', function () { it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { // given - const answerStatusArray = ['ok']; - const minimumEstimatedSuccessRateRanges = [ { type: 'fixed', @@ -341,14 +331,14 @@ describe('Integration | Application | scenario-simulator-controller', function ( const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -363,8 +353,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, minimumEstimatedSuccessRateRanges, }, null, @@ -424,7 +413,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( { initialCapacity, answerStatusArray, - type: 'deterministic', minimumEstimatedSuccessRateRanges, }, null, @@ -466,7 +454,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( { initialCapacity, answerStatusArray, - type: 'deterministic', minimumEstimatedSuccessRateRanges, }, null, @@ -501,7 +488,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( { initialCapacity, answerStatusArray, - type: 'deterministic', minimumEstimatedSuccessRateRanges, }, null, @@ -518,18 +504,17 @@ describe('Integration | Application | scenario-simulator-controller', function ( it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { // given const enablePassageByAllCompetences = true; - const answerStatusArray = ['ok']; const pickChallengeImplementation = sinon.stub(); pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); + const pickAnswerStatusForCapacityImplementation = sinon.stub(); + pickAnswerStatusService.pickAnswerStatusForCapacity + .withArgs(6) + .returns(pickAnswerStatusForCapacityImplementation); usecases.simulateFlashDeterministicAssessmentScenario .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, + pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', pickChallenge: pickChallengeImplementation, initialCapacity, @@ -544,8 +529,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( '/api/scenario-simulator', { initialCapacity, - answerStatusArray, - type: 'deterministic', + capacity: 6, enablePassageByAllCompetences, }, null, @@ -575,189 +559,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); }); - context('When the scenario is deterministic', function () { - context('When the route is called with correct arguments', function () { - context('When the route is called with an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { - // given - const answerStatusArray = ['ok']; - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); - - usecases.simulateFlashDeterministicAssessmentScenario - .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, - locale: 'en', - pickChallenge: pickChallengeImplementation, - initialCapacity, - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - initialCapacity, - answerStatusArray, - type: 'deterministic', - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - - context('When the route is called without an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { - // given - const answerStatusArray = ['ok']; - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); - - usecases.simulateFlashDeterministicAssessmentScenario - .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, - pickChallenge: pickChallengeImplementation, - locale: 'en', - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - answerStatusArray, - type: 'deterministic', - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - - context('When the route is called with a numberOfIterations', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { - // given - const answerStatusArray = ['ok']; - const numberOfIterations = 2; - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge - .returns(pickChallengeImplementation) - .returns(pickChallengeImplementation); - const pickAnswerStatusFromArrayImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusFromArray - .withArgs(['ok']) - .returns(pickAnswerStatusFromArrayImplementation); - - usecases.simulateFlashDeterministicAssessmentScenario - .withArgs({ - pickAnswerStatus: pickAnswerStatusFromArrayImplementation, - pickChallenge: pickChallengeImplementation, - locale: 'en', - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - numberOfIterations, - answerStatusArray, - type: 'deterministic', - }, - null, - { 'accept-language': 'en' }, - ); - - const result = { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }; - - // then - expect(response.statusCode).to.equal(200); - - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [result], - }, - { - index: 1, - simulationReport: [result], - }, - ]); - }); - }); - }); - }); - context('When the scenario is capacity', function () { context('When the route is called with correct arguments', function () { context('When the route is called without an initial capacity', function () { @@ -786,7 +587,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( 'POST', '/api/scenario-simulator', { - type: 'capacity', capacity, }, null, @@ -843,7 +643,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( 'POST', '/api/scenario-simulator', { - type: 'capacity', capacity, initialCapacity, }, From 68f3ee1b46d1c2cc46e3136e3ceaeb1990bc3c7e Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Thu, 14 Nov 2024 15:37:50 +0100 Subject: [PATCH 3/9] refactor(api): rename flash deterministic files --- .../scenario-simulator-controller.js | 2 +- ... => simulate-flash-assessment-scenario.js} | 2 +- .../scenario-simulator-controller_test.js | 32 +++++++++---------- ...imulate-flash-assessment-scenario_test.js} | 16 +++++----- 4 files changed, 26 insertions(+), 26 deletions(-) rename api/src/certification/flash-certification/domain/usecases/{simulate-flash-deterministic-assessment-scenario.js => simulate-flash-assessment-scenario.js} (96%) rename api/tests/unit/domain/usecases/{simulate-flash-deterministic-assessment-scenario_test.js => simulate-flash-assessment-scenario_test.js} (95%) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index 58ed1eb15a1..bf37f2a645e 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -74,7 +74,7 @@ async function simulateFlashAssessmentScenario( _.isUndefined, ); - const simulationReport = await usecases.simulateFlashDeterministicAssessmentScenario(usecaseParams); + const simulationReport = await usecases.simulateFlashAssessmentScenario(usecaseParams); yield JSON.stringify({ index, diff --git a/api/src/certification/flash-certification/domain/usecases/simulate-flash-deterministic-assessment-scenario.js b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js similarity index 96% rename from api/src/certification/flash-certification/domain/usecases/simulate-flash-deterministic-assessment-scenario.js rename to api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js index 69957671166..c60d986dfbb 100644 --- a/api/src/certification/flash-certification/domain/usecases/simulate-flash-deterministic-assessment-scenario.js +++ b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js @@ -4,7 +4,7 @@ import { AssessmentSimulatorDoubleMeasureStrategy } from '../models/AssessmentSi import { AssessmentSimulatorSingleMeasureStrategy } from '../models/AssessmentSimulatorSingleMeasureStrategy.js'; import { FlashAssessmentAlgorithm } from '../models/FlashAssessmentAlgorithm.js'; -export async function simulateFlashDeterministicAssessmentScenario({ +export async function simulateFlashAssessmentScenario({ locale, pickChallenge, pickAnswerStatus, diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index 02da0867bda..0ae3d21cd8f 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -15,7 +15,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( const initialCapacity = 2; beforeEach(async function () { - sinon.stub(usecases, 'simulateFlashDeterministicAssessmentScenario'); + sinon.stub(usecases, 'simulateFlashAssessmentScenario'); sinon.stub(securityPreHandlers, 'checkAdminMemberHasRoleSuperAdmin'); sinon.stub(pickAnswerStatusService, 'pickAnswerStatusFromArray'); sinon.stub(pickAnswerStatusService, 'pickAnswerStatusForCapacity'); @@ -58,7 +58,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When the scenario is forced to pass through some competences', function () { context('When there is no warmup', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const forcedCompetences = ['compA', 'compB', 'compC']; @@ -69,7 +69,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -129,7 +129,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -177,7 +177,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); context('When configuring the challenge pick probability', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const challengePickProbability = 40; @@ -190,7 +190,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -237,7 +237,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); context('When configuring the limit of challenges per tube', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const limitToOneQuestionPerTube = true; @@ -248,7 +248,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -297,7 +297,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When configuring the minimum success rates', function () { context('When providing valid parameters', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const minimumEstimatedSuccessRateRanges = [ { @@ -336,7 +336,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -501,7 +501,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); context('When configuring the passage by all competences', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const enablePassageByAllCompetences = true; @@ -512,7 +512,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(6) .returns(pickAnswerStatusForCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickAnswerStatus: pickAnswerStatusForCapacityImplementation, locale: 'en', @@ -562,7 +562,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( context('When the scenario is capacity', function () { context('When the route is called with correct arguments', function () { context('When the route is called without an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const capacity = -3.1; @@ -573,7 +573,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(capacity) .returns(pickAnswerStatusFromCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickChallenge: pickChallengeImplementation, locale: 'en', @@ -617,7 +617,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); context('When the route is called with an initial capacity', function () { - it('should call simulateFlashDeterministicAssessmentScenario usecase with correct arguments', async function () { + it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { // given const capacity = -3.1; @@ -628,7 +628,7 @@ describe('Integration | Application | scenario-simulator-controller', function ( .withArgs(capacity) .returns(pickAnswerStatusFromCapacityImplementation); - usecases.simulateFlashDeterministicAssessmentScenario + usecases.simulateFlashAssessmentScenario .withArgs({ pickChallenge: pickChallengeImplementation, locale: 'en', diff --git a/api/tests/unit/domain/usecases/simulate-flash-deterministic-assessment-scenario_test.js b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js similarity index 95% rename from api/tests/unit/domain/usecases/simulate-flash-deterministic-assessment-scenario_test.js rename to api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js index a3e926f810d..99d21c6bf71 100644 --- a/api/tests/unit/domain/usecases/simulate-flash-deterministic-assessment-scenario_test.js +++ b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js @@ -1,6 +1,6 @@ import _ from 'lodash'; -import { simulateFlashDeterministicAssessmentScenario } from '../../../../src/certification/flash-certification/domain/usecases/simulate-flash-deterministic-assessment-scenario.js'; +import { simulateFlashAssessmentScenario } from '../../../../src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js'; import { config } from '../../../../src/shared/config.js'; import { AnswerStatus } from '../../../../src/shared/domain/models/AnswerStatus.js'; import { catchErr, domainBuilder, expect, sinon } from '../../../test-helper.js'; @@ -11,7 +11,7 @@ const successAnswerMatcher = sinon.match({ result: AnswerStatus.OK, }); -describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', function () { +describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { context('when there are enough flash challenges left', function () { context('when no initial capacity is provided', function () { it('should return an array of capacity, challenge, reward and error rate for each answer', async function () { @@ -19,7 +19,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu const { challengeRepository, pickChallenge, pickAnswerStatus, flashAlgorithmService } = prepareStubs(); // when - const result = await simulateFlashDeterministicAssessmentScenario({ + const result = await simulateFlashAssessmentScenario({ stopAtChallenge: 3, challengeRepository, locale, @@ -60,7 +60,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu .returns(0.5); // when - const result = await simulateFlashDeterministicAssessmentScenario({ + const result = await simulateFlashAssessmentScenario({ stopAtChallenge: 3, challengeRepository, locale, @@ -128,7 +128,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu .returns([thirdChallenge]); // when - const result = await simulateFlashDeterministicAssessmentScenario({ + const result = await simulateFlashAssessmentScenario({ stopAtChallenge: 3, challengeRepository, locale, @@ -169,7 +169,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu }); // when - const result = await simulateFlashDeterministicAssessmentScenario({ + const result = await simulateFlashAssessmentScenario({ stopAtChallenge: 3, challengeRepository, locale, @@ -201,7 +201,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu }); // when - const result = await simulateFlashDeterministicAssessmentScenario({ + const result = await simulateFlashAssessmentScenario({ stopAtChallenge: 3, challengeRepository, locale, @@ -271,7 +271,7 @@ describe('Unit | UseCase | simulate-flash-deterministic-assessment-scenario', fu pickAnswerStatus.withArgs(sinon.match({ nextChallenge: challenge })).returns(AnswerStatus.OK); // when - const error = await catchErr(simulateFlashDeterministicAssessmentScenario)({ + const error = await catchErr(simulateFlashAssessmentScenario)({ challengeRepository, locale, pickChallenge, From 9d1a21c32be4462df8629908859d6925c65caea1 Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Thu, 14 Nov 2024 17:14:11 +0100 Subject: [PATCH 4/9] refactor(api): remove warmUpLength parameter --- .../application/scenario-simulator-controller.js | 2 -- .../flash-certification/application/scenario-simulator-route.js | 1 - .../domain/usecases/simulate-flash-assessment-scenario.js | 2 -- 3 files changed, 5 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index bf37f2a645e..38eaf9474c8 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -25,7 +25,6 @@ async function simulateFlashAssessmentScenario( stopAtChallenge, initialCapacity, numberOfIterations = 1, - warmUpLength, forcedCompetences, useObsoleteChallenges, challengePickProbability, @@ -60,7 +59,6 @@ async function simulateFlashAssessmentScenario( locale, stopAtChallenge, initialCapacity, - warmUpLength, forcedCompetences, useObsoleteChallenges, challengesBetweenSameCompetence, diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index cb179e28052..22324abbd33 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -23,7 +23,6 @@ const _baseScenarioParametersValidator = Joi.object().keys({ initialCapacity: Joi.number().integer().min(-8).max(8), stopAtChallenge: Joi.number().integer().min(0), numberOfIterations: Joi.number().integer().min(0), - warmpUpLength: Joi.number().integer().min(0), forcedCompetencies: Joi.array().items(Joi.string()), useObsoleteChallenges: Joi.boolean(), challengePickProbability: Joi.number().min(0).max(100), diff --git a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js index c60d986dfbb..357195539ad 100644 --- a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js +++ b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js @@ -11,7 +11,6 @@ export async function simulateFlashAssessmentScenario({ stopAtChallenge, initialCapacity, useObsoleteChallenges, - warmUpLength = 0, forcedCompetences = [], challengesBetweenSameCompetence = 0, limitToOneQuestionPerTube = true, @@ -28,7 +27,6 @@ export async function simulateFlashAssessmentScenario({ const flashAssessmentAlgorithm = new FlashAssessmentAlgorithm({ flashAlgorithmImplementation: flashAlgorithmService, configuration: new FlashAssessmentAlgorithmConfiguration({ - warmUpLength, forcedCompetences, limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges, From dc95cbf7eb86cb834999aa04cdcdc8e920bfc6eb Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Fri, 15 Nov 2024 11:15:40 +0100 Subject: [PATCH 5/9] refactor(api): remove linear success ranges parameter --- .../application/scenario-simulator-route.js | 20 ++--- .../FlashAssessmentSuccessRateHandler.js | 23 +---- ...essmentSuccessRateHandlerLinearStrategy.js | 22 ----- .../scenario-simulator-controller_test.js | 63 ------------- .../FlashAssessmentSuccessRateHandler_test.js | 45 +--------- .../models/FlashAssessmentAlgorithm_test.js | 89 +------------------ ...sessment-algorithm-success-rate-handler.js | 16 +--- .../tooling/domain-builder/factory/index.js | 6 +- 8 files changed, 11 insertions(+), 273 deletions(-) delete mode 100644 api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandlerLinearStrategy.js diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index 22324abbd33..d6c461d524f 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -3,21 +3,11 @@ import Joi from 'joi'; import { securityPreHandlers } from '../../../shared/application/security-pre-handlers.js'; import { scenarioSimulatorController } from './scenario-simulator-controller.js'; -const _successRatesConfigurationValidator = Joi.alternatives( - Joi.object({ - type: Joi.string().valid('fixed').required(), - startingChallengeIndex: Joi.number().integer().min(0).required(), - endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(), - value: Joi.number().min(0).max(1).required(), - }), - Joi.object({ - type: Joi.string().valid('linear').required(), - startingChallengeIndex: Joi.number().integer().min(0).required(), - endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(), - startingValue: Joi.number().min(0).max(1).required(), - endingValue: Joi.number().min(0).max(1).required(), - }), -); +const _successRatesConfigurationValidator = Joi.object({ + startingChallengeIndex: Joi.number().integer().min(0).required(), + endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(), + value: Joi.number().min(0).max(1).required(), +}); const _baseScenarioParametersValidator = Joi.object().keys({ initialCapacity: Joi.number().integer().min(-8).max(8), diff --git a/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandler.js b/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandler.js index 8a044b0570b..d5d8ae461a4 100644 --- a/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandler.js +++ b/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandler.js @@ -1,11 +1,9 @@ import { FlashAssessmentSuccessRateHandlerFixedStrategy } from './FlashAssessmentSuccessRateHandlerFixedStrategy.js'; -import { FlashAssessmentSuccessRateHandlerLinearStrategy } from './FlashAssessmentSuccessRateHandlerLinearStrategy.js'; class FlashAssessmentSuccessRateHandler { constructor({ startingChallengeIndex, endingChallengeIndex, strategy }) { this.startingChallengeIndex = startingChallengeIndex; this.endingChallengeIndex = endingChallengeIndex; - this._strategy = strategy; } @@ -18,15 +16,7 @@ class FlashAssessmentSuccessRateHandler { } static create(successRateRange) { - if (successRateRange.type === 'linear') { - return FlashAssessmentSuccessRateHandler.createLinear(successRateRange); - } - if (successRateRange.type === 'fixed') { - return FlashAssessmentSuccessRateHandler.createFixed(successRateRange); - } - } - - static createFixed({ startingChallengeIndex, endingChallengeIndex, value }) { + const { startingChallengeIndex, endingChallengeIndex, value } = successRateRange; return new FlashAssessmentSuccessRateHandler({ startingChallengeIndex, endingChallengeIndex, @@ -36,17 +26,6 @@ class FlashAssessmentSuccessRateHandler { }); } - static createLinear({ startingChallengeIndex, endingChallengeIndex, startingValue, endingValue }) { - return new FlashAssessmentSuccessRateHandler({ - startingChallengeIndex, - endingChallengeIndex, - strategy: new FlashAssessmentSuccessRateHandlerLinearStrategy({ - startingValue, - endingValue, - }), - }); - } - toDTO() { return { startingChallengeIndex: this.startingChallengeIndex, diff --git a/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandlerLinearStrategy.js b/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandlerLinearStrategy.js deleted file mode 100644 index 2cdcf186aab..00000000000 --- a/api/src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandlerLinearStrategy.js +++ /dev/null @@ -1,22 +0,0 @@ -export class FlashAssessmentSuccessRateHandlerLinearStrategy { - constructor({ startingValue, endingValue }) { - this.startingValue = startingValue; - this.endingValue = endingValue; - } - - // Computes a linear success rate variation between startingChallengeIndex and endingChallengeIndex - // It varies from this.startingValue to this.endingValue - getMinimalSuccessRate(startingChallengeIndex, endingChallengeIndex, challengeIndex) { - const successRateSlope = (this.endingValue - this.startingValue) / (endingChallengeIndex - startingChallengeIndex); - - return this.startingValue + successRateSlope * (challengeIndex - startingChallengeIndex); - } - - toDTO() { - return { - type: 'linear', - startingValue: this.startingValue, - endingValue: this.endingValue, - }; - } -} diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index 0ae3d21cd8f..ed470120355 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -301,18 +301,10 @@ describe('Integration | Application | scenario-simulator-controller', function ( // given const minimumEstimatedSuccessRateRanges = [ { - type: 'fixed', startingChallengeIndex: 0, endingChallengeIndex: 7, value: 0.8, }, - { - type: 'linear', - startingChallengeIndex: 8, - endingChallengeIndex: 15, - startingValue: 0.8, - endingValue: 0.5, - }, ]; const expectedSuccessRateRanges = [ @@ -321,12 +313,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( endingChallengeIndex: 7, value: 0.8, }), - domainBuilder.buildFlashAssessmentAlgorithmSuccessRateHandlerLinear({ - startingChallengeIndex: 8, - endingChallengeIndex: 15, - startingValue: 0.8, - endingValue: 0.5, - }), ]; const pickChallengeImplementation = sinon.stub(); @@ -390,59 +376,10 @@ describe('Integration | Application | scenario-simulator-controller', function ( const minimumEstimatedSuccessRateRanges = [ { - type: 'fixed', - startingChallengeIndex: 0, - endingChallengeIndex: 7, - value: 0.8, - }, - { - type: 'linear', - startingChallengeIndex: 8, - endingChallengeIndex: 7, - startingValue: 0.8, - endingValue: 0.5, - }, - ]; - - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - initialCapacity, - answerStatusArray, - minimumEstimatedSuccessRateRanges, - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(400); - }); - }); - - context('When providing invalid linear config', function () { - it('should respond with a 400 error', async function () { - // given - const answerStatusArray = ['ok']; - - const minimumEstimatedSuccessRateRanges = [ - { - type: 'fixed', startingChallengeIndex: 0, endingChallengeIndex: 7, value: 0.8, }, - { - type: 'linear', - startingChallengeIndex: 8, - endingChallengeIndex: 15, - startingValue: 1.3, - endingValue: 0.5, - }, ]; securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); diff --git a/api/tests/certification/flash-certification/unit/domain/models/FlashAssessmentSuccessRateHandler_test.js b/api/tests/certification/flash-certification/unit/domain/models/FlashAssessmentSuccessRateHandler_test.js index c8ae2b3c031..fcd16a56a2a 100644 --- a/api/tests/certification/flash-certification/unit/domain/models/FlashAssessmentSuccessRateHandler_test.js +++ b/api/tests/certification/flash-certification/unit/domain/models/FlashAssessmentSuccessRateHandler_test.js @@ -12,7 +12,7 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithmSuccessRateHandler', value: 0.8, }; - flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.createFixed(fixedConfig); + flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.create(fixedConfig); }); describe('when currentIndex is inside the application range', function () { @@ -48,7 +48,7 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithmSuccessRateHandler', value: configSuccessRate, }; - flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.createFixed(fixedConfig); + flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.create(fixedConfig); }); it('should return the fixed value', function () { @@ -58,28 +58,6 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithmSuccessRateHandler', expect(successRate).to.equal(configSuccessRate); }); }); - - describe('when strategy is linear', function () { - let flashAssessmentSuccessRateHandler; - - beforeEach(function () { - const linearConfig = { - startingChallengeIndex: 0, - endingChallengeIndex: 4, - startingValue: 0.8, - endingValue: 0.6, - }; - - flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.createLinear(linearConfig); - }); - - it('should return the computed linear value', function () { - const questionIndex = 2; - const successRate = flashAssessmentSuccessRateHandler.getMinimalSuccessRate(questionIndex); - - expect(successRate).to.equal(0.7); - }); - }); }); describe('#create', function () { @@ -101,24 +79,5 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithmSuccessRateHandler', expect(successRate).to.equal(configSuccessRate); }); }); - - describe('when type is linear', function () { - it('should return the linear value', function () { - const linearConfig = { - type: 'linear', - startingChallengeIndex: 0, - endingChallengeIndex: 2, - startingValue: 0.8, - endingValue: 0.6, - }; - - const flashAssessmentSuccessRateHandler = FlashAssessmentSuccessRateHandler.create(linearConfig); - - const questionIndex = 1; - const successRate = flashAssessmentSuccessRateHandler.getMinimalSuccessRate(questionIndex); - - expect(successRate).to.equal(0.7); - }); - }); }); }); diff --git a/api/tests/certification/shared/unit/domain/models/FlashAssessmentAlgorithm_test.js b/api/tests/certification/shared/unit/domain/models/FlashAssessmentAlgorithm_test.js index 284515a6cf9..407a8b6556c 100644 --- a/api/tests/certification/shared/unit/domain/models/FlashAssessmentAlgorithm_test.js +++ b/api/tests/certification/shared/unit/domain/models/FlashAssessmentAlgorithm_test.js @@ -361,7 +361,7 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithm | FlashAssessmentAlg configuration: _getAlgorithmConfig({ limitToOneQuestionPerTube: true, minimumEstimatedSuccessRateRanges: [ - FlashAssessmentSuccessRateHandler.createFixed({ + FlashAssessmentSuccessRateHandler.create({ startingChallengeIndex: 0, endingChallengeIndex: 1, value: 0.8, @@ -393,93 +393,6 @@ describe('Unit | Domain | Models | FlashAssessmentAlgorithm | FlashAssessmentAlg expect(nextChallenges).to.deep.equal([easyChallenge, hardChallenge]); }); }); - - context('when a linear minimal success rate has been set', function () { - it('should choose a challenge that has the required success rate first', function () { - // Given - const easyDifficulty = -3; - const hardDifficulty = 3; - const discriminant = 1; - const initialCapacity = 3; - - const easyChallenge = domainBuilder.buildChallenge({ - id: 'easyChallenge', - skill: domainBuilder.buildSkill({ - id: 'skillEasy', - }), - competenceId: 'compEasy', - discriminant, - difficulty: easyDifficulty, - }); - - const hardChallenge2 = domainBuilder.buildChallenge({ - id: 'hardChallenge2', - skill: domainBuilder.buildSkill({ - id: 'hardSkill2', - }), - competenceId: 'compHard2', - discriminant, - difficulty: hardDifficulty, - }); - - const hardChallenge = domainBuilder.buildChallenge({ - id: 'hardChallenge', - skill: domainBuilder.buildSkill({ - id: 'skillHard', - }), - competenceId: 'compHard', - discriminant, - difficulty: hardDifficulty, - }); - - const challenges = [hardChallenge, easyChallenge, hardChallenge2]; - const assessmentAnswers = [ - domainBuilder.buildAnswer({ - challengeId: hardChallenge.id, - }), - ]; - - // when - const algorithm = new FlashAssessmentAlgorithm({ - flashAlgorithmImplementation, - configuration: _getAlgorithmConfig({ - limitToOneQuestionPerTube: false, - minimumEstimatedSuccessRateRanges: [ - FlashAssessmentSuccessRateHandler.createLinear({ - startingChallengeIndex: 0, - endingChallengeIndex: 2, - startingValue: 0.8, - endingValue: 0.4, - }), - ], - }), - }); - - const expectedChallenges = [easyChallenge, hardChallenge2]; - flashAlgorithmImplementation.getCapacityAndErrorRate.returns({ - capacity: 0, - }); - flashAlgorithmImplementation.getPossibleNextChallenges - .withArgs({ - availableChallenges: expectedChallenges, - capacity: 0, - options: { - ...baseGetNextChallengeOptions, - // Due to JS having troubles with float numbers, we must use a matcher. - minimalSuccessRate: sinon.match((value) => value.toPrecision(1) === '0.6'), - }, - }) - .returns(expectedChallenges); - - const nextChallenges = algorithm.getPossibleNextChallenges({ - assessmentAnswers, - challenges, - initialCapacity, - }); - - expect(nextChallenges).to.deep.equal(expectedChallenges); - }); - }); }); }); }); diff --git a/api/tests/tooling/domain-builder/factory/build-flash-assessment-algorithm-success-rate-handler.js b/api/tests/tooling/domain-builder/factory/build-flash-assessment-algorithm-success-rate-handler.js index f84c744199d..21f35e0f351 100644 --- a/api/tests/tooling/domain-builder/factory/build-flash-assessment-algorithm-success-rate-handler.js +++ b/api/tests/tooling/domain-builder/factory/build-flash-assessment-algorithm-success-rate-handler.js @@ -1,23 +1,9 @@ import { FlashAssessmentSuccessRateHandler } from '../../../../src/certification/flash-certification/domain/models/FlashAssessmentSuccessRateHandler.js'; -export const buildFlashAssessmentAlgorithmSuccessRateHandlerLinear = ({ - startingChallengeIndex, - endingChallengeIndex, - startingValue, - endingValue, -}) => { - return FlashAssessmentSuccessRateHandler.createLinear({ - startingChallengeIndex, - endingChallengeIndex, - startingValue, - endingValue, - }); -}; - export const buildFlashAssessmentAlgorithmSuccessRateHandlerFixed = ({ startingChallengeIndex, endingChallengeIndex, value, }) => { - return FlashAssessmentSuccessRateHandler.createFixed({ startingChallengeIndex, endingChallengeIndex, value }); + return FlashAssessmentSuccessRateHandler.create({ startingChallengeIndex, endingChallengeIndex, value }); }; diff --git a/api/tests/tooling/domain-builder/factory/index.js b/api/tests/tooling/domain-builder/factory/index.js index 32e909fb766..9805556b9c3 100644 --- a/api/tests/tooling/domain-builder/factory/index.js +++ b/api/tests/tooling/domain-builder/factory/index.js @@ -93,10 +93,7 @@ import * as buildDataProtectionOfficer from './build-data-protection-officer.js' import { buildFeedback } from './build-feedback.js'; import { buildFinalizedSession } from './build-finalized-session.js'; import { buildFlashAlgorithmConfiguration } from './build-flash-algorithm-configuration.js'; -import { - buildFlashAssessmentAlgorithmSuccessRateHandlerFixed, - buildFlashAssessmentAlgorithmSuccessRateHandlerLinear, -} from './build-flash-assessment-algorithm-success-rate-handler.js'; +import { buildFlashAssessmentAlgorithmSuccessRateHandlerFixed } from './build-flash-assessment-algorithm-success-rate-handler.js'; import { buildFramework } from './build-framework.js'; import { buildHabilitation } from './build-habilitation.js'; import { buildHint } from './build-hint.js'; @@ -363,7 +360,6 @@ export { buildFlashAlgorithmConfiguration, buildFlashAssessmentAlgorithm, buildFlashAssessmentAlgorithmSuccessRateHandlerFixed, - buildFlashAssessmentAlgorithmSuccessRateHandlerLinear, buildFramework, buildHint, buildJuryCertification, From 1f05d70e90cfc829633f85f99cd4bbd9d410c994 Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Fri, 15 Nov 2024 11:31:33 +0100 Subject: [PATCH 6/9] refactor(api): remove forced competences parameter --- .../scenario-simulator-controller.js | 2 - .../application/scenario-simulator-route.js | 1 - .../simulate-flash-assessment-scenario.js | 2 - .../scenario-simulator-controller_test.js | 61 ------------------- 4 files changed, 66 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index 38eaf9474c8..a9ff01c4099 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -25,7 +25,6 @@ async function simulateFlashAssessmentScenario( stopAtChallenge, initialCapacity, numberOfIterations = 1, - forcedCompetences, useObsoleteChallenges, challengePickProbability, challengesBetweenSameCompetence, @@ -59,7 +58,6 @@ async function simulateFlashAssessmentScenario( locale, stopAtChallenge, initialCapacity, - forcedCompetences, useObsoleteChallenges, challengesBetweenSameCompetence, limitToOneQuestionPerTube, diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index d6c461d524f..fe2af02713d 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -13,7 +13,6 @@ const _baseScenarioParametersValidator = Joi.object().keys({ initialCapacity: Joi.number().integer().min(-8).max(8), stopAtChallenge: Joi.number().integer().min(0), numberOfIterations: Joi.number().integer().min(0), - forcedCompetencies: Joi.array().items(Joi.string()), useObsoleteChallenges: Joi.boolean(), challengePickProbability: Joi.number().min(0).max(100), challengesBetweenSameCompetence: Joi.number().min(0), diff --git a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js index 357195539ad..9cbb23e31be 100644 --- a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js +++ b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js @@ -11,7 +11,6 @@ export async function simulateFlashAssessmentScenario({ stopAtChallenge, initialCapacity, useObsoleteChallenges, - forcedCompetences = [], challengesBetweenSameCompetence = 0, limitToOneQuestionPerTube = true, minimumEstimatedSuccessRateRanges = [], @@ -27,7 +26,6 @@ export async function simulateFlashAssessmentScenario({ const flashAssessmentAlgorithm = new FlashAssessmentAlgorithm({ flashAlgorithmImplementation: flashAlgorithmService, configuration: new FlashAssessmentAlgorithmConfiguration({ - forcedCompetences, limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges, enablePassageByAllCompetences, diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index ed470120355..c5683c51451 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -56,67 +56,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( ]; }); - context('When the scenario is forced to pass through some competences', function () { - context('When there is no warmup', function () { - it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { - // given - const forcedCompetences = ['compA', 'compB', 'compC']; - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusForCapacityImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusForCapacity - .withArgs(6) - .returns(pickAnswerStatusForCapacityImplementation); - - usecases.simulateFlashAssessmentScenario - .withArgs({ - pickAnswerStatus: pickAnswerStatusForCapacityImplementation, - locale: 'en', - pickChallenge: pickChallengeImplementation, - initialCapacity, - forcedCompetences, - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - initialCapacity, - capacity: 6, - forcedCompetences, - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - }); - context('When the scenario is forced to space competences', function () { it('should call the usecase with the right parameters', async function () { // given From 6dbefde64c214ce87681185681cdf8f4ac2b40a0 Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Fri, 15 Nov 2024 11:37:06 +0100 Subject: [PATCH 7/9] refactor(api): remove useObsoleteChallenges parameter --- .../scenario-simulator-controller.js | 2 - .../application/scenario-simulator-route.js | 1 - .../simulate-flash-assessment-scenario.js | 3 +- .../repositories/challenge-repository.js | 8 -- .../repositories/challenge-repository_test.js | 100 ------------------ ...simulate-flash-assessment-scenario_test.js | 8 +- 6 files changed, 5 insertions(+), 117 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index a9ff01c4099..0804f182f16 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -25,7 +25,6 @@ async function simulateFlashAssessmentScenario( stopAtChallenge, initialCapacity, numberOfIterations = 1, - useObsoleteChallenges, challengePickProbability, challengesBetweenSameCompetence, limitToOneQuestionPerTube, @@ -58,7 +57,6 @@ async function simulateFlashAssessmentScenario( locale, stopAtChallenge, initialCapacity, - useObsoleteChallenges, challengesBetweenSameCompetence, limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges, diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index fe2af02713d..dee25a79a74 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -13,7 +13,6 @@ const _baseScenarioParametersValidator = Joi.object().keys({ initialCapacity: Joi.number().integer().min(-8).max(8), stopAtChallenge: Joi.number().integer().min(0), numberOfIterations: Joi.number().integer().min(0), - useObsoleteChallenges: Joi.boolean(), challengePickProbability: Joi.number().min(0).max(100), challengesBetweenSameCompetence: Joi.number().min(0), limitToOneQuestionPerTube: Joi.boolean(), diff --git a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js index 9cbb23e31be..310c755d715 100644 --- a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js +++ b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js @@ -10,7 +10,6 @@ export async function simulateFlashAssessmentScenario({ pickAnswerStatus, stopAtChallenge, initialCapacity, - useObsoleteChallenges, challengesBetweenSameCompetence = 0, limitToOneQuestionPerTube = true, minimumEstimatedSuccessRateRanges = [], @@ -21,7 +20,7 @@ export async function simulateFlashAssessmentScenario({ challengeRepository, flashAlgorithmService, }) { - const challenges = await challengeRepository.findFlashCompatible({ locale, useObsoleteChallenges }); + const challenges = await challengeRepository.findActiveFlashCompatible({ locale }); const flashAssessmentAlgorithm = new FlashAssessmentAlgorithm({ flashAlgorithmImplementation: flashAlgorithmService, diff --git a/api/src/shared/infrastructure/repositories/challenge-repository.js b/api/src/shared/infrastructure/repositories/challenge-repository.js index c17f7d2207d..f0e7fcb1b99 100644 --- a/api/src/shared/infrastructure/repositories/challenge-repository.js +++ b/api/src/shared/infrastructure/repositories/challenge-repository.js @@ -105,13 +105,6 @@ const findOperativeFlashCompatible = async function ({ return _toDomainCollection({ challengeDataObjects, skills, successProbabilityThreshold }); }; -const findFlashCompatible = async function ({ locale, useObsoleteChallenges } = {}) { - _assertLocaleIsDefined(locale); - const challengeDataObjects = await challengeDatasource.findFlashCompatible({ locale, useObsoleteChallenges }); - const skills = await skillDatasource.list(); - return _toDomainCollection({ challengeDataObjects, skills }); -}; - const findFlashCompatibleWithoutLocale = async function ({ useObsoleteChallenges } = {}) { const challengeDataObjects = await challengeDatasource.findFlashCompatibleWithoutLocale({ useObsoleteChallenges }); const skills = await skillDatasource.list(); @@ -132,7 +125,6 @@ export async function getManyTypes(ids) { export { findActiveFlashCompatible, - findFlashCompatible, findFlashCompatibleWithoutLocale, findOperative, findOperativeBySkills, diff --git a/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js b/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js index 4c6ea744ea7..be30b40e119 100644 --- a/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js +++ b/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js @@ -473,106 +473,6 @@ describe('Integration | Repository | challenge-repository', function () { }); }); - describe('#findFlashCompatible', function () { - beforeEach(function () { - // given - const skill = domainBuilder.buildSkill({ id: 'recSkill1' }); - const locales = ['fr-fr']; - const activeChallenge = domainBuilder.buildChallenge({ - id: 'activeChallenge', - skill, - status: 'validé', - locales, - }); - const archivedChallenge = domainBuilder.buildChallenge({ - id: 'archivedChallenge', - skill, - status: 'archivé', - locales, - }); - const outdatedChallenge = domainBuilder.buildChallenge({ - id: 'outdatedChallenge', - skill, - status: 'périmé', - locales, - }); - const learningContent = { - skills: [{ ...skill, status: 'actif', level: skill.difficulty }], - challenges: [ - { ...activeChallenge, skillId: 'recSkill1', alpha: 3.57, delta: -8.99 }, - { ...archivedChallenge, skillId: 'recSkill1', alpha: 3.2, delta: 1.06 }, - { ...outdatedChallenge, skillId: 'recSkill1', alpha: 4.1, delta: -2.08 }, - ], - }; - mockLearningContent(learningContent); - }); - - context('without requesting obsolete challenges', function () { - it('should return all flash compatible challenges with skills', async function () { - // given - const locale = 'fr-fr'; - - // when - const actualChallenges = await challengeRepository.findFlashCompatible({ - locale, - }); - - // then - expect(actualChallenges).to.have.lengthOf(2); - expect(actualChallenges[0]).to.be.instanceOf(Challenge); - expect(actualChallenges[0]).to.deep.contain({ - status: 'validé', - }); - expect(actualChallenges[1]).to.deep.contain({ - status: 'archivé', - }); - }); - - it('should allow overriding success probability threshold default value', async function () { - // given - const successProbabilityThreshold = 0.75; - - // when - const actualChallenges = await challengeRepository.findActiveFlashCompatible({ - locale: 'fr-fr', - successProbabilityThreshold, - }); - - // then - expect(actualChallenges).to.have.lengthOf(1); - expect(actualChallenges[0]).to.be.instanceOf(Challenge); - expect(actualChallenges[0].minimumCapability).to.equal(-8.682265465359073); - }); - }); - - context('when requesting obsolete challenges', function () { - it('should return all flash compatible challenges with skills', async function () { - // given - const locale = 'fr-fr'; - - // when - const actualChallenges = await challengeRepository.findFlashCompatible({ - locale, - useObsoleteChallenges: true, - }); - - // then - expect(actualChallenges).to.have.lengthOf(3); - expect(actualChallenges[0]).to.be.instanceOf(Challenge); - expect(actualChallenges[0]).to.deep.contain({ - status: 'validé', - }); - expect(actualChallenges[1]).to.deep.contain({ - status: 'archivé', - }); - - expect(actualChallenges[2]).to.deep.contain({ - status: 'périmé', - }); - }); - }); - }); - describe('#findFlashCompatibleWithoutLocale', function () { beforeEach(function () { // given diff --git a/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js index 99d21c6bf71..20aa7d1dbfd 100644 --- a/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js +++ b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js @@ -229,9 +229,9 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { const enablePassageByAllCompetences = false; const challenge = domainBuilder.buildChallenge({ id: 1 }); const challengeRepository = { - findFlashCompatible: sinon.stub(), + findActiveFlashCompatible: sinon.stub(), }; - challengeRepository.findFlashCompatible.resolves([challenge]); + challengeRepository.findActiveFlashCompatible.resolves([challenge]); const pickChallenge = sinon.stub(); const pickAnswerStatus = sinon.stub(); @@ -321,7 +321,7 @@ function prepareStubs({ const allChallenges = [firstChallenge, secondChallenge, thirdChallenge]; const challengeRepository = { - findFlashCompatible: sinon.stub(), + findActiveFlashCompatible: sinon.stub(), }; const pickChallenge = sinon.stub(); const pickAnswerStatus = sinon.stub(); @@ -430,7 +430,7 @@ function prepareStubs({ .returns([thirdChallenge, secondChallenge]); } - challengeRepository.findFlashCompatible.resolves([firstChallenge, secondChallenge, thirdChallenge]); + challengeRepository.findActiveFlashCompatible.resolves([firstChallenge, secondChallenge, thirdChallenge]); pickChallenge .withArgs({ From 1650255d5cd2506802370157884fd52a608fba1a Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Fri, 15 Nov 2024 11:56:23 +0100 Subject: [PATCH 8/9] refactor(api): remove unused methods in challenge repo and data source --- .../learning-content/challenge-datasource.js | 5 -- .../repositories/challenge-repository.js | 11 --- .../repositories/challenge-repository_test.js | 86 ------------------- .../challenge-datasource_test.js | 31 ------- 4 files changed, 133 deletions(-) diff --git a/api/src/shared/infrastructure/datasources/learning-content/challenge-datasource.js b/api/src/shared/infrastructure/datasources/learning-content/challenge-datasource.js index 056d5dbc997..76baf6aa51f 100644 --- a/api/src/shared/infrastructure/datasources/learning-content/challenge-datasource.js +++ b/api/src/shared/infrastructure/datasources/learning-content/challenge-datasource.js @@ -76,11 +76,6 @@ const challengeDatasource = datasource.extend({ return flashChallenges.filter((challengeData) => _challengeHasStatus(challengeData, [VALIDATED_CHALLENGE])); }, - async findOperativeFlashCompatible(locale) { - const flashChallenges = await this.findFlashCompatible({ locale }); - return flashChallenges.filter((challengeData) => _challengeHasStatus(challengeData, OPERATIVE_CHALLENGES)); - }, - async findFlashCompatible({ locale, useObsoleteChallenges }) { const challenges = await this.listByLocale(locale); diff --git a/api/src/shared/infrastructure/repositories/challenge-repository.js b/api/src/shared/infrastructure/repositories/challenge-repository.js index f0e7fcb1b99..55465aa6958 100644 --- a/api/src/shared/infrastructure/repositories/challenge-repository.js +++ b/api/src/shared/infrastructure/repositories/challenge-repository.js @@ -95,16 +95,6 @@ const findActiveFlashCompatible = async function ({ return _toDomainCollection({ challengeDataObjects, skills: activeSkills, successProbabilityThreshold }); }; -const findOperativeFlashCompatible = async function ({ - locale, - successProbabilityThreshold = config.features.successProbabilityThreshold, -} = {}) { - _assertLocaleIsDefined(locale); - const challengeDataObjects = await challengeDatasource.findOperativeFlashCompatible(locale); - const skills = await skillDatasource.list(); - return _toDomainCollection({ challengeDataObjects, skills, successProbabilityThreshold }); -}; - const findFlashCompatibleWithoutLocale = async function ({ useObsoleteChallenges } = {}) { const challengeDataObjects = await challengeDatasource.findFlashCompatibleWithoutLocale({ useObsoleteChallenges }); const skills = await skillDatasource.list(); @@ -128,7 +118,6 @@ export { findFlashCompatibleWithoutLocale, findOperative, findOperativeBySkills, - findOperativeFlashCompatible, findValidated, findValidatedByCompetenceId, findValidatedBySkillId, diff --git a/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js b/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js index be30b40e119..3cdd864ba6c 100644 --- a/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js +++ b/api/tests/shared/integration/infrastructure/repositories/challenge-repository_test.js @@ -625,92 +625,6 @@ describe('Integration | Repository | challenge-repository', function () { }); }); - describe('#findOperativeFlashCompatible', function () { - beforeEach(function () { - // given - const skill = domainBuilder.buildSkill({ id: 'recSkill1' }); - const locales = ['fr-fr']; - const activeChallenge = domainBuilder.buildChallenge({ - id: 'activeChallenge', - skill, - status: 'validé', - locales, - }); - const archivedChallenge = domainBuilder.buildChallenge({ - id: 'archivedChallenge', - skill, - status: 'archivé', - locales, - }); - const outdatedChallenge = domainBuilder.buildChallenge({ - id: 'outdatedChallenge', - skill, - status: 'périmé', - locales, - }); - const learningContent = { - skills: [{ ...skill, status: 'actif', level: skill.difficulty }], - challenges: [ - { ...activeChallenge, skillId: 'recSkill1', alpha: 3.57, delta: -8.99 }, - { ...archivedChallenge, skillId: 'recSkill1', alpha: 1.98723, delta: 5.42183 }, - { ...outdatedChallenge, skillId: 'recSkill1' }, - ], - }; - mockLearningContent(learningContent); - }); - - it('should return only flash compatible challenges with skills', async function () { - // given - const locale = 'fr-fr'; - - // when - const actualChallenges = await challengeRepository.findOperativeFlashCompatible({ locale }); - - // then - expect(actualChallenges).to.have.lengthOf(2); - expect(actualChallenges[1]).to.be.instanceOf(Challenge); - expect(actualChallenges[0]).to.deep.contain({ - id: 'activeChallenge', - status: 'validé', - locales: ['fr-fr'], - difficulty: -8.99, - discriminant: 3.57, - minimumCapability: -8.165227176704079, - }); - expect(actualChallenges[0].skill).to.contain({ - id: 'recSkill1', - }); - expect(actualChallenges[1]).to.deep.contain({ - id: 'archivedChallenge', - status: 'archivé', - locales: ['fr-fr'], - difficulty: 5.42183, - discriminant: 1.98723, - minimumCapability: 6.9035100164885, - }); - expect(actualChallenges[1].skill).to.contain({ - id: 'recSkill1', - }); - }); - - it('should allow overriding success probability threshold default value', async function () { - // given - const successProbabilityThreshold = 0.75; - - // when - const actualChallenges = await challengeRepository.findOperativeFlashCompatible({ - locale: 'fr-fr', - successProbabilityThreshold, - }); - - // then - expect(actualChallenges).to.have.lengthOf(2); - expect(actualChallenges[0]).to.be.instanceOf(Challenge); - expect(actualChallenges[0].minimumCapability).to.equal(-8.682265465359073); - expect(actualChallenges[1].minimumCapability).to.equal(5.974666002208154); - }); - }); - describe('#findValidatedBySkillId', function () { it('should return validated challenges of a skill', async function () { // given diff --git a/api/tests/shared/unit/infrastructure/datasources/learning-content/challenge-datasource_test.js b/api/tests/shared/unit/infrastructure/datasources/learning-content/challenge-datasource_test.js index 0c7bc4f25b9..8bf5d6909bc 100644 --- a/api/tests/shared/unit/infrastructure/datasources/learning-content/challenge-datasource_test.js +++ b/api/tests/shared/unit/infrastructure/datasources/learning-content/challenge-datasource_test.js @@ -392,37 +392,6 @@ describe('Unit | Infrastructure | Datasource | Learning Content | ChallengeDatas }); }); - describe('#findOperativeFlashCompatible', function () { - beforeEach(function () { - sinon.stub(lcms, 'getLatestRelease').resolves({ - challenges: [ - challenge_competence1, - challenge_competence1_noSkills, - challenge_competence2, - challenge_web1, - challenge_web1_notValidated, - challenge_web2_en, - challenge_web3, - challenge_web3_archived, - ], - }); - }); - - it('should resolve an array of matching Challenges from learning content', async function () { - // when - const locale = 'fr-fr'; - const result = await challengeDatasource.findOperativeFlashCompatible(locale); - - // then - expect(_.map(result, 'id')).to.deep.equal([ - challenge_competence1.id, - challenge_competence2.id, - challenge_web3.id, - challenge_web3_archived.id, - ]); - }); - }); - describe('#findValidatedBySkillId', function () { beforeEach(function () { sinon.stub(lcms, 'getLatestRelease').resolves({ From 6dd867934ba1baaef59b3912f096882cb9ce47a7 Mon Sep 17 00:00:00 2001 From: Alexandre COIN Date: Fri, 15 Nov 2024 14:20:21 +0100 Subject: [PATCH 9/9] refactor(api): replace enablePassageByAllCompetences parameter by value used in production --- .../scenario-simulator-controller.js | 2 - .../application/scenario-simulator-route.js | 1 - .../simulate-flash-assessment-scenario.js | 5 +- .../scenario-simulator-controller_test.js | 59 ------------------- ...simulate-flash-assessment-scenario_test.js | 9 --- 5 files changed, 3 insertions(+), 73 deletions(-) diff --git a/api/src/certification/flash-certification/application/scenario-simulator-controller.js b/api/src/certification/flash-certification/application/scenario-simulator-controller.js index 0804f182f16..efd008ed8d3 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-controller.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-controller.js @@ -29,7 +29,6 @@ async function simulateFlashAssessmentScenario( challengesBetweenSameCompetence, limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges: minimumEstimatedSuccessRateRangesDto, - enablePassageByAllCompetences, doubleMeasuresUntil, variationPercent, variationPercentUntil, @@ -60,7 +59,6 @@ async function simulateFlashAssessmentScenario( challengesBetweenSameCompetence, limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges, - enablePassageByAllCompetences, doubleMeasuresUntil, variationPercent, variationPercentUntil, diff --git a/api/src/certification/flash-certification/application/scenario-simulator-route.js b/api/src/certification/flash-certification/application/scenario-simulator-route.js index dee25a79a74..4e830212a7d 100644 --- a/api/src/certification/flash-certification/application/scenario-simulator-route.js +++ b/api/src/certification/flash-certification/application/scenario-simulator-route.js @@ -17,7 +17,6 @@ const _baseScenarioParametersValidator = Joi.object().keys({ challengesBetweenSameCompetence: Joi.number().min(0), limitToOneQuestionPerTube: Joi.boolean(), minimumEstimatedSuccessRateRanges: Joi.array().items(_successRatesConfigurationValidator), - enablePassageByAllCompetences: Joi.boolean(), doubleMeasuresUntil: Joi.number().min(0), variationPercent: Joi.number().min(0).max(1), variationPercentUntil: Joi.number().min(0), diff --git a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js index 310c755d715..1b23dacd5ff 100644 --- a/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js +++ b/api/src/certification/flash-certification/domain/usecases/simulate-flash-assessment-scenario.js @@ -13,7 +13,6 @@ export async function simulateFlashAssessmentScenario({ challengesBetweenSameCompetence = 0, limitToOneQuestionPerTube = true, minimumEstimatedSuccessRateRanges = [], - enablePassageByAllCompetences = false, doubleMeasuresUntil = 0, variationPercent, variationPercentUntil, @@ -22,12 +21,14 @@ export async function simulateFlashAssessmentScenario({ }) { const challenges = await challengeRepository.findActiveFlashCompatible({ locale }); + const enablePassageByAllCompetencesValueInProduction = true; + const flashAssessmentAlgorithm = new FlashAssessmentAlgorithm({ flashAlgorithmImplementation: flashAlgorithmService, configuration: new FlashAssessmentAlgorithmConfiguration({ limitToOneQuestionPerTube, minimumEstimatedSuccessRateRanges, - enablePassageByAllCompetences, + enablePassageByAllCompetences: enablePassageByAllCompetencesValueInProduction, variationPercent, variationPercentUntil, doubleMeasuresUntil, diff --git a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js index c5683c51451..9d8c45c63dc 100644 --- a/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js +++ b/api/tests/certification/flash-certification/integration/application/scenario-simulator-controller_test.js @@ -376,65 +376,6 @@ describe('Integration | Application | scenario-simulator-controller', function ( }); }); - context('When configuring the passage by all competences', function () { - it('should call simulateFlashAssessmentScenario usecase with correct arguments', async function () { - // given - const enablePassageByAllCompetences = true; - - const pickChallengeImplementation = sinon.stub(); - pickChallengeService.chooseNextChallenge.withArgs().returns(pickChallengeImplementation); - const pickAnswerStatusForCapacityImplementation = sinon.stub(); - pickAnswerStatusService.pickAnswerStatusForCapacity - .withArgs(6) - .returns(pickAnswerStatusForCapacityImplementation); - - usecases.simulateFlashAssessmentScenario - .withArgs({ - pickAnswerStatus: pickAnswerStatusForCapacityImplementation, - locale: 'en', - pickChallenge: pickChallengeImplementation, - initialCapacity, - enablePassageByAllCompetences, - }) - .resolves(simulationResults); - securityPreHandlers.checkAdminMemberHasRoleSuperAdmin.returns(() => true); - - // when - const response = await httpTestServer.request( - 'POST', - '/api/scenario-simulator', - { - initialCapacity, - capacity: 6, - enablePassageByAllCompetences, - }, - null, - { 'accept-language': 'en' }, - ); - - // then - expect(response.statusCode).to.equal(200); - const parsedResult = parseJsonStream(response); - expect(parsedResult).to.deep.equal([ - { - index: 0, - simulationReport: [ - { - challengeId: challenge1.id, - errorRate: errorRate1, - capacity: capacity1, - minimumCapability: 0.6190392084062237, - answerStatus: 'ok', - reward: reward1, - difficulty: challenge1.difficulty, - discriminant: challenge1.discriminant, - }, - ], - }, - ]); - }); - }); - context('When the scenario is capacity', function () { context('When the route is called with correct arguments', function () { context('When the route is called without an initial capacity', function () { diff --git a/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js index 20aa7d1dbfd..835a4efbd31 100644 --- a/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js +++ b/api/tests/unit/domain/usecases/simulate-flash-assessment-scenario_test.js @@ -26,7 +26,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { pickChallenge, pickAnswerStatus, flashAlgorithmService, - enablePassageByAllCompetences: false, }); // then @@ -69,7 +68,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { initialCapacity, flashAlgorithmService, limitToOneQuestionPerTube: false, - enablePassageByAllCompetences: false, }); // then @@ -88,7 +86,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { it('should return an array of estimated level, challenge, reward and error rate for each answer', async function () { // given const limitToOneQuestionPerTube = false; - const enablePassageByAllCompetences = false; const { challengeRepository, @@ -136,7 +133,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { pickAnswerStatus, limitToOneQuestionPerTube, flashAlgorithmService, - enablePassageByAllCompetences, }); // then @@ -155,7 +151,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { it('should return an array of estimated level, challenge, reward and error rate for each answer', async function () { // given const limitToOneQuestionPerTube = false; - const enablePassageByAllCompetences = false; const minimumEstimatedSuccessRateRanges = [ domainBuilder.buildFlashAssessmentAlgorithmSuccessRateHandlerFixed({ startingChallengeIndex: 0, @@ -178,7 +173,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { minimumEstimatedSuccessRateRanges, flashAlgorithmService, limitToOneQuestionPerTube, - enablePassageByAllCompetences, }); // then @@ -208,7 +202,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { pickChallenge, pickAnswerStatus, flashAlgorithmService, - enablePassageByAllCompetences: false, doubleMeasuresUntil: 2, }); @@ -226,7 +219,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { it('should stop simulating', async function () { // given const limitToOneQuestionPerTube = false; - const enablePassageByAllCompetences = false; const challenge = domainBuilder.buildChallenge({ id: 1 }); const challengeRepository = { findActiveFlashCompatible: sinon.stub(), @@ -278,7 +270,6 @@ describe('Unit | UseCase | simulate-flash-assessment-scenario', function () { pickAnswerStatus, flashAlgorithmService, limitToOneQuestionPerTube, - enablePassageByAllCompetences, }); // then