Skip to content

Commit 7bf56ce

Browse files
committed
test(api): add pix+ pdf certificate tests
1 parent 6a5fb9b commit 7bf56ce

4 files changed

Lines changed: 188 additions & 0 deletions

File tree

api/tests/certification/results/acceptance/application/certificate-route_test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,56 @@ describe('Certification | Results | Acceptance | Application | Certification', f
669669
expect(fileFormat).to.equal('PDF');
670670
});
671671
});
672+
673+
context('when certification is Pix+', function () {
674+
it('should return 200 HTTP status code and a PDF', async function () {
675+
// given
676+
const userId = databaseBuilder.factory.buildUser().id;
677+
678+
const session = databaseBuilder.factory.buildSession({
679+
publishedAt: new Date('2024-02-10T01:02:03Z'),
680+
version: AlgorithmEngineVersion.V3,
681+
});
682+
const certificationCourse = databaseBuilder.factory.buildCertificationCourse({
683+
sessionId: session.id,
684+
userId,
685+
isPublished: true,
686+
framework: Frameworks.DROIT,
687+
verificationCode: await generateCertificateVerificationCode(),
688+
});
689+
const assessment = databaseBuilder.factory.buildAssessment({
690+
userId,
691+
certificationCourseId: certificationCourse.id,
692+
type: Assessment.types.CERTIFICATION,
693+
state: Assessment.states.COMPLETED,
694+
});
695+
databaseBuilder.factory.buildAssessmentResult.last({
696+
certificationCourseId: certificationCourse.id,
697+
assessmentId: assessment.id,
698+
pixScore: 300,
699+
reachedMeshIndex: 1,
700+
status: AssessmentResult.status.VALIDATED,
701+
});
702+
703+
await databaseBuilder.commit();
704+
705+
const server = await createServer();
706+
707+
// when
708+
const response = await server.inject({
709+
method: 'GET',
710+
url: `/api/attestation/${certificationCourse.id}?isFrenchDomainExtension=true&lang=fr`,
711+
headers: generateAuthenticatedUserRequestHeaders({ userId }),
712+
});
713+
714+
// then
715+
expect(response.statusCode).to.equal(200);
716+
expect(response.headers['content-type']).to.equal('application/pdf');
717+
718+
const fileFormat = response.result.substring(1, 4);
719+
expect(fileFormat).to.equal('PDF');
720+
});
721+
});
672722
});
673723

