test: isolate channel media network guards

This commit is contained in:
Peter Steinberger
2026-04-11 00:01:21 +01:00
parent 97df07ed9a
commit ecf76bd97e
3 changed files with 30 additions and 24 deletions

View File

@@ -4,8 +4,8 @@ import os from "node:os";
import path from "node:path";
import { resetInboundDedupe } from "openclaw/plugin-sdk/reply-runtime";
import { resetLogger, setLoggerOverride } from "openclaw/plugin-sdk/runtime-env";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
import { afterAll, afterEach, beforeAll, beforeEach, vi, type Mock } from "vitest";
import { mockPinnedHostnameResolution } from "../../../src/test-helpers/ssrf.js";
import type { WebInboundMessage, WebListenerCloseReason } from "./inbound.js";
import {
resetBaileysMocks as _resetBaileysMocks,
@@ -38,7 +38,7 @@ type WebAutoReplyMonitorHarness = {
run: Promise<unknown>;
};
export const TEST_NET_IP = "203.0.113.10";
export const TEST_NET_IP = "93.184.216.34";
vi.mock("openclaw/plugin-sdk/agent-runtime", () => ({
abortEmbeddedPiRun: vi.fn().mockReturnValue(false),
@@ -148,19 +148,7 @@ export function installWebAutoReplyUnitTestHooks(opts?: { pinDns?: boolean }) {
_resetBaileysMocks();
_resetLoadConfigMock();
if (opts?.pinDns) {
const ssrf = await import("../../../src/infra/net/ssrf.js");
resolvePinnedHostnameSpy = vi
.spyOn(ssrf, "resolvePinnedHostname")
.mockImplementation(async (hostname) => {
// SSRF guard pins DNS; stub resolution to avoid live lookups in unit tests.
const normalized = normalizeLowercaseStringOrEmpty(hostname).replace(/\.$/, "");
const addresses = [TEST_NET_IP];
return {
hostname: normalized,
addresses,
lookup: ssrf.createPinnedLookup({ hostname: normalized, addresses }),
};
});
resolvePinnedHostnameSpy = mockPinnedHostnameResolution([TEST_NET_IP]);
}
});

View File

@@ -110,6 +110,17 @@ describe("web session", () => {
});
it("does not create a proxy agent when no env proxy is configured", async () => {
for (const key of [
"ALL_PROXY",
"all_proxy",
"HTTP_PROXY",
"http_proxy",
"HTTPS_PROXY",
"https_proxy",
]) {
vi.stubEnv(key, "");
}
await createWaSocket(false, false);
const passed = (baileys.makeWASocket as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as {

View File

@@ -1,21 +1,28 @@
import { vi } from "vitest";
import * as ssrf from "../infra/net/ssrf.js";
import type { LookupFn } from "../infra/net/ssrf.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
export function mockPinnedHostnameResolution(addresses: string[] = ["93.184.216.34"]) {
const resolve = async (hostname: string) => {
const resolvePinnedHostname = ssrf.resolvePinnedHostname;
const resolvePinnedHostnameWithPolicy = ssrf.resolvePinnedHostnameWithPolicy;
const lookupFn = (async (hostname: string, options?: { all?: boolean }) => {
const normalized = normalizeLowercaseStringOrEmpty(hostname).replace(/\.$/, "");
const pinnedAddresses = [...addresses];
return {
const resolved = addresses.map((address) => ({
address,
family: address.includes(":") ? 6 : 4,
hostname: normalized,
addresses: pinnedAddresses,
lookup: ssrf.createPinnedLookup({ hostname: normalized, addresses: pinnedAddresses }),
};
};
const pinned = vi.spyOn(ssrf, "resolvePinnedHostname").mockImplementation(resolve);
}));
return options?.all === true ? resolved : resolved[0];
}) as LookupFn;
const pinned = vi
.spyOn(ssrf, "resolvePinnedHostname")
.mockImplementation((hostname) => resolvePinnedHostname(hostname, lookupFn));
const pinnedWithPolicy = vi
.spyOn(ssrf, "resolvePinnedHostnameWithPolicy")
.mockImplementation(async (hostname) => resolve(hostname));
.mockImplementation((hostname, params) =>
resolvePinnedHostnameWithPolicy(hostname, { ...params, lookupFn }),
);
return {
mockRestore: () => {
pinned.mockRestore();