Files
pikasTech-unidesk/scripts/src/output.test.ts
T
2026-07-13 05:20:27 +02:00

61 lines
2.8 KiB
TypeScript

import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { describe, expect, test } from "bun:test";
import { repoRoot } from "./config";
const dumpDir = "/tmp/unidesk-cli-output";
function runOversizedIssueOutput(token: string, explicit = false): { status: number | null; stdout: string; stderr: string } {
const command = `gh issue view 1890 --repo pikasTech/unidesk --json body ${token}`;
const script = [
"import { emitJson } from './scripts/src/output.ts';",
`emitJson(${JSON.stringify(command)}, {`,
" command: 'issue view',",
" repo: 'pikasTech/unidesk',",
" issue: { number: 1890, title: 'large body', state: 'open', url: 'https://example.invalid/1890', body: 'x'.repeat(30000) },",
"});",
].join("\n");
const args = ["-e", script, "output-test", ...(explicit ? ["--full"] : [])];
const result = spawnSync("bun", args, { cwd: repoRoot, encoding: "utf8" });
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
}
function matchingDumps(token: string): string[] {
if (!existsSync(dumpDir)) return [];
return readdirSync(dumpDir).filter((name) => name.includes(token));
}
describe("CLI oversized output disclosure", () => {
test("default oversized output creates no dump and gives the semantic gh text route", () => {
const token = `nodump-${process.pid}-${Date.now()}`;
expect(matchingDumps(token)).toEqual([]);
const result = runOversizedIssueOutput(token);
expect(result.status).toBe(0);
expect(result.stderr).toBe("");
const payload = JSON.parse(result.stdout) as { data: { outputTruncated: boolean; dump?: unknown; next: string[]; disclosurePolicy: Record<string, unknown> } };
expect(payload.data.outputTruncated).toBe(true);
expect(payload.data.dump).toBeUndefined();
expect(payload.data.disclosurePolicy).toMatchObject({ defaultCreatesDump: false, dumpCreated: false });
expect(payload.data.next[0]).toBe("trans gh:/pikasTech/unidesk/issue/1890 cat");
expect(matchingDumps(token)).toEqual([]);
});
test("explicit full disclosure keeps a protected complete dump", () => {
const token = `fulldump-${process.pid}-${Date.now()}`;
expect(matchingDumps(token)).toEqual([]);
const result = runOversizedIssueOutput(token, true);
expect(result.status).toBe(0);
expect(result.stderr).toBe("");
const payload = JSON.parse(result.stdout) as { data: { dump: { path: string }; disclosurePolicy: Record<string, unknown> } };
expect(payload.data.disclosurePolicy).toMatchObject({ defaultCreatesDump: false, dumpCreated: true });
expect(existsSync(payload.data.dump.path)).toBe(true);
expect(readFileSync(payload.data.dump.path, "utf8")).toContain(token);
rmSync(payload.data.dump.path, { force: true });
expect(matchingDumps(token)).toEqual([]);
});
});