test: ajoute des tests automatisés frontend (Vitest) et mobile (Jest)
- Frontend Next.js : Vitest + Testing Library - Button (rendu, clic, état loading) - auth-store (setAuth, déconnexion, persistance token) - script `npm test`, config jsdom + alias @/ - Mobile Expo : Jest (preset jest-expo) - getApiError (erreur Axios, validation, erreur générique, sans réponse) - script `npm test`, transformIgnorePatterns adapté - Cahier de tests : section « Outils de test automatisés » (PHPUnit + Vitest + Jest) et entrée 6.4 (PV de recette) au sommaire Suites vertes : backend 15, frontend 6, mobile 4. tsc/lint/build OK, expo-doctor 18/18. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import Button from '@/components/ui/Button';
|
||||
|
||||
describe('Button', () => {
|
||||
it('affiche son libellé', () => {
|
||||
render(<Button>Enregistrer</Button>);
|
||||
expect(screen.getByRole('button', { name: 'Enregistrer' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('déclenche onClick au clic', () => {
|
||||
const onClick = vi.fn();
|
||||
render(<Button onClick={onClick}>Valider</Button>);
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Valider' }));
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('est désactivé pendant le chargement et ne déclenche pas onClick', () => {
|
||||
const onClick = vi.fn();
|
||||
render(
|
||||
<Button loading onClick={onClick}>
|
||||
Envoi
|
||||
</Button>
|
||||
);
|
||||
const btn = screen.getByRole('button');
|
||||
expect(btn).toBeDisabled();
|
||||
fireEvent.click(btn);
|
||||
expect(onClick).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { useAuthStore } from '@/lib/auth-store';
|
||||
import type { Utilisateur } from '@/types';
|
||||
|
||||
const fakeUser = {
|
||||
id: 1,
|
||||
nom: 'Martin',
|
||||
prenom: 'Claire',
|
||||
email: 'claire@email.fr',
|
||||
role: { id: 2, nom: 'membre' },
|
||||
} as unknown as Utilisateur;
|
||||
|
||||
describe('auth-store', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
useAuthStore.setState({ user: null, token: null, isAuthenticated: false });
|
||||
});
|
||||
|
||||
it('démarre déconnecté', () => {
|
||||
const state = useAuthStore.getState();
|
||||
expect(state.isAuthenticated).toBe(false);
|
||||
expect(state.token).toBeNull();
|
||||
});
|
||||
|
||||
it('setAuth stocke le token et authentifie l\'utilisateur', () => {
|
||||
useAuthStore.getState().setAuth(fakeUser, 'jwt-123');
|
||||
const state = useAuthStore.getState();
|
||||
expect(state.isAuthenticated).toBe(true);
|
||||
expect(state.token).toBe('jwt-123');
|
||||
expect(state.user?.email).toBe('claire@email.fr');
|
||||
expect(localStorage.getItem('cesizen_token')).toBe('jwt-123');
|
||||
});
|
||||
|
||||
it('setAuth(null) déconnecte et purge le token', () => {
|
||||
useAuthStore.getState().setAuth(fakeUser, 'jwt-123');
|
||||
useAuthStore.getState().setAuth(null, null);
|
||||
const state = useAuthStore.getState();
|
||||
expect(state.isAuthenticated).toBe(false);
|
||||
expect(state.token).toBeNull();
|
||||
expect(localStorage.getItem('cesizen_token')).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user