



















@@ -61,6 +61,41 @@ function releasedVideo(params: { contentType: string; bytes: string }) {
6161};
6262}
636364+type OpenRouterVideoProvider = ReturnType<typeof buildOpenRouterVideoGenerationProvider>;
65+type OpenRouterVideoResult = Awaited<ReturnType<OpenRouterVideoProvider["generateVideo"]>>;
66+67+function requireGenerateCapabilities(provider: OpenRouterVideoProvider) {
68+const capabilities = provider.capabilities.generate;
69+expect(capabilities).toBeDefined();
70+if (!capabilities) {
71+throw new Error("expected OpenRouter generate capabilities");
72+}
73+return capabilities;
74+}
75+76+function requireFetchCallHeaders(index: number): Headers {
77+const call = fetchWithTimeoutGuardedMock.mock.calls[index];
78+expect(call).toBeDefined();
79+if (!call) {
80+throw new Error(`expected OpenRouter fetch call ${index + 1}`);
81+}
82+const init = call[1] as { headers?: HeadersInit } | undefined;
83+expect(init).toBeDefined();
84+if (!init) {
85+throw new Error(`expected OpenRouter fetch call ${index + 1} init`);
86+}
87+return new Headers(init.headers);
88+}
89+90+function requireGeneratedVideo(result: OpenRouterVideoResult, index: number) {
91+const video = result.videos[index];
92+expect(video).toBeDefined();
93+if (!video) {
94+throw new Error(`expected OpenRouter generated video at index ${index}`);
95+}
96+return video;
97+}
98+6499describe("openrouter video generation provider", () => {
65100afterEach(() => {
66101assertOkOrThrowHttpErrorMock.mockClear();
@@ -77,12 +112,13 @@ describe("openrouter video generation provider", () => {
77112expectExplicitVideoGenerationCapabilities(provider);
78113expect(provider.id).toBe("openrouter");
79114expect(provider.defaultModel).toBe("google/veo-3.1-fast");
80-expect(provider.capabilities.generate?.supportsAudio).toBe(true);
81-expect(provider.capabilities.generate?.supportedDurationSeconds).toEqual([4, 6, 8]);
82-expect(provider.capabilities.generate?.resolutions).toEqual(["720P", "1080P"]);
83-expect(provider.capabilities.generate?.aspectRatios).toEqual(["16:9", "9:16"]);
84-expect(provider.capabilities.imageToVideo?.enabled).toBe(true);
85-expect(provider.capabilities.videoToVideo?.enabled).toBe(false);
115+const generateCapabilities = requireGenerateCapabilities(provider);
116+expect(generateCapabilities.supportsAudio).toBe(true);
117+expect(generateCapabilities.supportedDurationSeconds).toEqual([4, 6, 8]);
118+expect(generateCapabilities.resolutions).toEqual(["720P", "1080P"]);
119+expect(generateCapabilities.aspectRatios).toEqual(["16:9", "9:16"]);
120+expect(provider.capabilities.imageToVideo).toMatchObject({ enabled: true });
121+expect(provider.capabilities.videoToVideo).toMatchObject({ enabled: false });
86122});
8712388124it("submits OpenRouter video jobs, polls completion, and downloads the result", async () => {
@@ -204,11 +240,7 @@ describe("openrouter video generation provider", () => {
204240expect.any(Function),
205241expect.objectContaining({ auditContext: "openrouter-video-status" }),
206242);
207-expect(
208-(fetchWithTimeoutGuardedMock.mock.calls[0]?.[1]?.headers as Headers | undefined)?.get(
209-"authorization",
210-),
211-).toBe("Bearer openrouter-key");
243+expect(requireFetchCallHeaders(0).get("authorization")).toBe("Bearer openrouter-key");
212244expect(fetchWithTimeoutGuardedMock).toHaveBeenNthCalledWith(
2132452,
214246"https://custom.openrouter.test/api/v1/videos/job-123/content?index=0",
@@ -217,13 +249,10 @@ describe("openrouter video generation provider", () => {
217249expect.any(Function),
218250expect.objectContaining({ auditContext: "openrouter-video-download" }),
219251);
220-expect(
221-(fetchWithTimeoutGuardedMock.mock.calls[1]?.[1]?.headers as Headers | undefined)?.get(
222-"authorization",
223-),
224-).toBe("Bearer openrouter-key");
225-expect(result.videos[0]?.buffer?.toString()).toBe("mp4-bytes");
226-expect(result.videos[0]?.mimeType).toBe("video/mp4");
252+expect(requireFetchCallHeaders(1).get("authorization")).toBe("Bearer openrouter-key");
253+const video = requireGeneratedVideo(result, 0);
254+expect(video.buffer.toString()).toBe("mp4-bytes");
255+expect(video.mimeType).toBe("video/mp4");
227256expect(result.metadata).toEqual({
228257jobId: "job-123",
229258status: "completed",
@@ -266,11 +295,7 @@ describe("openrouter video generation provider", () => {
266295expect.any(Function),
267296expect.objectContaining({ auditContext: "openrouter-video-status" }),
268297);
269-expect(
270-(fetchWithTimeoutGuardedMock.mock.calls[0]?.[1]?.headers as Headers | undefined)?.get(
271-"authorization",
272-),
273-).toBeNull();
298+expect(requireFetchCallHeaders(0).get("authorization")).toBeNull();
274299expect(fetchWithTimeoutGuardedMock).toHaveBeenNthCalledWith(
2753002,
276301"https://cdn.openrouter.test/video.mp4",
@@ -279,11 +304,7 @@ describe("openrouter video generation provider", () => {
279304expect.any(Function),
280305expect.objectContaining({ auditContext: "openrouter-video-download" }),
281306);
282-expect(
283-(fetchWithTimeoutGuardedMock.mock.calls[1]?.[1]?.headers as Headers | undefined)?.get(
284-"authorization",
285-),
286-).toBeNull();
307+expect(requireFetchCallHeaders(1).get("authorization")).toBeNull();
287308});
288309289310it("falls back to the documented content endpoint when a completed job has no output URL", async () => {
@@ -313,8 +334,9 @@ describe("openrouter video generation provider", () => {
313334expect.any(Function),
314335expect.objectContaining({ auditContext: "openrouter-video-download" }),
315336);
316-expect(result.videos[0]?.buffer?.toString()).toBe("webm-bytes");
317-expect(result.videos[0]?.fileName).toBe("video-1.webm");
337+const video = requireGeneratedVideo(result, 0);
338+expect(video.buffer.toString()).toBe("webm-bytes");
339+expect(video.fileName).toBe("video-1.webm");
318340});
319341320342it("rejects video reference inputs", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。