import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; const repoRoot = fileURLToPath(new URL("../../../../", import.meta.url)); function readRepoFile(path: string): string { return readFileSync(resolve(repoRoot, path), "utf8"); } describe("front-end polish API integration", () => { it("uses a local Vite React entry without runtime CDN or mock data", () => { const pkg = readRepoFile("apps/web-legacy/package.json"); const html = readRepoFile("apps/web-legacy/index.html"); const main = readRepoFile("apps/web-legacy/src/main.tsx"); expect(pkg).toContain('"vite"'); expect(pkg).toContain('"react"'); expect(html).toContain('type="module"'); expect(html).not.toContain("unpkg.com"); expect(html).not.toContain("@babel/standalone"); expect(main).toContain("createRoot"); expect(main).not.toContain("MOCK"); }); it("keeps polish on browser direct with saved personal credentials", () => { const settings = readRepoFile("apps/web-legacy/src/settings.ts"); const polishClient = readRepoFile("apps/web-legacy/src/lib/polishClient.ts"); const app = readRepoFile("apps/web-legacy/src/App.tsx"); expect(settings).toContain('polishTransport: "browser"'); expect(settings).toContain("savedModelCredentials"); expect(polishClient).toContain("polishBrowser"); expect(polishClient).not.toContain("polishBackend"); expect(polishClient).not.toContain('fetch("/api/polish"'); expect(polishClient).toContain("请填写浏览器 API Key,或在个人设置里选择已保存的连接。"); expect(app).toContain("未选择保存的连接"); expect(app).toContain("保存当前连接"); expect(app).toContain("删除所选连接"); expect(app).not.toContain(''); }); it("keeps API/MCP analysis on the backend queue by default", () => { const settings = readRepoFile("apps/web-legacy/src/settings.ts"); const analysisClient = readRepoFile("apps/web-legacy/src/lib/analysisClient.ts"); const app = readRepoFile("apps/web-legacy/src/App.tsx"); expect(settings).toContain('analysisTransport: "backend"'); expect(analysisClient).toContain('form.append("requestedMode", requestedMode)'); expect(analysisClient).toContain('fetch("/api/analysis/jobs"'); expect(analysisClient).toContain('"/api/analysis/jobs/" + encodeURIComponent(jobId) + "/start"'); expect(analysisClient).toContain('"/api/analysis/jobs/" + encodeURIComponent(jobId) + "/items/"'); expect(analysisClient).not.toContain("rubricGeneration:"); expect(analysisClient).not.toContain("settings.judge"); expect(analysisClient).not.toContain("settings.streaming"); expect(app).not.toContain("启用流式渲染"); expect(app).toContain("state.items.map((item) => item.file).filter((file): file is File => Boolean(file))"); expect(app).toContain("刷新后无法恢复本地 ZIP 文件,请重新选择 zip 后再开始分析"); expect(app).toContain("detectedMode: created.items[index]?.detectedMode || item.detectedMode || kind"); expect(app).toContain("detectedMode: server.detectedMode || item.detectedMode"); expect(app).toContain("loadAnalysisState(\"mcp\")"); expect(app).toContain("saveAnalysisState(\"mcp\", mcpState)"); expect(app).toContain("清空队列"); expect(app).toContain("analysisTransport"); expect(app).toContain("optimizeTask: false"); expect(app).toContain("ignoreTaskComplexityForFullMarks: false"); expect(app).toContain("忽略 Complexity"); expect(app).toContain("btn-stop-analysis"); expect(app).toContain("!selected.hasExport"); expect(app).toContain("item.status !== \"queued\" || item.hasExport"); expect(app).toContain("latestJudgeScoreLabel"); expect(app).toContain("judgeHistory"); }); });