/** * UpgradeModal 组件单元测试 * * 测试 UpgradeModal 组件的功能名称显示和交互行为 * * **Feature: free-version-ui-restrictions** * **Property 5: UpgradeModal 功能名称显示** * **Validates: Requirements 1.2, 3.2, 3.3, 3.4** * * @jest-environment jsdom */ import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import UpgradeModal from '../UpgradeModal' import type { FeatureKey } from '@/lib/license/types' import { FEATURE_DESCRIPTIONS } from '@/lib/license/feature-descriptions' // Mock useThemeStyles hook jest.mock('@/lib/ui-styles', () => ({ useThemeStyles: jest.fn(() => ({ buttonStyles: { secondary: 'mock-secondary-button', }, modalStyles: { overlay: 'mock-overlay', container: 'mock-container', content: 'mock-content', header: 'mock-header', title: 'mock-title', closeButton: 'mock-close-button', body: 'mock-body', footer: 'mock-footer', sizes: { small: 'mock-small', }, }, })), cn: (...classes: (string | boolean | undefined)[]) => classes.filter(Boolean).join(' '), })) // Mock createPortal jest.mock('react-dom', () => ({ ...jest.requireActual('react-dom'), createPortal: (node: React.ReactNode) => node, })) describe('UpgradeModal 组件', () => { const mockOnClose = jest.fn() beforeEach(() => { mockOnClose.mockClear() }) describe('基础渲染', () => { it('当 isOpen 为 true 时应该渲染弹窗', () => { render( ) expect(screen.getByTestId('upgrade-modal')).toBeInTheDocument() }) it('当 isOpen 为 false 时不应该渲染弹窗', () => { render( ) expect(screen.queryByTestId('upgrade-modal')).not.toBeInTheDocument() }) }) /** * Property 5: UpgradeModal 功能名称显示 * *For any* 传递给 UpgradeModal 的功能名称,弹窗必须在其内容中显示该功能名称 * **Feature: free-version-ui-restrictions, Property 5: UpgradeModal Feature Name Display** * **Validates: Requirements 1.2, 3.2** */ describe('Property 5: UpgradeModal 功能名称显示', () => { const featureKeys: FeatureKey[] = [ 'customTemplates', 'systemSettings', 'departmentIsolation', 'apiAccess', 'intranetPenetration', ] featureKeys.forEach((featureKey) => { it(`应该显示 ${featureKey} 的功能名称`, () => { render( ) const expectedName = FEATURE_DESCRIPTIONS[featureKey].name expect(screen.getByTestId('upgrade-modal-feature-name')).toHaveTextContent(expectedName) }) }) it('应该允许自定义功能名称覆盖默认值', () => { const customName = '自定义功能名称' render( ) expect(screen.getByTestId('upgrade-modal-feature-name')).toHaveTextContent(customName) }) it('应该显示功能描述', () => { render( ) const expectedDescription = FEATURE_DESCRIPTIONS.customTemplates.description expect(screen.getByText(expectedDescription)).toBeInTheDocument() }) it('应该允许自定义功能描述覆盖默认值', () => { const customDescription = '自定义功能描述' render( ) expect(screen.getByText(customDescription)).toBeInTheDocument() }) }) describe('限制提示显示', () => { it('应该显示当前许可证限制提示', () => { render( ) expect(screen.getByText('当前许可证未包含此功能,请联系管理员处理授权')).toBeInTheDocument() }) }) describe('按钮交互', () => { it('点击"关闭"按钮应该调用 onClose', () => { render( ) fireEvent.click(screen.getByText('关闭')) expect(mockOnClose).toHaveBeenCalledTimes(1) }) it('点击"联系管理员"按钮应该调用 onClose', () => { render( ) fireEvent.click(screen.getByText('联系管理员')) expect(mockOnClose).toHaveBeenCalledTimes(1) }) it('应该显示两个按钮', () => { render( ) expect(screen.getByText('关闭')).toBeInTheDocument() expect(screen.getByText('联系管理员')).toBeInTheDocument() }) }) describe('视觉元素', () => { it('应该显示锁图标', () => { render( ) // 检查 SVG 图标存在 const modal = screen.getByTestId('upgrade-modal') const svgElements = modal.querySelectorAll('svg') expect(svgElements.length).toBeGreaterThan(0) }) it('应该显示限制说明文字', () => { render( ) expect(screen.getByText('当前许可证未包含此功能,请联系管理员处理授权')).toBeInTheDocument() }) }) })