diff --git a/api/db/database-builder/factory/build-complementary-certification-course-result.js b/api/db/database-builder/factory/build-complementary-certification-course-result.js index 55b88504c1d..6f7fcd4db2a 100644 --- a/api/db/database-builder/factory/build-complementary-certification-course-result.js +++ b/api/db/database-builder/factory/build-complementary-certification-course-result.js @@ -4,11 +4,13 @@ import { buildComplementaryCertification } from './build-complementary-certifica import { buildCertificationCourse } from './build-certification-course.js'; import _ from 'lodash'; import { ComplementaryCertificationCourseResult } from '../../../lib/domain/models/ComplementaryCertificationCourseResult.js'; +import { buildBadge } from './build-badge.js'; +import { buildComplementaryCertificationBadge } from './build-complementary-certification-badge.js'; const buildComplementaryCertificationCourseResult = function ({ id, complementaryCertificationCourseId, - partnerKey, + complementaryCertificationBadgeId, source = ComplementaryCertificationCourseResult.sources.PIX, acquired = true, }) { @@ -16,9 +18,12 @@ const buildComplementaryCertificationCourseResult = function ({ complementaryCertificationCourseId = _.isUndefined(complementaryCertificationCourseId) ? _buildComplementaryCertificationCourse().id : complementaryCertificationCourseId; + complementaryCertificationBadgeId = _.isUndefined(complementaryCertificationBadgeId) + ? _buildComplementaryCertificationBadge().id + : complementaryCertificationBadgeId; return databaseBuffer.pushInsertable({ tableName: 'complementary-certification-course-results', - values: { id, complementaryCertificationCourseId, partnerKey, source, acquired }, + values: { id, complementaryCertificationCourseId, complementaryCertificationBadgeId, source, acquired }, }); }; @@ -32,3 +37,9 @@ function _buildComplementaryCertificationCourse() { certificationCourseId, }); } + +function _buildComplementaryCertificationBadge() { + const { id: badgeId } = buildBadge(); + const { id: complementaryCertificationId } = buildComplementaryCertification(); + return buildComplementaryCertificationBadge({ badgeId, complementaryCertificationId }); +} diff --git a/api/db/migrations/20231106161726_add-cc-course-results-to-cc-badges-reference.js b/api/db/migrations/20231106161726_add-cc-course-results-to-cc-badges-reference.js new file mode 100644 index 00000000000..148c90ec1ce --- /dev/null +++ b/api/db/migrations/20231106161726_add-cc-course-results-to-cc-badges-reference.js @@ -0,0 +1,29 @@ +const TABLE_NAME = 'complementary-certification-course-results'; +const REF_TABLE_NAME = 'complementary-certification-badges'; +const COLUMN_NAME = 'complementaryCertificationBadgeId'; + +const up = async function (knex) { + await knex.schema.table(TABLE_NAME, function (table) { + table + .integer(COLUMN_NAME) + .defaultTo(null) + .references(`${REF_TABLE_NAME}.id`) + .withKeyName('cccresults-ccbadgeId_foreignkey'); + }); + + await knex(TABLE_NAME).update({ + [COLUMN_NAME]: knex(`${REF_TABLE_NAME}`) + .select(`${REF_TABLE_NAME}.id`) + .innerJoin('badges', 'badges.id', `${REF_TABLE_NAME}.badgeId`) + // eslint-disable-next-line knex/avoid-injections + .where('badges.key', '=', knex.raw(`"${TABLE_NAME}"."partnerKey"`)), + }); +}; + +const down = async function (knex) { + await knex.schema.table(TABLE_NAME, function (table) { + table.dropColumn(COLUMN_NAME); + }); +}; + +export { up, down }; diff --git a/api/db/seeds/data/common/tooling/session-tooling.js b/api/db/seeds/data/common/tooling/session-tooling.js index 961ca2d4247..b4b80bdeae5 100644 --- a/api/db/seeds/data/common/tooling/session-tooling.js +++ b/api/db/seeds/data/common/tooling/session-tooling.js @@ -1094,6 +1094,8 @@ function _makeCandidatesPassCertification({ }).id; databaseBuilder.factory.buildComplementaryCertificationCourseResult({ partnerKey: certificationCandidate.complementaryCertificationBadgeInfo.partnerKey, + complementaryCertificationBadgeId: + certificationCandidate.complementaryCertificationBadgeInfo.complementaryCertificationBadgeId, acquired: true, source: 'PIX', complementaryCertificationCourseId, diff --git a/api/lib/application/complementary-certification-course-results/index.js b/api/lib/application/complementary-certification-course-results/index.js index 90a2a3d73b7..f039539f582 100644 --- a/api/lib/application/complementary-certification-course-results/index.js +++ b/api/lib/application/complementary-certification-course-results/index.js @@ -2,6 +2,7 @@ import Joi from 'joi'; import { identifiersType } from '../../domain/types/identifiers-type.js'; import { securityPreHandlers } from '../security-pre-handlers.js'; import { complementaryCertificationCourseResultsController } from './complementary-certification-course-results-controller.js'; +import { juryOptions } from '../../domain/models/ComplementaryCertificationCourseResult.js'; const register = async function (server) { server.route([ @@ -13,7 +14,12 @@ const register = async function (server) { payload: Joi.object({ data: { attributes: { - juryLevel: Joi.string().required(), + juryLevel: Joi.alternatives() + .try( + identifiersType.complementaryCertificationBadgeId, + Joi.string().valid(juryOptions.REJECTED).valid(juryOptions.UNSET), + ) + .required(), complementaryCertificationCourseId: identifiersType.complementaryCertificationCourseId, }, }, diff --git a/api/lib/domain/events/handle-complementary-certifications-scoring.js b/api/lib/domain/events/handle-complementary-certifications-scoring.js index d2a8b7700c7..5286b078ca3 100644 --- a/api/lib/domain/events/handle-complementary-certifications-scoring.js +++ b/api/lib/domain/events/handle-complementary-certifications-scoring.js @@ -30,6 +30,7 @@ async function handleComplementaryCertificationsScoring({ const { minimumReproducibilityRate, complementaryCertificationCourseId, + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, hasComplementaryReferential, minimumEarnedPix, @@ -49,6 +50,7 @@ async function handleComplementaryCertificationsScoring({ _buildComplementaryCertificationScoringWithReferential( minimumReproducibilityRate, complementaryCertificationCourseId, + complementaryCertificationBadgeId, pixPlusChallenges, pixPlusAnswers, complementaryCertificationBadgeKey, @@ -58,6 +60,7 @@ async function handleComplementaryCertificationsScoring({ complementaryCertificationScoringWithComplementaryReferential = new ComplementaryCertificationScoringWithoutComplementaryReferential({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, reproducibilityRate: assessmentResult.reproducibilityRate, pixScore: assessmentResult.pixScore, @@ -69,6 +72,7 @@ async function handleComplementaryCertificationsScoring({ await complementaryCertificationCourseResultRepository.save( ComplementaryCertificationCourseResult.from({ ...complementaryCertificationScoringWithComplementaryReferential, + source: ComplementaryCertificationCourseResult.sources.PIX, acquired: complementaryCertificationScoringWithComplementaryReferential.isAcquired(), }), ); @@ -78,6 +82,7 @@ async function handleComplementaryCertificationsScoring({ function _buildComplementaryCertificationScoringWithReferential( minimumReproducibilityRate, complementaryCertificationCourseId, + complementaryCertificationBadgeId, challenges, answers, complementaryCertificationBadgeKey, @@ -92,6 +97,7 @@ function _buildComplementaryCertificationScoringWithReferential( return new ComplementaryCertificationScoringWithComplementaryReferential({ minimumReproducibilityRate, complementaryCertificationCourseId, + complementaryCertificationBadgeId, reproducibilityRate, complementaryCertificationBadgeKey, hasAcquiredPixCertification: assessmentResult.isValidated(), diff --git a/api/lib/domain/models/CertificationResult.js b/api/lib/domain/models/CertificationResult.js index 235cb52ce9f..3dee1c41a89 100644 --- a/api/lib/domain/models/CertificationResult.js +++ b/api/lib/domain/models/CertificationResult.js @@ -127,10 +127,6 @@ class CertificationResult { ), ]; } - - _getCertificationCourseResultByPartnerKeys(partnerKeys) { - return this.complementaryCertificationCourseResults.find(({ partnerKey }) => partnerKeys.includes(partnerKey)); - } } CertificationResult.status = status; diff --git a/api/lib/domain/models/ComplementaryCertificationCourseResult.js b/api/lib/domain/models/ComplementaryCertificationCourseResult.js index db846a4a4cc..97e5af3b3d5 100644 --- a/api/lib/domain/models/ComplementaryCertificationCourseResult.js +++ b/api/lib/domain/models/ComplementaryCertificationCourseResult.js @@ -9,29 +9,29 @@ const juryOptions = { }; class ComplementaryCertificationCourseResult { - constructor({ complementaryCertificationCourseId, partnerKey, source, acquired, label } = {}) { + constructor({ complementaryCertificationCourseId, complementaryCertificationBadgeId, source, acquired, label } = {}) { this.complementaryCertificationCourseId = complementaryCertificationCourseId; - this.partnerKey = partnerKey; + this.complementaryCertificationBadgeId = complementaryCertificationBadgeId; this.acquired = acquired; this.source = source; this.label = label; } - static from({ complementaryCertificationCourseId, partnerKey, acquired, source, label }) { + static from({ complementaryCertificationCourseId, complementaryCertificationBadgeId, acquired, source, label }) { return new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId, - partnerKey, + complementaryCertificationBadgeId, acquired, source, label, }); } - static buildFromJuryLevel({ complementaryCertificationCourseId, juryLevel, pixPartnerKey }) { - if (juryLevel === juryOptions.REJECTED) { + static buildFromJuryLevel({ complementaryCertificationCourseId, complementaryCertificationBadgeId, juryLevel }) { + if (juryLevel === 'REJECTED') { return new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId, - partnerKey: pixPartnerKey, + complementaryCertificationBadgeId, acquired: false, source: sources.EXTERNAL, }); @@ -39,7 +39,7 @@ class ComplementaryCertificationCourseResult { return new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId, - partnerKey: juryLevel, + complementaryCertificationBadgeId: juryLevel, acquired: true, source: sources.EXTERNAL, }); diff --git a/api/lib/domain/models/ComplementaryCertificationScoringCriteria.js b/api/lib/domain/models/ComplementaryCertificationScoringCriteria.js index ca42199568a..952ea2ec8e6 100644 --- a/api/lib/domain/models/ComplementaryCertificationScoringCriteria.js +++ b/api/lib/domain/models/ComplementaryCertificationScoringCriteria.js @@ -3,11 +3,13 @@ class ComplementaryCertificationScoringCriteria { complementaryCertificationCourseId, minimumReproducibilityRate, complementaryCertificationBadgeKey, + complementaryCertificationBadgeId, hasComplementaryReferential, minimumEarnedPix, } = {}) { this.complementaryCertificationCourseId = complementaryCertificationCourseId; this.minimumReproducibilityRate = minimumReproducibilityRate; + this.complementaryCertificationBadgeId = complementaryCertificationBadgeId; this.complementaryCertificationBadgeKey = complementaryCertificationBadgeKey; this.hasComplementaryReferential = hasComplementaryReferential; this.minimumEarnedPix = minimumEarnedPix; diff --git a/api/lib/domain/models/ComplementaryCertificationScoringWithComplementaryReferential.js b/api/lib/domain/models/ComplementaryCertificationScoringWithComplementaryReferential.js index 85e532faf99..22376fdec1c 100644 --- a/api/lib/domain/models/ComplementaryCertificationScoringWithComplementaryReferential.js +++ b/api/lib/domain/models/ComplementaryCertificationScoringWithComplementaryReferential.js @@ -4,6 +4,7 @@ import { PartnerCertificationScoring } from './PartnerCertificationScoring.js'; class ComplementaryCertificationScoringWithComplementaryReferential extends PartnerCertificationScoring { constructor({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, reproducibilityRate, hasAcquiredPixCertification, @@ -11,6 +12,7 @@ class ComplementaryCertificationScoringWithComplementaryReferential extends Part } = {}) { super({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, partnerKey: complementaryCertificationBadgeKey, source: ComplementaryCertificationCourseResult.sources.PIX, }); diff --git a/api/lib/domain/models/ComplementaryCertificationScoringWithoutComplementaryReferential.js b/api/lib/domain/models/ComplementaryCertificationScoringWithoutComplementaryReferential.js index 9bdb5068b27..655ab6d9b75 100644 --- a/api/lib/domain/models/ComplementaryCertificationScoringWithoutComplementaryReferential.js +++ b/api/lib/domain/models/ComplementaryCertificationScoringWithoutComplementaryReferential.js @@ -3,7 +3,7 @@ import { PartnerCertificationScoring } from './PartnerCertificationScoring.js'; class ComplementaryCertificationScoringWithoutComplementaryReferential extends PartnerCertificationScoring { constructor({ complementaryCertificationCourseId, - complementaryCertificationBadgeKey, + complementaryCertificationBadgeId, reproducibilityRate, pixScore, minimumEarnedPix, @@ -11,10 +11,9 @@ class ComplementaryCertificationScoringWithoutComplementaryReferential extends P } = {}) { super({ complementaryCertificationCourseId, - partnerKey: complementaryCertificationBadgeKey, + complementaryCertificationBadgeId, }); - this.complementaryCertificationCourseId = complementaryCertificationCourseId; this.reproducibilityRate = reproducibilityRate; this.pixScore = pixScore; this.minimumEarnedPix = minimumEarnedPix; diff --git a/api/lib/domain/models/PartnerCertificationScoring.js b/api/lib/domain/models/PartnerCertificationScoring.js index dd4dea33630..4aeb016fafe 100644 --- a/api/lib/domain/models/PartnerCertificationScoring.js +++ b/api/lib/domain/models/PartnerCertificationScoring.js @@ -10,13 +10,13 @@ const SOURCES = { }; class PartnerCertificationScoring { - constructor({ complementaryCertificationCourseId, partnerKey, source = SOURCES.PIX } = {}) { + constructor({ complementaryCertificationCourseId, complementaryCertificationBadgeId, source = SOURCES.PIX } = {}) { this.complementaryCertificationCourseId = complementaryCertificationCourseId; - this.partnerKey = partnerKey; + this.complementaryCertificationBadgeId = complementaryCertificationBadgeId; this.source = source; const schema = Joi.object({ complementaryCertificationCourseId: Joi.number().integer().required(), - partnerKey: Joi.string().allow(null).required(), + complementaryCertificationBadgeId: Joi.number().integer().required(), source: Joi.string() .required() .valid(...Object.values(SOURCES)), diff --git a/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertification.js b/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertification.js index 5593662f904..336a08121b7 100644 --- a/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertification.js +++ b/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertification.js @@ -4,15 +4,20 @@ const complementaryCertificationStatus = { }; class ComplementaryCertificationCourseResultForJuryCertification { - constructor({ id, partnerKey, acquired, label }) { + constructor({ id, complementaryCertificationBadgeId, acquired, label }) { this.id = id; - this.partnerKey = partnerKey; + this.complementaryCertificationBadgeId = complementaryCertificationBadgeId; this.acquired = acquired; this.label = label; } - static from({ id, partnerKey, acquired, label }) { - return new ComplementaryCertificationCourseResultForJuryCertification({ id, partnerKey, acquired, label }); + static from({ id, complementaryCertificationBadgeId, acquired, label }) { + return new ComplementaryCertificationCourseResultForJuryCertification({ + id, + complementaryCertificationBadgeId, + acquired, + label, + }); } get status() { diff --git a/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal.js b/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal.js index bf29b44357f..66dff9883f8 100644 --- a/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal.js +++ b/api/lib/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal.js @@ -9,11 +9,11 @@ const { EXTERNAL, PIX } = sources; class ComplementaryCertificationCourseResultForJuryCertificationWithExternal { constructor({ complementaryCertificationCourseId, - pixPartnerKey, + pixComplementaryCertificationBadgeId, pixLabel, pixAcquired, pixLevel, - externalPartnerKey, + externalComplementaryCertificationBadgeId, externalLabel, externalAcquired, externalLevel, @@ -21,13 +21,13 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal { }) { this.complementaryCertificationCourseId = complementaryCertificationCourseId; this.pixSection = new Section({ - partnerKey: pixPartnerKey, + complementaryCertificationBadgeId: pixComplementaryCertificationBadgeId, label: pixLabel, acquired: pixAcquired, level: pixLevel, }); this.externalSection = new Section({ - partnerKey: externalPartnerKey, + complementaryCertificationBadgeId: externalComplementaryCertificationBadgeId, label: externalLabel, acquired: externalAcquired, level: externalLevel, @@ -36,7 +36,7 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal { this.defaultJuryOptions = Object.values(juryOptions); } - static from(complementaryCertificationCourseResultWithExternal, badgesKeyAndLabel) { + static from(complementaryCertificationCourseResultWithExternal, badgesIdAndLabels) { if (!complementaryCertificationCourseResultWithExternal.length) { return; } @@ -47,16 +47,18 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal { ({ source }) => source === EXTERNAL, ); - const allowedExternalLevels = badgesKeyAndLabel.map(({ key, label }) => ({ label, value: key })); + const allowedExternalLevels = badgesIdAndLabels.map(({ id, label }) => ({ label, value: id })); return new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ complementaryCertificationCourseId: complementaryCertificationCourseResultWithExternal[0].complementaryCertificationCourseId, - pixPartnerKey: pixComplementaryCertificationCourseResult?.partnerKey, + pixComplementaryCertificationBadgeId: + pixComplementaryCertificationCourseResult?.complementaryCertificationBadgeId, pixLabel: pixComplementaryCertificationCourseResult?.label, pixAcquired: pixComplementaryCertificationCourseResult?.acquired, pixLevel: pixComplementaryCertificationCourseResult?.level, - externalPartnerKey: externalComplementaryCertificationCourseResult?.partnerKey, + externalComplementaryCertificationBadgeId: + externalComplementaryCertificationCourseResult?.complementaryCertificationBadgeId, externalLabel: externalComplementaryCertificationCourseResult?.label, externalAcquired: externalComplementaryCertificationCourseResult?.acquired, externalLevel: externalComplementaryCertificationCourseResult?.level, @@ -86,15 +88,15 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal { } class Section { - constructor({ partnerKey, label, acquired, level }) { - this.partnerKey = partnerKey; + constructor({ complementaryCertificationBadgeId, label, acquired, level }) { + this.complementaryCertificationBadgeId = complementaryCertificationBadgeId; this.label = label; this.acquired = acquired ?? false; this.level = level; } get isEvaluated() { - return Boolean(this.partnerKey); + return Boolean(this.complementaryCertificationBadgeId); } } diff --git a/api/lib/domain/types/identifiers-type.js b/api/lib/domain/types/identifiers-type.js index fecdb86ab98..c36b2e8f766 100644 --- a/api/lib/domain/types/identifiers-type.js +++ b/api/lib/domain/types/identifiers-type.js @@ -39,6 +39,7 @@ const typesPositiveInteger32bits = [ 'certificationIssueReportId', 'complementaryCertificationId', 'complementaryCertificationCourseId', + 'complementaryCertificationBadgeId', 'certificationCenterInvitationId', 'membershipId', 'organizationId', diff --git a/api/lib/domain/usecases/save-jury-complementary-certification-course-result.js b/api/lib/domain/usecases/save-jury-complementary-certification-course-result.js index d004bb51f88..4b67e781584 100644 --- a/api/lib/domain/usecases/save-jury-complementary-certification-course-result.js +++ b/api/lib/domain/usecases/save-jury-complementary-certification-course-result.js @@ -17,8 +17,6 @@ const saveJuryComplementaryCertificationCourseResult = async function ({ ); } - const { partnerKey: pixPartnerKey } = pixSourceComplementaryCertificationCourseResult; - if (juryLevel === ComplementaryCertificationCourseResult.juryOptions.UNSET) { await complementaryCertificationCourseResultRepository.removeExternalJuryResult({ complementaryCertificationCourseId, @@ -26,9 +24,11 @@ const saveJuryComplementaryCertificationCourseResult = async function ({ return; } - const allowedJuryLevels = await complementaryCertificationCourseResultRepository.getAllowedJuryLevelByBadgeKey({ - key: pixPartnerKey, - }); + const { complementaryCertificationBadgeId } = pixSourceComplementaryCertificationCourseResult; + const allowedJuryLevels = + await complementaryCertificationCourseResultRepository.getAllowedJuryLevelIdsByComplementaryCertificationBadgeId( + complementaryCertificationBadgeId, + ); if (![...allowedJuryLevels, ComplementaryCertificationCourseResult.juryOptions.REJECTED].includes(juryLevel)) { throw new InvalidJuryLevelError(); @@ -36,7 +36,7 @@ const saveJuryComplementaryCertificationCourseResult = async function ({ const externalComplementaryCertificationCourseResult = ComplementaryCertificationCourseResult.buildFromJuryLevel({ juryLevel, - pixPartnerKey, + complementaryCertificationBadgeId, complementaryCertificationCourseId, }); diff --git a/api/lib/infrastructure/repositories/certificate-repository.js b/api/lib/infrastructure/repositories/certificate-repository.js index 9fc8449c60f..efaf8a80161 100644 --- a/api/lib/infrastructure/repositories/certificate-repository.js +++ b/api/lib/infrastructure/repositories/certificate-repository.js @@ -71,7 +71,7 @@ export { getPrivateCertificate, findPrivateCertificatesByUserId, getShareableCer async function _getCertifiedBadges(certificationCourseId) { const complementaryCertificationCourseResults = await knex .select( - 'complementary-certification-course-results.partnerKey', + 'badges.key as partnerKey', 'complementary-certification-course-results.source', 'complementary-certification-course-results.acquired', 'complementary-certification-course-results.complementaryCertificationCourseId', @@ -89,15 +89,19 @@ async function _getCertifiedBadges(certificationCourseId) { 'complementary-certification-courses.id', 'complementary-certification-course-results.complementaryCertificationCourseId', ) - .innerJoin('badges', 'badges.key', 'complementary-certification-course-results.partnerKey') - .innerJoin('complementary-certification-badges', 'complementary-certification-badges.badgeId', 'badges.id') + .innerJoin( + 'complementary-certification-badges', + 'complementary-certification-badges.id', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + ) + .innerJoin('badges', 'badges.id', 'complementary-certification-badges.badgeId') .innerJoin( 'complementary-certifications', 'complementary-certifications.id', 'complementary-certification-badges.complementaryCertificationId', ) .where({ certificationCourseId }) - .orderBy('partnerKey'); + .orderBy('badges.key'); return CertifiedBadge.fromComplementaryCertificationCourseResults(complementaryCertificationCourseResults); } diff --git a/api/lib/infrastructure/repositories/certification-result-repository.js b/api/lib/infrastructure/repositories/certification-result-repository.js index 929f3664a0c..a79ca930bd4 100644 --- a/api/lib/infrastructure/repositories/certification-result-repository.js +++ b/api/lib/infrastructure/repositories/certification-result-repository.js @@ -1,9 +1,6 @@ import { knex } from '../../../db/knex-database-connection.js'; import { ComplementaryCertificationCourseResult } from '../../domain/models/ComplementaryCertificationCourseResult.js'; import { CertificationResult } from '../../domain/models/CertificationResult.js'; -import lodash from 'lodash'; - -const { isEmpty } = lodash; const findBySessionId = async function ({ sessionId }) { const certificationResultDTOs = await _selectCertificationResults() @@ -16,13 +13,9 @@ const findBySessionId = async function ({ sessionId }) { sessionId, }); - return certificationResultDTOs.map((certificationResultDTO) => { - certificationResultDTO.complementaryCertificationCourseResults = - complementaryCertificationCourseResultsByCertificationCourseId.find( - ({ certificationCourseId }) => certificationCourseId === certificationResultDTO.id, - )?.complementaryCertificationCourseResults; - return _toDomain(certificationResultDTO); - }); + return certificationResultDTOs.map((certificationResultDTO) => + _toDomain({ certificationResultDTO, complementaryCertificationCourseResultsByCertificationCourseId }), + ); }; const findByCertificationCandidateIds = async function ({ certificationCandidateIds }) { @@ -36,21 +29,18 @@ const findByCertificationCandidateIds = async function ({ certificationCandidate .orderBy('certification-courses.lastName', 'ASC') .orderBy('certification-courses.firstName', 'ASC'); - let complementaryCertificationCourseResultsByCertificationCourseId = []; - if (!isEmpty(certificationResultDTOs)) { - complementaryCertificationCourseResultsByCertificationCourseId = - await _selectComplementaryCertificationCourseResultsBySessionId({ - sessionId: certificationResultDTOs[0].sessionId, - }); + if (!certificationResultDTOs.length) { + return []; } - return certificationResultDTOs.map((certificationResultDTO) => { - certificationResultDTO.complementaryCertificationCourseResults = - complementaryCertificationCourseResultsByCertificationCourseId.find( - ({ certificationCourseId }) => certificationCourseId === certificationResultDTO.id, - )?.complementaryCertificationCourseResults; - return _toDomain(certificationResultDTO); - }); + const complementaryCertificationCourseResultsByCertificationCourseId = + await _selectComplementaryCertificationCourseResultsBySessionId({ + sessionId: certificationResultDTOs[0].sessionId, + }); + + return certificationResultDTOs.map((certificationResultDTO) => + _toDomain({ certificationResultDTO, complementaryCertificationCourseResultsByCertificationCourseId }), + ); }; export { findBySessionId, findByCertificationCandidateIds }; @@ -94,27 +84,26 @@ function _selectCertificationResults() { function _selectComplementaryCertificationCourseResultsBySessionId({ sessionId }) { return knex('complementary-certification-course-results') - .select({ certificationCourseId: 'certification-courses.id' }) - .select( - knex.raw(` - array_agg(json_build_object( - 'complementaryCertificationCourseId', "complementary-certification-course-results"."complementaryCertificationCourseId", - 'id', "complementary-certification-course-results"."id", - 'partnerKey', "complementary-certification-course-results"."partnerKey", - 'acquired', "complementary-certification-course-results"."acquired", - 'source', "complementary-certification-course-results"."source", - 'label', "complementary-certification-badges"."label", - 'order', "complementary-certifications".id - ) order by "complementary-certifications".id, "complementary-certification-badges".level) as "complementaryCertificationCourseResults" - `), - ) + .select({ + certificationCourseId: 'certification-courses.id', + complementaryCertificationCourseId: + 'complementary-certification-course-results.complementaryCertificationCourseId', + id: 'complementary-certification-course-results.id', + complementaryCertificationBadgeId: 'complementary-certification-course-results.complementaryCertificationBadgeId', + acquired: 'complementary-certification-course-results.acquired', + source: 'complementary-certification-course-results.source', + label: 'complementary-certification-badges.label', + }) .join( 'complementary-certification-courses', 'complementary-certification-courses.id', 'complementary-certification-course-results.complementaryCertificationCourseId', ) - .join('badges', 'badges.key', 'complementary-certification-course-results.partnerKey') - .join('complementary-certification-badges', 'complementary-certification-badges.badgeId', 'badges.id') + .join( + 'complementary-certification-badges', + 'complementary-certification-badges.id', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + ) .join( 'complementary-certifications', 'complementary-certifications.id', @@ -125,13 +114,20 @@ function _selectComplementaryCertificationCourseResultsBySessionId({ sessionId } 'certification-courses.id', 'complementary-certification-courses.certificationCourseId', ) - .where({ sessionId }) - .where('complementary-certification-course-results.source', ComplementaryCertificationCourseResult.sources.PIX) - .groupBy('certification-courses.id'); + .where({ + sessionId, + 'complementary-certification-course-results.source': ComplementaryCertificationCourseResult.sources.PIX, + }); } -function _toDomain(certificationResultDTO) { +function _toDomain({ certificationResultDTO, complementaryCertificationCourseResultsByCertificationCourseId }) { + const complementaryCertificationCourseResult = complementaryCertificationCourseResultsByCertificationCourseId.find( + (results) => results.certificationCourseId === certificationResultDTO.id, + ); return CertificationResult.from({ - certificationResultDTO, + certificationResultDTO: { + ...certificationResultDTO, + complementaryCertificationCourseResults: [complementaryCertificationCourseResult], + }, }); } diff --git a/api/lib/infrastructure/repositories/complementary-certification-course-result-repository.js b/api/lib/infrastructure/repositories/complementary-certification-course-result-repository.js index 52e485ff6f4..bcf319677a9 100644 --- a/api/lib/infrastructure/repositories/complementary-certification-course-result-repository.js +++ b/api/lib/infrastructure/repositories/complementary-certification-course-result-repository.js @@ -13,15 +13,31 @@ const getPixSourceResultByComplementaryCertificationCourseId = async function ({ return ComplementaryCertificationCourseResult.from(result); }; -const getAllowedJuryLevelByBadgeKey = async function ({ key }) { - return knex('badges') - .pluck('key') - .where('targetProfileId', '=', knex('badges').select('targetProfileId').where({ key })); +const getAllowedJuryLevelIdsByComplementaryCertificationBadgeId = async function (complementaryCertificationBadgeId) { + return knex + .pluck('complementary-certification-badges.id') + .from('badges') + .innerJoin('complementary-certification-badges', 'badges.id', 'complementary-certification-badges.badgeId') + .where( + 'targetProfileId', + '=', + knex('badges') + .select('targetProfileId') + .innerJoin('complementary-certification-badges', 'badges.id', 'complementary-certification-badges.badgeId') + .where({ 'complementary-certification-badges.id': complementaryCertificationBadgeId }) + .first(), + ) + .orderBy('complementary-certification-badges.level', 'asc'); }; -const save = async function ({ complementaryCertificationCourseId, partnerKey, acquired, source }) { +const save = async function ({ + complementaryCertificationCourseId, + complementaryCertificationBadgeId, + acquired, + source, +}) { return knex('complementary-certification-course-results') - .insert({ partnerKey, acquired, complementaryCertificationCourseId, source }) + .insert({ complementaryCertificationBadgeId, acquired, complementaryCertificationCourseId, source }) .onConflict(['complementaryCertificationCourseId', 'source']) .merge(); }; @@ -34,7 +50,7 @@ const removeExternalJuryResult = async function ({ complementaryCertificationCou export { getPixSourceResultByComplementaryCertificationCourseId, - getAllowedJuryLevelByBadgeKey, + getAllowedJuryLevelIdsByComplementaryCertificationBadgeId, save, removeExternalJuryResult, }; diff --git a/api/lib/infrastructure/repositories/complementary-certification-scoring-criteria-repository.js b/api/lib/infrastructure/repositories/complementary-certification-scoring-criteria-repository.js index 435d3519a83..ccb210747f7 100644 --- a/api/lib/infrastructure/repositories/complementary-certification-scoring-criteria-repository.js +++ b/api/lib/infrastructure/repositories/complementary-certification-scoring-criteria-repository.js @@ -5,6 +5,7 @@ const findByCertificationCourseId = async function ({ certificationCourseId }) { const results = await knex('complementary-certification-courses') .select({ complementaryCertificationCourseId: 'complementary-certification-courses.id', + complementaryCertificationBadgeId: 'complementary-certification-courses.complementaryCertificationBadgeId', minimumReproducibilityRate: 'complementary-certifications.minimumReproducibilityRate', complementaryCertificationBadgeKey: 'badges.key', hasComplementaryReferential: 'complementary-certifications.hasComplementaryReferential', @@ -26,15 +27,17 @@ const findByCertificationCourseId = async function ({ certificationCourseId }) { return results.map( ({ complementaryCertificationCourseId, - minimumReproducibilityRate, + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, + minimumReproducibilityRate, hasComplementaryReferential, minimumEarnedPix, }) => new ComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId, - minimumReproducibilityRate: Number(minimumReproducibilityRate), + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, + minimumReproducibilityRate: Number(minimumReproducibilityRate), hasComplementaryReferential, minimumEarnedPix, }), diff --git a/api/lib/infrastructure/repositories/jury-certification-repository.js b/api/lib/infrastructure/repositories/jury-certification-repository.js index cc8d9c6d32d..eb0554f8fa2 100644 --- a/api/lib/infrastructure/repositories/jury-certification-repository.js +++ b/api/lib/infrastructure/repositories/jury-certification-repository.js @@ -23,7 +23,10 @@ const get = async function (certificationCourseId) { const complementaryCertificationCourseResultDTOs = await knex('complementary-certification-course-results') .select( - 'complementary-certification-course-results.*', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + 'complementary-certification-course-results.complementaryCertificationCourseId', + 'complementary-certification-course-results.acquired', + 'complementary-certification-course-results.source', 'complementary-certification-courses.id', 'complementary-certification-badges.label', 'complementary-certification-badges.level', @@ -34,8 +37,12 @@ const get = async function (certificationCourseId) { 'complementary-certification-course-results.complementaryCertificationCourseId', 'complementary-certification-courses.id', ) - .leftJoin('badges', 'badges.key', 'complementary-certification-course-results.partnerKey') - .leftJoin('complementary-certification-badges', 'complementary-certification-badges.badgeId', 'badges.id') + .leftJoin( + 'complementary-certification-badges', + 'complementary-certification-badges.id', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + ) + .leftJoin('badges', 'complementary-certification-badges.badgeId', 'badges.id') .leftJoin( 'complementary-certifications', 'complementary-certifications.id', @@ -45,7 +52,7 @@ const get = async function (certificationCourseId) { certificationCourseId: juryCertificationDTO.certificationCourseId, }); - const badgesKeyAndLabel = await _getComplementaryBadgesKeyAndLabel({ certificationCourseId }); + const badgeIdAndLabels = await _getComplementaryBadgeIdAndLabels({ certificationCourseId }); const certificationIssueReportDTOs = await knex('certification-issue-reports') .where({ certificationCourseId }) @@ -56,7 +63,7 @@ const get = async function (certificationCourseId) { certificationIssueReportDTOs, competenceMarkDTOs, complementaryCertificationCourseResultDTOs, - badgesKeyAndLabel, + badgeIdAndLabels, }); }; @@ -110,7 +117,7 @@ async function _toDomainWithComplementaryCertifications({ certificationIssueReportDTOs, competenceMarkDTOs, complementaryCertificationCourseResultDTOs, - badgesKeyAndLabel, + badgeIdAndLabels, }) { const certificationIssueReports = certificationIssueReportDTOs.map( (certificationIssueReport) => new CertificationIssueReport({ ...certificationIssueReport }), @@ -119,7 +126,7 @@ async function _toDomainWithComplementaryCertifications({ const { complementaryCertificationCourseResultWithExternal, commonComplementaryCertificationCourseResult } = _toComplementaryCertificationCourseResultForJuryCertification( complementaryCertificationCourseResultDTOs, - badgesKeyAndLabel, + badgeIdAndLabels, ); return JuryCertification.from({ @@ -133,7 +140,7 @@ async function _toDomainWithComplementaryCertifications({ function _toComplementaryCertificationCourseResultForJuryCertification( complementaryCertificationCourseResults, - badgesKeyAndLabel, + badgeIdAndLabels, ) { const [complementaryCertificationCourseResultWithExternal, commonComplementaryCertificationCourseResult] = _.partition(complementaryCertificationCourseResults, 'hasExternalJury'); @@ -141,7 +148,7 @@ function _toComplementaryCertificationCourseResultForJuryCertification( const complementaryCertificationCourseResultsForJuryCertificationWithExternal = ComplementaryCertificationCourseResultForJuryCertificationWithExternal.from( complementaryCertificationCourseResultWithExternal, - badgesKeyAndLabel, + badgeIdAndLabels, ); if (commonComplementaryCertificationCourseResult.length > 1) { @@ -157,9 +164,9 @@ function _toComplementaryCertificationCourseResultForJuryCertification( }; } -async function _getComplementaryBadgesKeyAndLabel({ certificationCourseId }) { +async function _getComplementaryBadgeIdAndLabels({ certificationCourseId }) { return knex - .select('badges.key', 'complementary-certification-badges.label') + .select('complementary-certification-badges.id', 'complementary-certification-badges.label') .from('badges') .innerJoin('complementary-certification-badges', 'badges.id', 'complementary-certification-badges.badgeId') .where( diff --git a/api/lib/infrastructure/repositories/jury-certification-summary-repository.js b/api/lib/infrastructure/repositories/jury-certification-summary-repository.js index d79f83913ed..7492ec5977c 100644 --- a/api/lib/infrastructure/repositories/jury-certification-summary-repository.js +++ b/api/lib/infrastructure/repositories/jury-certification-summary-repository.js @@ -80,8 +80,11 @@ async function _getByCertificationCourseIds(orderedCertificationCourseIds) { ComplementaryCertificationCourseResult.sources.PIX, ); }) - .leftJoin('badges', 'badges.key', 'complementary-certification-course-results.partnerKey') - .leftJoin('complementary-certification-badges', 'complementary-certification-badges.badgeId', 'badges.id') + .leftJoin( + 'complementary-certification-badges', + 'complementary-certification-badges.id', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + ) .whereIn('certification-courses.id', orderedCertificationCourseIds); return orderedCertificationCourseIds.map((orderedId) => results.find(({ id }) => id === orderedId)); diff --git a/api/src/certification/complementary-certification/infrastructure/repositories/complementary-certification-course-repository.js b/api/src/certification/complementary-certification/infrastructure/repositories/complementary-certification-course-repository.js index 44d1769bbe5..905070edc28 100644 --- a/api/src/certification/complementary-certification/infrastructure/repositories/complementary-certification-course-repository.js +++ b/api/src/certification/complementary-certification/infrastructure/repositories/complementary-certification-course-repository.js @@ -6,12 +6,12 @@ const findByUserId = async function ({ userId }) { .select({ id: 'complementary-certification-courses.id', hasExternalJury: 'complementary-certifications.hasExternalJury', - complementaryCertificationBadgeId: 'complementaryCertificationBadgeId', + complementaryCertificationBadgeId: 'complementary-certification-badges.id', results: knex.raw( `array_agg(json_build_object( 'id', "complementary-certification-course-results".id, 'acquired', "complementary-certification-course-results".acquired, - 'partnerKey', "complementary-certification-course-results"."partnerKey", + 'complementaryCertificationBadgeId', "complementary-certification-course-results"."complementaryCertificationBadgeId", 'source', "complementary-certification-course-results".source))`, ), }) @@ -37,7 +37,8 @@ const findByUserId = async function ({ userId }) { 'complementary-certification-courses.certificationCourseId', ) .where({ userId }) - .groupBy('hasExternalJury', 'complementaryCertificationBadgeId', 'complementary-certification-courses.id'); + .groupBy('hasExternalJury', 'complementary-certification-badges.id', 'complementary-certification-courses.id') + .orderBy('complementary-certification-badges.id'); if (!results.length) return []; diff --git a/api/src/certification/course/infrastructure/repositories/certificate-repository.js b/api/src/certification/course/infrastructure/repositories/certificate-repository.js index 46162380813..444bc167007 100644 --- a/api/src/certification/course/infrastructure/repositories/certificate-repository.js +++ b/api/src/certification/course/infrastructure/repositories/certificate-repository.js @@ -142,7 +142,7 @@ function _toDomainForCertificationAttestation({ certificationCourseDTO, competen async function _getCertifiedBadges(certificationCourseId) { const complementaryCertificationCourseResults = await knex .select( - 'complementary-certification-course-results.partnerKey', + 'badges.key as partnerKey', 'complementary-certification-course-results.source', 'complementary-certification-course-results.acquired', 'complementary-certification-course-results.complementaryCertificationCourseId', @@ -160,15 +160,19 @@ async function _getCertifiedBadges(certificationCourseId) { 'complementary-certification-courses.id', 'complementary-certification-course-results.complementaryCertificationCourseId', ) - .innerJoin('badges', 'badges.key', 'complementary-certification-course-results.partnerKey') - .innerJoin('complementary-certification-badges', 'complementary-certification-badges.badgeId', 'badges.id') + .innerJoin( + 'complementary-certification-badges', + 'complementary-certification-badges.id', + 'complementary-certification-course-results.complementaryCertificationBadgeId', + ) + .innerJoin('badges', 'badges.id', 'complementary-certification-badges.badgeId') .innerJoin( 'complementary-certifications', 'complementary-certifications.id', 'complementary-certification-badges.complementaryCertificationId', ) .where({ certificationCourseId }) - .orderBy('partnerKey'); + .orderBy('badges.key'); return CertifiedBadge.fromComplementaryCertificationCourseResults(complementaryCertificationCourseResults); } diff --git a/api/tests/acceptance/application/certification-courses/certification-course-controller_test.js b/api/tests/acceptance/application/certification-courses/certification-course-controller_test.js index 83b379b0037..609d38fa75e 100644 --- a/api/tests/acceptance/application/certification-courses/certification-course-controller_test.js +++ b/api/tests/acceptance/application/certification-courses/certification-course-controller_test.js @@ -220,17 +220,19 @@ describe('Acceptance | API | Certification Course', function () { }); databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 777, badgeId: 456, complementaryCertificationId: pixBoxeComplementaryCertificationId, label: 'Pix Boxe 1', }); databaseBuilder.factory.buildComplementaryCertificationBadge({ - id: 789, + id: 778, badgeId: 457, complementaryCertificationId: pixBoxeComplementaryCertificationId, label: 'Pix Boxe 2', }); databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 779, badgeId: 458, complementaryCertificationId: pixBoxeComplementaryCertificationId, label: 'Pix Boxe 3', @@ -239,20 +241,20 @@ describe('Acceptance | API | Certification Course', function () { id: 654, certificationCourseId: 123, complementaryCertificationId: pixBoxeComplementaryCertificationId, - complementaryCertificationBadgeId: 789, + complementaryCertificationBadgeId: 778, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ id: 987, - partnerKey: 'PIX_BOXE_2', acquired: true, complementaryCertificationCourseId: 654, + complementaryCertificationBadgeId: 778, source: ComplementaryCertificationCourseResult.sources.PIX, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ id: 986, - partnerKey: 'PIX_BOXE_2', acquired: false, complementaryCertificationCourseId: 654, + complementaryCertificationBadgeId: 778, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); databaseBuilder.factory.buildAssessment({ id: 159, certificationCourseId: 123 }); @@ -353,15 +355,15 @@ describe('Acceptance | API | Certification Course', function () { 'allowed-external-levels': [ { label: 'Pix Boxe 1', - value: 'PIX_BOXE_1', + value: 777, }, { label: 'Pix Boxe 2', - value: 'PIX_BOXE_2', + value: 778, }, { label: 'Pix Boxe 3', - value: 'PIX_BOXE_3', + value: 779, }, ], 'default-jury-options': ['REJECTED', 'UNSET'], diff --git a/api/tests/acceptance/application/certifications/index_test.js b/api/tests/acceptance/application/certifications/index_test.js index 4922294654e..d94b1d42ea4 100644 --- a/api/tests/acceptance/application/certifications/index_test.js +++ b/api/tests/acceptance/application/certifications/index_test.js @@ -116,6 +116,7 @@ describe('Acceptance | API | Certifications', function () { await databaseBuilder.commit(); }); + it('should return 200 HTTP status code', async function () { options = { method: 'GET', @@ -204,6 +205,7 @@ describe('Acceptance | API | Certifications', function () { await databaseBuilder.commit(); }); + it('should return 200 HTTP status code', async function () { options = { method: 'GET', @@ -287,7 +289,16 @@ describe('Acceptance | API | Certifications', function () { 'last-name': certificationCourse.lastName, 'pix-score': assessmentResult.pixScore, status: assessmentResult.status, - 'certified-badge-images': [], + 'certified-badge-images': [ + { + imageUrl: 'http://tarte.fr/mirabelle.png', + isTemporaryBadge: false, + label: 'tarte à la mirabelle', + partnerKey: 'charlotte_aux_fraises', + stickerUrl: 'http://tarte.fr/sticker.png', + message: 'Miam', + }, + ], 'verification-code': certificationCourse.verificationCode, 'max-reachable-level-on-certification-date': certificationCourse.maxReachableLevelOnCertificationDate, }, @@ -442,7 +453,16 @@ describe('Acceptance | API | Certifications', function () { 'is-published': certificationCourse.isPublished, 'last-name': certificationCourse.lastName, 'pix-score': assessmentResult.pixScore, - 'certified-badge-images': [], + 'certified-badge-images': [ + { + imageUrl: 'http://tarte.fr/mirabelle.png', + isTemporaryBadge: false, + label: 'tarte à la mirabelle', + partnerKey: 'charlotte_aux_fraises', + stickerUrl: 'http://tarte.fr/sticker.png', + message: 'Miam', + }, + ], 'max-reachable-level-on-certification-date': certificationCourse.maxReachableLevelOnCertificationDate, }, id: `${certificationCourse.id}`, @@ -638,6 +658,17 @@ async function _buildDatabaseForV2Certification() { const userId = databaseBuilder.factory.buildUser().id; const session = databaseBuilder.factory.buildSession({ publishedAt: new Date('2018-12-01T01:02:03Z') }); const badge = databaseBuilder.factory.buildBadge({ key: 'charlotte_aux_fraises' }); + const cc = databaseBuilder.factory.buildComplementaryCertification(); + const ccBadge = databaseBuilder.factory.buildComplementaryCertificationBadge({ + complementaryCertificationId: cc.id, + partnerKey: 'charlotte_aux_fraises', + badgeId: badge.id, + imageUrl: 'http://tarte.fr/mirabelle.png', + isTemporaryBadge: false, + label: 'tarte à la mirabelle', + certificateMessage: 'Miam', + stickerUrl: 'http://tarte.fr/sticker.png', + }); const certificationCourse = databaseBuilder.factory.buildCertificationCourse({ sessionId: session.id, userId, @@ -665,6 +696,7 @@ async function _buildDatabaseForV2Certification() { }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: id, + complementaryCertificationBadgeId: ccBadge.id, partnerKey: badge.key, }); return { userId, session, badge, certificationCourse, assessment, assessmentResult }; diff --git a/api/tests/acceptance/application/certifications/sticker.pdf b/api/tests/acceptance/application/certifications/sticker.pdf new file mode 100644 index 00000000000..f7c613f259e Binary files /dev/null and b/api/tests/acceptance/application/certifications/sticker.pdf differ diff --git a/api/tests/acceptance/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js b/api/tests/acceptance/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js index d1c664965a7..e223a9745a4 100644 --- a/api/tests/acceptance/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js +++ b/api/tests/acceptance/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js @@ -13,13 +13,31 @@ describe('Acceptance | API | Certifications', function () { it('should return 201 HTTP status code', async function () { // given const server = await createServer(); + databaseBuilder.factory.buildTargetProfile({ id: 99 }); const badge = databaseBuilder.factory.buildBadge({ key: 'BADGE_KEY', + targetProfileId: 99, + }); + const badge2 = databaseBuilder.factory.buildBadge({ + key: 'BADGE_KEY_2', + targetProfileId: 99, }); databaseBuilder.factory.buildComplementaryCertification({ id: 1, name: 'Pix+ Test', }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 24, + complementaryCertificationId: 1, + badgeId: badge.id, + level: 1, + }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 25, + complementaryCertificationId: 1, + badgeId: badge2.id, + level: 2, + }); databaseBuilder.factory.buildCertificationCourse({ id: 456, }); @@ -27,10 +45,12 @@ describe('Acceptance | API | Certifications', function () { id: 1234, certificationCourseId: 456, complementaryCertificationId: 1, + complementaryCertificationBadgeId: 24, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 1234, + complementaryCertificationBadgeId: 24, partnerKey: badge.key, source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -45,7 +65,7 @@ describe('Acceptance | API | Certifications', function () { payload: { data: { attributes: { - juryLevel: badge.key, + juryLevel: 25, complementaryCertificationCourseId: 1234, }, }, diff --git a/api/tests/acceptance/application/session/session-controller-get-jury-certification-summaries_test.js b/api/tests/acceptance/application/session/session-controller-get-jury-certification-summaries_test.js index a079d7139fe..d28bd488749 100644 --- a/api/tests/acceptance/application/session/session-controller-get-jury-certification-summaries_test.js +++ b/api/tests/acceptance/application/session/session-controller-get-jury-certification-summaries_test.js @@ -74,6 +74,7 @@ describe('Acceptance | Controller | session-controller-get-jury-certification-su }); dbf.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: id, + complementaryCertificationBadgeId, partnerKey: badge.key, acquired: true, }); diff --git a/api/tests/certification/complementary-certification/integration/infrastucture/repositories/complementary-certification-course-repository_test.js b/api/tests/certification/complementary-certification/integration/infrastucture/repositories/complementary-certification-course-repository_test.js index 02d2144a624..a9bbad03091 100644 --- a/api/tests/certification/complementary-certification/integration/infrastucture/repositories/complementary-certification-course-repository_test.js +++ b/api/tests/certification/complementary-certification/integration/infrastucture/repositories/complementary-certification-course-repository_test.js @@ -66,21 +66,21 @@ describe('Integration | Repository | complementary-certification-course-reposito databaseBuilder.factory.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 123, source: ComplementaryCertificationCourseResult.sources.PIX, }).id; const complementaryCertificationCourseResultId2 = databaseBuilder.factory.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 1000, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 456, source: ComplementaryCertificationCourseResult.sources.PIX, }).id; const complementaryCertificationCourseResultId3 = databaseBuilder.factory.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 1000, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 456, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }).id; @@ -100,7 +100,7 @@ describe('Integration | Repository | complementary-certification-course-reposito { id: complementaryCertificationCourseResultId1, acquired: true, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 123, source: ComplementaryCertificationCourseResult.sources.PIX, }, ], @@ -114,13 +114,13 @@ describe('Integration | Repository | complementary-certification-course-reposito { id: complementaryCertificationCourseResultId3, acquired: true, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 456, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }, { id: complementaryCertificationCourseResultId2, acquired: true, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 456, source: ComplementaryCertificationCourseResult.sources.PIX, }, ], diff --git a/api/tests/certification/course/acceptance/application/certification-attestation-route_test.js b/api/tests/certification/course/acceptance/application/certification-attestation-route_test.js index 7e12d1817e4..72414d481f5 100644 --- a/api/tests/certification/course/acceptance/application/certification-attestation-route_test.js +++ b/api/tests/certification/course/acceptance/application/certification-attestation-route_test.js @@ -5,11 +5,15 @@ import { learningContentBuilder, mockLearningContent, insertUserWithRoleSuperAdmin, + nock, } from '../../../../test-helper.js'; import { createServer } from '../../../../../server.js'; import { Assessment } from '../../../../../src/shared/domain/models/Assessment.js'; import { generateCertificateVerificationCode } from '../../../../../lib/domain/services/verify-certificate-code-service.js'; import { AssessmentResult, Membership } from '../../../../../lib/domain/models/index.js'; +import { readFile } from 'node:fs/promises'; +import * as url from 'url'; + describe('Acceptance | Route | certification-attestation', function () { beforeEach(async function () { const learningContent = [ @@ -98,6 +102,11 @@ describe('Acceptance | Route | certification-attestation', function () { const learningContentObjects = learningContentBuilder.fromAreas(learningContent); mockLearningContent(learningContentObjects); + + const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); + nock('http://tarte.fr') + .get('/sticker.pdf') + .reply(200, () => readFile(`${__dirname}/sticker.pdf`)); }); describe('GET /api/attestation/', function () { @@ -105,7 +114,7 @@ describe('Acceptance | Route | certification-attestation', function () { it('should return 200 HTTP status code and the certification', async function () { // given const userId = databaseBuilder.factory.buildUser().id; - await _buildDatabaseForV2Certification({ userId }); + await _buildDatabaseForV2Certification({ userId, certificationCourseId: 1234 }); await databaseBuilder.commit(); const server = await createServer(); @@ -130,7 +139,7 @@ describe('Acceptance | Route | certification-attestation', function () { it('should return 200 HTTP status code and the certification', async function () { // given const superAdmin = await insertUserWithRoleSuperAdmin(); - await _buildDatabaseForV2Certification({ userId: superAdmin.id }); + await _buildDatabaseForV2Certification({ userId: superAdmin.id, sessionId: 4567 }); await databaseBuilder.commit(); const server = await createServer(); @@ -221,39 +230,56 @@ describe('Acceptance | Route | certification-attestation', function () { expect(response.statusCode).to.equal(200); }); }); - - async function _buildDatabaseForV2Certification({ userId }) { - const session = databaseBuilder.factory.buildSession({ id: 4567, publishedAt: new Date('2018-12-01T01:02:03Z') }); - const badge = databaseBuilder.factory.buildBadge({ key: 'charlotte_aux_fraises' }); - const certificationCourse = databaseBuilder.factory.buildCertificationCourse({ - id: 1234, - sessionId: session.id, - userId, - isPublished: true, - maxReachableLevelOnCertificationDate: 3, - verificationCode: await generateCertificateVerificationCode(), - }); - const assessment = databaseBuilder.factory.buildAssessment({ - userId, - certificationCourseId: certificationCourse.id, - type: Assessment.types.CERTIFICATION, - state: 'completed', - }); - databaseBuilder.factory.buildAssessmentResult.last({ - certificationCourseId: certificationCourse.id, - assessmentId: assessment.id, - level: 1, - pixScore: 23, - emitter: 'PIX-ALGO', - status: 'validated', - }); - const { id } = databaseBuilder.factory.buildComplementaryCertificationCourse({ - certificationCourseId: certificationCourse.id, - name: 'patisseries au fruits', - }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: id, - partnerKey: badge.key, - }); - } }); + +async function _buildDatabaseForV2Certification({ userId, certificationCourseId = 10, sessionId = 12 }) { + const session = databaseBuilder.factory.buildSession({ + id: sessionId, + publishedAt: new Date('2018-12-01T01:02:03Z'), + }); + const badge = databaseBuilder.factory.buildBadge({ key: 'charlotte_aux_fraises' }); + const cc = databaseBuilder.factory.buildComplementaryCertification(); + const ccBadge = databaseBuilder.factory.buildComplementaryCertificationBadge({ + complementaryCertificationId: cc.id, + partnerKey: 'charlotte_aux_fraises', + badgeId: badge.id, + imageUrl: 'http://tarte.fr/mirabelle.png', + isTemporaryBadge: false, + label: 'tarte à la mirabelle', + certificateMessage: 'Miam', + stickerUrl: 'http://tarte.fr/sticker.pdf', + }); + const certificationCourse = databaseBuilder.factory.buildCertificationCourse({ + sessionId: session.id, + id: certificationCourseId, + userId, + isPublished: true, + maxReachableLevelOnCertificationDate: 3, + verificationCode: await generateCertificateVerificationCode(), + }); + const assessment = databaseBuilder.factory.buildAssessment({ + userId, + certificationCourseId: certificationCourse.id, + type: Assessment.types.CERTIFICATION, + state: 'completed', + }); + const assessmentResult = databaseBuilder.factory.buildAssessmentResult.last({ + certificationCourseId: certificationCourse.id, + assessmentId: assessment.id, + level: 1, + pixScore: 23, + emitter: 'PIX-ALGO', + status: 'validated', + }); + const { id } = databaseBuilder.factory.buildComplementaryCertificationCourse({ + certificationCourseId: certificationCourse.id, + complementaryCertificationBadgeId: ccBadge.id, + name: 'patisseries au fruits', + }); + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: id, + complementaryCertificationBadgeId: ccBadge.id, + partnerKey: badge.key, + }); + return { userId, session, badge, certificationCourse, assessment, assessmentResult }; +} diff --git a/api/tests/certification/course/acceptance/application/sticker.pdf b/api/tests/certification/course/acceptance/application/sticker.pdf new file mode 100644 index 00000000000..f7c613f259e Binary files /dev/null and b/api/tests/certification/course/acceptance/application/sticker.pdf differ diff --git a/api/tests/certification/course/integration/infrastructure/repositories/certificate-repository_test.js b/api/tests/certification/course/integration/infrastructure/repositories/certificate-repository_test.js index a6ed53b5c51..55d21106e11 100644 --- a/api/tests/certification/course/integration/infrastructure/repositories/certificate-repository_test.js +++ b/api/tests/certification/course/integration/infrastructure/repositories/certificate-repository_test.js @@ -25,13 +25,18 @@ describe('Integration | Infrastructure | Repository | Certification', function ( }, ]; - describe('#findByDivisionForScoIsManagingStudentsOrganization', function () { - it('should return an empty array when there are no certification attestations for given organization', async function () { + describe('#getCertificationAttestation', function () { + it('should throw a NotFoundError when certification attestation does not exist', async function () { + // when + const error = await catchErr(certificationRepository.getCertificationAttestation)(123); + + // then + expect(error).to.be.instanceOf(NotFoundError); + expect(error.message).to.equal('There is no certification course with id "123"'); + }); + + it('should throw a NotFoundError when certification has no assessment-result', async function () { // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); - databaseBuilder.factory.buildOrganization({ id: 456, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -46,8 +51,7 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ @@ -56,30 +60,21 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildValidCertificationAttestation(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 456, - division: '3emeB', - }); + _buildIncomplete(certificationAttestationData); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const error = await catchErr(certificationRepository.getCertificationAttestation)( + certificationAttestationData.id, + ); // then - expect(certificationAttestations).to.be.empty; + expect(error).to.be.instanceOf(NotFoundError); + expect(error.message).to.equal('There is no certification course with id "123"'); }); - it('should return an empty array when the organization is not SCO IS MANAGING STUDENTS', async function () { + it('should throw a NotFoundError when certification is cancelled', async function () { // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SUP', isManagingStudents: false }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -94,47 +89,37 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ - userId: 456, - sessionId: 789, - publishedAt: new Date('2021-05-05'), - certificationCenter: 'Centre des poules bien dodues', - }); - _buildValidCertificationAttestation(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 123, - division: '3emeB', + userId: certificationAttestationData.userId, + sessionId: certificationAttestationData.sessionId, + publishedAt: certificationAttestationData.deliveredAt, + certificationCenter: certificationAttestationData.certificationCenter, }); + _buildCancelled(certificationAttestationData); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const error = await catchErr(certificationRepository.getCertificationAttestation)( + certificationAttestationData.id, + ); // then - expect(certificationAttestations).to.be.empty; + expect(error).to.be.instanceOf(NotFoundError); + expect(error.message).to.equal('There is no certification course with id "123"'); }); - it('should return an empty array when the certification does not belong to an organization learner in the right division', async function () { + it('should throw a NotFoundError when certification is not published', async function () { // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', - isPublished: true, + isPublished: false, userId: 456, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', @@ -142,8 +127,7 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ @@ -153,29 +137,20 @@ describe('Integration | Infrastructure | Repository | Certification', function ( certificationCenter: certificationAttestationData.certificationCenter, }); _buildValidCertificationAttestation(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 123, - division: '5emeG', - }); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const error = await catchErr(certificationRepository.getCertificationAttestation)( + certificationAttestationData.id, + ); // then - expect(certificationAttestations).to.be.empty; + expect(error).to.be.instanceOf(NotFoundError); + expect(error.message).to.equal('There is no certification course with id "123"'); }); - it('should not return certifications that have no validated assessment-result', async function () { + it('should throw a NotFoundError when certification is rejected', async function () { // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -190,8 +165,7 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ @@ -201,29 +175,23 @@ describe('Integration | Infrastructure | Repository | Certification', function ( certificationCenter: certificationAttestationData.certificationCenter, }); _buildRejected(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 123, - division: '3emeB', - }); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const error = await catchErr(certificationRepository.getCertificationAttestation)( + certificationAttestationData.id, + ); // then - expect(certificationAttestations).to.be.empty; + expect(error).to.be.instanceOf(NotFoundError); + expect(error.message).to.equal('There is no certification course with id "123"'); }); - it('should not return cancelled certifications', async function () { + it('should return a CertificationAttestation', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); + const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -238,8 +206,7 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ @@ -248,37 +215,29 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildCancelled(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 123, - division: '3emeB', - }); + _buildValidCertificationAttestation(certificationAttestationData); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const certificationAttestation = await certificationRepository.getCertificationAttestation(123); // then - expect(certificationAttestations).to.be.empty; + const expectedCertificationAttestation = + domainBuilder.buildCertificationAttestation(certificationAttestationData); + expect(certificationAttestation).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ + 'resultCompetenceTree', + ]); }); - it('should not return non published certifications', async function () { + it('should return a CertificationAttestation with appropriate result competence tree', async function () { // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', - isPublished: false, + isPublished: true, userId: 456, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', @@ -286,8 +245,7 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [], sessionId: 789, }; _buildSession({ @@ -296,276 +254,117 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildValidCertificationAttestation(certificationAttestationData); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationId: 123, - division: '3emeB', + const assessmentResultId = _buildValidCertificationAttestation(certificationAttestationData, false); + + const competenceMarks1 = domainBuilder.buildCompetenceMark({ + id: 1234, + level: 4, + score: 32, + area_code: '1', + competence_code: '1.1', + competenceId: 'recComp1', + assessmentResultId, + }); + databaseBuilder.factory.buildCompetenceMark(competenceMarks1); + + const competenceMarks2 = domainBuilder.buildCompetenceMark({ + id: 4567, + level: 5, + score: 40, + area_code: '1', + competence_code: '1.2', + competenceId: 'recComp2', + assessmentResultId, }); + databaseBuilder.factory.buildCompetenceMark(competenceMarks2); + await databaseBuilder.commit(); + const competence1 = domainBuilder.buildCompetence({ + id: 'recComp1', + index: '1.1', + name: 'Traiter des données', + }); + const competence2 = domainBuilder.buildCompetence({ + id: 'recComp2', + index: '1.2', + name: 'Traiter des choux', + }); + const area1 = domainBuilder.buildArea({ + id: 'recArea1', + code: '1', + competences: [ + { ...competence1, name_i18n: { fr: competence1.name } }, + { ...competence2, name_i18n: { fr: competence2.name } }, + ], + title: 'titre test', + framework: null, + }); + + const learningContentObjects = learningContentBuilder.fromAreas([{ ...area1, title_i18n: { fr: area1.title } }]); + mockLearningContent(learningContentObjects); + // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const certificationAttestation = await certificationRepository.getCertificationAttestation(123); // then - expect(certificationAttestations).to.be.empty; + const expectedResultCompetenceTree = domainBuilder.buildResultCompetenceTree({ + id: `123-${assessmentResultId}`, + competenceMarks: [competenceMarks1, competenceMarks2], + competenceTree: domainBuilder.buildCompetenceTree({ areas: [area1] }), + }); + expect(certificationAttestation.resultCompetenceTree).to.deepEqualInstance(expectedResultCompetenceTree); }); - it('should return an array of certification attestations ordered by last name, first name', async function () { + it('should take into account the latest validated assessment result of a student', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); - const certificationAttestationDataA = { - id: 456, - firstName: 'James', - lastName: 'Marsters', - birthdate: '1962-08-20', - birthplace: 'Trouville', - isPublished: true, - userId: 111, - date: new Date('2020-05-01'), - verificationCode: 'P-SOMEOTHERCODE', - maxReachableLevelOnCertificationDate: 6, - deliveredAt: new Date('2021-07-05'), - certificationCenter: 'Centre des poules bien dodues', - pixScore: 23, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 777, - }; - const certificationAttestationDataB = { + const certificationAttestationData = { id: 123, - firstName: 'Laura', + firstName: 'Sarah Michelle', lastName: 'Gellar', - birthdate: '1990-01-04', - birthplace: 'Torreilles', + birthdate: '1977-04-14', + birthplace: 'Saint-Ouen', isPublished: true, - userId: 333, - date: new Date('2019-01-01'), - verificationCode: 'P-YETANOTHERCODE', - maxReachableLevelOnCertificationDate: 5, - deliveredAt: new Date('2020-05-05'), - certificationCenter: 'Centre Catalan', - pixScore: 150, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 999, - }; - const certificationAttestationDataC = { - id: 789, - firstName: 'Sarah Michelle', - lastName: 'Gellar', - birthdate: '1977-04-14', - birthplace: 'Saint-Ouen', - isPublished: true, - userId: 222, + userId: 456, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', maxReachableLevelOnCertificationDate: 5, deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 888, + certifiedBadges: [], + sessionId: 789, }; - _buildSession({ - userId: certificationAttestationDataA.userId, - sessionId: certificationAttestationDataA.sessionId, - publishedAt: certificationAttestationDataA.deliveredAt, - certificationCenter: certificationAttestationDataA.certificationCenter, - }); - _buildSession({ - userId: certificationAttestationDataC.userId, - sessionId: certificationAttestationDataC.sessionId, - publishedAt: certificationAttestationDataC.deliveredAt, - certificationCenter: certificationAttestationDataC.certificationCenter, - }); - _buildSession({ - userId: certificationAttestationDataB.userId, - sessionId: certificationAttestationDataB.sessionId, - publishedAt: certificationAttestationDataB.deliveredAt, - certificationCenter: certificationAttestationDataB.certificationCenter, - }); - _buildValidCertificationAttestation(certificationAttestationDataA); - _buildValidCertificationAttestation(certificationAttestationDataB); - _buildValidCertificationAttestation(certificationAttestationDataC); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataA, - organizationId: 123, - division: '3emeB', - }); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataB, - organizationId: 123, - division: '3emeB', - }); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataC, - organizationId: 123, - division: '3emeB', - }); - await databaseBuilder.commit(); - - // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); - - // then - const expectedCertificationAttestationA = - domainBuilder.buildCertificationAttestation(certificationAttestationDataA); - const expectedCertificationAttestationB = - domainBuilder.buildCertificationAttestation(certificationAttestationDataB); - const expectedCertificationAttestationC = - domainBuilder.buildCertificationAttestation(certificationAttestationDataC); - expect(certificationAttestations).to.have.length(3); - - expect(certificationAttestations[0]).deepEqualInstanceOmitting(expectedCertificationAttestationB, [ - 'resultCompetenceTree', - ]); - expect(certificationAttestations[1]).deepEqualInstanceOmitting(expectedCertificationAttestationC, [ - 'resultCompetenceTree', - ]); - expect(certificationAttestations[2]).deepEqualInstanceOmitting(expectedCertificationAttestationA, [ - 'resultCompetenceTree', - ]); - }); - it('should ignore disabled shooling-registrations', async function () { - // given - const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); - mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); - const certificationAttestationDataA = { - id: 456, - firstName: 'James', - lastName: 'Marsters', - birthdate: '1962-08-20', - birthplace: 'Trouville', - isPublished: true, - userId: 111, - date: new Date('2020-05-01'), - verificationCode: 'P-SOMEOTHERCODE', - maxReachableLevelOnCertificationDate: 6, - deliveredAt: new Date('2021-07-05'), - certificationCenter: 'Centre des poules bien dodues', - pixScore: 23, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 777, - }; - const certificationAttestationDataB = { - id: 123, - firstName: 'Laura', - lastName: 'Gellar', - birthdate: '1990-01-04', - birthplace: 'Torreilles', - isPublished: true, - userId: 333, - date: new Date('2019-01-01'), - verificationCode: 'P-YETANOTHERCODE', - maxReachableLevelOnCertificationDate: 5, - deliveredAt: new Date('2020-05-05'), - certificationCenter: 'Centre Catalan', - pixScore: 150, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 999, - }; - const certificationAttestationDataC = { - id: 789, - firstName: 'Sarah Michelle', - lastName: 'Gellar', - birthdate: '1977-04-14', - birthplace: 'Saint-Ouen', - isPublished: true, - userId: 222, - date: new Date('2020-01-01'), - verificationCode: 'P-SOMECODE', - maxReachableLevelOnCertificationDate: 5, - deliveredAt: new Date('2021-05-05'), - certificationCenter: 'Centre des poules bien dodues', - pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 888, - }; - _buildSession({ - userId: certificationAttestationDataA.userId, - sessionId: certificationAttestationDataA.sessionId, - publishedAt: certificationAttestationDataA.deliveredAt, - certificationCenter: certificationAttestationDataA.certificationCenter, - }); - _buildSession({ - userId: certificationAttestationDataC.userId, - sessionId: certificationAttestationDataC.sessionId, - publishedAt: certificationAttestationDataC.deliveredAt, - certificationCenter: certificationAttestationDataC.certificationCenter, - }); _buildSession({ - userId: certificationAttestationDataB.userId, - sessionId: certificationAttestationDataB.sessionId, - publishedAt: certificationAttestationDataB.deliveredAt, - certificationCenter: certificationAttestationDataB.certificationCenter, - }); - _buildValidCertificationAttestation(certificationAttestationDataA); - _buildValidCertificationAttestation(certificationAttestationDataB); - _buildValidCertificationAttestation(certificationAttestationDataC); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataA, - organizationId: 123, - division: '3emeB', - }); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataB, - organizationId: 123, - division: '3emeB', - }); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataC, - organizationId: 123, - division: '3emeB', - isDisabled: true, + userId: certificationAttestationData.userId, + sessionId: certificationAttestationData.sessionId, + publishedAt: certificationAttestationData.deliveredAt, + certificationCenter: certificationAttestationData.certificationCenter, }); + _buildCertificationAttestationWithSeveralResults(certificationAttestationData); await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const certificationAttestation = await certificationRepository.getCertificationAttestation( + certificationAttestationData.id, + ); // then - const expectedCertificationAttestationA = - domainBuilder.buildCertificationAttestation(certificationAttestationDataA); - const expectedCertificationAttestationB = - domainBuilder.buildCertificationAttestation(certificationAttestationDataB); - - expect(certificationAttestations).to.have.length(2); - expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestationB, [ - 'resultCompetenceTree', - ]); - - expect(certificationAttestations[1]).to.deepEqualInstanceOmitting(expectedCertificationAttestationA, [ + const expectedCertificationAttestation = + domainBuilder.buildCertificationAttestation(certificationAttestationData); + expect(certificationAttestation).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ 'resultCompetenceTree', ]); }); - describe('when the last certification is rejected', function () { - it('should take into account the latest valid certification', async function () { + context('acquired certifiable badges', function () { + it(`should get the certified badge images when the certifications were acquired`, async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); - databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -580,80 +379,110 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, + certifiedBadges: [ + { + isTemporaryBadge: false, + label: 'Pix+ Test 1', + partnerKey: 'PIX_TEST_1', + imageUrl: 'https://images.pix.fr/badge1.svg', + stickerUrl: 'https://images.pix.fr/skicker1.pdf', + message: 'Pix+ Test 1 certificate message', + }, + { + isTemporaryBadge: true, + label: 'Pix+ Test 2', + partnerKey: 'PIX_TEST_2', + imageUrl: 'https://images.pix.fr/badge2.svg', + stickerUrl: 'https://images.pix.fr/skicker2.pdf', + message: 'Pix+ Test 2 temporary certificate message', + }, + ], sessionId: 789, }; - databaseBuilder.factory.buildUser({ id: 456 }); - databaseBuilder.factory.buildOrganizationLearner({ - id: 55, - organizationId: 123, - userId: 456, - division: '3emeB', - }).id; - const certificationCenterId = databaseBuilder.factory.buildCertificationCenter().id; - databaseBuilder.factory.buildSession({ - id: 789, - publishedAt: new Date('2021-05-05'), - certificationCenter: 'Centre des poules bien dodues', - certificationCenterId, + + _buildSession({ + userId: certificationAttestationData.userId, + sessionId: certificationAttestationData.sessionId, + publishedAt: certificationAttestationData.deliveredAt, + certificationCenter: certificationAttestationData.certificationCenter, }); + _buildValidCertificationAttestation(certificationAttestationData); + const badge1Id = databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_1' }).id; + const badge2Id = databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_2' }).id; + const complementaryCertification1Id = databaseBuilder.factory.buildComplementaryCertification({ + label: 'Pix+ Test 1', + hasExternalJury: false, + }).id; + const complementaryCertification2Id = databaseBuilder.factory.buildComplementaryCertification({ + label: 'Pix+ Test 2', + hasExternalJury: true, + }).id; + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 21, + label: 'Pix+ Test 1', + badgeId: badge1Id, + complementaryCertificationId: complementaryCertification1Id, + imageUrl: 'https://images.pix.fr/badge1.svg', + stickerUrl: 'https://images.pix.fr/skicker1.pdf', + certificateMessage: 'Pix+ Test 1 certificate message', + temporaryCertificateMessage: '', + }).id; + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 22, + label: 'Pix+ Test 2', + badgeId: badge2Id, + complementaryCertificationId: complementaryCertification2Id, + imageUrl: 'https://images.pix.fr/badge2.svg', + stickerUrl: 'https://images.pix.fr/skicker2.pdf', + certificateMessage: 'Pix+ Test 2 certificate message', + temporaryCertificateMessage: 'Pix+ Test 2 temporary certificate message', + }).id; - _buildCertificationAttestationWithSeveralResults(certificationAttestationData, status.VALIDATED); - _linkCertificationAttestationToOrganization({ - certificationAttestationData, - organizationLearnerId: 55, + databaseBuilder.factory.buildComplementaryCertificationCourse({ + id: 998, + certificationCourseId: 123, + complementaryCertificationId: complementaryCertification1Id, + complementaryCertificationBadgeId: 21, }); - - const certificationAttestationDataRejected = { - ...certificationAttestationData, - id: 124, - date: new Date('2020-01-03'), - sessionId: 790, - verificationCode: 'P-SOM3COD3', - }; - databaseBuilder.factory.buildSession({ - id: 790, - publishedAt: new Date('2021-05-07'), - certificationCenter: 'Centre des poules bien dodues', - certificationCenterId, + databaseBuilder.factory.buildComplementaryCertificationCourse({ + id: 999, + certificationCourseId: 123, + complementaryCertificationId: complementaryCertification2Id, + complementaryCertificationBadgeId: 22, }); - _buildCertificationAttestationWithSeveralResults(certificationAttestationDataRejected, status.REJECTED); - databaseBuilder.factory.buildCertificationCandidate({ - userId: 456, - sessionId: certificationAttestationDataRejected.sessionId, - organizationLearnerId: 55, + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: 998, + complementaryCertificationBadgeId: 21, + acquired: true, + }); + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 22, + acquired: true, }); - await databaseBuilder.commit(); // when - const certificationAttestations = - await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ - organizationId: 123, - division: '3emeB', - }); + const certificationAttestation = await certificationRepository.getCertificationAttestation(123); // then const expectedCertificationAttestation = domainBuilder.buildCertificationAttestation(certificationAttestationData); - expect(certificationAttestations).to.have.length(1); - expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ + expect(certificationAttestation).deepEqualInstanceOmitting(expectedCertificationAttestation, [ 'resultCompetenceTree', ]); }); }); + }); - it('should take into account the latest certification of an organization learner', async function () { + describe('#findByDivisionForScoIsManagingStudentsOrganization', function () { + it('should return an empty array when there are no certification attestations for given organization', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); - const organizationLearnerId = databaseBuilder.factory.buildOrganizationLearner({ - organizationId: 123, - division: '3emeb', - }).id; - const certificationAttestationDataOldest = { + databaseBuilder.factory.buildOrganization({ id: 456, type: 'SCO', isManagingStudents: true }); + const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', lastName: 'Gellar', @@ -671,47 +500,17 @@ describe('Integration | Infrastructure | Repository | Certification', function ( pixPlusDroitCertificationImagePath: null, sessionId: 789, }; - const certificationAttestationDataNewest = { - id: 456, - firstName: 'Sarah Michelle', - lastName: 'Gellar', - birthdate: '1977-04-14', - birthplace: 'Saint-Ouen', - isPublished: true, - userId: 789, - date: new Date('2021-01-01'), - verificationCode: 'P-SOMEOTHERCODE', - maxReachableLevelOnCertificationDate: 5, - deliveredAt: new Date('2021-05-05'), - certificationCenter: 'Centre des poules bien maigrelettes', - pixScore: 51, - cleaCertificationImagePath: null, - pixPlusDroitCertificationImagePath: null, - sessionId: 999, - }; - _buildSession({ - userId: certificationAttestationDataOldest.userId, - sessionId: certificationAttestationDataOldest.sessionId, - publishedAt: certificationAttestationDataOldest.deliveredAt, - certificationCenter: certificationAttestationDataOldest.certificationCenter, - }); _buildSession({ - userId: certificationAttestationDataNewest.userId, - sessionId: certificationAttestationDataNewest.sessionId, - publishedAt: certificationAttestationDataNewest.deliveredAt, - certificationCenter: certificationAttestationDataNewest.certificationCenter, - }); - _buildValidCertificationAttestation(certificationAttestationDataOldest); - _buildValidCertificationAttestation(certificationAttestationDataNewest); - _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataOldest, - organizationId: 123, - organizationLearnerId, + userId: certificationAttestationData.userId, + sessionId: certificationAttestationData.sessionId, + publishedAt: certificationAttestationData.deliveredAt, + certificationCenter: certificationAttestationData.certificationCenter, }); + _buildValidCertificationAttestation(certificationAttestationData); _linkCertificationAttestationToOrganization({ - certificationAttestationData: certificationAttestationDataNewest, - organizationId: 123, - organizationLearnerId, + certificationAttestationData, + organizationId: 456, + division: '3emeB', }); await databaseBuilder.commit(); @@ -723,28 +522,14 @@ describe('Integration | Infrastructure | Repository | Certification', function ( }); // then - const expectedCertificationAttestation = domainBuilder.buildCertificationAttestation( - certificationAttestationDataNewest, - ); - expect(certificationAttestations).to.have.length(1); - expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ - 'resultCompetenceTree', - ]); - }); - }); - - describe('#getCertificationAttestation', function () { - it('should throw a NotFoundError when certification attestation does not exist', async function () { - // when - const error = await catchErr(certificationRepository.getCertificationAttestation)(123); - - // then - expect(error).to.be.instanceOf(NotFoundError); - expect(error.message).to.equal('There is no certification course with id "123"'); + expect(certificationAttestations).to.be.empty; }); - it('should throw a NotFoundError when certification has no assessment-result', async function () { + it('should return an empty array when the organization is not SCO IS MANAGING STUDENTS', async function () { // given + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SUP', isManagingStudents: false }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -759,30 +544,40 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; _buildSession({ - userId: certificationAttestationData.userId, - sessionId: certificationAttestationData.sessionId, - publishedAt: certificationAttestationData.deliveredAt, - certificationCenter: certificationAttestationData.certificationCenter, + userId: 456, + sessionId: 789, + publishedAt: new Date('2021-05-05'), + certificationCenter: 'Centre des poules bien dodues', + }); + _buildValidCertificationAttestation(certificationAttestationData); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationId: 123, + division: '3emeB', }); - _buildIncomplete(certificationAttestationData); await databaseBuilder.commit(); // when - const error = await catchErr(certificationRepository.getCertificationAttestation)( - certificationAttestationData.id, - ); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - expect(error).to.be.instanceOf(NotFoundError); - expect(error.message).to.equal('There is no certification course with id "123"'); + expect(certificationAttestations).to.be.empty; }); - it('should throw a NotFoundError when certification is cancelled', async function () { + it('should return an empty array when the certification does not belong to an organization learner in the right division', async function () { // given + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -797,7 +592,8 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; _buildSession({ @@ -806,28 +602,37 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildCancelled(certificationAttestationData); + _buildValidCertificationAttestation(certificationAttestationData); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationId: 123, + division: '5emeG', + }); await databaseBuilder.commit(); // when - const error = await catchErr(certificationRepository.getCertificationAttestation)( - certificationAttestationData.id, - ); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - expect(error).to.be.instanceOf(NotFoundError); - expect(error.message).to.equal('There is no certification course with id "123"'); + expect(certificationAttestations).to.be.empty; }); - it('should throw a NotFoundError when certification is not published', async function () { + it('should not return certifications that have no validated assessment-result', async function () { // given + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', - isPublished: false, + isPublished: true, userId: 456, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', @@ -835,7 +640,8 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; _buildSession({ @@ -844,21 +650,30 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildValidCertificationAttestation(certificationAttestationData); + _buildRejected(certificationAttestationData); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationId: 123, + division: '3emeB', + }); await databaseBuilder.commit(); // when - const error = await catchErr(certificationRepository.getCertificationAttestation)( - certificationAttestationData.id, - ); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - expect(error).to.be.instanceOf(NotFoundError); - expect(error.message).to.equal('There is no certification course with id "123"'); + expect(certificationAttestations).to.be.empty; }); - it('should throw a NotFoundError when certification is rejected', async function () { + it('should not return cancelled certifications', async function () { // given + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -873,7 +688,8 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; _buildSession({ @@ -882,31 +698,37 @@ describe('Integration | Infrastructure | Repository | Certification', function ( publishedAt: certificationAttestationData.deliveredAt, certificationCenter: certificationAttestationData.certificationCenter, }); - _buildRejected(certificationAttestationData); + _buildCancelled(certificationAttestationData); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationId: 123, + division: '3emeB', + }); await databaseBuilder.commit(); // when - const error = await catchErr(certificationRepository.getCertificationAttestation)( - certificationAttestationData.id, - ); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - expect(error).to.be.instanceOf(NotFoundError); - expect(error.message).to.equal('There is no certification course with id "123"'); + expect(certificationAttestations).to.be.empty; }); - it('should return a CertificationAttestation', async function () { + it('should not return non published certifications', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); - + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', - isPublished: true, + isPublished: false, userId: 456, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', @@ -914,7 +736,8 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; _buildSession({ @@ -924,155 +747,275 @@ describe('Integration | Infrastructure | Repository | Certification', function ( certificationCenter: certificationAttestationData.certificationCenter, }); _buildValidCertificationAttestation(certificationAttestationData); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationId: 123, + division: '3emeB', + }); await databaseBuilder.commit(); // when - const certificationAttestation = await certificationRepository.getCertificationAttestation(123); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); - // then - const expectedCertificationAttestation = - domainBuilder.buildCertificationAttestation(certificationAttestationData); - expect(certificationAttestation).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ - 'resultCompetenceTree', - ]); + // then + expect(certificationAttestations).to.be.empty; }); - it('should return a CertificationAttestation with appropriate result competence tree', async function () { + it('should return an array of certification attestations ordered by last name, first name', async function () { // given - const certificationAttestationData = { + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); + const certificationAttestationDataA = { + id: 456, + firstName: 'James', + lastName: 'Marsters', + birthdate: '1962-08-20', + birthplace: 'Trouville', + isPublished: true, + userId: 111, + date: new Date('2020-05-01'), + verificationCode: 'P-SOMEOTHERCODE', + maxReachableLevelOnCertificationDate: 6, + deliveredAt: new Date('2021-07-05'), + certificationCenter: 'Centre des poules bien dodues', + pixScore: 23, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 777, + }; + const certificationAttestationDataB = { id: 123, + firstName: 'Laura', + lastName: 'Gellar', + birthdate: '1990-01-04', + birthplace: 'Torreilles', + isPublished: true, + userId: 333, + date: new Date('2019-01-01'), + verificationCode: 'P-YETANOTHERCODE', + maxReachableLevelOnCertificationDate: 5, + deliveredAt: new Date('2020-05-05'), + certificationCenter: 'Centre Catalan', + pixScore: 150, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 999, + }; + const certificationAttestationDataC = { + id: 789, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', isPublished: true, - userId: 456, + userId: 222, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', maxReachableLevelOnCertificationDate: 5, deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], - sessionId: 789, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 888, }; _buildSession({ - userId: certificationAttestationData.userId, - sessionId: certificationAttestationData.sessionId, - publishedAt: certificationAttestationData.deliveredAt, - certificationCenter: certificationAttestationData.certificationCenter, + userId: certificationAttestationDataA.userId, + sessionId: certificationAttestationDataA.sessionId, + publishedAt: certificationAttestationDataA.deliveredAt, + certificationCenter: certificationAttestationDataA.certificationCenter, }); - const assessmentResultId = _buildValidCertificationAttestation(certificationAttestationData, false); - - const competenceMarks1 = domainBuilder.buildCompetenceMark({ - id: 1234, - level: 4, - score: 32, - area_code: '1', - competence_code: '1.1', - competenceId: 'recComp1', - assessmentResultId, + _buildSession({ + userId: certificationAttestationDataC.userId, + sessionId: certificationAttestationDataC.sessionId, + publishedAt: certificationAttestationDataC.deliveredAt, + certificationCenter: certificationAttestationDataC.certificationCenter, }); - databaseBuilder.factory.buildCompetenceMark(competenceMarks1); - - const competenceMarks2 = domainBuilder.buildCompetenceMark({ - id: 4567, - level: 5, - score: 40, - area_code: '1', - competence_code: '1.2', - competenceId: 'recComp2', - assessmentResultId, + _buildSession({ + userId: certificationAttestationDataB.userId, + sessionId: certificationAttestationDataB.sessionId, + publishedAt: certificationAttestationDataB.deliveredAt, + certificationCenter: certificationAttestationDataB.certificationCenter, }); - databaseBuilder.factory.buildCompetenceMark(competenceMarks2); - - await databaseBuilder.commit(); - - const competence1 = domainBuilder.buildCompetence({ - id: 'recComp1', - index: '1.1', - name: 'Traiter des données', + _buildValidCertificationAttestation(certificationAttestationDataA); + _buildValidCertificationAttestation(certificationAttestationDataB); + _buildValidCertificationAttestation(certificationAttestationDataC); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataA, + organizationId: 123, + division: '3emeB', }); - const competence2 = domainBuilder.buildCompetence({ - id: 'recComp2', - index: '1.2', - name: 'Traiter des choux', + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataB, + organizationId: 123, + division: '3emeB', }); - const area1 = domainBuilder.buildArea({ - id: 'recArea1', - code: '1', - competences: [ - { ...competence1, name_i18n: { fr: competence1.name } }, - { ...competence2, name_i18n: { fr: competence2.name } }, - ], - title: 'titre test', - framework: null, + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataC, + organizationId: 123, + division: '3emeB', }); - - const learningContentObjects = learningContentBuilder.fromAreas([{ ...area1, title_i18n: { fr: area1.title } }]); - mockLearningContent(learningContentObjects); + await databaseBuilder.commit(); // when - const certificationAttestation = await certificationRepository.getCertificationAttestation(123); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - const expectedResultCompetenceTree = domainBuilder.buildResultCompetenceTree({ - id: `123-${assessmentResultId}`, - competenceMarks: [competenceMarks1, competenceMarks2], - competenceTree: domainBuilder.buildCompetenceTree({ areas: [area1] }), - }); - expect(certificationAttestation.resultCompetenceTree).to.deepEqualInstance(expectedResultCompetenceTree); + const expectedCertificationAttestationA = + domainBuilder.buildCertificationAttestation(certificationAttestationDataA); + const expectedCertificationAttestationB = + domainBuilder.buildCertificationAttestation(certificationAttestationDataB); + const expectedCertificationAttestationC = + domainBuilder.buildCertificationAttestation(certificationAttestationDataC); + expect(certificationAttestations).to.have.length(3); + + expect(certificationAttestations[0]).deepEqualInstanceOmitting(expectedCertificationAttestationB, [ + 'resultCompetenceTree', + ]); + expect(certificationAttestations[1]).deepEqualInstanceOmitting(expectedCertificationAttestationC, [ + 'resultCompetenceTree', + ]); + expect(certificationAttestations[2]).deepEqualInstanceOmitting(expectedCertificationAttestationA, [ + 'resultCompetenceTree', + ]); }); - it('should take into account the latest validated assessment result of a student', async function () { + it('should ignore disabled shooling-registrations', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); - const certificationAttestationData = { + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); + const certificationAttestationDataA = { + id: 456, + firstName: 'James', + lastName: 'Marsters', + birthdate: '1962-08-20', + birthplace: 'Trouville', + isPublished: true, + userId: 111, + date: new Date('2020-05-01'), + verificationCode: 'P-SOMEOTHERCODE', + maxReachableLevelOnCertificationDate: 6, + deliveredAt: new Date('2021-07-05'), + certificationCenter: 'Centre des poules bien dodues', + pixScore: 23, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 777, + }; + const certificationAttestationDataB = { id: 123, + firstName: 'Laura', + lastName: 'Gellar', + birthdate: '1990-01-04', + birthplace: 'Torreilles', + isPublished: true, + userId: 333, + date: new Date('2019-01-01'), + verificationCode: 'P-YETANOTHERCODE', + maxReachableLevelOnCertificationDate: 5, + deliveredAt: new Date('2020-05-05'), + certificationCenter: 'Centre Catalan', + pixScore: 150, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 999, + }; + const certificationAttestationDataC = { + id: 789, firstName: 'Sarah Michelle', lastName: 'Gellar', birthdate: '1977-04-14', birthplace: 'Saint-Ouen', isPublished: true, - userId: 456, + userId: 222, date: new Date('2020-01-01'), verificationCode: 'P-SOMECODE', maxReachableLevelOnCertificationDate: 5, deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [], - sessionId: 789, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 888, }; - _buildSession({ - userId: certificationAttestationData.userId, - sessionId: certificationAttestationData.sessionId, - publishedAt: certificationAttestationData.deliveredAt, - certificationCenter: certificationAttestationData.certificationCenter, + userId: certificationAttestationDataA.userId, + sessionId: certificationAttestationDataA.sessionId, + publishedAt: certificationAttestationDataA.deliveredAt, + certificationCenter: certificationAttestationDataA.certificationCenter, + }); + _buildSession({ + userId: certificationAttestationDataC.userId, + sessionId: certificationAttestationDataC.sessionId, + publishedAt: certificationAttestationDataC.deliveredAt, + certificationCenter: certificationAttestationDataC.certificationCenter, + }); + _buildSession({ + userId: certificationAttestationDataB.userId, + sessionId: certificationAttestationDataB.sessionId, + publishedAt: certificationAttestationDataB.deliveredAt, + certificationCenter: certificationAttestationDataB.certificationCenter, + }); + _buildValidCertificationAttestation(certificationAttestationDataA); + _buildValidCertificationAttestation(certificationAttestationDataB); + _buildValidCertificationAttestation(certificationAttestationDataC); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataA, + organizationId: 123, + division: '3emeB', + }); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataB, + organizationId: 123, + division: '3emeB', + }); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataC, + organizationId: 123, + division: '3emeB', + isDisabled: true, }); - _buildCertificationAttestationWithSeveralResults(certificationAttestationData); await databaseBuilder.commit(); // when - const certificationAttestation = await certificationRepository.getCertificationAttestation( - certificationAttestationData.id, - ); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then - const expectedCertificationAttestation = - domainBuilder.buildCertificationAttestation(certificationAttestationData); - expect(certificationAttestation).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ + const expectedCertificationAttestationA = + domainBuilder.buildCertificationAttestation(certificationAttestationDataA); + const expectedCertificationAttestationB = + domainBuilder.buildCertificationAttestation(certificationAttestationDataB); + + expect(certificationAttestations).to.have.length(2); + expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestationB, [ + 'resultCompetenceTree', + ]); + + expect(certificationAttestations[1]).to.deepEqualInstanceOmitting(expectedCertificationAttestationA, [ 'resultCompetenceTree', ]); }); - context('acquired certifiable badges', function () { - it(`should get the certified badge images when the certifications were acquired`, async function () { + describe('when the last certification is rejected', function () { + it('should take into account the latest valid certification', async function () { // given const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); const certificationAttestationData = { id: 123, firstName: 'Sarah Michelle', @@ -1087,101 +1030,178 @@ describe('Integration | Infrastructure | Repository | Certification', function ( deliveredAt: new Date('2021-05-05'), certificationCenter: 'Centre des poules bien dodues', pixScore: 51, - certifiedBadges: [ - { - isTemporaryBadge: false, - label: 'Pix+ Test 1', - partnerKey: 'PIX_TEST_1', - imageUrl: 'https://images.pix.fr/badge1.svg', - stickerUrl: 'https://images.pix.fr/skicker1.pdf', - message: 'Pix+ Test 1 certificate message', - }, - { - isTemporaryBadge: true, - label: 'Pix+ Test 2', - partnerKey: 'PIX_TEST_2', - imageUrl: 'https://images.pix.fr/badge2.svg', - stickerUrl: 'https://images.pix.fr/skicker2.pdf', - message: 'Pix+ Test 2 temporary certificate message', - }, - ], + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, sessionId: 789, }; - - _buildSession({ - userId: certificationAttestationData.userId, - sessionId: certificationAttestationData.sessionId, - publishedAt: certificationAttestationData.deliveredAt, - certificationCenter: certificationAttestationData.certificationCenter, - }); - _buildValidCertificationAttestation(certificationAttestationData); - const badge1Id = databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_1' }).id; - const badge2Id = databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_2' }).id; - const complementaryCertification1Id = databaseBuilder.factory.buildComplementaryCertification({ - label: 'Pix+ Test 1', - hasExternalJury: false, - }).id; - const complementaryCertification2Id = databaseBuilder.factory.buildComplementaryCertification({ - label: 'Pix+ Test 2', - hasExternalJury: true, - }).id; - const complementaryCertificationBadge1Id = databaseBuilder.factory.buildComplementaryCertificationBadge({ - label: 'Pix+ Test 1', - badgeId: badge1Id, - complementaryCertificationId: complementaryCertification1Id, - imageUrl: 'https://images.pix.fr/badge1.svg', - stickerUrl: 'https://images.pix.fr/skicker1.pdf', - certificateMessage: 'Pix+ Test 1 certificate message', - temporaryCertificateMessage: '', - }).id; - const complementaryCertificationBadge2Id = databaseBuilder.factory.buildComplementaryCertificationBadge({ - label: 'Pix+ Test 2', - badgeId: badge2Id, - complementaryCertificationId: complementaryCertification2Id, - imageUrl: 'https://images.pix.fr/badge2.svg', - stickerUrl: 'https://images.pix.fr/skicker2.pdf', - certificateMessage: 'Pix+ Test 2 certificate message', - temporaryCertificateMessage: 'Pix+ Test 2 temporary certificate message', + databaseBuilder.factory.buildUser({ id: 456 }); + databaseBuilder.factory.buildOrganizationLearner({ + id: 55, + organizationId: 123, + userId: 456, + division: '3emeB', }).id; - - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 998, - certificationCourseId: 123, - complementaryCertificationId: complementaryCertification1Id, - complementaryCertificationBadgeId: complementaryCertificationBadge1Id, + const certificationCenterId = databaseBuilder.factory.buildCertificationCenter().id; + databaseBuilder.factory.buildSession({ + id: 789, + publishedAt: new Date('2021-05-05'), + certificationCenter: 'Centre des poules bien dodues', + certificationCenterId, }); - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 999, - certificationCourseId: 123, - complementaryCertificationId: complementaryCertification2Id, - complementaryCertificationBadgeId: complementaryCertificationBadge2Id, + + _buildCertificationAttestationWithSeveralResults(certificationAttestationData, status.VALIDATED); + _linkCertificationAttestationToOrganization({ + certificationAttestationData, + organizationLearnerId: 55, }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 998, - partnerKey: 'PIX_TEST_1', - acquired: true, + + const certificationAttestationDataRejected = { + ...certificationAttestationData, + id: 124, + date: new Date('2020-01-03'), + sessionId: 790, + verificationCode: 'P-SOM3COD3', + }; + databaseBuilder.factory.buildSession({ + id: 790, + publishedAt: new Date('2021-05-07'), + certificationCenter: 'Centre des poules bien dodues', + certificationCenterId, }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_2', - acquired: true, + _buildCertificationAttestationWithSeveralResults(certificationAttestationDataRejected, status.REJECTED); + databaseBuilder.factory.buildCertificationCandidate({ + userId: 456, + sessionId: certificationAttestationDataRejected.sessionId, + organizationLearnerId: 55, }); + await databaseBuilder.commit(); // when - const certificationAttestation = await certificationRepository.getCertificationAttestation(123); + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); // then const expectedCertificationAttestation = domainBuilder.buildCertificationAttestation(certificationAttestationData); - expect(certificationAttestation).deepEqualInstanceOmitting(expectedCertificationAttestation, [ + expect(certificationAttestations).to.have.length(1); + expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ 'resultCompetenceTree', ]); }); }); + + it('should take into account the latest certification of an organization learner', async function () { + // given + const learningContentObjects = learningContentBuilder.fromAreas(minimalLearningContent); + mockLearningContent(learningContentObjects); + databaseBuilder.factory.buildOrganization({ id: 123, type: 'SCO', isManagingStudents: true }); + const organizationLearnerId = databaseBuilder.factory.buildOrganizationLearner({ + organizationId: 123, + division: '3emeb', + }).id; + const certificationAttestationDataOldest = { + id: 123, + firstName: 'Sarah Michelle', + lastName: 'Gellar', + birthdate: '1977-04-14', + birthplace: 'Saint-Ouen', + isPublished: true, + userId: 456, + date: new Date('2020-01-01'), + verificationCode: 'P-SOMECODE', + maxReachableLevelOnCertificationDate: 5, + deliveredAt: new Date('2021-05-05'), + certificationCenter: 'Centre des poules bien dodues', + pixScore: 51, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 789, + }; + const certificationAttestationDataNewest = { + id: 456, + firstName: 'Sarah Michelle', + lastName: 'Gellar', + birthdate: '1977-04-14', + birthplace: 'Saint-Ouen', + isPublished: true, + userId: 789, + date: new Date('2021-01-01'), + verificationCode: 'P-SOMEOTHERCODE', + maxReachableLevelOnCertificationDate: 5, + deliveredAt: new Date('2021-05-05'), + certificationCenter: 'Centre des poules bien maigrelettes', + pixScore: 51, + cleaCertificationImagePath: null, + pixPlusDroitCertificationImagePath: null, + sessionId: 999, + }; + _buildSession({ + userId: certificationAttestationDataOldest.userId, + sessionId: certificationAttestationDataOldest.sessionId, + publishedAt: certificationAttestationDataOldest.deliveredAt, + certificationCenter: certificationAttestationDataOldest.certificationCenter, + }); + _buildSession({ + userId: certificationAttestationDataNewest.userId, + sessionId: certificationAttestationDataNewest.sessionId, + publishedAt: certificationAttestationDataNewest.deliveredAt, + certificationCenter: certificationAttestationDataNewest.certificationCenter, + }); + _buildValidCertificationAttestation(certificationAttestationDataOldest); + _buildValidCertificationAttestation(certificationAttestationDataNewest); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataOldest, + organizationId: 123, + organizationLearnerId, + }); + _linkCertificationAttestationToOrganization({ + certificationAttestationData: certificationAttestationDataNewest, + organizationId: 123, + organizationLearnerId, + }); + await databaseBuilder.commit(); + + // when + const certificationAttestations = + await certificationRepository.findByDivisionForScoIsManagingStudentsOrganization({ + organizationId: 123, + division: '3emeB', + }); + + // then + const expectedCertificationAttestation = domainBuilder.buildCertificationAttestation( + certificationAttestationDataNewest, + ); + expect(certificationAttestations).to.have.length(1); + expect(certificationAttestations[0]).to.deepEqualInstanceOmitting(expectedCertificationAttestation, [ + 'resultCompetenceTree', + ]); + }); }); }); +function _buildIncomplete(certificationAttestationData) { + databaseBuilder.factory.buildCertificationCourse({ + id: certificationAttestationData.id, + firstName: certificationAttestationData.firstName, + lastName: certificationAttestationData.lastName, + birthdate: certificationAttestationData.birthdate, + birthplace: certificationAttestationData.birthplace, + isPublished: certificationAttestationData.isPublished, + isCancelled: false, + createdAt: certificationAttestationData.date, + verificationCode: certificationAttestationData.verificationCode, + maxReachableLevelOnCertificationDate: certificationAttestationData.maxReachableLevelOnCertificationDate, + sessionId: certificationAttestationData.sessionId, + userId: certificationAttestationData.userId, + }); + databaseBuilder.factory.buildAssessment({ certificationCourseId: certificationAttestationData.id }); +} + function _buildRejected(certificationAttestationData) { databaseBuilder.factory.buildCertificationCourse({ id: certificationAttestationData.id, @@ -1309,24 +1329,6 @@ function _buildCertificationAttestationWithSeveralResults(certificationAttestati }); } -function _buildIncomplete(certificationAttestationData) { - databaseBuilder.factory.buildCertificationCourse({ - id: certificationAttestationData.id, - firstName: certificationAttestationData.firstName, - lastName: certificationAttestationData.lastName, - birthdate: certificationAttestationData.birthdate, - birthplace: certificationAttestationData.birthplace, - isPublished: certificationAttestationData.isPublished, - isCancelled: false, - createdAt: certificationAttestationData.date, - verificationCode: certificationAttestationData.verificationCode, - maxReachableLevelOnCertificationDate: certificationAttestationData.maxReachableLevelOnCertificationDate, - sessionId: certificationAttestationData.sessionId, - userId: certificationAttestationData.userId, - }); - databaseBuilder.factory.buildAssessment({ certificationCourseId: certificationAttestationData.id }); -} - function _linkCertificationAttestationToOrganization({ certificationAttestationData, organizationId, diff --git a/api/tests/certification/course/integration/infrastructure/utils/pdf/certification-attestation-pdf_test.js b/api/tests/certification/course/integration/infrastructure/utils/pdf/certification-attestation-pdf_test.js index a74c02e716f..0e6892e7839 100644 --- a/api/tests/certification/course/integration/infrastructure/utils/pdf/certification-attestation-pdf_test.js +++ b/api/tests/certification/course/integration/infrastructure/utils/pdf/certification-attestation-pdf_test.js @@ -3,9 +3,8 @@ import dayjs from 'dayjs'; import { isSameBinary } from '../../../../../../tooling/binary-comparator.js'; import { getCertificationAttestationsPdfBuffer } from '../../../../../../../src/certification/course/infrastructure/utils/pdf/certification-attestation-pdf.js'; import { CertificationAttestationGenerationError } from '../../../../../../../src/shared/domain/errors.js'; -import fs from 'fs'; import pdfLibUtils from 'pdf-lib/cjs/utils/index.js'; -import { writeFile } from 'fs/promises'; +import { readFile, writeFile } from 'node:fs/promises'; import * as url from 'url'; import { getI18n } from '../../../../../../tooling/i18n/i18n.js'; @@ -17,17 +16,13 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation nock('https://images.pix.fr') .get('/stickers/macaron_clea.pdf') - // eslint-disable-next-line no-sync - .reply(200, () => fs.readFileSync(`${__dirname}/stickers/macaron_clea.pdf`)) + .reply(200, async () => readFile(`${__dirname}/stickers/macaron_clea.pdf`)) .get('/stickers/macaron_droit_avance.pdf') - // eslint-disable-next-line no-sync - .reply(200, () => fs.readFileSync(`${__dirname}/stickers/macaron_droit_avance.pdf`)) + .reply(200, async () => readFile(`${__dirname}/stickers/macaron_droit_avance.pdf`)) .get('/stickers/macaron_edu_2nd_initie.pdf') - // eslint-disable-next-line no-sync - .reply(200, () => fs.readFileSync(`${__dirname}/stickers/macaron_edu_2nd_initie.pdf`)) + .reply(200, async () => readFile(`${__dirname}/stickers/macaron_edu_2nd_initie.pdf`)) .get('/stickers/macaron_droit_expert.pdf') - // eslint-disable-next-line no-sync - .reply(200, () => fs.readFileSync(`${__dirname}/stickers/macaron_droit_expert.pdf`)); + .reply(200, async () => readFile(`${__dirname}/stickers/macaron_droit_expert.pdf`)); }); it('should generate full attestation (non-regression test)', async function () { diff --git a/api/tests/integration/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js b/api/tests/integration/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js index 98f94f217c5..8c4b887b298 100644 --- a/api/tests/integration/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js +++ b/api/tests/integration/application/complementary-certification-course-results/complementary-certification-course-results-controller_test.js @@ -29,7 +29,7 @@ describe('Integration | Application | complementary-certification-course-results const payload = { data: { attributes: { - juryLevel: 'JURY_LEVEL', + juryLevel: 1, complementaryCertificationCourseId: 123456, }, }, @@ -56,7 +56,7 @@ describe('Integration | Application | complementary-certification-course-results const payload = { data: { attributes: { - juryLevel: 'PIX_EDU_FORMATION_INITIALE_2ND_DEGRE_INITIE', + juryLevel: 1, complementaryCertificationCourseId: 123456, }, }, diff --git a/api/tests/integration/domain/event/handle-complementary-certifications-scoring_test.js b/api/tests/integration/domain/event/handle-complementary-certifications-scoring_test.js index 37863581e02..391c922bc0b 100644 --- a/api/tests/integration/domain/event/handle-complementary-certifications-scoring_test.js +++ b/api/tests/integration/domain/event/handle-complementary-certifications-scoring_test.js @@ -87,10 +87,10 @@ describe('Integration | Event | Handle Complementary Certifications Scoring', fu .select() .first(); - expect(_.omit(complementaryCertificationCourseResults, ['id'])).to.deep.equal({ + expect(_.omit(complementaryCertificationCourseResults, ['id', 'partnerKey'])).to.deep.equal({ acquired: true, complementaryCertificationCourseId, - partnerKey: 'badge_key', + complementaryCertificationBadgeId: 501, source: 'PIX', }); }); diff --git a/api/tests/integration/infrastructure/repositories/certificate-repository_private_test.js b/api/tests/integration/infrastructure/repositories/certificate-repository_private_test.js index 56921226b72..1bd7c9e8563 100644 --- a/api/tests/integration/infrastructure/repositories/certificate-repository_private_test.js +++ b/api/tests/integration/infrastructure/repositories/certificate-repository_private_test.js @@ -1004,6 +1004,7 @@ async function _buildValidPrivateCertificateWithAcquiredAndNotAcquiredBadges({ }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId, + complementaryCertificationBadgeId: acquiredComplementaryBadgeId, partnerKey: key, acquired: true, }); diff --git a/api/tests/integration/infrastructure/repositories/certificate-repository_shareable_test.js b/api/tests/integration/infrastructure/repositories/certificate-repository_shareable_test.js index b6702abc606..c1135b3470f 100644 --- a/api/tests/integration/infrastructure/repositories/certificate-repository_shareable_test.js +++ b/api/tests/integration/infrastructure/repositories/certificate-repository_shareable_test.js @@ -659,6 +659,7 @@ async function _buildValidShareableCertificateWithAcquiredBadges({ shareableCert }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, partnerKey: key, acquired: true, }); diff --git a/api/tests/integration/infrastructure/repositories/certification-result-repository_test.js b/api/tests/integration/infrastructure/repositories/certification-result-repository_test.js index 5c96860580a..319db8fe576 100644 --- a/api/tests/integration/infrastructure/repositories/certification-result-repository_test.js +++ b/api/tests/integration/infrastructure/repositories/certification-result-repository_test.js @@ -186,6 +186,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun key: 'PARTNER_KEY', }).id; const oneComplementaryCertificationBadgeId = databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 100, badgeId: oneBadgeId, complementaryCertificationId: oneComplementaryCertificationId, label: 'PARTNER_LABEL', @@ -198,7 +199,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 998, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 100, acquired: true, source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -211,6 +212,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun const otherComplementaryCertificationId = databaseBuilder.factory.buildComplementaryCertification().id; databaseBuilder.factory.buildBadge({ id: 12345, key: 'OTHER_PARTNER_KEY' }); const otherComplementaryCertificationBadgeId = databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 101, badgeId: '12345', complementaryCertificationId: otherComplementaryCertificationId, label: 'OTHER_PARTNER_LABEL', @@ -223,7 +225,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 997, - partnerKey: 'OTHER_PARTNER_KEY', + complementaryCertificationBadgeId: 101, acquired: false, source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -262,7 +264,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 998, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 100, source: ComplementaryCertificationCourseResult.sources.PIX, label: 'PARTNER_LABEL', }), @@ -295,7 +297,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun domainBuilder.buildComplementaryCertificationCourseResult({ acquired: false, complementaryCertificationCourseId: 997, - partnerKey: 'OTHER_PARTNER_KEY', + complementaryCertificationBadgeId: 101, source: ComplementaryCertificationCourseResult.sources.PIX, label: 'OTHER_PARTNER_LABEL', }), @@ -320,28 +322,30 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun id: 997, certificationCourseId: oneCertificationCourseId, }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY_PIX', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.PIX, - }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY_EXTERNAL', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.EXTERNAL, - }); databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 100, badgeId: 12345, complementaryCertificationId: oneComplementaryCertificationId, label: 'PARTNER_LABEL_PIX', }); databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 101, badgeId: 12346, complementaryCertificationId: oneComplementaryCertificationId, label: 'PARTNER_LABEL_EXTERNAL', }); + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: 997, + complementaryCertificationBadgeId: 100, + acquired: true, + source: ComplementaryCertificationCourseResult.sources.PIX, + }); + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: 997, + complementaryCertificationBadgeId: 101, + acquired: true, + source: ComplementaryCertificationCourseResult.sources.EXTERNAL, + }); await databaseBuilder.commit(); @@ -377,7 +381,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY_PIX', + complementaryCertificationBadgeId: 100, source: ComplementaryCertificationCourseResult.sources.PIX, label: 'PARTNER_LABEL_PIX', }), @@ -387,136 +391,88 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun expect(certificationResults).to.deepEqualArray(expectedResult); }); - it(`should return complementary certification results ordered by complementaryCertificationId and level`, async function () { + it(`should return complementary certification results`, async function () { // given const sessionId = databaseBuilder.factory.buildSession().id; - const { certificationCourseId } = await _buildCertificationResultInSession(sessionId); - databaseBuilder.factory.buildBadge({ key: 'First badge expert', id: 123 }); - databaseBuilder.factory.buildBadge({ key: 'First badge maître', id: 456 }); - databaseBuilder.factory.buildBadge({ key: 'Second badge expert', id: 789 }); - databaseBuilder.factory.buildBadge({ key: 'Second badge maître', id: 101112 }); + const { certificationCourseId: certificationCourseId1 } = await _buildCertificationResultInSession(sessionId); + const { certificationCourseId: certificationCourseId2 } = await _buildCertificationResultInSession(sessionId); databaseBuilder.factory.buildComplementaryCertification({ id: 123, }); - databaseBuilder.factory.buildComplementaryCertification({ - id: 456, - }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - id: 101, - badgeId: 789, - complementaryCertificationId: 456, - level: 1, - label: 'Second badge expert', - }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - id: 102, - badgeId: 456, - complementaryCertificationId: 123, - level: 2, - label: 'First badge maître', - }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - id: 103, - badgeId: 101112, - complementaryCertificationId: 456, - level: 2, - label: 'Second badge maître', - }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - id: 104, - badgeId: 123, - complementaryCertificationId: 123, - level: 1, - label: 'First badge expert', - }); - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 996, - certificationCourseId, - complementaryCertificationId: 123, - complementaryCertificationBadgeId: 104, - }); - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 997, - certificationCourseId, - complementaryCertificationId: 456, - complementaryCertificationBadgeId: 103, - }); - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 998, + const buildComplementaryResult = ({ certificationCourseId, + complementaryCertificationId, + complementaryCertificationBadgeId, + complementaryCertificationCourseId, + acquired = true, + label, + level, + }) => { + const { id: badgeId } = databaseBuilder.factory.buildBadge(); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: complementaryCertificationBadgeId, + badgeId, + complementaryCertificationId, + level, + label, + }); + databaseBuilder.factory.buildComplementaryCertificationCourse({ + id: complementaryCertificationCourseId, + certificationCourseId, + complementaryCertificationId, + complementaryCertificationBadgeId, + }); + databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId, + complementaryCertificationBadgeId, + acquired, + source: ComplementaryCertificationCourseResult.sources.PIX, + }); + }; + buildComplementaryResult({ + certificationCourseId: certificationCourseId1, complementaryCertificationId: 123, - complementaryCertificationBadgeId: 102, - }); - databaseBuilder.factory.buildComplementaryCertificationCourse({ - id: 999, - certificationCourseId, - complementaryCertificationId: 456, complementaryCertificationBadgeId: 101, - }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 998, - partnerKey: 'First badge expert', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.PIX, - }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 996, - partnerKey: 'First badge maître', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.PIX, + label: 'First badge expert', }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + + buildComplementaryResult({ + certificationCourseId: certificationCourseId2, + complementaryCertificationId: 123, + complementaryCertificationBadgeId: 102, complementaryCertificationCourseId: 999, - partnerKey: 'Second badge expert', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.PIX, - }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 997, - partnerKey: 'Second badge maître', - acquired: true, - source: ComplementaryCertificationCourseResult.sources.PIX, + label: 'First badge avance', + acquired: false, }); await databaseBuilder.commit(); // when - const [result] = await certificationResultRepository.findBySessionId({ + const [results1, results2] = await certificationResultRepository.findBySessionId({ sessionId, }); // then - const expectedResult = [ + + expect(results1.complementaryCertificationCourseResults[0]).to.deepEqualInstance( domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 998, - partnerKey: 'First badge expert', - source: ComplementaryCertificationCourseResult.sources.PIX, + complementaryCertificationBadgeId: 101, label: 'First badge expert', - }), - domainBuilder.buildComplementaryCertificationCourseResult({ - acquired: true, - complementaryCertificationCourseId: 996, - partnerKey: 'First badge maître', source: ComplementaryCertificationCourseResult.sources.PIX, - label: 'First badge maître', }), + ); + expect(results2.complementaryCertificationCourseResults[0]).to.deepEqualInstance( domainBuilder.buildComplementaryCertificationCourseResult({ - acquired: true, + acquired: false, complementaryCertificationCourseId: 999, - partnerKey: 'Second badge expert', - source: ComplementaryCertificationCourseResult.sources.PIX, - label: 'Second badge expert', - }), - domainBuilder.buildComplementaryCertificationCourseResult({ - acquired: true, - complementaryCertificationCourseId: 997, - partnerKey: 'Second badge maître', + complementaryCertificationBadgeId: 102, + label: 'First badge avance', source: ComplementaryCertificationCourseResult.sources.PIX, - label: 'Second badge maître', }), - ]; - expect(result.complementaryCertificationCourseResults).to.deepEqualArray(expectedResult); + ); }); }); @@ -727,36 +683,10 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun it(`should return only complementary certifications of Pix source`, async function () { // given - const sessionId = databaseBuilder.factory.buildSession().id; const userId = databaseBuilder.factory.buildUser().id; - const certificationCourseId = databaseBuilder.factory.buildCertificationCourse({ - firstName: 'Buffy', - lastName: 'Summers', - birthdate: '1981-01-19', - birthplace: 'Torreilles', - isPublished: true, - isCancelled: false, - externalId: 'VAMPIRES_SUCK', - createdAt: new Date('2020-01-01'), - sessionId, - userId, - }).id; - const assessmentResultId = databaseBuilder.factory.buildAssessmentResult.last({ - certificationCourseId, - pixScore: 123, - status: CertificationResult.status.VALIDATED, - commentForOrganization: 'Un commentaire orga 1', - }).id; + const sessionId = databaseBuilder.factory.buildSession().id; + const { certificationCourseId } = await _buildCertificationResultInSession(sessionId, userId); - databaseBuilder.factory.buildCompetenceMark({ - id: 123, - score: 10, - level: 4, - competence_code: '2.3', - area_code: '2', - competenceId: 'recComp23', - assessmentResultId, - }); const oneComplementaryCertificationId = databaseBuilder.factory.buildComplementaryCertification({ label: 'PARTNER_LABEL', }).id; @@ -765,68 +695,43 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun id: 997, certificationCourseId, }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 789, + badgeId: 12345, + complementaryCertificationId: oneComplementaryCertificationId, + label: 'PARTNER_LABEL', + }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 789, acquired: true, source: ComplementaryCertificationCourseResult.sources.PIX, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 789, acquired: true, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - badgeId: 12345, - complementaryCertificationId: oneComplementaryCertificationId, - label: 'PARTNER_LABEL', - }); const certificationCandidateId = databaseBuilder.factory.buildCertificationCandidate({ userId, sessionId }).id; await databaseBuilder.commit(); // when - const certificationResults = await certificationResultRepository.findByCertificationCandidateIds({ + const [certificationResults] = await certificationResultRepository.findByCertificationCandidateIds({ certificationCandidateIds: [certificationCandidateId], }); // then const expectedResult = [ - domainBuilder.buildCertificationResult({ - id: certificationCourseId, - firstName: 'Buffy', - lastName: 'Summers', - externalId: 'VAMPIRES_SUCK', - pixScore: 123, - sessionId, - status: 'validated', - birthdate: '1981-01-19', - birthplace: 'Torreilles', - createdAt: new Date('2020-01-01T00:00:00Z'), - commentForOrganization: 'Un commentaire orga 1', - competencesWithMark: [ - domainBuilder.buildCompetenceMark({ - id: 123, - score: 10, - level: 4, - competence_code: '2.3', - area_code: '2', - competenceId: 'recComp23', - assessmentResultId, - }), - ], - complementaryCertificationCourseResults: [ - domainBuilder.buildComplementaryCertificationCourseResult({ - acquired: true, - complementaryCertificationCourseId: 997, - partnerKey: 'PARTNER_KEY', - source: ComplementaryCertificationCourseResult.sources.PIX, - label: 'PARTNER_LABEL', - }), - ], + domainBuilder.buildComplementaryCertificationCourseResult({ + acquired: true, + complementaryCertificationCourseId: 997, + complementaryCertificationBadgeId: 789, + source: ComplementaryCertificationCourseResult.sources.PIX, + label: 'PARTNER_LABEL', }), ]; - expect(certificationResults).to.deepEqualArray(expectedResult); + expect(certificationResults.complementaryCertificationCourseResults).to.deepEqualArray(expectedResult); }); it(`should return complementary certification linked to the candidates`, async function () { @@ -854,7 +759,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 998, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 100, acquired: true, source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -895,7 +800,7 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 998, - partnerKey: 'PARTNER_KEY', + complementaryCertificationBadgeId: 100, source: ComplementaryCertificationCourseResult.sources.PIX, label: 'PARTNER_LABEL', }), @@ -907,9 +812,10 @@ describe('Integration | Infrastructure | Repository | Certification Result', fun }); }); -async function _buildCertificationResultInSession(sessionId) { +async function _buildCertificationResultInSession(sessionId, userId) { const certificationCourseId = databaseBuilder.factory.buildCertificationCourse({ sessionId, + userId, isPublished: true, }).id; const assessmentResultId = databaseBuilder.factory.buildAssessmentResult.last({ diff --git a/api/tests/integration/infrastructure/repositories/complementary-certification-course-result-repository_test.js b/api/tests/integration/infrastructure/repositories/complementary-certification-course-result-repository_test.js index 020ba6606ce..552a5f83cfc 100644 --- a/api/tests/integration/infrastructure/repositories/complementary-certification-course-result-repository_test.js +++ b/api/tests/integration/infrastructure/repositories/complementary-certification-course-result-repository_test.js @@ -21,10 +21,15 @@ describe('Integration | Repository | complementary-certification-courses-result- certificationCourseId: 99, complementaryCertificationId: 1, }); - databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_1' }); + databaseBuilder.factory.buildBadge({ id: 51, key: 'PIX_TEST_1' }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 42, + badgeId: 51, + complementaryCertificationId: 1, + }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 42, source: ComplementaryCertificationCourseResult.sources.PIX, acquired: true, }); @@ -43,7 +48,7 @@ describe('Integration | Repository | complementary-certification-courses-result- domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 42, source: ComplementaryCertificationCourseResult.sources.PIX, }), ); @@ -69,7 +74,6 @@ describe('Integration | Repository | complementary-certification-courses-result- databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_1' }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', source: ComplementaryCertificationCourseResult.sources.EXTERNAL, acquired: true, }); @@ -89,29 +93,93 @@ describe('Integration | Repository | complementary-certification-courses-result- ); }); - describe('#getAllowedJuryLevelByBadgeKey', function () { - it('should return the allowed jury level for a partner key', async function () { - // given - databaseBuilder.factory.buildTargetProfile({ id: 123 }); - databaseBuilder.factory.buildBadge({ id: 1212, key: 'KEY_1', targetProfileId: 123 }); + describe('#getAllowedJuryLevelIdsByComplementaryCertificationBadgeId', function () { + context('when there is one target profile for a complementary certification', function () { + it('should return the allowed jury level for that complementary certification', async function () { + // given + databaseBuilder.factory.buildTargetProfile({ id: 123 }); + databaseBuilder.factory.buildComplementaryCertification({ id: 1 }); + databaseBuilder.factory.buildBadge({ + id: 1212, + targetProfileId: 123, + }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 97, + badgeId: 1212, + complementaryCertificationId: 1, + }); - databaseBuilder.factory.buildTargetProfile({ id: 456 }); - databaseBuilder.factory.buildBadge({ id: 1213, key: 'KEY_2', targetProfileId: 456 }); - databaseBuilder.factory.buildBadge({ id: 1214, key: 'KEY_3', targetProfileId: 456 }); + databaseBuilder.factory.buildTargetProfile({ id: 456 }); + databaseBuilder.factory.buildComplementaryCertification({ id: 2 }); + databaseBuilder.factory.buildBadge({ id: 1213, targetProfileId: 456 }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 98, + badgeId: 1213, + complementaryCertificationId: 2, + }); - await databaseBuilder.commit(); + await databaseBuilder.commit(); - // when - const allowedBadgeKeys = await complementaryCertificationCourseResultRepository.getAllowedJuryLevelByBadgeKey({ - key: 'KEY_2', + // when + const allowedBadgeKeys = + await complementaryCertificationCourseResultRepository.getAllowedJuryLevelIdsByComplementaryCertificationBadgeId( + 97, + ); + + // then + expect(allowedBadgeKeys).to.deep.equal([97]); }); + }); - // then - expect(allowedBadgeKeys).to.deep.equal(['KEY_2', 'KEY_3']); + context('when there are two target profiles for a complementary certification', function () { + it('should return the allowed jury level for that target profile', async function () { + // given + databaseBuilder.factory.buildTargetProfile({ id: 123 }); + databaseBuilder.factory.buildComplementaryCertification({ id: 1 }); + databaseBuilder.factory.buildBadge({ + id: 1212, + key: 'KEY_1', + targetProfileId: 123, + }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 97, + badgeId: 1212, + complementaryCertificationId: 1, + }); + + databaseBuilder.factory.buildTargetProfile({ id: 456 }); + databaseBuilder.factory.buildBadge({ id: 1213, key: 'KEY_2', targetProfileId: 456 }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 98, + badgeId: 1213, + complementaryCertificationId: 1, + }); + databaseBuilder.factory.buildBadge({ id: 1214, key: 'KEY_3', targetProfileId: 456 }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 99, + badgeId: 1214, + complementaryCertificationId: 1, + }); + + await databaseBuilder.commit(); + + // when + const allowedBadgeKeys = + await complementaryCertificationCourseResultRepository.getAllowedJuryLevelIdsByComplementaryCertificationBadgeId( + 98, + ); + + // then + expect(allowedBadgeKeys).to.deep.equal([98, 99]); + }); }); }); describe('#save', function () { + afterEach(function () { + return knex('complementary-certification-course-results').delete(); + }); + describe('when the ComplementaryCertificationCourseResult does not exist', function () { it('saves the ComplementaryCertificationCourseResult', async function () { // given @@ -127,15 +195,21 @@ describe('Integration | Repository | complementary-certification-courses-result- }); databaseBuilder.factory.buildBadge({ + id: 10, key: 'PIX_TEST_1', }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 60, + badgeId: 10, + complementaryCertificationId: 1, + }); await databaseBuilder.commit(); const complementaryCertificationCourseResult = domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 60, source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -144,18 +218,13 @@ describe('Integration | Repository | complementary-certification-courses-result- // then const savedComplementaryCertificationCourseResult = await knex('complementary-certification-course-results') - .where({ - acquired: true, - complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', - source: ComplementaryCertificationCourseResult.sources.PIX, - }) + .select('id', 'acquired', 'complementaryCertificationBadgeId', 'complementaryCertificationCourseId', 'source') .first(); expect(_.omit(savedComplementaryCertificationCourseResult, 'id')).to.deep.equal({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 60, source: ComplementaryCertificationCourseResult.sources.PIX, }); }); @@ -175,13 +244,23 @@ describe('Integration | Repository | complementary-certification-courses-result- complementaryCertificationId: 1, }); - databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_1' }); - databaseBuilder.factory.buildBadge({ key: 'PIX_TEST_2' }); + databaseBuilder.factory.buildBadge({ id: 10, key: 'PIX_TEST_1' }); + databaseBuilder.factory.buildBadge({ id: 11, key: 'PIX_TEST_2' }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 60, + badgeId: 10, + complementaryCertificationId: 1, + }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 61, + badgeId: 11, + complementaryCertificationId: 1, + }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', + complementaryCertificationBadgeId: 61, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); @@ -190,7 +269,7 @@ describe('Integration | Repository | complementary-certification-courses-result- const complementaryCertificationCourseResult = domainBuilder.buildComplementaryCertificationCourseResult({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 61, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); @@ -198,17 +277,19 @@ describe('Integration | Repository | complementary-certification-courses-result- await complementaryCertificationCourseResultRepository.save(complementaryCertificationCourseResult); // then - const results = await knex('complementary-certification-course-results').where({ - acquired: true, - complementaryCertificationCourseId: 999, - source: ComplementaryCertificationCourseResult.sources.EXTERNAL, - }); + const results = await knex('complementary-certification-course-results') + .select('id', 'acquired', 'complementaryCertificationBadgeId', 'complementaryCertificationCourseId', 'source') + .where({ + acquired: true, + complementaryCertificationCourseId: 999, + source: ComplementaryCertificationCourseResult.sources.EXTERNAL, + }); expect(results).to.have.lengthOf(1); expect(_.omit(results[0], 'id')).to.deep.equal({ acquired: true, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_2', + complementaryCertificationBadgeId: 61, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); }); @@ -231,17 +312,21 @@ describe('Integration | Repository | complementary-certification-courses-result- }); databaseBuilder.factory.buildBadge({ + id: 11, key: 'PIX_TEST_1', }); - databaseBuilder.factory.buildBadge({ - key: 'PIX_EDU_1', + + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 301, + complementaryCertificationId: 1, + badgeId: 11, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ id: 10, acquired: true, + complementaryCertificationBadgeId: 301, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', source: ComplementaryCertificationCourseResult.sources.PIX, }); @@ -253,14 +338,20 @@ describe('Integration | Repository | complementary-certification-courses-result- }); // then - const courseResults = await knex('complementary-certification-course-results'); + const courseResults = await knex('complementary-certification-course-results').select( + 'id', + 'acquired', + 'complementaryCertificationBadgeId', + 'complementaryCertificationCourseId', + 'source', + ); expect(courseResults).to.deep.equal([ { id: 10, acquired: true, + complementaryCertificationBadgeId: 301, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', source: ComplementaryCertificationCourseResult.sources.PIX, }, ]); @@ -282,24 +373,36 @@ describe('Integration | Repository | complementary-certification-courses-result- }); databaseBuilder.factory.buildBadge({ + id: 11, key: 'PIX_TEST_1', }); databaseBuilder.factory.buildBadge({ + id: 12, key: 'PIX_EDU_1', }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 301, + complementaryCertificationId: 1, + badgeId: 12, + }); + databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 302, + complementaryCertificationId: 1, + badgeId: 12, + }); - databaseBuilder.factory.buildComplementaryCertificationCourseResult({ + const pixResult = databaseBuilder.factory.buildComplementaryCertificationCourseResult({ id: 10, acquired: true, + complementaryCertificationBadgeId: 301, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', source: ComplementaryCertificationCourseResult.sources.PIX, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ acquired: true, + complementaryCertificationBadgeId: 302, complementaryCertificationCourseId: 999, - partnerKey: 'PIX_EDU_1', source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); @@ -311,18 +414,14 @@ describe('Integration | Repository | complementary-certification-courses-result- }); // then - const courseResult = await knex('complementary-certification-course-results').where({ - complementaryCertificationCourseId: 999, - }); + const courseResult = await knex('complementary-certification-course-results') + .select('id', 'acquired', 'complementaryCertificationBadgeId', 'complementaryCertificationCourseId', 'source') + .where({ + complementaryCertificationCourseId: 999, + }); expect(courseResult).to.have.lengthOf(1); - expect(courseResult[0]).to.deep.equal({ - id: 10, - acquired: true, - complementaryCertificationCourseId: 999, - partnerKey: 'PIX_TEST_1', - source: ComplementaryCertificationCourseResult.sources.PIX, - }); + expect(courseResult[0]).to.deep.equal(pixResult); }); }); }); diff --git a/api/tests/integration/infrastructure/repositories/complementary-certification-scoring-criteria-repository_test.js b/api/tests/integration/infrastructure/repositories/complementary-certification-scoring-criteria-repository_test.js index 1ec0a949320..fde7effb1ea 100644 --- a/api/tests/integration/infrastructure/repositories/complementary-certification-scoring-criteria-repository_test.js +++ b/api/tests/integration/infrastructure/repositories/complementary-certification-scoring-criteria-repository_test.js @@ -57,12 +57,14 @@ describe('Integration | Repository | complementary certification scoring criteri expect(results).to.deep.equal([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: complementaryCertificationCourse1.id, + complementaryCertificationBadgeId: complementaryCertificationCourse1.complementaryCertificationBadgeId, minimumReproducibilityRate: complementaryCertification1.minimumReproducibilityRate, complementaryCertificationBadgeKey: badge1.key, hasComplementaryReferential: complementaryCertification1.hasComplementaryReferential, }), domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: complementaryCertificationCourse2.id, + complementaryCertificationBadgeId: complementaryCertificationCourse2.complementaryCertificationBadgeId, minimumReproducibilityRate: complementaryCertification2.minimumReproducibilityRate, complementaryCertificationBadgeKey: badge2.key, hasComplementaryReferential: complementaryCertification2.hasComplementaryReferential, diff --git a/api/tests/integration/infrastructure/repositories/jury-certification-repository_test.js b/api/tests/integration/infrastructure/repositories/jury-certification-repository_test.js index dd237d37cfc..ea2e0e0b9b4 100644 --- a/api/tests/integration/infrastructure/repositories/jury-certification-repository_test.js +++ b/api/tests/integration/infrastructure/repositories/jury-certification-repository_test.js @@ -37,6 +37,7 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct complementaryCertificationBadgeId: 3453, level: 1, label: 'Badge for complementary certification without external jury', + complementaryCertificationCourse: null, }); databaseBuilder.factory.buildUser({ id: 789 }); @@ -71,7 +72,6 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct complementaryCertificationId: 23, certificationCourseId: 1, complementaryCertificationBadgeId: 3453, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_WITHOUT_EXTERNAL_JURY', }); databaseBuilder.factory.buildUser({ id: 22, firstName: 'Jury' }); @@ -137,8 +137,8 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct version: 2, commonComplementaryCertificationCourseResult: { acquired: true, + complementaryCertificationBadgeId: 3453, id: 456, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_WITHOUT_EXTERNAL_JURY', label: 'Badge for complementary certification without external jury', }, complementaryCertificationCourseResultWithExternal: undefined, @@ -205,15 +205,13 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct complementaryCertificationCourseId: 456, complementaryCertificationId: 24, certificationCourseId: 1, - complementaryCertificationBadgeId: 3454, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_1', + complementaryCertificationBadgeId: 3453, }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 456, complementaryCertificationId: 24, certificationCourseId: 1, - complementaryCertificationBadgeId: 3455, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_2', + complementaryCertificationBadgeId: 3454, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); @@ -231,28 +229,28 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct const expectedJuryCertification = { complementaryCertificationCourseId: 456, externalSection: { + complementaryCertificationBadgeId: 3454, acquired: true, label: 'Badge for complementary certification with external jury level 2', level: 2, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_2', }, pixSection: { + complementaryCertificationBadgeId: 3453, acquired: true, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_1', label: 'Badge for complementary certification with external jury level 1', level: 1, }, allowedExternalLevels: [ { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_1', + value: 3453, label: 'Badge for complementary certification with external jury level 1', }, { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_2', + value: 3454, label: 'Badge for complementary certification with external jury level 2', }, { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_3', + value: 3455, label: 'Badge for complementary certification with external jury level 3', }, ], @@ -335,14 +333,12 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct complementaryCertificationId: 24, certificationCourseId: 1, complementaryCertificationBadgeId: 3454, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_1', }); databaseBuilder.factory.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 456, complementaryCertificationId: 24, certificationCourseId: 1, complementaryCertificationBadgeId: 3455, - partnerKey: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_2', source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }); @@ -362,15 +358,15 @@ describe('Integration | Infrastructure | Repository | Jury Certification', funct // then expect(complementaryCertificationCourseResultWithExternal.allowedExternalLevels).to.deep.equals([ { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_1', + value: 3453, label: 'Badge for complementary certification with external jury level 1', }, { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_2', + value: 3454, label: 'Badge for complementary certification with external jury level 2', }, { - value: 'BADGE_FOR_COMPLEMENTARY_CERTIFICATION_1_WITH_EXTERNAL_JURY_LEVEL_3', + value: 3455, label: 'Badge for complementary certification with external jury level 3', }, ]); diff --git a/api/tests/integration/infrastructure/repositories/jury-certification-summary-repository_test.js b/api/tests/integration/infrastructure/repositories/jury-certification-summary-repository_test.js index 44fcdc9c770..2616cfd344f 100644 --- a/api/tests/integration/infrastructure/repositories/jury-certification-summary-repository_test.js +++ b/api/tests/integration/infrastructure/repositories/jury-certification-summary-repository_test.js @@ -254,16 +254,23 @@ describe('Integration | Repository | JuryCertificationSummary', function () { const sessionId = dbf.buildSession().id; const certificationCourseId = dbf.buildCertificationCourse({ sessionId }).id; const badgeId = dbf.buildBadge({ key: 'PARTNER_KEY' }).id; - dbf.buildComplementaryCertificationCourse({ id: 998, certificationCourseId }); - dbf.buildComplementaryCertificationCourseResult({ - complementaryCertificationCourseId: 998, - partnerKey: 'PARTNER_KEY', - acquired: true, - }); + databaseBuilder.factory.buildComplementaryCertification({ id: 101 }); databaseBuilder.factory.buildComplementaryCertificationBadge({ + id: 11, label: 'PARTNER_LABEL', badgeId, - complementaryCertificationId: databaseBuilder.factory.buildComplementaryCertification().id, + complementaryCertificationId: 101, + }); + dbf.buildComplementaryCertificationCourse({ + id: 998, + complementaryCertificationId: 101, + certificationCourseId, + complementaryCertificationBadgeId: 11, + }); + dbf.buildComplementaryCertificationCourseResult({ + complementaryCertificationCourseId: 998, + complementaryCertificationBadgeId: 11, + acquired: true, }); await databaseBuilder.commit(); @@ -298,7 +305,6 @@ describe('Integration | Repository | JuryCertificationSummary', function () { it('should return JuryCertificationSummary based on their latest assessment result', async function () { // given const page = { size: 2, number: 1 }; - const partnerKey = 'partnerKey'; const label = 'label'; const dbf = databaseBuilder.factory; const sessionId = dbf.buildSession().id; @@ -341,18 +347,15 @@ describe('Integration | Repository | JuryCertificationSummary', function () { description: 'second certification issue report', hasBeenAutomaticallyResolved: false, }); - const badgeId = dbf.buildBadge({ key: partnerKey }).id; + const badgeId = dbf.buildBadge({ key: 'PARTNER_KEY' }).id; + dbf.buildComplementaryCertification({ id: 1 }); + dbf.buildComplementaryCertificationBadge({ id: 11, label, badgeId, complementaryCertificationId: 1 }); dbf.buildComplementaryCertificationCourse({ id: 998, certificationCourseId: manyAsrCertification.id }); dbf.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 998, - partnerKey, + complementaryCertificationBadgeId: 11, acquired: true, }); - databaseBuilder.factory.buildComplementaryCertificationBadge({ - label, - badgeId, - complementaryCertificationId: databaseBuilder.factory.buildComplementaryCertification().id, - }); await databaseBuilder.commit(); diff --git a/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result-for-certification-with-external.js b/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result-for-certification-with-external.js index ee0d147cf85..2fe6f18de22 100644 --- a/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result-for-certification-with-external.js +++ b/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result-for-certification-with-external.js @@ -2,11 +2,11 @@ import { ComplementaryCertificationCourseResultForJuryCertificationWithExternal const buildComplementaryCertificationCourseResultForJuryCertificationWithExternal = function ({ complementaryCertificationCourseId = 456, - pixPartnerKey = 'PIX_PARTNER_KEY', + pixComplementaryCertificationBadgeId = 12, pixLabel = 'Pix+ Édu 1er degré Avancé', pixAcquired = true, pixLevel = 2, - externalPartnerKey = 'PIX_EXTERNAL_PARTNER_KEY', + externalComplementaryCertificationBadgeId = 13, externalLabel = 'Pix+ Édu 1er degré Expert', externalAcquired = true, externalLevel = 1, @@ -14,11 +14,11 @@ const buildComplementaryCertificationCourseResultForJuryCertificationWithExterna } = {}) { return new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ complementaryCertificationCourseId, - pixPartnerKey, + pixComplementaryCertificationBadgeId, pixLabel, pixAcquired, pixLevel, - externalPartnerKey, + externalComplementaryCertificationBadgeId, externalLabel, externalAcquired, externalLevel, diff --git a/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result.js b/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result.js index 2ba9ff52f3f..1553d5dd8d8 100644 --- a/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result.js +++ b/api/tests/tooling/domain-builder/factory/build-complementary-certification-course-result.js @@ -2,6 +2,7 @@ import { ComplementaryCertificationCourseResult } from './../../../../lib/domain const buildComplementaryCertificationCourseResult = function ({ complementaryCertificationCourseId = 2, + complementaryCertificationBadgeId = 2, partnerKey = 'PARTNER_KEY', acquired = false, source = ComplementaryCertificationCourseResult.sources.PIX, @@ -9,6 +10,7 @@ const buildComplementaryCertificationCourseResult = function ({ } = {}) { return new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, partnerKey, acquired, source, diff --git a/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-criteria.js b/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-criteria.js index 6f31856f0fd..a6216b97c2e 100644 --- a/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-criteria.js +++ b/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-criteria.js @@ -3,12 +3,14 @@ import { ComplementaryCertificationScoringCriteria } from '../../../../lib/domai function buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId = 123, minimumReproducibilityRate = 70, + complementaryCertificationBadgeId = 89, complementaryCertificationBadgeKey = 'badge_key', hasComplementaryReferential = false, minimumEarnedPix = 0, } = {}) { return new ComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, minimumReproducibilityRate, complementaryCertificationBadgeKey, hasComplementaryReferential, diff --git a/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-without-complementary-referential.js b/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-without-complementary-referential.js index 6306747b5a1..e5c20f4dd03 100644 --- a/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-without-complementary-referential.js +++ b/api/tests/tooling/domain-builder/factory/build-complementary-certification-scoring-without-complementary-referential.js @@ -2,6 +2,7 @@ import { ComplementaryCertificationScoringWithoutComplementaryReferential } from const buildComplementaryCertificationScoringWithoutComplementaryReferential = function ({ complementaryCertificationCourseId = 99, + complementaryCertificationBadgeId = 60, certificationCourseId = 42, reproducibilityRate = 50, complementaryCertificationBadgeKey = 'badge_key', @@ -11,6 +12,7 @@ const buildComplementaryCertificationScoringWithoutComplementaryReferential = fu } = {}) { return new ComplementaryCertificationScoringWithoutComplementaryReferential({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, certificationCourseId, reproducibilityRate, complementaryCertificationBadgeKey, diff --git a/api/tests/tooling/domain-builder/factory/build-pix-plus-certification-scoring.js b/api/tests/tooling/domain-builder/factory/build-pix-plus-certification-scoring.js index 60f5612afa7..c91943ca023 100644 --- a/api/tests/tooling/domain-builder/factory/build-pix-plus-certification-scoring.js +++ b/api/tests/tooling/domain-builder/factory/build-pix-plus-certification-scoring.js @@ -3,6 +3,7 @@ import { buildReproducibilityRate } from './build-reproducibility-rate.js'; const buildComplementaryCertificationScoringWithComplementaryReferential = function ({ complementaryCertificationCourseId = 999, + complementaryCertificationBadgeId = 100, complementaryCertificationBadgeKey = 'PIX_PLUS_TEST', reproducibilityRate = buildReproducibilityRate({ value: 100 }), hasAcquiredPixCertification = true, @@ -10,6 +11,7 @@ const buildComplementaryCertificationScoringWithComplementaryReferential = funct } = {}) { return new ComplementaryCertificationScoringWithComplementaryReferential({ complementaryCertificationCourseId, + complementaryCertificationBadgeId, complementaryCertificationBadgeKey, reproducibilityRate, hasAcquiredPixCertification, diff --git a/api/tests/unit/application/complementary-certification-course-results/index_test.js b/api/tests/unit/application/complementary-certification-course-results/index_test.js index b27b0add460..e94dd2291ac 100644 --- a/api/tests/unit/application/complementary-certification-course-results/index_test.js +++ b/api/tests/unit/application/complementary-certification-course-results/index_test.js @@ -1,13 +1,15 @@ import { expect, HttpTestServer, sinon } from '../../../test-helper.js'; import { securityPreHandlers } from '../../../../lib/application/security-pre-handlers.js'; import * as moduleUnderTest from '../../../../lib/application/complementary-certification-course-results/index.js'; +import { juryOptions } from '../../../../lib/domain/models/ComplementaryCertificationCourseResult.js'; +import { complementaryCertificationCourseResultsController } from '../../../../lib/application/complementary-certification-course-results/complementary-certification-course-results-controller.js'; describe('Unit | Application | Complementary Certification Course Results | Route', function () { describe('POST /api/admin/complementary-certification-course-results', function () { it('return forbidden access if user has METIER role', async function () { // given - sinon - .stub(securityPreHandlers, 'adminMemberHasAtLeastOneAccessOf') + sinon.stub(securityPreHandlers, 'adminMemberHasAtLeastOneAccessOf'); + securityPreHandlers.adminMemberHasAtLeastOneAccessOf .withArgs([ securityPreHandlers.checkAdminMemberHasRoleSuperAdmin, securityPreHandlers.checkAdminMemberHasRoleCertif, @@ -27,7 +29,7 @@ describe('Unit | Application | Complementary Certification Course Results | Rout const response = await httpTestServer.request('POST', '/api/admin/complementary-certification-course-results', { data: { attributes: { - juryLevel: 'JURY_LEVEL_KEY', + juryLevel: 52, complementaryCertificationCourseId: 1234, }, }, @@ -36,5 +38,78 @@ describe('Unit | Application | Complementary Certification Course Results | Rout // then expect(response.statusCode).to.equal(403); }); + + // Rule disabled to allow dynamic generated tests. See https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-setup-in-describe.md#disallow-setup-in-describe-blocks-mochano-setup-in-describe + // eslint-disable-next-line mocha/no-setup-in-describe + [juryOptions.REJECTED, juryOptions.UNSET, 1].forEach((juryOption) => + it(`should accept juryLevel with value: ${juryOption}`, async function () { + // given + sinon.stub(complementaryCertificationCourseResultsController, 'saveJuryComplementaryCertificationCourseResult'); + complementaryCertificationCourseResultsController.saveJuryComplementaryCertificationCourseResult.resolves(); + sinon.stub(securityPreHandlers, 'adminMemberHasAtLeastOneAccessOf'); + securityPreHandlers.adminMemberHasAtLeastOneAccessOf + .withArgs([ + securityPreHandlers.checkAdminMemberHasRoleSuperAdmin, + securityPreHandlers.checkAdminMemberHasRoleCertif, + securityPreHandlers.checkAdminMemberHasRoleSupport, + ]) + .callsFake(() => (request, h) => h.response('ok').code(200).takeover()); + + const httpTestServer = new HttpTestServer(); + await httpTestServer.register(moduleUnderTest); + + // when + const response = await httpTestServer.request('POST', '/api/admin/complementary-certification-course-results', { + data: { + attributes: { + juryLevel: juryOption, + complementaryCertificationCourseId: 1234, + }, + }, + }); + + // then + expect(response.statusCode).to.equal(200); + }), + ); + + // Rule disabled to allow dynamic generated tests. See https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-setup-in-describe.md#disallow-setup-in-describe-blocks-mochano-setup-in-describe + // eslint-disable-next-line mocha/no-setup-in-describe + [ + { value: 'CACA_VALUE' }, + { value: [], label: '[]' }, + { value: undefined, label: 'undefined' }, + { value: -1 }, + ].forEach(({ value: juryOption, label }) => + it(`should not accept juryLevel with value: ${label ?? juryOption}"`, async function () { + // given + sinon.stub(complementaryCertificationCourseResultsController, 'saveJuryComplementaryCertificationCourseResult'); + complementaryCertificationCourseResultsController.saveJuryComplementaryCertificationCourseResult.resolves(); + sinon.stub(securityPreHandlers, 'adminMemberHasAtLeastOneAccessOf'); + securityPreHandlers.adminMemberHasAtLeastOneAccessOf + .withArgs([ + securityPreHandlers.checkAdminMemberHasRoleSuperAdmin, + securityPreHandlers.checkAdminMemberHasRoleCertif, + securityPreHandlers.checkAdminMemberHasRoleSupport, + ]) + .callsFake(() => (_, h) => h.response('ok').code(200).takeover()); + + const httpTestServer = new HttpTestServer(); + await httpTestServer.register(moduleUnderTest); + + // when + const response = await httpTestServer.request('POST', '/api/admin/complementary-certification-course-results', { + data: { + attributes: { + juryLevel: juryOption, + complementaryCertificationCourseId: 1234, + }, + }, + }); + + // then + expect(response.statusCode).to.equal(400); + }), + ); }); }); diff --git a/api/tests/unit/domain/events/handle-complementary-certifications-scoring_test.js b/api/tests/unit/domain/events/handle-complementary-certifications-scoring_test.js index 6e74d9a3a17..b0a35b2e91f 100644 --- a/api/tests/unit/domain/events/handle-complementary-certifications-scoring_test.js +++ b/api/tests/unit/domain/events/handle-complementary-certifications-scoring_test.js @@ -85,6 +85,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 70, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: true, @@ -106,6 +107,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: true, @@ -141,6 +143,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat const complementaryCertificationScoringCriteria = [ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 100, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: true, @@ -159,6 +162,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: false, @@ -197,6 +201,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 75, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: true, @@ -217,6 +222,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: false, @@ -255,6 +261,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 75, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: true, @@ -275,6 +282,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: true, @@ -312,6 +320,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 70, minimumEarnedPix: 50, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', @@ -335,6 +344,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: true, @@ -373,6 +383,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat const complementaryCertificationScoringCriteria = [ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 75, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: false, @@ -392,6 +403,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: false, @@ -430,6 +442,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 75, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: false, @@ -453,6 +466,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: false, @@ -491,6 +505,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 70, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: false, @@ -514,6 +529,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: false, @@ -552,6 +568,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat .resolves([ domainBuilder.buildComplementaryCertificationScoringCriteria({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, minimumReproducibilityRate: 70, complementaryCertificationBadgeKey: 'PIX_PLUS_TEST', hasComplementaryReferential: false, @@ -575,6 +592,7 @@ describe('Unit | Domain | Events | handle-complementary-certification-certificat expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( ComplementaryCertificationCourseResult.from({ complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 888, partnerKey: 'PIX_PLUS_TEST', source: ComplementaryCertificationCourseResult.sources.PIX, acquired: true, diff --git a/api/tests/unit/domain/models/ComplementaryCertificationCourseResult_test.js b/api/tests/unit/domain/models/ComplementaryCertificationCourseResult_test.js index af7a289c246..72185719d4e 100644 --- a/api/tests/unit/domain/models/ComplementaryCertificationCourseResult_test.js +++ b/api/tests/unit/domain/models/ComplementaryCertificationCourseResult_test.js @@ -7,7 +7,6 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResult', func // given const complementaryCertificationCourseResult = new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 'complementaryCertificationCourseId', - partnerKey: 'partnerKey', acquired: true, source: 'source', }); @@ -23,7 +22,6 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResult', func // given const complementaryCertificationCourseResult = new ComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 'complementaryCertificationCourseId', - partnerKey: 'partnerKey', acquired: false, source: 'source', }); @@ -50,14 +48,12 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResult', func const result = ComplementaryCertificationCourseResult.buildFromJuryLevel({ juryLevel: complementaryCertificationCourseResult.partnerKey, complementaryCertificationCourseId: 12, - pixPartnerKey: 'PARTNER_KEY', }); // then expect(result).to.deepEqualInstance( new ComplementaryCertificationCourseResult({ acquired: true, - partnerKey: 'PARTNER_KEY', source: ComplementaryCertificationCourseResult.sources.EXTERNAL, complementaryCertificationCourseId: 12, }), @@ -68,25 +64,16 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResult', func describe('when the jury level is "REJECTED"', function () { it('should return an acquired ComplementaryCertificationCourseResult with an external source', function () { // given - const complementaryCertificationCourseResult = domainBuilder.buildComplementaryCertificationCourseResult({ - partnerKey: 'REJECTED', - source: ComplementaryCertificationCourseResult.sources.PIX, - acquired: true, - complementaryCertificationCourseId: 12, - }); - // when const result = ComplementaryCertificationCourseResult.buildFromJuryLevel({ - juryLevel: complementaryCertificationCourseResult.partnerKey, + juryLevel: 'REJECTED', complementaryCertificationCourseId: 12, - pixPartnerKey: 'PARTNER_KEY', }); // then expect(result).to.deepEqualInstance( new ComplementaryCertificationCourseResult({ acquired: false, - partnerKey: 'PARTNER_KEY', source: ComplementaryCertificationCourseResult.sources.EXTERNAL, complementaryCertificationCourseId: 12, }), diff --git a/api/tests/unit/domain/models/ComplementaryCertificationScoringWithComplementaryReferential_test.js b/api/tests/unit/domain/models/ComplementaryCertificationScoringWithComplementaryReferential_test.js index 5bdb6378fbc..0e0df93d1cc 100644 --- a/api/tests/unit/domain/models/ComplementaryCertificationScoringWithComplementaryReferential_test.js +++ b/api/tests/unit/domain/models/ComplementaryCertificationScoringWithComplementaryReferential_test.js @@ -8,6 +8,7 @@ describe('Unit | Domain | Models | ComplementaryCertificationScoringWithCompleme const complementaryCertificationScoringWithComplementaryReferential = new ComplementaryCertificationScoringWithComplementaryReferential({ complementaryCertificationCourseId: 99, + complementaryCertificationBadgeId: 89, complementaryCertificationBadgeKey: 'BADGE', reproducibilityRate: 71, hasAcquiredPixCertification: false, @@ -17,11 +18,11 @@ describe('Unit | Domain | Models | ComplementaryCertificationScoringWithCompleme expect(complementaryCertificationScoringWithComplementaryReferential).to.deepEqualInstance( new ComplementaryCertificationScoringWithComplementaryReferential({ complementaryCertificationCourseId: 99, - reproducibilityRate: 71, + complementaryCertificationBadgeId: 89, complementaryCertificationBadgeKey: 'BADGE', + reproducibilityRate: 71, hasAcquiredPixCertification: false, minimumReproducibilityRate: undefined, - partnerKey: 'BADGE', source: 'PIX', }), ); diff --git a/api/tests/unit/domain/models/PartnerCertificationScoring_test.js b/api/tests/unit/domain/models/PartnerCertificationScoring_test.js index 04a855075d8..dd77e2bf18a 100644 --- a/api/tests/unit/domain/models/PartnerCertificationScoring_test.js +++ b/api/tests/unit/domain/models/PartnerCertificationScoring_test.js @@ -8,6 +8,7 @@ describe('Unit | Domain | Models | PartnerCertificationScoring', function () { beforeEach(function () { validArguments = { complementaryCertificationCourseId: 999, + complementaryCertificationBadgeId: 60, certificationCourseId: 123, partnerKey: 'partnerKey', }; diff --git a/api/tests/unit/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal_test.js b/api/tests/unit/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal_test.js index 1d1f8e09ff0..9c4ffc7093b 100644 --- a/api/tests/unit/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal_test.js +++ b/api/tests/unit/domain/read-models/ComplementaryCertificationCourseResultForJuryCertificationWithExternal_test.js @@ -9,9 +9,9 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = domainBuilder.buildComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY', + pixComplementaryCertificationBadgeId: 99, pixAcquired: true, - externalPartnerKey: null, + externalComplementaryCertificationBadgeId: null, }); // when @@ -26,7 +26,7 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = domainBuilder.buildComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY', + pixComplementaryCertificationBadgeId: 99, pixAcquired: false, }); @@ -42,9 +42,9 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = domainBuilder.buildComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY_1', + pixComplementaryCertificationBadgeId: 99, pixAcquired: true, - externalPartnerKey: 'KEY_2', + externalComplementaryCertificationBadgeId: 99, externalAcquired: false, }); @@ -59,11 +59,11 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = domainBuilder.buildComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'BADGE_KEY_1', + pixComplementaryCertificationBadgeId: 98, pixLabel: 'Badge Key 1', pixAcquired: true, pixLevel: 4, - externalPartnerKey: 'BADGE_KEY_2', + externalComplementaryCertificationBadgeId: 99, externalLabel: 'Badge Key 2', externalAcquired: true, externalLevel: 2, @@ -79,30 +79,30 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury }); describe('#from', function () { - it('should return a PixEduComplementaryCertificationCourseResultForJuryCertification', function () { + it('should return a ComplementaryCertificationCourseResultForJuryCertificationWithExternal', function () { // given const complementaryCertificationCourseResultWithExternal = [ domainBuilder.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 1234, - partnerKey: 'KEY_1', + complementaryCertificationBadgeId: 456, acquired: true, source: ComplementaryCertificationCourseResult.sources.PIX, }), domainBuilder.buildComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 1234, - partnerKey: 'KEY_2', + complementaryCertificationBadgeId: 457, acquired: false, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, }), ]; - const badgesKeyAndLabel = [ - { key: 'KEY_1', label: 'Key 1' }, - { key: 'KEY_2', label: 'Key 2' }, + const badgesIdAndLabels = [ + { id: 456, label: 'Key 1' }, + { id: 457, label: 'Key 2' }, ]; // when const result = ComplementaryCertificationCourseResultForJuryCertificationWithExternal.from( complementaryCertificationCourseResultWithExternal, - badgesKeyAndLabel, + badgesIdAndLabels, ); // then @@ -110,12 +110,12 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ pixAcquired: true, externalAcquired: false, - pixPartnerKey: 'KEY_1', - externalPartnerKey: 'KEY_2', + pixComplementaryCertificationBadgeId: 456, + externalComplementaryCertificationBadgeId: 457, complementaryCertificationCourseId: 1234, allowedExternalLevels: [ - { value: 'KEY_1', label: 'Key 1' }, - { value: 'KEY_2', label: 'Key 2' }, + { value: 456, label: 'Key 1' }, + { value: 457, label: 'Key 2' }, ], defaultJuryOptions: ['REJECTED', 'UNSET'], }), @@ -143,7 +143,7 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY', + pixComplementaryCertificationBadgeId: 98, pixLabel: 'Key label', pixAcquired: true, }); @@ -163,7 +163,7 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY', + pixComplementaryCertificationBadgeId: 99, pixAcquired: false, }); @@ -180,7 +180,7 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY', + pixComplementaryCertificationBadgeId: 99, pixAcquired: true, }); @@ -198,9 +198,9 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY_1', + pixComplementaryCertificationBadgeId: 98, pixAcquired: true, - externalPartnerKey: 'KEY_2', + externalComplementaryCertificationBadgeId: 99, externalLabel: 'Key 2 label', externalAcquired: true, }); @@ -218,9 +218,9 @@ describe('Unit | Domain | Models | ComplementaryCertificationCourseResultForJury // given const complementaryCertificationCourseResultForJuryCertificationWithExternal = new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({ - pixPartnerKey: 'KEY_1', + pixComplementaryCertificationBadgeId: 98, pixAcquired: true, - externalPartnerKey: 'KEY_2', + externalComplementaryCertificationBadgeId: 98, externalAcquired: false, }); diff --git a/api/tests/unit/domain/usecases/save-jury-complementary-certification-course-result_test.js b/api/tests/unit/domain/usecases/save-jury-complementary-certification-course-result_test.js index 1683ddffe0c..d8e9545f1b0 100644 --- a/api/tests/unit/domain/usecases/save-jury-complementary-certification-course-result_test.js +++ b/api/tests/unit/domain/usecases/save-jury-complementary-certification-course-result_test.js @@ -11,7 +11,7 @@ describe('Unit | UseCase | save-jury-complementary-certification-course-results' complementaryCertificationCourseResultRepository = { save: sinon.stub(), getPixSourceResultByComplementaryCertificationCourseId: sinon.stub(), - getAllowedJuryLevelByBadgeKey: sinon.stub(), + getAllowedJuryLevelIdsByComplementaryCertificationBadgeId: sinon.stub(), removeExternalJuryResult: sinon.stub(), }; }); @@ -26,7 +26,7 @@ describe('Unit | UseCase | save-jury-complementary-certification-course-results' // when const error = await catchErr(saveJuryComplementaryCertificationCourseResult)({ complementaryCertificationCourseId: 12345, - juryLevel: 'JURY_LEVEL', + juryLevel: 1, complementaryCertificationCourseResultRepository, }); @@ -46,20 +46,19 @@ describe('Unit | UseCase | save-jury-complementary-certification-course-results' .withArgs({ complementaryCertificationCourseId: 1234 }) .resolves( domainBuilder.buildComplementaryCertificationCourseResult({ - partnerKey: 'KEY_1', + complementaryCertificationBadgeId: 99, complementaryCertificationCourseId: 1234, source: ComplementaryCertificationCourseResult.sources.PIX, }), ); - - complementaryCertificationCourseResultRepository.getAllowedJuryLevelByBadgeKey - .withArgs({ key: 'KEY_1' }) - .resolves(['KEY_1', 'KEY_2']); + complementaryCertificationCourseResultRepository.getAllowedJuryLevelIdsByComplementaryCertificationBadgeId + .withArgs(99) + .resolves([98, 99, 100]); // when const error = await catchErr(saveJuryComplementaryCertificationCourseResult)({ complementaryCertificationCourseId: 1234, - juryLevel: 'KEY_3', + juryLevel: 101, complementaryCertificationCourseResultRepository, }); @@ -102,20 +101,20 @@ describe('Unit | UseCase | save-jury-complementary-certification-course-results' .withArgs({ complementaryCertificationCourseId: 1234 }) .resolves( domainBuilder.buildComplementaryCertificationCourseResult({ - partnerKey: 'KEY_1', + complementaryCertificationBadgeId: 99, complementaryCertificationCourseId: 1234, source: ComplementaryCertificationCourseResult.sources.PIX, }), ); - complementaryCertificationCourseResultRepository.getAllowedJuryLevelByBadgeKey - .withArgs({ key: 'KEY_1' }) - .resolves(['KEY_1', 'KEY_2']); + complementaryCertificationCourseResultRepository.getAllowedJuryLevelIdsByComplementaryCertificationBadgeId + .withArgs(99) + .resolves([98, 99, 100]); // when await saveJuryComplementaryCertificationCourseResult({ complementaryCertificationCourseId: 1234, - juryLevel: 'KEY_2', + juryLevel: 99, complementaryCertificationCourseResultRepository, }); @@ -123,6 +122,7 @@ describe('Unit | UseCase | save-jury-complementary-certification-course-results' expect(complementaryCertificationCourseResultRepository.save).to.have.been.calledWithExactly( new ComplementaryCertificationCourseResult({ partnerKey: 'KEY_2', + complementaryCertificationBadgeId: 99, source: ComplementaryCertificationCourseResult.sources.EXTERNAL, acquired: true, complementaryCertificationCourseId: 1234,