import { PaperclipClient } from '../src/client.js'; const mockFetch = jest.fn(); global.fetch = mockFetch as any; describe('PaperclipClient', () => { let client: PaperclipClient; beforeEach(() => { process.env.PAPERCLIP_API_URL = 'https://clip.descomplicar.pt/api'; process.env.PAPERCLIP_API_KEY = 'test_key'; process.env.PAPERCLIP_COMPANY_ID = 'test-company-id'; client = new PaperclipClient(); mockFetch.mockReset(); }); test('GET sends correct headers', async () => { mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ status: 'ok' }) }); await client.get('/health'); expect(mockFetch).toHaveBeenCalledWith( 'https://clip.descomplicar.pt/api/health', expect.objectContaining({ method: 'GET', headers: expect.objectContaining({ Authorization: 'Bearer test_key' }), }), ); }); test('companyPath injects company ID', () => { expect(client.companyPath('/agents')).toBe('/companies/test-company-id/agents'); }); test('POST sends JSON body', async () => { mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ id: '123' }) }); await client.post('/companies/test-company-id/issues', { title: 'Test' }); expect(mockFetch).toHaveBeenCalledWith( 'https://clip.descomplicar.pt/api/companies/test-company-id/issues', expect.objectContaining({ method: 'POST', body: JSON.stringify({ title: 'Test' }), }), ); }); test('handles 401 with clear error', async () => { mockFetch.mockResolvedValueOnce({ ok: false, status: 401, statusText: 'Unauthorized', json: async () => ({ error: 'Unauthorized' }) }); await expect(client.get('/health')).rejects.toThrow('Sem autorização. Verificar PAPERCLIP_API_KEY.'); }); test('handles 404 with resource info', async () => { mockFetch.mockResolvedValueOnce({ ok: false, status: 404, statusText: 'Not Found', json: async () => ({ error: 'Not found' }) }); await expect(client.get('/agents/abc')).rejects.toThrow('Recurso não encontrado: /agents/abc'); }); });