Initial commit
This commit is contained in:
389
app/(main)/clients/__tests__/page.test.tsx
Normal file
389
app/(main)/clients/__tests__/page.test.tsx
Normal file
@@ -0,0 +1,389 @@
|
||||
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<typeof clientService>
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
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(<ClientsPage />)
|
||||
|
||||
// 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(<ClientsPage />)
|
||||
|
||||
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()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user