Skip to content

Commit

Permalink
♻️ refactor: extract admin route to results
Browse files Browse the repository at this point in the history
Co-authored-by: Andreia Pena <[email protected]>
Co-authored-by: Jérémy Pluquet <[email protected]>
Co-authored-by: Alexandre Coin <[email protected]>

Co-Authored-By: GUL <[email protected]>
  • Loading branch information
yaf and HEYGUL authored Nov 21, 2024
1 parent ad822cb commit e94ed28
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { extractLocaleFromRequest } from '../../../shared/infrastructure/utils/request-response-utils.js';
import { usecases as certificationSharedUsecases } from '../../shared/domain/usecases/index.js';
import { usecases } from '../domain/usecases/index.js';
import * as certifiedProfileRepository from '../infrastructure/repositories/certified-profile-repository.js';
import * as certificationCourseSerializer from '../infrastructure/serializers/certification-course-serializer.js';
import * as certifiedProfileSerializer from '../infrastructure/serializers/certified-profile-serializer.js';

const save = async function (request, h, dependencies = { extractLocaleFromRequest, certificationCourseSerializer }) {
const userId = request.auth.credentials.userId;
Expand All @@ -29,20 +27,9 @@ const get = async function (request, h, dependencies = { certificationCourseSeri
return dependencies.certificationCourseSerializer.serialize(certificationCourse);
};

const getCertifiedProfile = async function (
request,
h,
dependencies = { certifiedProfileRepository, certifiedProfileSerializer },
) {
const certificationCourseId = request.params.id;
const certifiedProfile = await dependencies.certifiedProfileRepository.get(certificationCourseId);
return dependencies.certifiedProfileSerializer.serialize(certifiedProfile);
};

const certificationCourseController = {
save,
get,
getCertifiedProfile,
};

export { certificationCourseController };
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,7 @@ import { identifiersType } from '../../../shared/domain/types/identifiers-type.j
import { certificationCourseController } from './certification-course-controller.js';

const register = async function (server) {
const adminRoutes = [
{
method: 'GET',
path: '/api/admin/certifications/{id}/certified-profile',
config: {
pre: [
{
method: (request, h) =>
securityPreHandlers.hasAtLeastOneAccessOf([
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
securityPreHandlers.checkAdminMemberHasRoleCertif,
securityPreHandlers.checkAdminMemberHasRoleSupport,
securityPreHandlers.checkAdminMemberHasRoleMetier,
])(request, h),
assign: 'hasAuthorizationToAccessAdminScope',
},
],
validate: {
params: Joi.object({
id: identifiersType.certificationCourseId,
}),
},
handler: certificationCourseController.getCertifiedProfile,
tags: ['api'],
notes: [
'Cette route est utilisé par Pix Admin',
'Elle permet de récupérer le profil certifié pour une certification donnée',
],
},
},
];
server.route([
...adminRoutes,
{
method: 'POST',
path: '/api/certification-courses',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import dayjs from 'dayjs';

import { tokenService } from '../../../shared/domain/services/token-service.js';
import { usecases } from '../domain/usecases/index.js';
import * as certifiedProfileRepository from '../infrastructure/repositories/certified-profile-repository.js';
import * as certifiedProfileSerializer from '../infrastructure/serializers/certified-profile-serializer.js';
import { getCleaCertifiedCandidateCsv } from '../infrastructure/utils/csv/certification-results/get-clea-certified-candidate-csv.js';
import { getSessionCertificationResultsCsv } from '../infrastructure/utils/csv/certification-results/get-session-certification-results-csv.js';

Expand Down Expand Up @@ -69,10 +71,22 @@ const getSessionResultsToDownload = async function (
.header('Content-Disposition', `attachment; filename=${csvResult.filename}`);
};

const getCertifiedProfile = async function (
request,
h,
dependencies = { certifiedProfileRepository, certifiedProfileSerializer },
) {
const certificationCourseId = request.params.id;
//TODO add passthrough usecase to remove link between application and infrastructure
const certifiedProfile = await dependencies.certifiedProfileRepository.get(certificationCourseId);
return dependencies.certifiedProfileSerializer.serialize(certifiedProfile);
};

const certificationResultsController = {
getCleaCertifiedCandidateDataCsv,
getSessionResultsByRecipientEmail,
getSessionResultsToDownload,
getCertifiedProfile,
};

export { certificationResultsController };
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
import Joi from 'joi';

import { securityPreHandlers } from '../../../shared/application/security-pre-handlers.js';
import { identifiersType } from '../../../shared/domain/types/identifiers-type.js';
import { authorization } from '../../shared/application/pre-handlers/authorization.js';
import { certificationResultsController } from './certification-results-controller.js';

const register = async function (server) {
server.route([
{
method: 'GET',
path: '/api/admin/certifications/{id}/certified-profile',
config: {
pre: [
{
method: (request, h) =>
securityPreHandlers.hasAtLeastOneAccessOf([
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
securityPreHandlers.checkAdminMemberHasRoleCertif,
securityPreHandlers.checkAdminMemberHasRoleSupport,
securityPreHandlers.checkAdminMemberHasRoleMetier,
])(request, h),
assign: 'hasAuthorizationToAccessAdminScope',
},
],
validate: {
params: Joi.object({
id: identifiersType.certificationCourseId,
}),
},
handler: certificationResultsController.getCertifiedProfile,
tags: ['api'],
notes: [
'Cette route est utilisé par Pix Admin',
'Elle permet de récupérer le profil certifié pour une certification donnée',
],
},
},
{
method: 'GET',
path: '/api/sessions/{sessionId}/certified-clea-candidate-data',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as certifiedProfileRepository from '../../../../../../src/certification/evaluation/infrastructure/repositories/certified-profile-repository.js';
import * as certifiedProfileRepository from '../../../../../../src/certification/results/infrastructure/repositories/certified-profile-repository.js';
import { NotFoundError } from '../../../../../../src/shared/domain/errors.js';
import { KnowledgeElement } from '../../../../../../src/shared/domain/models/KnowledgeElement.js';
import { CertifiedProfile } from '../../../../../../src/shared/domain/read-models/CertifiedProfile.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@ import { securityPreHandlers } from '../../../../../src/shared/application/secur
import { expect, HttpTestServer, sinon } from '../../../../test-helper.js';

describe('Unit | Application | Certifications Course | Route', function () {
describe('GET /api/admin/certifications/{id}/certified-profile', function () {
it('should exist', async function () {
// given
sinon.stub(securityPreHandlers, 'hasAtLeastOneAccessOf').returns(() => true);
sinon.stub(certificationCoursesController, 'getCertifiedProfile').returns('ok');
const httpTestServer = new HttpTestServer();
await httpTestServer.register(moduleUnderTest);

// when
const response = await httpTestServer.request('GET', '/api/admin/certifications/1234/certified-profile');

// then
expect(response.statusCode).to.equal(200);
});
});

describe('POST /api/certification-courses', function () {
it('should return OK (200)', async function () {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,67 @@ describe('Certification | Results | Unit | Controller | certification results',
expect(response.headers['Content-Disposition']).to.equal(`attachment; filename=${fileName}`);
});
});

describe('#getCertifiedProfile', function () {
it('should fetch the associated certified profile serialized as JSONAPI', async function () {
const certifiedProfileSerializer = {
serialize: sinon.stub(),
};
const certifiedProfileRepository = {
get: sinon.stub(),
};
const skill1 = domainBuilder.buildCertifiedSkill({
id: 'recSkill1',
name: 'skill_1',
hasBeenAskedInCertif: false,
tubeId: 'recTube1',
difficulty: 1,
});
const skill2 = domainBuilder.buildCertifiedSkill({
id: 'recSkill2',
name: 'skill_2',
hasBeenAskedInCertif: true,
tubeId: 'recTube1',
difficulty: 2,
});
const tube1 = domainBuilder.buildCertifiedTube({
id: 'recTube1',
name: 'tube_1',
competenceId: 'recCompetence1',
});
const competence1 = domainBuilder.buildCertifiedCompetence({
id: 'recCompetence1',
name: 'competence_1',
areaId: 'recArea1',
origin: 'Pix',
});
const area1 = domainBuilder.buildCertifiedArea({
id: 'recArea1',
name: 'area_1',
color: 'someColor',
});
const certifiedProfile = domainBuilder.buildCertifiedProfile({
id: 123,
userId: 456,
certifiedSkills: [skill1, skill2],
certifiedTubes: [tube1],
certifiedCompetences: [competence1],
certifiedAreas: [area1],
});
certifiedProfileRepository.get.withArgs(123).resolves(certifiedProfile);
certifiedProfileSerializer.serialize.withArgs(certifiedProfile).resolves('ok');
const request = {
params: { id: 123 },
};

// when
const response = await certificationResultsController.getCertifiedProfile(request, hFake, {
certifiedProfileRepository,
certifiedProfileSerializer,
});

// then
expect(response).to.deep.equal('ok');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import { certificationResultsController } from '../../../../../src/certification/results/application/certification-results-controller.js';
import * as moduleUnderTest from '../../../../../src/certification/results/application/certification-results-route.js';
import { authorization } from '../../../../../src/certification/shared/application/pre-handlers/authorization.js';
import { securityPreHandlers } from '../../../../../src/shared/application/security-pre-handlers.js';
import { expect, HttpTestServer, sinon } from '../../../../test-helper.js';

describe('Certification | Results | Unit | Application | Certification Results Route', function () {
describe('GET /api/admin/certifications/{id}/certified-profile', function () {
it('should exist', async function () {
// given
sinon.stub(securityPreHandlers, 'hasAtLeastOneAccessOf').returns(() => true);
sinon.stub(certificationResultsController, 'getCertifiedProfile').returns('ok');
const httpTestServer = new HttpTestServer();
await httpTestServer.register(moduleUnderTest);

// when
const response = await httpTestServer.request('GET', '/api/admin/certifications/1234/certified-profile');

// then
expect(response.statusCode).to.equal(200);
});
});

describe('GET /api/sessions/{sessionId}/certified-clea-candidate-data', function () {
it('should exist', async function () {
// given
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as serializer from '../../../../../src/certification/evaluation/infrastructure/serializers/certified-profile-serializer.js';
import { domainBuilder, expect } from '../../../../test-helper.js';
import * as serializer from '../../../../../../src/certification/results/infrastructure/serializers/certified-profile-serializer.js';
import { domainBuilder, expect } from '../../../../../test-helper.js';

describe('Unit | Serializer | JSONAPI | certified-profile-serializer', function () {
describe('#serialize', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { certificationCourseController } from '../../../../src/certification/eva
import { usecases } from '../../../../src/certification/evaluation/domain/usecases/index.js';
import { CertificationCourse } from '../../../../src/certification/shared/domain/models/CertificationCourse.js';
import { usecases as certificationSharedUsecases } from '../../../../src/certification/shared/domain/usecases/index.js';
import { domainBuilder, expect, generateValidRequestAuthorizationHeader, hFake, sinon } from '../../../test-helper.js';
import { expect, generateValidRequestAuthorizationHeader, hFake, sinon } from '../../../test-helper.js';

describe('Unit | Controller | certification-course-controller', function () {
let certificationCourseSerializer;
let certifiedProfileSerializer;
let certifiedProfileRepository;
let requestResponseUtils;

beforeEach(function () {
Expand All @@ -16,12 +14,6 @@ describe('Unit | Controller | certification-course-controller', function () {
serializeFromCertificationCourse: sinon.stub(),
deserializeCertificationCandidateModificationCommand: sinon.stub(),
};
certifiedProfileSerializer = {
serialize: sinon.stub(),
};
certifiedProfileRepository = {
get: sinon.stub(),
};
requestResponseUtils = { extractLocaleFromRequest: sinon.stub() };
});

Expand Down Expand Up @@ -111,62 +103,4 @@ describe('Unit | Controller | certification-course-controller', function () {
expect(response).to.deep.equal(certificationCourse);
});
});

describe('#getCertifiedProfile', function () {
it('should fetch the associated certified profile serialized as JSONAPI', async function () {
// given
const skill1 = domainBuilder.buildCertifiedSkill({
id: 'recSkill1',
name: 'skill_1',
hasBeenAskedInCertif: false,
tubeId: 'recTube1',
difficulty: 1,
});
const skill2 = domainBuilder.buildCertifiedSkill({
id: 'recSkill2',
name: 'skill_2',
hasBeenAskedInCertif: true,
tubeId: 'recTube1',
difficulty: 2,
});
const tube1 = domainBuilder.buildCertifiedTube({
id: 'recTube1',
name: 'tube_1',
competenceId: 'recCompetence1',
});
const competence1 = domainBuilder.buildCertifiedCompetence({
id: 'recCompetence1',
name: 'competence_1',
areaId: 'recArea1',
origin: 'Pix',
});
const area1 = domainBuilder.buildCertifiedArea({
id: 'recArea1',
name: 'area_1',
color: 'someColor',
});
const certifiedProfile = domainBuilder.buildCertifiedProfile({
id: 123,
userId: 456,
certifiedSkills: [skill1, skill2],
certifiedTubes: [tube1],
certifiedCompetences: [competence1],
certifiedAreas: [area1],
});
certifiedProfileRepository.get.withArgs(123).resolves(certifiedProfile);
certifiedProfileSerializer.serialize.withArgs(certifiedProfile).resolves('ok');
const request = {
params: { id: 123 },
};

// when
const response = await certificationCourseController.getCertifiedProfile(request, hFake, {
certifiedProfileRepository,
certifiedProfileSerializer,
});

// then
expect(response).to.deep.equal('ok');
});
});
});

0 comments on commit e94ed28

Please sign in to comment.