test: add fetch mock helper and reaction coverage

This commit is contained in:
Sebastian
2026-02-17 09:01:30 -05:00
parent 0e023e300e
commit cc359d338e
28 changed files with 193 additions and 106 deletions

View File

@@ -1,4 +1,5 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { withFetchPreconnect } from "../test-utils/fetch-mock.js";
import { MediaAttachmentCache } from "./attachments.js";
import { normalizeMediaUnderstandingChatType, resolveMediaUnderstandingScope } from "./scope.js";
@@ -28,7 +29,7 @@ describe("media understanding attachments SSRF", () => {
it("blocks private IP URLs before fetching", async () => {
const fetchSpy = vi.fn();
globalThis.fetch = fetchSpy as typeof fetch;
globalThis.fetch = withFetchPreconnect(fetchSpy);
const cache = new MediaAttachmentCache([{ index: 0, url: "http://127.0.0.1/secret.jpg" }]);

View File

@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest";
import { withFetchPreconnect } from "../../../test-utils/fetch-mock.js";
import { installPinnedHostnameTestHooks, resolveRequestUrl } from "../audio.test-helpers.js";
import { transcribeDeepgramAudio } from "./audio.js";
@@ -7,7 +8,7 @@ installPinnedHostnameTestHooks();
describe("transcribeDeepgramAudio", () => {
it("respects lowercase authorization header overrides", async () => {
let seenAuth: string | null = null;
const fetchFn = async (_input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (_input: RequestInfo | URL, init?: RequestInit) => {
const headers = new Headers(init?.headers);
seenAuth = headers.get("authorization");
return new Response(
@@ -19,7 +20,7 @@ describe("transcribeDeepgramAudio", () => {
headers: { "content-type": "application/json" },
},
);
};
});
const result = await transcribeDeepgramAudio({
buffer: Buffer.from("audio"),
@@ -37,7 +38,7 @@ describe("transcribeDeepgramAudio", () => {
it("builds the expected request payload", async () => {
let seenUrl: string | null = null;
let seenInit: RequestInit | undefined;
const fetchFn = async (input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (input: RequestInfo | URL, init?: RequestInit) => {
seenUrl = resolveRequestUrl(input);
seenInit = init;
return new Response(
@@ -49,7 +50,7 @@ describe("transcribeDeepgramAudio", () => {
headers: { "content-type": "application/json" },
},
);
};
});
const result = await transcribeDeepgramAudio({
buffer: Buffer.from("audio-bytes"),

View File

@@ -1,5 +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 { describeGeminiVideo } from "./video.js";
const TEST_NET_IP = "203.0.113.10";
@@ -47,7 +48,7 @@ describe("describeGeminiVideo", () => {
it("respects case-insensitive x-goog-api-key overrides", async () => {
let seenKey: string | null = null;
const fetchFn = async (_input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (_input: RequestInfo | URL, init?: RequestInit) => {
const headers = new Headers(init?.headers);
seenKey = headers.get("x-goog-api-key");
return new Response(
@@ -56,7 +57,7 @@ describe("describeGeminiVideo", () => {
}),
{ status: 200, headers: { "content-type": "application/json" } },
);
};
});
const result = await describeGeminiVideo({
buffer: Buffer.from("video"),
@@ -74,7 +75,7 @@ describe("describeGeminiVideo", () => {
it("builds the expected request payload", async () => {
let seenUrl: string | null = null;
let seenInit: RequestInit | undefined;
const fetchFn = async (input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (input: RequestInfo | URL, init?: RequestInit) => {
seenUrl = resolveRequestUrl(input);
seenInit = init;
return new Response(
@@ -89,7 +90,7 @@ describe("describeGeminiVideo", () => {
}),
{ status: 200, headers: { "content-type": "application/json" } },
);
};
});
const result = await describeGeminiVideo({
buffer: Buffer.from("video-bytes"),

View File

@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest";
import { withFetchPreconnect } from "../../../test-utils/fetch-mock.js";
import { installPinnedHostnameTestHooks, resolveRequestUrl } from "../audio.test-helpers.js";
import { transcribeOpenAiCompatibleAudio } from "./audio.js";
@@ -7,14 +8,14 @@ installPinnedHostnameTestHooks();
describe("transcribeOpenAiCompatibleAudio", () => {
it("respects lowercase authorization header overrides", async () => {
let seenAuth: string | null = null;
const fetchFn = async (_input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (_input: RequestInfo | URL, init?: RequestInit) => {
const headers = new Headers(init?.headers);
seenAuth = headers.get("authorization");
return new Response(JSON.stringify({ text: "ok" }), {
status: 200,
headers: { "content-type": "application/json" },
});
};
});
const result = await transcribeOpenAiCompatibleAudio({
buffer: Buffer.from("audio"),
@@ -32,14 +33,14 @@ describe("transcribeOpenAiCompatibleAudio", () => {
it("builds the expected request payload", async () => {
let seenUrl: string | null = null;
let seenInit: RequestInit | undefined;
const fetchFn = async (input: RequestInfo | URL, init?: RequestInit) => {
const fetchFn = withFetchPreconnect(async (input: RequestInfo | URL, init?: RequestInit) => {
seenUrl = resolveRequestUrl(input);
seenInit = init;
return new Response(JSON.stringify({ text: "hello" }), {
status: 200,
headers: { "content-type": "application/json" },
});
};
});
const result = await transcribeOpenAiCompatibleAudio({
buffer: Buffer.from("audio-bytes"),