import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { runSelfAudit, formatSelfAudit, checkReadmeBadges } from '../../scanners/self-audit.mjs'; const __dirname = fileURLToPath(new URL('.', import.meta.url)); const FIXTURES = resolve(__dirname, '../fixtures'); // ======================================== // runSelfAudit // ======================================== describe('runSelfAudit', () => { it('runs without crash', async () => { const result = await runSelfAudit(); assert.ok(result); assert.ok(typeof result.configGrade === 'string'); assert.ok(typeof result.pluginGrade === 'string'); }); it('returns combined results (scanners + plugin health)', async () => { const result = await runSelfAudit(); assert.ok(result.configEnvelope); assert.ok(result.pluginHealthResult); assert.ok(Array.isArray(result.allFindings)); }); it('has valid exit code', async () => { const result = await runSelfAudit(); assert.ok([0, 1, 2].includes(result.exitCode)); }); it('includes verdict', async () => { const result = await runSelfAudit(); assert.ok(['PASS', 'WARN', 'FAIL'].includes(result.verdict)); }); it('has numeric scores', async () => { const result = await runSelfAudit(); assert.ok(typeof result.configScore === 'number'); assert.ok(typeof result.pluginScore === 'number'); assert.ok(result.configScore >= 0 && result.configScore <= 100); assert.ok(result.pluginScore >= 0 && result.pluginScore <= 100); }); it('points to correct plugin directory', async () => { const result = await runSelfAudit(); assert.ok(result.pluginDir.includes('config-audit')); }); }); // ======================================== // fixture filtering delegation // ======================================== describe('runSelfAudit — fixture filtering', () => { it('does not include fixture findings in allFindings', async () => { const result = await runSelfAudit(); for (const f of result.allFindings) { const p = f.file || f.path || f.location || ''; assert.ok( !p.includes('/tests/fixtures/'), `allFindings should not contain fixture paths: ${p}` ); } }); it('configEnvelope has fixture_findings from orchestrator', async () => { const result = await runSelfAudit(); // The orchestrator filters fixtures and attaches them to the envelope if (result.configEnvelope.fixture_findings) { assert.ok(Array.isArray(result.configEnvelope.fixture_findings)); assert.ok(result.configEnvelope.fixture_findings.length > 0); } }); }); // ======================================== // --check-readme (v5 F6) // ======================================== describe('checkReadmeBadges (v5 F6)', () => { it('detects mismatch in readme-desynced fixture', async () => { const path = resolve(FIXTURES, 'readme-desynced'); const result = await checkReadmeBadges(path); assert.equal(typeof result.passed, 'boolean'); assert.equal(result.passed, false, 'expected mismatch'); const cmd = result.mismatches.find(m => m.kind === 'commands'); assert.ok(cmd, `expected commands mismatch; got: ${JSON.stringify(result.mismatches)}`); assert.equal(cmd.expected, 2, `filesystem count should be 2`); assert.equal(cmd.foundInReadme, 1, `README badge claims 1`); }); it('returns counts and badges objects', async () => { const path = resolve(FIXTURES, 'readme-desynced'); const result = await checkReadmeBadges(path); assert.equal(typeof result.counts, 'object'); assert.equal(typeof result.badges, 'object'); assert.equal(result.counts.commands, 2); assert.equal(result.badges.commands, 1); }); }); describe('runSelfAudit({ checkReadme: true }) (v5 F6)', () => { it('attaches readmeCheck object to the result', async () => { const result = await runSelfAudit({ checkReadme: true }); assert.ok(result.readmeCheck, 'expected result.readmeCheck'); assert.equal(typeof result.readmeCheck.passed, 'boolean'); // Do NOT assert passed === true during alpha/beta phases — see plan Step 16. }); it('omits readmeCheck when flag not set', async () => { const result = await runSelfAudit(); assert.equal(result.readmeCheck, undefined); }); }); // ======================================== // formatSelfAudit // ======================================== describe('formatSelfAudit', () => { it('produces terminal output with Self-Audit header', async () => { const result = await runSelfAudit(); const output = formatSelfAudit(result); assert.ok(output.includes('Self-Audit')); assert.ok(output.includes('Plugin health:')); assert.ok(output.includes('Config quality:')); }); it('includes verdict', async () => { const result = await runSelfAudit(); const output = formatSelfAudit(result); assert.ok(output.includes('Self-audit:')); assert.ok(output.includes('PASS') || output.includes('WARN') || output.includes('FAIL')); }); });