Skip to content

Commit 055f8f5

Browse files
Steph0AndreiaPena
authored andcommitted
♻️ calling rescoring synchronously without eventDispatcher
Co-authored-by: Andreia Pena <58915422+AndreiaPena@users.noreply.github.com>
1 parent c5a397e commit 055f8f5

File tree

9 files changed

+94
-50
lines changed

9 files changed

+94
-50
lines changed

api/src/certification/session-management/application/cancellation-controller.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import * as events from '../../../../src/shared/domain/events/index.js';
21
import { usecases } from '../domain/usecases/index.js';
32

4-
const cancel = async function (request, h, dependencies = { events }) {
3+
const cancel = async function (request, h) {
54
const juryId = request.auth.credentials.userId;
65
const certificationCourseId = request.params.certificationCourseId;
7-
const certificationCancelledEvent = await usecases.cancelCertificationCourse({ certificationCourseId, juryId });
8-
await dependencies.events.eventDispatcher.dispatch(certificationCancelledEvent);
6+
await usecases.cancel({ certificationCourseId, juryId });
97

108
return h.response().code(204);
119
};
+10-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @typedef {import('./index.js'.CertificationCourseRepository} CertificationCourseRepository
33
* @typedef {import('./index.js'.SessionRepository} SessionRepository
4+
* @typedef {import('./index.js'.CertificationRescoringRepository} CertificationRescoringRepository
45
*/
56

67
import CertificationCancelled from '../../../../../src/shared/domain/events/CertificationCancelled.js';
@@ -11,13 +12,14 @@ import { NotFinalizedSessionError } from '../../../../shared/domain/errors.js';
1112
* @param {number} params.certificationCourseId
1213
* @param {CertificationCourseRepository} params.certificationCourseRepository
1314
* @param {SessionRepository} params.sessionRepository
14-
* @returns {Promise<CertificationCancelled>}
15+
* @param {CertificationRescoringRepository} params.certificationRescoringRepository
1516
*/
16-
export const cancelCertificationCourse = async function ({
17+
export const cancel = async function ({
1718
certificationCourseId,
1819
juryId,
1920
certificationCourseRepository,
2021
sessionRepository,
22+
certificationRescoringRepository,
2123
}) {
2224
const certificationCourse = await certificationCourseRepository.get({ id: certificationCourseId });
2325
const session = await sessionRepository.get({ id: certificationCourse.getSessionId() });
@@ -28,5 +30,10 @@ export const cancelCertificationCourse = async function ({
2830
certificationCourse.cancel();
2931
await certificationCourseRepository.update({ certificationCourse });
3032

31-
return new CertificationCancelled({ certificationCourseId: certificationCourse.getId(), juryId });
33+
const certificationCancelledEvent = new CertificationCancelled({
34+
certificationCourseId: certificationCourse.getId(),
35+
juryId,
36+
});
37+
38+
return certificationRescoringRepository.execute({ certificationCancelledEvent });
3239
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @typedef {import('../../../../../src/shared/domain/events/CertificationCancelled.js'} CertificationCancelled
3+
* @typedef {import('./index.js'.LibServices} LibServices
4+
*/
5+
6+
/**
7+
* @param {Object} params
8+
* @param {CertificationCancelled} params.certificationCancelledEvent
9+
* @param {LibServices} params.libServices
10+
*/
11+
export const execute = async ({ certificationCancelledEvent, libServices }) => {
12+
return libServices.handleCertificationRescoring({
13+
event: certificationCancelledEvent,
14+
});
15+
};

api/src/certification/session-management/infrastructure/repositories/index.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { handlersAsServices as libServices } from '../../../../../src/shared/domain/events/index.js';
12
import * as certificationIssueReportRepository from '../../../../certification/shared/infrastructure/repositories/certification-issue-report-repository.js';
23
import * as issueReportCategoryRepository from '../../../../certification/shared/infrastructure/repositories/issue-report-category-repository.js';
34
import * as answerRepository from '../../../../shared/infrastructure/repositories/answer-repository.js';
@@ -21,6 +22,7 @@ import * as certificationCandidateRepository from './certification-candidate-rep
2122
import * as certificationCompanionAlertRepository from './certification-companion-alert-repository.js';
2223
import * as certificationOfficerRepository from './certification-officer-repository.js';
2324
import * as certificationRepository from './certification-repository.js';
25+
import * as certificationRescoringRepository from './certification-rescoring-repository.js';
2426
import * as competenceMarkRepository from './competence-mark-repository.js';
2527
import * as courseAssessmentResultRepository from './course-assessment-result-repository.js';
2628
import * as cpfExportRepository from './cpf-export-repository.js';
@@ -75,6 +77,7 @@ import * as v3CertificationCourseDetailsForAdministrationRepository from './v3-c
7577
* @typedef {juryCertificationSummaryRepository} JuryCertificationSummaryRepository
7678
* @typedef {certificationCandidateRepository} CertificationCandidateRepository
7779
* @typedef {typeof certificationCompanionAlertRepository} CertificationCompanionAlertRepository
80+
* @typedef {certificationRescoringRepository} CertificationRescoringRepository
7881
*/
7982
const repositoriesWithoutInjectedDependencies = {
8083
assessmentRepository,
@@ -109,13 +112,17 @@ const repositoriesWithoutInjectedDependencies = {
109112
certificationCpfCountryRepository,
110113
certificationCandidateRepository,
111114
certificationCompanionAlertRepository,
115+
certificationRescoringRepository,
112116
};
113117

114118
/**
115119
* Using {@link https://jsdoc.app/tags-type "Closure Compiler's syntax"} to document injected dependencies
116-
*
120+
* @typedef {libServices} LibServices
117121
*/
118-
const dependencies = {};
122+
const dependencies = {
123+
libServices,
124+
};
125+
119126
const sessionRepositories = injectDependencies(repositoriesWithoutInjectedDependencies, dependencies);
120127
export {
121128
answerRepository,

api/src/shared/domain/events/index.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,14 @@ import * as competenceRepository from '../../infrastructure/repositories/compete
4040
import * as knowledgeElementRepository from '../../infrastructure/repositories/knowledge-element-repository.js';
4141
import * as organizationRepository from '../../infrastructure/repositories/organization-repository.js';
4242
import * as skillRepository from '../../infrastructure/repositories/skill-repository.js';
43-
import { injectDefaults } from '../../infrastructure/utils/dependency-injection.js';
43+
import { injectDefaults, injectDependencies } from '../../infrastructure/utils/dependency-injection.js';
4444
import { logger } from '../../infrastructure/utils/logger.js';
4545

4646
const { performance } = perf_hooks;
4747

48+
/**
49+
* @typedef {certificationAssessmentRepository} CertificationAssessmentRepository
50+
*/
4851
const dependencies = {
4952
answerRepository,
5053
assessmentRepository,
@@ -119,4 +122,10 @@ const _forTestOnly = {
119122
},
120123
};
121124

122-
export { _forTestOnly, eventBus, eventDispatcher };
125+
/**
126+
* Using {@link https://jsdoc.app/tags-type "Closure Compiler's syntax"} to document injected dependencies
127+
* @typedef {handleCertificationRescoring} HandleCertificationRescoring
128+
*/
129+
const handlersAsServices = injectDependencies(handlersToBeInjected, dependencies);
130+
131+
export { _forTestOnly, eventBus, eventDispatcher, handlersAsServices };

api/tests/certification/session-management/acceptance/application/cancellation-route_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { PIX_ADMIN } from '../../../../../src/authorization/domain/constants.js';
22
import { AlgorithmEngineVersion } from '../../../../../src/certification/shared/domain/models/AlgorithmEngineVersion.js';
33
import { SESSIONS_VERSIONS } from '../../../../../src/certification/shared/domain/models/SessionVersion.js';
4-
import { Assessment } from '../../../../../src/shared/domain/models/Assessment.js';
5-
import { AssessmentResult } from '../../../../../src/shared/domain/models/AssessmentResult.js';
4+
import { Assessment } from '../../../../../src/shared/domain/models/index.js';
5+
import { AssessmentResult } from '../../../../../src/shared/domain/models/index.js';
66
import { AnswerStatus } from '../../../../../src/shared/domain/models/index.js';
77
import {
88
createServer,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { sessionRepositories } from '../../../../../../src/certification/session-management/infrastructure/repositories/index.js';
2+
import { NotFoundError } from '../../../../../../src/shared/domain/errors.js';
3+
import CertificationCancelled from '../../../../../../src/shared/domain/events/CertificationCancelled.js';
4+
import { catchErr, expect } from '../../../../../test-helper.js';
5+
6+
describe('Integration | Repository | certification-rescoring-repository', function () {
7+
describe('#execute', function () {
8+
it('should trigger a rescoring', async function () {
9+
// given
10+
const certificationCancelledEvent = new CertificationCancelled({ certificationCourseId: 444, juryId: 555 });
11+
12+
// when
13+
const error = await catchErr(sessionRepositories.certificationRescoringRepository.execute)({
14+
certificationCancelledEvent,
15+
});
16+
17+
// then
18+
expect(error).to.deepEqualInstance(
19+
new NotFoundError(
20+
`L'assessment de certification avec un certificationCourseId de ${certificationCancelledEvent.certificationCourseId} n'existe pas ou son accès est restreint`,
21+
),
22+
);
23+
});
24+
});
25+
});

api/tests/certification/session-management/unit/application/cancellation-controller_test.js

+4-31
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { cancellationController } from '../../../../../src/certification/session-management/application/cancellation-controller.js';
22
import { usecases } from '../../../../../src/certification/session-management/domain/usecases/index.js';
3-
import CertificationCancelled from '../../../../../src/shared/domain/events/CertificationCancelled.js';
43
import { expect, hFake, sinon } from '../../../../test-helper.js';
54

65
describe('Certification | Session-management | Unit | Application | Controller | cancellation', function () {
76
describe('#cancel', function () {
8-
it('should call cancel-certification-course usecase', async function () {
7+
it('should call cancel usecase', async function () {
98
// given
10-
sinon.stub(usecases, 'cancelCertificationCourse');
9+
sinon.stub(usecases, 'cancel');
1110
const request = {
1211
auth: {
1312
credentials: {
@@ -18,43 +17,17 @@ describe('Certification | Session-management | Unit | Application | Controller |
1817
certificationCourseId: 123,
1918
},
2019
};
21-
usecases.cancelCertificationCourse.resolves();
20+
usecases.cancel.resolves();
2221

2322
// when
2423
await cancellationController.cancel(request, hFake);
2524

2625
// then
27-
expect(usecases.cancelCertificationCourse).to.have.been.calledWithExactly({
26+
expect(usecases.cancel).to.have.been.calledWithExactly({
2827
certificationCourseId: 123,
2928
juryId: 345,
3029
});
3130
});
32-
33-
it('should fire a CertificationCancelled event', async function () {
34-
// given
35-
const certificationCourseId = 123;
36-
const juryId = 456;
37-
const events = { eventDispatcher: { dispatch: sinon.stub() } };
38-
const expectedEvent = new CertificationCancelled({ certificationCourseId, juryId });
39-
sinon.stub(usecases, 'cancelCertificationCourse');
40-
const request = {
41-
auth: {
42-
credentials: {
43-
userId: 345,
44-
},
45-
},
46-
params: {
47-
certificationCourseId,
48-
},
49-
};
50-
usecases.cancelCertificationCourse.resolves(expectedEvent);
51-
52-
// when
53-
await cancellationController.cancel(request, hFake, { events });
54-
55-
// then
56-
expect(events.eventDispatcher.dispatch).to.have.been.calledWithExactly(expectedEvent);
57-
});
5831
});
5932

6033
describe('#uncancelCertificationCourse', function () {
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { cancelCertificationCourse } from '../../../../../../src/certification/session-management/domain/usecases/cancel-certification-course.js';
1+
import { cancel } from '../../../../../../src/certification/session-management/domain/usecases/cancel.js';
22
import { NotFinalizedSessionError } from '../../../../../../src/shared/domain/errors.js';
33
import CertificationCancelled from '../../../../../../src/shared/domain/events/CertificationCancelled.js';
44
import { catchErr, domainBuilder, expect, sinon } from '../../../../../test-helper.js';
55

6-
describe('Certification | Session-management | Unit | Domain | UseCases | cancel-certification-course', function () {
6+
describe('Certification | Session-management | Unit | Domain | UseCases | cancel', function () {
77
describe('when session is finalized', function () {
88
it('should cancel the certification course', async function () {
99
// given
@@ -20,22 +20,32 @@ describe('Certification | Session-management | Unit | Domain | UseCases | cancel
2020
const sessionRepository = {
2121
get: sinon.stub(),
2222
};
23+
const certificationRescoringRepository = {
24+
execute: sinon.stub(),
25+
};
2326
certificationCourseRepository.get.withArgs({ id: 123 }).resolves(certificationCourse);
2427
certificationCourseRepository.update.resolves();
28+
certificationRescoringRepository.execute.resolves();
2529
sessionRepository.get.withArgs({ id: certificationCourse.getSessionId() }).resolves(session);
2630

2731
// when
28-
const cancelledEvent = await cancelCertificationCourse({
32+
await cancel({
2933
certificationCourseId: 123,
34+
juryId,
3035
certificationCourseRepository,
3136
sessionRepository,
32-
juryId,
37+
certificationRescoringRepository,
3338
});
3439

3540
// then
3641
expect(certificationCourse.cancel).to.have.been.calledOnce;
3742
expect(certificationCourseRepository.update).to.have.been.calledWithExactly({ certificationCourse });
38-
expect(cancelledEvent).to.deepEqualInstance(new CertificationCancelled({ certificationCourseId: 123, juryId }));
43+
expect(certificationRescoringRepository.execute).to.have.been.calledWithExactly({
44+
certificationCancelledEvent: new CertificationCancelled({
45+
certificationCourseId: certificationCourse.getId(),
46+
juryId,
47+
}),
48+
});
3949
});
4050
});
4151

@@ -58,7 +68,7 @@ describe('Certification | Session-management | Unit | Domain | UseCases | cancel
5868
sessionRepository.get.withArgs({ id: certificationCourse.getSessionId() }).resolves(session);
5969

6070
// when
61-
const error = await catchErr(cancelCertificationCourse)({
71+
const error = await catchErr(cancel)({
6272
certificationCourseId: 123,
6373
certificationCourseRepository,
6474
sessionRepository,

0 commit comments

Comments
 (0)