Skip to content

Commit

Permalink
♻️ calling rescoring synchronously without eventDispatcher
Browse files Browse the repository at this point in the history
Co-authored-by: Andreia Pena <[email protected]>
  • Loading branch information
Steph0 authored and AndreiaPena committed Jan 27, 2025
1 parent 715c5db commit 327e23f
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 49 deletions.
11 changes: 8 additions & 3 deletions api/lib/domain/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import * as competenceRepository from '../../../src/shared/infrastructure/reposi
import * as knowledgeElementRepository from '../../../src/shared/infrastructure/repositories/knowledge-element-repository.js';
import * as organizationRepository from '../../../src/shared/infrastructure/repositories/organization-repository.js';
import * as skillRepository from '../../../src/shared/infrastructure/repositories/skill-repository.js';
import { injectDefaults } from '../../../src/shared/infrastructure/utils/dependency-injection.js';
import { injectDefaults, injectDependencies } from '../../../src/shared/infrastructure/utils/dependency-injection.js';
import { logger } from '../../../src/shared/infrastructure/utils/logger.js';
import * as eventBusBuilder from '../../infrastructure/events/EventBusBuilder.js';
import { EventDispatcher } from '../../infrastructure/events/EventDispatcher.js';
Expand All @@ -48,7 +48,6 @@ const { performance } = perf_hooks;
/**
* @typedef {certificationAssessmentRepository} CertificationAssessmentRepository
*/

const dependencies = {
answerRepository,
assessmentRepository,
Expand Down Expand Up @@ -123,4 +122,10 @@ const _forTestOnly = {
},
};

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

export { _forTestOnly, eventBus, eventDispatcher, handlersAsServices };
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as events from '../../../../lib/domain/events/index.js';
import { usecases } from '../domain/usecases/index.js';

