b288b091b2
移除素材查询分类筛选和分类列 精选审核通过后改为手动设置展示分类 公开精选按分类展示并补充底部点赞按钮 使用文档大拇指透明图标并同步点赞测试 同步精选审核数据契约、绑定和文档
201 lines
5.7 KiB
TypeScript
201 lines
5.7 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import {fireEvent, render, screen, waitFor, within} from '@testing-library/react';
|
|
import {beforeEach, expect, test, vi} from 'vitest';
|
|
|
|
import {
|
|
getAdminAssetReadUrl,
|
|
listAdminEditorAssets,
|
|
} from '../api/adminApiClient';
|
|
import type {AdminEditorAssetPayload} from '../api/adminApiTypes';
|
|
import {AdminEditorAssetQueryPage} from './AdminEditorAssetQueryPage';
|
|
|
|
vi.mock('../api/adminApiClient', () => ({
|
|
getAdminAssetReadUrl: vi.fn(),
|
|
listAdminEditorAssets: vi.fn(),
|
|
}));
|
|
|
|
const generatedAsset: AdminEditorAssetPayload = {
|
|
assetId: 'asset-1',
|
|
ownerUserId: 'user-1',
|
|
authorDisplayName: '作者昵称',
|
|
authorPublicUserCode: 'SY-00000042',
|
|
folderId: 'folder-1',
|
|
label: '角色形象 1',
|
|
assetObjectId: 'asset-object-1',
|
|
imageSrc: '/generated-character-drafts/editor/spec.png',
|
|
objectKey: 'generated-character-drafts/editor/spec.png',
|
|
width: 1024,
|
|
height: 1024,
|
|
sourceType: 'generated',
|
|
prompt: '完整提示词内容',
|
|
actualPrompt: null,
|
|
model: 'gpt-image-2',
|
|
provider: 'character',
|
|
taskId: 'task-1',
|
|
assetKind: 'character',
|
|
generationInputs: {style: 'clay'},
|
|
sourceResourceId: 'resource-1',
|
|
thumbnailSrc: null,
|
|
generationCostMudPoints: 12,
|
|
createdAt: '2026-07-04T10:00:00Z',
|
|
updatedAt: '2026-07-04T10:00:00Z',
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
vi.mocked(listAdminEditorAssets).mockResolvedValue({
|
|
entries: [generatedAsset],
|
|
nextCursor: null,
|
|
});
|
|
vi.mocked(getAdminAssetReadUrl).mockResolvedValue({
|
|
read: {
|
|
objectKey: 'generated-character-drafts/editor/spec.png',
|
|
signedUrl:
|
|
'https://signed.example.com/generated-character-drafts/editor/spec.png',
|
|
expiresAt: '2026-07-04T11:00:00Z',
|
|
},
|
|
});
|
|
});
|
|
|
|
test('后台素材查询展示作者昵称和陶泥号', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(await screen.findByText('作者昵称')).toBeTruthy();
|
|
expect(screen.getByText('SY-00000042')).toBeTruthy();
|
|
expect(screen.queryByText('user-1')).toBeNull();
|
|
});
|
|
|
|
test('后台素材查询按用户、搜索和时间调用查询接口', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
await screen.findByRole('img', {name: '素材:角色形象 1'});
|
|
|
|
fireEvent.change(screen.getByLabelText('用户 ID'), {
|
|
target: {value: 'user-1'},
|
|
});
|
|
fireEvent.change(screen.getByLabelText('搜索'), {
|
|
target: {value: '陶泥角色'},
|
|
});
|
|
fireEvent.change(screen.getByLabelText('开始时间'), {
|
|
target: {value: '2026-07-01'},
|
|
});
|
|
fireEvent.change(screen.getByLabelText('结束时间'), {
|
|
target: {value: '2026-07-04'},
|
|
});
|
|
|
|
await waitFor(() => {
|
|
expect(listAdminEditorAssets).toHaveBeenLastCalledWith('admin-token', {
|
|
ownerUserId: 'user-1',
|
|
keyword: '陶泥角色',
|
|
createdAfter: '2026-07-01T00:00:00+08:00',
|
|
createdBefore: '2026-07-04T23:59:59.999+08:00',
|
|
limit: 80,
|
|
});
|
|
});
|
|
});
|
|
|
|
test('后台素材查询不展示分类筛选和分类列', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(await screen.findByText('角色形象 1')).toBeTruthy();
|
|
expect(screen.queryByLabelText('分类')).toBeNull();
|
|
expect(screen.queryByRole('columnheader', {name: '分类'})).toBeNull();
|
|
});
|
|
|
|
test('后台素材查询缩略图使用 objectKey 换签后展示', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
const image = await screen.findByRole('img', {name: '素材:角色形象 1'});
|
|
|
|
await waitFor(() => {
|
|
expect(image.getAttribute('src')).toBe(
|
|
'https://signed.example.com/generated-character-drafts/editor/spec.png',
|
|
);
|
|
});
|
|
expect(getAdminAssetReadUrl).toHaveBeenCalledWith({
|
|
objectKey: 'generated-character-drafts/editor/spec.png',
|
|
expireSeconds: 300,
|
|
});
|
|
});
|
|
|
|
test('后台素材查询格式化微秒时间文本', async () => {
|
|
vi.mocked(listAdminEditorAssets).mockResolvedValueOnce({
|
|
entries: [
|
|
{
|
|
...generatedAsset,
|
|
createdAt: '1783231493.573727Z',
|
|
updatedAt: '1783231493.573727Z',
|
|
},
|
|
],
|
|
nextCursor: null,
|
|
});
|
|
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
expect(await screen.findByText('角色形象 1')).toBeTruthy();
|
|
expect(screen.queryByText('1783231493.573727Z')).toBeNull();
|
|
});
|
|
|
|
test('后台素材查询可查看素材详情', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: '详情'}));
|
|
|
|
const dialog = screen.getByRole('dialog', {name: '素材详情'});
|
|
expect(within(dialog).getByText('asset-1')).toBeTruthy();
|
|
expect(within(dialog).getByText('1024 x 1024')).toBeTruthy();
|
|
expect(within(dialog).getByText('12 泥点')).toBeTruthy();
|
|
expect(within(dialog).getByText(/"style": "clay"/u)).toBeTruthy();
|
|
});
|
|
|
|
test('后台素材查询可打开弹窗查看完整提示词', async () => {
|
|
render(
|
|
<AdminEditorAssetQueryPage
|
|
token="admin-token"
|
|
onUnauthorized={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: '完整提示词内容'}));
|
|
|
|
const dialog = screen.getByRole('dialog', {name: '完整提示词'});
|
|
expect(within(dialog).getByText('完整提示词内容')).toBeTruthy();
|
|
|
|
fireEvent.click(within(dialog).getByRole('button', {name: '关闭完整提示词'}));
|
|
|
|
await waitFor(() => {
|
|
expect(screen.queryByRole('dialog', {name: '完整提示词'})).toBeNull();
|
|
});
|
|
});
|