-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Appel du back-end depuis le formulaire (#207)
* Appel du back-end depuis le formulaire * Ajout de la page de formulaire validé * Correction des problèmes de validation * Ajout de tests pour la candidature validée * Retours de code review * Retours supplémentaires de code review * WIP : test d'erreur à faire fonctionner * Fix test stub * Ajout d'un test de changement de page
- Loading branch information
Showing
22 changed files
with
370 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
export default function Alert({ children, titre }) { | ||
return ( | ||
<div className="fr-alert fr-alert--error"> | ||
<h3 className="fr-alert__title">{titre}</h3> | ||
<p>{children}</p> | ||
</div> | ||
); | ||
} | ||
|
||
Alert.propTypes = { | ||
children: PropTypes.node, | ||
titre: PropTypes.string, | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import { render, screen, within, fireEvent } from '@testing-library/react'; | ||
import { render, screen, within, fireEvent, act } from '@testing-library/react'; | ||
import { describe, expect, it, vi } from 'vitest'; | ||
import CandidatureConseiller from './CandidatureConseiller'; | ||
import { textMatcher, dateDujour } from '../../../test/test-utils'; | ||
import * as ReactRouterDom from 'react-router-dom'; | ||
|
||
vi.mock('react-router-dom', () => ({ | ||
useLocation: () => ({ hash: '' }), | ||
useNavigate: vi.fn() | ||
})); | ||
|
||
describe('candidature conseiller', () => { | ||
|
@@ -57,9 +59,9 @@ describe('candidature conseiller', () => { | |
expect(email).toHaveAttribute('type', 'email'); | ||
expect(email).toBeRequired(); | ||
|
||
const telephone = within(etapeInformationsDeContact).getByLabelText('Téléphone Format attendu : 0122334455'); | ||
const telephone = within(etapeInformationsDeContact).getByLabelText('Téléphone Format attendu : +33122334455'); | ||
expect(telephone).toHaveAttribute('type', 'tel'); | ||
expect(telephone).toHaveAttribute('pattern', '0[1-9]{9}'); | ||
expect(telephone).toHaveAttribute('pattern', '[+](33|590|596|594|262|269|687)[1-9]{9}'); | ||
|
||
const habitation = within(etapeInformationsDeContact).getByLabelText('Votre lieu d’habitation Saississez le nom ou le code postal de votre commune.'); | ||
expect(habitation).toHaveAttribute('type', 'text'); | ||
|
@@ -104,11 +106,11 @@ describe('candidature conseiller', () => { | |
|
||
const oui = screen.getByRole('radio', { name: 'Oui' }); | ||
expect(oui).toBeRequired(); | ||
expect(oui).toHaveAttribute('name', 'experienceProfessionnelle'); | ||
expect(oui).toHaveAttribute('name', 'aUneExperienceMedNum'); | ||
|
||
const non = screen.getByRole('radio', { name: 'Non' }); | ||
expect(non).toBeRequired(); | ||
expect(non).toHaveAttribute('name', 'experienceProfessionnelle'); | ||
expect(non).toHaveAttribute('name', 'aUneExperienceMedNum'); | ||
}); | ||
|
||
it('quand je coche "diplomé" alors un champ pour préciser le diplôme s’affiche', () => { | ||
|
@@ -166,31 +168,31 @@ describe('candidature conseiller', () => { | |
|
||
const _5km = screen.getByRole('radio', { name: '5 km' }); | ||
expect(_5km).toBeRequired(); | ||
expect(_5km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_5km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const _10km = screen.getByRole('radio', { name: '10 km' }); | ||
expect(_10km).toBeRequired(); | ||
expect(_10km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_10km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const _15km = screen.getByRole('radio', { name: '15 km' }); | ||
expect(_15km).toBeRequired(); | ||
expect(_15km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_15km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const _20km = screen.getByRole('radio', { name: '20 km' }); | ||
expect(_20km).toBeRequired(); | ||
expect(_20km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_20km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const _40km = screen.getByRole('radio', { name: '40 km' }); | ||
expect(_40km).toBeRequired(); | ||
expect(_40km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_40km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const _100km = screen.getByRole('radio', { name: '100 km' }); | ||
expect(_100km).toBeRequired(); | ||
expect(_100km).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(_100km).toHaveAttribute('name', 'distanceMax'); | ||
|
||
const franceEntiere = screen.getByRole('radio', { name: 'France entière' }); | ||
expect(franceEntiere).toBeRequired(); | ||
expect(franceEntiere).toHaveAttribute('name', 'distanceDomicile'); | ||
expect(franceEntiere).toHaveAttribute('name', 'distanceMax'); | ||
}); | ||
|
||
it('quand j’affiche le formulaire alors l’étape "Votre motivation" est affiché', () => { | ||
|
@@ -210,7 +212,7 @@ describe('candidature conseiller', () => { | |
expect(aideMotivation).toBeInTheDocument(); | ||
|
||
const descriptionMotivation = within(votreMotivation).getByLabelText('Votre message *'); | ||
expect(descriptionMotivation).toHaveAttribute('name', 'descriptionMotivation'); | ||
expect(descriptionMotivation).toHaveAttribute('name', 'motivation'); | ||
expect(descriptionMotivation).toBeRequired(); | ||
}); | ||
|
||
|
@@ -290,6 +292,14 @@ describe('candidature conseiller', () => { | |
// GIVEN | ||
vi.useFakeTimers(); | ||
vi.setSystemTime(new Date(2023, 11, 12, 13)); | ||
|
||
vi.stubGlobal('fetch', vi.fn( | ||
() => ({ status: 200, json: async () => Promise.resolve({}) })) | ||
); | ||
|
||
const mockNavigate = vi.fn().mockReturnValue(() => { }); | ||
vi.spyOn(ReactRouterDom, 'useNavigate').mockReturnValue(mockNavigate); | ||
|
||
render(<CandidatureConseiller />); | ||
const prenom = screen.getByLabelText('Prénom *'); | ||
fireEvent.change(prenom, { target: { value: 'Jean' } }); | ||
|
@@ -322,6 +332,11 @@ describe('candidature conseiller', () => { | |
// GIVEN | ||
vi.useFakeTimers(); | ||
vi.setSystemTime(new Date(2023, 11, 12, 13)); | ||
|
||
vi.stubGlobal('fetch', vi.fn( | ||
() => ({ status: 200, json: async () => Promise.resolve({}) })) | ||
); | ||
|
||
render(<CandidatureConseiller />); | ||
const prenom = screen.getByLabelText('Prénom *'); | ||
fireEvent.change(prenom, { target: { value: 'Jean' } }); | ||
|
@@ -347,4 +362,91 @@ describe('candidature conseiller', () => { | |
expect(erreurCheckboxes).toBeInTheDocument(); | ||
vi.useRealTimers(); | ||
}); | ||
|
||
it('quand je remplis le formulaire, que je l’envoie et que le serveur me renvoie une erreur, alors elle s’affiche sur la page', async () => { | ||
// GIVEN | ||
vi.useFakeTimers(); | ||
vi.setSystemTime(new Date(2023, 11, 12, 13)); | ||
|
||
vi.stubGlobal('fetch', vi.fn( | ||
() => ({ status: 400, json: async () => Promise.resolve({ message: 'Cette adresse mail est déjà utilisée' }) })) | ||
); | ||
|
||
render(<CandidatureConseiller />); | ||
const prenom = screen.getByLabelText('Prénom *'); | ||
fireEvent.change(prenom, { target: { value: 'Jean' } }); | ||
const nom = screen.getByLabelText('Nom *'); | ||
fireEvent.change(nom, { target: { value: 'Dupont' } }); | ||
const email = screen.getByLabelText('Adresse e-mail * Format attendu : [email protected]'); | ||
fireEvent.change(email, { target: { value: '[email protected]' } }); | ||
const enEmploi = screen.getByRole('checkbox', { name: 'En emploi' }); | ||
fireEvent.click(enEmploi); | ||
const oui = screen.getByRole('radio', { name: 'Oui' }); | ||
fireEvent.click(oui); | ||
const date = screen.getByLabelText('Choisir une date'); | ||
fireEvent.change(date, { target: { value: dateDujour() } }); | ||
const _5km = screen.getByRole('radio', { name: '5 km' }); | ||
fireEvent.click(_5km); | ||
const descriptionMotivation = screen.getByLabelText('Votre message *'); | ||
fireEvent.change(descriptionMotivation, { target: { value: 'je suis motivé !' } }); | ||
|
||
// WHEN | ||
const envoyer = screen.getByRole('button', { name: 'Envoyer votre candidature' }); | ||
|
||
// eslint-disable-next-line testing-library/no-unnecessary-act | ||
await act(() => { | ||
fireEvent.click(envoyer); | ||
}); | ||
|
||
// THEN | ||
const titreErreurValidation = screen.getByRole('heading', { level: 3, name: 'Erreur de validation' }); | ||
expect(titreErreurValidation).toBeInTheDocument(); | ||
const contenuErreurValidation = screen.getByText('Cette adresse mail est déjà utilisée', { selector: 'p' }); | ||
expect(contenuErreurValidation).toBeInTheDocument(); | ||
vi.useRealTimers(); | ||
}); | ||
|
||
it('quand je remplis le formulaire avec toutes les informations valides, alors je suis redirigé vers la page de candidature validée', async () => { | ||
// GIVEN | ||
vi.useFakeTimers(); | ||
vi.setSystemTime(new Date(2023, 11, 12, 13)); | ||
|
||
vi.stubGlobal('fetch', vi.fn( | ||
() => ({ status: 200, json: async () => Promise.resolve({}) })) | ||
); | ||
|
||
const mockNavigate = vi.fn().mockReturnValue(() => { }); | ||
vi.spyOn(ReactRouterDom, 'useNavigate').mockReturnValue(mockNavigate); | ||
|
||
render(<CandidatureConseiller />); | ||
const prenom = screen.getByLabelText('Prénom *'); | ||
fireEvent.change(prenom, { target: { value: 'Jean' } }); | ||
const nom = screen.getByLabelText('Nom *'); | ||
fireEvent.change(nom, { target: { value: 'Dupont' } }); | ||
const email = screen.getByLabelText('Adresse e-mail * Format attendu : [email protected]'); | ||
fireEvent.change(email, { target: { value: '[email protected]' } }); | ||
const enEmploi = screen.getByRole('checkbox', { name: 'En emploi' }); | ||
fireEvent.click(enEmploi); | ||
const oui = screen.getByRole('radio', { name: 'Oui' }); | ||
fireEvent.click(oui); | ||
const date = screen.getByLabelText('Choisir une date'); | ||
fireEvent.change(date, { target: { value: dateDujour() } }); | ||
const _5km = screen.getByRole('radio', { name: '5 km' }); | ||
fireEvent.click(_5km); | ||
const descriptionMotivation = screen.getByLabelText('Votre message *'); | ||
fireEvent.change(descriptionMotivation, { target: { value: 'je suis motivé !' } }); | ||
|
||
// WHEN | ||
const envoyer = screen.getByRole('button', { name: 'Envoyer votre candidature' }); | ||
|
||
// eslint-disable-next-line testing-library/no-unnecessary-act | ||
await act(() => { | ||
fireEvent.click(envoyer); | ||
}); | ||
|
||
// THEN | ||
expect(mockNavigate).toHaveBeenCalledWith('/candidature-validee'); | ||
|
||
vi.useRealTimers(); | ||
}); | ||
}); |
Oops, something went wrong.