Assessor_2.0/tests/features/finding-badge-order.test.tsx

67 lines
4.6 KiB
TypeScript

// @vitest-environment jsdom
import { act, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { afterEach, describe, expect, it, vi } from 'vitest';
import type { FindingRecord } from '../../src/domain/finding';
import { TileCard } from '../../src/components/TileCard/TileCard';
import { FindingReader } from '../../src/features/finding-reader/FindingReader';
afterEach(() => { vi.unstubAllGlobals(); document.body.replaceChildren(); });
describe.each(['light', 'dark'])('Finding badge order (%s)', theme => {
it.each([
['pingcastle', 'Severity'], ['purple-knight', 'Severity'], ['maester', 'Severity'],
['cis-cat', 'Severity'], ['group-policy', 'Severity'], ['generic', 'Criticality'], ['generic', 'Priority']
])('keeps Outcome then %s severity (%s) ahead of native/derived categories and numeric metadata when opening a compact tile', async (toolId, severityLabel) => {
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
document.documentElement.dataset.theme = theme;
const record: FindingRecord = {
id: 'synthetic-badge-order', index: 0, title: '2.2.2 Ensure a synthetic setting', filled: [], meta: [],
fields: [['Domain Risk Level', '100'], ['Points', '20'], ['Category', 'Synthetic category'],
['Weight', '8'], ['Score', '73'], ['Status', 'Fail'], [severityLabel, 'Medium'],
['Rule ID', '2.2.2'], ['Baseline', 'Windows Server 2022 Security Baseline'], ['Scope', 'computer']]
.map(([label, value], index) => ({ label, value, index }))
};
const original = JSON.stringify(record);
function Reading() {
const [open, setOpen] = useState(false);
return open ? <FindingReader record={record} title={record.title} toolId={toolId} linkedSheets={[]}
resultReferences={[]} search="" position={0} recordCount={1} onPrevious={() => {}} onNext={() => {}} onReview={() => {}}/>
: <TileCard record={record} title={record.title} toolId={toolId} badgeLimit={3} bookmarked={false} onOpen={() => setOpen(true)} onBookmark={() => {}}/>;
}
const host = document.createElement('div'); document.body.append(host); const root = createRoot(host);
try {
await act(async () => root.render(<Reading/>));
const tileBadges = [...host.querySelector('.data-tile-badges')!.children];
expect(tileBadges[0].getAttribute('data-badge-role')).toBe('status');
expect(tileBadges[1].getAttribute('data-badge-role')).toBe('severity');
expect(tileBadges[1].textContent).toBe('Medium');
expect(tileBadges[2].getAttribute('data-badge-role')).toBe('category');
await act(async () => host.querySelector<HTMLElement>('.data-tile')!.click());
const readerBadges = [...host.querySelector('.finding-badges')!.children];
expect(readerBadges[0].classList.contains('outcome-mark')).toBe(true);
expect(readerBadges[1].classList.contains('severity-medium')).toBe(true);
expect(readerBadges[1].textContent).toBe('Medium');
expect(readerBadges.filter(badge => badge.classList.contains('severity-badge'))).toHaveLength(1);
expect(readerBadges.slice(2).some(badge => badge.textContent === 'Domain Risk Level: 100 / 100')).toBe(true);
expect(readerBadges.slice(2).some(badge => badge.textContent === 'Points: 20')).toBe(true);
expect(JSON.stringify(record)).toBe(original);
} finally { await act(async () => root.unmount()); host.remove(); }
});
it('omits unavailable Severity without creating a placeholder or hiding the category', async () => {
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
document.documentElement.dataset.theme = theme;
const record: FindingRecord = { id: 'synthetic-no-severity', index: 0, title: 'Synthetic finding', filled: [], meta: [],
fields: [{ label: 'Status', value: 'Failed', index: 0 }, { label: 'Category', value: 'Synthetic category', index: 1 }] };
const host = document.createElement('div'); document.body.append(host); const root = createRoot(host);
try {
await act(async () => root.render(<><TileCard record={record} title={record.title} bookmarked={false} onOpen={() => {}} onBookmark={() => {}}/>
<FindingReader record={record} title={record.title} linkedSheets={[]} resultReferences={[]} search="" position={0} recordCount={1}
onPrevious={() => {}} onNext={() => {}} onReview={() => {}}/></>));
expect([...host.querySelector('.data-tile-badges')!.children].map(b => b.textContent)).toEqual(['Failed', 'Synthetic category']);
expect([...host.querySelector('.finding-badges')!.children].map(b => b.textContent)).toEqual(['Failed', 'Category: Synthetic category']);
} finally { await act(async () => root.unmount()); host.remove(); }
});
});