刘光辉
8 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import { mount } from '@vue/test-utils';
 
import Antd, { Checkbox, Select } from 'ant-design-vue';
import { beforeAll, describe, expect, it, vi } from 'vitest';
 
import PrivateFieldForm from '../../src/components/PrivateFieldForm.vue';
 
beforeAll(() => {
  window.matchMedia ??= () =>
    ({
      addEventListener() {},
      addListener() {},
      dispatchEvent: () => false,
      matches: false,
      media: '',
      onchange: null,
      removeEventListener() {},
      removeListener() {},
    }) as MediaQueryList;
  globalThis.ResizeObserver ??= class ResizeObserver {
    disconnect() {}
    observe() {}
    unobserve() {}
  };
});
 
describe('privateFieldForm', () => {
  it('使用当前选中文本预填可编辑的字段名称', async () => {
    const wrapper = mount(PrivateFieldForm, {
      props: { initialName: '是否合格' },
      global: { plugins: [Antd] },
    });
 
    expect(wrapper.text()).toContain('字段名称');
    expect(wrapper.get('[data-test="private-field-name"]').attributes('value')).toBe('是否合格');
    await wrapper.get('[data-test="private-field-name"]').setValue('是否复核');
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toMatchObject({ ziduanMingcheng: '是否复核' });
  });
 
  it('只包含字段名称、类型、placeholder、默认值和选项,不出现来源或编码', () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    expect(wrapper.get('[data-test="private-field-name"]').attributes('placeholder')).toBe('请输入字段名称');
    expect(wrapper.find('[data-test="private-field-type"]').exists()).toBe(true);
    expect(wrapper.get('[data-test="private-field-placeholder"]').attributes('placeholder')).toBe('请输入占位文本');
    expect(wrapper.get('[data-test="private-field-default"]').attributes('placeholder')).toBe('请输入默认值');
    expect(wrapper.text()).not.toContain('字段编码');
    expect(wrapper.text()).not.toContain('来源');
  });
 
  it('下拉字段提交规范化选项,不提交来源、编码、必填或 binding', async () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-name"]').setValue(' 检测结论 ');
    wrapper.findComponent(Select).vm.$emit('update:value', 'SELECT');
    await wrapper.vm.$nextTick();
    await wrapper.get('[data-test="private-option-display-0"]').setValue(' 合格 ');
    await wrapper.get('[data-test="private-option-value-0"]').setValue(' PASS ');
    await wrapper.get('[data-test="private-option-display-1"]').setValue('不合格');
    await wrapper.get('[data-test="private-option-value-1"]').setValue('FAIL');
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toEqual({
      ziduanMingcheng: '检测结论',
      shujuLeixing: 'SELECT',
      kongjianPeizhi: {
        defaultValue: '',
        options: [
          { display: '合格', value: 'PASS' },
          { display: '不合格', value: 'FAIL' },
        ],
        placeholder: '检测结论',
      },
    });
  });
 
  it('数值字段未填写 placeholder 时使用显示名,避免 ONLYOFFICE 自动占位文本漂移', async () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-name"]').setValue(' P3验收链结果 ');
    wrapper.findComponent(Select).vm.$emit('update:value', 'DECIMAL');
    await wrapper.vm.$nextTick();
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toEqual({
      ziduanMingcheng: 'P3验收链结果',
      shujuLeixing: 'DECIMAL',
      kongjianPeizhi: { defaultValue: '', placeholder: 'P3验收链结果' },
    });
  });
 
  it.each([
    ['DATE', 'YYYY-MM-DD', false, '2026-09-04', 'yyyy-MM-dd'],
    ['DATETIME', 'YYYY-MM-DD HH:mm:ss', { format: 'HH:mm:ss' }, '2026-09-04 14:35:27', 'yyyy-MM-dd HH:mm:ss'],
  ] as const)('%s 字段隐藏占位文本并使用对应的日期选择组件', async (type, format, showTime, value, dateFormat) => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-name"]').setValue('检验时间');
    wrapper.findComponent(Select).vm.$emit('update:value', type);
    await wrapper.vm.$nextTick();
 
    expect(wrapper.find('[data-test="private-field-placeholder"]').exists()).toBe(false);
    expect(wrapper.find('[data-test="private-field-default"]').exists()).toBe(false);
    const picker = wrapper.getComponent({ name: 'ADatePicker' });
    expect(picker.props('format')).toBe(format);
    expect(picker.props('valueFormat')).toBe(format);
    expect(picker.props('showTime')).toEqual(showTime);
    expect(picker.props('value')).toBeUndefined();
 
    picker.vm.$emit('update:value', value);
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toEqual({
      ziduanMingcheng: '检验时间',
      shujuLeixing: type,
      kongjianPeizhi: { dateFormat, defaultValue: value, placeholder: '' },
    });
  });
 
  it('日期时间未选默认值时保持为空', async () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-name"]').setValue('检验时间');
    wrapper.findComponent(Select).vm.$emit('update:value', 'DATETIME');
    await wrapper.vm.$nextTick();
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toMatchObject({
      kongjianPeizhi: { dateFormat: 'yyyy-MM-dd HH:mm:ss', defaultValue: '', placeholder: '' },
    });
  });
 
  it('复选框以布尔控件提交 defaultChecked,且不提交 defaultValue', async () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-name"]').setValue('是否合格');
    await wrapper.get('[data-test="private-field-placeholder"]').setValue('不应保留');
    wrapper.findComponent(Select).vm.$emit('update:value', 'CHECKBOX');
    await wrapper.vm.$nextTick();
    expect(wrapper.find('[data-test="private-field-placeholder"]').exists()).toBe(false);
    const checkbox = wrapper.findComponent(Checkbox);
    expect(checkbox.exists()).toBe(true);
    checkbox.vm.$emit('update:checked', true);
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toEqual({
      ziduanMingcheng: '是否合格',
      shujuLeixing: 'CHECKBOX',
      kongjianPeizhi: { defaultChecked: true, placeholder: '' },
    });
  });
 
  it('本模板复选框可选择当前作用域选择组并随草稿提交权威规则', async () => {
    const wrapper = mount(PrivateFieldForm, {
      props: {
        checkboxGroupOptions: [{ label: 'inspection_result(2 个成员)', value: 'inspection_result' }],
        checkboxGroups: [{ groupCode: 'inspection_result', maxSelected: 3, minSelected: 1, version: 2 }],
      },
      global: { plugins: [Antd] },
    });
    await wrapper.get('[data-test="private-field-name"]').setValue('是否复核');
    wrapper.findComponent(Select).vm.$emit('update:value', 'CHECKBOX');
    await wrapper.vm.$nextTick();
 
    const groupInput = wrapper.getComponent({ name: 'AAutoComplete' });
    expect(groupInput.props('options')).toEqual([{ label: 'inspection_result(2 个成员)', value: 'inspection_result' }]);
    groupInput.vm.$emit('update:value', 'inspection_result');
    await wrapper.vm.$nextTick();
    expect((wrapper.get('[data-test="private-checkbox-group-min"]').element as HTMLInputElement).value).toBe('1');
    expect((wrapper.get('[data-test="private-checkbox-group-max"]').element as HTMLInputElement).value).toBe('3');
    expect(wrapper.get('[data-test="private-checkbox-group-min"]').attributes('disabled')).toBeDefined();
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
 
    expect(wrapper.emitted('submit')?.[0]?.[0]).toMatchObject({
      checkboxGroupCode: 'inspection_result',
      checkboxGroupMaxSelected: 3,
      checkboxGroupMinSelected: 1,
      shujuLeixing: 'CHECKBOX',
      ziduanMingcheng: '是否复核',
    });
  });
 
  it('本模板复选框可生成选择组编码,展示建议并确认后填入', async () => {
    const suggestCode = vi.fn(async () => 'jianyan_jieguo');
    const wrapper = mount(PrivateFieldForm, {
      props: { suggestCode },
      global: { plugins: [Antd] },
    });
    wrapper.findComponent(Select).vm.$emit('update:value', 'CHECKBOX');
    await wrapper.vm.$nextTick();
    const groupInput = wrapper.getComponent({ name: 'AAutoComplete' });
    groupInput.vm.$emit('update:value', 'original_group');
    await wrapper.vm.$nextTick();
 
    expect(wrapper.get('[data-test="private-checkbox-code-assist"]').attributes('aria-label')).toBe('中文转拼音');
    await wrapper.get('[data-test="private-checkbox-code-assist"]').trigger('click');
    expect(wrapper.get('[data-test="code-assist-modal"]').text()).toContain('生成选择组编码');
    await wrapper.get('[data-test="code-assist-text"]').setValue('检验结果');
    await wrapper.get('[data-test="code-assist-generate"]').trigger('click');
    await vi.waitFor(() => expect(suggestCode).toHaveBeenCalledWith('检验结果'));
 
    expect(wrapper.get('[data-test="code-assist-suggestion"]').attributes('value')).toBe('jianyan_jieguo');
    expect(groupInput.props('value')).toBe('original_group');
 
    await wrapper.get('[data-test="code-assist-confirm"]').trigger('click');
 
    expect(wrapper.find('[data-test="code-assist-modal"]').exists()).toBe(false);
    expect(groupInput.props('value')).toBe('jianyan_jieguo');
  });
 
  it('名称为空或下拉选项不完整时不提交', async () => {
    const wrapper = mount(PrivateFieldForm, { global: { plugins: [Antd] } });
    await wrapper.get('[data-test="private-field-submit"]').trigger('click');
    expect(wrapper.emitted('submit')).toBeUndefined();
    expect(wrapper.get('[data-test="private-field-error"]').text()).toContain('字段名称');
  });
});