test: cover canvas chat helper behavior

This commit is contained in:
Your Name 2026-05-27 10:27:49 +08:00
parent 63bafd278b
commit 31cccf87a1
2 changed files with 187 additions and 1 deletions

View File

@ -225,7 +225,7 @@ export function extractAssistantImageUrls(
break;
}
if (!selected) {
if (!selected && !referenceUrlKeys?.size) {
selected = candidates.find((candidate) => normalizeMediaUrl(candidate)) || "";
}
if (!selected) continue;

View File

@ -0,0 +1,186 @@
import { expect, test } from "@playwright/test";
import {
collectMessageImageUrls,
extractAssistantImageUrls,
extractVideoUrls,
normalizeMediaUrl,
stripMediaMarkup,
} from "@/components/canvas/chat-panel/canvas-chat-media";
import {
buildDetailResultMarkdown,
buildDetailReviewAppendMarkdown,
buildDetailReviewPlans,
} from "@/components/canvas/chat-panel/canvas-detail-markdown";
import type { ChatMessage } from "@/lib/types";
test.describe("canvas chat pure helpers", () => {
test("normalizes media urls without query strings or trailing slashes", () => {
expect(normalizeMediaUrl(" HTTPS://EXAMPLE.COM/assets/image.png?sig=secret#preview ")).toBe(
"https://example.com/assets/image.png"
);
expect(normalizeMediaUrl("not-a-url?cache=1#hash/")).toBe("not-a-url");
});
test("collects message image urls from parts, attachments, and legacy content", () => {
const message = {
id: "message-1",
role: "user",
parts: [
{
type: "file",
url: "https://cdn.example.com/upload-a.png?x=1",
mediaType: "image/png",
},
{
type: "text",
text: "参考 ![a](https://cdn.example.com/markdown-a.webp) 和 https://cdn.example.com/plain-a.jpg?token=1",
},
],
attachments: [
{
name: "attachment",
url: "https://cdn.example.com/attachment-a.jpeg?download=1",
contentType: "image/jpeg",
},
],
content: "legacy https://cdn.example.com/legacy-a.png",
} as unknown as ChatMessage;
expect(collectMessageImageUrls(message)).toEqual([
"https://cdn.example.com/upload-a.png?x=1",
"https://cdn.example.com/markdown-a.webp",
"https://cdn.example.com/plain-a.jpg?token=1",
"https://cdn.example.com/attachment-a.jpeg?download=1",
"https://cdn.example.com/legacy-a.png",
]);
});
test("filters assistant result images that match nearest user references", () => {
const referenceKeys = new Set(["https://cdn.example.com/reference.png"]);
const urls = extractAssistantImageUrls(
[
"![ref](https://cdn.example.com/reference.png?token=secret)",
"![result](https://cdn.example.com/result.png?token=secret)",
].join("\n"),
referenceKeys
);
expect(urls).toEqual(["https://cdn.example.com/result.png?token=secret"]);
});
test("extracts and strips video markup without removing surrounding text", () => {
const text = [
"生成完成",
'<video src="https://cdn.example.com/video-a.mp4?sig=1"></video>',
"[下载视频](https://cdn.example.com/video-b.mp4)",
"继续优化",
].join("\n");
expect(extractVideoUrls(text)).toEqual([
"https://cdn.example.com/video-a.mp4?sig=1",
"https://cdn.example.com/video-b.mp4",
]);
expect(stripMediaMarkup(text)).toBe("生成完成\n\n\n继续优化");
});
test("builds detail review plans with clamped count and localized fallbacks", () => {
const plans = buildDetailReviewPlans({
language: "zh",
count: 9,
summary: " 已验证卖点 ",
brief: {
productSpu: "",
demandType: "",
productName: "无线吸尘器",
targetAudience: "养宠家庭",
mainUser: "",
usageScenario: "客厅清洁",
triggerMoment: "",
coreNeed: "快速清理毛发",
riskConcern: "吸力不足",
expectedResult: "地面干净",
coreSellingPoint: "强吸力,轻量,低噪音",
positioningStatement: "",
userVoice: "",
competitorReference: "",
priceBand: "",
brandTone: "",
bannedWords: "",
},
});
expect(plans).toHaveLength(5);
expect(plans[0]).toMatchObject({
index: 1,
title: "真实需求反馈1",
});
expect(plans[0]?.reviewText).toContain("养宠家庭");
expect(plans[0]?.reviewText).toContain("已验证卖点");
expect(plans[0]?.imagePrompt).toContain("无线吸尘器");
});
test("builds stable detail result and appended review markdown", () => {
const markdown = buildDetailResultMarkdown({
generationMode: "agent_layout",
summary: "详情页生成成功",
images: [
{
originalUrl: "https://cdn.example.com/detail-1.png",
thumbnailUrl: "https://cdn.example.com/detail-1-thumb.webp",
},
],
prompts: ["商业摄影质感"],
skillFlow: {
name: "详情页生成",
version: "1.0",
steps: ["拆解卖点", "生成分镜"],
},
qualityChecks: {
passed: true,
},
screens: [
{
screenType: "A",
title: "核心卖点",
useModel: true,
fabe: {
b: "收益",
},
},
],
reviewGroups: [
{
reviewText: "真实好用",
images: [
{
originalUrl: "https://cdn.example.com/review-1.png",
thumbnailUrl: "https://cdn.example.com/review-1-thumb.webp",
},
],
},
],
});
expect(markdown).toContain("生成路线:AGENT排版(画面+可编辑文字层)");
expect(markdown).toContain("质检结果:通过");
expect(markdown).toContain("![thumb|||https://cdn.example.com/detail-1.png|||2K]");
expect(markdown).toContain("评价 1:真实好用");
expect(
buildDetailReviewAppendMarkdown({
failedCount: 1,
groups: [
{
reviewText: "追加评价",
images: [
{
originalUrl: "https://cdn.example.com/review-2.png",
thumbnailUrl: "https://cdn.example.com/review-2-thumb.webp",
},
],
},
],
})
).toContain("失败 1 条,已跳过。");
});
});