import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { loginApi, registerApi, verifyCodeApi, changePasswordApi } from '../../services/auth' // Tests unitaires du service auth : on mocke fetch, aucune vraie requête HTTP. const mockFetch = vi.fn() function jsonResponse(body, { ok = true, status = 200 } = {}) { return Promise.resolve({ ok, status, json: () => Promise.resolve(body) }) } beforeEach(() => { vi.stubGlobal('fetch', mockFetch) mockFetch.mockReset() }) afterEach(() => { vi.unstubAllGlobals() }) describe('loginApi', () => { it('envoie email et mot de passe et renvoie les données', async () => { const payload = { token: 'jwt', user: { email: 'a@b.fr', role: 'CLIENT' } } mockFetch.mockReturnValue(jsonResponse(payload)) const data = await loginApi({ email: 'a@b.fr', password: 'secret' }) expect(data).toEqual(payload) expect(mockFetch).toHaveBeenCalledWith('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'a@b.fr', password: 'secret' }), }) }) it("lève une erreur avec le message et le status de l'API en cas d'échec", async () => { mockFetch.mockReturnValue( jsonResponse({ message: 'Identifiants invalides.' }, { ok: false, status: 401 }) ) await expect(loginApi({ email: 'a@b.fr', password: 'faux' })).rejects.toMatchObject({ message: 'Identifiants invalides.', status: 401, }) }) it("utilise un message par défaut si l'API n'en renvoie pas", async () => { mockFetch.mockReturnValue(jsonResponse({}, { ok: false, status: 500 })) await expect(loginApi({ email: 'a@b.fr', password: 'x' })).rejects.toThrow( 'Erreur de connexion.' ) }) }) describe('registerApi', () => { it("envoie les informations d'inscription", async () => { mockFetch.mockReturnValue(jsonResponse({ message: 'ok' })) await registerApi({ email: 'a@b.fr', firstname: 'Jean', lastname: 'Dupont', password: 'secret' }) expect(mockFetch).toHaveBeenCalledWith('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'a@b.fr', firstname: 'Jean', lastname: 'Dupont', password: 'secret' }), }) }) }) describe('verifyCodeApi', () => { it('renvoie le token et le user quand le code est valide', async () => { const payload = { token: 'jwt', user: { email: 'a@b.fr' } } mockFetch.mockReturnValue(jsonResponse(payload)) const data = await verifyCodeApi({ email: 'a@b.fr', code: '1234' }) expect(data).toEqual(payload) }) it('lève "Code invalide." par défaut en cas d\'échec', async () => { mockFetch.mockReturnValue(jsonResponse({}, { ok: false, status: 400 })) await expect(verifyCodeApi({ email: 'a@b.fr', code: '0000' })).rejects.toThrow('Code invalide.') }) }) describe('changePasswordApi', () => { it('envoie le token du localStorage dans le header Authorization', async () => { localStorage.setItem('token', 'mon-jwt') mockFetch.mockReturnValue(jsonResponse({ message: 'ok' })) await changePasswordApi({ currentPassword: 'ancien', newPassword: 'nouveau' }) expect(mockFetch).toHaveBeenCalledWith('/api/auth/change-password', { method: 'PATCH', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer mon-jwt', }, body: JSON.stringify({ currentPassword: 'ancien', newPassword: 'nouveau' }), }) }) })