From 8caad53f57cd6fca8a14ac1d054e34d5dc95e1eb Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 17 Apr 2026 17:31:54 +0100 Subject: [PATCH] test(matrix): mock runtime fetch seam --- extensions/matrix/src/matrix/sdk.test.ts | 29 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/extensions/matrix/src/matrix/sdk.test.ts b/extensions/matrix/src/matrix/sdk.test.ts index 90e8de38ab6..f490bb247d7 100644 --- a/extensions/matrix/src/matrix/sdk.test.ts +++ b/extensions/matrix/src/matrix/sdk.test.ts @@ -18,6 +18,21 @@ function requestUrl(input: RequestInfo | URL | undefined): string { return input.url; } +const TEST_UNDICI_RUNTIME_DEPS_KEY = "__OPENCLAW_TEST_UNDICI_RUNTIME_DEPS__"; + +function clearTestUndiciRuntimeDepsOverride(): void { + Reflect.deleteProperty(globalThis as object, TEST_UNDICI_RUNTIME_DEPS_KEY); +} + +function stubRuntimeFetch(fetchImpl: typeof fetch): void { + (globalThis as Record)[TEST_UNDICI_RUNTIME_DEPS_KEY] = { + Agent: function MockAgent() {}, + EnvHttpProxyAgent: function MockEnvHttpProxyAgent() {}, + ProxyAgent: function MockProxyAgent() {}, + fetch: fetchImpl, + }; +} + class FakeMatrixEvent extends EventEmitter { private readonly roomId: string; private readonly eventId: string; @@ -224,11 +239,13 @@ describe("MatrixClient request hardening", () => { lastCreateClientOpts = null; vi.useRealTimers(); vi.unstubAllGlobals(); + clearTestUndiciRuntimeDepsOverride(); }); afterEach(() => { vi.useRealTimers(); vi.unstubAllGlobals(); + clearTestUndiciRuntimeDepsOverride(); }); it("blocks absolute endpoints unless explicitly allowed", async () => { @@ -238,7 +255,7 @@ describe("MatrixClient request hardening", () => { headers: { "content-type": "application/json" }, }); }); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("https://matrix.example.org", "token"); await expect(client.doRequest("GET", "https://matrix.example.org/start")).rejects.toThrow( @@ -265,7 +282,7 @@ describe("MatrixClient request hardening", () => { const fetchMock = vi.fn<(input: RequestInfo | URL, init?: RequestInit) => Promise>( async () => new Response(payload, { status: 200 }), ); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("http://127.0.0.1:8008", "token", { ssrfPolicy: { allowPrivateNetwork: true }, @@ -296,7 +313,7 @@ describe("MatrixClient request hardening", () => { } return new Response(payload, { status: 200 }); }); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("http://127.0.0.1:8008", "token", { ssrfPolicy: { allowPrivateNetwork: true }, @@ -475,7 +492,7 @@ describe("MatrixClient request hardening", () => { }, }); }); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("http://127.0.0.1:8008", "token", { ssrfPolicy: { allowPrivateNetwork: true }, @@ -506,7 +523,7 @@ describe("MatrixClient request hardening", () => { headers: { "content-type": "application/json" }, }); }); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("http://127.0.0.1:8008", "token", { ssrfPolicy: { allowPrivateNetwork: true }, @@ -531,7 +548,7 @@ describe("MatrixClient request hardening", () => { }); }); }); - vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + stubRuntimeFetch(fetchMock as unknown as typeof fetch); const client = new MatrixClient("http://127.0.0.1:8008", "token", { localTimeoutMs: 25,