import { beforeEach, describe, expect, it, vi } from 'vitest'; const fetchJsonMock = vi.fn(); vi.mock('../apiClient', () => ({ fetchJson: (...args: unknown[]) => fetchJsonMock(...args), })); vi.mock('../../lib/device', () => ({ getDeviceId: () => 'device-123', })); import { createGuestAiEdit, fetchGuestAiEditStatus, fetchGuestAiStyles } from '../aiEditsApi'; describe('aiEditsApi', () => { beforeEach(() => { fetchJsonMock.mockReset(); }); it('loads guest ai styles with device header', async () => { fetchJsonMock.mockResolvedValue({ data: { data: [{ id: 10, key: 'style-a', name: 'Style A' }], meta: { allow_custom_prompt: false }, }, }); const payload = await fetchGuestAiStyles('token-abc'); expect(fetchJsonMock).toHaveBeenCalledWith('/api/v1/events/token-abc/ai-styles', { headers: { 'X-Device-Id': 'device-123', }, noStore: true, }); expect(payload.data).toHaveLength(1); expect(payload.data[0]?.key).toBe('style-a'); expect(payload.meta.allow_custom_prompt).toBe(false); }); it('creates guest ai edit with json payload', async () => { fetchJsonMock.mockResolvedValue({ data: { duplicate: false, data: { id: 55, event_id: 1, photo_id: 9, status: 'queued', outputs: [], }, }, }); const payload = await createGuestAiEdit('token-abc', 9, { style_key: 'style-a', idempotency_key: 'demo-key', }); expect(fetchJsonMock).toHaveBeenCalledWith('/api/v1/events/token-abc/photos/9/ai-edits', { method: 'POST', headers: { 'X-Device-Id': 'device-123', 'Content-Type': 'application/json', }, body: JSON.stringify({ style_key: 'style-a', idempotency_key: 'demo-key', }), noStore: true, }); expect(payload.data.id).toBe(55); expect(payload.data.status).toBe('queued'); }); it('throws when status payload is malformed', async () => { fetchJsonMock.mockResolvedValue({ data: null }); await expect(fetchGuestAiEditStatus('token-abc', 55)).rejects.toThrow('AI edit status response is invalid.'); }); });