diff --git a/api/src/certification/evaluation/domain/services/scoring/scoring-v3.js b/api/src/certification/evaluation/domain/services/scoring/scoring-v3.js index 19d72004e34..927707cca0a 100644 --- a/api/src/certification/evaluation/domain/services/scoring/scoring-v3.js +++ b/api/src/certification/evaluation/domain/services/scoring/scoring-v3.js @@ -64,6 +64,7 @@ export const handleV3CertificationScoring = async ({ locale, ); + _restoreCalibrationValues(certificationChallengesForScoring, answeredChallenges); const certificationCourse = await certificationCourseRepository.get({ id: certificationCourseId }); const abortReason = certificationCourse.getAbortReason(); @@ -127,6 +128,14 @@ export const handleV3CertificationScoring = async ({ return certificationCourse; }; +function _restoreCalibrationValues(certificationChallengesForScoring, answeredChallenges) { + certificationChallengesForScoring.forEach((certificationChallengeForScoring) => { + const answeredChallenge = answeredChallenges.find(({ id }) => id === certificationChallengeForScoring.id); + answeredChallenge.discriminant = certificationChallengeForScoring.discriminant; + answeredChallenge.difficulty = certificationChallengeForScoring.difficulty; + }); +} + function _createV3AssessmentResult({ allAnswers, emitter, diff --git a/api/src/certification/scoring/domain/models/CertificationAssessmentHistory.js b/api/src/certification/scoring/domain/models/CertificationAssessmentHistory.js index 92620bb8469..776457cf727 100644 --- a/api/src/certification/scoring/domain/models/CertificationAssessmentHistory.js +++ b/api/src/certification/scoring/domain/models/CertificationAssessmentHistory.js @@ -1,10 +1,20 @@ +/** + * @typedef {import('../../../flash-certification/domain/models/FlashAssessmentAlgorithm.js').FlashAssessmentAlgorithm} FlashAssessmentAlgorithm + * @typedef {import('./CertificationChallengeForScoring.js').CertificationChallengeForScoring} CertificationChallengeForScoring + * @typedef {import('../../../../evaluation/domain/models/Answer.js').Answer} Answer + */ import { CertificationChallengeCapacity } from './CertificationChallengeCapacity.js'; export class CertificationAssessmentHistory { constructor({ capacityHistory }) { this.capacityHistory = capacityHistory; } - // WARN: challenges are not Array but Array + /** + * @param {Object} params + * @param {FlashAssessmentAlgorithm } params.algorithm + * @param {Array} params.challenges + * @param {Array} params.allAnswers + **/ static fromChallengesAndAnswers({ algorithm, challenges, allAnswers }) { const capacityAndErrorRateHistory = algorithm.getCapacityAndErrorRateHistory({ allAnswers, diff --git a/api/src/certification/scoring/domain/models/CertificationAssessmentScoreV3.js b/api/src/certification/scoring/domain/models/CertificationAssessmentScoreV3.js index 51450f5e06a..4c904c7bd1d 100644 --- a/api/src/certification/scoring/domain/models/CertificationAssessmentScoreV3.js +++ b/api/src/certification/scoring/domain/models/CertificationAssessmentScoreV3.js @@ -43,7 +43,13 @@ class CertificationAssessmentScoreV3 { allAnswers, }); - if (_shouldDowngradeCapacity({ flashAssessmentAlgorithmConfiguration, answers: allAnswers, abortReason })) { + if ( + _shouldDowngradeCapacity({ + maximumAssessmentLength: flashAssessmentAlgorithmConfiguration.maximumAssessmentLength, + answers: allAnswers, + abortReason, + }) + ) { capacity = scoringDegradationService.downgradeCapacity({ algorithm, capacity, diff --git a/api/tests/certification/evaluation/unit/domain/services/scoring/scoring-v3_test.js b/api/tests/certification/evaluation/unit/domain/services/scoring/scoring-v3_test.js index 24d950a0eb2..645a2432ac7 100644 --- a/api/tests/certification/evaluation/unit/domain/services/scoring/scoring-v3_test.js +++ b/api/tests/certification/evaluation/unit/domain/services/scoring/scoring-v3_test.js @@ -50,8 +50,12 @@ describe('Certification | Shared | Unit | Domain | Services | Scoring V3', funct competenceMarkRepository = { save: sinon.stub().rejects(new Error('Args mismatch')) }; flashAlgorithmConfigurationRepository = { getMostRecentBeforeDate: sinon.stub() }; flashAlgorithmService = { - getCapacityAndErrorRate: sinon.stub().rejects(new Error('Args mismatch')), - getCapacityAndErrorRateHistory: sinon.stub().rejects(new Error('Args mismatch')), + getCapacityAndErrorRate: sinon.stub().callsFake((a) => { + throw new Error(`Args mismatch, was called with ${JSON.stringify(a.challenges)}`); + }), + getCapacityAndErrorRateHistory: sinon.stub().callsFake(() => { + throw new Error('Args mismatch'); + }), }; scoringDegradationService = { downgradeCapacity: sinon.stub().rejects(new Error('Args mismatch')) }; scoringConfigurationRepository = { @@ -1032,6 +1036,18 @@ describe('Certification | Shared | Unit | Domain | Services | Scoring V3', funct capacityHistory, }); + const challengeExcludedFromCalibration = domainBuilder.buildChallenge({ + ...answeredChallenges[0], + discriminant: null, + difficulty: null, + }); + + const challengesAfterCalibration = answeredChallenges.slice(1); + + challengeRepository.getMany + .withArgs(answeredChallenges.map((e) => e.id)) + .returns([challengeExcludedFromCalibration, ...challengesAfterCalibration]); + certificationChallengeForScoringRepository.getByCertificationCourseId .withArgs({ certificationCourseId }) .resolves(certificationChallengesForScoring); @@ -1044,7 +1060,7 @@ describe('Certification | Shared | Unit | Domain | Services | Scoring V3', funct .resolves(baseFlashAlgorithmConfiguration); flashAlgorithmService.getCapacityAndErrorRate .withArgs({ - challenges: allChallenges, + challenges: answeredChallenges, allAnswers: answers, capacity: sinon.match.number, variationPercent: undefined, @@ -1069,6 +1085,12 @@ describe('Certification | Shared | Unit | Domain | Services | Scoring V3', funct }, ]); + challengeRepository.findFlashCompatibleWithoutLocale + .withArgs({ + useObsoleteChallenges: true, + }) + .returns(challengesAfterCalibration); + scoringConfigurationRepository.getLatestByDateAndLocale .withArgs({ locale: 'fr', date: abortedCertificationCourse.getStartDate() }) .resolves(scoringConfiguration);