You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
7.1 KiB

4 days ago
import { shallowMount, createLocalVue } from '@vue/test-utils'
import ElementUI from 'element-ui'
import Rules from '@/views/course/components/CourseFieldRules.vue'
import Answer from '@/views/course/components/CourseAnswerField.vue'
import SurveySettings from '@/views/survey/components/SurveyFieldSettings.vue'
import CourseEditor from '@/views/course/components/editPane.vue'
import { save as saveCourseField } from '@/api/course/form'
import { prepareCourseFields, visibleCourseFields, courseFormError, courseSubmission } from '@/utils/courseForm'
jest.mock('@/api/course/form', () => ({ save: jest.fn(() => Promise.resolve({ id: 7 })), destroy: jest.fn() }))
const localVue = createLocalVue()
localVue.use(ElementUI)
function mountForm(component, props, mocks = {}) {
const state = new localVue({ data() { return { fields: props } } })
return shallowMount(component, { localVue, propsData: state.fields, mocks })
}
const choices = [{ key: 'tax', value: '财税' }, { key: 'legal', value: '法律' }, { key: 'ip', value: '知识产权' }]
describe('Course and survey form compatibility', () => {
it('allows new option keys and ordering after reopening a saved field, while locking only original keys', async () => {
saveCourseField.mockClear()
const field = { id: 7, field: 'venues', name: '会场', edit_input: 'checkbox', select_item: choices.slice(0, 2).map(option => ({ ...option })), config: { option_notes: { tax: { placeholder: '咨询内容', required: false } } } }
const wrapper = shallowMount(CourseEditor, {
localVue, propsData: { rules: {}, types: [] },
methods: { getAllPara() {}, getCompanyConfig() {} },
mocks: { base: { isNull: value => value == null || String(value).trim() === '' }, $Message: { warning: jest.fn(), success: jest.fn() } }
})
await wrapper.setData({ showForm: true, selectedForm: field })
const original = wrapper.vm.selectItem[0]
expect(wrapper.vm.isSavedOption(original)).toBe(true)
expect(wrapper.findAll('.select-item__body').at(0).find('el-input-stub').attributes('disabled')).toBeDefined()
wrapper.find('el-button-stub[icon="el-icon-plus"]').vm.$emit('click')
await wrapper.vm.$nextTick()
const added = wrapper.vm.selectItem[2]
expect(wrapper.vm.isSavedOption(added)).toBe(false)
expect(wrapper.findAll('.select-item__body').at(2).find('el-input-stub').attributes('disabled')).toBeUndefined()
added.key = 'new'; added.value = '其他'
wrapper.vm.moveOption(2, -1)
wrapper.vm.moveOption(0, 1)
expect(wrapper.vm.selectItem.map(option => option.key)).toEqual(['new', 'tax', 'legal'])
expect(wrapper.vm.isSavedOption(added)).toBe(false)
expect(wrapper.vm.isSavedOption(original)).toBe(true)
wrapper.vm.saveField()
await new Promise(resolve => setTimeout(resolve, 0))
const saved = saveCourseField.mock.calls[0][0]
expect(saved.select_item.map(option => option.key)).toEqual(['new', 'tax', 'legal'])
expect(saved.config.option_notes.tax.placeholder).toBe('咨询内容')
expect(wrapper.emitted('refreshFormItem')).toBeTruthy()
await wrapper.setData({ showForm: true, selectedForm: { ...saved, id: 7 } })
expect(wrapper.vm.selectItem.every(option => wrapper.vm.isSavedOption(option))).toBe(true)
wrapper.destroy()
})
it('sets default minima, keeps unlimited maxima, and rejects a maximum below the minimum', () => {
for (const component of [Rules, SurveySettings]) {
const field = { id: 1, field: 'venues', name: '会场', edit_input: 'checkbox', config: {}, select_item: [...choices] }
const warning = jest.fn()
const wrapper = mountForm(component, { field }, { $message: { warning } })
expect(wrapper.findAll('el-input-number-stub').at(0).props('min')).toBe(1)
if (component === Rules) { wrapper.vm.minimum(2); wrapper.vm.maximum(1); wrapper.vm.maximum(0) } else { wrapper.vm.changeMinimum(2); wrapper.vm.changeMaximum(1); wrapper.vm.changeMaximum(0) }
expect(field.config.min_choices).toBe(2)
expect(field.config.max_choices).toBe(0)
expect(warning).toHaveBeenCalledWith('最多选择项数不能小于最少选择项数')
wrapper.destroy()
}
})
it('configures multiple triggers and required overrides without changing existing field identifiers', () => {
const parent = { id: 1, field: 'finance', sort: 1, name: '融资', edit_input: 'radio', select_item: choices }
const field = { id: 2, field: 'legacy_field', sort: 2, name: '材料', edit_input: 'text', config: {} }
const wrapper = mountForm(Rules, { field, fields: [parent, field] })
wrapper.vm.toggleCondition(true)
wrapper.vm.changeParent('finance')
field.config.visible_when.values = ['tax', 'legal']
wrapper.vm.toggleRequired(true)
field.config.visible_when.required_values = ['tax']
expect(wrapper.vm.parents).toEqual([parent])
expect(field.field).toBe('legacy_field')
expect(field.config.visible_when.required_values).toEqual(['tax'])
wrapper.vm.changeParent('finance')
expect(field.config.visible_when.values).toEqual([])
expect(field.config.visible_when.required_values).toEqual([])
wrapper.destroy()
})
it('restores comma answers, shows selected supplements, enforces limits, and clears deselected notes', async () => {
const fields = prepareCourseFields([{ id: 1, field: 'venues', name: '会场', edit_input: 'checkbox', value: '财税,法律', select_item: choices, config: { min_choices: 2, max_choices: 2, option_notes: { tax: { placeholder: '咨询内容', required: true } } } }])
const wrapper = mountForm(Answer, { field: fields[0] })
expect(wrapper.vm.selection).toEqual(['tax', 'legal'])
expect(wrapper.find('el-input-stub').attributes('placeholder')).toBe('咨询内容')
expect(courseFormError(fields)).toContain('请填写补充说明')
fields[0].option_texts.tax = '问题'
expect(courseFormError(fields)).toBe('')
wrapper.vm.choose(['legal'])
await wrapper.vm.$nextTick()
expect(wrapper.find('el-input-stub').exists()).toBe(false)
expect(fields[0].option_texts).toEqual({})
expect(courseFormError(fields)).toContain('至少选择2项')
wrapper.destroy()
})
it('keeps saved identity values and zero; hidden answers never enter profile/update payloads', () => {
const fields = prepareCourseFields([
{ field: 'username', name: '姓名', edit_input: 'text', belong_user: true, value: '原报名姓名' },
{ field: 'parent', name: '前置', edit_input: 'radio', value: '否', select_item: [{ key: 'no', value: '否' }] },
{ field: 'hidden', name: '条件题', edit_input: 'checkbox', value: '财税', config: { visible_when: { field: 'parent', values: ['yes'] } }, select_item: choices, option_texts: { tax: '旧说明' } },
{ field: 'zero', name: '数量', edit_input: 'number', value: 0 }
], { username: '最新资料姓名' })
expect(fields[0].value).toBe('原报名姓名')
expect(fields[3].value).toBe(0)
expect(visibleCourseFields(fields).map(field => field.field)).toEqual(['username', 'parent', 'zero'])
expect(courseSubmission(fields)[2]).toMatchObject({ hidden: true, value: null, option_texts: {}, selected_keys: [] })
})
})