import { describe, it, expect, vi, beforeEach } from 'vitest' import { sendMessage, testConnection } from '../utils/llmApi.js' describe('LLM API', () => { beforeEach(() => { vi.clearAllMocks() }) describe('sendMessage', () => { it('should throw error when endpoint is missing', async () => { await expect(sendMessage('', 'hello')).rejects.toThrow('API endpoint is required') }) it('should send POST request and extract content from response', async () => { global.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ choices: [{ message: { content: 'Hello there!' } }] }) }) ) const result = await sendMessage('https://api.example.com/chat', 'Hi') expect(fetch).toHaveBeenCalledWith( 'https://api.example.com/chat', expect.objectContaining({ method: 'POST', headers: { 'Content-Type': 'application/json' } }) ) expect(result).toBe('Hello there!') }) it('should throw error when response has no content', async () => { global.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ choices: [] }) }) ) await expect(sendMessage('https://api.example.com/chat', 'Hi')) .rejects.toThrow('Invalid response format: no content found') }) it('should throw error on network failure', async () => { global.fetch = vi.fn(() => Promise.reject(new Error('Network error'))) await expect(sendMessage('https://api.example.com/chat', 'Hi')) .rejects.toThrow('Network error') }) it('should include system prompt when provided', async () => { global.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ choices: [{ message: { content: 'Response' } }] }) }) ) await sendMessage('https://api.example.com/chat', 'Hi', [], 'You are helpful') const callBody = JSON.parse(global.fetch.mock.calls[0][1].body) expect(callBody.messages[0]).toEqual({ role: 'system', content: 'You are helpful' }) }) it('should include message history', async () => { global.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ choices: [{ message: { content: 'Response' } }] }) }) ) const history = [ { role: 'user', content: 'Hello' }, { role: 'assistant', content: 'Hi there!' } ] await sendMessage('https://api.example.com/chat', 'How are you?', history) const callBody = JSON.parse(global.fetch.mock.calls[0][1].body) expect(callBody.messages[0]).toEqual({ role: 'user', content: 'Hello' }) expect(callBody.messages[1]).toEqual({ role: 'assistant', content: 'Hi there!' }) expect(callBody.messages[2]).toEqual({ role: 'user', content: 'How are you?' }) }) }) describe('testConnection', () => { it('should return true on successful response', async () => { global.fetch = vi.fn(() => Promise.resolve({ status: 200 }) ) const result = await testConnection('https://api.example.com/chat') expect(result).toBe(true) }) it('should return true on error response (not 404)', async () => { global.fetch = vi.fn(() => Promise.resolve({ status: 401 }) ) const result = await testConnection('https://api.example.com/chat') expect(result).toBe(true) }) it('should return false on 404', async () => { global.fetch = vi.fn(() => Promise.resolve({ status: 404 }) ) const result = await testConnection('https://api.example.com/chat') expect(result).toBe(false) }) it('should return false on network error', async () => { global.fetch = vi.fn(() => Promise.reject(new Error('Network error'))) const result = await testConnection('https://api.example.com/chat') expect(result).toBe(false) }) }) })