Skip to content

Commit

Permalink
[FEATURE] Ne pas afficher la mention professionnalisante sur le PDF d…
Browse files Browse the repository at this point in the history
…e l'attestation d'une certification v3 (PIX-15163).

 #10508
  • Loading branch information
pix-service-auto-merge authored Nov 14, 2024
2 parents 86eb8ec + 04a2ccf commit 6806b0d
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class CertificationAttestation {
resultCompetenceTree = null,
verificationCode,
maxReachableLevelOnCertificationDate,
version,
} = {}) {
this.id = id;
this.firstName = firstName;
Expand All @@ -34,6 +35,7 @@ class CertificationAttestation {
this.resultCompetenceTree = resultCompetenceTree;
this.verificationCode = verificationCode;
this.maxReachableLevelOnCertificationDate = maxReachableLevelOnCertificationDate;
this.version = version;
this.maxReachableScore = this.maxReachableLevelOnCertificationDate * PIX_COUNT_BY_LEVEL * COMPETENCE_COUNT;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ function _selectCertificationAttestations() {
userId: 'certification-courses.userId',
date: 'certification-courses.createdAt',
deliveredAt: 'sessions.publishedAt',
version: 'sessions.version',
verificationCode: 'certification-courses.verificationCode',
certificationCenter: 'sessions.certificationCenter',
maxReachableLevelOnCertificationDate: 'certification-courses.maxReachableLevelOnCertificationDate',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@ const { sortBy } = lodash;
import dayjs from 'dayjs';

import { toArrayOfFixedLengthStringsConservingWords } from '../../../../../shared/infrastructure/utils/string-utils.js';
import { SESSIONS_VERSIONS } from '../../../../shared/domain/models/SessionVersion.js';

const PROFESSIONALIZING_VALIDITY_START_DATE = new Date('2022-01-01');

class AttestationViewModel {
/**
* @param {Object} props
* @param {number} props.pixScore
* @param {number} props.maxReachableScore
* @param {string} props.maxLevel
* @param {string} props.absoluteMaxLevelIndication
* @param {string} props.maxReachableLevelIndication
* @param {string} props.fullName
* @param {Date} props.birthplace
* @param {Date} props.birth
* @param {string} props.certificationCenter
* @param {Date} props.deliveredAt
* @param {string} props.verificationCode
* @param {Date} props.maxReachableLevelOnCertificationDate
* @param {Boolean} props.hasAcquiredAnyComplementaryCertifications
* @param {Object} props.stickers
* @param {Array} props.competenceDetailViewModels
* @param {Boolean} props.isFrenchDomainExtension
* @param {number} props.version
*/
constructor({
pixScore,
maxReachableScore,
Expand All @@ -25,7 +46,8 @@ class AttestationViewModel {
hasAcquiredAnyComplementaryCertifications,
stickers,
competenceDetailViewModels,
isFrenchDomainExtension,
isFrenchDomainExtension = true,
version,
}) {
this.pixScore = pixScore;
this.maxReachableScore = maxReachableScore;
Expand All @@ -43,6 +65,7 @@ class AttestationViewModel {
this._hasAcquiredAnyComplementaryCertifications = hasAcquiredAnyComplementaryCertifications;
this.stickers = stickers;
this._isFrenchDomainExtension = isFrenchDomainExtension;
this._version = version;
}

certificationDate({ lang }) {
Expand All @@ -58,9 +81,14 @@ class AttestationViewModel {
}

shouldDisplayProfessionalizingCertificationMessage() {
if (!this._isFrenchDomainExtension) return false;
if (!this._deliveredAt) return false;
return this._deliveredAt.getTime() >= PROFESSIONALIZING_VALIDITY_START_DATE.getTime();
return this.#isDeliveredAfterProfessionalizingStartDate() && this._version === SESSIONS_VERSIONS.V2;
}

#isDeliveredAfterProfessionalizingStartDate() {
return (
this._isFrenchDomainExtension && this._deliveredAt.getTime() >= PROFESSIONALIZING_VALIDITY_START_DATE.getTime()
);
}

static from({ certificate, isFrenchDomainExtension, translate, lang }) {
Expand All @@ -85,6 +113,7 @@ class AttestationViewModel {
const birth = _formatDate({ date: certificate.birthdate, lang }) + birthplace;
const certificationCenter = certificate.certificationCenter;
const deliveredAt = certificate.deliveredAt;
const version = certificate.version;

const maxReachableLevelOnCertificationDate = certificate.maxReachableLevelOnCertificationDate < 8;
const hasAcquiredAnyComplementaryCertifications = certificate.hasAcquiredAnyComplementaryCertifications();
Expand Down Expand Up @@ -119,6 +148,7 @@ class AttestationViewModel {
stickers,
competenceDetailViewModels,
isFrenchDomainExtension,
version,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ describe('Integration | Infrastructure | Repository | Certification', function (
cleaCertificationImagePath: null,
pixPlusDroitCertificationImagePath: null,
sessionId: 789,
version: SESSIONS_VERSIONS.V2,
};
databaseBuilder.factory.buildUser({ id: 456 });
databaseBuilder.factory.buildOrganizationLearner({
Expand Down Expand Up @@ -1067,6 +1068,7 @@ describe('Integration | Infrastructure | Repository | Certification', function (
publishedAt: new Date('2021-05-07'),
certificationCenter: 'Centre des poules bien dodues',
certificationCenterId,
version: SESSIONS_VERSIONS.V2,
});
_buildCertificationAttestationWithSeveralResults(certificationAttestationDataRejected, status.REJECTED);
const candidate = databaseBuilder.factory.buildCertificationCandidate({
Expand Down Expand Up @@ -2845,6 +2847,7 @@ function _buildSession({ userId, sessionId, publishedAt, certificationCenter })
publishedAt,
certificationCenter: certificationCenter,
certificationCenterId,
version: SESSIONS_VERSIONS.V3,
});
}

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dayjs from 'dayjs';
import pdfLibUtils from 'pdf-lib/cjs/utils/index.js';

import { getCertificationAttestationsPdfBuffer } from '../../../../../../../src/certification/results/infrastructure/utils/pdf/certification-attestation-pdf.js';
import { SESSIONS_VERSIONS } from '../../../../../../../src/certification/shared/domain/models/SessionVersion.js';
import { CertificationAttestationGenerationError } from '../../../../../../../src/shared/domain/errors.js';
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, domainBuilder, expect, nock, sinon } from '../../../../../../test-helper.js';
Expand Down Expand Up @@ -162,6 +163,7 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
},
],
deliveredAt: deliveredBeforeStartDate,
version: SESSIONS_VERSIONS.V2,
});
const certificateWithComplementaryCertificationsAndWithProfessionalizingMessage =
domainBuilder.buildCertificationAttestation({
Expand All @@ -180,6 +182,7 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
},
],
deliveredAt: deliveredAfterStartDate,
version: SESSIONS_VERSIONS.V2,
});
const certificateWithoutComplementaryCertificationsAndWithoutProfessionalizingMessage =
domainBuilder.buildCertificationAttestation({
Expand All @@ -191,6 +194,7 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
pixPlusDroitCertificationImagePath: null,
certifiedBadges: [],
deliveredAt: deliveredBeforeStartDate,
version: SESSIONS_VERSIONS.V2,
});
const certificateComplementaryCertificationsAndWithProfessionalizingMessage =
domainBuilder.buildCertificationAttestation({
Expand All @@ -202,6 +206,7 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
pixPlusDroitCertificationImagePath: null,
certifiedBadges: [],
deliveredAt: deliveredAfterStartDate,
version: SESSIONS_VERSIONS.V2,
});
const referencePdfPath = 'certification-attestation-pdf_several_pages.pdf';
const i18n = getI18n();
Expand Down Expand Up @@ -287,6 +292,43 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
referencePdfPath + ' is not generated as expected',
).to.be.true;
});

describe('when the certification session is version 3', function () {
it('should not display the professionalizing certification message in attestation', async function () {
// given
const professionalizingValidityStartDate = new Date('2022-01-01');
const deliveredAfterStartDate = dayjs(professionalizingValidityStartDate).add(1, 'days').toDate();

const resultCompetenceTree = domainBuilder.buildResultCompetenceTree();
const certificateWithoutProfessionalizingMessage = domainBuilder.buildCertificationAttestation({
id: 1,
firstName: 'Alain',
lastName: 'Cendy',
resultCompetenceTree,
certifiedBadges: [],
deliveredAt: deliveredAfterStartDate,
version: SESSIONS_VERSIONS.V3,
});
const referencePdfPath = 'certification-attestation-pdf-v3-without-professionalizing-message_test.pdf';
const i18n = getI18n();

// when
const { buffer } = await getCertificationAttestationsPdfBuffer({
certificates: [certificateWithoutProfessionalizingMessage],
isFrenchDomainExtension: true,
i18n,
creationDate: new Date('2021-01-01'),
});

await _writeFile(buffer, referencePdfPath);

// then
expect(
await isSameBinary(`${__dirname}/${referencePdfPath}`, buffer),
referencePdfPath + ' is not generated as expected',
).to.be.true;
});
});
});

async function _writeFile(buffer, outputFilename, dryRun = true) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CertificationAttestation } from '../../../../src/certification/results/domain/models/CertificationAttestation.js';
import { SESSIONS_VERSIONS } from '../../../../src/certification/shared/domain/models/SessionVersion.js';

const buildCertificationAttestation = function ({
id = 1,
Expand All @@ -16,6 +17,7 @@ const buildCertificationAttestation = function ({
verificationCode = 'P-SOMECODE',
certifiedBadges = [],
resultCompetenceTree = null,
version = SESSIONS_VERSIONS.V3,
} = {}) {
return new CertificationAttestation({
id,
Expand All @@ -33,6 +35,7 @@ const buildCertificationAttestation = function ({
verificationCode,
certifiedBadges,
resultCompetenceTree,
version,
});
};

Expand Down

0 comments on commit 6806b0d

Please sign in to comment.