/* @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 { getCharacterById } from '../data/characterPresets'; import type { CompanionState } from '../types'; import { CompanionCampModal } from './CompanionCampModal'; function createCompanion( overrides: Partial = {}, ): CompanionState { return { npcId: 'npc-archer', characterId: 'archer-hero', joinedAtAffinity: 36, hp: 42, maxHp: 50, mana: 18, maxMana: 24, skillCooldowns: {}, ...overrides, }; } test('营地编组战斗中提示复用暗色 PlatformStatusMessage chrome', () => { render( , ); const warning = screen.getByText('战斗中无法调整编组。'); expect(warning.className).toContain('platform-status-message'); expect(warning.className).toContain('border-amber-300/15'); expect(warning.className).toContain('bg-amber-500/10'); expect(warning.className).toContain('mb-3'); const currentSection = screen.getByText('当前队伍').closest('section'); const reserveSection = screen.getByText('后备队伍').closest('section'); const activeEmptyState = screen.getByText('当前没有已出战的同行者。'); const reserveEmptyState = screen.getByText('当前还没有后备同行者。'); const activeCountBadge = screen.getByText(/^出战 0\//); const campFooter = screen.getByText('营地气氛').closest( '.platform-dark-modal-footer', ); expect(currentSection?.className).toContain('bg-black/25'); expect(reserveSection?.className).toContain('bg-black/25'); expect(activeEmptyState.className).toContain('platform-empty-state'); expect(reserveEmptyState.className).toContain('platform-empty-state'); expect(activeCountBadge.className).toContain('rounded-full'); expect(activeCountBadge.className).toContain('bg-black/20'); expect(campFooter?.className).toContain('border-t'); expect(campFooter?.className).toContain('px-5'); }); test('营地编组同行者卡片和替换位按钮复用暗色公共组件', async () => { const user = userEvent.setup(); const playerCharacter = getCharacterById('sword-princess'); if (!playerCharacter) { throw new Error('测试需要剑姬角色预设'); } render( , ); const activeCard = screen.getByTestId('active-companion-card-npc-archer'); const reserveCard = screen.getByTestId('reserve-companion-card-npc-girl'); const replacementButton = screen.getByRole('button', { name: '设为替换位', }); const benchButton = screen.getByRole('button', { name: '转入后备' }); const activateButton = screen.getByRole('button', { name: '编入队伍' }); const hpBadge = within(activeCard).getByText('生命 42/50'); const activePortrait = within(activeCard).getByRole('img'); const reservePortrait = within(reserveCard).getByRole('img'); const activePortraitFrame = activePortrait.closest('.platform-media-frame'); const reservePortraitFrame = reservePortrait.closest('.platform-media-frame'); expect(activeCard.className).toContain('bg-black/25'); expect(reserveCard.className).toContain('bg-black/25'); expect(activePortraitFrame?.className).toContain('border-white/10'); expect(activePortraitFrame?.className).toContain('radial-gradient'); expect(reservePortraitFrame?.className).toContain('platform-media-frame'); expect(activePortrait.className).toContain('scale-125'); expect(replacementButton.className).toContain('platform-dark-option-card'); expect(benchButton.className).toContain( 'platform-action-button--editor-dark', ); expect(benchButton.className).toContain('bg-white/5'); expect(activateButton.className).toContain( 'platform-action-button--editor-dark', ); expect(activateButton.className).toContain('bg-emerald-400'); expect(hpBadge.className).toContain('rounded-full'); await user.click(replacementButton); expect(activeCard.className).toContain('border-sky-400/18'); expect(activeCard.className).toContain('bg-sky-500/8'); expect(replacementButton.className).toContain('border-sky-400/45'); });