mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 21:24:46 +00:00
test: guard google provider mock calls
This commit is contained in:
@@ -37,6 +37,14 @@ function fetchJsonBody(fetchMock: ReturnType<typeof vi.fn>, index: number): unkn
|
||||
return JSON.parse(body) as unknown;
|
||||
}
|
||||
|
||||
function requireFirstFetchInput(fetchMock: ReturnType<typeof vi.fn>): RequestInfo | URL {
|
||||
const [call] = fetchMock.mock.calls;
|
||||
if (!call) {
|
||||
throw new Error("expected Gemini embedding fetch call");
|
||||
}
|
||||
return call[0] as RequestInfo | URL;
|
||||
}
|
||||
|
||||
describe("Gemini embedding request helpers", () => {
|
||||
it("builds requests and resolves model settings", () => {
|
||||
expect(
|
||||
@@ -153,7 +161,7 @@ describe("Gemini embedding provider", () => {
|
||||
[0, 0, 1],
|
||||
]);
|
||||
|
||||
expect(fetchMock.mock.calls[0]?.[0]).toBe(
|
||||
expect(requireFirstFetchInput(fetchMock)).toBe(
|
||||
"https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent",
|
||||
);
|
||||
expect(fetchJsonBody(fetchMock, 0)).toEqual({
|
||||
|
||||
@@ -398,13 +398,19 @@ describe("google transport stream", () => {
|
||||
|
||||
expect(result.content).toEqual([{ type: "text", text: "recovered" }]);
|
||||
expect(guardedFetchMock).toHaveBeenCalledTimes(2);
|
||||
const firstBody = JSON.parse(guardedFetchMock.mock.calls[0]?.[1]?.body as string);
|
||||
const retryBody = JSON.parse(guardedFetchMock.mock.calls[1]?.[1]?.body as string);
|
||||
expect(firstBody.generationConfig.thinkingConfig).toEqual({
|
||||
const firstBody = parseRequestJsonBody(
|
||||
requireRequestInit(requireMockCall(guardedFetchMock, 0, "guarded fetch"), "guarded fetch"),
|
||||
);
|
||||
const retryBody = parseRequestJsonBody(
|
||||
requireRequestInit(requireMockCall(guardedFetchMock, 1, "guarded fetch"), "guarded fetch"),
|
||||
);
|
||||
const firstGenerationConfig = requireGenerationConfig(firstBody);
|
||||
const retryGenerationConfig = requireGenerationConfig(retryBody);
|
||||
expect(firstGenerationConfig.thinkingConfig).toEqual({
|
||||
includeThoughts: true,
|
||||
thinkingLevel: "HIGH",
|
||||
});
|
||||
expect(retryBody.generationConfig.thinkingConfig).toEqual({
|
||||
expect(retryGenerationConfig.thinkingConfig).toEqual({
|
||||
thinkingLevel: "LOW",
|
||||
});
|
||||
expect(retryBody.tools).toEqual(firstBody.tools);
|
||||
|
||||
@@ -37,7 +37,11 @@ type MockWithCalls = {
|
||||
};
|
||||
|
||||
function firstObjectArg(mock: MockWithCalls): Record<string, unknown> {
|
||||
const value = mock.mock.calls[0]?.[0];
|
||||
const [call] = mock.mock.calls;
|
||||
if (!call) {
|
||||
throw new Error("expected first mock call to receive an object argument");
|
||||
}
|
||||
const value = call[0];
|
||||
if (value === undefined || value === null || typeof value !== "object" || Array.isArray(value)) {
|
||||
throw new Error("expected first mock call to receive an object argument");
|
||||
}
|
||||
@@ -55,6 +59,37 @@ function firstGoogleClientHttpOptions(): Record<string, unknown> {
|
||||
return recordField(firstObjectArg(createGoogleGenAIMock).httpOptions, "httpOptions");
|
||||
}
|
||||
|
||||
function requireFetchCall(
|
||||
fetchMock: ReturnType<typeof vi.fn>,
|
||||
index: number,
|
||||
): [RequestInfo | URL, RequestInit | undefined] {
|
||||
const call = fetchMock.mock.calls[index];
|
||||
if (!call) {
|
||||
throw new Error(`expected Google video fetch call ${index}`);
|
||||
}
|
||||
return call as [RequestInfo | URL, RequestInit | undefined];
|
||||
}
|
||||
|
||||
function parseFetchJsonBody(fetchMock: ReturnType<typeof vi.fn>, index: number): unknown {
|
||||
const [, init] = requireFetchCall(fetchMock, index);
|
||||
const body = init?.body;
|
||||
if (typeof body !== "string") {
|
||||
throw new Error(`expected Google video fetch body ${index}`);
|
||||
}
|
||||
return JSON.parse(body) as unknown;
|
||||
}
|
||||
|
||||
function fetchInputUrl(fetchMock: ReturnType<typeof vi.fn>, index: number): string {
|
||||
const [input] = requireFetchCall(fetchMock, index);
|
||||
if (typeof input === "string") {
|
||||
return input;
|
||||
}
|
||||
if (input instanceof URL) {
|
||||
return input.toString();
|
||||
}
|
||||
return input.url;
|
||||
}
|
||||
|
||||
let ssrfMock: { mockRestore: () => void } | undefined;
|
||||
|
||||
describe("google video generation provider", () => {
|
||||
@@ -308,14 +343,14 @@ describe("google video generation provider", () => {
|
||||
});
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(2);
|
||||
expect(String(fetchMock.mock.calls[0]?.[0])).toBe(
|
||||
expect(fetchInputUrl(fetchMock, 0)).toBe(
|
||||
"https://generativelanguage.googleapis.com/v1beta/models/veo-3.1-fast-generate-preview:predictLongRunning",
|
||||
);
|
||||
expect(JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body))).toEqual({
|
||||
expect(parseFetchJsonBody(fetchMock, 0)).toEqual({
|
||||
instances: [{ prompt: "A tiny robot watering a windowsill garden" }],
|
||||
parameters: { durationSeconds: 4 },
|
||||
});
|
||||
expect(String(fetchMock.mock.calls[1]?.[0])).toBe(
|
||||
expect(fetchInputUrl(fetchMock, 1)).toBe(
|
||||
"https://generativelanguage.googleapis.com/v1beta/files/rest-video:download?alt=media&key=google-key",
|
||||
);
|
||||
expect(downloadMock).not.toHaveBeenCalled();
|
||||
|
||||
@@ -38,13 +38,23 @@ function createGoogleModelProviderConfig(
|
||||
};
|
||||
}
|
||||
|
||||
function requireFirstGeminiFetchCall(
|
||||
mockFetch: ReturnType<typeof installGeminiFetch>,
|
||||
): [RequestInfo | URL | undefined, RequestInit | undefined] {
|
||||
const [call] = mockFetch.mock.calls;
|
||||
if (!call) {
|
||||
throw new Error("expected Gemini web search fetch call");
|
||||
}
|
||||
return call as [RequestInfo | URL | undefined, RequestInit | undefined];
|
||||
}
|
||||
|
||||
function getFetchHeaders(mockFetch: ReturnType<typeof installGeminiFetch>): Record<string, string> {
|
||||
const init = mockFetch.mock.calls[0]?.[1] as { headers?: Record<string, string> } | undefined;
|
||||
return init?.headers ?? {};
|
||||
const [, init] = requireFirstGeminiFetchCall(mockFetch);
|
||||
return (init?.headers as Record<string, string> | undefined) ?? {};
|
||||
}
|
||||
|
||||
function getGeminiFetchUrl(mockFetch: ReturnType<typeof installGeminiFetch>): string | undefined {
|
||||
const input = mockFetch.mock.calls[0]?.[0];
|
||||
const [input] = requireFirstGeminiFetchCall(mockFetch);
|
||||
if (typeof input === "string") {
|
||||
return input;
|
||||
}
|
||||
@@ -57,7 +67,8 @@ function getGeminiFetchUrl(mockFetch: ReturnType<typeof installGeminiFetch>): st
|
||||
function parseGeminiFetchBody(mockFetch: ReturnType<typeof installGeminiFetch>): {
|
||||
tools?: Array<{ google_search?: { timeRangeFilter?: unknown } }>;
|
||||
} {
|
||||
const body = mockFetch.mock.calls[0]?.[1]?.body;
|
||||
const [, init] = requireFirstGeminiFetchCall(mockFetch);
|
||||
const body = init?.body;
|
||||
if (typeof body !== "string") {
|
||||
throw new Error("Expected Gemini fetch body string");
|
||||
}
|
||||
@@ -179,7 +190,7 @@ describe("google web search provider", () => {
|
||||
|
||||
await tool?.execute({ query: "OpenClaw docs" }, { signal: controller.signal });
|
||||
|
||||
const init = mockFetch.mock.calls[0]?.[1] as { signal?: AbortSignal } | undefined;
|
||||
const [, init] = requireFirstGeminiFetchCall(mockFetch);
|
||||
expect(init?.signal?.aborted).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user