Files
workspace/code/fms/fms-vue/tests/unit/module-fields-panel-participation.spec.js
T
2026-09-15 22:10:13 +08:00

137 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 字段定义面板参与勾选接线测试(V2:界面配置为 s_module_schema JSON):
* - 虚拟字段 __form/__list/__query 由 view/edit/query JSON 物化(内置 checkbox 的勾选态)
* - change 事件按列路由:参与列 → 对应配置 JSON(update:viewSchema/editSchema/querySchema),
* 普通列 → 字段模型(update:modelValue)
* - 字段派生虚拟字段在提交前由 stripInternalKeys 剥离,不污染保存
*/
import { mount } from '@vue/test-utils'
import { beforeAll, describe, expect, it } from 'vitest'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { registerFeature, useAreaSelection } from 'stk-table-vue'
import ModuleFieldsPanel from '@/views/module/module-management/ModuleFieldsPanel.vue'
import { stripInternalKeys } from '@/utils/dataChanges'
// 与 main.js 一致:注册 stk-table 的按需 feature
registerFeature(useAreaSelection)
// jsdom 无布局,容器 clientWidth 为 0 时 StkTable 走默认宽度并启用虚拟列裁剪,
// 只渲染首列——patch 成宽容器让全部列真实渲染
beforeAll(() => {
Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
configurable: true,
get() {
return 5000
},
})
})
function makeFields() {
return [
{ b_field: 'amount', b_name: '金额', b_type: 'money', b_canuse: 1, b_i18n: null },
{ b_field: 'remark', b_name: '备注', b_type: 'textarea', b_canuse: 1, b_i18n: null },
]
}
function mountPanel() {
const localFields = makeFields()
const wrapper = mount(ModuleFieldsPanel, {
props: {
moduleId: 'm1',
modelValue: localFields,
// amount 已参与表单与列表;查询未配置
editSchema: { schemaVersion: 1, children: [{ field: 'amount', span: 24 }] },
viewSchema: { schemaVersion: 1, columns: [{ field: 'amount', width: 110 }] },
querySchema: { schemaVersion: 1, quick: [], groups: [] },
i18n: [],
module: { b_id: 'demo' },
loading: false,
},
attachTo: document.body,
})
return { wrapper, localFields }
}
async function settle() {
await nextTick()
await new Promise((r) => setTimeout(r, 100))
}
describe('ModuleFieldsPanel 参与勾选', () => {
it('虚拟字段按配置 JSON 物化:amount 表单/列表参与、查询未配置', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
expect(localFields[0].__form).toBe(1)
expect(localFields[0].__list).toBe(1)
expect(localFields[0].__query).toBe(0)
expect(localFields[1].__form).toBe(0)
wrapper.unmount()
})
it('勾选查询列 → emit update:querySchema,生成默认查询条件', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit('change', localFields[0], { dataIndex: '__query' })
await nextTick()
const events = wrapper.emitted('update:querySchema')
expect(events?.length).toBeGreaterThan(0)
const schema = events.at(-1)[0]
const condition = schema.groups[0].conditions[0]
expect(condition.field).toBe('amount')
expect(condition.operator).toBe('eq')
expect(condition.component).toBe('number')
wrapper.unmount()
})
it('取消列表参与 → emit update:viewSchema 移除该字段节点', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit('change', localFields[0], { dataIndex: '__list' })
await nextTick()
const events = wrapper.emitted('update:viewSchema')
expect(events?.length).toBeGreaterThan(0)
const schema = events.at(-1)[0]
expect((schema.columns || []).map((n) => n.field)).not.toContain('amount')
wrapper.unmount()
})
it('普通列 change → emit update:modelValue,派生虚拟字段可由 stripInternalKeys 剥离', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
const table = wrapper.findComponent({ name: 'FmsTable' })
table.vm.$emit('change', localFields[0], { dataIndex: 'b_name' })
await nextTick()
const events = wrapper.emitted('update:modelValue')
expect(events?.length).toBeGreaterThan(0)
const emitted = events.at(-1)[0]
expect(emitted[0].b_field).toBe('amount')
const stripped = stripInternalKeys(emitted[0])
expect('__form' in stripped).toBe(false)
expect('__list' in stripped).toBe(false)
expect('__query' in stripped).toBe(false)
wrapper.unmount()
})
/**
* 回归点:b_i18n 是派生值(field.{模块编码}.{字段名}),加载阶段不得自动补齐。
* 补了会让草稿与基线不一致,表现为「打开模块什么都没改,切换节点却提示有未保存的修改」。
* 它只在用户编辑(onCellChange)与父级保存前(beforeSave)物化。
*/
it('模块加载后不自动派生 b_i18n,草稿保持与库中一致', async () => {
setActivePinia(createPinia())
const { wrapper, localFields } = mountPanel()
await settle()
expect(localFields[0].b_i18n).toBeNull()
expect(localFields[1].b_i18n).toBeNull()
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
wrapper.unmount()
})
})