import { describe, expect, it } from 'vitest' import { filterRepositories, orderSwitcherRepositories, paginateRepositories, sortRepositories } from './catalog' import type { RepositorySummary } from './api' function repository(index: number): RepositorySummary { return { id: `gitea:${index}`, provider: 'gitea', provider_repository_id: String(index), owner: index % 2 ? 'Jens' : 'Team', name: `repo-${String(index).padStart(3, '0')}`, full_name: `${index % 2 ? 'Jens' : 'Team'}/repo-${String(index).padStart(3, '0')}`, description: null, html_url: null, clone_url: null, default_branch: index % 3 ? 'main' : 'develop', private: index % 4 === 0, archived: index % 17 === 0, available: true, latest_revision: `revision-${index}`, latest_revision_at: '2026-09-12T10:00:00Z', last_synced_at: '2026-09-12T10:00:00Z', sync_error: null, state: index % 11 === 0 ? 'never_scanned' : 'current', stale: false, active_job_id: null, last_scan_id: index % 11 === 0 ? null : `scan-${index}`, last_scan_at: index % 11 === 0 ? null : '2026-09-12T10:00:00Z', last_scan_health: index % 11 === 0 ? null : 80 + (index % 20), last_scan_readiness: index % 11 === 0 ? null : 'READY', last_scan_revision: `revision-${index}`, last_scan_blockers: 0, last_scan_warnings: 0, last_scan_primary_signal: null, last_scan_health_delta: null, last_scan_added_findings: 0, last_scan_resolved_findings: 0, policy: { auto_scan: true, min_health_score: 70, max_blockers: 0, require_tests: false, require_ci: false, suppressions: [] }, } } describe('repository catalog helpers', () => { it('filters by owner, branch, visibility and readiness', () => { const repositories = Array.from({ length: 20 }, (_, index) => repository(index + 1)) const result = filterRepositories(repositories, { query: 'repo-0', state: 'all', readiness: 'ready', owner: 'Jens', branch: 'main', visibility: 'public', archived: 'active', }) expect(result.every((item) => item.owner === 'Jens' && item.default_branch === 'main' && !item.private && !item.archived)).toBe(true) expect(result.length).toBeGreaterThan(0) }) it('sorts deterministically and paginates large catalogs without rendering all rows', () => { const repositories = Array.from({ length: 500 }, (_, index) => repository(index + 1)) const sorted = sortRepositories(repositories, { key: 'name', direction: 'asc' }) const page = paginateRepositories(sorted, 7, 25) expect(page.total).toBe(500) expect(page.pageCount).toBe(20) expect(page.page).toBe(7) expect(page.items).toHaveLength(25) expect(page.items[0].full_name).toBe('Jens/repo-301') }) it('puts pinned and recent repositories first in the quick switcher', () => { const repositories = [repository(1), repository(2), repository(3)] const result = orderSwitcherRepositories(repositories, ['gitea:3'], ['gitea:2'], 'repo') expect(result.map((item) => item.id)).toEqual(['gitea:3', 'gitea:2', 'gitea:1']) }) })