Files
Philipp d89fb25d7b
CI Tests / cross-check-mixed-sbom (sbom=true) (pull_request) Successful in 3m0s
CI Tests / cross-check-mixed-sbom (sbom=false) (pull_request) Successful in 3m0s
CI Tests / without-inbuild-sbom (sbom=false) (pull_request) Successful in 3m1s
CI Tests / without-inbuild-sbom (sbom=true) (pull_request) Successful in 7m14s
CI Tests / with-inbuild-sbom (sbom=false) (pull_request) Successful in 7m14s
CI Tests / with-inbuild-sbom (sbom=true) (pull_request) Successful in 7m32s
Philipp/Global-Workflows: Pre-commit Lint (Scoped) / pre-commit (pull_request) Successful in 1m29s
test: add unit tests for cve-diff and fallback for in-build sbom scans
2026-09-14 22:27:49 +02:00

112 lines
4.0 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const path = require('node:path');
const {
loadReportsForArg,
formatVulnRow,
renderMarkdownDiff,
renderFullSummary,
} = require('../cve-diff.js');
const FIXTURES_DIR = path.join(__dirname, 'fixtures');
test('loadReportsForArg loads valid reports and extracts multi-arch metadata', () => {
const targetDir = path.join(FIXTURES_DIR, 'target');
const cves = loadReportsForArg(targetDir);
assert.equal(cves.size, 2);
assert.ok(cves.has('CVE-2023-0001:::glibc'));
assert.ok(cves.has('CVE-2023-0002:::openssl'));
const glibc = cves.get('CVE-2023-0001:::glibc');
assert.equal(glibc.Severity, 'CRITICAL');
assert.deepEqual(Array.from(glibc._archs).sort(), ['amd64', 'arm64']);
assert.deepEqual(Array.from(cves.scannedArchs).sort(), ['amd64', 'arm64']);
const openssl = cves.get('CVE-2023-0002:::openssl');
assert.equal(openssl.Severity, 'HIGH');
assert.deepEqual(Array.from(openssl._archs), ['amd64']);
});
test('loadReportsForArg handles reports with missing or null Results array without crashing', () => {
const emptyDir = path.join(FIXTURES_DIR, 'empty');
const cves = loadReportsForArg(emptyDir);
assert.equal(cves.size, 0);
});
test('renderMarkdownDiff produces correct introduced, resolved, and unchanged sets', () => {
const targetDir = path.join(FIXTURES_DIR, 'target');
const headDir = path.join(FIXTURES_DIR, 'head');
const baseCves = loadReportsForArg(targetDir);
const branchCves = loadReportsForArg(headDir);
const diff = renderMarkdownDiff(baseCves, branchCves, 'main');
// Introduced: CVE-2023-0003 (curl)
assert.ok(diff.includes('New Vulnerabilities Introduced (1)'));
assert.ok(diff.includes('CVE-2023-0003'));
assert.ok(diff.includes('`curl`'));
// Resolved: CVE-2023-0001 (glibc)
assert.ok(diff.includes('Resolved / Removed Vulnerabilities (1)'));
assert.ok(diff.includes('CVE-2023-0001'));
assert.ok(diff.includes('`glibc`'));
// Unchanged count
assert.ok(diff.includes('| ⚪ **Unchanged Vulnerabilities** | 1 |'));
// Multi-arch is present in fixtures (amd64, arm64), so Arch column should be shown
assert.ok(diff.includes('| Arch |'));
});
test('renderMarkdownDiff hides Arch column when single architecture is scanned', () => {
const targetSingle = path.join(FIXTURES_DIR, 'target', 'cve-amd64.json');
const headSingle = path.join(FIXTURES_DIR, 'head', 'cve-amd64.json');
const baseCves = loadReportsForArg(targetSingle);
const branchCves = loadReportsForArg(headSingle);
const diff = renderMarkdownDiff(baseCves, branchCves, 'main');
assert.ok(!diff.includes('| Arch |'));
assert.ok(diff.includes('New Vulnerabilities Introduced (1)'));
assert.ok(diff.includes('Resolved / Removed Vulnerabilities (1)'));
});
test('renderFullSummary outputs summary table and lists all vulnerabilities', () => {
const headDir = path.join(FIXTURES_DIR, 'head');
const headCves = loadReportsForArg(headDir);
const summary = renderFullSummary(headCves);
assert.ok(summary.includes('### 🛡️ Security Scan Report'));
assert.ok(summary.includes('| Total Vulnerabilities | **2** |'));
assert.ok(summary.includes('CVE-2023-0002'));
assert.ok(summary.includes('CVE-2023-0003'));
});
test('formatVulnRow properly formats badge, architecture tag, and escape pipes', () => {
const vuln = {
Severity: 'CRITICAL',
VulnerabilityID: 'CVE-2023-0001',
PrimaryURL: 'https://avd.aquasec.com/nvd/cve-2023-0001',
PkgName: 'glibc',
InstalledVersion: '2.31',
FixedVersion: '2.32',
Title: 'A vulnerability with | pipe symbol',
_archs: new Set(['amd64']),
};
const allArchs = new Set(['amd64', 'arm64']);
const rowWithArch = formatVulnRow(vuln, allArchs, true);
assert.ok(rowWithArch.includes('🔴 CRITICAL'));
assert.ok(rowWithArch.includes('`amd64`'));
assert.ok(rowWithArch.includes('\\|')); // Pipe escaped
const rowWithoutArch = formatVulnRow(vuln, allArchs, false);
assert.ok(!rowWithoutArch.includes('`amd64`'));
});