From 944ec112face6cbbd55a8fb7757ab8cecf99e167 Mon Sep 17 00:00:00 2001 From: Tideclaw Date: Wed, 10 Jun 2026 20:02:17 +0000 Subject: [PATCH] test: tolerate stale mcp pairing approvals (cherry picked from commit c3b31018905b6d34763e60a55b9d0980df2254c7) (cherry picked from commit b73232a594a33e8afa7d48ec789297a2494215ca) --- scripts/e2e/mcp-channels-harness.ts | 9 ++++++- test/scripts/mcp-channels-harness.test.ts | 31 +++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/scripts/e2e/mcp-channels-harness.ts b/scripts/e2e/mcp-channels-harness.ts index 330194e9eeda..a1c5a049ad83 100644 --- a/scripts/e2e/mcp-channels-harness.ts +++ b/scripts/e2e/mcp-channels-harness.ts @@ -307,6 +307,13 @@ export async function maybeApprovePendingBridgePairing( if (!pendingRequest?.requestId) { return false; } - await gateway.request("device.pair.approve", { requestId: pendingRequest.requestId }); + try { + await gateway.request("device.pair.approve", { requestId: pendingRequest.requestId }); + } catch (error) { + if (formatErrorMessage(error).includes("unknown requestId")) { + return false; + } + throw error; + } return true; } diff --git a/test/scripts/mcp-channels-harness.test.ts b/test/scripts/mcp-channels-harness.test.ts index 6147bf876042..ac87fd565457 100644 --- a/test/scripts/mcp-channels-harness.test.ts +++ b/test/scripts/mcp-channels-harness.test.ts @@ -3,12 +3,24 @@ import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from "node:fs import { tmpdir } from "node:os"; import path from "node:path"; import { describe, expect, it, vi } from "vitest"; +import { + maybeApprovePendingBridgePairing, + type GatewayRpcClient, +} from "../../scripts/e2e/mcp-channels-harness.ts"; import { connectMcpClientWithPairingReconnect, createMcpClientTempState, type McpClientTempState, } from "../../scripts/e2e/mcp-client-temp-state.js"; +function createGateway(request: GatewayRpcClient["request"]): GatewayRpcClient { + return { + request, + events: [], + close: async () => {}, + }; +} + describe("mcp-channels harness", () => { it("creates unique client temp state and removes token files on cleanup", () => { const tempRoot = mkdtempSync(path.join(tmpdir(), "openclaw-mcp-harness-test-")); @@ -97,4 +109,23 @@ describe("mcp-channels harness", () => { tempState.cleanup(); } }); + + it("treats stale pairing request approvals as already handled", async () => { + const request = vi.fn(async (method) => { + if (method === "device.pair.list") { + return { + pending: [{ requestId: "stale-request", role: "operator" }], + }; + } + if (method === "device.pair.approve") { + throw new Error("unknown requestId"); + } + throw new Error(`unexpected method: ${method}`); + }); + + await expect(maybeApprovePendingBridgePairing(createGateway(request))).resolves.toBe(false); + expect(request).toHaveBeenCalledWith("device.pair.approve", { + requestId: "stale-request", + }); + }); });