diff --git a/src/components/commun/Input.jsx b/src/components/commun/Input.jsx
index 2db9e1c..c08fadc 100644
--- a/src/components/commun/Input.jsx
+++ b/src/components/commun/Input.jsx
@@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
-export default function Input({ children, id, isRequired = true, type = 'text', pattern, onChange, list, min, readOnly, isLoading, ariaBusy, value, testId = '' }) {
+export default function Input({ children, id, isRequired = true, autoComplete = 'on', testId = '', type = 'text',
+ pattern, onChange, list, min, readOnly, isLoading, ariaBusy, value }) {
return (
@@ -11,13 +12,14 @@ export default function Input({ children, id, isRequired = true, type = 'text',
type={type}
id={id}
required={isRequired}
+ autoComplete={autoComplete}
pattern={pattern}
onChange={onChange}
list={list}
min={min}
readOnly={readOnly}
name={id}
- value={value}
+ value={value?.trim()}
aria-busy={ariaBusy}
data-testid={testId}
/>
@@ -35,6 +37,7 @@ Input.propTypes = {
children: PropTypes.node,
id: PropTypes.string,
isRequired: PropTypes.bool,
+ autoComplete: PropTypes.string,
type: PropTypes.string,
pattern: PropTypes.string,
onChange: PropTypes.func,
diff --git a/src/views/candidature-conseiller/AddressChooser.jsx b/src/views/candidature-conseiller/AddressChooser.jsx
index 7d112f8..194357a 100644
--- a/src/views/candidature-conseiller/AddressChooser.jsx
+++ b/src/views/candidature-conseiller/AddressChooser.jsx
@@ -10,6 +10,7 @@ export default function AddressChooser() {
return (
<>
{
diff --git a/src/views/candidature-conseiller/CandidatureConseiller.jsx b/src/views/candidature-conseiller/CandidatureConseiller.jsx
index e1ca6e7..ed0f3a6 100644
--- a/src/views/candidature-conseiller/CandidatureConseiller.jsx
+++ b/src/views/candidature-conseiller/CandidatureConseiller.jsx
@@ -54,10 +54,13 @@ export default function CandidatureConseiller() {
} else {
const conseillerData = await buildConseillerData(formData);
const resultatCreation = await creerCandidatureConseiller(conseillerData);
- if (resultatCreation.status >= 400) {
+ if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.scrollTo({ top: 0, behavior: 'smooth' });
+ } else if (!resultatCreation.status) {
+ setValidationError(resultatCreation.message);
+ window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-conseiller');
}
diff --git a/src/views/candidature-conseiller/CandidatureConseiller.test.jsx b/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
index 961eaf5..ee73c21 100644
--- a/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
+++ b/src/views/candidature-conseiller/CandidatureConseiller.test.jsx
@@ -522,7 +522,7 @@ describe('candidature conseiller', () => {
vi.useRealTimers();
});
- it('quand je remplis complètementle formulaire avec un numéro téléphone valide, alors je suis redirigé vers la page de candidature validée', async () => {
+ it('quand je remplis complètement le formulaire avec un numéro téléphone valide, alors je suis redirigé vers la page de candidature validée', async () => {
// GIVEN
vi.useFakeTimers();
vi.setSystemTime(new Date(2023, 11, 12, 13));
@@ -661,4 +661,51 @@ describe('candidature conseiller', () => {
vi.useRealTimers();
});
+
+ it('quand je remplis le formulaire et qu’une erreur se produit alors un message d’erreur s’affiche', async () => {
+ // GIVEN
+ vi.useFakeTimers();
+ vi.setSystemTime(new Date(2023, 11, 12, 13));
+
+ vi.spyOn(useApiAdmin, 'useApiAdmin').mockImplementation(() => ({
+ creerCandidatureConseiller: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
+ buildConseillerData: vi.fn(),
+ }));
+
+ 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 adresse = screen.getByLabelText('Votre lieu d’habitation * Saississez le nom ou le code postal de votre commune.');
+ fireEvent.change(adresse, { target: { value: '93100 Montreuil' } });
+ const telephone = screen.getByLabelText('Téléphone Format attendu : +33122334455');
+ fireEvent.change(telephone, { target: { value: '+33159590730' } });
+ 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 contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
+ expect(contenuErreurValidation).toBeInTheDocument();
+
+ vi.useRealTimers();
+ });
});
diff --git a/src/views/candidature-coordinateur/CandidatureCoordinateur.jsx b/src/views/candidature-coordinateur/CandidatureCoordinateur.jsx
index b754f52..b1a72b6 100644
--- a/src/views/candidature-coordinateur/CandidatureCoordinateur.jsx
+++ b/src/views/candidature-coordinateur/CandidatureCoordinateur.jsx
@@ -39,10 +39,13 @@ export default function CandidatureCoordinateur() {
const formData = new FormData(event.currentTarget);
const coordinateurData = await buildCoordinateurData(formData, geoLocation, codeCommune);
const resultatCreation = await creerCandidatureCoordinateur(coordinateurData);
- if (resultatCreation.status >= 400) {
+ if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.scrollTo({ top: 0, behavior: 'smooth' });
+ } else if (!resultatCreation.status) {
+ setValidationError(resultatCreation.message);
+ window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-structure');
}
diff --git a/src/views/candidature-coordinateur/CandidatureCoordinateur.test.jsx b/src/views/candidature-coordinateur/CandidatureCoordinateur.test.jsx
index 358db4a..f166a49 100644
--- a/src/views/candidature-coordinateur/CandidatureCoordinateur.test.jsx
+++ b/src/views/candidature-coordinateur/CandidatureCoordinateur.test.jsx
@@ -3,7 +3,7 @@ import { describe, expect, it, vi } from 'vitest';
import CandidatureCoordinateur from './CandidatureCoordinateur';
import { textMatcher, dateDujour } from '../../../test/test-utils';
import * as ReactRouterDom from 'react-router-dom';
-import { useApiAdmin } from '../candidature-conseiller/useApiAdmin';
+import * as useApiAdmin from '../candidature-conseiller/useApiAdmin';
import { useEntrepriseFinder } from '../candidature-structure/useEntrepriseFinder';
vi.mock('react-router-dom', () => ({
@@ -427,7 +427,7 @@ describe('candidature coordinateur', () => {
]
];
- const { buildCoordinateurData } = renderHook(() => useApiAdmin()).result.current;
+ const { buildCoordinateurData } = renderHook(() => useApiAdmin.useApiAdmin()).result.current;
const { getGeoLocationFromAddress } = renderHook(() => useEntrepriseFinder()).result.current;
// //WHEN
@@ -462,5 +462,61 @@ describe('candidature coordinateur', () => {
vi.useRealTimers();
});
+
+ it('quand je remplis le formulaire et qu’une erreur se produit alors un message d’erreur s’affiche', async () => {
+ // GIVEN
+ vi.useFakeTimers();
+ vi.setSystemTime(new Date(2023, 11, 12, 13));
+
+ vi.spyOn(useApiAdmin, 'useApiAdmin').mockImplementation(() => ({
+ creerCandidatureCoordinateur: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
+ buildCoordinateurData: vi.fn(),
+ }));
+
+ render();
+ const siret = screen.getByLabelText('SIRET / RIDET *');
+ fireEvent.change(siret, { target: { value: '1234567890123' } });
+ const denomination = screen.getByLabelText('Dénomination *');
+ fireEvent.change(denomination, { target: { value: 'Entreprise' } });
+ const adresse = screen.getByLabelText('Adresse *');
+ fireEvent.change(adresse, { target: { value: '75007 Paris' } });
+ const typeStructure = screen.getByRole('radio', { name: 'Une commune' });
+ fireEvent.click(typeStructure);
+ const prenom = screen.getByLabelText('Prénom *');
+ fireEvent.change(prenom, { target: { value: 'Jean' } });
+ const nom = screen.getByLabelText('Nom *');
+ fireEvent.change(nom, { target: { value: 'Dupont' } });
+ const fonction = screen.getByLabelText('Fonction *');
+ fireEvent.change(fonction, { target: { value: 'Test' } });
+ const email = screen.getByLabelText('Adresse e-mail *');
+ fireEvent.change(email, { target: { value: 'jean.dupont@example.com' } });
+ const telephone = screen.getByLabelText('Téléphone *');
+ fireEvent.change(telephone, { target: { value: '+33123456789' } });
+ const identificationCandidat = screen.getByRole('radio', { name: 'Oui' });
+ fireEvent.click(identificationCandidat);
+ const typeMission = screen.getByRole('radio', { name: 'Accompagnera également des publics' });
+ fireEvent.click(typeMission);
+ const date = screen.getByLabelText('Choisir une date');
+ fireEvent.change(date, { target: { value: dateDujour() } });
+ const descriptionMotivation = screen.getByLabelText('Votre message *');
+ fireEvent.change(descriptionMotivation, { target: { value: 'je suis motivé !' } });
+ const confirmation = screen.getByRole('checkbox', { name: 'Je confirme avoir lu et pris connaissance des conditions d’engagement. *' });
+ fireEvent.click(confirmation);
+
+ // 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 contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
+ expect(contenuErreurValidation).toBeInTheDocument();
+
+ vi.useRealTimers();
+ });
});
diff --git a/src/views/candidature-structure/CandidatureStructure.jsx b/src/views/candidature-structure/CandidatureStructure.jsx
index 3695c26..9208e5c 100644
--- a/src/views/candidature-structure/CandidatureStructure.jsx
+++ b/src/views/candidature-structure/CandidatureStructure.jsx
@@ -40,10 +40,13 @@ export default function CandidatureStructure() {
const formData = new FormData(event.currentTarget);
const structureData = await buildStructureData(formData, geoLocation, codeCommune);
const resultatCreation = await creerCandidatureStructure(structureData);
- if (resultatCreation.status >= 400) {
+ if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.scrollTo({ top: 0, behavior: 'smooth' });
+ } else if (!resultatCreation.status) {
+ setValidationError(resultatCreation.message);
+ window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-structure');
}
diff --git a/src/views/candidature-structure/CandidatureStructure.test.jsx b/src/views/candidature-structure/CandidatureStructure.test.jsx
index c890545..de05cdd 100644
--- a/src/views/candidature-structure/CandidatureStructure.test.jsx
+++ b/src/views/candidature-structure/CandidatureStructure.test.jsx
@@ -3,7 +3,7 @@ import { describe, expect, it, vi } from 'vitest';
import CandidatureStructure from './CandidatureStructure';
import { textMatcher, dateDujour } from '../../../test/test-utils';
import * as ReactRouterDom from 'react-router-dom';
-import { useApiAdmin } from '../candidature-conseiller/useApiAdmin';
+import * as useApiAdmin from '../candidature-conseiller/useApiAdmin';
import { useEntrepriseFinder } from './useEntrepriseFinder';
vi.mock('react-router-dom', () => ({
@@ -519,7 +519,7 @@ describe('candidature structure', () => {
]
];
- const { buildStructureData } = renderHook(() => useApiAdmin()).result.current;
+ const { buildStructureData } = renderHook(() => useApiAdmin.useApiAdmin()).result.current;
const { getGeoLocationFromAddress } = renderHook(() => useEntrepriseFinder()).result.current;
// //WHEN
@@ -555,5 +555,61 @@ describe('candidature structure', () => {
vi.useRealTimers();
});
+
+ it('quand je remplis le formulaire et qu’une erreur se produit alors un message d’erreur s’affiche', async () => {
+ // GIVEN
+ vi.useFakeTimers();
+ vi.setSystemTime(new Date(2023, 11, 12, 13));
+
+ vi.spyOn(useApiAdmin, 'useApiAdmin').mockImplementation(() => ({
+ creerCandidatureStructure: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
+ buildStructureData: vi.fn(),
+ }));
+
+ render();
+ const siret = screen.getByLabelText('SIRET / RIDET *');
+ fireEvent.change(siret, { target: { value: '1234567890123' } });
+ const denomination = screen.getByLabelText('Dénomination *');
+ fireEvent.change(denomination, { target: { value: 'Entreprise' } });
+ const adresse = screen.getByLabelText('Adresse *');
+ fireEvent.change(adresse, { target: { value: '75007 Paris' } });
+ const typeStructure = screen.getByRole('radio', { name: 'Une commune' });
+ fireEvent.click(typeStructure);
+ const prenom = screen.getByLabelText('Prénom *');
+ fireEvent.change(prenom, { target: { value: 'Jean' } });
+ const nom = screen.getByLabelText('Nom *');
+ fireEvent.change(nom, { target: { value: 'Dupont' } });
+ const fonction = screen.getByLabelText('Fonction *');
+ fireEvent.change(fonction, { target: { value: 'Test' } });
+ const email = screen.getByLabelText('Adresse e-mail *');
+ fireEvent.change(email, { target: { value: 'jean.dupont@example.com' } });
+ const telephone = screen.getByLabelText('Téléphone *');
+ fireEvent.change(telephone, { target: { value: '+33123456789' } });
+ const nombre = screen.getByLabelText('Combien de conseillers numériques souhaitez-vous accueillir ?*');
+ fireEvent.change(nombre, { target: { value: 1 } });
+ const identificationCandidat = screen.getByRole('radio', { name: 'Oui' });
+ fireEvent.click(identificationCandidat);
+ const date = screen.getByLabelText('Choisir une date');
+ fireEvent.change(date, { target: { value: dateDujour() } });
+ const descriptionMotivation = screen.getByLabelText('Votre message *');
+ fireEvent.change(descriptionMotivation, { target: { value: 'je suis motivé !' } });
+ const confirmation = screen.getByRole('checkbox', { name: 'Je confirme avoir lu et pris connaissance des conditions d’engagement. *' });
+ fireEvent.click(confirmation);
+
+ // 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 contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
+ expect(contenuErreurValidation).toBeInTheDocument();
+
+ vi.useRealTimers();
+ });
});