



























@@ -15,6 +15,14 @@ function restoreEnvVar(name: string, value: string | undefined): void {
1515}
1616}
171718+function jsonResponse(payload: unknown, init: ResponseInit = {}): Response {
19+return new Response(JSON.stringify(payload), {
20+status: 200,
21+headers: { "Content-Type": "application/json" },
22+ ...init,
23+});
24+}
25+1826async function withLiveChutesDiscovery<T>(
1927fetchMock: ReturnType<typeof vi.fn>,
2028run: () => Promise<T>,
@@ -45,12 +53,11 @@ async function withLiveChutesDiscovery<T>(
4553function createAuthEchoFetchMock() {
4654return vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
4755const auth = readAuthorizationHeader(init);
48-return Promise.resolve({
49-ok: true,
50-json: async () => ({
56+return Promise.resolve(
57+jsonResponse({
5158data: [{ id: auth ? `${auth}-model` : "public-model" }],
5259}),
53-});
60+);
5461});
5562}
5663@@ -124,9 +131,8 @@ describe("chutes-models", () => {
124131});
125132126133it("discoverChutesModels correctly maps API response when not in test env", async () => {
127-const mockFetch = vi.fn().mockResolvedValue({
128-ok: true,
129-json: async () => ({
134+const mockFetch = vi.fn().mockResolvedValue(
135+jsonResponse({
130136data: [
131137{ id: "zai-org/GLM-4.7-TEE" },
132138{
@@ -140,7 +146,7 @@ describe("chutes-models", () => {
140146{ id: "new-provider/simple-model" },
141147],
142148}),
143-});
149+);
144150await withLiveChutesDiscovery(mockFetch, async () => {
145151const models = await discoverChutesModels("test-token-real-fetch");
146152expect(models.length).toBeGreaterThan(0);
@@ -158,9 +164,8 @@ describe("chutes-models", () => {
158164});
159165160166it("falls back from malformed live token metadata", async () => {
161-const mockFetch = vi.fn().mockResolvedValue({
162-ok: true,
163-json: async () => ({
167+const mockFetch = vi.fn().mockResolvedValue(
168+jsonResponse({
164169data: [
165170{
166171id: "provider/bad-window",
@@ -174,7 +179,7 @@ describe("chutes-models", () => {
174179},
175180],
176181}),
177-});
182+);
178183179184await withLiveChutesDiscovery(mockFetch, async () => {
180185const models = await discoverChutesModels("malformed-token-metadata");
@@ -195,14 +200,10 @@ describe("chutes-models", () => {
195200it("discoverChutesModels retries without auth on 401", async () => {
196201const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
197202if (readAuthorizationHeader(init) === "Bearer test-token-error") {
198-return Promise.resolve({
199-ok: false,
200-status: 401,
201-});
203+return Promise.resolve(new Response("", { status: 401 }));
202204}
203-return Promise.resolve({
204-ok: true,
205-json: async () => ({
205+return Promise.resolve(
206+jsonResponse({
206207data: [
207208{
208209id: "Qwen/Qwen3-32B",
@@ -232,7 +233,7 @@ describe("chutes-models", () => {
232233},
233234],
234235}),
235-});
236+);
236237});
237238await withLiveChutesDiscovery(mockFetch, async () => {
238239const models = await discoverChutesModels("test-token-error");
@@ -242,10 +243,7 @@ describe("chutes-models", () => {
242243});
243244244245it("does not cache fallback static catalog for non-OK responses", async () => {
245-const mockFetch = vi.fn().mockResolvedValue({
246-ok: false,
247-status: 503,
248-});
246+const mockFetch = vi.fn().mockResolvedValue(new Response("", { status: 503 }));
249247250248await withLiveChutesDiscovery(mockFetch, async () => {
251249const first = await discoverChutesModels("chutes-fallback-token");
@@ -260,27 +258,24 @@ describe("chutes-models", () => {
260258const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
261259const auth = readAuthorizationHeader(init);
262260if (auth === "Bearer chutes-token-a") {
263-return Promise.resolve({
264-ok: true,
265-json: async () => ({
261+return Promise.resolve(
262+jsonResponse({
266263data: [{ id: "private/model-a" }],
267264}),
268-});
265+);
269266}
270267if (auth === "Bearer chutes-token-b") {
271-return Promise.resolve({
272-ok: true,
273-json: async () => ({
268+return Promise.resolve(
269+jsonResponse({
274270data: [{ id: "private/model-b" }],
275271}),
276-});
272+);
277273}
278-return Promise.resolve({
279-ok: true,
280-json: async () => ({
274+return Promise.resolve(
275+jsonResponse({
281276data: [{ id: "public/model" }],
282277}),
283-});
278+);
284279});
285280await withLiveChutesDiscovery(mockFetch, async () => {
286281const modelsA = await discoverChutesModels("chutes-token-a");
@@ -325,17 +320,13 @@ describe("chutes-models", () => {
325320it("does not cache 401 fallback under the failed token key", async () => {
326321const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
327322if (readAuthorizationHeader(init) === "Bearer failed-token") {
328-return Promise.resolve({
329-ok: false,
330-status: 401,
331-});
323+return Promise.resolve(new Response("", { status: 401 }));
332324}
333-return Promise.resolve({
334-ok: true,
335-json: async () => ({
325+return Promise.resolve(
326+jsonResponse({
336327data: [{ id: "public/model" }],
337328}),
338-});
329+);
339330});
340331await withLiveChutesDiscovery(mockFetch, async () => {
341332await discoverChutesModels("failed-token");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。