






















@@ -0,0 +1,127 @@
1+import http from "node:http";
2+import { afterEach, describe, expect, it, vi } from "vitest";
3+import type { OpenClawConfig } from "../config/config.js";
4+import { getFreePort, installGatewayTestHooks, startGatewayServer } from "./test-helpers.js";
5+6+const webFetchProviderDiscovery = vi.hoisted(() => ({
7+resolveBundledWebFetchProvidersFromPublicArtifactsMock: vi.fn(() => {
8+throw new Error("gateway startup must not discover bundled web fetch providers before bind");
9+}),
10+resolvePluginWebFetchProvidersMock: vi.fn(() => {
11+throw new Error("gateway startup must not discover plugin web fetch providers before bind");
12+}),
13+}));
14+15+vi.mock("../secrets/runtime-web-tools-fallback.runtime.js", async () => {
16+const actual = await vi.importActual<
17+typeof import("../secrets/runtime-web-tools-fallback.runtime.js")
18+>("../secrets/runtime-web-tools-fallback.runtime.js");
19+return {
20+ ...actual,
21+runtimeWebToolsFallbackProviders: {
22+ ...actual.runtimeWebToolsFallbackProviders,
23+resolvePluginWebFetchProviders: webFetchProviderDiscovery.resolvePluginWebFetchProvidersMock,
24+},
25+};
26+});
27+28+vi.mock("../secrets/runtime-web-tools-public-artifacts.runtime.js", async () => {
29+const actual = await vi.importActual<
30+typeof import("../secrets/runtime-web-tools-public-artifacts.runtime.js")
31+>("../secrets/runtime-web-tools-public-artifacts.runtime.js");
32+return {
33+ ...actual,
34+resolveBundledWebFetchProvidersFromPublicArtifacts:
35+webFetchProviderDiscovery.resolveBundledWebFetchProvidersFromPublicArtifactsMock,
36+};
37+});
38+39+installGatewayTestHooks();
40+41+afterEach(() => {
42+webFetchProviderDiscovery.resolveBundledWebFetchProvidersFromPublicArtifactsMock.mockClear();
43+webFetchProviderDiscovery.resolvePluginWebFetchProvidersMock.mockClear();
44+});
45+46+async function requestHealthz(port: number): Promise<{ status: number; body: string }> {
47+return await new Promise((resolve, reject) => {
48+const req = http.request(
49+{
50+host: "127.0.0.1",
51+ port,
52+path: "/healthz",
53+},
54+(res) => {
55+let body = "";
56+res.setEncoding("utf8");
57+res.on("data", (chunk) => {
58+body += chunk;
59+});
60+res.once("end", () => {
61+resolve({ status: res.statusCode ?? 0, body });
62+});
63+},
64+);
65+req.once("error", reject);
66+req.setTimeout(5_000, () => {
67+req.destroy(new Error("timeout waiting for /healthz"));
68+});
69+req.end();
70+});
71+}
72+73+async function writeConfig(config: OpenClawConfig): Promise<void> {
74+const { writeConfigFile } = await import("../config/config.js");
75+await writeConfigFile(config);
76+}
77+78+describe("gateway startup web fetch config", () => {
79+it("binds HTTP with credential-free tools.web.fetch config without fetch provider discovery", async () => {
80+const previousMinimal = process.env.OPENCLAW_TEST_MINIMAL_GATEWAY;
81+process.env.OPENCLAW_TEST_MINIMAL_GATEWAY = "0";
82+let server: Awaited<ReturnType<typeof startGatewayServer>> | undefined;
83+try {
84+await writeConfig({
85+gateway: {
86+mode: "local",
87+auth: { mode: "none" },
88+},
89+plugins: {
90+enabled: true,
91+allow: [],
92+entries: {},
93+},
94+tools: {
95+web: {
96+fetch: {
97+enabled: true,
98+maxChars: 200_000,
99+maxCharsCap: 2_000_000,
100+},
101+},
102+},
103+} as OpenClawConfig);
104+105+const port = await getFreePort();
106+server = await startGatewayServer(port, {
107+auth: { mode: "none" },
108+});
109+110+const response = await requestHealthz(port);
111+expect(response.status).toBe(200);
112+expect(
113+webFetchProviderDiscovery.resolveBundledWebFetchProvidersFromPublicArtifactsMock,
114+).not.toHaveBeenCalled();
115+expect(webFetchProviderDiscovery.resolvePluginWebFetchProvidersMock).not.toHaveBeenCalled();
116+} finally {
117+if (server) {
118+await server.close();
119+}
120+if (previousMinimal === undefined) {
121+delete process.env.OPENCLAW_TEST_MINIMAL_GATEWAY;
122+} else {
123+process.env.OPENCLAW_TEST_MINIMAL_GATEWAY = previousMinimal;
124+}
125+}
126+});
127+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。