Files
jhonny-editor/code/tests/tools/workflow-recipes.test.ts
T
João Henrique b541f502ba feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto
- Configurado MCP server para Premiere Pro
- Adicionado documentação e skills
- Configurado Gitignore para o projeto
2026-09-08 09:59:31 -04:00

48 lines
4.1 KiB
TypeScript
Executable File

import { describe, expect, it } from "vitest";
import { getWorkflowRecipeTools, validateWorkflowRecipe } from "../../src/tools/workflow-recipes.js";
import { mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
describe("workflow recipes", () => {
it("expands only audited declarative routes", async () => {
const tools = getWorkflowRecipeTools();
const result = await tools.preview_workflow_recipe.handler({ recipe_id: "talking-head-cleanup", provided_inputs: ["source_project_item_id"] });
expect(result.success).toBe(true);
expect((result.data as any).applied).toBe(false);
expect((result.data as any).execution_manifest[0].routes).toEqual(["verify_premiere_connection"]);
});
it("rejects arbitrary steps", () => expect(() => validateWorkflowRecipe({ schema_version: 1, id: "x", title: "X", description: "X", tags: [], required_inputs: [], steps: ["execute_extendscript"] })).toThrow(/unsupported/));
it("loads a contained custom recipe and rejects conflicts", async () => {
const root = mkdtempSync(path.join(tmpdir(), "recipes-")), file = path.join(root, "recipes.json");
const recipe = { schema_version: 1, id: "custom", title: "Custom", description: "Custom", tags: ["one"], required_inputs: [], steps: ["verify_connection"] };
writeFileSync(file, JSON.stringify([recipe]));
const tools = getWorkflowRecipeTools();
expect((await tools.search_workflow_recipes.handler({ query: "custom", approved_workspace_path: root, recipe_file: file })).success).toBe(true);
writeFileSync(file, JSON.stringify([{ ...recipe, id: "talking-head-cleanup" }]));
expect((await tools.search_workflow_recipes.handler({ approved_workspace_path: root, recipe_file: file })).success).toBe(false);
});
it.each([null, [], { schema_version: 2 }, { schema_version: 1, id: "x", title: "X", description: "X", steps: [] }, { schema_version: 1, id: "x", title: "X", description: "X", tags: ["a", "a"], required_inputs: [], steps: ["verify_connection"] }])("rejects invalid recipe %#", (recipe) => expect(() => validateWorkflowRecipe(recipe)).toThrow());
it("fails closed for malformed and escaped custom files", async () => {
const root = mkdtempSync(path.join(tmpdir(), "recipes-")), outside = mkdtempSync(path.join(tmpdir(), "recipes-out-"));
const tools = getWorkflowRecipeTools();
writeFileSync(path.join(outside, "r.json"), "[]");
expect((await tools.search_workflow_recipes.handler({ approved_workspace_path: root, recipe_file: path.join(outside, "r.json") })).success).toBe(false);
const file = path.join(root, "r.json"); writeFileSync(file, "not json");
expect((await tools.search_workflow_recipes.handler({ approved_workspace_path: root, recipe_file: file })).success).toBe(false);
writeFileSync(file, "{}"); expect((await tools.search_workflow_recipes.handler({ approved_workspace_path: root, recipe_file: file })).success).toBe(false);
expect((await tools.search_workflow_recipes.handler({ approved_workspace_path: root })).success).toBe(false);
expect((await tools.preview_workflow_recipe.handler({ recipe_id: "missing" })).success).toBe(false);
expect((await tools.preview_workflow_recipe.handler({ recipe_id: "talking-head-cleanup", provided_inputs: [1] })).success).toBe(false);
});
it("reports ready built-ins and custom recipe sources", async () => {
const root = mkdtempSync(path.join(tmpdir(), "recipes-")), file = path.join(root, "r.json");
writeFileSync(file, JSON.stringify([{ schema_version: 1, id: "custom-ready", title: "Custom", description: "Custom", tags: [], required_inputs: [], steps: ["verify_connection"] }]));
const tools = getWorkflowRecipeTools();
const custom = await tools.search_workflow_recipes.handler({ approved_workspace_path: root, recipe_file: file }) as any;
expect(custom.data.recipes.find((item: any) => item.id === "custom-ready").source).toBe("workspace_file");
const provided_inputs = ["source_project_item_id", "transcript_revision", "approved_segments", "sequence_name"];
expect(((await tools.preview_workflow_recipe.handler({ recipe_id: "talking-head-cleanup", provided_inputs })) as any).data.ready).toBe(true);
});
});