import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { UserManagement } from '../../src/components/UserManagement';
// Mock API client
vi.mock('../../src/api/userClient', () => ({
userClient: {
$get: vi.fn(),
$post: vi.fn(),
':id': {
$put: vi.fn(),
$delete: vi.fn(),
},
},
}));
// Mock toast
vi.mock('sonner', () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
},
}));
const createTestQueryClient = () =>
new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});
const renderWithProviders = (component: React.ReactElement) => {
const queryClient = createTestQueryClient();
return render(
{component}
);
};
describe('UserManagement', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should render user management page', () => {
renderWithProviders();
expect(screen.getByText('用户管理')).toBeInTheDocument();
expect(screen.getByText('创建用户')).toBeInTheDocument();
});
it('should display user list when data is loaded', async () => {
const mockUsers = {
data: [
{
id: 1,
username: 'testuser',
nickname: 'Test User',
email: 'test@example.com',
phone: '1234567890',
name: 'Test Name',
isDisabled: 0,
createdAt: '2024-01-01T00:00:00Z',
roles: [{ id: 1, name: 'admin' }],
avatarFile: null,
},
],
pagination: {
total: 1,
page: 1,
pageSize: 10,
},
};
const { userClient } = await import('../../src/api/userClient');
(userClient.$get as any).mockResolvedValue({
status: 200,
json: async () => mockUsers,
});
renderWithProviders();
await waitFor(() => {
expect(screen.getByText('testuser')).toBeInTheDocument();
expect(screen.getByText('Test User')).toBeInTheDocument();
expect(screen.getByText('test@example.com')).toBeInTheDocument();
});
});
it('should open create user modal when create button is clicked', () => {
renderWithProviders();
const createButton = screen.getByText('创建用户');
fireEvent.click(createButton);
expect(screen.getByText('创建用户')).toBeInTheDocument();
expect(screen.getByPlaceholderText('请输入用户名')).toBeInTheDocument();
});
it('should handle search functionality', async () => {
const { userClient } = await import('../../src/api/userClient');
(userClient.$get as any).mockResolvedValue({
status: 200,
json: async () => ({
data: [],
pagination: { total: 0, page: 1, pageSize: 10 },
}),
});
renderWithProviders();
const searchInput = screen.getByPlaceholderText('搜索用户名、昵称或邮箱...');
fireEvent.change(searchInput, { target: { value: 'test' } });
await waitFor(() => {
expect(userClient.$get).toHaveBeenCalledWith({
query: {
page: 1,
pageSize: 10,
keyword: 'test',
filters: undefined,
},
});
});
});
it('should handle filter functionality', async () => {
const { userClient } = await import('../../src/api/userClient');
(userClient.$get as any).mockResolvedValue({
status: 200,
json: async () => ({
data: [],
pagination: { total: 0, page: 1, pageSize: 10 },
}),
});
renderWithProviders();
// Open filters
const filterButton = screen.getByText('高级筛选');
fireEvent.click(filterButton);
// Select status filter
const statusSelect = screen.getByText('选择状态');
fireEvent.click(statusSelect);
const enabledOption = screen.getByText('启用');
fireEvent.click(enabledOption);
await waitFor(() => {
expect(userClient.$get).toHaveBeenCalledWith({
query: {
page: 1,
pageSize: 10,
keyword: '',
filters: expect.any(String),
},
});
});
});
});