ktg-plugin-marketplace/plugins/config-audit/tests/lib/severity.test.mjs
Kjell Tore Guttormsen e5efc2ff64 feat(config-audit): export WEIGHTS from severity.mjs (v5 F3 prep)
Promote WEIGHTS const to named export with Object.freeze for downstream
use in scoring.mjs (severity-weighted scoreByArea, F3).

Tests: +2 cases asserting WEIGHTS shape.
2026-05-01 06:16:28 +02:00

146 lines
3.9 KiB
JavaScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { SEVERITY, WEIGHTS, riskScore, verdict, riskBand, gradeFromPassRate, QUALITY_CATEGORIES } from '../../scanners/lib/severity.mjs';
describe('SEVERITY constants', () => {
it('has all 5 levels', () => {
assert.deepStrictEqual(Object.keys(SEVERITY).sort(), ['critical', 'high', 'info', 'low', 'medium']);
});
it('is frozen', () => {
assert.throws(() => { SEVERITY.critical = 'x'; }, TypeError);
});
});
describe('WEIGHTS named export (v5 F3 prep)', () => {
it('exposes critical=25', () => {
assert.strictEqual(WEIGHTS.critical, 25);
});
it('exposes high=10, medium=4, low=1, info=0', () => {
assert.strictEqual(WEIGHTS.high, 10);
assert.strictEqual(WEIGHTS.medium, 4);
assert.strictEqual(WEIGHTS.low, 1);
assert.strictEqual(WEIGHTS.info, 0);
});
});
describe('riskScore', () => {
it('returns 0 for empty counts', () => {
assert.strictEqual(riskScore({}), 0);
});
it('returns 0 for info-only findings', () => {
assert.strictEqual(riskScore({ info: 10 }), 0);
});
it('scores low findings at 1 point each', () => {
assert.strictEqual(riskScore({ low: 5 }), 5);
});
it('scores medium findings at 4 points each', () => {
assert.strictEqual(riskScore({ medium: 3 }), 12);
});
it('scores high findings at 10 points each', () => {
assert.strictEqual(riskScore({ high: 2 }), 20);
});
it('scores critical findings at 25 points each', () => {
assert.strictEqual(riskScore({ critical: 1 }), 25);
});
it('caps at 100', () => {
assert.strictEqual(riskScore({ critical: 10 }), 100);
});
it('combines all severities', () => {
assert.strictEqual(riskScore({ critical: 1, high: 1, medium: 1, low: 1, info: 1 }), 40);
});
});
describe('verdict', () => {
it('returns PASS for no findings', () => {
assert.strictEqual(verdict({}), 'PASS');
});
it('returns PASS for low findings only', () => {
assert.strictEqual(verdict({ low: 5, info: 10 }), 'PASS');
});
it('returns WARNING for any high finding', () => {
assert.strictEqual(verdict({ high: 1 }), 'WARNING');
});
it('returns FAIL for any critical finding', () => {
assert.strictEqual(verdict({ critical: 1 }), 'FAIL');
});
it('returns FAIL for score >= 61', () => {
assert.strictEqual(verdict({ high: 6, medium: 1 }), 'FAIL');
});
it('returns WARNING for score >= 21', () => {
assert.strictEqual(verdict({ medium: 6 }), 'WARNING');
});
});
describe('riskBand', () => {
it('returns Low for score 0', () => {
assert.strictEqual(riskBand(0), 'Low');
});
it('returns Low for score 10', () => {
assert.strictEqual(riskBand(10), 'Low');
});
it('returns Medium for score 11-30', () => {
assert.strictEqual(riskBand(20), 'Medium');
});
it('returns High for score 31-60', () => {
assert.strictEqual(riskBand(50), 'High');
});
it('returns Critical for score 61-80', () => {
assert.strictEqual(riskBand(70), 'Critical');
});
it('returns Extreme for score > 80', () => {
assert.strictEqual(riskBand(90), 'Extreme');
});
});
describe('gradeFromPassRate', () => {
it('returns A for 90+', () => {
assert.strictEqual(gradeFromPassRate(95), 'A');
});
it('returns B for 75-89', () => {
assert.strictEqual(gradeFromPassRate(80), 'B');
});
it('returns C for 60-74', () => {
assert.strictEqual(gradeFromPassRate(65), 'C');
});
it('returns D for 40-59', () => {
assert.strictEqual(gradeFromPassRate(50), 'D');
});
it('returns F for below 40', () => {
assert.strictEqual(gradeFromPassRate(20), 'F');
});
});
describe('QUALITY_CATEGORIES', () => {
it('has expected categories', () => {
assert.ok(QUALITY_CATEGORIES.STRUCTURE);
assert.ok(QUALITY_CATEGORIES.FEATURES);
assert.ok(QUALITY_CATEGORIES.SECURITY);
});
it('is frozen', () => {
assert.throws(() => { QUALITY_CATEGORIES.NEW = 'x'; }, TypeError);
});
});