Skip to content

Commit c04badc

Browse files
tech(api): stop usecase if assessment is not started
1 parent 9936414 commit c04badc

File tree

2 files changed

+68
-28
lines changed

2 files changed

+68
-28
lines changed

api/src/shared/domain/usecases/get-next-challenge.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { AssessmentEndedError } from '../errors.js';
2+
13
export async function getNextChallenge({
24
assessmentId,
35
userId,
@@ -7,10 +9,10 @@ export async function getNextChallenge({
79
certificationEvaluationRepository,
810
}) {
911
const assessment = await assessmentRepository.get(assessmentId);
10-
11-
if (assessment.isStarted()) {
12-
await assessmentRepository.updateLastQuestionDate({ id: assessment.id, lastQuestionDate: new Date() });
12+
if (!assessment.isStarted()) {
13+
throw new AssessmentEndedError();
1314
}
15+
await assessmentRepository.updateLastQuestionDate({ id: assessment.id, lastQuestionDate: new Date() });
1416

1517
let nextChallenge = null;
1618
if (assessment.isCertification()) {

api/tests/shared/unit/domain/usecases/get-next-challenge_test.js

+63-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { AssessmentEndedError } from '../../../../../src/shared/domain/errors.js';
12
import { Assessment } from '../../../../../src/shared/domain/models/index.js';
23
import { getNextChallenge } from '../../../../../src/shared/domain/usecases/get-next-challenge.js';
3-
import { domainBuilder, expect, preventStubsToBeCalledUnexpectedly, sinon } from '../../../../test-helper.js';
4+
import { catchErr, domainBuilder, expect, preventStubsToBeCalledUnexpectedly, sinon } from '../../../../test-helper.js';
45

56
describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function () {
67
describe('#getNextChallenge', function () {
@@ -69,12 +70,37 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
6970
};
7071
});
7172

73+
context('when assessment is not started', function () {
74+
let assessment;
75+
76+
beforeEach(function () {
77+
assessment = domainBuilder.buildAssessment({ id: assessmentId, type: Assessment.types.PREVIEW });
78+
});
79+
80+
// eslint-disable-next-line mocha/no-setup-in-describe
81+
Object.values(Assessment.states)
82+
.filter((assessmentState) => assessmentState !== Assessment.states.STARTED)
83+
.forEach((assessmentState) => {
84+
it(`should throw a AssessmentEndedError when assessment is ${assessmentState}`, async function () {
85+
assessment.state = assessmentState;
86+
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
87+
88+
const err = await catchErr(getNextChallenge)(dependencies);
89+
90+
expect(err).to.be.instanceOf(AssessmentEndedError);
91+
});
92+
});
93+
});
94+
7295
context('Assessment types', function () {
7396
context('for assessment of type PREVIEW', function () {
7497
let assessment;
7598

7699
beforeEach(function () {
77-
assessment = domainBuilder.buildAssessment({ type: Assessment.types.PREVIEW });
100+
assessment = domainBuilder.buildAssessment({
101+
state: Assessment.states.STARTED,
102+
type: Assessment.types.PREVIEW,
103+
});
78104
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
79105
assessmentRepository_updateLastQuestionDateStub.resolves();
80106
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -93,7 +119,10 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
93119
let assessment;
94120

95121
beforeEach(function () {
96-
assessment = domainBuilder.buildAssessment({ type: Assessment.types.DEMO });
122+
assessment = domainBuilder.buildAssessment({
123+
state: Assessment.states.STARTED,
124+
type: Assessment.types.DEMO,
125+
});
97126
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
98127
assessmentRepository_updateLastQuestionDateStub.resolves();
99128
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -112,7 +141,10 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
112141
let assessment;
113142

114143
beforeEach(function () {
115-
assessment = domainBuilder.buildAssessment({ type: Assessment.types.CAMPAIGN });
144+
assessment = domainBuilder.buildAssessment({
145+
state: Assessment.states.STARTED,
146+
type: Assessment.types.CAMPAIGN,
147+
});
116148
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
117149
assessmentRepository_updateLastQuestionDateStub.resolves();
118150
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -133,7 +165,10 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
133165
let assessment;
134166

135167
beforeEach(function () {
136-
assessment = domainBuilder.buildAssessment({ type: Assessment.types.COMPETENCE_EVALUATION });
168+
assessment = domainBuilder.buildAssessment({
169+
state: Assessment.states.STARTED,
170+
type: Assessment.types.COMPETENCE_EVALUATION,
171+
});
137172
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
138173
assessmentRepository_updateLastQuestionDateStub.resolves();
139174
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -154,7 +189,11 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
154189
let assessment;
155190

156191
beforeEach(function () {
157-
assessment = domainBuilder.buildAssessment({ id: assessmentId, type: Assessment.types.CERTIFICATION });
192+
assessment = domainBuilder.buildAssessment({
193+
state: Assessment.states.STARTED,
194+
id: assessmentId,
195+
type: Assessment.types.CERTIFICATION,
196+
});
158197
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
159198
assessmentRepository_updateLastQuestionDateStub.resolves();
160199
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -175,7 +214,11 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
175214
let assessment;
176215

177216
beforeEach(function () {
178-
assessment = domainBuilder.buildAssessment({ id: assessmentId, type: 'coucou les zamis' });
217+
assessment = domainBuilder.buildAssessment({
218+
state: Assessment.states.STARTED,
219+
id: assessmentId,
220+
type: 'coucou les zamis',
221+
});
179222
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
180223
assessmentRepository_updateLastQuestionDateStub.resolves();
181224
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
@@ -196,7 +239,11 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
196239

197240
beforeEach(function () {
198241
clock = sinon.useFakeTimers(new Date('2023-10-05'));
199-
assessment = domainBuilder.buildAssessment({ id: assessmentId, type: Assessment.types.PREVIEW });
242+
assessment = domainBuilder.buildAssessment({
243+
state: Assessment.states.STARTED,
244+
id: assessmentId,
245+
type: Assessment.types.PREVIEW,
246+
});
200247
evaluationUsecases_getNextChallengeForPreviewStub.withArgs({}).resolves({ id: 'someChallengeId' });
201248
assessmentRepository_updateWhenNewChallengeIsAskedStub.resolves();
202249
});
@@ -205,22 +252,7 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
205252
clock.restore();
206253
});
207254

208-
// eslint-disable-next-line mocha/no-setup-in-describe
209-
Object.values(Assessment.states)
210-
.filter((assessmentState) => assessmentState !== Assessment.states.STARTED)
211-
.forEach((assessmentState) => {
212-
it(`should not update the last question date when assessment is in state ${assessmentState}`, async function () {
213-
assessment.state = assessmentState;
214-
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
215-
216-
await getNextChallenge(dependencies);
217-
218-
expect(assessmentRepository_updateLastQuestionDateStub).to.not.have.been.called;
219-
});
220-
});
221-
222-
it(`should update the last question date when assessment is in state Started`, async function () {
223-
assessment.state = Assessment.states.STARTED;
255+
it(`should update the last question date`, async function () {
224256
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
225257
assessmentRepository_updateLastQuestionDateStub.resolves();
226258

@@ -239,7 +271,11 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
239271

240272
context('when no next challenge has been found', function () {
241273
it('should not update last challenge asked', async function () {
242-
const assessment = domainBuilder.buildAssessment({ id: assessmentId, type: Assessment.types.PREVIEW });
274+
const assessment = domainBuilder.buildAssessment({
275+
id: assessmentId,
276+
state: Assessment.states.STARTED,
277+
type: Assessment.types.PREVIEW,
278+
});
243279
assessmentRepository_getStub.withArgs(assessmentId).resolves(assessment);
244280
evaluationUsecases_getNextChallengeForPreviewStub.withArgs({}).resolves(null);
245281

@@ -253,6 +289,7 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
253289
it('should not update last challenge asked', async function () {
254290
const assessment = domainBuilder.buildAssessment({
255291
id: assessmentId,
292+
state: Assessment.states.STARTED,
256293
type: Assessment.types.PREVIEW,
257294
lastChallengeId: 'currentChallengeId',
258295
});
@@ -271,6 +308,7 @@ describe('Shared | Unit | Domain | Use Cases | get-next-challenge', function ()
271308
it('should update last challenge asked', async function () {
272309
const assessment = domainBuilder.buildAssessment({
273310
id: assessmentId,
311+
state: Assessment.states.STARTED,
274312
type: Assessment.types.PREVIEW,
275313
lastChallengeId: 'previousChallengeId',
276314
});

0 commit comments

Comments
 (0)