





















@@ -43,8 +43,8 @@ async function withLiveChutesDiscovery<T>(
4343}
44444545function createAuthEchoFetchMock() {
46-return vi.fn().mockImplementation((_url, init?: { headers?: Record<string, string> }) => {
47-const auth = init?.headers?.Authorization ?? "";
46+return vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
47+const auth = readAuthorizationHeader(init);
4848return Promise.resolve({
4949ok: true,
5050json: async () => ({
@@ -54,6 +54,17 @@ function createAuthEchoFetchMock() {
5454});
5555}
565657+function readAuthorizationHeader(init?: { headers?: HeadersInit }): string {
58+const headers = init?.headers;
59+if (headers instanceof Headers) {
60+return headers.get("Authorization") ?? "";
61+}
62+if (Array.isArray(headers)) {
63+return headers.find(([key]) => key.toLowerCase() === "authorization")?.[1] ?? "";
64+}
65+return headers?.Authorization ?? headers?.authorization ?? "";
66+}
67+5768function requireChutesModel(
5869models: Awaited<ReturnType<typeof discoverChutesModels>>,
5970index: number,
@@ -182,8 +193,8 @@ describe("chutes-models", () => {
182193});
183194184195it("discoverChutesModels retries without auth on 401", async () => {
185-const mockFetch = vi.fn().mockImplementation((url, init) => {
186-if (init?.headers?.Authorization === "Bearer test-token-error") {
196+const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
197+if (readAuthorizationHeader(init) === "Bearer test-token-error") {
187198return Promise.resolve({
188199ok: false,
189200status: 401,
@@ -230,7 +241,7 @@ describe("chutes-models", () => {
230241});
231242});
232243233-it("caches fallback static catalog for non-OK responses", async () => {
244+it("does not cache fallback static catalog for non-OK responses", async () => {
234245const mockFetch = vi.fn().mockResolvedValue({
235246ok: false,
236247status: 503,
@@ -241,38 +252,36 @@ describe("chutes-models", () => {
241252const second = await discoverChutesModels("chutes-fallback-token");
242253expect(first.map((m) => m.id)).toEqual(CHUTES_MODEL_CATALOG.map((m) => m.id));
243254expect(second.map((m) => m.id)).toEqual(CHUTES_MODEL_CATALOG.map((m) => m.id));
244-expect(mockFetch).toHaveBeenCalledTimes(1);
255+expect(mockFetch).toHaveBeenCalledTimes(2);
245256});
246257});
247258248259it("scopes discovery cache by access token", async () => {
249-const mockFetch = vi
250-.fn()
251-.mockImplementation((_url, init?: { headers?: Record<string, string> }) => {
252-const auth = init?.headers?.Authorization;
253-if (auth === "Bearer chutes-token-a") {
254-return Promise.resolve({
255-ok: true,
256-json: async () => ({
257-data: [{ id: "private/model-a" }],
258-}),
259-});
260-}
261-if (auth === "Bearer chutes-token-b") {
262-return Promise.resolve({
263-ok: true,
264-json: async () => ({
265-data: [{ id: "private/model-b" }],
266-}),
267-});
268-}
260+const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
261+const auth = readAuthorizationHeader(init);
262+if (auth === "Bearer chutes-token-a") {
263+return Promise.resolve({
264+ok: true,
265+json: async () => ({
266+data: [{ id: "private/model-a" }],
267+}),
268+});
269+}
270+if (auth === "Bearer chutes-token-b") {
269271return Promise.resolve({
270272ok: true,
271273json: async () => ({
272-data: [{ id: "public/model" }],
274+data: [{ id: "private/model-b" }],
273275}),
274276});
277+}
278+return Promise.resolve({
279+ok: true,
280+json: async () => ({
281+data: [{ id: "public/model" }],
282+}),
275283});
284+});
276285await withLiveChutesDiscovery(mockFetch, async () => {
277286const modelsA = await discoverChutesModels("chutes-token-a");
278287const modelsB = await discoverChutesModels("chutes-token-b");
@@ -314,26 +323,24 @@ describe("chutes-models", () => {
314323});
315324316325it("does not cache 401 fallback under the failed token key", async () => {
317-const mockFetch = vi
318-.fn()
319-.mockImplementation((_url, init?: { headers?: Record<string, string> }) => {
320-if (init?.headers?.Authorization === "Bearer failed-token") {
321-return Promise.resolve({
322-ok: false,
323-status: 401,
324-});
325-}
326+const mockFetch = vi.fn().mockImplementation((_url, init?: { headers?: HeadersInit }) => {
327+if (readAuthorizationHeader(init) === "Bearer failed-token") {
326328return Promise.resolve({
327-ok: true,
328-json: async () => ({
329-data: [{ id: "public/model" }],
330-}),
329+ok: false,
330+status: 401,
331331});
332+}
333+return Promise.resolve({
334+ok: true,
335+json: async () => ({
336+data: [{ id: "public/model" }],
337+}),
332338});
339+});
333340await withLiveChutesDiscovery(mockFetch, async () => {
334341await discoverChutesModels("failed-token");
335342await discoverChutesModels("failed-token");
336-expect(mockFetch).toHaveBeenCalledTimes(4);
343+expect(mockFetch).toHaveBeenCalledTimes(3);
337344});
338345});
339346});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。