收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
112
src/components/CharacterChatModal.test.tsx
Normal file
112
src/components/CharacterChatModal.test.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import type { CharacterChatModalState } from '../hooks/rpg-runtime-story';
|
||||
import type { Character } from '../types';
|
||||
import { CharacterChatModal } from './CharacterChatModal';
|
||||
|
||||
function createCharacter(): Character {
|
||||
return {
|
||||
id: 'hero',
|
||||
name: '沈行',
|
||||
title: '试剑客',
|
||||
description: '测试角色',
|
||||
backstory: '测试背景',
|
||||
avatar: '/hero.png',
|
||||
portrait: '/hero.png',
|
||||
assetFolder: 'hero',
|
||||
assetVariant: 'default',
|
||||
attributes: {
|
||||
strength: 10,
|
||||
agility: 10,
|
||||
intelligence: 8,
|
||||
spirit: 9,
|
||||
},
|
||||
personality: '冷静谨慎',
|
||||
skills: [],
|
||||
adventureOpenings: {},
|
||||
} as Character;
|
||||
}
|
||||
|
||||
function createModalState(
|
||||
overrides: Partial<CharacterChatModalState> = {},
|
||||
): CharacterChatModalState {
|
||||
return {
|
||||
target: {
|
||||
character: createCharacter(),
|
||||
npcId: 'npc-hero',
|
||||
roleLabel: '队友',
|
||||
hp: 80,
|
||||
maxHp: 100,
|
||||
mana: 24,
|
||||
maxMana: 30,
|
||||
},
|
||||
draft: '',
|
||||
messages: [],
|
||||
suggestions: ['先问问线索'],
|
||||
summary: '',
|
||||
isSending: false,
|
||||
isLoadingSuggestions: false,
|
||||
error: '暂时无法生成回复。',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('角色聊天错误提示复用暗色 PlatformStatusMessage chrome', () => {
|
||||
render(
|
||||
<CharacterChatModal
|
||||
modal={createModalState()}
|
||||
onClose={vi.fn()}
|
||||
onDraftChange={vi.fn()}
|
||||
onUseSuggestion={vi.fn()}
|
||||
onRefreshSuggestions={vi.fn()}
|
||||
onSendDraft={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const errorMessage = screen.getByText('暂时无法生成回复。');
|
||||
|
||||
expect(errorMessage.className).toContain('platform-status-message');
|
||||
expect(errorMessage.className).toContain('border-amber-300/15');
|
||||
expect(errorMessage.className).toContain('bg-amber-500/10');
|
||||
expect(errorMessage.className).toContain('text-amber-50/90');
|
||||
});
|
||||
|
||||
test('角色聊天状态、空态和建议复用暗色 UI Kit chrome', () => {
|
||||
render(
|
||||
<CharacterChatModal
|
||||
modal={createModalState()}
|
||||
onClose={vi.fn()}
|
||||
onDraftChange={vi.fn()}
|
||||
onUseSuggestion={vi.fn()}
|
||||
onRefreshSuggestions={vi.fn()}
|
||||
onSendDraft={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const hpStatus = screen.getByText('生命值 80 / 100');
|
||||
const summaryFallback = screen.getByText('你们还没有形成新的私下聊天总结。');
|
||||
const emptyHistory = screen.getByText(
|
||||
'这里会保留你和该角色的私下聊天记录。输入框支持自由发挥,上方三条文本可以帮你快速起句。',
|
||||
);
|
||||
const refreshButton = screen.getByRole('button', { name: '换一组' });
|
||||
const suggestionButton = screen.getByRole('button', { name: '先问问线索' });
|
||||
const draftTextarea = screen.getByPlaceholderText('对沈行说点什么...');
|
||||
|
||||
expect(hpStatus.className).toContain('border-white/10');
|
||||
expect(hpStatus.className).toContain('bg-black/25');
|
||||
expect(summaryFallback.className).toContain('border-white/10');
|
||||
expect(summaryFallback.className).toContain('bg-black/25');
|
||||
expect(emptyHistory.className).toContain('platform-empty-state');
|
||||
expect(emptyHistory.className).toContain('border-dashed');
|
||||
expect(refreshButton.className).toContain(
|
||||
'platform-action-button--editor-dark',
|
||||
);
|
||||
expect(refreshButton.className).toContain('text-[10px]');
|
||||
expect(suggestionButton.className).toContain('platform-dark-option-card');
|
||||
expect(suggestionButton.className).toContain('border-white/8');
|
||||
expect(draftTextarea.className).toContain('platform-text-field--editor-dark');
|
||||
expect(draftTextarea.className).toContain('focus:border-sky-300/35');
|
||||
});
|
||||
Reference in New Issue
Block a user