import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import { useDownloadsStore } from '../src/stores/downloads.js' function stubFetch(handler) { globalThis.fetch = vi.fn(async (url, init) => { const { status, body } = handler(url, init) return { ok: status >= 200 && status < 300, status, statusText: String(status), text: async () => (body == null ? '' : JSON.stringify(body)), } }) } describe('downloads store', () => { beforeEach(() => setActivePinia(createPinia())) afterEach(() => vi.restoreAllMocks()) it('loadFirst populates events and cursor', async () => { const s = useDownloadsStore() stubFetch(() => ({ status: 200, body: [ { id: 10, status: 'ok', summary: {} }, { id: 9, status: 'error', summary: {} }, ], })) await s.loadFirst() expect(s.events.map(e => e.id)).toEqual([10, 9]) expect(s.cursor).toBe(9) expect(s.hasMore).toBe(false) }) it('loadMore appends and updates cursor', async () => { const s = useDownloadsStore() s.events = [{ id: 10, summary: {} }, { id: 9, summary: {} }] s.cursor = 9 s.hasMore = true stubFetch(() => ({ status: 200, body: [{ id: 8, status: 'ok', summary: {} }], })) await s.loadMore() expect(s.events.map(e => e.id)).toEqual([10, 9, 8]) expect(s.cursor).toBe(8) }) it('applyFilter merges and reloads', async () => { const s = useDownloadsStore() const urls = [] stubFetch((url) => { urls.push(url) return { status: 200, body: [] } }) await s.applyFilter({ status: 'error' }) expect(s.filter.status).toBe('error') expect(urls[0]).toContain('status=error') }) it('loadOne populates selected', async () => { const s = useDownloadsStore() stubFetch(() => ({ status: 200, body: { id: 42, metadata: { run_stats: {} } } })) const out = await s.loadOne(42) expect(s.selected.id).toBe(42) expect(out.id).toBe(42) }) it('closeDetail clears selected', async () => { const s = useDownloadsStore() s.selected = { id: 1 } s.closeDetail() expect(s.selected).toBe(null) }) })