




















@@ -866,7 +866,7 @@ describe("createTelegramBot", () => {
866866expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-approve-target");
867867});
868868869-it("keeps legacy plugin fallback approval failures retryable for target-only recipients", async () => {
869+it("drops target-only approval not-found misses without clearing legacy fallback buttons", async () => {
870870onSpy.mockClear();
871871editMessageReplyMarkupSpy.mockClear();
872872editMessageTextSpy.mockClear();
@@ -898,23 +898,21 @@ describe("createTelegramBot", () => {
898898throw new Error("Expected Telegram callback_query handler");
899899}
900900901-await expect(
902-callbackHandler({
903-callbackQuery: {
904-id: "cbq-legacy-plugin-fallback-blocked",
905-data: "/approve 138e9b8c allow-once",
906-from: { id: 9, first_name: "Ada", username: "ada_bot" },
907-message: {
908-chat: { id: 1234, type: "private" },
909-date: 1736380800,
910-message_id: 25,
911-text: "Legacy plugin approval required.",
912-},
901+await callbackHandler({
902+callbackQuery: {
903+id: "cbq-legacy-plugin-fallback-blocked",
904+data: "/approve 138e9b8c allow-once",
905+from: { id: 9, first_name: "Ada", username: "ada_bot" },
906+message: {
907+chat: { id: 1234, type: "private" },
908+date: 1736380800,
909+message_id: 25,
910+text: "Legacy plugin approval required.",
913911},
914- me: { username: "openclaw_bot" },
915- getFile: async () => ({ download: async () => new Uint8Array() }),
916-}),
917-).rejects.toThrow("unknown or expired approval id");
912+},
913+me: { username: "openclaw_bot" },
914+getFile: async () => ({ download: async () => new Uint8Array() }),
915+});
918916919917const approvalCall = execApprovalCall();
920918const execApprovals = execApprovalTargetConfig(approvalCall);
@@ -930,6 +928,63 @@ describe("createTelegramBot", () => {
930928expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-legacy-plugin-fallback-blocked");
931929});
932930931+it("drops expired approval callbacks for configured approvers after clearing buttons", async () => {
932+onSpy.mockClear();
933+editMessageReplyMarkupSpy.mockClear();
934+editMessageTextSpy.mockClear();
935+resolveExecApprovalSpy.mockClear();
936+replySpy.mockClear();
937+sendMessageSpy.mockClear();
938+resolveExecApprovalSpy.mockRejectedValueOnce(new Error("unknown or expired approval id"));
939+940+loadConfig.mockReturnValue({
941+channels: {
942+telegram: {
943+dmPolicy: "open",
944+allowFrom: ["*"],
945+execApprovals: {
946+enabled: true,
947+approvers: ["9"],
948+target: "dm",
949+},
950+},
951+},
952+});
953+createTelegramBot({ token: "tok" });
954+const callbackHandler = onSpy.mock.calls.find((call) => call[0] === "callback_query")?.[1] as (
955+ctx: Record<string, unknown>,
956+) => Promise<void>;
957+if (!callbackHandler) {
958+throw new Error("Expected Telegram callback_query handler");
959+}
960+961+await callbackHandler({
962+callbackQuery: {
963+id: "cbq-expired-approval",
964+data: "/approve 138e9b8c allow-once",
965+from: { id: 9, first_name: "Ada", username: "ada_bot" },
966+message: {
967+chat: { id: 1234, type: "private" },
968+date: 1736380800,
969+message_id: 26,
970+text: "Approval required.",
971+},
972+},
973+me: { username: "openclaw_bot" },
974+getFile: async () => ({ download: async () => new Uint8Array() }),
975+});
976+977+const approvalCall = execApprovalCall();
978+expect(approvalCall.approvalId).toBe("138e9b8c");
979+expect(approvalCall.decision).toBe("allow-once");
980+expect(approvalCall.allowPluginFallback).toBe(true);
981+expect(approvalCall.senderId).toBe("9");
982+expect(editMessageReplyMarkupSpy).toHaveBeenCalledTimes(1);
983+expect(replySpy).not.toHaveBeenCalled();
984+expect(sendMessageSpy).not.toHaveBeenCalled();
985+expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-expired-approval");
986+});
987+933988it("keeps plugin approval callback buttons for target-only recipients", async () => {
934989onSpy.mockClear();
935990editMessageReplyMarkupSpy.mockClear();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。