flnxi-Wu/app/activate/__tests__/page.test.tsx
WuYongJie ba98bf22cc feat: 添加许可证系统、Agent部署模块和Harbor镜像管理
- 新增许可证服务器 (license-server/)
- 新增 Agent 部署模块 (flnxi-agent/)
- 添加许可证验证和激活页面
- 添加 Harbor 镜像同步脚本
- 更新素材系统支持许可证验证
2025-12-15 21:19:46 +08:00

245 lines
7.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @jest-environment jsdom
*/
/**
* 激活页面测试
* 测试许可证激活和免费试用功能
*/
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
import ActivatePage from '../page';
// Mock next/navigation
const mockPush = jest.fn();
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: mockPush,
}),
}));
// Mock fetch
global.fetch = jest.fn();
describe('ActivatePage', () => {
beforeEach(() => {
jest.clearAllMocks();
(global.fetch as jest.Mock).mockReset();
});
describe('渲染测试', () => {
it('应该正确渲染页面标题和表单', () => {
render(<ActivatePage />);
expect(screen.getByText('FLNXI 素材系统')).toBeInTheDocument();
expect(screen.getByText('请激活您的许可证')).toBeInTheDocument();
expect(screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX')).toBeInTheDocument();
expect(screen.getByText('激活许可证')).toBeInTheDocument();
expect(screen.getByText('免费试用')).toBeInTheDocument();
});
it('应该显示免费版限制说明', () => {
render(<ActivatePage />);
expect(screen.getByText('免费版限制:10 个用户、100 个素材')).toBeInTheDocument();
});
it('应该显示联系信息', () => {
render(<ActivatePage />);
expect(screen.getByText('需要购买许可证?请联系我们')).toBeInTheDocument();
});
});
describe('许可证密钥格式化', () => {
it('应该自动将输入转换为大写', () => {
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX') as HTMLInputElement;
fireEvent.change(input, { target: { value: 'abcd' } });
expect(input.value).toBe('ABCD');
});
it('应该自动添加横杠分隔符', () => {
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX') as HTMLInputElement;
fireEvent.change(input, { target: { value: 'abcd1234' } });
expect(input.value).toBe('ABCD-1234');
});
it('应该过滤非字母数字字符', () => {
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX') as HTMLInputElement;
fireEvent.change(input, { target: { value: 'ab!@#cd12' } });
expect(input.value).toBe('ABCD-12');
});
it('应该限制最大长度为19个字符(含横杠)', () => {
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX') as HTMLInputElement;
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678EXTRA' } });
expect(input.value).toBe('ABCD-1234-EFGH-5678');
});
});
describe('激活按钮状态', () => {
it('密钥不完整时激活按钮应该禁用', () => {
render(<ActivatePage />);
const button = screen.getByText('激活许可证');
expect(button).toBeDisabled();
});
it('密钥完整时激活按钮应该启用', () => {
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
expect(button).not.toBeDisabled();
});
});
describe('许可证激活', () => {
it('激活成功后应该跳转到首页', async () => {
(global.fetch as jest.Mock).mockResolvedValueOnce({
json: () => Promise.resolve({ success: true }),
});
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(mockPush).toHaveBeenCalledWith('/');
});
});
it('激活失败应该显示错误信息', async () => {
(global.fetch as jest.Mock).mockResolvedValueOnce({
json: () => Promise.resolve({ success: false, error: '许可证无效' }),
});
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(screen.getByText('许可证无效')).toBeInTheDocument();
});
});
it('网络错误应该显示网络错误提示', async () => {
(global.fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'));
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(screen.getByText('网络错误,请检查网络连接')).toBeInTheDocument();
});
});
it('激活时应该显示加载状态', async () => {
let resolvePromise: (value: unknown) => void;
(global.fetch as jest.Mock).mockImplementation(() =>
new Promise(resolve => { resolvePromise = resolve; })
);
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
await act(async () => {
fireEvent.click(button);
});
expect(screen.getByText('激活中...')).toBeInTheDocument();
// 清理
await act(async () => {
resolvePromise!({ json: () => Promise.resolve({ success: true }) });
});
});
});
describe('免费试用', () => {
it('免费试用成功后应该跳转到首页', async () => {
(global.fetch as jest.Mock).mockResolvedValueOnce({
json: () => Promise.resolve({ success: true }),
});
render(<ActivatePage />);
const button = screen.getByText('免费试用');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(mockPush).toHaveBeenCalledWith('/');
});
expect(global.fetch).toHaveBeenCalledWith('/api/license/activate-free', {
method: 'POST',
});
});
it('免费试用失败应该显示错误信息', async () => {
(global.fetch as jest.Mock).mockResolvedValueOnce({
json: () => Promise.resolve({ success: false, error: '试用已过期' }),
});
render(<ActivatePage />);
const button = screen.getByText('免费试用');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(screen.getByText('试用已过期')).toBeInTheDocument();
});
});
});
describe('API 调用', () => {
it('激活时应该发送正确的请求', async () => {
(global.fetch as jest.Mock).mockResolvedValueOnce({
json: () => Promise.resolve({ success: true }),
});
render(<ActivatePage />);
const input = screen.getByPlaceholderText('XXXX-XXXX-XXXX-XXXX');
fireEvent.change(input, { target: { value: 'ABCD1234EFGH5678' } });
const button = screen.getByText('激活许可证');
await act(async () => {
fireEvent.click(button);
});
await waitFor(() => {
expect(global.fetch).toHaveBeenCalledWith('/api/license/activate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ licenseKey: 'ABCD-1234-EFGH-5678' }),
});
});
});
});
});