// topic-guard.test.mjs // Tester UserPromptSubmit emne-guard (SC6) i inject-okr-context: kun // OKR-relevante prompter injiserer kontekst; en eksplisitt ikke-matchende // prompt suppresses; tvil (tomt felt / ingen stdin) -> default-inject. // Spawner hooken som subprosess med kontrollert cwd + stdin. Zero npm deps. // Moenster: tests/inject-okr-context.test.mjs (begge-casen + input-opsjon). import { test } from 'node:test'; import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const HOOK = join( dirname(fileURLToPath(import.meta.url)), '..', 'hooks', 'scripts', 'inject-okr-context.mjs', ); function makeProjectConfig(workDir, navn) { const p = join(workDir, '.claude'); mkdirSync(p, { recursive: true }); writeFileSync(join(p, 'okr.local.md'), `---\nnavn: "${navn}"\n---\n`); } function runHook(cwd, input = '') { // execFileSync returnerer stdout; hooken avslutter alltid med exit 0. return execFileSync('node', [HOOK], { cwd, env: { ...process.env }, input: input, encoding: 'utf8', }); } function withWork(fn) { const work = mkdtempSync(join(tmpdir(), 'okrtopic-')); try { fn(work); } finally { rmSync(work, { recursive: true, force: true }); } } test('irrelevant prompt: suppresses injeksjon (tom stdout)', () => { withWork((work) => { makeProjectConfig(work, 'TopicOrg'); const out = runHook(work, JSON.stringify({ prompt: 'hva er vaeret i dag' })); assert.equal(out.trim(), '', 'ikke-OKR-prompt skal suppresses selv med gyldig config'); }); }); test('relevant prompt: injiserer OKR-kontekst', () => { withWork((work) => { makeProjectConfig(work, 'TopicOrg'); const out = runHook(work, JSON.stringify({ prompt: 'hjelp meg skrive en OKR for neste tertial' })); assert.match(out, /OKR-kontekst/, 'OKR-relevant prompt skal injisere kontekst'); }); }); test('tomt prompt-felt: bevarer inject-default (tvil -> injiser)', () => { withWork((work) => { makeProjectConfig(work, 'TopicOrg'); const out = runHook(work, JSON.stringify({ prompt: '' })); assert.match(out, /OKR-kontekst/, 'tomt prompt-felt -> tvil -> injiser'); }); }); test('ingen stdin: bevarer inject-default (regresjonsvakt)', () => { withWork((work) => { makeProjectConfig(work, 'TopicOrg'); const out = runHook(work); // input utelatt -> tom stdin assert.match(out, /OKR-kontekst/, 'ingen stdin -> tvil -> injiser'); }); });