import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import * as api from '@/api/index.js'
describe('API request helper', () => {
beforeEach(() => {
vi.stubGlobal('fetch', vi.fn())
})
afterEach(() => {
vi.unstubAllGlobals()
})
it('getProfiles calls GET /agents/profiles', async () => {
global.fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => [{ id: 'secretary' }],
})
const result = await api.getProfiles()
expect(global.fetch).toHaveBeenCalledOnce()
const [url, opts] = global.fetch.mock.calls[0]
expect(url).toContain('/agents/profiles')
expect(opts.method).toBe('GET')
expect(result).toEqual([{ id: 'secretary' }])
})
it('createSession calls POST /sessions with body', async () => {
global.fetch.mockResolvedValue({
ok: true,
status: 201,
json: async () => ({ session_id: 's1' }),
})
const result = await api.createSession('developer')
const [url, opts] = global.fetch.mock.calls[0]
expect(url).toContain('/sessions')
expect(opts.method).toBe('POST')
expect(opts.headers['Content-Type']).toBe('application/json')
expect(JSON.parse(opts.body)).toEqual({ profile_id: 'developer' })
expect(result).toEqual({ session_id: 's1' })
})
it('deleteSession calls DELETE', async () => {
global.fetch.mockResolvedValue({ ok: true, status: 204 })
await api.deleteSession('s1')
const [url, opts] = global.fetch.mock.calls[0]
expect(opts.method).toBe('DELETE')
expect(url).toContain('/sessions/s1')
})
it('204 response returns null', async () => {
global.fetch.mockResolvedValue({ ok: true, status: 204 })
const result = await api.deleteSession('s1')
expect(result).toBeNull()
})
it('4xx throws with status text', async () => {
global.fetch.mockResolvedValue({
ok: false,
status: 404,
text: async () => 'Not found',
})
await expect(api.getSession('bad')).rejects.toThrow('404')
})
it('getSessions calls GET /sessions', async () => {
global.fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => [],
})
await api.getSessions()
const [url] = global.fetch.mock.calls[0]
expect(url).toContain('/sessions')
})
it('pinSession calls PATCH with pinned', async () => {
global.fetch.mockResolvedValue({
ok: true,
status: 200,
json: async () => ({ pinned: true }),
})
await api.pinSession('s1', true)
const [url, opts] = global.fetch.mock.calls[0]
expect(url).toContain('/sessions/s1/pin')
expect(opts.method).toBe('PATCH')
expect(JSON.parse(opts.body)).toEqual({ pinned: true })
})
it('uploadFile sends FormData', async () => {
global.fetch.mockResolvedValue({
ok: true,
status: 201,
json: async () => ({ name: 'file.txt' }),
})
const file = new File(['content'], 'file.txt', { type: 'text/plain' })
await api.uploadFile('s1', file)
const [url, opts] = global.fetch.mock.calls[0]
expect(url).toContain('/sessions/s1/files')
expect(opts.method).toBe('POST')
expect(opts.body instanceof FormData).toBe(true)
})
})