mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
test(fetch): align mocks openclaw#19194 thanks @sebslight
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as ssrf from "../../infra/net/ssrf.js";
|
||||
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
|
||||
import { type FetchMock, withFetchPreconnect } from "../../test-utils/fetch-mock.js";
|
||||
|
||||
const lookupMock = vi.fn();
|
||||
const resolvePinnedHostname = ssrf.resolvePinnedHostname;
|
||||
@@ -29,8 +29,10 @@ function textResponse(body: string): Response {
|
||||
} as unknown as Response;
|
||||
}
|
||||
|
||||
function setMockFetch(impl?: (...args: unknown[]) => unknown) {
|
||||
const fetchSpy = vi.fn(impl);
|
||||
function setMockFetch(
|
||||
impl: FetchMock = async (_input: RequestInfo | URL, _init?: RequestInit) => textResponse(""),
|
||||
) {
|
||||
const fetchSpy = vi.fn<FetchMock>(impl);
|
||||
global.fetch = withFetchPreconnect(fetchSpy);
|
||||
return fetchSpy;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ describe("web_search external content wrapping", () => {
|
||||
|
||||
it("wraps Brave result descriptions", async () => {
|
||||
vi.stubEnv("BRAVE_API_KEY", "test-key");
|
||||
const mockFetch = vi.fn(() =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -233,7 +233,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
const result = await tool?.execute?.("call-1", { query: "test" });
|
||||
@@ -254,7 +254,7 @@ describe("web_search external content wrapping", () => {
|
||||
it("does not wrap Brave result urls (raw for tool chaining)", async () => {
|
||||
vi.stubEnv("BRAVE_API_KEY", "test-key");
|
||||
const url = "https://example.com/some-page";
|
||||
const mockFetch = vi.fn(() =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -271,7 +271,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
const result = await tool?.execute?.("call-1", { query: "unique-test-url-not-wrapped" });
|
||||
@@ -284,7 +284,7 @@ describe("web_search external content wrapping", () => {
|
||||
|
||||
it("does not wrap Brave site names", async () => {
|
||||
vi.stubEnv("BRAVE_API_KEY", "test-key");
|
||||
const mockFetch = vi.fn(() =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -301,7 +301,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
const result = await tool?.execute?.("call-1", { query: "unique-test-site-name-wrapping" });
|
||||
@@ -313,7 +313,7 @@ describe("web_search external content wrapping", () => {
|
||||
|
||||
it("does not wrap Brave published ages", async () => {
|
||||
vi.stubEnv("BRAVE_API_KEY", "test-key");
|
||||
const mockFetch = vi.fn(() =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -331,7 +331,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({ config: undefined, sandboxed: true });
|
||||
const result = await tool?.execute?.("call-1", {
|
||||
@@ -345,7 +345,7 @@ describe("web_search external content wrapping", () => {
|
||||
|
||||
it("wraps Perplexity content", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
const mockFetch = vi.fn(() =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -355,7 +355,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
@@ -371,7 +371,7 @@ describe("web_search external content wrapping", () => {
|
||||
it("does not wrap Perplexity citations (raw for tool chaining)", async () => {
|
||||
vi.stubEnv("PERPLEXITY_API_KEY", "pplx-test");
|
||||
const citation = "https://example.com/some-article";
|
||||
const mockFetch = vi.fn((_input?: unknown, _init?: unknown) =>
|
||||
const mockFetch = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
@@ -381,7 +381,7 @@ describe("web_search external content wrapping", () => {
|
||||
}),
|
||||
} as Response),
|
||||
);
|
||||
global.fetch = mockFetch;
|
||||
global.fetch = withFetchPreconnect(mockFetch);
|
||||
|
||||
const tool = createWebSearchTool({
|
||||
config: { tools: { web: { search: { provider: "perplexity" } } } },
|
||||
|
||||
@@ -32,7 +32,7 @@ function createOAuthFetchFn(params: {
|
||||
refreshToken: string;
|
||||
username: string;
|
||||
passthrough?: boolean;
|
||||
}): typeof fetch {
|
||||
}) {
|
||||
return withFetchPreconnect(async (input, init) => {
|
||||
const url = urlToString(input);
|
||||
if (url === CHUTES_TOKEN_ENDPOINT) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import * as authModule from "../agents/model-auth.js";
|
||||
import { withFetchPreconnect } from "../test-utils/fetch-mock.js";
|
||||
import { type FetchMock, withFetchPreconnect } from "../test-utils/fetch-mock.js";
|
||||
import { createVoyageEmbeddingProvider, normalizeVoyageModel } from "./embeddings-voyage.js";
|
||||
|
||||
vi.mock("../agents/model-auth.js", () => ({
|
||||
@@ -14,13 +14,14 @@ vi.mock("../agents/model-auth.js", () => ({
|
||||
}));
|
||||
|
||||
const createFetchMock = () => {
|
||||
const fetchMock = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) => {
|
||||
return new Response(JSON.stringify({ data: [{ embedding: [0.1, 0.2, 0.3] }] }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
});
|
||||
return withFetchPreconnect(fetchMock) as typeof fetch & typeof fetchMock;
|
||||
const fetchMock = vi.fn<FetchMock>(
|
||||
async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
new Response(JSON.stringify({ data: [{ embedding: [0.1, 0.2, 0.3] }] }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
);
|
||||
return withFetchPreconnect(fetchMock);
|
||||
};
|
||||
|
||||
describe("voyage embedding provider", () => {
|
||||
@@ -95,6 +96,7 @@ describe("voyage embedding provider", () => {
|
||||
|
||||
it("passes input_type=document for embedBatch", async () => {
|
||||
const fetchMock = withFetchPreconnect(
|
||||
<<<<<<< HEAD
|
||||
vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) => {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
@@ -106,6 +108,17 @@ describe("voyage embedding provider", () => {
|
||||
},
|
||||
);
|
||||
}),
|
||||
=======
|
||||
vi.fn<FetchMock>(
|
||||
async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
data: [{ embedding: [0.1, 0.2] }, { embedding: [0.3, 0.4] }],
|
||||
}),
|
||||
{ status: 200, headers: { "Content-Type": "application/json" } },
|
||||
),
|
||||
),
|
||||
>>>>>>> 03a725142 (test(fetch): align mocks openclaw#19194 thanks @sebslight)
|
||||
);
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as ssrf from "../../infra/net/ssrf.js";
|
||||
import type { SavedMedia } from "../../media/store.js";
|
||||
import * as mediaStore from "../../media/store.js";
|
||||
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
|
||||
import { type FetchMock, withFetchPreconnect } from "../../test-utils/fetch-mock.js";
|
||||
import {
|
||||
fetchWithSlackAuth,
|
||||
resolveSlackAttachmentContent,
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
|
||||
// Store original fetch
|
||||
const originalFetch = globalThis.fetch;
|
||||
let mockFetch: ReturnType<typeof vi.fn>;
|
||||
let mockFetch: ReturnType<typeof vi.fn<FetchMock>>;
|
||||
const createSavedMedia = (filePath: string, contentType: string): SavedMedia => ({
|
||||
id: "saved-media-id",
|
||||
path: filePath,
|
||||
@@ -23,7 +23,9 @@ const createSavedMedia = (filePath: string, contentType: string): SavedMedia =>
|
||||
describe("fetchWithSlackAuth", () => {
|
||||
beforeEach(() => {
|
||||
// Create a new mock for each test
|
||||
mockFetch = vi.fn();
|
||||
mockFetch = vi.fn<FetchMock>(
|
||||
async (_input: RequestInfo | URL, _init?: RequestInit) => new Response(),
|
||||
);
|
||||
globalThis.fetch = withFetchPreconnect(mockFetch);
|
||||
});
|
||||
|
||||
@@ -366,8 +368,9 @@ describe("resolveSlackMedia", () => {
|
||||
return createSavedMedia("/tmp/unknown", "application/octet-stream");
|
||||
});
|
||||
|
||||
mockFetch.mockImplementation(async (input) => {
|
||||
const url = String(input);
|
||||
mockFetch.mockImplementation(async (input: RequestInfo | URL) => {
|
||||
const url =
|
||||
typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
||||
if (url.includes("/a.jpg")) {
|
||||
return new Response(Buffer.from("image a"), {
|
||||
status: 200,
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
export type FetchMock = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
||||
|
||||
type FetchPreconnectOptions = {
|
||||
dns?: boolean;
|
||||
tcp?: boolean;
|
||||
http?: boolean;
|
||||
https?: boolean;
|
||||
};
|
||||
|
||||
type FetchWithPreconnect = {
|
||||
preconnect: (url: string, init?: { credentials?: RequestCredentials }) => void;
|
||||
preconnect: (url: string | URL, options?: FetchPreconnectOptions) => void;
|
||||
};
|
||||
|
||||
export function withFetchPreconnect<T extends typeof fetch>(fn: T): T & FetchWithPreconnect;
|
||||
@@ -8,6 +17,6 @@ export function withFetchPreconnect<T extends object>(
|
||||
): T & FetchWithPreconnect & typeof fetch;
|
||||
export function withFetchPreconnect(fn: object) {
|
||||
return Object.assign(fn, {
|
||||
preconnect: (_url: string, _init?: { credentials?: RequestCredentials }) => {},
|
||||
preconnect: (_url: string | URL, _options?: FetchPreconnectOptions) => {},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user