import { expect, test } from "@playwright/test"; import { analyzeAliyunVideo, isAliyunVideoModel, supportsVideoSound } from "@/lib/video-canvas/aliyun-video-analysis"; test("only official Alibaba video-understanding models use direct video input", () => { expect(isAliyunVideoModel("qwen3.8-max", "alibaba")).toBe(true); expect(isAliyunVideoModel("qwen3.8-omni-flash", "alibaba")).toBe(true); expect(isAliyunVideoModel("qwen3-vl-plus", "alibaba")).toBe(false); expect(isAliyunVideoModel("qwen3.8-max", "custom")).toBe(false); expect(supportsVideoSound("qwen3.8-max")).toBe(false); expect(supportsVideoSound("qwen3.8-omni-flash")).toBe(true); }); test("direct visual analysis sends the full video to the official endpoint", async () => { const original = globalThis.fetch; let body: any; globalThis.fetch = async (input, init) => { expect(String(input)).toBe("https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"); body = JSON.parse(String(init?.body)); return Response.json({ choices: [{ message: { content: '{"summary":"已解析真实画面"}' } }] }); }; try { const result = await analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId: "qwen3.8-max", prompt: "按时间分析", videoUrl: "https://example.com/test.mp4" }); expect(result).toContain("已解析真实画面"); expect(body.messages[0].content[0]).toMatchObject({ type: "video_url", video_url: { url: "https://example.com/test.mp4" } }); expect(body.stream).toBe(false); } finally { globalThis.fetch = original; } }); test("Omni parses streaming video and sound response", async () => { const original = globalThis.fetch; globalThis.fetch = async (_input, init) => { const body = JSON.parse(String(init?.body)); expect(body.model).toBe("qwen3.8-omni-flash"); expect(body.stream).toBe(true); expect(body.modalities).toEqual(["text"]); return new Response('data: {"choices":[{"delta":{"content":"有人声"}}]}\n\ndata: [DONE]\n', { status: 200 }); }; try { expect(await analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId: "qwen3.8-omni-flash", prompt: "听声音", videoUrl: "https://example.com/test.mp4" })).toBe("有人声"); } finally { globalThis.fetch = original; } }); test("native highlight analysis uses temporal video input with adjacent shot context", async () => { const original = globalThis.fetch; globalThis.fetch = async (_input, init) => { const body = JSON.parse(String(init?.body)); expect(body.messages[0].content).toEqual([ { type: "video_url", video_url: { url: "https://example.com/shot.mp4" }, fps: 2 }, { type: "image_url", image_url: { url: "data:image/jpeg;base64,bmVpZ2hib3I=" } }, { type: "text", text: "挑选动作高光,并检查衔接" }, ]); return Response.json({ choices: [{ message: { content: '{"startSeconds":2,"matchScore":90}' } }] }); }; try { expect(await analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId: "qwen3.8-max", prompt: "挑选动作高光,并检查衔接", videoUrl: "https://example.com/shot.mp4", contextImages: ["data:image/jpeg;base64,bmVpZ2hib3I="], fps: 2 })).toContain("startSeconds"); } finally { globalThis.fetch = original; } }); test("rejects private video URLs and unofficial provider endpoints", async () => { await expect(analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId: "qwen3.8-max", prompt: "分析", videoUrl: "http://127.0.0.1/test.mp4" })).rejects.toThrow("公网访问"); await expect(analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://example.com/v1", modelId: "qwen3.8-max", prompt: "分析", videoUrl: "https://example.com/test.mp4" })).rejects.toThrow("官方地址"); }); test("highlight requests enforce provider JSON output without changing free-text analysis", async () => { const original = globalThis.fetch; const bodies: any[] = []; globalThis.fetch = async (_input, init) => { bodies.push(JSON.parse(String(init?.body))); return Response.json({ choices: [{ finish_reason: "stop", message: { content: '{"startSeconds":0}' } }] }); }; const input = { apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId: "qwen3.8-max" as const, prompt: "返回 JSON", videoUrl: "https://example.com/shot.mp4" }; try { await analyzeAliyunVideo({ ...input, jsonOutput: true }); await analyzeAliyunVideo(input); expect(bodies[0].response_format).toEqual({ type: "json_object" }); expect(bodies[1].response_format).toBeUndefined(); } finally { globalThis.fetch = original; } }); for (const modelId of ["qwen3.8-max", "qwen3.8-omni-flash"] as const) { test(`${modelId} rejects truncated analysis even when the partial text is valid JSON`, async () => { const original = globalThis.fetch; let calls = 0; globalThis.fetch = async () => { calls++; return modelId === "qwen3.8-max" ? Response.json({ choices: [{ finish_reason: "length", message: { content: '{"matchScore":99}' } }] }) : new Response('data: {"choices":[{"delta":{"content":"{\"matchScore\":99}"}}]}\n\ndata: {"choices":[{"delta":{},"finish_reason":"length"}]}\n\ndata: [DONE]\n'); }; try { await expect(analyzeAliyunVideo({ apiKey: "test-key", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1", modelId, prompt: "返回 JSON", videoUrl: "https://example.com/shot.mp4", jsonOutput: true })).rejects.toThrow("被截断"); expect(calls).toBe(1); } finally { globalThis.fetch = original; } }); }