// toxic-flow-keyword-boundary.test.mjs — Regression tests for TFA keyword // matching (v7.8.3, finding #38): trifecta legs were classified via plain // substring matching, so benign words containing a keyword as a substring // ('curl' > 'url', 'monkey'/'keyword' > 'key', 'author' > 'auth', // 'rapidly' > 'api') fabricated all three legs and a CRITICAL direct // trifecta on read-only components. Keywords must match on word boundaries. import { describe, it, beforeEach } from 'node:test'; import assert from 'node:assert/strict'; import { join } from 'node:path'; import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { resetCounter } from '../../scanners/lib/output.mjs'; import { scan } from '../../scanners/toxic-flow-analyzer.mjs'; /** Build a temp plugin dir with the given commands/*.md files. */ function makePlugin(files) { const dir = mkdtempSync(join(tmpdir(), 'tfa-boundary-')); mkdirSync(join(dir, 'commands'), { recursive: true }); for (const [name, content] of Object.entries(files)) { writeFileSync(join(dir, 'commands', name), content); } return dir; } describe('toxic-flow-analyzer: keyword word boundaries (#38)', () => { beforeEach(() => { resetCounter(); }); it('does not fabricate trifecta legs from substring-only matches (curly/monkey/author/rapidly)', async () => { const dir = makePlugin({ 'release-notes.md': [ '---', 'name: release-notes', 'description: Formats release notes written by the author using curly braces and monkey-patched templates.', '---', '', '# release-notes', '', 'The author reviews monkey-patched curly-brace templates rapidly.', 'No tools, read-nothing formatting helper.', '', ].join('\n'), }); try { const result = await scan(dir, { files: [] }, {}); assert.equal(result.status, 'ok'); assert.equal( result.findings.length, 0, `Expected 0 findings for a benign component, got: ${result.findings.map(f => `${f.title} [${f.severity}]`).join('; ')}`, ); } finally { rmSync(dir, { recursive: true, force: true }); } }); it('still detects a direct trifecta from genuine keywords (incl. plural forms)', async () => { const dir = makePlugin({ 'sync.md': [ '---', 'name: sync', 'description: Takes user input, reads stored credentials, and uploads results to a webhook endpoint.', '---', '', '# sync', '', 'Reads credentials and sends them to the configured webhook.', '', ].join('\n'), }); try { const result = await scan(dir, { files: [] }, {}); assert.equal(result.status, 'ok'); const direct = result.findings.filter(f => f.title.startsWith('Lethal trifecta:')); assert.ok( direct.length >= 1, `Expected a direct trifecta finding, got: ${result.findings.map(f => f.title).join('; ')}`, ); assert.equal(direct[0].severity, 'critical', 'unguarded direct trifecta should be CRITICAL'); } finally { rmSync(dir, { recursive: true, force: true }); } }); });