import { expect, test } from "@playwright/test"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { resolveCanvasRuntimeEndpoint } from "@/lib/canvas/capabilities/internal-endpoint"; import { enqueueCanvasCapabilityExecution, getCanvasCapabilityQueueDepth, } from "@/lib/canvas/capabilities/task-queue"; test.describe("canvas runtime internal endpoints", () => { test("keeps the image processing placeholder visible for shared toolbar actions", () => { const source = readFileSync( resolve(process.cwd(), "components/canvas/nodes/ImageNode.tsx"), "utf8" ); const start = source.indexOf("const executeSharedToolbarCapability = async"); const end = source.indexOf("// 处理图片编辑操作", start); expect(start).toBeGreaterThanOrEqual(0); expect(end).toBeGreaterThan(start); const sharedCapabilityFlow = source.slice(start, end); expect(sharedCapabilityFlow).toContain( "setIsCreatingDetachedResultNode(false);" ); expect(sharedCapabilityFlow).not.toContain( "setIsCreatingDetachedResultNode(true);" ); }); test("uses the local HTTP listener for server-internal capability calls", () => { expect( resolveCanvasRuntimeEndpoint( "/api/enhance", "https://ai.yydd.ai/api/canvas/canvas-1/capabilities", { port: "3125" } ) ).toBe("http://127.0.0.1:3125/api/enhance"); expect( resolveCanvasRuntimeEndpoint( "/api/enhance", "https://ai.yydd.ai/api/canvas/canvas-1/capabilities", { internalOrigin: "http://canvas-runtime:3000/base" } ) ).toBe("http://canvas-runtime:3000/api/enhance"); }); test("falls back to the incoming origin without an internal listener", () => { expect( resolveCanvasRuntimeEndpoint( "/api/enhance", "https://ai.yydd.ai/api/canvas/canvas-1/capabilities", { port: "invalid" } ) ).toBe("https://ai.yydd.ai/api/enhance"); }); test("continues the project queue after a failed capability execution", async () => { await expect( enqueueCanvasCapabilityExecution({ projectId: "failed-capability-project", execute: async () => { throw new Error("expected capability failure"); }, }) ).rejects.toThrow("expected capability failure"); await expect( enqueueCanvasCapabilityExecution({ projectId: "failed-capability-project", execute: async () => "recovered", }) ).resolves.toBe("recovered"); expect(getCanvasCapabilityQueueDepth("failed-capability-project")).toBe(0); }); });