import { ChatServiceError, extractChatText, normalizeChatMessages, sendReportableCommandMessage, sendChatMessage, } from '../src/features/chat/chat-service' const originalFetch = global.fetch afterEach(() => { global.fetch = originalFetch }) describe('chat service', () => { it('normalizes bounded messages and extracts text blocks', () => { expect(normalizeChatMessages([{ role: 'user', content: ' hello ' }])) .toEqual([{ role: 'user', content: 'hello' }]) expect(extractChatText({ content: [ { type: 'text', text: 'hello ' }, { type: 'tool_use', input: {} }, { type: 'text', text: 'world' }, ] })).toBe('hello world') }) it('rejects invalid requests before network I/O', async () => { global.fetch = jest.fn() await expect(sendChatMessage([], { accessToken: 'token' })) .rejects.toMatchObject({ code: 'INVALID_REQUEST', retryable: false }) expect(global.fetch).not.toHaveBeenCalled() }) it('maps quota responses without creating a fallback answer', async () => { global.fetch = jest.fn().mockResolvedValue({ ok: false, status: 429, json: async () => ({ error: 'quota_exceeded' }), }) await expect(sendChatMessage([{ role: 'user', content: 'hello' }], { accessToken: 'token' })) .rejects.toMatchObject({ code: 'QUOTA_EXCEEDED', retryable: false, status: 429 }) }) it('requires a non-empty provider response', async () => { global.fetch = jest.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({ content: [{ type: 'text', text: '' }] }), }) await expect(sendChatMessage([{ role: 'user', content: 'hello' }], { accessToken: 'token' })) .rejects.toBeInstanceOf(ChatServiceError) }) it('requires and returns a server-issued receipt for reportable command output', async () => { const generationId = '11111111-1111-4111-8111-111111111111' global.fetch = jest.fn().mockResolvedValue({ ok: true, status: 200, headers: { get: (name: string) => name.toLowerCase() === 'x-d3ro-generation-id' ? generationId : null }, json: async () => ({ content: [{ type: 'text', text: 'result' }] }), }) await expect(sendReportableCommandMessage( [{ role: 'user', content: 'hello' }], { accessToken: 'token' }, )).resolves.toEqual({ text: 'result', generationId }) const request = (global.fetch as jest.Mock).mock.calls[0][1] expect(request.headers['X-D3RO-Generation-Purpose']).toBe('command_response') }) })