/* Tests du service API : authentification et gestion du token JWT */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { login, getServices, getToken, setToken } from '../services/api'; describe('api.login', () => { beforeEach(() => { localStorage.clear(); vi.restoreAllMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); it('stocke le token et envoie un corps urlencoded', async () => { const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({ access_token: 'jwt-abc-123', token_type: 'bearer', user: { username: 'alice', role: 'Admin' }, }), }); vi.stubGlobal('fetch', fetchMock); const user = await login('alice', 's3cret'); /* Le token est persisté */ expect(getToken()).toBe('jwt-abc-123'); /* L'utilisateur retourné provient de la réponse */ expect(user).toEqual({ username: 'alice', role: 'Admin' }); /* Vérifie l'URL, la méthode et l'en-tête de contenu */ const [url, options] = fetchMock.mock.calls[0]; expect(url).toMatch(/\/auth\/login$/); expect(options.method).toBe('POST'); expect(options.headers['Content-Type']).toBe('application/x-www-form-urlencoded'); /* Le corps urlencoded contient bien username et password */ const params = new URLSearchParams(options.body); expect(params.get('username')).toBe('alice'); expect(params.get('password')).toBe('s3cret'); }); it('lève "Identifiants invalides" sur une réponse 401', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: false, status: 401, text: async () => 'Unauthorized', })); await expect(login('alice', 'wrong')).rejects.toThrow('Identifiants invalides'); expect(getToken()).toBeNull(); }); }); describe('fetchApi (401)', () => { beforeEach(() => { localStorage.clear(); vi.restoreAllMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); it('purge le token lorsqu\'une requête renvoie 401', async () => { setToken('expired-token'); expect(getToken()).toBe('expired-token'); vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: false, status: 401, text: async () => 'Unauthorized', })); await expect(getServices()).rejects.toThrow(); /* Le token doit avoir été supprimé par handleUnauthorized */ expect(getToken()).toBeNull(); }); });