import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { test } from 'node:test'; const dir = dirname(fileURLToPath(import.meta.url)); const reviewSrc = readFileSync(join(dir, 'Review.svelte'), 'utf8'); const figSrc = readFileSync(join(dir, 'figTags.ts'), 'utf8'); test('Review UI: no AI assist labels or AI badge chrome', () => { assert.equal(reviewSrc.includes('AI assist'), false); assert.equal(reviewSrc.includes('class="ai"'), false); assert.equal(reviewSrc.includes('ps-tag'), false); }); test('Review UI: no fig-* MultiSelect picker', () => { assert.equal(reviewSrc.includes('data-testid="fig-tag"'), false); assert.equal(reviewSrc.includes('figTagOpts'), false); assert.equal(reviewSrc.includes('label="fig-* tags"'), false); assert.equal(reviewSrc.includes('placeholder="Choose fig-* tags"'), false); assert.match(reviewSrc, /deriveFigTagIds/); assert.match(reviewSrc, /Features/); assert.match(reviewSrc, /testid="feat-tag"/); }); test('Tag family scope uses hyphenated slug prefix', () => { assert.match(figSrc, /startsWith\('fig-'\)/); assert.match(figSrc, /startsWith\('feat-'\)/); assert.equal(/startsWith\('fig'\)/.test(figSrc), false); assert.equal(/startsWith\('feat'\)/.test(figSrc), false); assert.equal(/startsWith\('fig'\)/.test(reviewSrc), false); assert.equal(/startsWith\('feat'\)/.test(reviewSrc), false); }); test('Review UI: View prompt + Create desc gate wiring', () => { assert.match(reviewSrc, /data-testid="view-prompt"/); assert.match(reviewSrc, /getCall2Prompt/); assert.match(reviewSrc, /createDescMissing/); assert.match(reviewSrc, /missingCreateDescLabels/); assert.match(reviewSrc, /orderWoodCatGroups/); assert.match(reviewSrc, /applyMoistureDefault/); assert.match(reviewSrc, /onCommit=\{commitReview\}/); // Description is not part of the Create-desc gate label list assert.equal(reviewSrc.includes("Create desc needs: description"), false); }); test('Review UI: live field commit + unified secondary buttons + moisture default', () => { assert.match(reviewSrc, /scheduleFieldCommit/); assert.match(reviewSrc, /scheduleDescCommit/); assert.match(reviewSrc, /class="btn-sec"/); assert.match(reviewSrc, /applyMoistureDefault/); assert.match(reviewSrc, /void syncSelects\(\)/); // No leftover white unstyled view-prompt class assert.equal(reviewSrc.includes('view-prompt-btn'), false); assert.equal(reviewSrc.includes('create-btn'), false); });