Files

90 lines
3.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test, vi } from "vite-plus/test";
import { defineCommand, ExitCode, type CommandRisk, type LocalizedText } from "bailian-cli-core";
import { ConfirmationRequiredError, confirmationFlagDefs } from "../src/confirm.ts";
import { confirmationStage, type RunContext } from "../src/middleware.ts";
const HIGH_RISK_MESSAGE = {
"en-US": "This permanently deletes the document and its chunks.",
"zh-CN": "该操作会永久删除文档及其 Chunk且无法撤销。",
} satisfies LocalizedText;
function makeContext(options: {
risk?: CommandRisk;
confirmed?: boolean;
dryRun?: boolean;
}): RunContext {
const command = defineCommand({
description: "Delete a document",
auth: "none",
risk: options.risk,
async run() {},
});
return {
identity: {
binName: "bl",
version: "0.0.0-test",
clientName: "bailian-cli-test",
npmPackage: "bailian-cli",
},
path: ["knowledge", "doc", "delete"],
command,
flags: {},
confirmed: options.confirmed ?? false,
localize: (text: LocalizedText) => (typeof text === "string" ? text : text["zh-CN"]),
settings: { dryRun: options.dryRun ?? false } as RunContext["settings"],
} as unknown as RunContext;
}
describe("confirmation metadata", () => {
test("injects --yes only for high-risk commands", () => {
expect(
confirmationFlagDefs({ risk: { level: "high", message: HIGH_RISK_MESSAGE } }),
).toHaveProperty("yes");
expect(confirmationFlagDefs({})).toEqual({});
});
test("serializes the stable Agent-readable confirmation contract", () => {
const error = new ConfirmationRequiredError({
message: HIGH_RISK_MESSAGE["zh-CN"],
hint: "此命令将执行高风险操作。如确认继续,请在原命令中添加 --yes 后重新执行。",
});
expect(error.exitCode).toBe(ExitCode.CONFIRMATION_REQUIRED);
expect(error.toJSON()).toEqual({
error: {
code: 7,
type: "requires_confirmation",
message: HIGH_RISK_MESSAGE["zh-CN"],
hint: "此命令将执行高风险操作。如确认继续,请在原命令中添加 --yes 后重新执行。",
},
});
});
});
describe("confirmationStage", () => {
test("blocks high-risk execution without echoing the original command", async () => {
const next = vi.fn(async () => {});
const promise = confirmationStage(
makeContext({ risk: { level: "high", message: HIGH_RISK_MESSAGE } }),
next,
);
await expect(promise).rejects.toMatchObject({
exitCode: 7,
message: HIGH_RISK_MESSAGE["zh-CN"],
hint: "此命令将执行高风险操作。如确认继续,请在原命令中添加 --yes 后重新执行。",
});
expect(next).not.toHaveBeenCalled();
});
test.each([
["explicit --yes", { risk: { level: "high", message: HIGH_RISK_MESSAGE }, confirmed: true }],
["dry-run", { risk: { level: "high", message: HIGH_RISK_MESSAGE }, dryRun: true }],
["normal command", {}],
] as const)("passes %s through", async (_label, options) => {
const next = vi.fn(async () => {});
await confirmationStage(makeContext(options), next);
expect(next).toHaveBeenCalledOnce();
});
});