import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { sendBugReport } from './bug-report-api'; /** * bug-report-api.test — NEU (quick-260918-gza). Bisher pruefte nur der * Komponententest (`bug-report-button.test.tsx`) die FormData von * `sendBugReport` — die reinen Nutzlastfelder (insbesondere die vier neuen * Herkunftsfelder) gehoeren aber an die Funktion selbst, unabhaengig vom * Dialog. Drei Tests: Desktop-Nutzlast, Browser-Nutzlast, Netzwerk-/ * HTTP-Fehler. */ const { mockFetch } = vi.hoisted(() => ({ mockFetch: vi.fn() })); const basePayload = { description: 'x', page: '/a', webVersion: 'v1', webChannel: 'beta', webCommit: 'c', userAgent: 'UA', viewport: '1x1', clientTime: 't', errors: ['e1', 'e2'], screenshot: null, }; beforeEach(() => { mockFetch.mockReset(); mockFetch.mockResolvedValue(new Response('{}', { status: 200 })); vi.stubGlobal('fetch', mockFetch); }); afterEach(() => { vi.unstubAllGlobals(); }); describe('sendBugReport (quick-260918-gza)', () => { it('Test 1: Desktop-Nutzlast — clientKind/clientOs/clientVersion/clientCommit im FormData, errors mehrfach, kein screenshot-Feld', async () => { const result = await sendBugReport({ ...basePayload, clientKind: 'desktop', clientOs: 'windows', clientVersion: '1.2.0', clientCommit: 'a6d1a64', }); expect(result).toEqual({ ok: true }); const [url, init] = mockFetch.mock.calls[0] as [string, RequestInit]; expect(String(url).endsWith('/bug-reports')).toBe(true); expect(init.credentials).toBe('include'); const body = init.body as FormData; expect(body.get('clientKind')).toBe('desktop'); expect(body.get('clientOs')).toBe('windows'); expect(body.get('clientVersion')).toBe('1.2.0'); expect(body.get('clientCommit')).toBe('a6d1a64'); expect(body.getAll('errors')).toEqual(['e1', 'e2']); expect(body.has('screenshot')).toBe(false); }); it('Test 2: Browser-Nutzlast — die drei uebrigen Client-Felder sind vorhanden, aber leer (nicht weggelassen)', async () => { await sendBugReport({ ...basePayload, clientKind: 'browser', clientOs: '', clientVersion: '', clientCommit: '', }); const body = (mockFetch.mock.calls[0] as [string, RequestInit])[1].body as FormData; expect(body.get('clientKind')).toBe('browser'); expect(body.get('clientOs')).toBe(''); expect(body.get('clientVersion')).toBe(''); expect(body.get('clientCommit')).toBe(''); }); it('Test 3: Netzwerkfehler -> { ok: false, status: 0 }; HTTP-Fehler -> { ok: false, status }', async () => { mockFetch.mockRejectedValueOnce(new Error('offline')); await expect( sendBugReport({ ...basePayload, clientKind: 'browser', clientOs: '', clientVersion: '', clientCommit: '' }), ).resolves.toEqual({ ok: false, status: 0 }); mockFetch.mockResolvedValueOnce(new Response('', { status: 429 })); await expect( sendBugReport({ ...basePayload, clientKind: 'browser', clientOs: '', clientVersion: '', clientCommit: '' }), ).resolves.toEqual({ ok: false, status: 429 }); }); });