





















@@ -15,6 +15,40 @@ beforeAll(async () => {
15151616installProviderHttpMockCleanup();
171718+function requirePostJsonCall(index = 0): {
19+url?: string;
20+body?: Record<string, unknown>;
21+} {
22+const params = (postJsonRequestMock.mock.calls as unknown as Array<[unknown]>)[index]?.[0] as
23+| {
24+url?: string;
25+body?: Record<string, unknown>;
26+}
27+| undefined;
28+if (!params) {
29+throw new Error(`Expected postJsonRequest call ${index}`);
30+}
31+return params;
32+}
33+34+function requireFetchInitCall(index: number): {
35+url?: string;
36+init?: { method?: string };
37+timeoutMs?: number;
38+} {
39+const call = (
40+fetchWithTimeoutMock.mock.calls as unknown as Array<[string, { method?: string }, number]>
41+)[index];
42+if (!call) {
43+throw new Error(`Expected fetchWithTimeout call ${index}`);
44+}
45+return {
46+url: call[0],
47+init: call[1],
48+timeoutMs: call[2],
49+};
50+}
51+1852describe("xai video generation provider", () => {
1953it("declares explicit mode capabilities", () => {
2054expectExplicitVideoGenerationCapabilities(buildXaiVideoGenerationProvider());
@@ -53,33 +87,21 @@ describe("xai video generation provider", () => {
5387resolution: "720P",
5488});
558956-expect(postJsonRequestMock).toHaveBeenCalledWith(
57-expect.objectContaining({
58-url: "https://api.x.ai/v1/videos/generations",
59-body: expect.objectContaining({
60-model: "grok-imagine-video",
61-prompt: "A tiny robot crab crossing a moonlit tide pool",
62-duration: 6,
63-aspect_ratio: "16:9",
64-resolution: "720p",
65-}),
66-}),
67-);
68-expect(fetchWithTimeoutMock).toHaveBeenNthCalledWith(
69-1,
70-"https://api.x.ai/v1/videos/req_123",
71-expect.objectContaining({ method: "GET" }),
72-120000,
73-fetch,
74-);
90+const createRequest = requirePostJsonCall();
91+expect(createRequest.url).toBe("https://api.x.ai/v1/videos/generations");
92+expect(createRequest.body?.model).toBe("grok-imagine-video");
93+expect(createRequest.body?.prompt).toBe("A tiny robot crab crossing a moonlit tide pool");
94+expect(createRequest.body?.duration).toBe(6);
95+expect(createRequest.body?.aspect_ratio).toBe("16:9");
96+expect(createRequest.body?.resolution).toBe("720p");
97+const pollRequest = requireFetchInitCall(0);
98+expect(pollRequest.url).toBe("https://api.x.ai/v1/videos/req_123");
99+expect(pollRequest.init?.method).toBe("GET");
100+expect(pollRequest.timeoutMs).toBe(120000);
75101expect(result.videos[0]?.mimeType).toBe("video/webm");
76102expect(result.videos[0]?.fileName).toBe("video-1.webm");
77-expect(result.metadata).toEqual(
78-expect.objectContaining({
79-requestId: "req_123",
80-mode: "generate",
81-}),
82-);
103+expect(result.metadata?.requestId).toBe("req_123");
104+expect(result.metadata?.mode).toBe("generate");
83105});
8410685107it("sends a single unroled image as xAI first-frame image-to-video", async () => {
@@ -113,23 +135,13 @@ describe("xai video generation provider", () => {
113135inputImages: [{ buffer: Buffer.from("png-bytes"), mimeType: "image/png" }],
114136});
115137116-const body = postJsonRequestMock.mock.calls[0]?.[0]?.body as Record<string, unknown>;
117-expect(postJsonRequestMock).toHaveBeenCalledWith(
118-expect.objectContaining({
119-url: "https://api.x.ai/v1/videos/generations",
120-body: expect.objectContaining({
121-image: {
122-url: expect.stringMatching(/^data:image\/png;base64,/),
123-},
124-}),
125-}),
126-);
138+const request = requirePostJsonCall();
139+expect(request.url).toBe("https://api.x.ai/v1/videos/generations");
140+const image = request.body?.image as { url?: string } | undefined;
141+expect(image?.url).toMatch(/^data:image\/png;base64,/u);
142+const body = request.body ?? {};
127143expect(body).not.toHaveProperty("reference_images");
128-expect(result.metadata).toEqual(
129-expect.objectContaining({
130-mode: "generate",
131-}),
132-);
144+expect(result.metadata?.mode).toBe("generate");
133145});
134146135147it("sends reference_image roles through xAI reference_images mode", async () => {
@@ -169,27 +181,18 @@ describe("xai video generation provider", () => {
169181],
170182});
171183172-const body = postJsonRequestMock.mock.calls[0]?.[0]?.body as Record<string, unknown>;
173-expect(postJsonRequestMock).toHaveBeenCalledWith(
174-expect.objectContaining({
175-url: "https://api.x.ai/v1/videos/generations",
176-body: expect.objectContaining({
177-reference_images: [
178-{ url: "https://example.com/subject.png" },
179-{ url: "https://example.com/style.png" },
180-],
181-duration: 10,
182-aspect_ratio: "9:16",
183-resolution: "720p",
184-}),
185-}),
186-);
184+const request = requirePostJsonCall();
185+expect(request.url).toBe("https://api.x.ai/v1/videos/generations");
186+expect(request.body?.reference_images).toEqual([
187+{ url: "https://example.com/subject.png" },
188+{ url: "https://example.com/style.png" },
189+]);
190+expect(request.body?.duration).toBe(10);
191+expect(request.body?.aspect_ratio).toBe("9:16");
192+expect(request.body?.resolution).toBe("720p");
193+const body = request.body ?? {};
187194expect(body).not.toHaveProperty("image");
188-expect(result.metadata).toEqual(
189-expect.objectContaining({
190-mode: "referenceToVideo",
191-}),
192-);
195+expect(result.metadata?.mode).toBe("referenceToVideo");
193196});
194197195198it("rejects mixed xAI first-frame and reference-image roles", async () => {
@@ -244,14 +247,9 @@ describe("xai video generation provider", () => {
244247inputVideos: [{ url: "https://example.com/input.mp4" }],
245248});
246249247-expect(postJsonRequestMock).toHaveBeenCalledWith(
248-expect.objectContaining({
249-url: "https://api.x.ai/v1/videos/extensions",
250-body: expect.objectContaining({
251-video: { url: "https://example.com/input.mp4" },
252-duration: 8,
253-}),
254-}),
255-);
250+const request = requirePostJsonCall();
251+expect(request.url).toBe("https://api.x.ai/v1/videos/extensions");
252+expect(request.body?.video).toEqual({ url: "https://example.com/input.mp4" });
253+expect(request.body?.duration).toBe(8);
256254});
257255});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。