58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||
|
|
import MockAdapter from 'axios-mock-adapter';
|
||
|
|
import { apiClient, getToken, registerUnauthorizedHandler, setToken } from '@/api/client';
|
||
|
|
|
||
|
|
describe('apiClient interceptors', () => {
|
||
|
|
let mock: MockAdapter;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
mock = new MockAdapter(apiClient);
|
||
|
|
setToken(null);
|
||
|
|
});
|
||
|
|
|
||
|
|
afterEach(() => {
|
||
|
|
mock.restore();
|
||
|
|
setToken(null);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('attaches Bearer token from storage', async () => {
|
||
|
|
setToken('abc123');
|
||
|
|
mock.onGet('/auth/me').reply((config) => {
|
||
|
|
expect(config.headers?.Authorization).toBe('Bearer abc123');
|
||
|
|
return [200, { id: 1, username: 'alice', role: 'admin', created_at: '2026-01-01' }];
|
||
|
|
});
|
||
|
|
|
||
|
|
const resp = await apiClient.get('/auth/me');
|
||
|
|
expect(resp.status).toBe(200);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('purges token and calls the registered handler on 401', async () => {
|
||
|
|
setToken('expired');
|
||
|
|
const handler = vi.fn();
|
||
|
|
registerUnauthorizedHandler(handler);
|
||
|
|
|
||
|
|
mock.onGet('/engagements').reply(401, { error: 'token expired' });
|
||
|
|
|
||
|
|
await expect(apiClient.get('/engagements')).rejects.toMatchObject({
|
||
|
|
response: { status: 401 },
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(getToken()).toBeNull();
|
||
|
|
expect(handler).toHaveBeenCalledTimes(1);
|
||
|
|
|
||
|
|
// Reset to avoid leaking into other tests.
|
||
|
|
registerUnauthorizedHandler(() => {});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('leaves the token intact on non-401 errors', async () => {
|
||
|
|
setToken('still-valid');
|
||
|
|
mock.onGet('/users').reply(403, { error: 'forbidden' });
|
||
|
|
|
||
|
|
await expect(apiClient.get('/users')).rejects.toMatchObject({
|
||
|
|
response: { status: 403 },
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(getToken()).toBe('still-valid');
|
||
|
|
});
|
||
|
|
});
|