import { afterEach, describe, expect, it, vi } from 'vitest' import { api } from './api' describe('api helper', () => { afterEach(() => { vi.restoreAllMocks() }) it('returns parsed json when content-type is json', async () => { const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue( new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'content-type': 'application/json' }, }), ) const res = await api<{ ok: boolean }>('/api/healthz') expect(res.ok).toBe(true) expect(fetchMock).toHaveBeenCalledWith('/api/healthz', { credentials: 'include' }) }) it('parses json from text payload when response header is not json', async () => { vi.spyOn(globalThis, 'fetch').mockResolvedValue( new Response('{"value":42}', { status: 200, headers: { 'content-type': 'text/plain' }, }), ) const res = await api<{ value: number }>('/api/text-json') expect(res.value).toBe(42) }) it('returns raw text when text is not json', async () => { vi.spyOn(globalThis, 'fetch').mockResolvedValue( new Response('hello', { status: 200, headers: { 'content-type': 'text/plain' }, }), ) const res = await api('/api/text') expect(res).toBe('hello') }) it('throws server message when response is not ok', async () => { vi.spyOn(globalThis, 'fetch').mockResolvedValue( new Response('invalid credentials', { status: 401, headers: { 'content-type': 'text/plain' }, }), ) await expect(api('/api/login')).rejects.toThrow('invalid credentials') }) })