160 lines
4.3 KiB
TypeScript
160 lines
4.3 KiB
TypeScript
/**
|
||
* PRO 徽章集成测试
|
||
*
|
||
* 测试 PRO 徽章在 RestrictedToggle 中的存在性
|
||
*
|
||
* **Feature: free-version-ui-restrictions**
|
||
* **Property 2: 付费功能 PRO 徽章存在性**
|
||
* **Validates: Requirements 2.1, 2.2**
|
||
*
|
||
* @jest-environment jsdom
|
||
*/
|
||
|
||
import React from 'react'
|
||
import { render, screen } from '@testing-library/react'
|
||
import '@testing-library/jest-dom'
|
||
import RestrictedToggle from '../RestrictedToggle'
|
||
import type { FeatureKey } from '@/lib/license/types'
|
||
|
||
// Mock hooks
|
||
jest.mock('@/lib/ui-styles', () => ({
|
||
useTheme: jest.fn(() => 'light'),
|
||
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,
|
||
}))
|
||
|
||
/**
|
||
* Property 2: 付费功能 PRO 徽章存在性
|
||
* *For any* 需要 STANDARD 或 PRO 许可证的功能,UI 必须在功能标签旁显示 PRO 徽章
|
||
* **Feature: free-version-ui-restrictions, Property 2: PRO Badge Presence on Premium Features**
|
||
* **Validates: Requirements 2.1, 2.2**
|
||
*/
|
||
describe('Property 2: 付费功能 PRO 徽章存在性', () => {
|
||
const premiumFeatures: { key: FeatureKey; label: string }[] = [
|
||
{ key: 'customTemplates', label: '自定义模板' },
|
||
{ key: 'departmentIsolation', label: '部门隔离' },
|
||
{ key: 'intranetPenetration', label: '内网穿透' },
|
||
{ key: 'apiAccess', label: 'API 访问' },
|
||
{ key: 'systemSettings', label: '系统设置' },
|
||
]
|
||
|
||
premiumFeatures.forEach(({ key, label }) => {
|
||
it(`受限的 ${label} 功能应该显示 PRO 徽章`, () => {
|
||
render(
|
||
<RestrictedToggle
|
||
label={label}
|
||
featureKey={key}
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={true}
|
||
/>
|
||
)
|
||
|
||
// 应该显示 PRO 徽章
|
||
expect(screen.getByTestId('pro-badge')).toBeInTheDocument()
|
||
expect(screen.getByText('PRO')).toBeInTheDocument()
|
||
})
|
||
|
||
it(`不受限的 ${label} 功能不应该显示 PRO 徽章`, () => {
|
||
render(
|
||
<RestrictedToggle
|
||
label={label}
|
||
featureKey={key}
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={false}
|
||
/>
|
||
)
|
||
|
||
// 不应该显示 PRO 徽章
|
||
expect(screen.queryByTestId('pro-badge')).not.toBeInTheDocument()
|
||
})
|
||
})
|
||
|
||
it('PRO 徽章应该使用一致的视觉样式', () => {
|
||
const { rerender } = render(
|
||
<RestrictedToggle
|
||
label="功能1"
|
||
featureKey="customTemplates"
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={true}
|
||
/>
|
||
)
|
||
|
||
const badge1 = screen.getByTestId('pro-badge')
|
||
const badge1ClassName = badge1.className
|
||
|
||
rerender(
|
||
<RestrictedToggle
|
||
label="功能2"
|
||
featureKey="departmentIsolation"
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={true}
|
||
/>
|
||
)
|
||
|
||
const badge2 = screen.getByTestId('pro-badge')
|
||
const badge2ClassName = badge2.className
|
||
|
||
// 两个徽章应该有相同的样式类
|
||
expect(badge1ClassName).toBe(badge2ClassName)
|
||
})
|
||
|
||
it('PRO 徽章应该使用中性工作台样式', () => {
|
||
render(
|
||
<RestrictedToggle
|
||
label="测试功能"
|
||
featureKey="customTemplates"
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={true}
|
||
/>
|
||
)
|
||
|
||
const badge = screen.getByTestId('pro-badge')
|
||
expect(badge.className).toContain('bg-slate-100')
|
||
expect(badge.className).toContain('text-slate-700')
|
||
expect(badge.className).not.toContain('bg-gradient-to-r')
|
||
})
|
||
|
||
it('PRO 徽章应该包含 PRO 文字', () => {
|
||
render(
|
||
<RestrictedToggle
|
||
label="测试功能"
|
||
featureKey="customTemplates"
|
||
value={false}
|
||
onChange={() => {}}
|
||
isRestricted={true}
|
||
/>
|
||
)
|
||
|
||
expect(screen.getByText('PRO')).toBeInTheDocument()
|
||
})
|
||
})
|