237 lines
6.8 KiB
TypeScript
237 lines
6.8 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import { test, expect } from "vitest";
|
|
|
|
import { OrderDetail } from "@/features/orders/order-detail";
|
|
import type { OrderDetailVM } from "@/lib/types/view-models";
|
|
|
|
const BASE_ORDER_DETAIL: OrderDetailVM = {
|
|
orderId: 101,
|
|
workflowId: "wf-101",
|
|
customerLevel: "mid",
|
|
serviceMode: "semi_pro",
|
|
status: "waiting_review",
|
|
statusMeta: {
|
|
label: "待审核",
|
|
tone: "warning",
|
|
},
|
|
currentStep: "review",
|
|
currentStepLabel: "人工审核",
|
|
modelId: 1001,
|
|
poseId: 2002,
|
|
garmentAssetId: 3003,
|
|
sceneRefAssetId: 4004,
|
|
currentRevisionAssetId: null,
|
|
currentRevisionVersion: null,
|
|
latestRevisionAssetId: null,
|
|
latestRevisionVersion: null,
|
|
revisionCount: 0,
|
|
reviewTaskStatus: null,
|
|
pendingManualConfirm: false,
|
|
createdAt: "2026-03-27T00:00:00Z",
|
|
updatedAt: "2026-03-27T00:10:00Z",
|
|
finalAsset: {
|
|
id: 88,
|
|
orderId: 101,
|
|
type: "final",
|
|
stepName: null,
|
|
parentAssetId: null,
|
|
rootAssetId: null,
|
|
versionNo: 0,
|
|
isCurrentVersion: false,
|
|
stepLabel: "最终图",
|
|
label: "最终图",
|
|
uri: "mock://final-preview",
|
|
metadata: null,
|
|
createdAt: "2026-03-27T00:10:00Z",
|
|
isMock: true,
|
|
},
|
|
finalAssetState: {
|
|
kind: "ready",
|
|
},
|
|
assets: [
|
|
{
|
|
id: 77,
|
|
orderId: 101,
|
|
type: "fusion",
|
|
stepName: "fusion",
|
|
parentAssetId: null,
|
|
rootAssetId: null,
|
|
versionNo: 0,
|
|
isCurrentVersion: false,
|
|
stepLabel: "融合",
|
|
label: "融合产物",
|
|
uri: "mock://fusion-preview",
|
|
metadata: null,
|
|
createdAt: "2026-03-27T00:09:00Z",
|
|
isMock: true,
|
|
},
|
|
],
|
|
assetGalleryState: {
|
|
kind: "ready",
|
|
},
|
|
hasMockAssets: true,
|
|
};
|
|
|
|
test("shows a mock asset banner when the current order contains mock assets", () => {
|
|
render(<OrderDetail viewModel={BASE_ORDER_DETAIL} />);
|
|
|
|
expect(screen.getByText("当前资产来自 mock 流程")).toBeInTheDocument();
|
|
expect(screen.getAllByText("最终图").length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders the business-empty final-result state when no final asset exists", () => {
|
|
render(
|
|
<OrderDetail
|
|
viewModel={{
|
|
...BASE_ORDER_DETAIL,
|
|
finalAsset: null,
|
|
finalAssetState: {
|
|
kind: "business-empty",
|
|
title: "最终图暂未生成",
|
|
description: "当前订单还没有可展示的最终结果。",
|
|
},
|
|
}}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText("最终图暂未生成")).toBeInTheDocument();
|
|
expect(screen.getByText("当前订单还没有可展示的最终结果。")).toBeInTheDocument();
|
|
});
|
|
|
|
test("renders prepared-model input snapshots when asset metadata contains resource inputs", () => {
|
|
render(
|
|
<OrderDetail
|
|
viewModel={{
|
|
...BASE_ORDER_DETAIL,
|
|
assets: [
|
|
{
|
|
id: 66,
|
|
orderId: 101,
|
|
type: "prepared_model",
|
|
stepName: "prepare_model",
|
|
parentAssetId: null,
|
|
rootAssetId: null,
|
|
versionNo: 0,
|
|
isCurrentVersion: false,
|
|
stepLabel: "模型准备",
|
|
label: "模型准备产物",
|
|
uri: "https://images.example.com/prepared-model.jpg",
|
|
metadata: {
|
|
model_input: {
|
|
resource_id: 3,
|
|
resource_name: "主模特",
|
|
original_url: "https://images.example.com/model.jpg",
|
|
},
|
|
garment_input: {
|
|
resource_id: 4,
|
|
resource_name: "上衣",
|
|
original_url: "https://images.example.com/garment.jpg",
|
|
},
|
|
scene_input: {
|
|
resource_id: 5,
|
|
resource_name: "白棚",
|
|
original_url: "https://images.example.com/scene.jpg",
|
|
},
|
|
},
|
|
createdAt: "2026-03-27T00:08:00Z",
|
|
isMock: false,
|
|
},
|
|
],
|
|
}}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText("输入素材")).toBeInTheDocument();
|
|
expect(screen.getByText("模特图")).toBeInTheDocument();
|
|
expect(screen.getByText("服装图")).toBeInTheDocument();
|
|
expect(screen.getByText("场景图")).toBeInTheDocument();
|
|
expect(screen.getByText("主模特")).toBeInTheDocument();
|
|
expect(screen.getByText("上衣")).toBeInTheDocument();
|
|
expect(screen.getByText("白棚")).toBeInTheDocument();
|
|
expect(screen.getByAltText("模型准备产物预览")).toBeInTheDocument();
|
|
});
|
|
|
|
test("renders image previews for non-mock final and process assets", () => {
|
|
render(
|
|
<OrderDetail
|
|
viewModel={{
|
|
...BASE_ORDER_DETAIL,
|
|
hasMockAssets: false,
|
|
finalAsset: {
|
|
...BASE_ORDER_DETAIL.finalAsset!,
|
|
uri: "https://images.example.com/final.jpg",
|
|
isMock: false,
|
|
},
|
|
assets: [
|
|
{
|
|
id: 78,
|
|
orderId: 101,
|
|
type: "tryon",
|
|
stepName: "tryon",
|
|
parentAssetId: null,
|
|
rootAssetId: null,
|
|
versionNo: 0,
|
|
isCurrentVersion: false,
|
|
stepLabel: "试穿生成",
|
|
label: "试穿生成产物",
|
|
uri: "https://images.example.com/tryon.jpg",
|
|
metadata: null,
|
|
createdAt: "2026-03-27T00:09:00Z",
|
|
isMock: false,
|
|
},
|
|
],
|
|
}}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByAltText("最终图预览")).toBeInTheDocument();
|
|
expect(screen.getByAltText("试穿生成产物预览")).toBeInTheDocument();
|
|
});
|
|
|
|
test("opens an asset preview dialog for real images and resets zoom state", () => {
|
|
render(
|
|
<OrderDetail
|
|
viewModel={{
|
|
...BASE_ORDER_DETAIL,
|
|
hasMockAssets: false,
|
|
finalAsset: {
|
|
...BASE_ORDER_DETAIL.finalAsset!,
|
|
uri: "https://images.example.com/final.jpg",
|
|
isMock: false,
|
|
},
|
|
assets: [
|
|
{
|
|
id: 78,
|
|
orderId: 101,
|
|
type: "scene",
|
|
stepName: "scene",
|
|
parentAssetId: null,
|
|
rootAssetId: null,
|
|
versionNo: 0,
|
|
isCurrentVersion: false,
|
|
stepLabel: "场景处理",
|
|
label: "场景处理产物",
|
|
uri: "https://images.example.com/scene.jpg",
|
|
metadata: null,
|
|
createdAt: "2026-03-27T00:09:00Z",
|
|
isMock: false,
|
|
},
|
|
],
|
|
}}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "查看场景处理产物大图" }));
|
|
|
|
expect(screen.getByRole("dialog", { name: "场景处理产物预览" })).toBeInTheDocument();
|
|
|
|
const zoomableImage = screen.getByAltText("场景处理产物大图");
|
|
fireEvent.wheel(zoomableImage, { deltaY: -120 });
|
|
|
|
expect(zoomableImage).toHaveStyle({ transform: "translate(0px, 0px) scale(1.12)" });
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "重置预览" }));
|
|
|
|
expect(zoomableImage).toHaveStyle({ transform: "translate(0px, 0px) scale(1)" });
|
|
});
|