返回 DeepSeek-Reasonix
tool-approval-mode.test.ts
根目录 / desktop / frontend / src / __tests__ / tool-approval-mode.test.ts
1 // Run: tsx src/__tests__/tool-approval-mode.test.ts
2
3 import { restorableToolApprovalMode, toggleYoloToolApprovalMode } from "../lib/toolApprovalMode";
4 import { en } from "../locales/en";
5 import { zh } from "../locales/zh";
6 import { zhTW } from "../locales/zh-TW";
7
8 let passed = 0;
9 let failed = 0;
10
11 function eq(a: unknown, b: unknown, label: string) {
12 if (a === b) {
13 process.stdout.write(` PASS ${label}\n`);
14 passed += 1;
15 } else {
16 process.stdout.write(` FAIL ${label}: expected ${JSON.stringify(b)}, got ${JSON.stringify(a)}\n`);
17 failed += 1;
18 }
19 }
20
21 console.log("\ntool approval mode");
22
23 eq(restorableToolApprovalMode("ask"), "ask", "ask restores to ask");
24 eq(restorableToolApprovalMode("auto"), "auto", "auto restores to auto");
25 eq(restorableToolApprovalMode("yolo"), "ask", "yolo cannot be a restore base");
26
27 let next = toggleYoloToolApprovalMode("ask");
28 eq(next.mode, "yolo", "Ctrl+Y turns ask into yolo");
29 eq(next.restore, "ask", "Ctrl+Y remembers ask");
30
31 next = toggleYoloToolApprovalMode("auto");
32 eq(next.mode, "yolo", "Ctrl+Y turns auto into yolo");
33 eq(next.restore, "auto", "Ctrl+Y remembers auto");
34
35 next = toggleYoloToolApprovalMode("yolo", "auto");
36 eq(next.mode, "auto", "Ctrl+Y restores auto from yolo");
37
38 next = toggleYoloToolApprovalMode("yolo");
39 eq(next.mode, "ask", "Ctrl+Y falls back to ask when no restore base exists");
40
41 eq(en["composer.accessAskTitle"].includes("not read-only"), true, "English Ask copy is not presented as read-only");
42 eq(zh["composer.accessAskTitle"].includes("不是只读"), true, "Simplified Chinese Ask copy is not presented as read-only");
43 eq(zhTW["composer.accessAskTitle"].includes("不是唯讀"), true, "Traditional Chinese Ask copy is not presented as read-only");
44 eq(en["heartbeat.approvalModeAskHint"].includes("not read-only"), true, "heartbeat Ask hint preserves the same boundary");
45 eq(en["composer.taskModePlanDesc"].includes("permissions and sandbox"), true, "Plan copy names permissions and sandbox");
46 eq(en["composer.accessFullDesc"].includes("ordinary") && en["composer.accessFullDesc"].includes("fresh reviews"), true, "English Full access preserves fresh-review boundary");
47 eq(zh["composer.accessFullDesc"].includes("普通") && zh["composer.accessFullDesc"].includes("强制新鲜审查"), true, "Simplified Chinese Full access preserves fresh-review boundary");
48 eq(zhTW["composer.accessFullDesc"].includes("普通") && zhTW["composer.accessFullDesc"].includes("強制新鮮審查"), true, "Traditional Chinese Full access preserves fresh-review boundary");
49 eq(en["composer.accessFullDesc"].includes("all tool permission approvals"), false, "Full access does not promise to bypass every approval");
50 eq(en["status.yoloTitle"].includes("ordinary") && en["status.yoloTitle"].includes("fresh reviews"), true, "English YOLO status preserves fresh-review boundary");
51 eq(zh["status.yoloTitle"].includes("普通") && zh["status.yoloTitle"].includes("强制新鲜审批"), true, "Simplified Chinese YOLO status preserves fresh-review boundary");
52 eq(zhTW["status.yoloTitle"].includes("普通") && zhTW["status.yoloTitle"].includes("強制新鮮審批"), true, "Traditional Chinese YOLO status preserves fresh-review boundary");
53 eq(en["settings.yolo"].includes("ordinary"), true, "English YOLO setting names ordinary prompts only");
54 eq(zh["settings.yolo"].includes("普通"), true, "Simplified Chinese YOLO setting names ordinary prompts only");
55 eq(zhTW["settings.yolo"].includes("普通"), true, "Traditional Chinese YOLO setting names ordinary prompts only");
56
57 console.log(`\n${passed} passed, ${failed} failed, ${passed + failed} total`);
58 if (failed > 0) process.exit(1);
59
59 lines TYPESCRIPT