| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- 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(
- <QueryClientProvider client={queryClient}>
- {component}
- </QueryClientProvider>
- );
- };
- describe('UserManagement Integration Tests', () => {
- beforeEach(() => {
- vi.clearAllMocks();
- });
- it('should complete full user CRUD flow', async () => {
- const mockUsers = {
- data: [
- {
- id: 1,
- username: 'existinguser',
- nickname: 'Existing User',
- email: 'existing@example.com',
- phone: '1234567890',
- name: 'Existing 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');
- const { toast } = await import('sonner');
- // Mock initial user list
- (userClient.$get as any).mockResolvedValue({
- status: 200,
- json: async () => mockUsers,
- });
- renderWithProviders(<UserManagement />);
- // Wait for initial data to load
- await waitFor(() => {
- expect(screen.getByText('existinguser')).toBeInTheDocument();
- });
- // Test create user
- const createButton = screen.getByText('创建用户');
- fireEvent.click(createButton);
- // Fill create form
- const usernameInput = screen.getByPlaceholderText('请输入用户名');
- const passwordInput = screen.getByPlaceholderText('请输入密码');
- const emailInput = screen.getByPlaceholderText('请输入邮箱');
- fireEvent.change(usernameInput, { target: { value: 'newuser' } });
- fireEvent.change(passwordInput, { target: { value: 'password123' } });
- fireEvent.change(emailInput, { target: { value: 'new@example.com' } });
- // Mock successful creation
- (userClient.$post as any).mockResolvedValue({
- status: 201,
- });
- const submitButton = screen.getByText('创建用户');
- fireEvent.click(submitButton);
- await waitFor(() => {
- expect(userClient.$post).toHaveBeenCalledWith({
- json: {
- username: 'newuser',
- password: 'password123',
- email: 'new@example.com',
- nickname: undefined,
- phone: null,
- name: null,
- isDisabled: 0,
- },
- });
- expect(toast.success).toHaveBeenCalledWith('用户创建成功');
- });
- // Test edit user
- const editButtons = screen.getAllByRole('button', { name: /edit/i });
- fireEvent.click(editButtons[0]);
- // Verify edit form is populated
- await waitFor(() => {
- expect(screen.getByDisplayValue('existinguser')).toBeInTheDocument();
- });
- // Update user
- const updateUsernameInput = screen.getByDisplayValue('existinguser');
- fireEvent.change(updateUsernameInput, { target: { value: 'updateduser' } });
- // Mock successful update
- (userClient[':id']['$put'] as any).mockResolvedValue({
- status: 200,
- });
- const updateButton = screen.getByText('更新用户');
- fireEvent.click(updateButton);
- await waitFor(() => {
- expect(userClient[':id']['$put']).toHaveBeenCalledWith({
- param: { id: 1 },
- json: {
- username: 'updateduser',
- nickname: 'Existing User',
- email: 'existing@example.com',
- phone: '1234567890',
- name: 'Existing Name',
- password: undefined,
- avatarFileId: null,
- isDisabled: 0,
- },
- });
- expect(toast.success).toHaveBeenCalledWith('用户更新成功');
- });
- // Test delete user
- const deleteButtons = screen.getAllByRole('button', { name: /trash/i });
- fireEvent.click(deleteButtons[0]);
- // Confirm deletion
- expect(screen.getByText('确认删除')).toBeInTheDocument();
- // Mock successful deletion
- (userClient[':id']['$delete'] as any).mockResolvedValue({
- status: 204,
- });
- const confirmDeleteButton = screen.getByText('删除');
- fireEvent.click(confirmDeleteButton);
- await waitFor(() => {
- expect(userClient[':id']['$delete']).toHaveBeenCalledWith({
- param: { id: 1 },
- });
- expect(toast.success).toHaveBeenCalledWith('用户删除成功');
- });
- });
- it('should handle API errors gracefully', async () => {
- const { userClient } = await import('../../src/api/userClient');
- const { toast } = await import('sonner');
- // Mock API error
- (userClient.$get as any).mockRejectedValue(new Error('API Error'));
- renderWithProviders(<UserManagement />);
- // Should handle error without crashing
- await waitFor(() => {
- expect(screen.getByText('用户管理')).toBeInTheDocument();
- });
- // Test create user error
- const createButton = screen.getByText('创建用户');
- fireEvent.click(createButton);
- const usernameInput = screen.getByPlaceholderText('请输入用户名');
- const passwordInput = screen.getByPlaceholderText('请输入密码');
- fireEvent.change(usernameInput, { target: { value: 'testuser' } });
- fireEvent.change(passwordInput, { target: { value: 'password' } });
- // Mock creation error
- (userClient.$post as any).mockRejectedValue(new Error('Creation failed'));
- const submitButton = screen.getByText('创建用户');
- fireEvent.click(submitButton);
- await waitFor(() => {
- expect(toast.error).toHaveBeenCalledWith('创建失败,请重试');
- });
- });
- it('should handle search and filter integration', async () => {
- const { userClient } = await import('../../src/api/userClient');
- const mockUsers = {
- data: [],
- pagination: { total: 0, page: 1, pageSize: 10 },
- };
- (userClient.$get as any).mockResolvedValue({
- status: 200,
- json: async () => mockUsers,
- });
- renderWithProviders(<UserManagement />);
- // Test search
- const searchInput = screen.getByPlaceholderText('搜索用户名、昵称或邮箱...');
- fireEvent.change(searchInput, { target: { value: 'searchterm' } });
- await waitFor(() => {
- expect(userClient.$get).toHaveBeenCalledWith({
- query: {
- page: 1,
- pageSize: 10,
- keyword: 'searchterm',
- filters: undefined,
- },
- });
- });
- // Test filter
- const filterButton = screen.getByText('高级筛选');
- fireEvent.click(filterButton);
- // Apply 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: 'searchterm',
- filters: expect.stringContaining('isDisabled'),
- },
- });
- });
- });
- });
|