import { describe, it, expect, vi, beforeEach } from 'vitest' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { Provider } from 'react-redux' import { MemoryRouter, Routes, Route } from 'react-router-dom' import { configureStore } from '@reduxjs/toolkit' import authReducer from '../store/slices/authSlice' import tabsReducer from '../store/slices/tabsSlice' import UserDetailPage from '../pages/usr/UserDetailPage' vi.mock('../api/usr', () => ({ getStaffs: vi.fn().mockResolvedValue([{ sId: 's1', sStaffName: '张三' }]), getPermissionGroups: vi.fn().mockResolvedValue([{ sId: 'pg1', sGroupCode: 'usr:create', sGroupName: '新增用户', sCategory: '用户管理' }]), createUser: vi.fn().mockResolvedValue({ userId: 'u2', userCode: 'UC002', username: 'bob' }), updateUser: vi.fn().mockResolvedValue({ userId: 'u1', username: 'alice', updatedAt: '2026-05-08T10:00:00' }), getUserList: vi.fn().mockResolvedValue({ total: 0, page: 1, pageSize: 20, list: [] }), })) vi.mock('../api/request', () => ({ default: { get: vi.fn(), post: vi.fn(), put: vi.fn() }, })) function makeStore() { const store = configureStore({ reducer: { auth: authReducer, tabs: tabsReducer } }) store.dispatch({ type: 'auth/setCredentials', payload: { accessToken: 'tok', refreshToken: 'ref', userInfo: { userId: 'u0', username: 'admin', userType: '超级管理员', language: '中文', brandId: 'b1' } }, }) return store } const rowData = { sId: 'u1', sUsername: 'alice', sUserCode: 'UC001', sUserType: '普通用户', sLanguage: '中文', bCanEditDoc: 0, bIsDisabled: 0, tLastLoginDate: null, sCreatorUsername: 'admin', tCreateDate: '2026-01-01 00:00:00', sStaffName: null, sDepartment: null, } function renderNew() { return render( } /> UserList} /> ) } function renderEdit(state = rowData) { return render( } /> UserList} /> ) } describe('UserDetailPage', () => { beforeEach(() => { vi.clearAllMocks() }) it('newMode_showsSaveButton', () => { renderNew() expect(screen.getByRole('button', { name: /保存/ })).toBeInTheDocument() }) it('newMode_showsPermissionGroupTab', async () => { renderNew() await waitFor(() => expect(screen.getByText('新增用户')).toBeInTheDocument()) }) it('editMode_showsUsernameReadonly', async () => { renderEdit() await waitFor(() => expect(screen.getByText('alice')).toBeInTheDocument()) }) it('editMode_noState_redirectsToList', async () => { render( } /> UserList} /> ) await waitFor(() => expect(screen.getByText('UserList')).toBeInTheDocument()) }) it('newMode_save_callsCreateUser', async () => { const { createUser } = await import('../api/usr') renderNew() await userEvent.type(screen.getByPlaceholderText('请输入用户号'), 'UC002') await userEvent.type(screen.getByPlaceholderText('请输入用户名'), 'bob') await userEvent.click(screen.getByRole('button', { name: /保存/ })) await waitFor(() => expect(vi.mocked(createUser)).toHaveBeenCalledWith( expect.objectContaining({ userCode: 'UC002', username: 'bob' }) )) }) it('editMode_save_callsUpdateUser', async () => { const { updateUser } = await import('../api/usr') renderEdit() await waitFor(() => expect(screen.getByText('alice')).toBeInTheDocument()) await userEvent.click(screen.getByRole('button', { name: /保存/ })) await waitFor(() => expect(vi.mocked(updateUser)).toHaveBeenCalledWith( 'u1', expect.objectContaining({ userType: '普通用户' }) )) }) it('permCheckbox_togglesSelection', async () => { renderNew() await waitFor(() => expect(screen.getByText('新增用户')).toBeInTheDocument()) const cb = screen.getByRole('checkbox') expect(cb).not.toBeChecked() await userEvent.click(cb) expect(cb).toBeChecked() await userEvent.click(cb) expect(cb).not.toBeChecked() }) it('cancelButton_navigatesToList', async () => { renderNew() await userEvent.click(screen.getByRole('button', { name: /取消/ })) await waitFor(() => expect(screen.getByText('UserList')).toBeInTheDocument()) }) })