diff --git a/src/components/commun/Checkbox.jsx b/src/components/commun/Checkbox.jsx
index 78c6600..1f72a88 100644
--- a/src/components/commun/Checkbox.jsx
+++ b/src/components/commun/Checkbox.jsx
@@ -17,6 +17,7 @@ export default function Checkbox({ children, id, onCheck, checked, required = tr
Checkbox.propTypes = {
children: PropTypes.node,
id: PropTypes.string,
+ name: PropTypes.string,
onCheck: PropTypes.func,
checked: PropTypes.bool,
required: PropTypes.bool,
diff --git a/src/views/candidature-conseiller/CandidatureConseiller.jsx b/src/views/candidature-conseiller/CandidatureConseiller.jsx
index 228ceac..fe4b14a 100644
--- a/src/views/candidature-conseiller/CandidatureConseiller.jsx
+++ b/src/views/candidature-conseiller/CandidatureConseiller.jsx
@@ -18,18 +18,18 @@ import '@gouvfr/dsfr/dist/component/sidemenu/sidemenu.min.css';
import './CandidatureConseiller.css';
export default function CandidatureConseiller() {
- const [dateDisponibilite, setDateDisponibilite] = useState();
+ const [dateDisponibilite, setDateDisponibilite] = useState('');
const [isSituationValid, setIsSituationValid] = useState(true);
- const [situationChecks, setSituationChecks] = useState(
- new Array(situations.length).fill(false)
- );
useScrollToSection();
const valider = () => {
setIsSituationValid(situationChecks.some(checked => checked));
if (!isSituationValid) {
+
document.getElementById('situationEtExperience').scrollIntoView();
+ } else {
+ event.currentTarget.submit();
}
};
@@ -42,17 +42,13 @@ export default function CandidatureConseiller() {
Je veux devenir conseiller numérique
Les champs avec * sont obligatoires.
-
diff --git a/src/views/candidature-conseiller/CandidatureConseiller.test.jsx b/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
index 07b0b98..d7c9a02 100644
--- a/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
+++ b/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
@@ -8,34 +8,32 @@ vi.mock('react-router-dom', () => ({
}));
describe('candidature conseiller', () => {
- describe('étant un candidat', () => {
- it('quand j’affiche le formulaire alors le titre et le menu s’affichent', () => {
- // WHEN
- render(
);
+ it('quand j’affiche le formulaire alors le titre et le menu s’affichent', () => {
+ // WHEN
+ render(
);
- // THEN
- const titre = screen.getByRole('heading', { level: 1, name: 'Je veux devenir conseiller numérique' });
- expect(titre).toBeInTheDocument();
+ // THEN
+ const titre = screen.getByRole('heading', { level: 1, name: 'Je veux devenir conseiller numérique' });
+ expect(titre).toBeInTheDocument();
- const champsObligatoires = screen.getByText(textMatcher('Les champs avec * sont obligatoires.'), { selector: 'p' });
- expect(champsObligatoires).toBeInTheDocument();
+ const champsObligatoires = screen.getByText(textMatcher('Les champs avec * sont obligatoires.'), { selector: 'p' });
+ expect(champsObligatoires).toBeInTheDocument();
- const navigation = screen.getByRole('navigation', { name: 'Sommaire' });
- const menu = within(navigation).getByRole('list');
- const menuItems = within(menu).getAllByRole('listitem');
+ const navigation = screen.getByRole('navigation', { name: 'Sommaire' });
+ const menu = within(navigation).getByRole('list');
+ const menuItems = within(menu).getAllByRole('listitem');
- const informationsDeContact = within(menuItems[0]).getByRole('link', { name: 'Vos informations de contact' });
- expect(informationsDeContact).toHaveAttribute('href', '#informations-de-contact');
+ const informationsDeContact = within(menuItems[0]).getByRole('link', { name: 'Vos informations de contact' });
+ expect(informationsDeContact).toHaveAttribute('href', '#informations-de-contact');
- const situationEtExperience = within(menuItems[1]).getByRole('link', { name: 'Votre situation et expérience' });
- expect(situationEtExperience).toHaveAttribute('href', '#situation-et-experience');
+ const situationEtExperience = within(menuItems[1]).getByRole('link', { name: 'Votre situation et expérience' });
+ expect(situationEtExperience).toHaveAttribute('href', '#situation-et-experience');
- const votreDisponibilite = within(menuItems[2]).getByRole('link', { name: 'Votre disponibilité' });
- expect(votreDisponibilite).toHaveAttribute('href', '#votre-disponibilite');
+ const votreDisponibilite = within(menuItems[2]).getByRole('link', { name: 'Votre disponibilité' });
+ expect(votreDisponibilite).toHaveAttribute('href', '#votre-disponibilite');
- const votreMotivation = within(menuItems[3]).getByRole('link', { name: 'Votre motivation' });
- expect(votreMotivation).toHaveAttribute('href', '#votre-motivation');
- });
+ const votreMotivation = within(menuItems[3]).getByRole('link', { name: 'Votre motivation' });
+ expect(votreMotivation).toHaveAttribute('href', '#votre-motivation');
});
it('quand j’affiche le formulaire alors l’étape "Vos informations de contact" est affiché', () => {
@@ -113,7 +111,7 @@ describe('candidature conseiller', () => {
expect(non).toHaveAttribute('name', 'experienceProfessionnelle');
});
- it('quand je coche "diplomé", un champ pour préciser le diplôme s’affiche', () => {
+ it('quand je coche "diplomé" alors un champ pour préciser le diplôme s’affiche', () => {
// GIVEN
render(
);
@@ -221,7 +219,7 @@ describe('candidature conseiller', () => {
render(
);
// THEN
- const enResume = screen.getByText(textMatcher('En résumé'), { selector: 'p' });
+ const enResume = screen.getByText('En résumé', { selector: 'p' });
expect(enResume).toBeInTheDocument();
const titreResume = screen.getByText(
@@ -242,11 +240,10 @@ describe('candidature conseiller', () => {
it('quand je modifie la date de disponibilité, alors elle s’affiche dans l’encart "En résumé"', () => {
// GIVEN
render(
);
- const dateDisponibilite = '2023-12-12';
// WHEN
- const date = screen.getByLabelText('Choisir une date');
- fireEvent.change(date, { target: { value: dateDisponibilite } });
+ const dateDisponibilite = screen.getByLabelText('Choisir une date');
+ fireEvent.change(dateDisponibilite, { target: { value: '2023-12-12' } });
// THEN
const titreResume = screen.getByText(
@@ -270,8 +267,8 @@ describe('candidature conseiller', () => {
},
];
- vi.spyOn(global, 'fetch').mockResolvedValue({
- json: () => Promise.resolve(geoApiResponse)
+ vi.spyOn(global, 'fetch').mockResolvedValueOnce({
+ json: async () => Promise.resolve(geoApiResponse)
});
// WHEN
@@ -279,8 +276,8 @@ describe('candidature conseiller', () => {
fireEvent.change(adresse, { target: { value: 'par' } });
// THEN
- const paris = await screen.findByText(textMatcher('75001 Paris'), { selector: 'option' });
- const parisot = await screen.findByText(textMatcher('82137 Parisot'), { selector: 'option' });
+ const paris = await screen.findByRole('option', { name: '75001 Paris', hidden: true });
+ const parisot = await screen.findByRole('option', { name: '82137 Parisot', hidden: true });
expect(paris).toBeInTheDocument();
expect(parisot).toBeInTheDocument();
});
@@ -288,28 +285,56 @@ describe('candidature conseiller', () => {
it('quand je coche au moins une case de situation et que je valide le formulaire alors il n’y a pas d’erreur de validation', () => {
// GIVEN
render(
);
+ 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 : nom@domaine.fr');
+ fireEvent.change(email, { target: { value: 'jean.dupont@example.com' } });
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: '2023-12-12' } });
+ 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', { type: 'submit' });
+ const envoyer = screen.getByRole('button', { name: 'Envoyer votre candidature' });
fireEvent.click(envoyer);
// THEN
- const erreurCheckboxes = screen.queryByText(textMatcher('Vous devez cocher au moins une case'), { selector: 'p' });
+ const erreurCheckboxes = screen.queryByText('Vous devez cocher au moins une case', { selector: 'p' });
expect(erreurCheckboxes).not.toBeInTheDocument();
});
it('quand je ne coche pas de case de situation et que je valide le formulaire alors il y a une erreur de validation', () => {
// GIVEN
render(
);
+ 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 : nom@domaine.fr');
+ fireEvent.change(email, { target: { value: 'jean.dupont@example.com' } });
+ const oui = screen.getByRole('radio', { name: 'Oui' });
+ fireEvent.click(oui);
+ const date = screen.getByLabelText('Choisir une date');
+ fireEvent.change(date, { target: { value: '2023-12-12' } });
+ 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', { type: 'submit' });
+ const envoyer = screen.getByRole('button', { name: 'Envoyer votre candidature' });
fireEvent.click(envoyer);
// THEN
- const erreurCheckboxes = screen.getByText(textMatcher('Vous devez cocher au moins une case'), { selector: 'p' });
+ const erreurCheckboxes = screen.getByText('Vous devez cocher au moins une case', { selector: 'p' });
expect(erreurCheckboxes).toBeInTheDocument();
});
});
diff --git a/src/views/candidature-conseiller/EnResume.jsx b/src/views/candidature-conseiller/EnResume.jsx
index f45eab7..18ee81f 100644
--- a/src/views/candidature-conseiller/EnResume.jsx
+++ b/src/views/candidature-conseiller/EnResume.jsx
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
export default function EnResume({ dateDisponibilite }) {
const formatDate = () => {
- if (!dateDisponibilite) {
+ if (dateDisponibilite === '') {
return '[Renseignez votre date de disponibilité]';
}
return new Date(dateDisponibilite).toLocaleDateString();
diff --git a/src/views/candidature-conseiller/SituationEtExperience.jsx b/src/views/candidature-conseiller/SituationEtExperience.jsx
index d3aea37..89f4d55 100644
--- a/src/views/candidature-conseiller/SituationEtExperience.jsx
+++ b/src/views/candidature-conseiller/SituationEtExperience.jsx
@@ -5,16 +5,10 @@ import Input from '../../components/commun/Input';
import { situations } from './situations';
import PropTypes from 'prop-types';
-export default function SituationEtExperience({ situationChecks, setSituationChecks, isSituationValid }) {
+export default function SituationEtExperience({ isSituationValid }) {
const [isDiplomeSelected, setIsDiplomeSelected] = useState(false);
const handleCheck = event => {
- const indexCaseCochee = situations.findIndex(situation => situation.id === event.target.id);
- const updatedCheckedState = situationChecks.map((item, index) =>
- index === indexCaseCochee ? !item : item
- );
- setSituationChecks(updatedCheckedState);
-
setIsDiplomeSelected(event.target.id === 'diplome' && event.target.checked);
};
@@ -58,7 +52,5 @@ export default function SituationEtExperience({ situationChecks, setSituationChe
}
SituationEtExperience.propTypes = {
- situationChecks: PropTypes.array,
- setSituationChecks: PropTypes.func,
isSituationValid: PropTypes.bool
};
diff --git a/vitest.setup.js b/vitest.setup.js
index e856011..730c7d2 100644
--- a/vitest.setup.js
+++ b/vitest.setup.js
@@ -1 +1,5 @@
+import { vi } from 'vitest';
import 'vitest-dom/extend-expect';
+
+// scrollIntoView is not implemented in jsdom
+window.HTMLElement.prototype.scrollIntoView = vi.fn();