const cancel = async function (request, h, dependencies = { events }) {
const cancel = async function (request, h) {
const juryId = request.auth.credentials.userId;
const certificationCourseId = request.params.certificationCourseId;
const certificationCancelledEvent = await usecases.cancelCertificationCourse({ certificationCourseId, juryId });
await dependencies.events.eventDispatcher.dispatch(certificationCancelledEvent);

await usecases.cancel({ certificationCourseId, juryId });

return h.response().code(204);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* @typedef {import('./index.js'.CertificationCourseRepository} CertificationCourseRepository
* @typedef {import('./index.js'.SessionRepository} SessionRepository
* @typedef {import('./index.js'.CertificationRescoringRepository} CertificationRescoringRepository
*/

import CertificationCancelled from '../../../../../lib/domain/events/CertificationCancelled.js';
Expand All @@ -11,13 +12,14 @@ import { NotFinalizedSessionError } from '../../../../shared/domain/errors.js';
* @param {number} params.certificationCourseId
* @param {CertificationCourseRepository} params.certificationCourseRepository
* @param {SessionRepository} params.sessionRepository
* @returns {Promise<CertificationCancelled>}
* @param {CertificationRescoringRepository} params.certificationRescoringRepository
*/
export const cancelCertificationCourse = async function ({
export const cancel = async function ({
certificationCourseId,
juryId,
certificationCourseRepository,
sessionRepository,
certificationRescoringRepository,
}) {
const certificationCourse = await certificationCourseRepository.get({ id: certificationCourseId });
const session = await sessionRepository.get({ id: certificationCourse.getSessionId() });
Expand All @@ -28,5 +30,10 @@ export const cancelCertificationCourse = async function ({
certificationCourse.cancel();
await certificationCourseRepository.update({ certificationCourse });

return new CertificationCancelled({ certificationCourseId: certificationCourse.getId(), juryId });
const certificationCancelledEvent = new CertificationCancelled({
certificationCourseId: certificationCourse.getId(),
juryId,
});

return certificationRescoringRepository.execute({ certificationCancelledEvent });
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @typedef {import('../../../../../lib/domain/events/CertificationCancelled.js'} CertificationCancelled
* @typedef {import('./index.js'.LibServices} LibServices
*/

/**
* @param {Object} params
* @param {CertificationCancelled} params.certificationCancelledEvent
* @param {LibServices} params.libServices
*/
export const execute = async ({ certificationCancelledEvent, libServices }) => {
return libServices.handleCertificationRescoring({
event: certificationCancelledEvent,
});
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { handlersAsServices as libServices } from '../../../../../lib/domain/events/index.js';
import * as certificationIssueReportRepository from '../../../../certification/shared/infrastructure/repositories/certification-issue-report-repository.js';
import * as issueReportCategoryRepository from '../../../../certification/shared/infrastructure/repositories/issue-report-category-repository.js';
import * as answerRepository from '../../../../shared/infrastructure/repositories/answer-repository.js';
Expand All @@ -21,6 +22,7 @@ import * as certificationCandidateRepository from './certification-candidate-rep
import * as certificationCompanionAlertRepository from './certification-companion-alert-repository.js';
import * as certificationOfficerRepository from './certification-officer-repository.js';
import * as certificationRepository from './certification-repository.js';
import * as certificationRescoringRepository from './certification-rescoring-repository.js';
import * as competenceMarkRepository from './competence-mark-repository.js';
import * as courseAssessmentResultRepository from './course-assessment-result-repository.js';
import * as cpfExportRepository from './cpf-export-repository.js';
Expand Down Expand Up @@ -75,6 +77,7 @@ import * as v3CertificationCourseDetailsForAdministrationRepository from './v3-c
* @typedef {juryCertificationSummaryRepository} JuryCertificationSummaryRepository
* @typedef {certificationCandidateRepository} CertificationCandidateRepository
* @typedef {typeof certificationCompanionAlertRepository} CertificationCompanionAlertRepository
* @typedef {certificationRescoringRepository} CertificationRescoringRepository
*/
const repositoriesWithoutInjectedDependencies = {
assessmentRepository,
Expand Down Expand Up @@ -109,13 +112,17 @@ const repositoriesWithoutInjectedDependencies = {
certificationCpfCountryRepository,
certificationCandidateRepository,
certificationCompanionAlertRepository,
certificationRescoringRepository,
};

/**
* Using {@link https://jsdoc.app/tags-type "Closure Compiler's syntax"} to document injected dependencies
*
* @typedef {libServices} LibServices
*/
const dependencies = {};
const dependencies = {
libServices,
};

const sessionRepositories = injectDependencies(repositoriesWithoutInjectedDependencies, dependencies);
export {
answerRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import CertificationCancelled from '../../../../../../lib/domain/events/CertificationCancelled.js';
import { sessionRepositories } from '../../../../../../src/certification/session-management/infrastructure/repositories/index.js';
import { NotFoundError } from '../../../../../../src/shared/domain/errors.js';
import { catchErr, expect } from '../../../../../test-helper.js';

describe('Integration | Repository | certification-rescoring-repository', function () {
describe('#execute', function () {
it('should trigger a rescoring', async function () {
// given
const certificationCancelledEvent = new CertificationCancelled({ certificationCourseId: 444, juryId: 555 });
sessionRepositories;

// when
const error = await catchErr(sessionRepositories.certificationRescoringRepository.execute)({
certificationCancelledEvent,
});

// then
expect(error).to.deepEqualInstance(
new NotFoundError(
`L'assessment de certification avec un certificationCourseId de ${certificationCancelledEvent.certificationCourseId} n'existe pas ou son accès est restreint`,
),
);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import CertificationCancelled from '../../../../../lib/domain/events/CertificationCancelled.js';
import { cancellationController } from '../../../../../src/certification/session-management/application/cancellation-controller.js';
import { usecases } from '../../../../../src/certification/session-management/domain/usecases/index.js';
import { expect, hFake, sinon } from '../../../../test-helper.js';

describe('Certification | Session-management | Unit | Application | Controller | cancellation', function () {
describe('#cancel', function () {
it('should call cancel-certification-course usecase', async function () {
it('should call cancel usecase', async function () {
// given
sinon.stub(usecases, 'cancelCertificationCourse');
sinon.stub(usecases, 'cancel');
const request = {
auth: {
credentials: {
Expand All @@ -18,43 +17,17 @@ describe('Certification | Session-management | Unit | Application | Controller |
certificationCourseId: 123,
},
};
usecases.cancelCertificationCourse.resolves();
usecases.cancel.resolves();

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

// then
expect(usecases.cancelCertificationCourse).to.have.been.calledWithExactly({
expect(usecases.cancel).to.have.been.calledWithExactly({
certificationCourseId: 123,
juryId: 345,
});
});

it('should fire a CertificationCancelled event', async function () {
// given
const certificationCourseId = 123;
const juryId = 456;
const events = { eventDispatcher: { dispatch: sinon.stub() } };
const expectedEvent = new CertificationCancelled({ certificationCourseId, juryId });
sinon.stub(usecases, 'cancelCertificationCourse');
const request = {
auth: {
credentials: {
userId: 345,
},
},
params: {
certificationCourseId,
},
};
usecases.cancelCertificationCourse.resolves(expectedEvent);

// when
await cancellationController.cancel(request, hFake, { events });

// then
expect(events.eventDispatcher.dispatch).to.have.been.calledWithExactly(expectedEvent);
});
});

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

describe('Certification | Session-management | Unit | Domain | UseCases | cancel-certification-course', function () {
describe('Certification | Session-management | Unit | Domain | UseCases | cancel', function () {
describe('when session is finalized', function () {
it('should cancel the certification course', async function () {
// given
Expand All @@ -20,22 +20,32 @@ describe('Certification | Session-management | Unit | Domain | UseCases | cancel
const sessionRepository = {
get: sinon.stub(),
};
const certificationRescoringRepository = {
execute: sinon.stub(),
};
certificationCourseRepository.get.withArgs({ id: 123 }).resolves(certificationCourse);
certificationCourseRepository.update.resolves();
certificationRescoringRepository.execute.resolves();
sessionRepository.get.withArgs({ id: certificationCourse.getSessionId() }).resolves(session);

// when
const cancelledEvent = await cancelCertificationCourse({
await cancel({
certificationCourseId: 123,
juryId,
certificationCourseRepository,
sessionRepository,
juryId,
certificationRescoringRepository,
});

// then
expect(certificationCourse.cancel).to.have.been.calledOnce;
expect(certificationCourseRepository.update).to.have.been.calledWithExactly({ certificationCourse });
expect(cancelledEvent).to.deepEqualInstance(new CertificationCancelled({ certificationCourseId: 123, juryId }));
expect(certificationRescoringRepository.execute).to.have.been.calledWithExactly({
certificationCancelledEvent: new CertificationCancelled({
certificationCourseId: certificationCourse.getId(),
juryId,
}),
});
});
});

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

// when
const error = await catchErr(cancelCertificationCourse)({
const error = await catchErr(cancel)({
certificationCourseId: 123,
certificationCourseRepository,
sessionRepository,
Expand Down

0 comments on commit 327e23f

Please sign in to comment.