UserFormPage.test.tsx
3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { describe, it, expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import { ConfigProvider } from 'antd';
import { configureStore } from '@reduxjs/toolkit';
import authReducer, { setSession } from '../../store/slices/authSlice';
import UserFormPage from './UserFormPage';
function makeStore() {
const store = configureStore({ reducer: { auth: authReducer } });
store.dispatch(
setSession({
accessToken: 'jwt',
userInfo: {
userId: 2,
username: 'admin',
userType: 'SUPER_ADMIN',
language: 'zh-CN',
companyCode: 'HQ',
},
}),
);
return store;
}
function renderForm(mode: 'create' | 'edit', initialEntry: string) {
return render(
<Provider store={makeStore()}>
<ConfigProvider>
<MemoryRouter initialEntries={[initialEntry]}>
<Routes>
<Route path="/users" element={<div data-testid="users-list">LIST</div>} />
<Route path="/users/new" element={<UserFormPage mode={mode} />} />
<Route path="/users/:userId" element={<UserFormPage mode={mode} />} />
</Routes>
</MemoryRouter>
</ConfigProvider>
</Provider>,
);
}
describe('UserFormPage (create)', () => {
it('renders empty form with username editable', () => {
renderForm('create', '/users/new');
const usernameInput = screen.getByLabelText('用户名') as HTMLInputElement;
expect(usernameInput).not.toBeDisabled();
});
it('cancel button navigates back to /users', async () => {
renderForm('create', '/users/new');
const user = userEvent.setup();
await user.click(screen.getByTestId('form-cancel'));
expect(await screen.findByTestId('users-list')).toBeInTheDocument();
});
it('submit valid form navigates to /users', async () => {
renderForm('create', '/users/new');
const user = userEvent.setup();
await user.type(screen.getByLabelText('用户名'), 'newbie');
await user.type(screen.getByLabelText('用户号'), 'U999');
await user.click(screen.getByTestId('form-save'));
expect(await screen.findByTestId('users-list', {}, { timeout: 3000 })).toBeInTheDocument();
});
it('duplicate username (40901) shows field-level error', async () => {
renderForm('create', '/users/new');
const user = userEvent.setup();
await user.type(screen.getByLabelText('用户名'), 'dup');
await user.type(screen.getByLabelText('用户号'), 'U999');
await user.click(screen.getByTestId('form-save'));
await waitFor(() => expect(screen.getByText('用户名已存在')).toBeInTheDocument());
});
});
describe('UserFormPage (edit)', () => {
it('fetches detail and prefills form with username readonly', async () => {
renderForm('edit', '/users/1');
await waitFor(() => {
const usernameInput = screen.getByLabelText('用户名') as HTMLInputElement;
expect(usernameInput.value).toBe('alice');
expect(usernameInput).toBeDisabled();
});
});
it('prefills canEditDocument from backend (not hardcoded false)', async () => {
renderForm('edit', '/users/1');
// backend mock 返回 canEditDocument=true;UI 应反映为 checkbox.checked=true
await waitFor(() => {
const checkbox = document.querySelector('input[type="checkbox"]') as HTMLInputElement;
expect(checkbox?.checked).toBe(true);
});
});
it('unknown userId (40401) shows 404 result', async () => {
renderForm('edit', '/users/99999');
await waitFor(() => expect(screen.getByTestId('user-not-found')).toBeInTheDocument());
});
});