Files
RepoPulse-Public/frontend/src/FindingsView.test.tsx
T

113 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment jsdom
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it } from 'vitest'
import type { ScanReport } from './api'
import { FindingsView } from './components/FindingsView'
const report: ScanReport = {
id: 'scan-1',
repository_path: '/scan/repopulse',
repository_name: 'RepoPulse',
source: {
origin: 'gitea',
provider: 'gitea',
repository_id: '64',
repository_full_name: 'Jens/RepoPulse',
branch: 'main',
requested_revision: 'revision-1',
actual_revision: 'revision-1',
trigger: 'scheduled',
},
policy: {
auto_scan: true,
min_health_score: 70,
max_blockers: 0,
require_tests: true,
require_ci: true,
suppressions: [],
},
scanned_at: '2026-09-12T20:00:00Z',
duration_ms: 1200,
metrics: {
files: 2,
source_files: 2,
lines_of_code: 20,
test_files: 1,
todo: 0,
fixme: 0,
hack: 0,
xxx: 0,
dependency_manifests: 1,
declared_dependencies: 1,
large_files: 0,
large_source_files: 0,
},
languages: { TypeScript: 20 },
category_scores: { 'Security basics': 20, Maintainability: 80 },
health_score: 70,
release_readiness: 'BLOCKED',
findings: [
{
code: 'security.secret-assignment',
category: 'Security basics',
severity: 'blocker',
message: 'Potential credential assignment detected; value intentionally redacted',
path: 'backend/app/main.py',
line: 245,
deduction: 20,
fingerprint: 'fingerprint-1',
suppressed: false,
},
{
code: 'maintainability.long-function',
category: 'Maintainability',
severity: 'warning',
message: 'Function is longer than the configured threshold',
path: 'backend/app/signals.py',
line: 111,
deduction: 4,
fingerprint: 'fingerprint-2',
suppressed: false,
},
],
tests: { frameworks: ['pytest'], coverage_artifacts: [], ci_workflows: [], test_source_ratio: null },
git: { available: true, commit_count: 1, contributor_count: 1, latest_commit_at: null, tracked_files: 2, renamed_files: [] },
dependencies: { manifests: ['package.json'], lockfiles: ['package-lock.json'], declared_dependencies: 1, unbounded_dependencies: 0, unpinned_dependencies: 0, duplicate_dependencies: [] },
architecture: { nodes: [], edges: [], clusters: {}, truncated: false, total_nodes: 0, total_edges: 0 },
hotspots: [],
release_gate: null,
}
afterEach(() => cleanup())
describe('FindingsView', () => {
it('keeps findings scanable while exposing expandable rule details', () => {
const { container } = render(<FindingsView report={report} />)
const firstFinding = container.querySelector('details.finding') as HTMLDetailsElement
expect(firstFinding.open).toBe(false)
expect(screen.getByText('Potential credential assignment detected; value intentionally redacted')).toBeTruthy()
fireEvent.click(screen.getByText('Potential credential assignment detected; value intentionally redacted'))
expect(firstFinding.open).toBe(true)
expect(screen.getByText('−20 points')).toBeTruthy()
expect(screen.getByText('backend/app/main.py:245')).toBeTruthy()
expect(screen.getByText('security.secret-assignment')).toBeTruthy()
})
it('filters by severity and reports an actionable empty state', () => {
render(<FindingsView report={report} />)
const severity = screen.getByRole('combobox', { name: 'Filter findings by severity' })
const query = screen.getByRole('textbox', { name: 'Filter findings' })
fireEvent.change(severity, { target: { value: 'warning' } })
expect(screen.getByText(/Showing 1 of 2/)).toBeTruthy()
fireEvent.change(query, { target: { value: 'does-not-exist' } })
expect(screen.getByText('No findings match the current filters.')).toBeTruthy()
})
})