




















@@ -11,6 +11,7 @@ const {
1111 fetchWithTimeoutMock,
1212 fetchWithTimeoutGuardedMock,
1313 pollProviderOperationJsonMock,
14+ assertOkOrThrowHttpErrorMock,
1415 resolveProviderHttpRequestConfigMock,
1516 sanitizeConfiguredModelProviderRequestMock,
1617} = getProviderHttpMocks();
@@ -303,6 +304,60 @@ describe("openai video generation provider", () => {
303304});
304305});
305306307+it("releases guarded local video download requests when HTTP errors throw", async () => {
308+const release = vi.fn(async () => {});
309+assertOkOrThrowHttpErrorMock
310+.mockImplementationOnce(async () => {})
311+.mockImplementationOnce(async () => {})
312+.mockImplementationOnce(async (_response, label) => {
313+throw new Error(label);
314+});
315+postJsonRequestMock.mockResolvedValue({
316+response: {
317+json: async () => ({
318+id: "vid_local",
319+model: "sora-2",
320+status: "queued",
321+}),
322+},
323+release: vi.fn(async () => {}),
324+});
325+fetchWithTimeoutMock.mockResolvedValueOnce({
326+json: async () => ({
327+id: "vid_local",
328+model: "sora-2",
329+status: "completed",
330+}),
331+});
332+fetchWithTimeoutGuardedMock.mockResolvedValueOnce({
333+response: new Response("busy", { status: 503, statusText: "Service Unavailable" }),
334+finalUrl: "http://127.0.0.1:44080/v1/videos/vid_local/content?variant=video",
335+ release,
336+});
337+338+const provider = buildOpenAIVideoGenerationProvider();
339+await expect(
340+provider.generateVideo({
341+provider: "openai",
342+model: "sora-2",
343+prompt: "Render via local relay",
344+cfg: {
345+models: {
346+providers: {
347+openai: {
348+baseUrl: "http://127.0.0.1:44080/v1",
349+request: { allowPrivateNetwork: true },
350+models: [],
351+},
352+},
353+},
354+},
355+}),
356+).rejects.toThrow("OpenAI video download failed");
357+358+expect(release).toHaveBeenCalledTimes(1);
359+});
360+306361it("uses multipart input_reference for video-to-video uploads", async () => {
307362fetchWithTimeoutMock
308363.mockResolvedValueOnce({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。