Files
Front-DataSentinel/DataSentinel/src/__tests__/api.test.jsx
T

83 lines
2.4 KiB
React

/* 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();
});
});