Skip to content

Commit b59efa7

Browse files
[FEATURE] Ajout d'un lien vers les explications de résultats sur le Certificat Pix (PIX-16247).
#11250
2 parents 55e7f71 + db86cd0 commit b59efa7

File tree

9 files changed

+158
-2
lines changed

9 files changed

+158
-2
lines changed

mon-pix/app/components/user-certifications-detail-header.hbs

+10
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@
3737
{{t "pages.certificate.professionalizing-warning"}}</p>
3838
{{/if}}
3939

40+
{{#if this.displayCertificationResultsExplanation}}
41+
<PixButtonLink
42+
@href={{this.certificationResultsExplanationUrl}}
43+
target="_blank"
44+
rel="noopener noreferrer"
45+
@variant="tertiary"
46+
@iconAfter="openNew"
47+
> {{t "pages.certificate.learn-about-certification-results"}}</PixButtonLink>
48+
{{/if}}
49+
4050
</div>
4151
</div>
4252
{{#if @certification.verificationCode}}

mon-pix/app/components/user-certifications-detail-header.js

+14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export default class UserCertificationsDetailHeader extends Component {
1010
@service fileSaver;
1111
@service session;
1212
@service currentDomain;
13+
@service currentUser;
14+
@service url;
1315

1416
@tracked tooltipText = this.intl.t('pages.certificate.verification-code.copy');
1517
@tracked attestationDownloadErrorMessage = null;
@@ -18,6 +20,18 @@ export default class UserCertificationsDetailHeader extends Component {
1820
return parseISODateOnly(this.args.certification.birthdate);
1921
}
2022

23+
get isUserFrenchReader() {
24+
return this.currentUser.user && this.currentUser.user.lang === 'fr';
25+
}
26+
27+
get displayCertificationResultsExplanation() {
28+
return this.args.certification.isV3 && (this.currentDomain.isFranceDomain || this.isUserFrenchReader);
29+
}
30+
31+
get certificationResultsExplanationUrl() {
32+
return this.url.certificationResultsExplanationUrl;
33+
}
34+
2135
@action
2236
clipboardSuccess() {
2337
this.tooltipText = this.intl.t('pages.certificate.verification-code.copied');

mon-pix/app/models/certification.js

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ export default class Certification extends Model {
5050
);
5151
}
5252

53+
get isV3() {
54+
return this.version === 3;
55+
}
56+
5357
get maxReachablePixCountOnCertificationDate() {
5458
return this.maxReachableLevelOnCertificationDate * 8 * 16;
5559
}

mon-pix/app/services/url.js

+8
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ export default class Url extends Service {
132132
return `https://status.pix.org/?locale=${currentLanguage}`;
133133
}
134134

135+
get certificationResultsExplanationUrl() {
136+
if (this.currentDomain.isFranceDomain) {
137+
return 'https://pix.fr/certification-comprendre-score-niveau';
138+
}
139+
140+
return 'https://pix.org/fr/certification-comprendre-score-niveau';
141+
}
142+
135143
get _showcaseWebsiteUrl() {
136144
const currentLanguage = this.intl.primaryLocale;
137145

mon-pix/tests/helpers/service-stubs.js

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export function stubSessionService(owner, sessionData = {}) {
6767
* @param {string} [userData.firstName='John'] - The first name of the user.
6868
* @param {string} [userData.lastName='Doe'] - The last name of the user.
6969
* @param {string} [userData.email] - The email of the user.
70+
* @param {string} [userData.lang] - The language of the user.
7071
* @param {Object} [userData.profile] - The profile of the user.
7172
* @param {boolean} [userData.mustValidateTermsOfService=false] - Indicates if the user must validate terms of service.
7273
* @param {boolean} [userData.hasRecommendedTrainings=false] - Indicates if the user has recommended trainings.
@@ -85,6 +86,7 @@ export function stubCurrentUserService(owner, userData = {}, { withStoreStubbed
8586
const firstName = userData.firstName || 'John';
8687
const lastName = userData.lastName || 'Doe';
8788
const fullName = `${firstName} ${lastName}`;
89+
const lang = userData.lang || 'fr';
8890
const email = userData.email || `${firstName.toLowerCase()}.${lastName.toLowerCase()}@example.net`;
8991
const codeForLastProfileToShare = userData.codeForLastProfileToShare || null;
9092
const mustValidateTermsOfService = userData.mustValidateTermsOfService || false;
@@ -123,6 +125,7 @@ export function stubCurrentUserService(owner, userData = {}, { withStoreStubbed
123125
firstName,
124126
lastName,
125127
fullName,
128+
lang,
126129
profile,
127130
codeForLastProfileToShare,
128131
mustValidateTermsOfService,

mon-pix/tests/integration/components/user-certifications-detail-header-test.js

+85-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { render as renderScreen } from '@1024pix/ember-testing-library';
22
import Service from '@ember/service';
33
import { click } from '@ember/test-helpers';
44
import { hbs } from 'ember-cli-htmlbars';
5+
import { t } from 'ember-intl/test-support';
56
import { module, test } from 'qunit';
67
import sinon from 'sinon';
78

9+
import { stubCurrentUserService } from '../../helpers/service-stubs';
810
import setupIntlRenderingTest from '../../helpers/setup-intl-rendering';
911

1012
module('Integration | Component | user certifications detail header', function (hooks) {
@@ -16,6 +18,7 @@ module('Integration | Component | user certifications detail header', function (
1618

1719
hooks.beforeEach(async function () {
1820
// given
21+
stubCurrentUserService(this.owner);
1922
store = this.owner.lookup('service:store');
2023
certification = store.createRecord('certification', {
2124
id: '1',
@@ -92,6 +95,7 @@ module('Integration | Component | user certifications detail header', function (
9295

9396
module('when domain is french', function (hooks) {
9497
hooks.beforeEach(function () {
98+
stubCurrentUserService(this.owner, { lang: 'fr' });
9599
class CurrentDomainServiceStub extends Service {
96100
get isFranceDomain() {
97101
return true;
@@ -136,7 +140,7 @@ module('Integration | Component | user certifications detail header', function (
136140
});
137141
});
138142

139-
module('when certification is delivered before 2022-01-01', function () {
143+
module('when certification is v2 and delivered before 2022-01-01', function () {
140144
test('should not display the professionalizing warning', async function (assert) {
141145
// given
142146
const store = this.owner.lookup('service:store');
@@ -246,9 +250,35 @@ module('Integration | Component | user certifications detail header', function (
246250
});
247251
assert.ok(true);
248252
});
253+
254+
test('should display a link to the results explanation', async function (assert) {
255+
// given
256+
stubCurrentUserService(this.owner, { lang: 'en' });
257+
const store = this.owner.lookup('service:store');
258+
const certification = store.createRecord('certification', {
259+
birthdate: '2000-01-22',
260+
date: new Date('2018-02-15T15:15:52Z'),
261+
isPublished: true,
262+
status: 'validated',
263+
version: 3,
264+
});
265+
this.set('certification', certification);
266+
267+
// when
268+
const screen = await renderScreen(hbs`<UserCertificationsDetailHeader @certification={{this.certification}} />`);
269+
270+
// then
271+
assert
272+
.dom(screen.getByRole('link', { name: t('pages.certificate.learn-about-certification-results') }))
273+
.hasAttribute('href', 'https://pix.fr/certification-comprendre-score-niveau');
274+
});
249275
});
250276

251-
module('when domain is not french', function () {
277+
module('when domain is not french', function (hooks) {
278+
hooks.beforeEach(function () {
279+
stubCurrentUserService(this.owner, { lang: 'en' });
280+
});
281+
252282
test('should not display the professionalizing warning', async function (assert) {
253283
// given
254284
class CurrentDomainServiceStub extends Service {
@@ -327,11 +357,64 @@ module('Integration | Component | user certifications detail header', function (
327357
});
328358
assert.ok(true);
329359
});
360+
361+
module('when user is a French reader', function () {
362+
test('should display a link to the results explanation', async function (assert) {
363+
// given
364+
stubCurrentUserService(this.owner, { lang: 'fr' });
365+
366+
const store = this.owner.lookup('service:store');
367+
const certification = store.createRecord('certification', {
368+
birthdate: '2000-01-22',
369+
date: new Date('2018-02-15T15:15:52Z'),
370+
isPublished: true,
371+
status: 'validated',
372+
version: 3,
373+
});
374+
this.set('certification', certification);
375+
376+
// when
377+
const screen = await renderScreen(
378+
hbs`<UserCertificationsDetailHeader @certification={{this.certification}} />`,
379+
);
380+
381+
// then
382+
assert
383+
.dom(screen.getByRole('link', { name: t('pages.certificate.learn-about-certification-results') }))
384+
.hasAttribute('href', 'https://pix.org/fr/certification-comprendre-score-niveau');
385+
});
386+
});
387+
388+
module('when user is not a French reader', function () {
389+
test('should not display a link to the results explanation', async function (assert) {
390+
// given
391+
stubCurrentUserService(this.owner, { lang: 'en' });
392+
const store = this.owner.lookup('service:store');
393+
const certification = store.createRecord('certification', {
394+
birthdate: '2000-01-22',
395+
date: new Date('2018-02-15T15:15:52Z'),
396+
isPublished: true,
397+
status: 'validated',
398+
});
399+
this.set('certification', certification);
400+
401+
// when
402+
const screen = await renderScreen(
403+
hbs`<UserCertificationsDetailHeader @certification={{this.certification}} />`,
404+
);
405+
406+
// then
407+
assert
408+
.dom(screen.queryByRole('link', { name: t('pages.certificate.learn-about-certification-results') }))
409+
.doesNotExist();
410+
});
411+
});
330412
});
331413

332414
module('when there is an error during the download of the attestation', function () {
333415
test('should show the common error message', async function (assert) {
334416
// given
417+
stubCurrentUserService(this.owner);
335418
const fileSaverSaveStub = sinon.stub();
336419

337420
class FileSaverStub extends Service {

mon-pix/tests/unit/services/url-test.js

+32
Original file line numberDiff line numberDiff line change
@@ -507,4 +507,36 @@ module('Unit | Service | url', function (hooks) {
507507
});
508508
});
509509
});
510+
511+
module('#certificationResultsExplanationUrl', function () {
512+
module('when domain extension is .fr', function () {
513+
test('returns the pix.fr website certification details page', function (assert) {
514+
// given
515+
const service = this.owner.lookup('service:url');
516+
service.currentDomain = { isFranceDomain: true };
517+
const expectedCertificationResultsExplanationUrl = 'https://pix.fr/certification-comprendre-score-niveau';
518+
519+
// when
520+
const certificationResultsExplanationUrl = service.certificationResultsExplanationUrl;
521+
522+
// then
523+
assert.strictEqual(certificationResultsExplanationUrl, expectedCertificationResultsExplanationUrl);
524+
});
525+
});
526+
527+
module('when domain extension is .org', function () {
528+
test('returns the pix.org website certification details page', function (assert) {
529+
// given
530+
const service = this.owner.lookup('service:url');
531+
service.currentDomain = { isFranceDomain: false };
532+
const expectedCertificationResultsExplanationUrl = 'https://pix.org/fr/certification-comprendre-score-niveau';
533+
534+
// when
535+
const certificationResultsExplanationUrl = service.certificationResultsExplanationUrl;
536+
537+
// then
538+
assert.strictEqual(certificationResultsExplanationUrl, expectedCertificationResultsExplanationUrl);
539+
});
540+
});
541+
});
510542
});

mon-pix/translations/en.json

+1
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@
599599
"issued-on": "Delivered on",
600600
"jury-info": "Notes from the examining body are not displayed on the verification page of your certificate.",
601601
"jury-title": "Notes from the examining body",
602+
"learn-about-certification-results": "Learn more about my Pix Certification results",
602603
"professionalizing-warning": "The Pix certificate is recognised as professionalising by France Compétences upon reaching a minimum score of 120 pix.",
603604
"title": "Pix Certificate",
604605
"verification-code": {

mon-pix/translations/fr.json

+1
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@
599599
"issued-on": "Délivré le",
600600
"jury-info": "Les observations du jury ne sont pas partagées sur la page de vérification de votre certificat.",
601601
"jury-title": "Observations du jury",
602+
"learn-about-certification-results": "Comprendre mes résultats de Certification Pix",
602603
"professionalizing-warning": "Le certificat Pix est reconnu comme professionnalisant par France compétences à compter d’un score minimal de 120 pix",
603604
"title": "Certificat Pix",
604605
"verification-code": {

0 commit comments

Comments
 (0)