674724
context('when session version is V2', function () {

api/tests/certification/results/integration/infrastructure/utils/pdf/generate-pdf-certificate_test.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import dayjs from 'dayjs';
55
import { getDocument } from 'pdfjs-dist/legacy/build/pdf.mjs';
66

77
import { generate } from '../../../../../../../src/certification/results/infrastructure/utils/pdf/generate-pdf-certificate.js';
8+
import { Frameworks } from '../../../../../../../src/certification/shared/domain/models/Frameworks.js';
89
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
910
import { expect } from '../../../../../../test-helper.js';
1011
import { domainBuilder } from '../../../../../../tooling/domain-builder/domain-builder.js';
@@ -267,6 +268,141 @@ describe('Integration | Infrastructure | Utils | Pdf | V3 Certification Attestat
267268
});
268269
});
269270
});
271+
272+
for (const { framework, reachedMeshIndex, expectedLevel } of [
273+
{ framework: Frameworks.DROIT, reachedMeshIndex: 1, expectedLevel: 'LEVEL_CONFIRMED' },
274+
{ framework: Frameworks.PRO_SANTE, reachedMeshIndex: 2, expectedLevel: 'LEVEL_ADVANCED' },
275+
]) {
276+
describe(`for a Pix+ ${framework} certification`, function () {
277+
it('should display Pix+ title, framework label, and level', async function () {
278+
// given
279+
const certificates = [
280+
domainBuilder.certification.results.buildCertificate({
281+
firstName: 'Marie',
282+
lastName: 'Durand',
283+
birthdate: '1985-03-21',
284+
birthplace: 'Lyon',
285+
verificationCode: 'P-PIXPLUS',
286+
deliveredAt: new Date('2024-02-10'),
287+
certificationCenter: 'Centre de certification',
288+
pixScore: 300,
289+
reachedMeshIndex,
290+
certificationFramework: framework,
291+
}),
292+
];
293+
294+
// when
295+
const pdfStream = await generate({ certificates, i18n });
296+
const pdfBuffer = await _convertStreamToBuffer(pdfStream);
297+
298+
// then
299+
const parsedPdf = await getDocument({ data: new Uint8Array(pdfBuffer) }).promise;
300+
const page = await parsedPdf.getPage(1);
301+
const text = await page.getTextContent();
302+
const content = text.items.map((item) => item.str).join(' ');
303+
304+
expect(content).to.include(translate('certification.certificate.v3.main-content.title-pix-plus'));
305+
expect(content).to.include(translate(`certification.certificate.v3.pix-plus-labels.${framework}`));
306+
expect(content).to.include('Marie DURAND');
307+
expect(content).to.include('P-PIXPLUS');
308+
expect(content).to.include(translate('certification.certificate.v3.score-content.level-explanation'));
309+
expect(content).to.include(translate(`certification.meshlevel.${framework}.${expectedLevel}.label`));
310+
expect(content).to.include(translate(`certification.meshlevel.${framework}.${expectedLevel}.summary`));
311+
expect(content).to.not.include(translate('certification.certificate.v3.complementary-content.title'));
312+
});
313+
});
314+
}
315+
316+
describe('for a Pix+ EDU certification', function () {
317+
for (const { framework, eduV3ExternalJuryResult, expectedLevel } of [
318+
{ framework: Frameworks.EDU_1ER_DEGRE, eduV3ExternalJuryResult: null, expectedLevel: 'LEVEL_ADMISSIBLE' },
319+
{ framework: Frameworks.EDU_2ND_DEGRE, eduV3ExternalJuryResult: 'ADVANCED', expectedLevel: 'LEVEL_ADVANCED' },
320+
{ framework: Frameworks.EDU_CPE, eduV3ExternalJuryResult: 'EXPERT', expectedLevel: 'LEVEL_EXPERT' },
321+
]) {
322+
it(`should display the ${expectedLevel} level for ${framework}`, async function () {
323+
// given
324+
const certificates = [
325+
domainBuilder.certification.results.buildCertificate({
326+
firstName: 'Sophie',
327+
lastName: 'Leroy',
328+
birthdate: '1988-11-05',
329+
birthplace: 'Toulouse',
330+
verificationCode: 'P-EDUPIX',
331+
deliveredAt: new Date('2024-02-10'),
332+
certificationCenter: 'INSPE de Toulouse',
333+
pixScore: 280,
334+
reachedMeshIndex: 0,
335+
certificationFramework: framework,
336+
eduV3ExternalJuryResult,
337+
}),
338+
];
339+
340+
// when
341+
const pdfStream = await generate({ certificates, i18n });
342+
const pdfBuffer = await _convertStreamToBuffer(pdfStream);
343+
344+
// then
345+
const parsedPdf = await getDocument({ data: new Uint8Array(pdfBuffer) }).promise;
346+
const page = await parsedPdf.getPage(1);
347+
const text = await page.getTextContent();
348+
const content = text.items.map((item) => item.str).join(' ');
349+
350+
expect(content).to.include(translate('certification.certificate.v3.main-content.title-pix-plus'));
351+
expect(content).to.include(translate(`certification.certificate.v3.pix-plus-labels.${framework}`));
352+
expect(content).to.include('Sophie LEROY');
353+
expect(content).to.include(translate(`certification.meshlevel.${framework}.${expectedLevel}.label`));
354+
expect(content).to.include(translate(`certification.meshlevel.${framework}.${expectedLevel}.summary`));
355+
});
356+
}
357+
});
358+
359+
describe('Pix+ snapshot', function () {
360+
it('snapshot', async function () {
361+
// given
362+
const certificates = [
363+
domainBuilder.certification.results.buildCertificate({
364+
id: 300,
365+
firstName: 'Marie',
366+
lastName: 'Durand',
367+
birthdate: '1985-03-21',
368+
birthplace: 'Lyon',
369+
verificationCode: 'P-PIXPLUS',
370+
deliveredAt: new Date('2024-02-10'),
371+
certificationCenter: "L'université du Pix /",
372+
pixScore: 300,
373+
reachedMeshIndex: 1,
374+
certificationFramework: Frameworks.DROIT,
375+
}),
376+
];
377+
const referencePdfPath = 'pix-plus-certificate-test.pdf';
378+
const pdfStream = await generate({ certificates, i18n });
379+
const pdfBuffer = await _convertStreamToBuffer(pdfStream);
380+
await _writeFile(pdfBuffer, referencePdfPath);
381+
382+
// when
383+
const parsedPdf = await getDocument({ data: new Uint8Array(pdfBuffer) }).promise;
384+
const page = await parsedPdf.getPage(1);
385+
const text = await page.getTextContent();
386+
387+
text.items.forEach((item) => {
388+
delete item.fontName;
389+
});
390+
text.styles = Object.values(text.styles);
391+
392+
const expectedBuffer = await readFile(`${__dirname}${referencePdfPath}`);
393+
const expectedParsedPdf = await getDocument({ data: new Uint8Array(expectedBuffer) }).promise;
394+
const expectedPage = await expectedParsedPdf.getPage(1);
395+
const expectedText = await expectedPage.getTextContent();
396+
397+
expectedText.items.forEach((item) => {
398+
delete item.fontName;
399+
});
400+
expectedText.styles = Object.values(expectedText.styles);
401+
402+
// then
403+
expect(text).to.deep.equal(expectedText);
404+
});
405+
});
270406
});
271407

272408
function _convertStreamToBuffer(streamData) {

api/tests/tooling/domain-builder/factory/certification/results/build-v3-certification-attestation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const buildCertificate = function ({
1818
certificationDate = new Date('2015-10-03T01:02:03Z'),
1919
acquiredComplementaryCertification = null,
2020
certificationFramework = Frameworks.CORE,
21+
eduV3ExternalJuryResult = null,
2122
} = {}) {
2223
return new Certificate({
2324
id,
@@ -35,6 +36,7 @@ const buildCertificate = function ({
3536
certificationDate,
3637
acquiredComplementaryCertification,
3738
certificationFramework,
39+
eduV3ExternalJuryResult,
3840
});
3941
};
4042

0 commit comments

Comments
 (0)