Skip to content

Commit

Permalink
fix(api): prevent candidate from answering the challenge if a validat…
Browse files Browse the repository at this point in the history
…ed live alert exists
  • Loading branch information
alexandrecoin authored Nov 13, 2024
1 parent 541031d commit c8a9280
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ const correctAnswerThenUpdateAssessment = async function ({
let certificationCandidate;

if (assessment.isCertification()) {
const onGoingCertificationChallengeLiveAlert =
await certificationChallengeLiveAlertRepository.getOngoingByChallengeIdAndAssessmentId({
const ongoingOrValidatedCertificationChallengeLiveAlert =
await certificationChallengeLiveAlertRepository.getOngoingOrValidatedByChallengeIdAndAssessmentId({
challengeId: challenge.id,
assessmentId: assessment.id,
});

if (onGoingCertificationChallengeLiveAlert) {
if (ongoingOrValidatedCertificationChallengeLiveAlert) {
throw new ForbiddenAccess('An alert has been set.');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { correctAnswerThenUpdateAssessment } from '../../../../lib/domain/usecases/correct-answer-then-update-assessment.js';
import { CertificationChallengeLiveAlertStatus } from '../../../../src/certification/shared/domain/models/CertificationChallengeLiveAlert.js';
import { EmptyAnswerError } from '../../../../src/evaluation/domain/errors.js';
import { AnswerJob } from '../../../../src/quest/domain/models/AnwserJob.js';
import {
Expand Down Expand Up @@ -58,7 +59,7 @@ describe('Unit | Domain | Use Cases | correct-answer-then-update-assessment', fu
flashAssessmentResultRepository = { save: sinon.stub() };
scorecardService = { computeScorecard: sinon.stub() };
knowledgeElementRepository = { findUniqByUserIdAndAssessmentId: sinon.stub() };
certificationChallengeLiveAlertRepository = { getOngoingByChallengeIdAndAssessmentId: sinon.stub() };
certificationChallengeLiveAlertRepository = { getOngoingOrValidatedByChallengeIdAndAssessmentId: sinon.stub() };
certificationEvaluationCandidateRepository = { findByAssessmentId: sinon.stub() };
flashAlgorithmService = { getCapacityAndErrorRate: sinon.stub() };
algorithmDataFetcherService = { fetchForFlashLevelEstimation: sinon.stub() };
Expand Down Expand Up @@ -1128,37 +1129,75 @@ describe('Unit | Domain | Use Cases | correct-answer-then-update-assessment', fu
});
});

context('when a live alert has been set in V3 certification', function () {
it('should throw an error', async function () {
// given
const challenge = domainBuilder.buildChallenge({ id: '123' });
const assessment = domainBuilder.buildAssessment({
userId,
lastQuestionDate: nowDate,
state: Assessment.states.STARTED,
});
const answer = domainBuilder.buildAnswer({ challengeId: challenge.id });
const certificationChallengeLiveAlert = domainBuilder.buildCertificationChallengeLiveAlert({
assessmentId: assessment.id,
challengeId: challenge.id,
});
assessmentRepository.get.resolves(assessment);
challengeRepository.get.withArgs(challenge.id).resolves(challenge);
context('when a live alert has been set for the current challenge in V3 certification', function () {
context('when the live alert is ongoing', function () {
it('should throw an error', async function () {
// given
const challenge = domainBuilder.buildChallenge({ id: '123' });
const assessment = domainBuilder.buildAssessment({
userId,
lastQuestionDate: nowDate,
state: Assessment.states.STARTED,
});
const answer = domainBuilder.buildAnswer({ challengeId: challenge.id });
const certificationChallengeLiveAlert = domainBuilder.buildCertificationChallengeLiveAlert({
assessmentId: assessment.id,
challengeId: challenge.id,
status: CertificationChallengeLiveAlertStatus.ONGOING,
});
assessmentRepository.get.resolves(assessment);
challengeRepository.get.withArgs(challenge.id).resolves(challenge);

certificationChallengeLiveAlertRepository.getOngoingByChallengeIdAndAssessmentId
.withArgs({ challengeId: challenge.id, assessmentId: assessment.id })
.resolves(certificationChallengeLiveAlert);
certificationChallengeLiveAlertRepository.getOngoingOrValidatedByChallengeIdAndAssessmentId
.withArgs({ challengeId: challenge.id, assessmentId: assessment.id })
.resolves(certificationChallengeLiveAlert);

// when
const error = await catchErr(correctAnswerThenUpdateAssessment)({
answer,
userId,
...dependencies,
// when
const error = await catchErr(correctAnswerThenUpdateAssessment)({
answer,
userId,
...dependencies,
});

// then
expect(error).to.be.an.instanceOf(ForbiddenAccess);
expect(error.message).to.equal('An alert has been set.');
});
});

// then
expect(error).to.be.an.instanceOf(ForbiddenAccess);
expect(error.message).to.equal('An alert has been set.');
context('when the live alert is validated', function () {
it('should throw an error', async function () {
// given
const challenge = domainBuilder.buildChallenge({ id: '123' });
const assessment = domainBuilder.buildAssessment({
userId,
lastQuestionDate: nowDate,
state: Assessment.states.STARTED,
});
const answer = domainBuilder.buildAnswer({ challengeId: challenge.id });
const certificationChallengeLiveAlert = domainBuilder.buildCertificationChallengeLiveAlert({
assessmentId: assessment.id,
challengeId: challenge.id,
status: CertificationChallengeLiveAlertStatus.VALIDATED,
});
assessmentRepository.get.resolves(assessment);
challengeRepository.get.withArgs(challenge.id).resolves(challenge);

certificationChallengeLiveAlertRepository.getOngoingOrValidatedByChallengeIdAndAssessmentId
.withArgs({ challengeId: challenge.id, assessmentId: assessment.id })
.resolves(certificationChallengeLiveAlert);

// when
const error = await catchErr(correctAnswerThenUpdateAssessment)({
answer,
userId,
...dependencies,
});

// then
expect(error).to.be.an.instanceOf(ForbiddenAccess);
expect(error.message).to.equal('An alert has been set.');
});
});
});

Expand Down

0 comments on commit c8a9280

Please sign in to comment.