UserBasicForm.test.tsx
5.88 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// REQ-USR-001 / REQ-USR-002: UserBasicForm 表单网格单测(字段/默认/只读/枚举/必填+格式/员工联动,BR1-BR9)
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Form } from 'antd';
import { renderShell } from './renderShell';
import UserBasicForm from '../../src/pages/usr/UserDetail/UserBasicForm';
import { CREATE_DEFAULTS, type UserFormValues } from '../../src/pages/usr/UserDetail/constants';
import type { EmployeeOption } from '../../src/api/types';
const EMPLOYEES: EmployeeOption[] = [
{ value: 3, label: '张三', sEmployeeNo: 'zs' },
{ value: 4, label: '李四', sEmployeeNo: 'ls' },
];
interface HarnessProps {
mode?: 'create' | 'edit';
initialValues?: Partial<UserFormValues>;
onSelectEmployee?: (v: number | null) => void;
readonlyCreator?: string;
exposeSubmit?: (submit: () => void) => void;
}
function Harness({
mode = 'create',
initialValues,
onSelectEmployee = () => {},
readonlyCreator,
exposeSubmit,
}: HarnessProps) {
const [form] = Form.useForm<UserFormValues>();
exposeSubmit?.(() => form.submit());
return (
<Form
form={form}
initialValues={{ ...CREATE_DEFAULTS, ...initialValues }}
onFinish={() => {}}
>
<UserBasicForm
form={form}
mode={mode}
employees={EMPLOYEES}
readonlyCreator={readonlyCreator}
onSelectEmployee={onSelectEmployee}
/>
</Form>
);
}
function setup(props: HarnessProps = {}) {
let submit = () => {};
renderShell(
<Harness {...props} exposeSubmit={(s) => { submit = s; }} />,
{ preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } },
);
return { triggerSubmit: () => submit() };
}
describe('UserBasicForm', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('renders 8 labeled fields', () => {
setup();
expect(screen.getByText('创建时间')).toBeInTheDocument();
expect(screen.getByText('制单人')).toBeInTheDocument();
expect(screen.getByText('员工名')).toBeInTheDocument();
expect(screen.getByText('用户名')).toBeInTheDocument();
expect(screen.getByText('类型')).toBeInTheDocument();
expect(screen.getByText('语言')).toBeInTheDocument();
expect(screen.getByText('用户号')).toBeInTheDocument();
expect(screen.getByText('单据修改权限')).toBeInTheDocument();
});
it('create mode username editable; edit mode username disabled', () => {
const { unmount } = renderShell(
<Harness mode="create" />,
{ preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } },
);
expect(screen.getByTestId('field-username')).not.toBeDisabled();
unmount();
renderShell(
<Harness mode="edit" initialValues={{ sUserName: 'zhangsan' }} />,
{ preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } },
);
expect(screen.getByTestId('field-username')).toBeDisabled();
});
it('create mode defaults usertype 普通用户', () => {
setup({ mode: 'create' });
expect(within(screen.getByTestId('select-usertype')).getByText('普通用户')).toBeInTheDocument();
});
it('username format rule rejects short/invalid and required when empty', async () => {
const user = userEvent.setup();
const { triggerSubmit } = setup({ mode: 'create' });
const input = screen.getByTestId('field-username') as HTMLInputElement;
await user.type(input, 'ab');
triggerSubmit();
expect(await screen.findByText('用户名须为 3-20 位字母数字下划线')).toBeInTheDocument();
await user.clear(input);
triggerSubmit();
expect(await screen.findByText('请输入用户名')).toBeInTheDocument();
});
it('userno required', async () => {
const { triggerSubmit } = setup({ mode: 'create', initialValues: { sUserName: 'zhangsan', sUserNo: '' } });
triggerSubmit();
expect(await screen.findByText('请输入用户号')).toBeInTheDocument();
});
it('usertype/language selects expose enum options only', async () => {
const user = userEvent.setup();
setup({ mode: 'create' });
await user.click(screen.getByTestId('select-usertype').querySelector('.ant-select-selector')!);
await waitFor(() => expect(screen.getAllByText('超级管理员').length).toBeGreaterThan(0));
await user.click(screen.getByTestId('select-language').querySelector('.ant-select-selector')!);
await waitFor(() => {
expect(screen.getByText('英文')).toBeInTheDocument();
expect(screen.getByText('繁体')).toBeInTheDocument();
});
});
it('create mode creator shows 保存后自动生成; edit shows readonlyCreator', () => {
const { unmount } = renderShell(
<Harness mode="create" />,
{ preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } },
);
expect(screen.getByText('保存后自动生成')).toBeInTheDocument();
unmount();
renderShell(
<Harness mode="edit" readonlyCreator="admin" />,
{ preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } },
);
expect(screen.getByText('admin')).toBeInTheDocument();
});
it('selecting employee calls onSelectEmployee', async () => {
const user = userEvent.setup();
const onSelectEmployee = vi.fn();
setup({ mode: 'create', onSelectEmployee });
await user.click(screen.getByTestId('select-employee').querySelector('.ant-select-selector')!);
await user.click(await screen.findByText('张三'));
expect(onSelectEmployee).toHaveBeenCalledWith(3);
});
it('单据修改权限 checkbox default unchecked (create)', () => {
setup({ mode: 'create' });
const cb = screen.getByTestId('field-canmodify') as HTMLInputElement;
expect(cb.checked).toBe(false);
});
});