From 2393065a54367d38785d31dde0aeb229b0a8854f Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 10:10:26 +0100 Subject: [PATCH] test(agents): share video tool plugin fixtures --- src/agents/tools/video-generate-tool.test.ts | 307 +++++-------------- 1 file changed, 72 insertions(+), 235 deletions(-) diff --git a/src/agents/tools/video-generate-tool.test.ts b/src/agents/tools/video-generate-tool.test.ts index 54c5c2167da..75189c052df 100644 --- a/src/agents/tools/video-generate-tool.test.ts +++ b/src/agents/tools/video-generate-tool.test.ts @@ -23,6 +23,53 @@ function asConfig(value: unknown): OpenClawConfig { return value as OpenClawConfig; } +function mockVideoPluginProvider(capabilities: Record = {}) { + vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ + { + id: "video-plugin", + defaultModel: "vid-v1", + models: ["vid-v1"], + capabilities, + generateVideo: vi.fn(async () => ({ + videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], + })), + }, + ]); +} + +function createVideoPluginTool() { + const tool = createVideoGenerateTool({ + config: asConfig({ + agents: { + defaults: { + videoGenerationModel: { primary: "video-plugin/vid-v1" }, + }, + }, + }), + }); + if (!tool) { + throw new Error("expected video_generate tool"); + } + return tool; +} + +function mockSavedVideoResult(fileName = "out.mp4") { + const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ + provider: "video-plugin", + model: "vid-v1", + attempts: [], + ignoredOverrides: [], + videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName }], + }); + vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({ + path: `/tmp/${fileName}`, + id: fileName, + size: 11, + contentType: "video/mp4", + }); + return generateSpy; +} + describe("createVideoGenerateTool", () => { beforeEach(() => { vi.restoreAllMocks(); @@ -597,31 +644,9 @@ describe("createVideoGenerateTool", () => { }); it("rejects providerOptions that is not a plain JSON object", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: {}, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); + mockVideoPluginProvider(); const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const tool = createVideoPluginTool(); // Array-shaped providerOptions should be rejected up front, not cast to a // Record with numeric-string keys and silently forwarded. @@ -646,45 +671,11 @@ describe("createVideoGenerateTool", () => { }); it("forwards providerOptions to the runtime for valid JSON-object payloads", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: { - providerOptions: { seed: "number", draft: "boolean" }, - }, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ - provider: "video-plugin", - model: "vid-v1", - attempts: [], - ignoredOverrides: [], - videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }], + mockVideoPluginProvider({ + providerOptions: { seed: "number", draft: "boolean" }, }); - vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({ - path: "/tmp/out.mp4", - id: "out.mp4", - size: 11, - contentType: "video/mp4", - }); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const generateSpy = mockSavedVideoResult(); + const tool = createVideoPluginTool(); await tool.execute("call-1", { prompt: "lobster", @@ -699,33 +690,11 @@ describe("createVideoGenerateTool", () => { }); it("rejects *Roles arrays that are longer than the asset list", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: { - imageToVideo: { enabled: true, maxInputImages: 2 }, - }, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), + mockVideoPluginProvider({ + imageToVideo: { enabled: true, maxInputImages: 2 }, }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); + const tool = createVideoPluginTool(); await expect( tool.execute("call-1", { @@ -739,30 +708,9 @@ describe("createVideoGenerateTool", () => { }); it("rejects *Roles that are not arrays", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: {}, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); + mockVideoPluginProvider(); const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const tool = createVideoPluginTool(); await expect( tool.execute("call-1", { @@ -776,45 +724,11 @@ describe("createVideoGenerateTool", () => { }); it("attaches positional role hints to loaded reference assets", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: { - imageToVideo: { enabled: true, maxInputImages: 2 }, - }, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ - provider: "video-plugin", - model: "vid-v1", - attempts: [], - ignoredOverrides: [], - videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }], + mockVideoPluginProvider({ + imageToVideo: { enabled: true, maxInputImages: 2 }, }); - vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({ - path: "/tmp/out.mp4", - id: "out.mp4", - size: 11, - contentType: "video/mp4", - }); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const generateSpy = mockSavedVideoResult(); + const tool = createVideoPluginTool(); await tool.execute("call-1", { prompt: "lobster", @@ -832,33 +746,11 @@ describe("createVideoGenerateTool", () => { }); it("rejects audio data: URLs via the templated rejection branch", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: { - maxInputAudios: 1, - }, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), + mockVideoPluginProvider({ + maxInputAudios: 1, }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo"); + const tool = createVideoPluginTool(); await expect( tool.execute("call-1", { @@ -870,43 +762,9 @@ describe("createVideoGenerateTool", () => { }); it("accepts aspectRatio=adaptive and forwards it to the runtime", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: {}, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const generateSpy = vi.spyOn(videoGenerationRuntime, "generateVideo").mockResolvedValue({ - provider: "video-plugin", - model: "vid-v1", - attempts: [], - ignoredOverrides: [], - videos: [{ buffer: Buffer.from("video-bytes"), mimeType: "video/mp4", fileName: "out.mp4" }], - }); - vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValueOnce({ - path: "/tmp/out.mp4", - id: "out.mp4", - size: 11, - contentType: "video/mp4", - }); - - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + mockVideoPluginProvider(); + const generateSpy = mockSavedVideoResult(); + const tool = createVideoPluginTool(); await tool.execute("call-1", { prompt: "lobster", @@ -917,29 +775,8 @@ describe("createVideoGenerateTool", () => { }); it("rejects unsupported aspectRatio values", async () => { - vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ - { - id: "video-plugin", - defaultModel: "vid-v1", - models: ["vid-v1"], - capabilities: {}, - generateVideo: vi.fn(async () => ({ - videos: [{ buffer: Buffer.from("x"), mimeType: "video/mp4" }], - })), - }, - ]); - const tool = createVideoGenerateTool({ - config: asConfig({ - agents: { - defaults: { - videoGenerationModel: { primary: "video-plugin/vid-v1" }, - }, - }, - }), - }); - if (!tool) { - throw new Error("expected video_generate tool"); - } + mockVideoPluginProvider(); + const tool = createVideoPluginTool(); await expect( tool.execute("call-1", {