Files
Autonomous-Bug-Explorer/tests/server/cli.test.ts

92 lines
3.0 KiB
TypeScript

/**
* Tests for CLI flag parsing and exit code logic.
* These test the logic functions extracted from the CLI, not the CLI process itself.
*/
describe('CLI exit code logic', () => {
const severityRank: Record<string, number> = { low: 0, medium: 1, high: 2, critical: 3 };
function shouldFailOnSeverity(
anomalies: Array<{ severity: string }>,
threshold: string
): boolean {
const thresholdRank = severityRank[threshold] ?? 0;
return anomalies.some((a) => (severityRank[a.severity] ?? 0) >= thresholdRank);
}
it('exit 0 when no anomalies', () => {
expect(shouldFailOnSeverity([], 'high')).toBe(false);
});
it('exit 1 when anomaly at threshold', () => {
expect(shouldFailOnSeverity([{ severity: 'high' }], 'high')).toBe(true);
});
it('exit 1 when anomaly above threshold', () => {
expect(shouldFailOnSeverity([{ severity: 'critical' }], 'high')).toBe(true);
});
it('exit 0 when anomaly below threshold', () => {
expect(shouldFailOnSeverity([{ severity: 'low' }], 'high')).toBe(false);
});
it('exit 0 when medium anomaly and threshold is high', () => {
expect(shouldFailOnSeverity([{ severity: 'medium' }], 'high')).toBe(false);
});
});
describe('JUnit XML generation', () => {
function buildJunit(
anomalies: Array<{ id: string; type: string; severity: string; description: string }>,
url: string
): string {
function escapeXml(s: string): string {
return s
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
const cases = anomalies
.map(
(a) =>
` <testcase name="${escapeXml(a.description)}" classname="abe.anomaly.${escapeXml(a.type)}">\n` +
` <failure message="${escapeXml(a.description)}" type="${escapeXml(a.severity)}">${escapeXml(a.id)}</failure>\n` +
` </testcase>`
)
.join('\n');
return (
`<?xml version="1.0" encoding="UTF-8"?>\n` +
`<testsuite name="ABE Exploration: ${escapeXml(url)}" tests="${anomalies.length}" failures="${anomalies.length}">\n` +
cases + '\n' +
`</testsuite>\n`
);
}
it('generates valid XML with one anomaly', () => {
const xml = buildJunit(
[{ id: 'a1', type: 'http_error', severity: 'high', description: 'Server error on form' }],
'http://localhost:3000'
);
expect(xml).toContain('<testsuite');
expect(xml).toContain('<failure');
expect(xml).toContain('http_error');
expect(xml).toContain('Server error on form');
});
it('generates empty testsuite for no anomalies', () => {
const xml = buildJunit([], 'http://localhost:3000');
expect(xml).toContain('tests="0"');
expect(xml).not.toContain('<failure');
});
it('escapes XML special characters', () => {
const xml = buildJunit(
[{ id: 'a1', type: 'http_error', severity: 'high', description: '<script>alert(1)</script>' }],
'http://app.com'
);
expect(xml).not.toContain('<script>');
expect(xml).toContain('&lt;script&gt;');
});
});