Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
66
server/web/src/components/Fleet/ReconBadges.test.tsx
Normal file
66
server/web/src/components/Fleet/ReconBadges.test.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @vitest-environment happy-dom
|
||||
*/
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { cleanup, render, screen, waitFor } from '@testing-library/react';
|
||||
import RiskBadge from './RiskBadge';
|
||||
import JoinLaneBadge from './JoinLaneBadge';
|
||||
import CredentialGraphTable from './CredentialGraphTable';
|
||||
import { api } from '../../api/client';
|
||||
|
||||
vi.mock('../../api/client', () => ({
|
||||
api: {
|
||||
getCredentialGraph: vi.fn(),
|
||||
getServiceGraph: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Recon badges', () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('RiskBadge renders critical chip from vuln_findings', () => {
|
||||
render(
|
||||
<RiskBadge
|
||||
findings={[{ cve_id: 'CVE-2021-44228', severity: 'critical', patched: false }]}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByText('RISK CRIT')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('RiskBadge renders nothing when findings are patched', () => {
|
||||
const { container } = render(
|
||||
<RiskBadge findings={[{ cve_id: 'CVE-1', severity: 'high', patched: true }]} />,
|
||||
);
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('JoinLaneBadge renders lane label', () => {
|
||||
render(<JoinLaneBadge lane="docker" />);
|
||||
expect(screen.getByText('Docker')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('CredentialGraphTable shows subnet rows from API', async () => {
|
||||
vi.mocked(api.getCredentialGraph).mockResolvedValue({
|
||||
subnets: [
|
||||
{ subnet: '10.0.1.x', edges: 5, success_count: 3, fail_count: 2 },
|
||||
],
|
||||
});
|
||||
render(<CredentialGraphTable />);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('10.0.1.x')).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.getByText('5')).toBeInTheDocument();
|
||||
expect(screen.getByText('3')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('CredentialGraphTable shows unavailable message on 404', async () => {
|
||||
vi.mocked(api.getCredentialGraph).mockResolvedValue(null);
|
||||
render(<CredentialGraphTable />);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/not available yet/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user