This commit is contained in:
2026-05-08 11:44:42 +08:00
parent b08127031c
commit abf1f1ebea
249 changed files with 39411 additions and 887 deletions

View File

@@ -0,0 +1,130 @@
/* @vitest-environment jsdom */
import { render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { expect, test, vi } from 'vitest';
import { buildVisualNovelForbiddenCopyPattern } from '../visual-novel-runtime/visualNovelForbiddenCopy';
import { mockVisualNovelDraft } from '../visual-novel-runtime/visualNovelMockData';
import { VisualNovelResultView } from './VisualNovelResultView';
vi.mock('../../services/visual-novel-creation', () => ({
listVisualNovelHistoryAssets: vi.fn().mockResolvedValue([]),
uploadVisualNovelAsset: vi.fn(),
}));
vi.mock('../../services/assetReadUrlService', () => ({
resolveAssetReadUrl: vi.fn().mockResolvedValue(''),
}));
test('visual novel result opens complex editors as a dialog', async () => {
const user = userEvent.setup();
render(
<VisualNovelResultView draft={mockVisualNovelDraft} onBack={() => {}} />,
);
await user.click(screen.getByRole('button', { name: '角色' }));
await user.click(screen.getByRole('button', { name: //u }));
const dialog = screen.getByRole('dialog', { name: '林遥' });
expect(within(dialog).getByDisplayValue('林遥')).toBeTruthy();
expect(screen.queryByText(buildVisualNovelForbiddenCopyPattern())).toBeNull();
});
test('visual novel result exposes test run action with current draft', async () => {
const user = userEvent.setup();
const onStartTestRun = vi.fn();
render(
<VisualNovelResultView
draft={mockVisualNovelDraft}
onBack={() => {}}
onStartTestRun={onStartTestRun}
/>,
);
await user.click(screen.getByRole('button', { name: '试玩' }));
expect(onStartTestRun).toHaveBeenCalledTimes(1);
expect(onStartTestRun.mock.calls[0]?.[0].workTitle).toBe('雪线电台');
});
test('visual novel result sends edited character draft to save and test run', async () => {
const user = userEvent.setup();
const onSaveDraft = vi.fn();
const onStartTestRun = vi.fn();
render(
<VisualNovelResultView
draft={mockVisualNovelDraft}
onBack={() => {}}
onSaveDraft={onSaveDraft}
onStartTestRun={onStartTestRun}
/>,
);
await user.click(screen.getByRole('button', { name: '角色' }));
await user.click(screen.getByRole('button', { name: //u }));
const dialog = screen.getByRole('dialog', { name: '林遥' });
const nameInput = within(dialog).getByDisplayValue('林遥');
await user.clear(nameInput);
await user.type(nameInput, '林遥改');
await user.click(within(dialog).getByRole('button', { name: '关闭' }));
const saveButtons = screen.getAllByRole('button', { name: '保存草稿' });
await user.click(saveButtons[1]!);
await user.click(screen.getByRole('button', { name: '试玩' }));
expect(onSaveDraft.mock.calls[0]?.[0].characters[0]?.name).toBe('林遥改');
expect(onStartTestRun.mock.calls[0]?.[0].characters[0]?.name).toBe('林遥改');
});
test('visual novel result uploads scene and character assets into platform references', async () => {
const user = userEvent.setup();
const onSaveDraft = vi.fn();
const uploadMock = vi.mocked(
await import('../../services/visual-novel-creation'),
).uploadVisualNovelAsset;
uploadMock.mockResolvedValue({
assetObjectId: 'asset-scene-1',
assetKind: 'scene_image',
objectKey: 'generated-custom-world-scenes/vn-profile/scene-1/background.png',
imageSrc: '/generated-custom-world-scenes/vn-profile/scene-1/background.png',
});
render(
<VisualNovelResultView
draft={mockVisualNovelDraft}
onBack={() => {}}
onSaveDraft={onSaveDraft}
/>,
);
await user.click(screen.getByRole('button', { name: '场景' }));
await user.click(screen.getByRole('button', { name: //u }));
const dialog = screen.getByRole('dialog', { name: '风雪站台' });
const backgroundButtons = within(dialog).getAllByRole('button', {
name: '背景图',
});
await user.click(backgroundButtons[0]!);
const fileInput = within(screen.getByRole('dialog', { name: '背景图' })).getByLabelText(
'上传背景图文件',
) as HTMLInputElement;
await user.upload(
fileInput,
new File(['image-bytes'], 'scene.png', { type: 'image/png' }),
);
await user.click(within(dialog).getByRole('button', { name: '关闭' }));
await user.click(screen.getAllByRole('button', { name: '保存草稿' })[1]!);
expect(onSaveDraft).toHaveBeenCalled();
expect(onSaveDraft.mock.calls[0]?.[0].scenes[0]?.backgroundImageSrc).toContain(
'/generated-custom-world-scenes/',
);
});

File diff suppressed because it is too large Load Diff