Files
RepoPulse-Public/frontend/src/catalog.test.ts
T

79 lines
3.0 KiB
TypeScript

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'])
})
})