137 lines
5.3 KiB
JavaScript
137 lines
5.3 KiB
JavaScript
/**
|
||
* 字段定义面板参与勾选接线测试(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()
|
||
})
|
||
})
|