Files
auto-virtual-tryon-frontend/tests/features/libraries/library-page.test.tsx
2026-03-28 13:42:22 +08:00

118 lines
4.4 KiB
TypeScript

import { fireEvent, render, screen } from "@testing-library/react";
import { expect, test } from "vitest";
import { LibraryPage } from "@/features/libraries/library-page";
import type { LibraryItemVM } from "@/lib/types/view-models";
const MODEL_ITEMS: LibraryItemVM[] = [
{
id: "12",
libraryType: "models",
name: "Ava / Studio",
description: "中性棚拍模特占位数据,用于提交页联调。",
previewUri: "mock://libraries/models/ava",
tags: ["女装", "半身", "mock"],
isMock: false,
backendId: 12,
files: [
{
id: 101,
role: "thumbnail",
url: "mock://libraries/models/ava",
},
{
id: 102,
role: "gallery",
url: "mock://libraries/models/ava-side",
},
],
},
];
test("surfaces the current resource library data-source message", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
expect(screen.getByText("资源库当前显示真实后端数据。")).toBeInTheDocument();
expect(screen.getByText("Ava / Studio")).toBeInTheDocument();
});
test("renders in-page tabs plus an upload slot ahead of the masonry cards", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
expect(
screen.getByRole("navigation", { name: "Library sections" }),
).toBeInTheDocument();
expect(screen.getByRole("link", { name: "模特" })).toHaveAttribute(
"aria-current",
"page",
);
expect(screen.getByRole("link", { name: "场景" })).toHaveAttribute(
"href",
"/libraries/scenes",
);
expect(screen.getByRole("link", { name: "服装" })).toHaveAttribute(
"href",
"/libraries/garments",
);
expect(screen.getByText("上传模特资源")).toBeInTheDocument();
expect(screen.getByRole("button", { name: "打开上传弹窗" })).toBeInTheDocument();
expect(screen.getByTestId("library-masonry").className).toContain("columns-1");
expect(screen.getByTestId("library-masonry").className).toContain("2xl:columns-4");
expect(screen.getByText("Ava / Studio")).toBeInTheDocument();
});
test("renders direct management actions inside each resource card", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
expect(screen.getByRole("img", { name: "Ava / Studio 预览图" })).toHaveAttribute(
"src",
"mock://libraries/models/ava",
);
expect(screen.getByRole("button", { name: "编辑" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "删除" })).toBeInTheDocument();
});
test("opens a model-specific upload dialog from the first masonry card", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
fireEvent.click(screen.getByRole("button", { name: "打开上传弹窗" }));
expect(screen.getByRole("dialog", { name: "上传模特资源" })).toBeInTheDocument();
expect(screen.getByLabelText("资源名称")).toBeInTheDocument();
expect(screen.getByLabelText("模特性别")).toBeInTheDocument();
expect(screen.getByLabelText("年龄段")).toBeInTheDocument();
expect(screen.getByLabelText("原图")).toBeInTheDocument();
expect(screen.getByLabelText("附加图库")).toBeInTheDocument();
expect(screen.getByText("缩略图将根据原图自动生成。")).toBeInTheDocument();
});
test("opens an edit dialog that lets operators inspect multiple images and choose a cover", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
fireEvent.click(screen.getByRole("button", { name: "编辑" }));
expect(screen.getByRole("dialog", { name: "编辑模特资源" })).toBeInTheDocument();
expect(screen.getByDisplayValue("Ava / Studio")).toBeInTheDocument();
expect(screen.getByRole("img", { name: "Ava / Studio 图片 1" })).toHaveAttribute(
"src",
"mock://libraries/models/ava",
);
expect(screen.getByRole("img", { name: "Ava / Studio 图片 2" })).toHaveAttribute(
"src",
"mock://libraries/models/ava-side",
);
expect(screen.getByRole("button", { name: "设为封面 2" })).toBeInTheDocument();
});
test("opens an alert dialog before archiving a resource", () => {
render(<LibraryPage libraryType="models" items={MODEL_ITEMS} />);
fireEvent.click(screen.getByRole("button", { name: "删除" }));
expect(
screen.getByRole("alertdialog", { name: "确认删除模特资源" }),
).toBeInTheDocument();
expect(screen.getByRole("button", { name: "确认删除" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "取消" })).toBeInTheDocument();
});