mirror of https://github.com/openclaw/openclaw.git
122 lines
4.3 KiB
TypeScript
122 lines
4.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const gatewayRuntimeHoisted = vi.hoisted(() => ({
|
|
requestSpy: vi.fn(),
|
|
startSpy: vi.fn(),
|
|
stopSpy: vi.fn(),
|
|
stopAndWaitSpy: vi.fn(async () => undefined),
|
|
createClientSpy: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("openclaw/plugin-sdk/gateway-runtime", () => ({
|
|
createOperatorApprovalsGatewayClient: gatewayRuntimeHoisted.createClientSpy,
|
|
}));
|
|
|
|
describe("resolveTelegramExecApproval", () => {
|
|
beforeEach(() => {
|
|
gatewayRuntimeHoisted.requestSpy.mockReset();
|
|
gatewayRuntimeHoisted.startSpy.mockReset();
|
|
gatewayRuntimeHoisted.stopSpy.mockReset();
|
|
gatewayRuntimeHoisted.stopAndWaitSpy.mockReset().mockResolvedValue(undefined);
|
|
gatewayRuntimeHoisted.createClientSpy.mockReset().mockImplementation((opts) => ({
|
|
start: () => {
|
|
gatewayRuntimeHoisted.startSpy();
|
|
opts.onHelloOk?.();
|
|
},
|
|
request: gatewayRuntimeHoisted.requestSpy,
|
|
stop: gatewayRuntimeHoisted.stopSpy,
|
|
stopAndWait: gatewayRuntimeHoisted.stopAndWaitSpy,
|
|
}));
|
|
});
|
|
|
|
it("routes plugin approval ids through plugin.approval.resolve", async () => {
|
|
const { resolveTelegramExecApproval } = await import("./exec-approval-resolver.js");
|
|
|
|
await resolveTelegramExecApproval({
|
|
cfg: {} as never,
|
|
approvalId: "plugin:abc123",
|
|
decision: "allow-once",
|
|
senderId: "9",
|
|
});
|
|
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenCalledWith("plugin.approval.resolve", {
|
|
id: "plugin:abc123",
|
|
decision: "allow-once",
|
|
});
|
|
});
|
|
|
|
it("falls back to plugin.approval.resolve when exec approval ids are unknown", async () => {
|
|
gatewayRuntimeHoisted.requestSpy
|
|
.mockRejectedValueOnce(new Error("unknown or expired approval id"))
|
|
.mockResolvedValueOnce(undefined);
|
|
const { resolveTelegramExecApproval } = await import("./exec-approval-resolver.js");
|
|
|
|
await resolveTelegramExecApproval({
|
|
cfg: {} as never,
|
|
approvalId: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
senderId: "9",
|
|
allowPluginFallback: true,
|
|
});
|
|
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenNthCalledWith(1, "exec.approval.resolve", {
|
|
id: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
});
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenNthCalledWith(2, "plugin.approval.resolve", {
|
|
id: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
});
|
|
});
|
|
|
|
it("falls back to plugin.approval.resolve for structured approval-not-found errors", async () => {
|
|
const err = new Error("approval not found");
|
|
(err as Error & { gatewayCode?: string; details?: { reason?: string } }).gatewayCode =
|
|
"INVALID_REQUEST";
|
|
(err as Error & { gatewayCode?: string; details?: { reason?: string } }).details = {
|
|
reason: "APPROVAL_NOT_FOUND",
|
|
};
|
|
gatewayRuntimeHoisted.requestSpy.mockRejectedValueOnce(err).mockResolvedValueOnce(undefined);
|
|
const { resolveTelegramExecApproval } = await import("./exec-approval-resolver.js");
|
|
|
|
await resolveTelegramExecApproval({
|
|
cfg: {} as never,
|
|
approvalId: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
senderId: "9",
|
|
allowPluginFallback: true,
|
|
});
|
|
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenNthCalledWith(1, "exec.approval.resolve", {
|
|
id: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
});
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenNthCalledWith(2, "plugin.approval.resolve", {
|
|
id: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
});
|
|
});
|
|
|
|
it("does not fall back to plugin.approval.resolve without explicit permission", async () => {
|
|
gatewayRuntimeHoisted.requestSpy.mockRejectedValueOnce(
|
|
new Error("unknown or expired approval id"),
|
|
);
|
|
const { resolveTelegramExecApproval } = await import("./exec-approval-resolver.js");
|
|
|
|
await expect(
|
|
resolveTelegramExecApproval({
|
|
cfg: {} as never,
|
|
approvalId: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
senderId: "9",
|
|
}),
|
|
).rejects.toThrow("unknown or expired approval id");
|
|
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenCalledTimes(1);
|
|
expect(gatewayRuntimeHoisted.requestSpy).toHaveBeenCalledWith("exec.approval.resolve", {
|
|
id: "legacy-plugin-123",
|
|
decision: "allow-always",
|
|
});
|
|
});
|
|
});
|