mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-19 08:41:38 +00:00
* fix(exec-approval): stop misattributing Allow Always unavailability to policy Allow Always is dropped both when policy ask=always AND when a command is non-persistable (e.g. shell redirect `2>&1` -> one-shot), but the prompt always claimed 'effective approval policy requires approval every time'. That's misleading for the non-persistable case (#97069). Reword to reason-neutral 'Allow Always is unavailable for this command.' across all approval surfaces, update en + 20 locale bundles, refresh i18n meta, and the matching tests. Closes #97069 * fix(exec-approval): stop misattributing Allow Always unavailability to policy * test(ui): await exec approval render updates * chore(ui): sync approval i18n metadata --------- Co-authored-by: saju01 <saju01@users.noreply.github.com> Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com> Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
108 lines
3.0 KiB
TypeScript
108 lines
3.0 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { html, nothing, render, type LitElement } from "lit";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { ExecApprovalRequest } from "../app/exec-approval.ts";
|
|
import { i18n } from "../i18n/index.ts";
|
|
import { getRenderedModalDialog, installDialogPolyfill } from "../test-helpers/modal-dialog.ts";
|
|
import "./exec-approval.ts";
|
|
|
|
let container: HTMLDivElement;
|
|
let restoreDialogPolyfill: () => void;
|
|
|
|
function createExecRequest(overrides: Partial<ExecApprovalRequest> = {}): ExecApprovalRequest {
|
|
return {
|
|
id: "approval-1",
|
|
kind: "exec",
|
|
request: {
|
|
command: "echo hello",
|
|
ask: "on-request",
|
|
},
|
|
createdAtMs: Date.now() - 1_000,
|
|
expiresAtMs: Date.now() + 60_000,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
async function renderApproval(request: ExecApprovalRequest) {
|
|
render(
|
|
html`<openclaw-exec-approval
|
|
.props=${{
|
|
queue: [request],
|
|
busy: false,
|
|
error: null,
|
|
onDecision: vi.fn(),
|
|
}}
|
|
></openclaw-exec-approval>`,
|
|
container,
|
|
);
|
|
const approval = container.querySelector<LitElement>("openclaw-exec-approval");
|
|
if (!approval) {
|
|
throw new Error("Expected exec approval");
|
|
}
|
|
await approval.updateComplete;
|
|
}
|
|
|
|
describe("openclaw-exec-approval", () => {
|
|
beforeEach(async () => {
|
|
restoreDialogPolyfill = installDialogPolyfill();
|
|
await i18n.setLocale("en");
|
|
container = document.createElement("div");
|
|
document.body.append(container);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
render(nothing, container);
|
|
container.remove();
|
|
await i18n.setLocale("en");
|
|
restoreDialogPolyfill();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("uses neutral unavailable copy for exec allow-always decisions", async () => {
|
|
await renderApproval(
|
|
createExecRequest({
|
|
request: {
|
|
command: "echo hello",
|
|
ask: "always",
|
|
allowedDecisions: ["allow-once", "deny"],
|
|
},
|
|
}),
|
|
);
|
|
|
|
await getRenderedModalDialog(container);
|
|
|
|
expect(
|
|
Array.from(container.querySelectorAll(".exec-approval-actions button")).map((button) =>
|
|
button.textContent?.trim(),
|
|
),
|
|
).toEqual(["Allow once", "Deny"]);
|
|
expect(container.querySelector(".exec-approval-warning")?.textContent?.trim()).toBe(
|
|
"Allow Always is unavailable for this command.",
|
|
);
|
|
});
|
|
|
|
it("does not show exec unavailable copy for restricted plugin approvals", async () => {
|
|
await renderApproval(
|
|
createExecRequest({
|
|
id: "plugin-approval-1",
|
|
kind: "plugin",
|
|
request: {
|
|
command: "Plugin approval",
|
|
allowedDecisions: ["allow-once", "deny"],
|
|
},
|
|
pluginTitle: "Plugin approval",
|
|
}),
|
|
);
|
|
|
|
await getRenderedModalDialog(container);
|
|
|
|
expect(
|
|
Array.from(container.querySelectorAll(".exec-approval-actions button")).map((button) =>
|
|
button.textContent?.trim(),
|
|
),
|
|
).toEqual(["Allow once", "Deny"]);
|
|
expect(container.querySelector(".exec-approval-warning")).toBeNull();
|
|
});
|
|
});
|