import { Log } from '../../native_adapters/configuration' import { instrumentedFetch } from '../instrumented_fetch' const buildResponse = (status: number) => new Response('', { status }) describe('instrumentedFetch', () => { let reportError: jest.SpyInstance let warnSpy: jest.SpyInstance let fetchSpy: jest.SpyInstance beforeEach(() => { reportError = jest.spyOn(Log, 'reportError').mockImplementation(() => {}) warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}) fetchSpy = jest.spyOn(globalThis, 'fetch') }) afterEach(() => { reportError.mockRestore() warnSpy.mockRestore() fetchSpy.mockRestore() }) it('passes successful responses through without reporting', async () => { const response = buildResponse(200) fetchSpy.mockResolvedValueOnce(response) const result = await instrumentedFetch('https://api.example.com/conversations', { method: 'GET', }) expect(result).toBe(response) expect(reportError).not.toHaveBeenCalled() expect(warnSpy).not.toHaveBeenCalled() }) it.each([400, 422, 500])( 'reports %d with method, status, and templated path tags', async status => { fetchSpy.mockResolvedValueOnce(buildResponse(status)) await instrumentedFetch('https://api.example.com/conversations/123/messages', { method: 'POST', }) expect(reportError).toHaveBeenCalledTimes(1) const [error, context] = reportError.mock.calls[0] expect(error.name).toBe(`HTTPError${status}`) expect(error.message).toBe(`HTTP ${status} POST /conversations/:id/messages`) expect(context).toMatchObject({ scope: 'http', tags: { team: 'chat', package: 'chat-react-native', 'http.status': String(status), 'http.method': 'POST', 'http.path': '/conversations/:id/messages', }, }) } ) it.each([401, 403, 404])('does not report %d (expected user states)', async status => { fetchSpy.mockResolvedValueOnce(buildResponse(status)) await instrumentedFetch('https://api.example.com/x', { method: 'GET' }) expect(reportError).not.toHaveBeenCalled() }) it('warns on network failures instead of reporting them', async () => { const networkError = new TypeError('Network request failed') fetchSpy.mockRejectedValueOnce(networkError) await expect( instrumentedFetch('https://api.example.com/conversations/123', { method: 'GET' }) ).rejects.toBe(networkError) expect(reportError).not.toHaveBeenCalled() expect(warnSpy).toHaveBeenCalledTimes(1) const [message, context] = warnSpy.mock.calls[0] expect(message).toContain('Network failure GET /conversations/:id') expect(context.tags).toMatchObject({ 'http.method': 'GET', 'http.path': '/conversations/:id', 'http.error': 'network', }) }) })