@@ -5,6 +5,7 @@ import dayjs from 'dayjs';
55import { getDocument } from 'pdfjs-dist/legacy/build/pdf.mjs' ;
66
77import { generate } from '../../../../../../../src/certification/results/infrastructure/utils/pdf/generate-pdf-certificate.js' ;
8+ import { Frameworks } from '../../../../../../../src/certification/shared/domain/models/Frameworks.js' ;
89import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js' ;
910import { expect } from '../../../../../../test-helper.js' ;
1011import { 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
272408function _convertStreamToBuffer ( streamData ) {
0 commit comments