From ddb57826cdbd503a57089c3cb63bf69289c54bee Mon Sep 17 00:00:00 2001 From: dienamo Date: Mon, 25 Nov 2024 17:11:18 +0100 Subject: [PATCH 1/3] =?UTF-8?q?:fix=20r=C3=A9initialisation=20du=20drawer?= =?UTF-8?q?=20apr=C3=A8s=20invitation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + .../MesUtilisateurs/InviterUnUtilisateur.tsx | 1 + .../MesUtilisateurs/MesUtilisateurs.test.tsx | 87 ++++++++++++++++++- yarn.lock | 12 ++- 4 files changed, 99 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ff834324..0b89dfd8 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "knip": "^5.37.2", "prettier": "^3.3.3", "prisma": "^5.21.1", + "react-select-event": "^5.5.1", "stylelint": "^16.10.0", "stylelint-config-standard": "^36.0.1", "stylelint-order": "^6.0.4", diff --git a/src/components/MesUtilisateurs/InviterUnUtilisateur.tsx b/src/components/MesUtilisateurs/InviterUnUtilisateur.tsx index 3ad7ad8e..54d13791 100644 --- a/src/components/MesUtilisateurs/InviterUnUtilisateur.tsx +++ b/src/components/MesUtilisateurs/InviterUnUtilisateur.tsx @@ -186,6 +186,7 @@ export default function InviterUnUtilisateur({ function fermerEtReinitialiser(htmlFormElement: HTMLFormElement): void { setIsOpen(false) + setRoleSelectionne('') window.dsfr(dialogRef.current).modal.conceal() htmlFormElement.reset() } diff --git a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx index ba08efc5..9be9e023 100644 --- a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx +++ b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx @@ -1,4 +1,5 @@ import { fireEvent, screen, waitFor, within } from '@testing-library/react' +import selectEvent from 'react-select-event' import { Mock } from 'vitest' import MesUtilisateurs from './MesUtilisateurs' @@ -852,7 +853,7 @@ describe('mes utilisateurs', () => { expect(envoyerInvitation).toHaveAttribute('type', 'submit') }) - it('dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche', async () => { + it('dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { // GIVEN const inviterUnUtilisateurAction = vi.fn(async () => Promise.resolve(['OK'])) const windowDsfr = window.dsfr @@ -917,6 +918,90 @@ describe('mes utilisateurs', () => { window.dsfr = windowDsfr }) + it('en invitant un gestionnaire, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { + const roleGestionnaireLabelSelectionMapping = { + 'Gestionnaire département': 'Département', + 'Gestionnaire groupement': 'Groupement', + 'Gestionnaire région': 'Région', + 'Gestionnaire structure': 'Structure', + } + // GIVEN + vi.spyOn(inviterAction, 'inviterUnUtilisateurAction') + .mockResolvedValueOnce('emailExistant') + .mockResolvedValueOnce('OK') + const windowDsfr = window.dsfr + window.dsfr = (): {modal: {conceal: Mock}} => { + return { + modal: { + conceal: vi.fn(), + }, + } + } + const mesUtilisateursViewModel = mesUtilisateursPresenter([utilisateurActifReadModel, utilisateurEnAttenteReadModel], 'fooId', totalUtilisateur) + renderComponent( + , { + sessionUtilisateurViewModel: sessionUtilisateurViewModelFactory({ + role: { + groupe: 'admin', + libelle: 'Rhône', + nom: 'Administrateur dispositif', + pictogramme: 'maille', + rolesGerables: [ + 'Administrateur dispositif', + 'Gestionnaire département', + 'Gestionnaire groupement', + 'Gestionnaire région', + 'Gestionnaire structure', + 'Instructeur', + 'Pilote politique publique', + 'Support animation', + ], + }, + }), + } + ) + const inviter = screen.getByRole('button', { name: 'Inviter une personne' }) + fireEvent.click(inviter) + const formulaireInvitation = screen.getByRole('dialog', { name: 'Invitez un utilisateur à rejoindre l’espace de gestion' }) + const roleRadios = within(formulaireInvitation).getAllByRole('radio') + // WHEN + const nom = within(formulaireInvitation).getByLabelText('Nom *') + fireEvent.change(nom, { target: { value: 'Tartempion' } }) + const prenom = within(formulaireInvitation).getByLabelText('Prénom *') + fireEvent.change(prenom, { target: { value: 'Martin' } }) + const email = within(formulaireInvitation).getByLabelText(/Adresse électronique/) + fireEvent.change(email, { target: { value: 'martin.tartempion@example.com' } }) + const gestionnaireRole = within(formulaireInvitation).getByLabelText('Gestionnaire département') + fireEvent.click(gestionnaireRole) + const departementSelect = within(formulaireInvitation).getByLabelText('Département *') + expect(departementSelect).toBeInTheDocument() + // eslint-disable-next-line import/no-named-as-default-member + await selectEvent.select(departementSelect, 'Ain') + const envoyerInvitation = await within(formulaireInvitation).findByRole('button', { name: 'Envoyer l’invitation' }) + fireEvent.click(envoyerInvitation) + const messageDErreur = await within(formulaireInvitation).findByText('Cet utilisateur dispose déjà d’un compte', { selector: 'p' }) + fireEvent.click(envoyerInvitation) + + // THEN + expect(messageDErreur).toBeInTheDocument() + const absenceMessageDErreur = await within(formulaireInvitation).findByText('Cet utilisateur dispose déjà d’un compte', { selector: 'p' }) + expect(absenceMessageDErreur).not.toBeInTheDocument() + const notification = screen.getByRole('alert') + expect(notification).toHaveTextContent('Invitation envoyée à martin.tartempion@example.com') + expect(formulaireInvitation).not.toHaveAttribute('open', '') + expect(nom).toHaveValue('') + expect(prenom).toHaveValue('') + expect(email).toHaveValue('') + roleRadios.forEach((roleRadio) => { + expect(roleRadio).not.toBeChecked() + }) + Object.values(roleGestionnaireLabelSelectionMapping).forEach((labelChampSelection) => { + const champSelection = within(formulaireInvitation).queryByLabelText(`${labelChampSelection} *`) + expect(champSelection).not.toBeInTheDocument() + }) + window.dsfr = windowDsfr + }) + it('dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un mail existant, alors il y a un message d’erreur', async () => { // GIVEN const inviterUnUtilisateurAction = vi.fn(async () => Promise.resolve(['emailExistant'])) diff --git a/yarn.lock b/yarn.lock index a39a5c81..e176903c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3732,7 +3732,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^10.4.0": +"@testing-library/dom@npm:>=7, @testing-library/dom@npm:^10.4.0": version: 10.4.0 resolution: "@testing-library/dom@npm:10.4.0" dependencies: @@ -10425,6 +10425,15 @@ __metadata: languageName: node linkType: hard +"react-select-event@npm:^5.5.1": + version: 5.5.1 + resolution: "react-select-event@npm:5.5.1" + dependencies: + "@testing-library/dom": "npm:>=7" + checksum: 10c0/908b4961b0c981223b2731ecf28e707b600fb71e9681c9be7185693623663b5e319cd2b77a8bdae471aa27f2b7838773e593982fea1523bde5fd5485dd9b154a + languageName: node + linkType: hard + "react-select@npm:^5.8.3": version: 5.8.3 resolution: "react-select@npm:5.8.3" @@ -11494,6 +11503,7 @@ __metadata: react: "npm:^18" react-dom: "npm:^18" react-select: "npm:^5.8.3" + react-select-event: "npm:^5.5.1" react-toastify: "npm:^10.0.6" stylelint: "npm:^16.10.0" stylelint-config-standard: "npm:^36.0.1" From 8fa8c5e1426b2a348a92e1839c72bd724a5776ee Mon Sep 17 00:00:00 2001 From: dienamo Date: Wed, 27 Nov 2024 10:59:19 +0100 Subject: [PATCH 2/3] modification wording test invitation --- src/components/MesUtilisateurs/MesUtilisateurs.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx index 9be9e023..3c7cdb01 100644 --- a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx +++ b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx @@ -853,7 +853,7 @@ describe('mes utilisateurs', () => { expect(envoyerInvitation).toHaveAttribute('type', 'submit') }) - it('dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { + it('en invitant un memebre du groupe admin, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { // GIVEN const inviterUnUtilisateurAction = vi.fn(async () => Promise.resolve(['OK'])) const windowDsfr = window.dsfr @@ -918,7 +918,7 @@ describe('mes utilisateurs', () => { window.dsfr = windowDsfr }) - it('en invitant un gestionnaire, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { + it('en invitant un memebre du groupe gestionnaire, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { const roleGestionnaireLabelSelectionMapping = { 'Gestionnaire département': 'Département', 'Gestionnaire groupement': 'Groupement', From 1b3fd6a716e1fc7c71b4e8fc51c81186eba934c6 Mon Sep 17 00:00:00 2001 From: dienamo Date: Wed, 27 Nov 2024 11:19:22 +0100 Subject: [PATCH 3/3] fix des conflits au rebase --- .../MesUtilisateurs/MesUtilisateurs.test.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx index 3c7cdb01..c52dad5c 100644 --- a/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx +++ b/src/components/MesUtilisateurs/MesUtilisateurs.test.tsx @@ -853,7 +853,7 @@ describe('mes utilisateurs', () => { expect(envoyerInvitation).toHaveAttribute('type', 'submit') }) - it('en invitant un memebre du groupe admin, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { + it('en invitant un membre du groupe admin, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { // GIVEN const inviterUnUtilisateurAction = vi.fn(async () => Promise.resolve(['OK'])) const windowDsfr = window.dsfr @@ -918,7 +918,7 @@ describe('mes utilisateurs', () => { window.dsfr = windowDsfr }) - it('en invitant un memebre du groupe gestionnaire, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { + it('en invitant un membre du groupe gestionnaire, dans le drawer d’invitation, quand je remplis correctement le formulaire et avec un nouveau mail, alors un message de validation s’affiche et le drawer est réinitialisé', async () => { const roleGestionnaireLabelSelectionMapping = { 'Gestionnaire département': 'Département', 'Gestionnaire groupement': 'Groupement', @@ -926,9 +926,7 @@ describe('mes utilisateurs', () => { 'Gestionnaire structure': 'Structure', } // GIVEN - vi.spyOn(inviterAction, 'inviterUnUtilisateurAction') - .mockResolvedValueOnce('emailExistant') - .mockResolvedValueOnce('OK') + const inviterUnUtilisateurAction = vi.fn(async () => Promise.resolve(['OK'])) const windowDsfr = window.dsfr window.dsfr = (): {modal: {conceal: Mock}} => { return { @@ -940,6 +938,7 @@ describe('mes utilisateurs', () => { const mesUtilisateursViewModel = mesUtilisateursPresenter([utilisateurActifReadModel, utilisateurEnAttenteReadModel], 'fooId', totalUtilisateur) renderComponent( , { + inviterUnUtilisateurAction, sessionUtilisateurViewModel: sessionUtilisateurViewModelFactory({ role: { groupe: 'admin', @@ -979,14 +978,9 @@ describe('mes utilisateurs', () => { await selectEvent.select(departementSelect, 'Ain') const envoyerInvitation = await within(formulaireInvitation).findByRole('button', { name: 'Envoyer l’invitation' }) fireEvent.click(envoyerInvitation) - const messageDErreur = await within(formulaireInvitation).findByText('Cet utilisateur dispose déjà d’un compte', { selector: 'p' }) - fireEvent.click(envoyerInvitation) // THEN - expect(messageDErreur).toBeInTheDocument() - const absenceMessageDErreur = await within(formulaireInvitation).findByText('Cet utilisateur dispose déjà d’un compte', { selector: 'p' }) - expect(absenceMessageDErreur).not.toBeInTheDocument() - const notification = screen.getByRole('alert') + const notification = await screen.findByRole('alert') expect(notification).toHaveTextContent('Invitation envoyée à martin.tartempion@example.com') expect(formulaireInvitation).not.toHaveAttribute('open', '') expect(nom).toHaveValue('')