Initial commit
This commit is contained in:
241
app/(main)/dashboard/__tests__/page.test.tsx
Normal file
241
app/(main)/dashboard/__tests__/page.test.tsx
Normal file
@@ -0,0 +1,241 @@
|
||||
import React from 'react'
|
||||
import { render, screen, waitFor } from '../../../../test-utils'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import Dashboard from '../page'
|
||||
import useDashboard from '../../../../hooks/useDashboard'
|
||||
|
||||
// Mock des hooks
|
||||
jest.mock('../../../../hooks/useDashboard')
|
||||
jest.mock('../../../../components/auth/ProtectedRoute', () => {
|
||||
return function MockProtectedRoute({ children }: { children: React.ReactNode }) {
|
||||
return <div data-testid="protected-route">{children}</div>
|
||||
}
|
||||
})
|
||||
|
||||
const mockUseDashboard = useDashboard as jest.MockedFunction<typeof useDashboard>
|
||||
|
||||
const mockDashboardData = {
|
||||
stats: {
|
||||
totalChantiers: 12,
|
||||
chiffreAffaires: 125000,
|
||||
totalClients: 34,
|
||||
facturesEnRetard: 3,
|
||||
},
|
||||
chantiersRecents: [
|
||||
{
|
||||
id: '1',
|
||||
nom: 'Rénovation Bureau',
|
||||
client: 'Entreprise ABC',
|
||||
statut: 'EN_COURS' as const,
|
||||
dateDebut: '2024-01-15',
|
||||
montantPrevu: 45000,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
nom: 'Construction Garage',
|
||||
client: 'Client XYZ',
|
||||
statut: 'PLANIFIE' as const,
|
||||
dateDebut: '2024-02-01',
|
||||
montantPrevu: 25000,
|
||||
},
|
||||
],
|
||||
facturesEnRetard: [
|
||||
{
|
||||
id: '1',
|
||||
numero: 'F2024-001',
|
||||
client: 'Client A',
|
||||
montant: 5000,
|
||||
dateEcheance: '2024-01-01',
|
||||
},
|
||||
],
|
||||
devisEnAttente: [
|
||||
{
|
||||
id: '1',
|
||||
numero: 'D2024-001',
|
||||
client: 'Client B',
|
||||
montant: 8000,
|
||||
dateCreation: '2024-01-10',
|
||||
},
|
||||
],
|
||||
loading: false,
|
||||
error: null,
|
||||
refresh: jest.fn(),
|
||||
}
|
||||
|
||||
describe('Page Dashboard', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
mockUseDashboard.mockReturnValue(mockDashboardData)
|
||||
})
|
||||
|
||||
it('devrait afficher le dashboard avec toutes les sections', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
expect(screen.getByTestId('protected-route')).toBeInTheDocument()
|
||||
expect(screen.getByText('Tableau de Bord BTP Xpress')).toBeInTheDocument()
|
||||
expect(screen.getByText('Bienvenue sur votre plateforme de gestion BTP. Voici un aperçu de vos projets en cours.')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait afficher les cartes de statistiques', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
expect(screen.getByText('Projets actifs')).toBeInTheDocument()
|
||||
expect(screen.getByText('Budget total')).toBeInTheDocument()
|
||||
expect(screen.getByText('Clients')).toBeInTheDocument()
|
||||
expect(screen.getByText('Factures impayées')).toBeInTheDocument()
|
||||
|
||||
// Vérifier les valeurs
|
||||
expect(screen.getByText('12')).toBeInTheDocument()
|
||||
expect(screen.getByText('125 000 €')).toBeInTheDocument()
|
||||
expect(screen.getByText('34')).toBeInTheDocument()
|
||||
expect(screen.getByText('3')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait afficher les chantiers récents', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
expect(screen.getByText('Rénovation Bureau')).toBeInTheDocument()
|
||||
expect(screen.getByText('Construction Garage')).toBeInTheDocument()
|
||||
expect(screen.getByText('Entreprise ABC')).toBeInTheDocument()
|
||||
expect(screen.getByText('Client XYZ')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait permettre d\'actualiser les données', async () => {
|
||||
const user = userEvent.setup()
|
||||
const mockRefresh = jest.fn()
|
||||
mockUseDashboard.mockReturnValue({
|
||||
...mockDashboardData,
|
||||
refresh: mockRefresh,
|
||||
})
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
const refreshButton = screen.getByText('Actualiser')
|
||||
await user.click(refreshButton)
|
||||
|
||||
expect(mockRefresh).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('devrait afficher l\'état de chargement', () => {
|
||||
mockUseDashboard.mockReturnValue({
|
||||
...mockDashboardData,
|
||||
loading: true,
|
||||
})
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
const refreshButton = screen.getByText('Actualiser')
|
||||
expect(refreshButton).toHaveAttribute('data-pc-section', 'loadingicon')
|
||||
})
|
||||
|
||||
it('devrait afficher les erreurs', () => {
|
||||
mockUseDashboard.mockReturnValue({
|
||||
...mockDashboardData,
|
||||
error: 'Erreur de connexion au serveur',
|
||||
})
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
expect(screen.getByText('Erreur de connexion au serveur')).toBeInTheDocument()
|
||||
expect(screen.getByText('Réessayer')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait permettre de réessayer après une erreur', async () => {
|
||||
const user = userEvent.setup()
|
||||
const mockRefresh = jest.fn()
|
||||
mockUseDashboard.mockReturnValue({
|
||||
...mockDashboardData,
|
||||
error: 'Erreur de connexion',
|
||||
refresh: mockRefresh,
|
||||
})
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
const retryButton = screen.getByText('Réessayer')
|
||||
await user.click(retryButton)
|
||||
|
||||
expect(mockRefresh).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('devrait afficher les valeurs par défaut quand les stats sont vides', () => {
|
||||
mockUseDashboard.mockReturnValue({
|
||||
...mockDashboardData,
|
||||
stats: null,
|
||||
})
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
// Vérifier que les valeurs par défaut (0) sont affichées
|
||||
expect(screen.getByText('0')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait afficher les icônes correctes pour chaque statistique', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
expect(document.querySelector('.pi-building')).toBeInTheDocument()
|
||||
expect(document.querySelector('.pi-euro')).toBeInTheDocument()
|
||||
expect(document.querySelector('.pi-users')).toBeInTheDocument()
|
||||
expect(document.querySelector('.pi-exclamation-triangle')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait afficher les tendances sur les cartes', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
// Vérifier que les tendances sont affichées
|
||||
expect(screen.getByText('+12%')).toBeInTheDocument()
|
||||
expect(screen.getByText('+8%')).toBeInTheDocument()
|
||||
expect(screen.getByText('+15%')).toBeInTheDocument()
|
||||
expect(screen.getByText('-5%')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait avoir une mise en page responsive', () => {
|
||||
const { container } = render(<Dashboard />)
|
||||
|
||||
// Vérifier la structure en grille
|
||||
expect(container.querySelector('.grid')).toBeInTheDocument()
|
||||
expect(container.querySelector('.col-12')).toBeInTheDocument()
|
||||
expect(container.querySelector('.col-12.md\\:col-3')).toBeInTheDocument()
|
||||
expect(container.querySelector('.col-12.md\\:col-8')).toBeInTheDocument()
|
||||
expect(container.querySelector('.col-12.md\\:col-4')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait gérer les actions sur les chantiers', () => {
|
||||
// Spy sur console.log pour vérifier les handlers
|
||||
const consoleSpy = jest.spyOn(console, 'log').mockImplementation()
|
||||
|
||||
render(<Dashboard />)
|
||||
|
||||
// Les handlers sont appelés dans le composant mais pas directement testables
|
||||
// On peut vérifier leur présence dans le code
|
||||
expect(consoleSpy).not.toHaveBeenCalled()
|
||||
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('devrait utiliser le ProtectedRoute avec les bonnes permissions', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
// Vérifier que le composant est wrappé dans ProtectedRoute
|
||||
expect(screen.getByTestId('protected-route')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('devrait afficher un toast après actualisation', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(<Dashboard />)
|
||||
|
||||
const refreshButton = screen.getByText('Actualiser')
|
||||
await user.click(refreshButton)
|
||||
|
||||
// Le toast est géré par PrimeReact, on vérifie juste que la fonction est appelée
|
||||
await waitFor(() => {
|
||||
expect(mockDashboardData.refresh).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it('devrait formater correctement les montants', () => {
|
||||
render(<Dashboard />)
|
||||
|
||||
// Vérifier que le chiffre d'affaires est formaté
|
||||
expect(screen.getByText('125 000 €')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user