import { describe, it, expect, vi, beforeEach } from 'vitest'; import { getCoverProviders, updateCoverProvider, testCoverProvider, type CoverProvider, type CoverProvidersResponse } from './admin'; vi.mock('./client', () => ({ api: { get: vi.fn(), post: vi.fn(), patch: vi.fn() } })); import { api } from './client'; describe('admin cover-sources API', () => { beforeEach(() => vi.clearAllMocks()); it('getCoverProviders GETs the correct path', async () => { const sample: CoverProvidersResponse = { providers: [ { id: 'mbcaa', display_name: 'Cover Art Archive', requires_api_key: false, supports: ['album_cover'], enabled: true, api_key_set: false, display_order: 0, testable: true } ], sources_version: 1 }; (api.get as unknown as ReturnType).mockResolvedValueOnce(sample); const got = await getCoverProviders(); expect(api.get).toHaveBeenCalledWith('/api/admin/cover-sources'); expect(got.providers[0].id).toBe('mbcaa'); expect(got.sources_version).toBe(1); }); it('updateCoverProvider PATCHes the right path with patch body', async () => { const patched: CoverProvider & { version_bumped: boolean } = { id: 'theaudiodb', display_name: 'TheAudioDB', requires_api_key: true, supports: ['album_cover', 'artist_thumb', 'artist_fanart'], enabled: true, api_key_set: true, display_order: 1, testable: true, version_bumped: false }; (api.patch as unknown as ReturnType).mockResolvedValueOnce(patched); const got = await updateCoverProvider('theaudiodb', { api_key: 'mykey' }); expect(api.patch).toHaveBeenCalledWith( '/api/admin/cover-sources/theaudiodb', { api_key: 'mykey' } ); expect(got.api_key_set).toBe(true); expect(got.version_bumped).toBe(false); }); it('updateCoverProvider with enabled toggle returns version_bumped: true', async () => { const patched: CoverProvider & { version_bumped: boolean } = { id: 'theaudiodb', display_name: 'TheAudioDB', requires_api_key: true, supports: ['album_cover', 'artist_thumb', 'artist_fanart'], enabled: false, api_key_set: false, display_order: 1, testable: true, version_bumped: true }; (api.patch as unknown as ReturnType).mockResolvedValueOnce(patched); const got = await updateCoverProvider('theaudiodb', { enabled: false }); expect(got.version_bumped).toBe(true); expect(got.enabled).toBe(false); }); it('testCoverProvider POSTs to /test endpoint with empty body', async () => { (api.post as unknown as ReturnType).mockResolvedValueOnce({ ok: true, duration_ms: 234 }); const got = await testCoverProvider('theaudiodb'); expect(api.post).toHaveBeenCalledWith('/api/admin/cover-sources/theaudiodb/test', {}); expect(got.ok).toBe(true); expect(got.duration_ms).toBe(234); }); it('testCoverProvider returns ok=false with error string on failure', async () => { (api.post as unknown as ReturnType).mockResolvedValueOnce({ ok: false, duration_ms: 12, error: 'connection refused' }); const got = await testCoverProvider('theaudiodb'); expect(got.ok).toBe(false); expect(got.error).toBe('connection refused'); }); });