import React from 'react' import { render, screen, waitFor } from '../../../../test-utils' import userEvent from '@testing-library/user-event' import ClientsPage from '../page' import { clientService } from '../../../../services/api' import { Client } from '../../../../types/btp' // Mock des services jest.mock('../../../../services/api') const mockClientService = clientService as jest.Mocked const mockClients: Client[] = [ { id: '1', nom: 'Dupont', prenom: 'Jean', entreprise: 'Entreprise ABC', email: 'jean.dupont@abc.com', telephone: '0612345678', adresse: '123 rue de la Paix', codePostal: '75001', ville: 'Paris', numeroTVA: 'FR12345678901', siret: '12345678901234', actif: true, }, { id: '2', nom: 'Martin', prenom: 'Marie', entreprise: 'Société XYZ', email: 'marie.martin@xyz.com', telephone: '0687654321', adresse: '456 avenue des Champs', codePostal: '75008', ville: 'Paris', numeroTVA: 'FR98765432109', siret: '98765432109876', actif: true, }, ] describe('Page Clients', () => { beforeEach(() => { jest.clearAllMocks() mockClientService.getAll.mockResolvedValue(mockClients) }) it('devrait charger et afficher la liste des clients', async () => { render() expect(screen.getByText('Gestion des Clients')).toBeInTheDocument() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() expect(screen.getByText('Marie Martin')).toBeInTheDocument() }) expect(mockClientService.getAll).toHaveBeenCalledTimes(1) }) it('devrait permettre d\'ouvrir le formulaire de création', async () => { const user = userEvent.setup() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) const newButton = screen.getByText('Nouveau') await user.click(newButton) expect(screen.getByText('Détails du Client')).toBeInTheDocument() expect(screen.getByLabelText('Nom')).toBeInTheDocument() expect(screen.getByLabelText('Prénom')).toBeInTheDocument() }) it('devrait permettre de créer un nouveau client', async () => { const user = userEvent.setup() const newClient = { id: '3', nom: 'Nouveau', prenom: 'Client', entreprise: 'Nouvelle Entreprise', email: 'nouveau@client.com', telephone: '0123456789', adresse: '789 rue Neuve', codePostal: '69000', ville: 'Lyon', numeroTVA: 'FR11111111111', siret: '11111111111111', actif: true, } mockClientService.create.mockResolvedValue(newClient) render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Ouvrir le formulaire const newButton = screen.getByText('Nouveau') await user.click(newButton) // Remplir le formulaire await user.type(screen.getByLabelText('Nom'), 'Nouveau') await user.type(screen.getByLabelText('Prénom'), 'Client') await user.type(screen.getByLabelText('Entreprise'), 'Nouvelle Entreprise') await user.type(screen.getByLabelText('Email'), 'nouveau@client.com') await user.type(screen.getByLabelText('Téléphone'), '0123456789') await user.type(screen.getByLabelText('Adresse'), '789 rue Neuve') await user.type(screen.getByLabelText('Code Postal'), '69000') await user.type(screen.getByLabelText('Ville'), 'Lyon') // Sauvegarder const saveButton = screen.getByText('Sauvegarder') await user.click(saveButton) await waitFor(() => { expect(mockClientService.create).toHaveBeenCalledWith({ id: '', nom: 'Nouveau', prenom: 'Client', entreprise: 'Nouvelle Entreprise', email: 'nouveau@client.com', telephone: '0123456789', adresse: '789 rue Neuve', codePostal: '69000', ville: 'Lyon', numeroTVA: '', siret: '', actif: true, }) }) }) it('devrait permettre de modifier un client existant', async () => { const user = userEvent.setup() const updatedClient = { ...mockClients[0], nom: 'Dupont-Modifié' } mockClientService.update.mockResolvedValue(updatedClient) render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Cliquer sur le bouton d'édition const editButtons = screen.getAllByRole('button', { name: '' }) const editButton = editButtons.find(button => button.querySelector('.pi-pencil') ) expect(editButton).toBeInTheDocument() await user.click(editButton!) // Modifier le nom const nomInput = screen.getByLabelText('Nom') await user.clear(nomInput) await user.type(nomInput, 'Dupont-Modifié') // Sauvegarder const saveButton = screen.getByText('Sauvegarder') await user.click(saveButton) await waitFor(() => { expect(mockClientService.update).toHaveBeenCalledWith('1', { ...mockClients[0], nom: 'Dupont-Modifié', }) }) }) it('devrait permettre de supprimer un client', async () => { const user = userEvent.setup() mockClientService.delete.mockResolvedValue() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Cliquer sur le bouton de suppression const deleteButtons = screen.getAllByRole('button', { name: '' }) const deleteButton = deleteButtons.find(button => button.querySelector('.pi-trash') ) expect(deleteButton).toBeInTheDocument() await user.click(deleteButton!) // Confirmer la suppression expect(screen.getByText('Êtes-vous sûr de vouloir supprimer Jean Dupont ?')).toBeInTheDocument() const confirmButton = screen.getByText('Oui') await user.click(confirmButton) await waitFor(() => { expect(mockClientService.delete).toHaveBeenCalledWith('1') }) }) it('devrait permettre la recherche dans la liste', async () => { const user = userEvent.setup() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() expect(screen.getByText('Marie Martin')).toBeInTheDocument() }) // Rechercher "Jean" const searchInput = screen.getByPlaceholderText('Rechercher...') await user.type(searchInput, 'Jean') // La recherche est gérée par PrimeReact DataTable // On vérifie que l'input a bien la valeur expect(searchInput).toHaveValue('Jean') }) it('devrait permettre d\'exporter les données', async () => { const user = userEvent.setup() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) const exportButton = screen.getByText('Exporter') expect(exportButton).toBeInTheDocument() // L'export est géré par PrimeReact DataTable await user.click(exportButton) }) it('devrait valider les champs requis', async () => { const user = userEvent.setup() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Ouvrir le formulaire const newButton = screen.getByText('Nouveau') await user.click(newButton) // Essayer de sauvegarder sans remplir les champs requis const saveButton = screen.getByText('Sauvegarder') await user.click(saveButton) // Vérifier les messages d'erreur await waitFor(() => { expect(screen.getByText('Le nom est requis.')).toBeInTheDocument() expect(screen.getByText('Le prénom est requis.')).toBeInTheDocument() }) // Le service ne devrait pas être appelé expect(mockClientService.create).not.toHaveBeenCalled() }) it('devrait afficher les erreurs de l\'API', async () => { const user = userEvent.setup() mockClientService.create.mockRejectedValue(new Error('Erreur serveur')) render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Ouvrir le formulaire et remplir les champs requis const newButton = screen.getByText('Nouveau') await user.click(newButton) await user.type(screen.getByLabelText('Nom'), 'Test') await user.type(screen.getByLabelText('Prénom'), 'Client') // Sauvegarder const saveButton = screen.getByText('Sauvegarder') await user.click(saveButton) // Vérifier qu'une erreur est affichée await waitFor(() => { expect(screen.getByText('Impossible de sauvegarder le client')).toBeInTheDocument() }) }) it('devrait permettre la suppression multiple', async () => { const user = userEvent.setup() mockClientService.delete.mockResolvedValue() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Sélectionner plusieurs clients const checkboxes = screen.getAllByRole('checkbox') await user.click(checkboxes[1]) // Premier client await user.click(checkboxes[2]) // Deuxième client // Supprimer les clients sélectionnés const deleteButton = screen.getByText('Supprimer') await user.click(deleteButton) // Confirmer la suppression const confirmButton = screen.getByText('Oui') await user.click(confirmButton) await waitFor(() => { expect(mockClientService.delete).toHaveBeenCalledTimes(2) }) }) it('devrait afficher les statuts des clients', async () => { render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Vérifier que les statuts "Actif" sont affichés const activeStatuses = screen.getAllByText('Actif') expect(activeStatuses).toHaveLength(2) }) it('devrait formater les numéros de téléphone', async () => { render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Les numéros de téléphone sont formatés par la fonction formatPhoneNumber expect(screen.getByText('0612345678')).toBeInTheDocument() expect(screen.getByText('0687654321')).toBeInTheDocument() }) it('devrait formater les adresses complètes', async () => { render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Les adresses sont formatées par la fonction formatAddress expect(screen.getByText('123 rue de la Paix, 75001 Paris')).toBeInTheDocument() expect(screen.getByText('456 avenue des Champs, 75008 Paris')).toBeInTheDocument() }) it('devrait gérer l\'état de chargement', () => { mockClientService.getAll.mockImplementation( () => new Promise(() => {}) // Promise qui ne se résout jamais ) render() // Vérifier que le tableau est en état de chargement const dataTable = document.querySelector('[data-pc-name="datatable"]') expect(dataTable).toBeInTheDocument() }) it('devrait annuler les modifications', async () => { const user = userEvent.setup() render() await waitFor(() => { expect(screen.getByText('Jean Dupont')).toBeInTheDocument() }) // Ouvrir le formulaire const newButton = screen.getByText('Nouveau') await user.click(newButton) // Remplir partiellement le formulaire await user.type(screen.getByLabelText('Nom'), 'Test') // Annuler const cancelButton = screen.getByText('Annuler') await user.click(cancelButton) // Vérifier que le formulaire est fermé expect(screen.queryByText('Détails du Client')).not.toBeInTheDocument() }) })