import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import * as harness from "../src/index.js"; const roots: string[] = []; afterEach(async () => { for (const root of roots.splice(0)) await rm(root, { recursive: true, force: true }); }); describe("Minis report service", () => { it("requires captured query evidence and returns real HTML with an explicit PDF failure", async () => { const root = await mkdtemp(join(tmpdir(), "minis-report-test-")); roots.push(root); const skill = join(root, "skill"); await mkdir(join(skill, "scripts"), { recursive: true }); await writeFile(join(skill, "scripts/generate_report.py"), 'import sys,json,html\nfrom pathlib import Path\nd=json.loads(Path(sys.argv[1]).read_text())\nPath(sys.argv[2]).write_text("

"+html.escape(d["title"])+"

")\n'); const Constructor = Reflect.get(harness, "MinisReportService"); expect(Constructor).toBeDefined(); const service = new Constructor({ workspace: await harness.SafeWorkspace.create(root), sessionId: "ses_test", skillRoot: skill, chromeExecutable: "/missing/chrome", pythonExecutable: "/usr/bin/python3" }); const data = { title: "渲染验收(人工测试数据)", report_type: "daily", period: "2026-09-01", comparison_period: "2026-08-31", currency: "USD", timezone: "UTC", data_status: "测试", conclusion: "仅测试排版,不是经营数据", cards: [], issues: [] }; await expect(service.generate({ data, source_query_ids: [] })).rejects.toThrow("query"); const queryId = service.recordQuery({ date_from: "2026-09-01" }, { content: [{ type: "text", text: "test-only" }] }); await expect(service.generate({ data, source_query_ids: ["unknown"] })).rejects.toThrow("query"); const output = await service.generate({ data, source_query_ids: [queryId] }); expect(output.pdfStatus).toBe("failed"); expect(output.files.map((f: {format: string}) => f.format)).toEqual(["json", "html"]); expect(output.files[1]?.url).toMatch(/^\/api\/sessions\/ses_test\/reports\/rpt_[\w-]+\/html$/); const html = await service.read(output.reportId, "html"); expect(html.bytes.toString()).toContain("人工测试数据"); await expect(service.read(output.reportId, "../../.env")).rejects.toThrow(); const json = JSON.parse((await service.read(output.reportId, "json")).bytes.toString()) as { source_queries: Array<{queryId: string}> }; expect(json.source_queries[0]?.queryId).toBe(queryId); expect(await readFile(join(skill, "scripts/generate_report.py"), "utf8")).not.toContain("SWADS_MCP_TOKEN"); }); });