Files
Genarrative/src/components/InventoryPanel.test.tsx
T
kdletters 01c0028b87 继续收口账号空态与运行态动作按钮
账号安全面板空态统一复用 PlatformEmptyState
登录入口不可用提示改为复用 PlatformEmptyState
RPG运行态底部与覆盖层动作统一委托 PlatformActionButton
背包工坊按钮回到共享 success tone
更新 PlatformUiKit 收口文档与团队决策记录
2026-06-11 02:03:41 +08:00

166 lines
5.4 KiB
TypeScript

/* @vitest-environment jsdom */
import { render, screen } from '@testing-library/react';
import { expect, test, vi } from 'vitest';
import type { RuntimeStoryForgeRecipeView } from '../../packages/shared/src/contracts/rpgRuntimeStoryState';
import { type Character, type InventoryItem, WorldType } from '../types';
import { InventoryPanel } from './InventoryPanel';
const inventoryItem: InventoryItem = {
id: 'training-token',
category: '材料',
name: '练习石',
quantity: 1,
rarity: 'common',
tags: [],
};
const documentItem: InventoryItem = {
id: 'thread-note',
category: '文书',
name: '潮汐证词',
quantity: 1,
rarity: 'common',
tags: ['document'],
description: '记录着潮汐线索。',
};
const forgeRecipe: RuntimeStoryForgeRecipeView = {
id: 'forge-tide-amulet',
name: '潮汐护符',
kind: 'forge',
description: '用于测试工坊需求状态。',
resultLabel: '潮汐护符',
currencyCost: 5,
currencyText: '5 贝币',
requirements: [
{
id: 'iron',
label: '铁矿',
quantity: 2,
owned: 2,
},
{
id: 'wood',
label: '木材',
quantity: 1,
owned: 0,
},
],
canCraft: false,
disabledReason: '材料不足',
action: {
functionId: 'craft',
actionText: '锻造',
enabled: false,
reason: '材料不足',
},
};
test('背包工坊材料需求状态复用暗色平台胶囊标签', () => {
render(
<InventoryPanel
playerCharacter={{} as Character}
worldType={WorldType.CUSTOM}
playerInventory={[inventoryItem]}
playerCurrency={0}
playerHp={10}
playerMaxHp={10}
playerMana={5}
playerMaxMana={5}
inBattle={false}
forgeRecipes={[forgeRecipe]}
onUseItem={vi.fn(async () => false)}
onEquipItem={vi.fn(async () => false)}
onCraftRecipe={vi.fn(async () => false)}
onDismantleItem={vi.fn(async () => false)}
onReforgeItem={vi.fn(async () => false)}
/>,
);
const metRequirement = screen.getByText('铁矿 2/2');
const missingRequirement = screen.getByText('木材 0/1');
const forgePanel = screen.getByText('工坊').closest('section');
const recipePanel = screen.getByText('潮汐护符').closest('section');
const forgeButton = screen.getByRole('button', { name: '锻造' });
expect(metRequirement.className).toContain('rounded-full');
expect(metRequirement.className).toContain('font-black');
expect(metRequirement.className).toContain('bg-emerald-500/10');
expect(missingRequirement.className).toContain('rounded-full');
expect(missingRequirement.className).toContain('font-black');
expect(missingRequirement.className).toContain('bg-black/20');
expect(missingRequirement.className).toContain('text-zinc-400');
expect(forgePanel?.className).toContain('border-white/10');
expect(forgePanel?.className).toContain('bg-black/25');
expect(recipePanel?.className).toContain('border-white/10');
expect(recipePanel?.className).toContain('bg-black/25');
expect(forgeButton.className).toContain('platform-action-button--editor-dark');
expect(forgeButton.className).toContain('rounded-lg');
expect(forgeButton.className).toContain('bg-emerald-400');
expect(forgeButton.className).toContain('disabled:bg-black/20');
});
test('背包文书和故事档案区块复用暗色 PlatformSubpanel chrome', () => {
render(
<InventoryPanel
playerCharacter={{} as Character}
worldType={WorldType.CUSTOM}
playerInventory={[documentItem]}
playerCurrency={0}
playerHp={10}
playerMaxHp={10}
playerMana={5}
playerMaxMana={5}
inBattle={false}
forgeRecipes={[]}
narrativeQaReport={{
generatedAt: '2026-06-10T00:00:00.000Z',
issues: [],
summary: '叙事链路稳定。',
}}
narrativeCodex={[
{
id: 'codex-tide',
title: '潮汐档案',
entries: [
{
id: 'entry-tide',
title: '旧港线索',
summary: '证词指向旧港。',
category: 'document',
relatedIds: [],
},
],
},
]}
onUseItem={vi.fn(async () => false)}
onEquipItem={vi.fn(async () => false)}
onCraftRecipe={vi.fn(async () => false)}
onDismantleItem={vi.fn(async () => false)}
onReforgeItem={vi.fn(async () => false)}
/>,
);
const documentPanel = screen.getByText('文书与证据').closest('section');
const documentButton = screen.getByRole('button', {
name: /潮汐证词/,
});
const storyPanel = screen.getByText('故事档案').closest('section');
const qaMessage = screen.getByText('QA:叙事链路稳定。');
const codexPanel = screen.getByText('潮汐档案').closest('section');
expect(documentPanel?.className).toContain('border-white/10');
expect(documentPanel?.className).toContain('bg-black/25');
expect(documentButton.className).toContain('border-white/10');
expect(documentButton.className).toContain('bg-black/25');
expect(storyPanel?.className).toContain('border-white/10');
expect(storyPanel?.className).toContain('bg-black/25');
expect(qaMessage.className).toContain('platform-status-message');
expect(qaMessage.className).toContain('border-amber-300/15');
expect(qaMessage.className).toContain('bg-amber-500/10');
expect(codexPanel?.className).toContain('border-white/10');
expect(codexPanel?.className).toContain('bg-black/25');
});