- {{t "pages.certification-start.subscription"}}
+ {{this.subscriptionTitle}}
diff --git a/mon-pix/app/components/certification-starter.js b/mon-pix/app/components/certification-starter.js
index e9b0d327064..0343ee12e11 100644
--- a/mon-pix/app/components/certification-starter.js
+++ b/mon-pix/app/components/certification-starter.js
@@ -27,6 +27,17 @@ export default class CertificationStarter extends Component {
).label;
}
+ get subscriptionTitle() {
+ if (
+ !this.args.certificationCandidateSubscription.isSessionVersion3 ||
+ this.args.certificationCandidateSubscription.isV3CoreAndComplementary
+ ) {
+ return this.intl.t('pages.certification-start.core-and-complementary-subscriptions');
+ } else {
+ return this.intl.t('pages.certification-start.complementary-subscription');
+ }
+ }
+
@action
async submit(e) {
e.preventDefault();
diff --git a/mon-pix/app/models/certification-candidate-subscription.js b/mon-pix/app/models/certification-candidate-subscription.js
index 54794ec0211..fcca1aceb1c 100644
--- a/mon-pix/app/models/certification-candidate-subscription.js
+++ b/mon-pix/app/models/certification-candidate-subscription.js
@@ -20,6 +20,15 @@ export default class CertificationCandidateSubscription extends Model {
);
}
+ get isV3CoreAndComplementary() {
+ return (
+ this.isSessionVersion3 &&
+ this.eligibleSubscriptions.length === 2 &&
+ this.eligibleSubscriptions.some((eligibleSubscription) => eligibleSubscription.type === 'CORE') &&
+ this.eligibleSubscriptions.some((eligibleSubscription) => eligibleSubscription.type === 'COMPLEMENTARY')
+ );
+ }
+
get isSessionVersion3() {
return this.sessionVersion === 3;
}
diff --git a/mon-pix/tests/integration/components/certification-starter-test.js b/mon-pix/tests/integration/components/certification-starter-test.js
index c220c914c4c..831756114f5 100644
--- a/mon-pix/tests/integration/components/certification-starter-test.js
+++ b/mon-pix/tests/integration/components/certification-starter-test.js
@@ -68,17 +68,20 @@ module('Integration | Component | certification-starter', function (hooks) {
);
});
});
- });
- module('when the candidate has complementary certification subscription', function () {
- module('when the candidate is eligible', function () {
+
+ module('when the candidate has core and complementary subscriptions', function () {
test('should display subscription eligible panel', async function (assert) {
// given
const store = this.owner.lookup('service:store');
this.set(
'certificationCandidateSubscription',
store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: [{ label: 'Certif complémentaire 1' }],
+ eligibleSubscriptions: [
+ { label: null, type: 'CORE' },
+ { label: 'Pix+ toto', type: 'COMPLEMENTARY' },
+ ],
nonEligibleSubscription: null,
+ sessionVersion: 3,
}),
);
@@ -88,22 +91,26 @@ module('Integration | Component | certification-starter', function (hooks) {
);
// then
+ assert.notOk(screen.queryByText('Vous n’êtes pas éligible à'));
assert.ok(
- screen.getByText(
+ screen.queryByText(
'Vous êtes inscrit à la certification complémentaire suivante en plus de la certification Pix :',
),
);
- assert.ok(screen.getByText('Certif complémentaire 1'));
+ assert.ok(screen.getByText('Pix+ toto'));
});
+ });
- test('should not display subscription non eligible panel', async function (assert) {
+ module('when the candidate has only a complementary subscriptions', function () {
+ test('should display subscription eligible panel', async function (assert) {
// given
const store = this.owner.lookup('service:store');
this.set(
'certificationCandidateSubscription',
store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: [{ label: 'Certif complémentaire 1' }],
+ eligibleSubscriptions: [{ label: 'Pix+ toto', type: 'COMPLEMENTARY' }],
nonEligibleSubscription: null,
+ sessionVersion: 3,
}),
);
@@ -114,56 +121,112 @@ module('Integration | Component | certification-starter', function (hooks) {
// then
assert.notOk(screen.queryByText('Vous n’êtes pas éligible à'));
+ assert.ok(screen.queryByText('Vous êtes inscrit à la certification complémentaire suivante :'));
+ assert.ok(screen.getByText('Pix+ toto'));
});
});
+ });
- module('when the candidate is not eligible', function () {
- test('should display subscription non eligible panel', async function (assert) {
- // given
- const store = this.owner.lookup('service:store');
- this.set(
- 'certificationCandidateSubscription',
- store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: null,
- nonEligibleSubscription: { label: 'Certif complémentaire 1' },
- }),
- );
+ module('when the session is v2', function () {
+ module('when the candidate has complementary certification subscription', function () {
+ module('when the candidate is eligible', function () {
+ test('should display subscription eligible panel', async function (assert) {
+ // given
+ const store = this.owner.lookup('service:store');
+ this.set(
+ 'certificationCandidateSubscription',
+ store.createRecord('certification-candidate-subscription', {
+ eligibleSubscriptions: [{ label: 'Certif complémentaire 1', type: 'COMPLEMENTARY' }],
+ nonEligibleSubscription: null,
+ sessionVersion: 2,
+ }),
+ );
- // when
- const screen = await render(
- hbs`
`,
- );
+ // when
+ const screen = await render(
+ hbs`
`,
+ );
- // then
- assert.ok(
- screen.getByText(
- "Vous n'êtes pas éligible à Certif complémentaire 1. Vous pouvez néanmoins passer votre certification Pix.",
- ),
- );
+ // then
+ assert.ok(
+ screen.getByText(
+ 'Vous êtes inscrit à la certification complémentaire suivante en plus de la certification Pix :',
+ ),
+ );
+ assert.ok(screen.getByText('Certif complémentaire 1'));
+ });
+
+ test('should not display subscription non eligible panel', async function (assert) {
+ // given
+ const store = this.owner.lookup('service:store');
+ this.set(
+ 'certificationCandidateSubscription',
+ store.createRecord('certification-candidate-subscription', {
+ eligibleSubscriptions: [{ label: 'Certif complémentaire 1', type: 'COMPLEMENTARY' }],
+ nonEligibleSubscription: null,
+ }),
+ );
+
+ // when
+ const screen = await render(
+ hbs`
`,
+ );
+
+ // then
+ assert.notOk(screen.queryByText('Vous n’êtes pas éligible à'));
+ });
});
- test('should not display subscription eligible panel', async function (assert) {
- // given
- const store = this.owner.lookup('service:store');
- this.set(
- 'certificationCandidateSubscription',
- store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: null,
- nonEligibleSubscription: { label: 'Certif complémentaire 1' },
- }),
- );
+ module('when the candidate is not eligible', function () {
+ test('should display subscription non eligible panel', async function (assert) {
+ // given
+ const store = this.owner.lookup('service:store');
+ this.set(
+ 'certificationCandidateSubscription',
+ store.createRecord('certification-candidate-subscription', {
+ eligibleSubscriptions: null,
+ nonEligibleSubscription: { label: 'Certif complémentaire 1' },
+ sessionVersion: 2,
+ }),
+ );
- // when
- const screen = await render(
- hbs`
`,
- );
+ // when
+ const screen = await render(
+ hbs`
`,
+ );
- // then
- assert.notOk(
- screen.queryByText(
- 'Vous êtes inscrit aux certifications complémentaires suivantes en plus de la certification Pix :',
- ),
- );
+ // then
+ assert.ok(
+ screen.getByText(
+ "Vous n'êtes pas éligible à Certif complémentaire 1. Vous pouvez néanmoins passer votre certification Pix.",
+ ),
+ );
+ });
+
+ test('should not display subscription eligible panel', async function (assert) {
+ // given
+ const store = this.owner.lookup('service:store');
+ this.set(
+ 'certificationCandidateSubscription',
+ store.createRecord('certification-candidate-subscription', {
+ eligibleSubscriptions: null,
+ nonEligibleSubscription: { label: 'Certif complémentaire 1' },
+ sessionVersion: 2,
+ }),
+ );
+
+ // when
+ const screen = await render(
+ hbs`
`,
+ );
+
+ // then
+ assert.notOk(
+ screen.queryByText(
+ 'Vous êtes inscrit aux certifications complémentaires suivantes en plus de la certification Pix :',
+ ),
+ );
+ });
});
});
});
diff --git a/mon-pix/translations/en.json b/mon-pix/translations/en.json
index b2b7fcc4e2e..2d62350a173 100644
--- a/mon-pix/translations/en.json
+++ b/mon-pix/translations/en.json
@@ -676,7 +676,8 @@
"first-title": "You are about to begin your certification test.",
"link-to-user-certification": "See my certificates",
"non-eligible-subscription": "You are not eligible to {nonEligibleSubscriptionLabel}. However, you can still take your Pix Certification.",
- "subscription": "You are registered for the following additional certification in combination with the Pix Certification:"
+ "core-and-complementary-subscriptions": "You are registered for the following additional certification in combination with the Pix Certification:",
+ "complementary-subscription": "You are registered for the following additional certification :"
},
"certifications-list": {
"title": "My Certifications",
diff --git a/mon-pix/translations/es.json b/mon-pix/translations/es.json
index 108cff45ba2..1f77d485772 100644
--- a/mon-pix/translations/es.json
+++ b/mon-pix/translations/es.json
@@ -667,7 +667,7 @@
"first-title": "Estás a punto de empezar tu prueba de certificación",
"link-to-user-certification": "Ver mis certificaciones",
"non-eligible-subscription": "No eres elegible para {nonEligibleSubscriptionLabel}. Sin embargo, puedes presentarte a la certificación Pix.",
- "subscription": "Además de la certificación Pix, estás inscrito en la siguiente certificación complementaria:",
+ "core-and-complementary-subscriptions": "Además de la certificación Pix, estás inscrito en la siguiente certificación complementaria:",
"title": "Unirse a una sesión de certificación"
},
"certifications-list": {
diff --git a/mon-pix/translations/fr.json b/mon-pix/translations/fr.json
index c349130b919..f9eb621532c 100644
--- a/mon-pix/translations/fr.json
+++ b/mon-pix/translations/fr.json
@@ -676,7 +676,8 @@
"first-title": "Vous allez commencer votre test de certification",
"link-to-user-certification": "Voir mes certifications",
"non-eligible-subscription": "Vous n'êtes pas éligible à {nonEligibleSubscriptionLabel}. Vous pouvez néanmoins passer votre certification Pix.",
- "subscription": "Vous êtes inscrit à la certification complémentaire suivante en plus de la certification Pix :"
+ "core-and-complementary-subscriptions": "Vous êtes inscrit à la certification complémentaire suivante en plus de la certification Pix :",
+ "complementary-subscription": "Vous êtes inscrit à la certification complémentaire suivante :"
},
"certifications-list": {
"title": "Mes Certifications",
diff --git a/mon-pix/translations/nl.json b/mon-pix/translations/nl.json
index 68bcabe9b9b..f23376c21b1 100644
--- a/mon-pix/translations/nl.json
+++ b/mon-pix/translations/nl.json
@@ -667,7 +667,7 @@
"first-title": "Je staat op het punt om aan je certificeringstest te beginnen",
"link-to-user-certification": "Bekijk mijn certificaten",
"non-eligible-subscription": "Je komt niet in aanmerking voor {nonEligibleSubscriptionLabel}. Je kunt echter wel je Pix-certificering behalen.",
- "subscription": "Je bent geregistreerd voor de volgende aanvullende certificering naast de Pix-certificering:",
+ "core-and-complementary-subscriptions": "Je bent geregistreerd voor de volgende aanvullende certificering naast de Pix-certificering:",
"title": "Doe mee aan een certificeringssessie"
},
"certifications-list": {
From d6b43e63e7415e5831d7a59cecdaf685a8d6dffb Mon Sep 17 00:00:00 2001
From: P-Jeremy
Date: Wed, 9 Oct 2024 12:55:43 +0200
Subject: [PATCH 05/12] :sparkles: api: get all candidate subscriptions
Co-authored-by: Alexandre Coin
---
.../certification-candidate-repository.js | 39 ++++++++-----
.../domain/models/CertificationCandidate.js | 24 +-------
...certification-candidate-repository_test.js | 57 +++++++++++++++++--
.../models/CertificationCandidate_test.js | 5 +-
4 files changed, 81 insertions(+), 44 deletions(-)
diff --git a/api/src/certification/enrolment/infrastructure/repositories/certification-candidate-repository.js b/api/src/certification/enrolment/infrastructure/repositories/certification-candidate-repository.js
index f24c8e06e1f..29f3aedbd11 100644
--- a/api/src/certification/enrolment/infrastructure/repositories/certification-candidate-repository.js
+++ b/api/src/certification/enrolment/infrastructure/repositories/certification-candidate-repository.js
@@ -5,16 +5,27 @@ import { ComplementaryCertification } from '../../domain/models/ComplementaryCer
import { Subscription } from '../../domain/models/Subscription.js';
const getBySessionIdAndUserId = async function ({ sessionId, userId }) {
- const certificationCandidate = await _candidateBaseQuery().where({ sessionId, userId }).first();
- return certificationCandidate ? _toDomain(certificationCandidate) : undefined;
+ const candidateData = await _candidateBaseQuery().where({ sessionId, userId }).first();
+ const subscriptionData = candidateData ? await _getSubscriptions(candidateData.id) : undefined;
+ return candidateData ? _toDomain({ candidateData, subscriptionData }) : undefined;
};
const findBySessionId = async function (sessionId) {
- const results = await _candidateBaseQuery()
+ const certificationCandidates = await _candidateBaseQuery()
.where({ 'certification-candidates.sessionId': sessionId })
.orderByRaw('LOWER("certification-candidates"."lastName") asc')
.orderByRaw('LOWER("certification-candidates"."firstName") asc');
- return results.map(_toDomain);
+
+ const result = [];
+
+ for (const candidateData of certificationCandidates) {
+ const subscriptions = await _getSubscriptions(candidateData.id);
+ const certificationCandidate = _toDomain({ candidateData, subscriptions });
+
+ result.push(certificationCandidate);
+ }
+
+ return result;
};
const update = async function (certificationCandidate) {
@@ -30,24 +41,22 @@ const update = async function (certificationCandidate) {
const getWithComplementaryCertification = async function ({ id }) {
const candidateData = await _candidateBaseQuery().where('certification-candidates.id', id).first();
+ const subscriptionData = await _getSubscriptions(id);
+
if (!candidateData) {
throw new NotFoundError('Candidate not found');
}
- return _toDomain(candidateData);
+ return _toDomain({ candidateData, subscriptionData });
};
export { findBySessionId, getBySessionIdAndUserId, getWithComplementaryCertification, update };
-/**
- * @deprecated migration: new ComplementaryCertification(...) should not be done here
- * it should come from internal API complementary-certification bounded context.
- * Please beware of that when refactoring this code in the future
- */
-function _toDomain(candidateData) {
+function _toDomain({ candidateData, subscriptionData }) {
+ const subscriptions = subscriptionData?.map((subscription) => new Subscription({ ...subscription }));
return new CertificationCandidate({
...candidateData,
- subscriptions: [Subscription.buildCore({ id: candidateData.certificationCandidateId })],
+ subscriptions,
complementaryCertification: candidateData.complementaryCertificationId
? new ComplementaryCertification({
id: candidateData.complementaryCertificationId,
@@ -63,8 +72,8 @@ function _candidateBaseQuery() {
.select({
certificationCandidate: 'certification-candidates.*',
complementaryCertificationId: 'complementary-certifications.id',
- complementaryCertificationKey: 'complementary-certifications.key',
complementaryCertificationLabel: 'complementary-certifications.label',
+ complementaryCertificationKey: 'complementary-certifications.key',
})
.from('certification-candidates')
.leftJoin('certification-subscriptions', (builder) =>
@@ -79,3 +88,7 @@ function _candidateBaseQuery() {
)
.groupBy('certification-candidates.id', 'complementary-certifications.id');
}
+
+async function _getSubscriptions(candidateId) {
+ return knex.select('*').from('certification-subscriptions').where('certificationCandidateId', candidateId);
+}
diff --git a/api/src/shared/domain/models/CertificationCandidate.js b/api/src/shared/domain/models/CertificationCandidate.js
index 97df9d76751..479893d713c 100644
--- a/api/src/shared/domain/models/CertificationCandidate.js
+++ b/api/src/shared/domain/models/CertificationCandidate.js
@@ -1,7 +1,6 @@
import lodash from 'lodash';
-import { Subscription } from '../../../certification/enrolment/domain/models/Subscription.js';
-import { BILLING_MODES, SUBSCRIPTION_TYPES } from '../../../certification/shared/domain/constants.js';
+import { BILLING_MODES } from '../../../certification/shared/domain/constants.js';
const { isNil } = lodash;
@@ -65,27 +64,6 @@ class CertificationCandidate {
this.hasSeenCertificationInstructions = hasSeenCertificationInstructions;
this.accessibilityAdjustmentNeeded = accessibilityAdjustmentNeeded;
this.reconciledAt = reconciledAt;
-
- Object.defineProperty(this, 'complementaryCertification', {
- enumerable: true,
- get: function () {
- return this.#complementaryCertification;
- },
-
- set: function (complementaryCertification) {
- this.#complementaryCertification = complementaryCertification;
- this.subscriptions = this.subscriptions.filter((subscription) => subscription.type === SUBSCRIPTION_TYPES.CORE);
- if (complementaryCertification?.id) {
- this.subscriptions.push(
- Subscription.buildComplementary({
- certificationCandidateId: this.id,
- complementaryCertificationId: complementaryCertification.id,
- }),
- );
- }
- },
- });
-
this.complementaryCertification = complementaryCertification;
}
diff --git a/api/tests/certification/enrolment/integration/infrastructure/repositories/certification-candidate-repository_test.js b/api/tests/certification/enrolment/integration/infrastructure/repositories/certification-candidate-repository_test.js
index 57a598c70fa..2fb17201d02 100644
--- a/api/tests/certification/enrolment/integration/infrastructure/repositories/certification-candidate-repository_test.js
+++ b/api/tests/certification/enrolment/integration/infrastructure/repositories/certification-candidate-repository_test.js
@@ -199,7 +199,7 @@ describe('Integration | Repository | CertificationCandidate', function () {
sex: 'M',
subscriptions: [
{
- certificationCandidateId: undefined,
+ certificationCandidateId,
complementaryCertificationId: null,
type: 'CORE',
},
@@ -350,13 +350,53 @@ describe('Integration | Repository | CertificationCandidate', function () {
domainBuilder.buildCertificationCandidate({
...certificationCandidate,
complementaryCertification: null,
- subscriptions: [domainBuilder.buildCoreSubscription()],
+ subscriptions: [
+ domainBuilder.buildCoreSubscription({
+ certificationCandidateId: certificationCandidate.id,
+ }),
+ ],
}),
);
});
});
- context('when the candidate has complementary certification subscriptions', function () {
+ context('when the candidate has only complementary certification subscription', function () {
+ it('should return the candidate with his complementary certification', async function () {
+ // given
+ const certificationCandidate = databaseBuilder.factory.buildCertificationCandidate();
+ const complementaryCertification = databaseBuilder.factory.buildComplementaryCertification({
+ label: 'Complementary certification 2',
+ });
+ databaseBuilder.factory.buildComplementaryCertificationSubscription({
+ complementaryCertificationId: complementaryCertification.id,
+ certificationCandidateId: certificationCandidate.id,
+ });
+ await databaseBuilder.commit();
+
+ // when
+ const certificationCandidateWithComplementaryCertification =
+ await certificationCandidateRepository.getWithComplementaryCertification({ id: certificationCandidate.id });
+
+ // then
+ expect(certificationCandidateWithComplementaryCertification).to.deep.equal(
+ domainBuilder.buildCertificationCandidate({
+ ...certificationCandidate,
+ subscriptions: [
+ domainBuilder.buildComplementarySubscription({
+ certificationCandidateId: certificationCandidate.id,
+ complementaryCertificationId: complementaryCertification.id,
+ }),
+ ],
+ complementaryCertification:
+ domainBuilder.certification.sessionManagement.buildCertificationSessionComplementaryCertification(
+ complementaryCertification,
+ ),
+ }),
+ );
+ });
+ });
+
+ context('when the candidate has core and complementary certification subscriptions', function () {
it('should return the candidate with his complementary certification', async function () {
// given
const certificationCandidate = databaseBuilder.factory.buildCertificationCandidate();
@@ -368,6 +408,7 @@ describe('Integration | Repository | CertificationCandidate', function () {
complementaryCertificationId: complementaryCertification.id,
certificationCandidateId: certificationCandidate.id,
});
+
await databaseBuilder.commit();
// when
@@ -378,7 +419,15 @@ describe('Integration | Repository | CertificationCandidate', function () {
expect(certificationCandidateWithComplementaryCertification).to.deep.equal(
domainBuilder.buildCertificationCandidate({
...certificationCandidate,
- subscriptions: [domainBuilder.buildCoreSubscription()],
+ subscriptions: [
+ domainBuilder.buildCoreSubscription({
+ certificationCandidateId: certificationCandidate.id,
+ }),
+ domainBuilder.buildComplementarySubscription({
+ complementaryCertificationId: complementaryCertification.id,
+ certificationCandidateId: certificationCandidate.id,
+ }),
+ ],
complementaryCertification:
domainBuilder.certification.sessionManagement.buildCertificationSessionComplementaryCertification(
complementaryCertification,
diff --git a/api/tests/unit/domain/models/CertificationCandidate_test.js b/api/tests/unit/domain/models/CertificationCandidate_test.js
index 762a8c7617d..4d2de0e4254 100644
--- a/api/tests/unit/domain/models/CertificationCandidate_test.js
+++ b/api/tests/unit/domain/models/CertificationCandidate_test.js
@@ -71,10 +71,7 @@ describe('Unit | Domain | Models | Certification Candidate', function () {
expectedData = {
...expectedData,
complementaryCertification: { id: 99 },
- subscriptions: [
- coreSubscription,
- domainBuilder.buildComplementarySubscription({ complementaryCertificationId: 99 }),
- ],
+ subscriptions: [coreSubscription],
};
// when
From b5d934f6519333589501604172e308598be76b30 Mon Sep 17 00:00:00 2001
From: Alexandre COIN
Date: Wed, 9 Oct 2024 16:10:40 +0200
Subject: [PATCH 06/12] :sparkles: api: get subscriptions in usecase
---
.../CertificationCandidateSubscription.js | 4 +-
...et-certification-candidate-subscription.js | 14 +-
...rtification-candidate-subscription_test.js | 167 +++++++++++++++++-
...ld-certification-candidate-subscription.js | 4 +-
4 files changed, 178 insertions(+), 11 deletions(-)
diff --git a/api/src/certification/enrolment/domain/read-models/CertificationCandidateSubscription.js b/api/src/certification/enrolment/domain/read-models/CertificationCandidateSubscription.js
index 3553e89a94a..b67919697f6 100644
--- a/api/src/certification/enrolment/domain/read-models/CertificationCandidateSubscription.js
+++ b/api/src/certification/enrolment/domain/read-models/CertificationCandidateSubscription.js
@@ -1,8 +1,8 @@
class CertificationCandidateSubscription {
- constructor({ id, sessionId, eligibleSubscription, nonEligibleSubscription, sessionVersion }) {
+ constructor({ id, sessionId, eligibleSubscriptions, nonEligibleSubscription, sessionVersion }) {
this.id = id;
this.sessionId = sessionId;
- this.eligibleSubscription = eligibleSubscription;
+ this.eligibleSubscriptions = eligibleSubscriptions;
this.nonEligibleSubscription = nonEligibleSubscription;
this.sessionVersion = sessionVersion;
}
diff --git a/api/src/certification/enrolment/domain/usecases/get-certification-candidate-subscription.js b/api/src/certification/enrolment/domain/usecases/get-certification-candidate-subscription.js
index b7364fca7c7..0a8d735a7e1 100644
--- a/api/src/certification/enrolment/domain/usecases/get-certification-candidate-subscription.js
+++ b/api/src/certification/enrolment/domain/usecases/get-certification-candidate-subscription.js
@@ -17,7 +17,7 @@ const getCertificationCandidateSubscription = async function ({
return new CertificationCandidateSubscription({
id: certificationCandidateId,
sessionId: certificationCandidate.sessionId,
- eligibleSubscription: null,
+ eligibleSubscriptions: [],
nonEligibleSubscription: null,
sessionVersion: session.version,
});
@@ -27,10 +27,11 @@ const getCertificationCandidateSubscription = async function ({
id: session.certificationCenterId,
});
- let eligibleSubscription = null;
+ let eligibleSubscriptions = [];
let nonEligibleSubscription = null;
const certifiableBadgeAcquisitions = await certificationBadgesService.findStillValidBadgeAcquisitions({
userId: certificationCandidate.userId,
+ limitDate: certificationCandidate.reconciledAt,
});
if (center.isHabilitated(certificationCandidate.complementaryCertification.key)) {
@@ -40,7 +41,12 @@ const getCertificationCandidateSubscription = async function ({
);
if (isSubscriptionEligible) {
- eligibleSubscription = certificationCandidate.complementaryCertification;
+ eligibleSubscriptions = certificationCandidate.subscriptions.map((subscription) => {
+ return {
+ label: subscription.type === 'COMPLEMENTARY' ? certificationCandidate.complementaryCertification.label : null,
+ type: subscription.type,
+ };
+ });
} else {
nonEligibleSubscription = certificationCandidate.complementaryCertification;
}
@@ -49,7 +55,7 @@ const getCertificationCandidateSubscription = async function ({
return new CertificationCandidateSubscription({
id: certificationCandidateId,
sessionId: certificationCandidate.sessionId,
- eligibleSubscription,
+ eligibleSubscriptions,
nonEligibleSubscription,
sessionVersion: session.version,
});
diff --git a/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js b/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
index 57fb86e08ff..29f51802903 100644
--- a/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
+++ b/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
@@ -28,6 +28,7 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
userId,
sessionId,
subscriptions: [domainBuilder.buildCoreSubscription()],
+ reconciledAt: new Date('2024-10-09'),
};
sessionRepository = {
@@ -90,7 +91,7 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
domainBuilder.buildCertificationCandidateSubscription({
id: certificationCandidateId,
sessionId,
- eligibleSubscription: null,
+ eligibleSubscriptions: [],
nonEligibleSubscription: null,
sessionVersion: 2,
}),
@@ -128,6 +129,7 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
const candidateWithoutComplementaryCertification = domainBuilder.buildCertificationCandidate({
...certificationCandidateData,
complementaryCertification: null,
+ subscriptions: [],
});
certificationCandidateRepository.getWithComplementaryCertification
.withArgs({ id: certificationCandidateId })
@@ -143,7 +145,82 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
centerRepository.getById.withArgs({ id: 777 }).resolves(center);
certificationBadgesService.findStillValidBadgeAcquisitions
- .withArgs({ userId })
+ .withArgs({ userId, limitDate: certificationCandidateData.reconciledAt })
+ .resolves([certifiableBadgeAcquisition]);
+
+ // when
+ const certificationCandidateSubscription = await getCertificationCandidateSubscription({
+ certificationCandidateId,
+ certificationBadgesService,
+ certificationCandidateRepository,
+ centerRepository,
+ sessionRepository,
+ });
+
+ // then
+ expect(certificationCandidateSubscription).to.deep.equal(
+ domainBuilder.buildCertificationCandidateSubscription({
+ id: certificationCandidateId,
+ sessionId,
+ eligibleSubscriptions: [],
+ nonEligibleSubscription: null,
+ sessionVersion: 2,
+ }),
+ );
+ });
+ });
+
+ context('when the candidate is registered and eligible to one complementary certification', function () {
+ it('should return the candidate with one complementary certification', async function () {
+ // given
+ const certificationCandidateId = 123;
+ const userId = 456;
+ const sessionId = 789;
+
+ const complementaryCertification = domainBuilder.buildComplementaryCertification({ key: 'PIX+' });
+
+ const center = domainBuilder.certification.enrolment.buildCenter({
+ habilitations: [
+ domainBuilder.certification.enrolment.buildHabilitation({
+ key: 'PIX+',
+ }),
+ ],
+ });
+
+ const certifiableBadgeAcquisition = domainBuilder.buildCertifiableBadgeAcquisition({
+ badge: domainBuilder.buildBadge({
+ key: 'PIX+_BADGE',
+ isCertifiable: true,
+ }),
+ complementaryCertificationKey: complementaryCertification.key,
+ complementaryCertification,
+ });
+
+ const candidateWithoutComplementaryCertification = domainBuilder.buildCertificationCandidate({
+ ...certificationCandidateData,
+ complementaryCertification,
+ subscriptions: [
+ domainBuilder.certification.enrolment.buildComplementarySubscription({
+ certificationCandidateId,
+ complementaryCertificationId: complementaryCertification.id,
+ }),
+ ],
+ });
+ certificationCandidateRepository.getWithComplementaryCertification
+ .withArgs({ id: certificationCandidateId })
+ .resolves(candidateWithoutComplementaryCertification);
+
+ sessionRepository.get.withArgs({ id: sessionId }).resolves(
+ domainBuilder.certification.enrolment.buildSession({
+ certificationCenterId: 777,
+ version: 2,
+ }),
+ );
+
+ centerRepository.getById.withArgs({ id: 777 }).resolves(center);
+
+ certificationBadgesService.findStillValidBadgeAcquisitions
+ .withArgs({ userId, limitDate: certificationCandidateData.reconciledAt })
.resolves([certifiableBadgeAcquisition]);
// when
@@ -160,12 +237,96 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
domainBuilder.buildCertificationCandidateSubscription({
id: certificationCandidateId,
sessionId,
- eligibleSubscription: null,
+ eligibleSubscriptions: [
+ {
+ label: 'Complementary certification name',
+ type: 'COMPLEMENTARY',
+ },
+ ],
nonEligibleSubscription: null,
sessionVersion: 2,
}),
);
});
});
+
+ context('when the candidate is registered and not eligible to any complementary certification', function () {
+ it('should return the candidate without any complementary certification', async function () {
+ // given
+ const certificationCandidateId = 123;
+ const userId = 456;
+ const sessionId = 789;
+
+ const complementaryCertification = domainBuilder.buildComplementaryCertification({ key: 'PIX+' });
+
+ const center = domainBuilder.certification.enrolment.buildCenter({
+ habilitations: [
+ domainBuilder.certification.enrolment.buildHabilitation({
+ key: 'PIX+',
+ }),
+ ],
+ });
+
+ const certifiableBadgeAcquisition = domainBuilder.buildCertifiableBadgeAcquisition({
+ badge: domainBuilder.buildBadge({
+ key: 'PIX+_BADGE',
+ isCertifiable: true,
+ }),
+ complementaryCertificationKey: 'OTHER PIX+ KEY',
+ complementaryCertification,
+ });
+
+ const candidateWithoutComplementaryCertification = domainBuilder.buildCertificationCandidate({
+ ...certificationCandidateData,
+ complementaryCertification,
+ subscriptions: [
+ domainBuilder.certification.enrolment.buildComplementarySubscription({
+ certificationCandidateId,
+ complementaryCertificationId: complementaryCertification.id,
+ }),
+ ],
+ });
+ certificationCandidateRepository.getWithComplementaryCertification
+ .withArgs({ id: certificationCandidateId })
+ .resolves(candidateWithoutComplementaryCertification);
+
+ sessionRepository.get.withArgs({ id: sessionId }).resolves(
+ domainBuilder.certification.enrolment.buildSession({
+ certificationCenterId: 777,
+ version: 2,
+ }),
+ );
+
+ centerRepository.getById.withArgs({ id: 777 }).resolves(center);
+
+ certificationBadgesService.findStillValidBadgeAcquisitions
+ .withArgs({ userId, limitDate: certificationCandidateData.reconciledAt })
+ .resolves([certifiableBadgeAcquisition]);
+
+ // when
+ const certificationCandidateSubscription = await getCertificationCandidateSubscription({
+ certificationCandidateId,
+ certificationBadgesService,
+ certificationCandidateRepository,
+ centerRepository,
+ sessionRepository,
+ });
+
+ // then
+ expect(certificationCandidateSubscription).to.deep.equal(
+ domainBuilder.buildCertificationCandidateSubscription({
+ id: certificationCandidateId,
+ sessionId,
+ eligibleSubscriptions: [],
+ nonEligibleSubscription: {
+ id: 1,
+ key: 'PIX+',
+ label: 'Complementary certification name',
+ },
+ sessionVersion: 2,
+ }),
+ );
+ });
+ });
});
});
diff --git a/api/tests/tooling/domain-builder/factory/build-certification-candidate-subscription.js b/api/tests/tooling/domain-builder/factory/build-certification-candidate-subscription.js
index f9dc727b191..da34ae59504 100644
--- a/api/tests/tooling/domain-builder/factory/build-certification-candidate-subscription.js
+++ b/api/tests/tooling/domain-builder/factory/build-certification-candidate-subscription.js
@@ -3,14 +3,14 @@ import { CertificationCandidateSubscription } from '../../../../src/certificatio
const buildCertificationCandidateSubscription = function ({
id = 1234,
sessionId = 1234,
- eligibleSubscription = null,
+ eligibleSubscriptions = [],
nonEligibleSubscription = null,
sessionVersion = 2,
} = {}) {
return new CertificationCandidateSubscription({
id,
sessionId,
- eligibleSubscription,
+ eligibleSubscriptions,
nonEligibleSubscription,
sessionVersion,
});
From dcfe3fc1ccdd4ee123bd0fa094b37ad3d1ccfb70 Mon Sep 17 00:00:00 2001
From: P-Jeremy
Date: Thu, 10 Oct 2024 09:43:09 +0200
Subject: [PATCH 07/12] :sparkles: api: serialize new elligibleSubscriptions
---
...ation-candidate-subscription-serializer.js | 2 +-
.../application/subscription-route_test.js | 239 +++++++++++++++++-
...-candidate-subscription-serializer_test.js | 17 +-
3 files changed, 233 insertions(+), 25 deletions(-)
diff --git a/api/src/certification/enrolment/infrastructure/serializers/certification-candidate-subscription-serializer.js b/api/src/certification/enrolment/infrastructure/serializers/certification-candidate-subscription-serializer.js
index fbc06d5e2f4..75ff7b8ba97 100644
--- a/api/src/certification/enrolment/infrastructure/serializers/certification-candidate-subscription-serializer.js
+++ b/api/src/certification/enrolment/infrastructure/serializers/certification-candidate-subscription-serializer.js
@@ -4,7 +4,7 @@ const { Serializer } = jsonapiSerializer;
const serialize = function (certificationCandidateSubscription) {
return new Serializer('certification-candidate-subscription', {
- attributes: ['sessionId', 'eligibleSubscription', 'nonEligibleSubscription', 'sessionVersion'],
+ attributes: ['sessionId', 'eligibleSubscriptions', 'nonEligibleSubscription', 'sessionVersion'],
}).serialize(certificationCandidateSubscription);
};
diff --git a/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js b/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
index 5ae8939e3f1..8b159b231af 100644
--- a/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
+++ b/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
@@ -4,6 +4,8 @@ import {
databaseBuilder,
expect,
generateValidRequestAuthorizationHeader,
+ learningContentBuilder,
+ mockLearningContent,
} from '../../../../test-helper.js';
describe('Certification | Enrolment | Acceptance | Application | Routes | subscription', function () {
@@ -11,29 +13,220 @@ describe('Certification | Enrolment | Acceptance | Application | Routes | subscr
it('should return the certification candidate subscriptions', async function () {
// given
const server = await createServer();
+
+ const learningContent = learningContentBuilder.fromAreas([
+ {
+ id: 'recvoGdo7z2z7pXWa',
+ title_i18n: {
+ fr: 'Information et données',
+ },
+ color: 'jaffa',
+ code: '1',
+ competences: [
+ {
+ id: 'recCompetence1',
+ name_i18n: {
+ fr: 'Mener une recherche et une veille d’information',
+ },
+ index: '1.1',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence1',
+ tubes: [
+ {
+ id: 'recTubeCompetence1',
+ skills: [
+ {
+ id: 'skillId@web3',
+ name: '@web3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence2',
+ name_i18n: {
+ fr: 'Gérer les données',
+ },
+ index: '1.2',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence2',
+ tubes: [
+ {
+ id: 'recTubeCompetence2',
+ skills: [
+ {
+ id: 'skillId@fichier3',
+ name: '@fichier3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence3',
+ name_i18n: {
+ fr: 'Traiter les données',
+ },
+ index: '1.3',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence3',
+ tubes: [
+ {
+ id: 'recTubeCompetence3',
+ skills: [
+ {
+ id: 'skillId@tri3',
+ name: '@tri3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recDH19F7kKrfL3Ii',
+ title_i18n: {
+ fr: 'Communication et collaboration',
+ },
+ color: 'jaffa',
+ code: '1',
+ competences: [
+ {
+ id: 'recCompetence4',
+ name_i18n: {
+ fr: 'Intéragir',
+ },
+ index: '2.1',
+ origin: 'Pix',
+ areaId: 'recDH19F7kKrfL3Ii',
+ thematics: [
+ {
+ id: 'recThemCompetence4',
+ tubes: [
+ {
+ id: 'recTubeCompetence4',
+ skills: [
+ {
+ id: 'skillId@spam3',
+ name: '@spam3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence5',
+ name_i18n: {
+ fr: 'Partager et publier',
+ },
+ index: '2.2',
+ origin: 'Pix',
+ areaId: 'recDH19F7kKrfL3Ii',
+ thematics: [
+ {
+ id: 'recThemCompetence5',
+ tubes: [
+ {
+ id: 'recTubeCompetence5',
+ skills: [
+ {
+ id: 'skillId@vocRS3',
+ name: '@vocRS3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ]);
+ mockLearningContent(learningContent);
+
const userId = databaseBuilder.factory.buildUser().id;
+
+ learningContent.skills.forEach(({ id: skillId, competenceId }) => {
+ databaseBuilder.factory.buildKnowledgeElement({ userId, earnedPix: 10, competenceId, skillId });
+ });
+
+ const targetProfileId = databaseBuilder.factory.buildTargetProfile().id;
+ const badgeId = databaseBuilder.factory.buildBadge({ isCertifiable: true, targetProfileId }).id;
+ const campaignId = databaseBuilder.factory.buildCampaign({
+ targetProfileId,
+ }).id;
+ const campaignParticipationId = databaseBuilder.factory.buildCampaignParticipation({
+ campaignId,
+ isCertifiable: true,
+ userId,
+ }).id;
+
+ learningContent.skills.forEach(({ id: skillId }) => {
+ databaseBuilder.factory.buildCampaignSkill({
+ campaignId,
+ skillId,
+ });
+ });
+
+ databaseBuilder.factory.buildBadgeCriterion({
+ badgeId,
+ threshold: 75,
+ cappedTubes: JSON.stringify(
+ learningContent.tubes.map(({ id }) => ({
+ id,
+ level: 8,
+ })),
+ ),
+ });
+
const certificationCenter = databaseBuilder.factory.buildCertificationCenter();
const cleaComplementaryCertification = databaseBuilder.factory.buildComplementaryCertification({
key: ComplementaryCertificationKeys.CLEA,
label: 'CléA Numérique',
});
- const pixPlusDroitComplementaryCertification = databaseBuilder.factory.buildComplementaryCertification({
- key: ComplementaryCertificationKeys.PIX_PLUS_DROIT,
- label: 'Pix+ Droit',
- });
+
databaseBuilder.factory.buildComplementaryCertificationHabilitation({
certificationCenterId: certificationCenter.id,
complementaryCertificationId: cleaComplementaryCertification.id,
});
- databaseBuilder.factory.buildComplementaryCertificationHabilitation({
- certificationCenterId: certificationCenter.id,
- complementaryCertificationId: pixPlusDroitComplementaryCertification.id,
- });
+
const session = databaseBuilder.factory.buildSession({
certificationCenterId: certificationCenter.id,
});
+
const candidate = databaseBuilder.factory.buildCertificationCandidate({
sessionId: session.id,
+ userId,
+ reconciledAt: new Date('2021-01-01'),
});
databaseBuilder.factory.buildCoreSubscription({ certificationCandidateId: candidate.id });
@@ -42,6 +235,19 @@ describe('Certification | Enrolment | Acceptance | Application | Routes | subscr
certificationCandidateId: candidate.id,
complementaryCertificationId: cleaComplementaryCertification.id,
});
+
+ databaseBuilder.factory.buildComplementaryCertificationBadge({
+ badgeId,
+ complementaryCertificationId: cleaComplementaryCertification.id,
+ });
+
+ databaseBuilder.factory.buildBadgeAcquisition({
+ userId,
+ badgeId,
+ campaignParticipationId,
+ createdAt: new Date('2020-01-01'),
+ });
+
await databaseBuilder.commit();
const options = {
@@ -61,12 +267,17 @@ describe('Certification | Enrolment | Acceptance | Application | Routes | subscr
attributes: {
'session-id': session.id,
'session-version': session.version,
- 'eligible-subscription': null,
- 'non-eligible-subscription': {
- id: cleaComplementaryCertification.id,
- label: 'CléA Numérique',
- key: ComplementaryCertificationKeys.CLEA,
- },
+ 'eligible-subscriptions': [
+ {
+ label: null,
+ type: 'CORE',
+ },
+ {
+ label: 'CléA Numérique',
+ type: 'COMPLEMENTARY',
+ },
+ ],
+ 'non-eligible-subscription': null,
},
});
});
diff --git a/api/tests/certification/enrolment/unit/infrastructure/serializers/certification-candidate-subscription-serializer_test.js b/api/tests/certification/enrolment/unit/infrastructure/serializers/certification-candidate-subscription-serializer_test.js
index 270575275b1..11809c5ab78 100644
--- a/api/tests/certification/enrolment/unit/infrastructure/serializers/certification-candidate-subscription-serializer_test.js
+++ b/api/tests/certification/enrolment/unit/infrastructure/serializers/certification-candidate-subscription-serializer_test.js
@@ -7,12 +7,8 @@ describe('Certification | Enrolment | Unit | Serializer | certification-candidat
const certificationCandidateSubscription = domainBuilder.buildCertificationCandidateSubscription({
id: 123,
sessionId: 456,
- eligibleSubscription: domainBuilder.buildComplementaryCertification({
- key: 'FIRST_COMPLEMENTARY',
- label: 'First Complementary Certification',
- }),
+ eligibleSubscriptions: [{ type: 'COMPLEMENTARY', label: 'First Complementary Certification' }],
sessionVersion: 2,
-
nonEligibleSubscription: domainBuilder.buildComplementaryCertification({
key: 'SECOND_COMPLEMENTARY',
label: 'Second Complementary Certification',
@@ -24,11 +20,12 @@ describe('Certification | Enrolment | Unit | Serializer | certification-candidat
id: '123',
type: 'certification-candidate-subscriptions',
attributes: {
- 'eligible-subscription': {
- id: 1,
- key: 'FIRST_COMPLEMENTARY',
- label: 'First Complementary Certification',
- },
+ 'eligible-subscriptions': [
+ {
+ type: 'COMPLEMENTARY',
+ label: 'First Complementary Certification',
+ },
+ ],
'non-eligible-subscription': {
id: 1,
key: 'SECOND_COMPLEMENTARY',
From 5c9e7bc9c8221d1999636faab311471044cd1679 Mon Sep 17 00:00:00 2001
From: Guillaume Lagorce
Date: Thu, 10 Oct 2024 14:10:59 +0200
Subject: [PATCH 08/12] chore(mon-pix): group redundant tests
Co-authored-by:
Co-authored-by:
---
.../components/certification-starter-test.js | 39 -------------------
1 file changed, 39 deletions(-)
diff --git a/mon-pix/tests/integration/components/certification-starter-test.js b/mon-pix/tests/integration/components/certification-starter-test.js
index 831756114f5..bfdda5322c8 100644
--- a/mon-pix/tests/integration/components/certification-starter-test.js
+++ b/mon-pix/tests/integration/components/certification-starter-test.js
@@ -154,25 +154,6 @@ module('Integration | Component | certification-starter', function (hooks) {
),
);
assert.ok(screen.getByText('Certif complémentaire 1'));
- });
-
- test('should not display subscription non eligible panel', async function (assert) {
- // given
- const store = this.owner.lookup('service:store');
- this.set(
- 'certificationCandidateSubscription',
- store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: [{ label: 'Certif complémentaire 1', type: 'COMPLEMENTARY' }],
- nonEligibleSubscription: null,
- }),
- );
-
- // when
- const screen = await render(
- hbs``,
- );
-
- // then
assert.notOk(screen.queryByText('Vous n’êtes pas éligible à'));
});
});
@@ -201,26 +182,6 @@ module('Integration | Component | certification-starter', function (hooks) {
"Vous n'êtes pas éligible à Certif complémentaire 1. Vous pouvez néanmoins passer votre certification Pix.",
),
);
- });
-
- test('should not display subscription eligible panel', async function (assert) {
- // given
- const store = this.owner.lookup('service:store');
- this.set(
- 'certificationCandidateSubscription',
- store.createRecord('certification-candidate-subscription', {
- eligibleSubscriptions: null,
- nonEligibleSubscription: { label: 'Certif complémentaire 1' },
- sessionVersion: 2,
- }),
- );
-
- // when
- const screen = await render(
- hbs``,
- );
-
- // then
assert.notOk(
screen.queryByText(
'Vous êtes inscrit aux certifications complémentaires suivantes en plus de la certification Pix :',
From 79c1a245d8002f0ce682659ccff25c91acc73780 Mon Sep 17 00:00:00 2001
From: Guillaume Lagorce
Date: Thu, 10 Oct 2024 14:15:30 +0200
Subject: [PATCH 09/12] refactor(subscription): move building learning content
in private function
Co-authored-by:
Co-authored-by:
---
.../application/subscription-route_test.js | 318 +++++++++---------
1 file changed, 161 insertions(+), 157 deletions(-)
diff --git a/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js b/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
index 8b159b231af..934d81221eb 100644
--- a/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
+++ b/api/tests/certification/enrolment/acceptance/application/subscription-route_test.js
@@ -14,163 +14,7 @@ describe('Certification | Enrolment | Acceptance | Application | Routes | subscr
// given
const server = await createServer();
- const learningContent = learningContentBuilder.fromAreas([
- {
- id: 'recvoGdo7z2z7pXWa',
- title_i18n: {
- fr: 'Information et données',
- },
- color: 'jaffa',
- code: '1',
- competences: [
- {
- id: 'recCompetence1',
- name_i18n: {
- fr: 'Mener une recherche et une veille d’information',
- },
- index: '1.1',
- origin: 'Pix',
- areaId: 'recvoGdo7z2z7pXWa',
- thematics: [
- {
- id: 'recThemCompetence1',
- tubes: [
- {
- id: 'recTubeCompetence1',
- skills: [
- {
- id: 'skillId@web3',
- name: '@web3',
- status: 'actif',
- level: 3,
- },
- ],
- },
- ],
- },
- ],
- },
- {
- id: 'recCompetence2',
- name_i18n: {
- fr: 'Gérer les données',
- },
- index: '1.2',
- origin: 'Pix',
- areaId: 'recvoGdo7z2z7pXWa',
- thematics: [
- {
- id: 'recThemCompetence2',
- tubes: [
- {
- id: 'recTubeCompetence2',
- skills: [
- {
- id: 'skillId@fichier3',
- name: '@fichier3',
- status: 'actif',
- level: 3,
- },
- ],
- },
- ],
- },
- ],
- },
- {
- id: 'recCompetence3',
- name_i18n: {
- fr: 'Traiter les données',
- },
- index: '1.3',
- origin: 'Pix',
- areaId: 'recvoGdo7z2z7pXWa',
- thematics: [
- {
- id: 'recThemCompetence3',
- tubes: [
- {
- id: 'recTubeCompetence3',
- skills: [
- {
- id: 'skillId@tri3',
- name: '@tri3',
- status: 'actif',
- level: 3,
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
- {
- id: 'recDH19F7kKrfL3Ii',
- title_i18n: {
- fr: 'Communication et collaboration',
- },
- color: 'jaffa',
- code: '1',
- competences: [
- {
- id: 'recCompetence4',
- name_i18n: {
- fr: 'Intéragir',
- },
- index: '2.1',
- origin: 'Pix',
- areaId: 'recDH19F7kKrfL3Ii',
- thematics: [
- {
- id: 'recThemCompetence4',
- tubes: [
- {
- id: 'recTubeCompetence4',
- skills: [
- {
- id: 'skillId@spam3',
- name: '@spam3',
- status: 'actif',
- level: 3,
- },
- ],
- },
- ],
- },
- ],
- },
- {
- id: 'recCompetence5',
- name_i18n: {
- fr: 'Partager et publier',
- },
- index: '2.2',
- origin: 'Pix',
- areaId: 'recDH19F7kKrfL3Ii',
- thematics: [
- {
- id: 'recThemCompetence5',
- tubes: [
- {
- id: 'recTubeCompetence5',
- skills: [
- {
- id: 'skillId@vocRS3',
- name: '@vocRS3',
- status: 'actif',
- level: 3,
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
- ]);
+ const learningContent = _buildLearningContent();
mockLearningContent(learningContent);
const userId = databaseBuilder.factory.buildUser().id;
@@ -283,3 +127,163 @@ describe('Certification | Enrolment | Acceptance | Application | Routes | subscr
});
});
});
+
+function _buildLearningContent() {
+ return learningContentBuilder.fromAreas([
+ {
+ id: 'recvoGdo7z2z7pXWa',
+ title_i18n: {
+ fr: 'Information et données',
+ },
+ color: 'jaffa',
+ code: '1',
+ competences: [
+ {
+ id: 'recCompetence1',
+ name_i18n: {
+ fr: 'Mener une recherche et une veille d’information',
+ },
+ index: '1.1',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence1',
+ tubes: [
+ {
+ id: 'recTubeCompetence1',
+ skills: [
+ {
+ id: 'skillId@web3',
+ name: '@web3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence2',
+ name_i18n: {
+ fr: 'Gérer les données',
+ },
+ index: '1.2',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence2',
+ tubes: [
+ {
+ id: 'recTubeCompetence2',
+ skills: [
+ {
+ id: 'skillId@fichier3',
+ name: '@fichier3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence3',
+ name_i18n: {
+ fr: 'Traiter les données',
+ },
+ index: '1.3',
+ origin: 'Pix',
+ areaId: 'recvoGdo7z2z7pXWa',
+ thematics: [
+ {
+ id: 'recThemCompetence3',
+ tubes: [
+ {
+ id: 'recTubeCompetence3',
+ skills: [
+ {
+ id: 'skillId@tri3',
+ name: '@tri3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recDH19F7kKrfL3Ii',
+ title_i18n: {
+ fr: 'Communication et collaboration',
+ },
+ color: 'jaffa',
+ code: '1',
+ competences: [
+ {
+ id: 'recCompetence4',
+ name_i18n: {
+ fr: 'Intéragir',
+ },
+ index: '2.1',
+ origin: 'Pix',
+ areaId: 'recDH19F7kKrfL3Ii',
+ thematics: [
+ {
+ id: 'recThemCompetence4',
+ tubes: [
+ {
+ id: 'recTubeCompetence4',
+ skills: [
+ {
+ id: 'skillId@spam3',
+ name: '@spam3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'recCompetence5',
+ name_i18n: {
+ fr: 'Partager et publier',
+ },
+ index: '2.2',
+ origin: 'Pix',
+ areaId: 'recDH19F7kKrfL3Ii',
+ thematics: [
+ {
+ id: 'recThemCompetence5',
+ tubes: [
+ {
+ id: 'recTubeCompetence5',
+ skills: [
+ {
+ id: 'skillId@vocRS3',
+ name: '@vocRS3',
+ status: 'actif',
+ level: 3,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ]);
+}
From 2438e932e90a4da92508f1e822c6f142a4e975f1 Mon Sep 17 00:00:00 2001
From: Guillaume Lagorce
Date: Thu, 10 Oct 2024 14:19:22 +0200
Subject: [PATCH 10/12] refactor(subscription): remove redundant test setup
Co-authored-by:
Co-authored-by:
---
.../get-certification-candidate-subscription_test.js | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js b/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
index 29f51802903..355add84aa3 100644
--- a/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
+++ b/api/tests/certification/enrolment/unit/domain/usecases/get-certification-candidate-subscription_test.js
@@ -104,10 +104,6 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
context('when the candidate is not registered but eligible to one complementary certification', function () {
it('should return the candidate without any complementary certification', async function () {
// given
- const certificationCandidateId = 123;
- const userId = 456;
- const sessionId = 789;
-
const complementaryCertification = domainBuilder.buildComplementaryCertification({ key: 'PIX+' });
const center = domainBuilder.certification.enrolment.buildCenter({
@@ -173,10 +169,6 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
context('when the candidate is registered and eligible to one complementary certification', function () {
it('should return the candidate with one complementary certification', async function () {
// given
- const certificationCandidateId = 123;
- const userId = 456;
- const sessionId = 789;
-
const complementaryCertification = domainBuilder.buildComplementaryCertification({ key: 'PIX+' });
const center = domainBuilder.certification.enrolment.buildCenter({
@@ -253,10 +245,6 @@ describe('Certification | Enrolment | Unit | Domain | UseCase | get-certificatio
context('when the candidate is registered and not eligible to any complementary certification', function () {
it('should return the candidate without any complementary certification', async function () {
// given
- const certificationCandidateId = 123;
- const userId = 456;
- const sessionId = 789;
-
const complementaryCertification = domainBuilder.buildComplementaryCertification({ key: 'PIX+' });
const center = domainBuilder.certification.enrolment.buildCenter({
From d8d449faf5b4287e6739adb88f2c9d6cc7ca0456 Mon Sep 17 00:00:00 2001
From: Guillaume Lagorce
Date: Thu, 10 Oct 2024 14:29:51 +0200
Subject: [PATCH 11/12] refactor(mon-pix): clarify eligibility display in
certification-starter
Co-authored-by:
Co-authored-by:
---
mon-pix/app/components/certification-starter.js | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/mon-pix/app/components/certification-starter.js b/mon-pix/app/components/certification-starter.js
index 0343ee12e11..81b69bc6c20 100644
--- a/mon-pix/app/components/certification-starter.js
+++ b/mon-pix/app/components/certification-starter.js
@@ -28,14 +28,12 @@ export default class CertificationStarter extends Component {
}
get subscriptionTitle() {
- if (
- !this.args.certificationCandidateSubscription.isSessionVersion3 ||
- this.args.certificationCandidateSubscription.isV3CoreAndComplementary
- ) {
- return this.intl.t('pages.certification-start.core-and-complementary-subscriptions');
- } else {
- return this.intl.t('pages.certification-start.complementary-subscription');
- }
+ const { isSessionVersion3, isV3CoreAndComplementary } = this.args.certificationCandidateSubscription;
+
+ const complementaryAlone = isSessionVersion3 && !isV3CoreAndComplementary;
+ const intlSuffix = complementaryAlone ? 'complementary-subscription' : 'core-and-complementary-subscriptions';
+
+ return this.intl.t(`pages.certification-start.${intlSuffix}`);
}
@action
From 74cc40a6838a76e0c0e202493ee0815cc0f875b8 Mon Sep 17 00:00:00 2001
From: Guillaume Lagorce
Date: Thu, 10 Oct 2024 14:33:38 +0200
Subject: [PATCH 12/12] refactor(mon-pix): remove extra check when defining
isV3CoreAndComplementary
Co-authored-by:
Co-authored-by:
Co-authored-by:
---
mon-pix/app/models/certification-candidate-subscription.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/mon-pix/app/models/certification-candidate-subscription.js b/mon-pix/app/models/certification-candidate-subscription.js
index fcca1aceb1c..2af4f75eb8f 100644
--- a/mon-pix/app/models/certification-candidate-subscription.js
+++ b/mon-pix/app/models/certification-candidate-subscription.js
@@ -23,7 +23,6 @@ export default class CertificationCandidateSubscription extends Model {
get isV3CoreAndComplementary() {
return (
this.isSessionVersion3 &&
- this.eligibleSubscriptions.length === 2 &&
this.eligibleSubscriptions.some((eligibleSubscription) => eligibleSubscription.type === 'CORE') &&
this.eligibleSubscriptions.some((eligibleSubscription) => eligibleSubscription.type === 'COMPLEMENTARY')
);