ai-chatbot/tests/routes/video-history-assets.test.ts

173 lines
5.3 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
defaultVideoCanvasHistoryPickerConfig,
VIDEO_CANVAS_HISTORY_ZOOM_LEVELS,
allocateVideoCanvasHistoryMediaNodeTitle,
formatVideoCanvasHistoryDate,
getInitialVideoCanvasHistoryMediaOrdinals,
getVideoCanvasHistoryMediaNodeDimensions,
getVideoCanvasHistoryMediaNodePosition,
getVideoCanvasHistoryZoomIndex,
groupVideoCanvasHistoryItems,
normalizeVideoCanvasHistoryAssetIds,
normalizeVideoCanvasHistoryPickerConfig,
paginateVideoCanvasHistoryItems,
} from "../../lib/video-canvas/history-assets";
test.describe("video canvas history assets", () => {
test("uses the competitor-matched zoom levels and card sizes", () => {
expect(VIDEO_CANVAS_HISTORY_ZOOM_LEVELS).toEqual([
{ cardSize: 130, percent: 75 },
{ cardSize: 144, percent: 100 },
{ cardSize: 182, percent: 125 },
{ cardSize: 248, percent: 150 },
]);
expect(getVideoCanvasHistoryZoomIndex(100)).toBe(1);
expect(getVideoCanvasHistoryZoomIndex(150)).toBe(3);
});
test("normalizes selected database asset ids", () => {
expect(
normalizeVideoCanvasHistoryAssetIds([" a ", "a", "", null, "b"]),
).toEqual(["a", "b"]);
expect(normalizeVideoCanvasHistoryAssetIds("a")).toEqual([]);
});
test("formats and groups real creation dates in display order", () => {
const items = [
{ createdAt: "2026-07-14T01:30:00.000Z", id: "new" },
{ createdAt: "2026-07-13T17:30:00.000Z", id: "same-local-day" },
{ createdAt: "2026-07-09T03:00:00.000Z", id: "old" },
];
expect(
formatVideoCanvasHistoryDate(items[0].createdAt, "Asia/Shanghai"),
).toBe("2026-07-14");
expect(groupVideoCanvasHistoryItems(items, "Asia/Shanghai")).toEqual([
{ date: "2026-07-14", items: items.slice(0, 2) },
{ date: "2026-07-09", items: items.slice(2) },
]);
});
test("keeps the observed picker sources and source-specific media tabs", () => {
expect(defaultVideoCanvasHistoryPickerConfig).toMatchObject({
maxSelection: 10,
mediaShortSide: 350,
pageSize: 15,
placementGap: 450,
sources: [
{ label: "LibTV", mediaModes: ["image", "video", "audio"] },
{ label: "Lib生成器", mediaModes: ["image", "video"] },
{ label: "WebUI", mediaModes: ["image", "video"] },
{ label: "ComfyUI", mediaModes: ["image", "av"] },
{ label: "AI应用", mediaModes: ["image", "av"] },
],
});
});
test("normalizes administrator picker limits, sources, and media modes", () => {
expect(
normalizeVideoCanvasHistoryPickerConfig({
maxSelection: 99,
mediaShortSide: 50,
pageSize: 0,
placementGap: 9999,
sources: [
{
enabled: false,
id: " Custom Source ",
label: " 本地历史 ",
mediaModes: ["image", "av", "invalid"],
usesLocalAssets: true,
},
],
}),
).toEqual({
maxSelection: 50,
mediaShortSide: 120,
pageSize: 1,
placementGap: 2000,
sources: [
{
enabled: false,
id: "custom-source",
label: "本地历史",
mediaModes: ["image", "av"],
usesLocalAssets: true,
},
],
});
});
test("paginates fifteen items while preserving the full selection source", () => {
const items = Array.from({ length: 17 }, (_, index) => index + 1);
expect(paginateVideoCanvasHistoryItems(items, 1, 15)).toEqual({
items: items.slice(0, 15),
page: 1,
pageCount: 2,
});
expect(paginateVideoCanvasHistoryItems(items, 2, 15)).toEqual({
items: items.slice(15),
page: 2,
pageCount: 2,
});
});
test("uses a 350px short side and a 450px horizontal multi-select gap", () => {
expect(
getVideoCanvasHistoryMediaNodeDimensions({
height: 531,
mediaShortSide: 350,
mediaType: "image",
width: 400,
}),
).toEqual({ height: 465, width: 350 });
expect(
getVideoCanvasHistoryMediaNodeDimensions({
height: 350,
mediaShortSide: 350,
mediaType: "image",
width: 700,
}),
).toEqual({ height: 350, width: 700 });
expect(
getVideoCanvasHistoryMediaNodeDimensions({
height: 720,
mediaShortSide: 350,
mediaType: "video",
width: 1280,
}),
).toEqual({ height: 350, width: 622 });
expect(
getVideoCanvasHistoryMediaNodePosition({
center: { x: 752.5, y: 398.25 },
index: 1,
placementGap: 450,
}),
).toEqual({ x: 1203, y: 398 });
});
test("increments numbered history titles per media type without renaming custom titles", () => {
expect(
getInitialVideoCanvasHistoryMediaOrdinals([
{ inputType: "image", title: "图片节点 3" },
{ inputType: "video", title: "成品" },
]),
).toEqual({ audio: 1, image: 4, video: 1 });
expect(
allocateVideoCanvasHistoryMediaNodeTitle({
mediaType: "image",
nextOrdinal: 4,
sourceTitle: "图片节点 3",
}),
).toEqual({ nextOrdinal: 5, title: "图片节点 4" });
expect(
allocateVideoCanvasHistoryMediaNodeTitle({
mediaType: "image",
nextOrdinal: 5,
sourceTitle: "角色立绘",
}),
).toEqual({ nextOrdinal: 5, title: "角色立绘" });
});
});