import assert from 'node:assert/strict'; import { existsSync, readFileSync } from 'node:fs'; import test from 'node:test'; function readSource(path: string): string { assert.equal(existsSync(path), true, `${path} should exist`); return readFileSync(path, 'utf8'); } test('analysis context drawer is read-only and reuses the shared analysis result block', () => { const entryButton = readSource('components/analysis/AnalysisEntryButton.tsx'); const drawer = readSource('components/analysis/AnalysisContextDrawer.tsx'); assert.match(entryButton, /export function AnalysisEntryButton/); assert.match(entryButton, /智能分析/); assert.match(drawer, /requestAnalysis/); assert.match(drawer, /AnalysisResultBlock/); assert.match(drawer, /只读取当前上下文和已有权限数据/); assert.match(drawer, /permissions: string\[\]/); assert.doesNotMatch(drawer, /create(Product|Project|Version|Requirement|Plan|Task|TestCase|Bug)/); assert.doesNotMatch(drawer, /update(Product|Project|Version|Requirement|Plan|Task|TestCase|Bug)/); assert.doesNotMatch(drawer, /delete(Product|Project|Version|Requirement|Plan|Task|TestCase|Bug)/); assert.doesNotMatch(drawer, /use(Product|Requirement|VersionPlan|DevTask|TestCase|Bug)Store/); }); test('product, project, and version detail pages wire analysis drawer with scoped contexts', () => { const productPage = readSource('app/products/[id]/page.tsx'); const projectPage = readSource('app/projects/[id]/page.tsx'); const versionPage = readSource('app/versions/[id]/page.tsx'); for (const source of [productPage, projectPage, versionPage]) { assert.match(source, /AnalysisEntryButton/); assert.match(source, /AnalysisContextDrawer/); assert.match(source, /showAnalysisDrawer/); assert.match(source, /currentPermissions/); } assert.match(productPage, /surface: 'product_detail'/); assert.match(productPage, /productId: currentProduct\.id/); assert.match(projectPage, /surface: 'project_detail'/); assert.match(projectPage, /projectId: project\.id/); assert.match(versionPage, /surface: 'version_detail'/); assert.match(versionPage, /versionId: version\.id/); });