From d84fd089a4293f6477833e2f05ec652d16adce20 Mon Sep 17 00:00:00 2001 From: AndreiaPena Date: Mon, 4 Nov 2024 16:43:48 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20certif:=20temporarily=20block=20the?= =?UTF-8?q?=20finalization=20button=20when=20the=20session=20is=20v3=20and?= =?UTF-8?q?=20a=20certification=20candidate=20has=20complementary=20subscr?= =?UTF-8?q?iption=20(only=20one)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sessions/details/parameters.js | 7 ++ certif/app/models/certification-candidate.js | 6 ++ certif/app/models/subscription.js | 4 + .../sessions/details/parameters.hbs | 16 ++-- .../session-details-parameters-test.js | 59 +++++++++++++++ .../models/certification-candidate-test.js | 74 +++++++++++++++++++ certif/tests/unit/models/subscription-test.js | 43 +++++++++++ certif/translations/en.json | 3 + certif/translations/fr.json | 3 + 9 files changed, 210 insertions(+), 5 deletions(-) diff --git a/certif/app/controllers/authenticated/sessions/details/parameters.js b/certif/app/controllers/authenticated/sessions/details/parameters.js index 9458f8d1ae1..7af9f040e48 100644 --- a/certif/app/controllers/authenticated/sessions/details/parameters.js +++ b/certif/app/controllers/authenticated/sessions/details/parameters.js @@ -19,6 +19,13 @@ export default class SessionParametersController extends Controller { return this.certificationCandidates.some(({ isLinked }) => isLinked); } + get isSessionFinalizationTemporarilyBlocked() { + return ( + this.certificationCandidates.some((candidate) => candidate.hasOnlyComplementarySubscription) && + this.sessionManagement.version === 3 + ); + } + @action async showSessionIdTooltip() { await navigator.clipboard.writeText(this.session.id); diff --git a/certif/app/models/certification-candidate.js b/certif/app/models/certification-candidate.js index 1fa637571c6..bc914a5afe1 100644 --- a/certif/app/models/certification-candidate.js +++ b/certif/app/models/certification-candidate.js @@ -58,4 +58,10 @@ export default class CertificationCandidate extends Model { const hasCleaSubscription = this.subscriptions.some((sub) => sub.isClea(centerHabilitations)); return hasCoreSubscription && hasCleaSubscription; } + + get hasOnlyComplementarySubscription() { + const hasCoreSubscription = this.subscriptions.some((sub) => sub.isCore); + const hasComplementarySubscription = this.subscriptions.some((sub) => sub.isComplementary); + return !hasCoreSubscription && hasComplementarySubscription; + } } diff --git a/certif/app/models/subscription.js b/certif/app/models/subscription.js index 92a556a044f..0670a79d6d9 100644 --- a/certif/app/models/subscription.js +++ b/certif/app/models/subscription.js @@ -17,6 +17,10 @@ export default class SubscriptionModel extends Model { return this.type === SUBSCRIPTION_TYPES.CORE; } + get isComplementary() { + return this.type === SUBSCRIPTION_TYPES.COMPLEMENTARY; + } + isClea(centerHabilitations) { const matchingHabilitation = centerHabilitations.find( (habilitation) => habilitation.id === this.complementaryCertificationId, diff --git a/certif/app/templates/authenticated/sessions/details/parameters.hbs b/certif/app/templates/authenticated/sessions/details/parameters.hbs index 2cfe2bf28e1..a9fcb481083 100644 --- a/certif/app/templates/authenticated/sessions/details/parameters.hbs +++ b/certif/app/templates/authenticated/sessions/details/parameters.hbs @@ -129,14 +129,20 @@ {{t "common.actions.update"}} {{#if this.sessionHasStarted}} - {{#if this.sessionManagement.isFinalized}} + {{#if this.isSessionFinalizationTemporarilyBlocked}}

- {{t "pages.sessions.detail.parameters.finalization-info"}} + {{t "pages.sessions.detail.parameters.finalization.temporarily-blocked"}}

{{else}} - - {{t "pages.sessions.detail.parameters.actions.finalizing"}} - + {{#if this.sessionManagement.isFinalized}} +

+ {{t "pages.sessions.detail.parameters.finalization-info"}} +

+ {{else}} + + {{t "pages.sessions.detail.parameters.actions.finalizing"}} + + {{/if}} {{/if}} {{/if}} diff --git a/certif/tests/acceptance/session-details-parameters-test.js b/certif/tests/acceptance/session-details-parameters-test.js index b7977fd0c90..b510adcf49e 100644 --- a/certif/tests/acceptance/session-details-parameters-test.js +++ b/certif/tests/acceptance/session-details-parameters-test.js @@ -4,6 +4,7 @@ import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { setupIntl } from 'ember-intl/test-support'; import { setupApplicationTest } from 'ember-qunit'; import { CREATED, FINALIZED } from 'pix-certif/models/session-management'; +import { SUBSCRIPTION_TYPES } from 'pix-certif/models/subscription'; import { module, test } from 'qunit'; import { authenticateSession } from '../helpers/test-init'; @@ -85,6 +86,64 @@ module('Acceptance | Session Details Parameters', function (hooks) { .exists(); }); + module('when the session version is 3 and candidates have been enrolled for a complementary course', function () { + test('it should temporarily block the finalise button', async function (assert) { + // given + const allowedCertificationCenterAccess = server.create('allowed-certification-center-access', { + isAccessBlockedCollege: false, + isAccessBlockedLycee: false, + isAccessBlockedAEFE: false, + isAccessBlockedAgri: false, + isV3Pilot: true, + habilitations: [ + { + id: 123, + label: 'Pix+Droit', + }, + ], + }); + certificationPointOfContact = server.create('certification-point-of-contact', { + firstName: 'Buffy', + lastName: 'Summers', + allowedCertificationCenterAccesses: [allowedCertificationCenterAccess], + pixCertifTermsOfServiceAccepted: true, + }); + await authenticateSession(certificationPointOfContact.id); + const sessionCreated = server.create('session-enrolment', { + id: 123, + status: CREATED, + certificationCenterId: allowedCertificationCenterAccess.id, + }); + const complementarySubscription = server.create('subscription', { + type: SUBSCRIPTION_TYPES.COMPLEMENTARY, + complementaryCertificationId: 123, + }); + server.create('certification-candidate', { + isLinked: true, + subscriptions: [complementarySubscription], + sessionId: sessionCreated.id, + }); + server.create('session-management', { + id: sessionCreated.id, + status: CREATED, + version: 3, + }); + + // when + const screen = await visit(`/sessions/${sessionCreated.id}`); + + // then + assert.dom(screen.queryByRole('button', { name: 'Finaliser la session' })).doesNotExist(); + assert + .dom( + screen.getByText( + 'Cette session ne peut pas être finalisée pour le moment. Les équipes de Pix travaillent au déblocage de la finalisation.', + ), + ) + .exists(); + }); + }); + module('when the session is not finalized', function () { module('when the session is CREATED', function () { test('it should not display the finalize button if no candidate has joined the session', async function (assert) { diff --git a/certif/tests/unit/models/certification-candidate-test.js b/certif/tests/unit/models/certification-candidate-test.js index 958ad238c3a..1236d50b61e 100644 --- a/certif/tests/unit/models/certification-candidate-test.js +++ b/certif/tests/unit/models/certification-candidate-test.js @@ -222,6 +222,80 @@ module('Unit | Model | certification-candidate', function (hooks) { }); }); + module('#get hasOnlyComplementarySubscription', function () { + module('when candidate has only one complementary subscription', function () { + test('should return true', function (assert) { + // given + // when + const store = this.owner.lookup('service:store'); + const habilitations = [ + { + id: 123, + label: 'Certif Pix+Droit', + key: 'DROIT', + }, + ]; + const complementarySubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.COMPLEMENTARY, + complementaryCertificationId: habilitations[0].id, + }); + const candidate = store.createRecord('certification-candidate', { + subscriptions: [complementarySubscription], + }); + + // then + assert.true(candidate.hasOnlyComplementarySubscription); + }); + }); + + module('when candidate has a core subscription', function () { + test('should return false', function (assert) { + // given + // when + const store = this.owner.lookup('service:store'); + const coreSubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.CORE, + complementaryCertificationId: null, + }); + const candidate = store.createRecord('certification-candidate', { + subscriptions: [coreSubscription], + }); + + // then + assert.false(candidate.hasOnlyComplementarySubscription); + }); + }); + + module('when candidate has a clea subscription', function () { + test('should return false', function (assert) { + // given + // when + const habilitations = [ + { + id: 123, + label: 'Certif CLEA', + key: COMPLEMENTARY_KEYS.CLEA, + }, + ]; + const store = this.owner.lookup('service:store'); + const coreSubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.CORE, + complementaryCertificationId: null, + }); + const cleaSubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.COMPLEMENTARY, + complementaryCertificationId: habilitations[0].id, + }); + const candidate = store.createRecord('certification-candidate', { + subscriptions: [coreSubscription, cleaSubscription], + }); + + // then + assert.false(candidate.hasOnlyComplementarySubscription); + }); + }); + }); + function _pickModelData(certificationCandidate) { return pick(certificationCandidate, [ 'firstName', diff --git a/certif/tests/unit/models/subscription-test.js b/certif/tests/unit/models/subscription-test.js index 018aee157a5..28fcf4cdfa2 100644 --- a/certif/tests/unit/models/subscription-test.js +++ b/certif/tests/unit/models/subscription-test.js @@ -109,4 +109,47 @@ module('Unit | Model | subscription', function (hooks) { assert.false(isCore); }); }); + + module('get isComplementary', function () { + module('when subscription is COMPLEMENTARY', function () { + test('it should return true', function (assert) { + // given + const store = this.owner.lookup('service:store'); + const habilitations = [ + { + id: 123, + label: 'Pix+Droit', + key: 'DROIT', + }, + ]; + const complementarySubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.COMPLEMENTARY, + complementaryCertificationId: habilitations[0].id, + }); + + // when + const isComplementary = complementarySubscription.isComplementary; + + // then + assert.true(isComplementary); + }); + }); + + module('when subscription is not COMPLEMENTARY', function () { + test('it should return false', function (assert) { + // given + const store = this.owner.lookup('service:store'); + const coreSubscription = store.createRecord('subscription', { + type: SUBSCRIPTION_TYPES.CORE, + complementaryCertificationId: null, + }); + + // when + const isComplementary = coreSubscription.isComplementary; + + // then + assert.false(isComplementary); + }); + }); + }); }); diff --git a/certif/translations/en.json b/certif/translations/en.json index 366d00716ba..d5beb99ac46 100644 --- a/certif/translations/en.json +++ b/certif/translations/en.json @@ -702,6 +702,9 @@ "finalizing": "Finalise the session", "update": "Edit the details for session {sessionId}" }, + "finalization": { + "temporarily-blocked": "This session cannot be finalised at the moment. The Pix teams are working to unblock the finalization." + }, "finalization-info": "The finalisation information for the session has already been transmitted to Pix.", "password": { "copy-password": "Copy the invigilator’s session password", diff --git a/certif/translations/fr.json b/certif/translations/fr.json index fdd2a17ee0e..9cb8dfddceb 100644 --- a/certif/translations/fr.json +++ b/certif/translations/fr.json @@ -702,6 +702,9 @@ "finalizing": "Finaliser la session", "update": "Modifier les informations de la session {sessionId}" }, + "finalization": { + "temporarily-blocked": "Cette session ne peut pas être finalisée pour le moment. Les équipes de Pix travaillent au déblocage de la finalisation." + }, "finalization-info": "Les informations de finalisation de la session ont déjà été transmises aux équipes de Pix.", "password": { "copy-password": "Copier le mot de passe de session pour le surveillant",