Files
dashboard-cpsp/services/__tests__/apiClient.test.ts
T

76 lines
2.3 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest';
import { api, ApiError, errorMessage } from '../apiClient.ts';
const jsonResponse = (body: unknown, status = 200, headers: Record<string, string> = {}) =>
new Response(JSON.stringify(body), {
status,
headers: { 'Content-Type': 'application/json', ...headers },
});
describe('apiClient', () => {
afterEach(() => {
vi.unstubAllGlobals();
document.cookie = 'csrftoken=; Max-Age=0; path=/';
});
it('unwraps paginated list results', async () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValue(
jsonResponse({
count: 1,
next: null,
previous: null,
results: [{ id: 7, site_name: 'Sukawarna', user: 1 }],
})
)
);
const sites = await api.sites.list();
expect(sites).toEqual([{ id: 7, site_name: 'Sukawarna', user: 1 }]);
});
it('unwraps a bare array list', async () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValue(jsonResponse([{ id: 2, site_name: 'Cilayang', user: 1 }]))
);
const sites = await api.sites.list();
expect(sites[0]?.site_name).toBe('Cilayang');
});
it('sends CSRF token on POST', async () => {
document.cookie = 'csrftoken=abc123; path=/';
const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ id: 1, user_name: 'admin', display_name: 'Admin' }));
vi.stubGlobal('fetch', fetchMock);
await api.auth.login('admin', 'admin123');
const init = fetchMock.mock.calls[0]?.[1] as RequestInit;
const headers = new Headers(init.headers);
expect(headers.get('X-CSRFToken')).toBe('abc123');
expect(init.credentials).toBe('include');
});
it('throws ApiError with detail and status', async () => {
document.cookie = 'csrftoken=abc123; path=/';
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValue(jsonResponse({ detail: 'Bad credentials' }, 400))
);
await expect(api.auth.login('x', 'y')).rejects.toMatchObject({
name: 'ApiError',
status: 400,
message: 'Bad credentials',
});
});
it('maps unknown errors through errorMessage', () => {
expect(errorMessage(new ApiError('Gagal', 502, null))).toBe('Gagal');
expect(errorMessage(new Error('boom'))).toBe('boom');
expect(errorMessage('nope')).toBe('Terjadi kesalahan');
});
});